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