mesa: print the invalid enum when CreateShader fails
[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 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 */
142 void 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 */
238 static GLbitfield
239 make_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 if (att[BUFFER_BACK_LEFT].Renderbuffer)
271 mask |= BUFFER_BIT_BACK_LEFT;
272 if (att[BUFFER_BACK_RIGHT].Renderbuffer)
273 mask |= BUFFER_BIT_BACK_RIGHT;
274 break;
275 case GL_LEFT:
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 break;
281 case GL_RIGHT:
282 if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
283 mask |= BUFFER_BIT_FRONT_RIGHT;
284 if (att[BUFFER_BACK_RIGHT].Renderbuffer)
285 mask |= BUFFER_BIT_BACK_RIGHT;
286 break;
287 case GL_FRONT_AND_BACK:
288 if (att[BUFFER_FRONT_LEFT].Renderbuffer)
289 mask |= BUFFER_BIT_FRONT_LEFT;
290 if (att[BUFFER_BACK_LEFT].Renderbuffer)
291 mask |= BUFFER_BIT_BACK_LEFT;
292 if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
293 mask |= BUFFER_BIT_FRONT_RIGHT;
294 if (att[BUFFER_BACK_RIGHT].Renderbuffer)
295 mask |= BUFFER_BIT_BACK_RIGHT;
296 break;
297 default:
298 {
299 GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer];
300
301 if (buf >= 0 && att[buf].Renderbuffer) {
302 mask |= 1 << buf;
303 }
304 }
305 }
306
307 return mask;
308 }
309
310
311
312 /**
313 * New in GL 3.0
314 * Clear signed integer color buffer or stencil buffer (not depth).
315 */
316 void GLAPIENTRY
317 _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
318 {
319 GET_CURRENT_CONTEXT(ctx);
320 FLUSH_VERTICES(ctx, 0);
321
322 FLUSH_CURRENT(ctx, 0);
323
324 if (ctx->NewState) {
325 _mesa_update_state( ctx );
326 }
327
328 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
329 * of the OpenGL 4.5 spec states:
330 *
331 * "An INVALID_ENUM error is generated by ClearBufferiv and
332 * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL."
333 */
334 if (buffer == GL_DEPTH || buffer == GL_DEPTH_STENCIL) {
335 _mesa_error(ctx, GL_INVALID_ENUM,
336 "glClearBufferiv(buffer=GL_DEPTH || GL_DEPTH_STENCIL)");
337 return;
338 }
339
340 switch (buffer) {
341 case GL_STENCIL:
342 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
343 *
344 * "ClearBuffer generates an INVALID VALUE error if buffer is
345 * COLOR and drawbuffer is less than zero, or greater than the
346 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
347 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
348 */
349 if (drawbuffer != 0) {
350 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
351 drawbuffer);
352 return;
353 }
354 else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer
355 && !ctx->RasterDiscard) {
356 /* Save current stencil clear value, set to 'value', do the
357 * stencil clear and restore the clear value.
358 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
359 * hook instead.
360 */
361 const GLuint clearSave = ctx->Stencil.Clear;
362 ctx->Stencil.Clear = *value;
363 ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL);
364 ctx->Stencil.Clear = clearSave;
365 }
366 break;
367 case GL_COLOR:
368 {
369 const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
370 if (mask == INVALID_MASK) {
371 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
372 drawbuffer);
373 return;
374 }
375 else if (mask && !ctx->RasterDiscard) {
376 union gl_color_union clearSave;
377
378 /* save color */
379 clearSave = ctx->Color.ClearColor;
380 /* set color */
381 COPY_4V(ctx->Color.ClearColor.i, value);
382 /* clear buffer(s) */
383 ctx->Driver.Clear(ctx, mask);
384 /* restore color */
385 ctx->Color.ClearColor = clearSave;
386 }
387 }
388 break;
389 case GL_DEPTH:
390 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
391 *
392 * "The result of ClearBuffer is undefined if no conversion between
393 * the type of the specified value and the type of the buffer being
394 * cleared is defined (for example, if ClearBufferiv is called for a
395 * fixed- or floating-point buffer, or if ClearBufferfv is called
396 * for a signed or unsigned integer buffer). This is not an error."
397 *
398 * In this case we take "undefined" and "not an error" to mean "ignore."
399 * Note that we still need to generate an error for the invalid
400 * drawbuffer case (see the GL_STENCIL case above).
401 */
402 if (drawbuffer != 0) {
403 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
404 drawbuffer);
405 return;
406 }
407 return;
408 default:
409 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
410 _mesa_enum_to_string(buffer));
411 return;
412 }
413 }
414
415
416 /**
417 * The ClearBuffer framework is so complicated and so riddled with the
418 * assumption that the framebuffer is bound that, for now, we will just fake
419 * direct state access clearing for the user.
420 */
421 void GLAPIENTRY
422 _mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer,
423 GLint drawbuffer, const GLint *value)
424 {
425 GLint oldfb;
426
427 _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
428 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
429 _mesa_ClearBufferiv(buffer, drawbuffer, value);
430 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
431 }
432
433
434 /**
435 * New in GL 3.0
436 * Clear unsigned integer color buffer (not depth, not stencil).
437 */
438 void GLAPIENTRY
439 _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
440 {
441 GET_CURRENT_CONTEXT(ctx);
442
443 FLUSH_VERTICES(ctx, 0);
444 FLUSH_CURRENT(ctx, 0);
445
446 if (ctx->NewState) {
447 _mesa_update_state( ctx );
448 }
449
450 switch (buffer) {
451 case GL_COLOR:
452 {
453 const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
454 if (mask == INVALID_MASK) {
455 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
456 drawbuffer);
457 return;
458 }
459 else if (mask && !ctx->RasterDiscard) {
460 union gl_color_union clearSave;
461
462 /* save color */
463 clearSave = ctx->Color.ClearColor;
464 /* set color */
465 COPY_4V(ctx->Color.ClearColor.ui, value);
466 /* clear buffer(s) */
467 ctx->Driver.Clear(ctx, mask);
468 /* restore color */
469 ctx->Color.ClearColor = clearSave;
470 }
471 }
472 break;
473 case GL_DEPTH:
474 case GL_STENCIL:
475 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
476 *
477 * "The result of ClearBuffer is undefined if no conversion between
478 * the type of the specified value and the type of the buffer being
479 * cleared is defined (for example, if ClearBufferiv is called for a
480 * fixed- or floating-point buffer, or if ClearBufferfv is called
481 * for a signed or unsigned integer buffer). This is not an error."
482 *
483 * In this case we take "undefined" and "not an error" to mean "ignore."
484 * Even though we could do something sensible for GL_STENCIL, page 263
485 * (page 279 of the PDF) says:
486 *
487 * "Only ClearBufferiv should be used to clear stencil buffers."
488 *
489 * Note that we still need to generate an error for the invalid
490 * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
491 */
492 if (drawbuffer != 0) {
493 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
494 drawbuffer);
495 return;
496 }
497 return;
498 default:
499 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
500 _mesa_enum_to_string(buffer));
501 return;
502 }
503 }
504
505
506 /**
507 * The ClearBuffer framework is so complicated and so riddled with the
508 * assumption that the framebuffer is bound that, for now, we will just fake
509 * direct state access clearing for the user.
510 */
511 void GLAPIENTRY
512 _mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer,
513 GLint drawbuffer, const GLuint *value)
514 {
515 GLint oldfb;
516
517 _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
518 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
519 _mesa_ClearBufferuiv(buffer, drawbuffer, value);
520 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
521 }
522
523
524 /**
525 * New in GL 3.0
526 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
527 */
528 void GLAPIENTRY
529 _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
530 {
531 GET_CURRENT_CONTEXT(ctx);
532
533 FLUSH_VERTICES(ctx, 0);
534 FLUSH_CURRENT(ctx, 0);
535
536 if (ctx->NewState) {
537 _mesa_update_state( ctx );
538 }
539
540 switch (buffer) {
541 case GL_DEPTH:
542 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
543 *
544 * "ClearBuffer generates an INVALID VALUE error if buffer is
545 * COLOR and drawbuffer is less than zero, or greater than the
546 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
547 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
548 */
549 if (drawbuffer != 0) {
550 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
551 drawbuffer);
552 return;
553 }
554 else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer
555 && !ctx->RasterDiscard) {
556 /* Save current depth clear value, set to 'value', do the
557 * depth clear and restore the clear value.
558 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
559 * hook instead.
560 */
561 const GLclampd clearSave = ctx->Depth.Clear;
562 ctx->Depth.Clear = *value;
563 ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH);
564 ctx->Depth.Clear = clearSave;
565 }
566 /* clear depth buffer to value */
567 break;
568 case GL_COLOR:
569 {
570 const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
571 if (mask == INVALID_MASK) {
572 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
573 drawbuffer);
574 return;
575 }
576 else if (mask && !ctx->RasterDiscard) {
577 union gl_color_union clearSave;
578
579 /* save color */
580 clearSave = ctx->Color.ClearColor;
581 /* set color */
582 COPY_4V(ctx->Color.ClearColor.f, value);
583 /* clear buffer(s) */
584 ctx->Driver.Clear(ctx, mask);
585 /* restore color */
586 ctx->Color.ClearColor = clearSave;
587 }
588 }
589 break;
590 case GL_STENCIL:
591 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
592 *
593 * "The result of ClearBuffer is undefined if no conversion between
594 * the type of the specified value and the type of the buffer being
595 * cleared is defined (for example, if ClearBufferiv is called for a
596 * fixed- or floating-point buffer, or if ClearBufferfv is called
597 * for a signed or unsigned integer buffer). This is not an error."
598 *
599 * In this case we take "undefined" and "not an error" to mean "ignore."
600 * Note that we still need to generate an error for the invalid
601 * drawbuffer case (see the GL_DEPTH case above).
602 */
603 if (drawbuffer != 0) {
604 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
605 drawbuffer);
606 return;
607 }
608 return;
609 default:
610 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
611 _mesa_enum_to_string(buffer));
612 return;
613 }
614 }
615
616
617 /**
618 * The ClearBuffer framework is so complicated and so riddled with the
619 * assumption that the framebuffer is bound that, for now, we will just fake
620 * direct state access clearing for the user.
621 */
622 void GLAPIENTRY
623 _mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer,
624 GLint drawbuffer, const GLfloat *value)
625 {
626 GLint oldfb;
627
628 _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
629 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
630 _mesa_ClearBufferfv(buffer, drawbuffer, value);
631 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
632 }
633
634
635 /**
636 * New in GL 3.0
637 * Clear depth/stencil buffer only.
638 */
639 void GLAPIENTRY
640 _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
641 GLfloat depth, GLint stencil)
642 {
643 GET_CURRENT_CONTEXT(ctx);
644 GLbitfield mask = 0;
645
646 FLUSH_VERTICES(ctx, 0);
647 FLUSH_CURRENT(ctx, 0);
648
649 if (buffer != GL_DEPTH_STENCIL) {
650 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
651 _mesa_enum_to_string(buffer));
652 return;
653 }
654
655 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
656 *
657 * "ClearBuffer generates an INVALID VALUE error if buffer is
658 * COLOR and drawbuffer is less than zero, or greater than the
659 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
660 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
661 */
662 if (drawbuffer != 0) {
663 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)",
664 drawbuffer);
665 return;
666 }
667
668 if (ctx->RasterDiscard)
669 return;
670
671 if (ctx->NewState) {
672 _mesa_update_state( ctx );
673 }
674
675 if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer)
676 mask |= BUFFER_BIT_DEPTH;
677 if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer)
678 mask |= BUFFER_BIT_STENCIL;
679
680 if (mask) {
681 /* save current clear values */
682 const GLclampd clearDepthSave = ctx->Depth.Clear;
683 const GLuint clearStencilSave = ctx->Stencil.Clear;
684
685 /* set new clear values */
686 ctx->Depth.Clear = depth;
687 ctx->Stencil.Clear = stencil;
688
689 /* clear buffers */
690 ctx->Driver.Clear(ctx, mask);
691
692 /* restore */
693 ctx->Depth.Clear = clearDepthSave;
694 ctx->Stencil.Clear = clearStencilSave;
695 }
696 }
697
698
699 /**
700 * The ClearBuffer framework is so complicated and so riddled with the
701 * assumption that the framebuffer is bound that, for now, we will just fake
702 * direct state access clearing for the user.
703 */
704 void GLAPIENTRY
705 _mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
706 GLfloat depth, GLint stencil)
707 {
708 GLint oldfb;
709
710 _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
711 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
712 _mesa_ClearBufferfi(buffer, 0, depth, stencil);
713 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
714 }