1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2007  Brian Paul   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 "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:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
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.
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 "enums.h"
37#include "fbobject.h"
38#include "get.h"
39#include "macros.h"
40#include "mtypes.h"
41#include "state.h"
42
43
44
45void GLAPIENTRY
46_mesa_ClearIndex( GLfloat c )
47{
48   GET_CURRENT_CONTEXT(ctx);
49
50   ctx->Color.ClearIndex = (GLuint) c;
51}
52
53
54/**
55 * Specify the clear values for the color buffers.
56 *
57 * \param red red color component.
58 * \param green green color component.
59 * \param blue blue color component.
60 * \param alpha alpha component.
61 *
62 * \sa glClearColor().
63 */
64void GLAPIENTRY
65_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
66{
67   GET_CURRENT_CONTEXT(ctx);
68
69   ctx->Color.ClearColor.f[0] = red;
70   ctx->Color.ClearColor.f[1] = green;
71   ctx->Color.ClearColor.f[2] = blue;
72   ctx->Color.ClearColor.f[3] = alpha;
73}
74
75
76/**
77 * GL_EXT_texture_integer
78 */
79void GLAPIENTRY
80_mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a)
81{
82   GET_CURRENT_CONTEXT(ctx);
83
84   ctx->Color.ClearColor.i[0] = r;
85   ctx->Color.ClearColor.i[1] = g;
86   ctx->Color.ClearColor.i[2] = b;
87   ctx->Color.ClearColor.i[3] = a;
88}
89
90
91/**
92 * GL_EXT_texture_integer
93 */
94void GLAPIENTRY
95_mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a)
96{
97   GET_CURRENT_CONTEXT(ctx);
98
99   ctx->Color.ClearColor.ui[0] = r;
100   ctx->Color.ClearColor.ui[1] = g;
101   ctx->Color.ClearColor.ui[2] = b;
102   ctx->Color.ClearColor.ui[3] = a;
103}
104
105
106/**
107 * Returns true if color writes are enabled for the given color attachment.
108 *
109 * Beyond checking ColorMask, this uses _mesa_format_has_color_component to
110 * ignore components that don't actually exist in the format (such as X in
111 * XRGB).
112 */
113static bool
114color_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx)
115{
116   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[idx];
117   GLuint c;
118   GLubyte colorMask = 0;
119
120   if (rb) {
121      for (c = 0; c < 4; c++) {
122         if (_mesa_format_has_color_component(rb->Format, c))
123            colorMask |= ctx->Color.ColorMask[idx][c];
124      }
125   }
126
127   return colorMask != 0;
128}
129
130
131/**
132 * Clear buffers.
133 *
134 * \param mask bit-mask indicating the buffers to be cleared.
135 *
136 * Flushes the vertices and verifies the parameter.
137 * If __struct gl_contextRec::NewState is set then calls _mesa_update_state()
138 * to update gl_frame_buffer::_Xmin, etc.  If the rasterization mode is set to
139 * GL_RENDER then requests the driver to clear the buffers, via the
140 * dd_function_table::Clear callback.
141 */
142void GLAPIENTRY
143_mesa_Clear( GLbitfield mask )
144{
145   GET_CURRENT_CONTEXT(ctx);
146   FLUSH_VERTICES(ctx, 0);
147
148   FLUSH_CURRENT(ctx, 0);
149
150   if (MESA_VERBOSE & VERBOSE_API)
151      _mesa_debug(ctx, "glClear 0x%x\n", mask);
152
153   if (mask & ~(GL_COLOR_BUFFER_BIT |
154                GL_DEPTH_BUFFER_BIT |
155                GL_STENCIL_BUFFER_BIT |
156                GL_ACCUM_BUFFER_BIT)) {
157      /* invalid bit set */
158      _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask);
159      return;
160   }
161
162   /* Accumulation buffers were removed in core contexts, and they never
163    * existed in OpenGL ES.
164    */
165   if ((mask & GL_ACCUM_BUFFER_BIT) != 0
166       && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) {
167      _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)");
168      return;
169   }
170
171   if (ctx->NewState) {
172      _mesa_update_state( ctx );	/* update _Xmin, etc */
173   }
174
175   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
176      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
177                  "glClear(incomplete framebuffer)");
178      return;
179   }
180
181   if (ctx->RasterDiscard)
182      return;
183
184   if (ctx->RenderMode == GL_RENDER) {
185      GLbitfield bufferMask;
186
187      /* don't clear depth buffer if depth writing disabled */
188      if (!ctx->Depth.Mask)
189         mask &= ~GL_DEPTH_BUFFER_BIT;
190
191      /* Build the bitmask to send to device driver's Clear function.
192       * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
193       * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
194       * BUFFER_BIT_COLORn flags.
195       */
196      bufferMask = 0;
197      if (mask & GL_COLOR_BUFFER_BIT) {
198         GLuint i;
199         for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
200            GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
201
202            if (buf >= 0 && color_buffer_writes_enabled(ctx, i)) {
203               bufferMask |= 1 << buf;
204            }
205         }
206      }
207
208      if ((mask & GL_DEPTH_BUFFER_BIT)
209          && ctx->DrawBuffer->Visual.haveDepthBuffer) {
210         bufferMask |= BUFFER_BIT_DEPTH;
211      }
212
213      if ((mask & GL_STENCIL_BUFFER_BIT)
214          && ctx->DrawBuffer->Visual.haveStencilBuffer) {
215         bufferMask |= BUFFER_BIT_STENCIL;
216      }
217
218      if ((mask & GL_ACCUM_BUFFER_BIT)
219          && ctx->DrawBuffer->Visual.haveAccumBuffer) {
220         bufferMask |= BUFFER_BIT_ACCUM;
221      }
222
223      assert(ctx->Driver.Clear);
224      ctx->Driver.Clear(ctx, bufferMask);
225   }
226}
227
228
229/** Returned by make_color_buffer_mask() for errors */
230#define INVALID_MASK ~0x0U
231
232
233/**
234 * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
235 * BUFFER_BIT_x values.
236 * Return INVALID_MASK if the drawbuffer value is invalid.
237 */
238static GLbitfield
239make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer)
240{
241   const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
242   GLbitfield mask = 0x0;
243
244   /* From the GL 4.0 specification:
245    *	If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is
246    *	specified by passing i as the parameter drawbuffer, and value
247    *	points to a four-element vector specifying the R, G, B, and A
248    *	color to clear that draw buffer to. If the draw buffer is one
249    *	of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
250    *	multiple buffers, each selected buffer is cleared to the same
251    *	value.
252    *
253    * Note that "drawbuffer" and "draw buffer" have different meaning.
254    * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's
255    * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK,
256    * etc.
257    */
258   if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) {
259      return INVALID_MASK;
260   }
261
262   switch (ctx->DrawBuffer->ColorDrawBuffer[drawbuffer]) {
263   case GL_FRONT:
264      if (att[BUFFER_FRONT_LEFT].Renderbuffer)
265         mask |= BUFFER_BIT_FRONT_LEFT;
266      if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
267         mask |= BUFFER_BIT_FRONT_RIGHT;
268      break;
269   case GL_BACK:
270      /* For GLES contexts with a single buffered configuration, we actually
271       * only have a front renderbuffer, so any clear calls to GL_BACK should
272       * affect that buffer. See draw_buffer_enum_to_bitmask for details.
273       */
274      if (_mesa_is_gles(ctx))
275         if (!ctx->DrawBuffer->Visual.doubleBufferMode)
276            if (att[BUFFER_FRONT_LEFT].Renderbuffer)
277               mask |= BUFFER_BIT_FRONT_LEFT;
278      if (att[BUFFER_BACK_LEFT].Renderbuffer)
279         mask |= BUFFER_BIT_BACK_LEFT;
280      if (att[BUFFER_BACK_RIGHT].Renderbuffer)
281         mask |= BUFFER_BIT_BACK_RIGHT;
282      break;
283   case GL_LEFT:
284      if (att[BUFFER_FRONT_LEFT].Renderbuffer)
285         mask |= BUFFER_BIT_FRONT_LEFT;
286      if (att[BUFFER_BACK_LEFT].Renderbuffer)
287         mask |= BUFFER_BIT_BACK_LEFT;
288      break;
289   case GL_RIGHT:
290      if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
291         mask |= BUFFER_BIT_FRONT_RIGHT;
292      if (att[BUFFER_BACK_RIGHT].Renderbuffer)
293         mask |= BUFFER_BIT_BACK_RIGHT;
294      break;
295   case GL_FRONT_AND_BACK:
296      if (att[BUFFER_FRONT_LEFT].Renderbuffer)
297         mask |= BUFFER_BIT_FRONT_LEFT;
298      if (att[BUFFER_BACK_LEFT].Renderbuffer)
299         mask |= BUFFER_BIT_BACK_LEFT;
300      if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
301         mask |= BUFFER_BIT_FRONT_RIGHT;
302      if (att[BUFFER_BACK_RIGHT].Renderbuffer)
303         mask |= BUFFER_BIT_BACK_RIGHT;
304      break;
305   default:
306      {
307         GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer];
308
309         if (buf >= 0 && att[buf].Renderbuffer) {
310            mask |= 1 << buf;
311         }
312      }
313   }
314
315   return mask;
316}
317
318
319
320/**
321 * New in GL 3.0
322 * Clear signed integer color buffer or stencil buffer (not depth).
323 */
324void GLAPIENTRY
325_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
326{
327   GET_CURRENT_CONTEXT(ctx);
328   FLUSH_VERTICES(ctx, 0);
329
330   FLUSH_CURRENT(ctx, 0);
331
332   if (ctx->NewState) {
333      _mesa_update_state( ctx );
334   }
335
336   switch (buffer) {
337   case GL_STENCIL:
338      /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
339       *
340       *     "ClearBuffer generates an INVALID VALUE error if buffer is
341       *     COLOR and drawbuffer is less than zero, or greater than the
342       *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
343       *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
344       */
345      if (drawbuffer != 0) {
346         _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
347                     drawbuffer);
348         return;
349      }
350      else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer
351               && !ctx->RasterDiscard) {
352         /* Save current stencil clear value, set to 'value', do the
353          * stencil clear and restore the clear value.
354          * XXX in the future we may have a new ctx->Driver.ClearBuffer()
355          * hook instead.
356          */
357         const GLuint clearSave = ctx->Stencil.Clear;
358         ctx->Stencil.Clear = *value;
359         ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL);
360         ctx->Stencil.Clear = clearSave;
361      }
362      break;
363   case GL_COLOR:
364      {
365         const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
366         if (mask == INVALID_MASK) {
367            _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
368                        drawbuffer);
369            return;
370         }
371         else if (mask && !ctx->RasterDiscard) {
372            union gl_color_union clearSave;
373
374            /* save color */
375            clearSave = ctx->Color.ClearColor;
376            /* set color */
377            COPY_4V(ctx->Color.ClearColor.i, value);
378            /* clear buffer(s) */
379            ctx->Driver.Clear(ctx, mask);
380            /* restore color */
381            ctx->Color.ClearColor = clearSave;
382         }
383      }
384      break;
385   default:
386      /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
387       * of the OpenGL 4.5 spec states:
388       *
389       *    "An INVALID_ENUM error is generated by ClearBufferiv and
390       *     ClearNamedFramebufferiv if buffer is not COLOR or STENCIL."
391       */
392      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
393                  _mesa_enum_to_string(buffer));
394      return;
395   }
396}
397
398
399/**
400 * The ClearBuffer framework is so complicated and so riddled with the
401 * assumption that the framebuffer is bound that, for now, we will just fake
402 * direct state access clearing for the user.
403 */
404void GLAPIENTRY
405_mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer,
406                              GLint drawbuffer, const GLint *value)
407{
408   GLint oldfb;
409
410   _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
411   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
412   _mesa_ClearBufferiv(buffer, drawbuffer, value);
413   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
414}
415
416
417/**
418 * New in GL 3.0
419 * Clear unsigned integer color buffer (not depth, not stencil).
420 */
421void GLAPIENTRY
422_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
423{
424   GET_CURRENT_CONTEXT(ctx);
425
426   FLUSH_VERTICES(ctx, 0);
427   FLUSH_CURRENT(ctx, 0);
428
429   if (ctx->NewState) {
430      _mesa_update_state( ctx );
431   }
432
433   switch (buffer) {
434   case GL_COLOR:
435      {
436         const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
437         if (mask == INVALID_MASK) {
438            _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
439                        drawbuffer);
440            return;
441         }
442         else if (mask && !ctx->RasterDiscard) {
443            union gl_color_union clearSave;
444
445            /* save color */
446            clearSave = ctx->Color.ClearColor;
447            /* set color */
448            COPY_4V(ctx->Color.ClearColor.ui, value);
449            /* clear buffer(s) */
450            ctx->Driver.Clear(ctx, mask);
451            /* restore color */
452            ctx->Color.ClearColor = clearSave;
453         }
454      }
455      break;
456   default:
457      /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
458       * of the OpenGL 4.5 spec states:
459       *
460       *    "An INVALID_ENUM error is generated by ClearBufferuiv and
461       *     ClearNamedFramebufferuiv if buffer is not COLOR."
462       */
463      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
464                  _mesa_enum_to_string(buffer));
465      return;
466   }
467}
468
469
470/**
471 * The ClearBuffer framework is so complicated and so riddled with the
472 * assumption that the framebuffer is bound that, for now, we will just fake
473 * direct state access clearing for the user.
474 */
475void GLAPIENTRY
476_mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer,
477                               GLint drawbuffer, const GLuint *value)
478{
479   GLint oldfb;
480
481   _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
482   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
483   _mesa_ClearBufferuiv(buffer, drawbuffer, value);
484   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
485}
486
487
488/**
489 * New in GL 3.0
490 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
491 */
492void GLAPIENTRY
493_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
494{
495   GET_CURRENT_CONTEXT(ctx);
496
497   FLUSH_VERTICES(ctx, 0);
498   FLUSH_CURRENT(ctx, 0);
499
500   if (ctx->NewState) {
501      _mesa_update_state( ctx );
502   }
503
504   switch (buffer) {
505   case GL_DEPTH:
506      /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
507       *
508       *     "ClearBuffer generates an INVALID VALUE error if buffer is
509       *     COLOR and drawbuffer is less than zero, or greater than the
510       *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
511       *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
512       */
513      if (drawbuffer != 0) {
514         _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
515                     drawbuffer);
516         return;
517      }
518      else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer
519               && !ctx->RasterDiscard) {
520         /* Save current depth clear value, set to 'value', do the
521          * depth clear and restore the clear value.
522          * XXX in the future we may have a new ctx->Driver.ClearBuffer()
523          * hook instead.
524          */
525         const GLclampd clearSave = ctx->Depth.Clear;
526         ctx->Depth.Clear = *value;
527         ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH);
528         ctx->Depth.Clear = clearSave;
529      }
530      /* clear depth buffer to value */
531      break;
532   case GL_COLOR:
533      {
534         const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
535         if (mask == INVALID_MASK) {
536            _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
537                        drawbuffer);
538            return;
539         }
540         else if (mask && !ctx->RasterDiscard) {
541            union gl_color_union clearSave;
542
543            /* save color */
544            clearSave = ctx->Color.ClearColor;
545            /* set color */
546            COPY_4V(ctx->Color.ClearColor.f, value);
547            /* clear buffer(s) */
548            ctx->Driver.Clear(ctx, mask);
549            /* restore color */
550            ctx->Color.ClearColor = clearSave;
551         }
552      }
553      break;
554   default:
555      /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
556       * of the OpenGL 4.5 spec states:
557       *
558       *    "An INVALID_ENUM error is generated by ClearBufferfv and
559       *     ClearNamedFramebufferfv if buffer is not COLOR or DEPTH."
560       */
561      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
562                  _mesa_enum_to_string(buffer));
563      return;
564   }
565}
566
567
568/**
569 * The ClearBuffer framework is so complicated and so riddled with the
570 * assumption that the framebuffer is bound that, for now, we will just fake
571 * direct state access clearing for the user.
572 */
573void GLAPIENTRY
574_mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer,
575                              GLint drawbuffer, const GLfloat *value)
576{
577   GLint oldfb;
578
579   _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
580   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
581   _mesa_ClearBufferfv(buffer, drawbuffer, value);
582   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
583}
584
585
586/**
587 * New in GL 3.0
588 * Clear depth/stencil buffer only.
589 */
590void GLAPIENTRY
591_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
592                    GLfloat depth, GLint stencil)
593{
594   GET_CURRENT_CONTEXT(ctx);
595   GLbitfield mask = 0;
596
597   FLUSH_VERTICES(ctx, 0);
598   FLUSH_CURRENT(ctx, 0);
599
600   if (buffer != GL_DEPTH_STENCIL) {
601      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
602                  _mesa_enum_to_string(buffer));
603      return;
604   }
605
606   /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
607    *
608    *     "ClearBuffer generates an INVALID VALUE error if buffer is
609    *     COLOR and drawbuffer is less than zero, or greater than the
610    *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
611    *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
612    */
613   if (drawbuffer != 0) {
614      _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)",
615                  drawbuffer);
616      return;
617   }
618
619   if (ctx->RasterDiscard)
620      return;
621
622   if (ctx->NewState) {
623      _mesa_update_state( ctx );
624   }
625
626   if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer)
627      mask |= BUFFER_BIT_DEPTH;
628   if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer)
629      mask |= BUFFER_BIT_STENCIL;
630
631   if (mask) {
632      /* save current clear values */
633      const GLclampd clearDepthSave = ctx->Depth.Clear;
634      const GLuint clearStencilSave = ctx->Stencil.Clear;
635
636      /* set new clear values */
637      ctx->Depth.Clear = depth;
638      ctx->Stencil.Clear = stencil;
639
640      /* clear buffers */
641      ctx->Driver.Clear(ctx, mask);
642
643      /* restore */
644      ctx->Depth.Clear = clearDepthSave;
645      ctx->Stencil.Clear = clearStencilSave;
646   }
647}
648
649
650/**
651 * The ClearBuffer framework is so complicated and so riddled with the
652 * assumption that the framebuffer is bound that, for now, we will just fake
653 * direct state access clearing for the user.
654 */
655void GLAPIENTRY
656_mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
657                              GLint drawbuffer, GLfloat depth, GLint stencil)
658{
659   GLint oldfb;
660
661   _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
662   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
663   _mesa_ClearBufferfi(buffer, drawbuffer, depth, stencil);
664   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
665}
666