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