1 /*
2  * Mesa 3-D graphics library
3  * Version:  7.1
4  *
5  * Copyright (C) 1999-2007  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 
26 /**
27  * \file clear.c
28  * glClearColor, glClearIndex, glClear() functions.
29  */
30 
31 
32 
33 #include "glheader.h"
34 #include "clear.h"
35 #include "context.h"
36 #include "colormac.h"
37 #include "enums.h"
38 #include "macros.h"
39 #include "mtypes.h"
40 #include "state.h"
41 
42 
43 
44 #if _HAVE_FULL_GL
45 void GLAPIENTRY
_mesa_ClearIndex(GLfloat c)46 _mesa_ClearIndex( GLfloat c )
47 {
48    GET_CURRENT_CONTEXT(ctx);
49    ASSERT_OUTSIDE_BEGIN_END(ctx);
50 
51    if (ctx->Color.ClearIndex == (GLuint) c)
52       return;
53 
54    FLUSH_VERTICES(ctx, _NEW_COLOR);
55    ctx->Color.ClearIndex = (GLuint) c;
56 }
57 #endif
58 
59 
60 /**
61  * Specify the clear values for the color buffers.
62  *
63  * \param red red color component.
64  * \param green green color component.
65  * \param blue blue color component.
66  * \param alpha alpha component.
67  *
68  * \sa glClearColor().
69  *
70  * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor.  On a
71  * change, flushes the vertices and notifies the driver via the
72  * dd_function_table::ClearColor callback.
73  */
74 void GLAPIENTRY
_mesa_ClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)75 _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
76 {
77    GLfloat tmp[4];
78    GET_CURRENT_CONTEXT(ctx);
79    ASSERT_OUTSIDE_BEGIN_END(ctx);
80 
81    tmp[0] = red;
82    tmp[1] = green;
83    tmp[2] = blue;
84    tmp[3] = alpha;
85 
86    if (TEST_EQ_4V(tmp, ctx->Color.ClearColor.f))
87       return; /* no change */
88 
89    FLUSH_VERTICES(ctx, _NEW_COLOR);
90    COPY_4V(ctx->Color.ClearColor.f, tmp);
91 }
92 
93 
94 /**
95  * GL_EXT_texture_integer
96  */
97 void GLAPIENTRY
_mesa_ClearColorIiEXT(GLint r,GLint g,GLint b,GLint a)98 _mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a)
99 {
100    GLint tmp[4];
101    GET_CURRENT_CONTEXT(ctx);
102    ASSERT_OUTSIDE_BEGIN_END(ctx);
103 
104    tmp[0] = r;
105    tmp[1] = g;
106    tmp[2] = b;
107    tmp[3] = a;
108 
109    if (TEST_EQ_4V(tmp, ctx->Color.ClearColor.i))
110       return; /* no change */
111 
112    FLUSH_VERTICES(ctx, _NEW_COLOR);
113    COPY_4V(ctx->Color.ClearColor.i, tmp);
114 }
115 
116 
117 /**
118  * GL_EXT_texture_integer
119  */
120 void GLAPIENTRY
_mesa_ClearColorIuiEXT(GLuint r,GLuint g,GLuint b,GLuint a)121 _mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a)
122 {
123    GLuint tmp[4];
124    GET_CURRENT_CONTEXT(ctx);
125    ASSERT_OUTSIDE_BEGIN_END(ctx);
126 
127    tmp[0] = r;
128    tmp[1] = g;
129    tmp[2] = b;
130    tmp[3] = a;
131 
132    if (TEST_EQ_4V(tmp, ctx->Color.ClearColor.ui))
133       return; /* no change */
134 
135    FLUSH_VERTICES(ctx, _NEW_COLOR);
136    COPY_4V(ctx->Color.ClearColor.ui, tmp);
137 }
138 
139 
140 /**
141  * Clear buffers.
142  *
143  * \param mask bit-mask indicating the buffers to be cleared.
144  *
145  * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState
146  * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin,
147  * etc. If the rasterization mode is set to GL_RENDER then requests the driver
148  * to clear the buffers, via the dd_function_table::Clear callback.
149  */
150 void GLAPIENTRY
_mesa_Clear(GLbitfield mask)151 _mesa_Clear( GLbitfield mask )
152 {
153    GET_CURRENT_CONTEXT(ctx);
154    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
155 
156    FLUSH_CURRENT(ctx, 0);
157 
158    if (MESA_VERBOSE & VERBOSE_API)
159       _mesa_debug(ctx, "glClear 0x%x\n", mask);
160 
161    if (mask & ~(GL_COLOR_BUFFER_BIT |
162                 GL_DEPTH_BUFFER_BIT |
163                 GL_STENCIL_BUFFER_BIT |
164                 GL_ACCUM_BUFFER_BIT)) {
165       /* invalid bit set */
166       _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask);
167       return;
168    }
169 
170    /* Accumulation buffers were removed in core contexts, and they never
171     * existed in OpenGL ES.
172     */
173    if ((mask & GL_ACCUM_BUFFER_BIT) != 0
174        && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) {
175       _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)");
176       return;
177    }
178 
179    if (ctx->NewState) {
180       _mesa_update_state( ctx );	/* update _Xmin, etc */
181    }
182 
183    if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
184       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
185                   "glClear(incomplete framebuffer)");
186       return;
187    }
188 
189    if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 ||
190        ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax ||
191        ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax)
192       return;
193 
194    if (ctx->RasterDiscard)
195       return;
196 
197    if (ctx->RenderMode == GL_RENDER) {
198       GLbitfield bufferMask;
199 
200       /* don't clear depth buffer if depth writing disabled */
201       if (!ctx->Depth.Mask)
202          mask &= ~GL_DEPTH_BUFFER_BIT;
203 
204       /* Build the bitmask to send to device driver's Clear function.
205        * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
206        * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
207        * BUFFER_BIT_COLORn flags.
208        */
209       bufferMask = 0;
210       if (mask & GL_COLOR_BUFFER_BIT) {
211          GLuint i;
212          for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
213             bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]);
214          }
215       }
216 
217       if ((mask & GL_DEPTH_BUFFER_BIT)
218           && ctx->DrawBuffer->Visual.haveDepthBuffer) {
219          bufferMask |= BUFFER_BIT_DEPTH;
220       }
221 
222       if ((mask & GL_STENCIL_BUFFER_BIT)
223           && ctx->DrawBuffer->Visual.haveStencilBuffer) {
224          bufferMask |= BUFFER_BIT_STENCIL;
225       }
226 
227       if ((mask & GL_ACCUM_BUFFER_BIT)
228           && ctx->DrawBuffer->Visual.haveAccumBuffer) {
229          bufferMask |= BUFFER_BIT_ACCUM;
230       }
231 
232       ASSERT(ctx->Driver.Clear);
233       ctx->Driver.Clear(ctx, bufferMask);
234    }
235 }
236 
237 
238 /** Returned by make_color_buffer_mask() for errors */
239 #define INVALID_MASK ~0x0
240 
241 
242 /**
243  * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
244  * BUFFER_BIT_x values.
245  * Return INVALID_MASK if the drawbuffer value is invalid.
246  */
247 static GLbitfield
make_color_buffer_mask(struct gl_context * ctx,GLint drawbuffer)248 make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer)
249 {
250    const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
251    GLbitfield mask = 0x0;
252 
253    switch (drawbuffer) {
254    case GL_FRONT:
255       if (att[BUFFER_FRONT_LEFT].Renderbuffer)
256          mask |= BUFFER_BIT_FRONT_LEFT;
257       if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
258          mask |= BUFFER_BIT_FRONT_RIGHT;
259       break;
260    case GL_BACK:
261       if (att[BUFFER_BACK_LEFT].Renderbuffer)
262          mask |= BUFFER_BIT_BACK_LEFT;
263       if (att[BUFFER_BACK_RIGHT].Renderbuffer)
264          mask |= BUFFER_BIT_BACK_RIGHT;
265       break;
266    case GL_LEFT:
267       if (att[BUFFER_FRONT_LEFT].Renderbuffer)
268          mask |= BUFFER_BIT_FRONT_LEFT;
269       if (att[BUFFER_BACK_LEFT].Renderbuffer)
270          mask |= BUFFER_BIT_BACK_LEFT;
271       break;
272    case GL_RIGHT:
273       if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
274          mask |= BUFFER_BIT_FRONT_RIGHT;
275       if (att[BUFFER_BACK_RIGHT].Renderbuffer)
276          mask |= BUFFER_BIT_BACK_RIGHT;
277       break;
278    case GL_FRONT_AND_BACK:
279       if (att[BUFFER_FRONT_LEFT].Renderbuffer)
280          mask |= BUFFER_BIT_FRONT_LEFT;
281       if (att[BUFFER_BACK_LEFT].Renderbuffer)
282          mask |= BUFFER_BIT_BACK_LEFT;
283       if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
284          mask |= BUFFER_BIT_FRONT_RIGHT;
285       if (att[BUFFER_BACK_RIGHT].Renderbuffer)
286          mask |= BUFFER_BIT_BACK_RIGHT;
287       break;
288    default:
289       if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) {
290          mask = INVALID_MASK;
291       }
292       else if (att[BUFFER_COLOR0 + drawbuffer].Renderbuffer) {
293          mask |= (BUFFER_BIT_COLOR0 << drawbuffer);
294       }
295    }
296 
297    return mask;
298 }
299 
300 
301 
302 /**
303  * New in GL 3.0
304  * Clear signed integer color buffer or stencil buffer (not depth).
305  */
306 void GLAPIENTRY
_mesa_ClearBufferiv(GLenum buffer,GLint drawbuffer,const GLint * value)307 _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
308 {
309    GET_CURRENT_CONTEXT(ctx);
310    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
311 
312    FLUSH_CURRENT(ctx, 0);
313 
314    if (ctx->NewState) {
315       _mesa_update_state( ctx );
316    }
317 
318    switch (buffer) {
319    case GL_STENCIL:
320       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
321        *
322        *     "ClearBuffer generates an INVALID VALUE error if buffer is
323        *     COLOR and drawbuffer is less than zero, or greater than the
324        *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
325        *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
326        */
327       if (drawbuffer != 0) {
328          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
329                      drawbuffer);
330          return;
331       }
332       else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer && !ctx->RasterDiscard) {
333          /* Save current stencil clear value, set to 'value', do the
334           * stencil clear and restore the clear value.
335           * XXX in the future we may have a new ctx->Driver.ClearBuffer()
336           * hook instead.
337           */
338          const GLuint clearSave = ctx->Stencil.Clear;
339          ctx->Stencil.Clear = *value;
340          ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL);
341          ctx->Stencil.Clear = clearSave;
342       }
343       break;
344    case GL_COLOR:
345       {
346          const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
347          if (mask == INVALID_MASK) {
348             _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
349                         drawbuffer);
350             return;
351          }
352          else if (mask && !ctx->RasterDiscard) {
353             union gl_color_union clearSave;
354 
355             /* save color */
356             clearSave = ctx->Color.ClearColor;
357             /* set color */
358             COPY_4V(ctx->Color.ClearColor.i, value);
359             /* clear buffer(s) */
360             ctx->Driver.Clear(ctx, mask);
361             /* restore color */
362             ctx->Color.ClearColor = clearSave;
363          }
364       }
365       break;
366    case GL_DEPTH:
367       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
368        *
369        *     "The result of ClearBuffer is undefined if no conversion between
370        *     the type of the specified value and the type of the buffer being
371        *     cleared is defined (for example, if ClearBufferiv is called for a
372        *     fixed- or floating-point buffer, or if ClearBufferfv is called
373        *     for a signed or unsigned integer buffer). This is not an error."
374        *
375        * In this case we take "undefined" and "not an error" to mean "ignore."
376        * Note that we still need to generate an error for the invalid
377        * drawbuffer case (see the GL_STENCIL case above).
378        */
379       if (drawbuffer != 0) {
380          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
381                      drawbuffer);
382          return;
383       }
384       return;
385    default:
386       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
387                   _mesa_lookup_enum_by_nr(buffer));
388       return;
389    }
390 }
391 
392 
393 /**
394  * New in GL 3.0
395  * Clear unsigned integer color buffer (not depth, not stencil).
396  */
397 void GLAPIENTRY
_mesa_ClearBufferuiv(GLenum buffer,GLint drawbuffer,const GLuint * value)398 _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
399 {
400    GET_CURRENT_CONTEXT(ctx);
401    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
402 
403    FLUSH_CURRENT(ctx, 0);
404 
405    if (ctx->NewState) {
406       _mesa_update_state( ctx );
407    }
408 
409    switch (buffer) {
410    case GL_COLOR:
411       {
412          const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
413          if (mask == INVALID_MASK) {
414             _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
415                         drawbuffer);
416             return;
417          }
418          else if (mask && !ctx->RasterDiscard) {
419             union gl_color_union clearSave;
420 
421             /* save color */
422             clearSave = ctx->Color.ClearColor;
423             /* set color */
424             COPY_4V(ctx->Color.ClearColor.ui, value);
425             /* clear buffer(s) */
426             ctx->Driver.Clear(ctx, mask);
427             /* restore color */
428             ctx->Color.ClearColor = clearSave;
429          }
430       }
431       break;
432    case GL_DEPTH:
433    case GL_STENCIL:
434       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
435        *
436        *     "The result of ClearBuffer is undefined if no conversion between
437        *     the type of the specified value and the type of the buffer being
438        *     cleared is defined (for example, if ClearBufferiv is called for a
439        *     fixed- or floating-point buffer, or if ClearBufferfv is called
440        *     for a signed or unsigned integer buffer). This is not an error."
441        *
442        * In this case we take "undefined" and "not an error" to mean "ignore."
443        * Even though we could do something sensible for GL_STENCIL, page 263
444        * (page 279 of the PDF) says:
445        *
446        *     "Only ClearBufferiv should be used to clear stencil buffers."
447        *
448        * Note that we still need to generate an error for the invalid
449        * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
450        */
451       if (drawbuffer != 0) {
452          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
453                      drawbuffer);
454          return;
455       }
456       return;
457    default:
458       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
459                   _mesa_lookup_enum_by_nr(buffer));
460       return;
461    }
462 }
463 
464 
465 /**
466  * New in GL 3.0
467  * Clear fixed-pt or float color buffer or depth buffer (not stencil).
468  */
469 void GLAPIENTRY
_mesa_ClearBufferfv(GLenum buffer,GLint drawbuffer,const GLfloat * value)470 _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
471 {
472    GET_CURRENT_CONTEXT(ctx);
473    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
474 
475    FLUSH_CURRENT(ctx, 0);
476 
477    if (ctx->NewState) {
478       _mesa_update_state( ctx );
479    }
480 
481    switch (buffer) {
482    case GL_DEPTH:
483       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
484        *
485        *     "ClearBuffer generates an INVALID VALUE error if buffer is
486        *     COLOR and drawbuffer is less than zero, or greater than the
487        *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
488        *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
489        */
490       if (drawbuffer != 0) {
491          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
492                      drawbuffer);
493          return;
494       }
495       else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer && !ctx->RasterDiscard) {
496          /* Save current depth clear value, set to 'value', do the
497           * depth clear and restore the clear value.
498           * XXX in the future we may have a new ctx->Driver.ClearBuffer()
499           * hook instead.
500           */
501          const GLclampd clearSave = ctx->Depth.Clear;
502          ctx->Depth.Clear = *value;
503          ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH);
504          ctx->Depth.Clear = clearSave;
505       }
506       /* clear depth buffer to value */
507       break;
508    case GL_COLOR:
509       {
510          const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
511          if (mask == INVALID_MASK) {
512             _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
513                         drawbuffer);
514             return;
515          }
516          else if (mask && !ctx->RasterDiscard) {
517             union gl_color_union clearSave;
518 
519             /* save color */
520             clearSave = ctx->Color.ClearColor;
521             /* set color */
522             COPY_4V(ctx->Color.ClearColor.f, value);
523             /* clear buffer(s) */
524             ctx->Driver.Clear(ctx, mask);
525             /* restore color */
526             ctx->Color.ClearColor = clearSave;
527          }
528       }
529       break;
530    case GL_STENCIL:
531       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
532        *
533        *     "The result of ClearBuffer is undefined if no conversion between
534        *     the type of the specified value and the type of the buffer being
535        *     cleared is defined (for example, if ClearBufferiv is called for a
536        *     fixed- or floating-point buffer, or if ClearBufferfv is called
537        *     for a signed or unsigned integer buffer). This is not an error."
538        *
539        * In this case we take "undefined" and "not an error" to mean "ignore."
540        * Note that we still need to generate an error for the invalid
541        * drawbuffer case (see the GL_DEPTH case above).
542        */
543       if (drawbuffer != 0) {
544          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
545                      drawbuffer);
546          return;
547       }
548       return;
549    default:
550       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
551                   _mesa_lookup_enum_by_nr(buffer));
552       return;
553    }
554 }
555 
556 
557 /**
558  * New in GL 3.0
559  * Clear depth/stencil buffer only.
560  */
561 void GLAPIENTRY
_mesa_ClearBufferfi(GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)562 _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
563                     GLfloat depth, GLint stencil)
564 {
565    GET_CURRENT_CONTEXT(ctx);
566    GLbitfield mask = 0;
567 
568    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
569 
570    FLUSH_CURRENT(ctx, 0);
571 
572    if (buffer != GL_DEPTH_STENCIL) {
573       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
574                   _mesa_lookup_enum_by_nr(buffer));
575       return;
576    }
577 
578    /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
579     *
580     *     "ClearBuffer generates an INVALID VALUE error if buffer is
581     *     COLOR and drawbuffer is less than zero, or greater than the
582     *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
583     *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
584     */
585    if (drawbuffer != 0) {
586       _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)",
587                   drawbuffer);
588       return;
589    }
590 
591    if (ctx->RasterDiscard)
592       return;
593 
594    if (ctx->NewState) {
595       _mesa_update_state( ctx );
596    }
597 
598    if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer)
599       mask |= BUFFER_BIT_DEPTH;
600    if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer)
601       mask |= BUFFER_BIT_STENCIL;
602 
603    if (mask) {
604       /* save current clear values */
605       const GLclampd clearDepthSave = ctx->Depth.Clear;
606       const GLuint clearStencilSave = ctx->Stencil.Clear;
607 
608       /* set new clear values */
609       ctx->Depth.Clear = depth;
610       ctx->Stencil.Clear = stencil;
611 
612       /* clear buffers */
613       ctx->Driver.Clear(ctx, mask);
614 
615       /* restore */
616       ctx->Depth.Clear = clearDepthSave;
617       ctx->Stencil.Clear = clearStencilSave;
618    }
619 }
620