2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
28 * glClearColor, glClearIndex, glClear() functions.
46 _mesa_ClearIndex( GLfloat c
)
48 GET_CURRENT_CONTEXT(ctx
);
49 ASSERT_OUTSIDE_BEGIN_END(ctx
);
51 if (ctx
->Color
.ClearIndex
== (GLuint
) c
)
54 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
55 ctx
->Color
.ClearIndex
= (GLuint
) c
;
61 * Specify the clear values for the color buffers.
63 * \param red red color component.
64 * \param green green color component.
65 * \param blue blue color component.
66 * \param alpha alpha component.
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.
75 _mesa_ClearColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
78 GET_CURRENT_CONTEXT(ctx
);
79 ASSERT_OUTSIDE_BEGIN_END(ctx
);
86 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
.f
))
87 return; /* no change */
89 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
90 COPY_4V(ctx
->Color
.ClearColor
.f
, tmp
);
95 * GL_EXT_texture_integer
98 _mesa_ClearColorIiEXT(GLint r
, GLint g
, GLint b
, GLint a
)
101 GET_CURRENT_CONTEXT(ctx
);
102 ASSERT_OUTSIDE_BEGIN_END(ctx
);
109 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
.i
))
110 return; /* no change */
112 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
113 COPY_4V(ctx
->Color
.ClearColor
.i
, tmp
);
118 * GL_EXT_texture_integer
121 _mesa_ClearColorIuiEXT(GLuint r
, GLuint g
, GLuint b
, GLuint a
)
124 GET_CURRENT_CONTEXT(ctx
);
125 ASSERT_OUTSIDE_BEGIN_END(ctx
);
132 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
.ui
))
133 return; /* no change */
135 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
136 COPY_4V(ctx
->Color
.ClearColor
.ui
, tmp
);
143 * \param mask bit-mask indicating the buffers to be cleared.
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.
151 _mesa_Clear( GLbitfield mask
)
153 GET_CURRENT_CONTEXT(ctx
);
154 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
156 FLUSH_CURRENT(ctx
, 0);
158 if (MESA_VERBOSE
& VERBOSE_API
)
159 _mesa_debug(ctx
, "glClear 0x%x\n", mask
);
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
);
171 _mesa_update_state( ctx
); /* update _Xmin, etc */
174 if (ctx
->DrawBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
175 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
176 "glClear(incomplete framebuffer)");
180 if (ctx
->DrawBuffer
->Width
== 0 || ctx
->DrawBuffer
->Height
== 0 ||
181 ctx
->DrawBuffer
->_Xmin
>= ctx
->DrawBuffer
->_Xmax
||
182 ctx
->DrawBuffer
->_Ymin
>= ctx
->DrawBuffer
->_Ymax
)
185 if (ctx
->RasterDiscard
)
188 if (ctx
->RenderMode
== GL_RENDER
) {
189 GLbitfield bufferMask
;
191 /* don't clear depth buffer if depth writing disabled */
192 if (!ctx
->Depth
.Mask
)
193 mask
&= ~GL_DEPTH_BUFFER_BIT
;
195 /* Build the bitmask to send to device driver's Clear function.
196 * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
197 * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
198 * BUFFER_BIT_COLORn flags.
201 if (mask
& GL_COLOR_BUFFER_BIT
) {
203 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
204 bufferMask
|= (1 << ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[i
]);
208 if ((mask
& GL_DEPTH_BUFFER_BIT
)
209 && ctx
->DrawBuffer
->Visual
.haveDepthBuffer
) {
210 bufferMask
|= BUFFER_BIT_DEPTH
;
213 if ((mask
& GL_STENCIL_BUFFER_BIT
)
214 && ctx
->DrawBuffer
->Visual
.haveStencilBuffer
) {
215 bufferMask
|= BUFFER_BIT_STENCIL
;
218 if ((mask
& GL_ACCUM_BUFFER_BIT
)
219 && ctx
->DrawBuffer
->Visual
.haveAccumBuffer
) {
220 bufferMask
|= BUFFER_BIT_ACCUM
;
223 ASSERT(ctx
->Driver
.Clear
);
224 ctx
->Driver
.Clear(ctx
, bufferMask
);
229 /** Returned by make_color_buffer_mask() for errors */
230 #define INVALID_MASK ~0x0
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.
239 make_color_buffer_mask(struct gl_context
*ctx
, GLint drawbuffer
)
241 const struct gl_renderbuffer_attachment
*att
= ctx
->DrawBuffer
->Attachment
;
242 GLbitfield mask
= 0x0;
244 switch (drawbuffer
) {
246 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
247 mask
|= BUFFER_BIT_FRONT_LEFT
;
248 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
249 mask
|= BUFFER_BIT_FRONT_RIGHT
;
252 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
253 mask
|= BUFFER_BIT_BACK_LEFT
;
254 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
255 mask
|= BUFFER_BIT_BACK_RIGHT
;
258 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
259 mask
|= BUFFER_BIT_FRONT_LEFT
;
260 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
261 mask
|= BUFFER_BIT_BACK_LEFT
;
264 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
265 mask
|= BUFFER_BIT_FRONT_RIGHT
;
266 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
267 mask
|= BUFFER_BIT_BACK_RIGHT
;
269 case GL_FRONT_AND_BACK
:
270 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
271 mask
|= BUFFER_BIT_FRONT_LEFT
;
272 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
273 mask
|= BUFFER_BIT_BACK_LEFT
;
274 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
275 mask
|= BUFFER_BIT_FRONT_RIGHT
;
276 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
277 mask
|= BUFFER_BIT_BACK_RIGHT
;
280 if (drawbuffer
< 0 || drawbuffer
>= (GLint
)ctx
->Const
.MaxDrawBuffers
) {
283 else if (att
[BUFFER_COLOR0
+ drawbuffer
].Renderbuffer
) {
284 mask
|= (BUFFER_BIT_COLOR0
<< drawbuffer
);
295 * Clear signed integer color buffer or stencil buffer (not depth).
298 _mesa_ClearBufferiv(GLenum buffer
, GLint drawbuffer
, const GLint
*value
)
300 GET_CURRENT_CONTEXT(ctx
);
301 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
303 FLUSH_CURRENT(ctx
, 0);
306 _mesa_update_state( ctx
);
311 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
313 * "ClearBuffer generates an INVALID VALUE error if buffer is
314 * COLOR and drawbuffer is less than zero, or greater than the
315 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
316 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
318 if (drawbuffer
!= 0) {
319 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
323 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
&& !ctx
->RasterDiscard
) {
324 /* Save current stencil clear value, set to 'value', do the
325 * stencil clear and restore the clear value.
326 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
329 const GLuint clearSave
= ctx
->Stencil
.Clear
;
330 ctx
->Stencil
.Clear
= *value
;
331 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_STENCIL
);
332 ctx
->Stencil
.Clear
= clearSave
;
337 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
338 if (mask
== INVALID_MASK
) {
339 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
343 else if (mask
&& !ctx
->RasterDiscard
) {
344 union gl_color_union clearSave
;
347 clearSave
= ctx
->Color
.ClearColor
;
349 COPY_4V(ctx
->Color
.ClearColor
.i
, value
);
350 /* clear buffer(s) */
351 ctx
->Driver
.Clear(ctx
, mask
);
353 ctx
->Color
.ClearColor
= clearSave
;
358 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
360 * "The result of ClearBuffer is undefined if no conversion between
361 * the type of the specified value and the type of the buffer being
362 * cleared is defined (for example, if ClearBufferiv is called for a
363 * fixed- or floating-point buffer, or if ClearBufferfv is called
364 * for a signed or unsigned integer buffer). This is not an error."
366 * In this case we take "undefined" and "not an error" to mean "ignore."
367 * Note that we still need to generate an error for the invalid
368 * drawbuffer case (see the GL_STENCIL case above).
370 if (drawbuffer
!= 0) {
371 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
377 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferiv(buffer=%s)",
378 _mesa_lookup_enum_by_nr(buffer
));
386 * Clear unsigned integer color buffer (not depth, not stencil).
389 _mesa_ClearBufferuiv(GLenum buffer
, GLint drawbuffer
, const GLuint
*value
)
391 GET_CURRENT_CONTEXT(ctx
);
392 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
394 FLUSH_CURRENT(ctx
, 0);
397 _mesa_update_state( ctx
);
403 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
404 if (mask
== INVALID_MASK
) {
405 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
409 else if (mask
&& !ctx
->RasterDiscard
) {
410 union gl_color_union clearSave
;
413 clearSave
= ctx
->Color
.ClearColor
;
415 COPY_4V(ctx
->Color
.ClearColor
.ui
, value
);
416 /* clear buffer(s) */
417 ctx
->Driver
.Clear(ctx
, mask
);
419 ctx
->Color
.ClearColor
= clearSave
;
425 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
427 * "The result of ClearBuffer is undefined if no conversion between
428 * the type of the specified value and the type of the buffer being
429 * cleared is defined (for example, if ClearBufferiv is called for a
430 * fixed- or floating-point buffer, or if ClearBufferfv is called
431 * for a signed or unsigned integer buffer). This is not an error."
433 * In this case we take "undefined" and "not an error" to mean "ignore."
434 * Even though we could do something sensible for GL_STENCIL, page 263
435 * (page 279 of the PDF) says:
437 * "Only ClearBufferiv should be used to clear stencil buffers."
439 * Note that we still need to generate an error for the invalid
440 * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
442 if (drawbuffer
!= 0) {
443 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
449 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferuiv(buffer=%s)",
450 _mesa_lookup_enum_by_nr(buffer
));
458 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
461 _mesa_ClearBufferfv(GLenum buffer
, GLint drawbuffer
, const GLfloat
*value
)
463 GET_CURRENT_CONTEXT(ctx
);
464 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
466 FLUSH_CURRENT(ctx
, 0);
469 _mesa_update_state( ctx
);
474 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
476 * "ClearBuffer generates an INVALID VALUE error if buffer is
477 * COLOR and drawbuffer is less than zero, or greater than the
478 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
479 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
481 if (drawbuffer
!= 0) {
482 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
486 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
&& !ctx
->RasterDiscard
) {
487 /* Save current depth clear value, set to 'value', do the
488 * depth clear and restore the clear value.
489 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
492 const GLclampd clearSave
= ctx
->Depth
.Clear
;
493 ctx
->Depth
.Clear
= *value
;
494 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_DEPTH
);
495 ctx
->Depth
.Clear
= clearSave
;
497 /* clear depth buffer to value */
501 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
502 if (mask
== INVALID_MASK
) {
503 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
507 else if (mask
&& !ctx
->RasterDiscard
) {
508 union gl_color_union clearSave
;
511 clearSave
= ctx
->Color
.ClearColor
;
513 COPY_4V_CAST(ctx
->Color
.ClearColor
.f
, value
, GLclampf
);
514 /* clear buffer(s) */
515 ctx
->Driver
.Clear(ctx
, mask
);
517 ctx
->Color
.ClearColor
= clearSave
;
522 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
524 * "The result of ClearBuffer is undefined if no conversion between
525 * the type of the specified value and the type of the buffer being
526 * cleared is defined (for example, if ClearBufferiv is called for a
527 * fixed- or floating-point buffer, or if ClearBufferfv is called
528 * for a signed or unsigned integer buffer). This is not an error."
530 * In this case we take "undefined" and "not an error" to mean "ignore."
531 * Note that we still need to generate an error for the invalid
532 * drawbuffer case (see the GL_DEPTH case above).
534 if (drawbuffer
!= 0) {
535 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
541 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfv(buffer=%s)",
542 _mesa_lookup_enum_by_nr(buffer
));
550 * Clear depth/stencil buffer only.
553 _mesa_ClearBufferfi(GLenum buffer
, GLint drawbuffer
,
554 GLfloat depth
, GLint stencil
)
556 GET_CURRENT_CONTEXT(ctx
);
559 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
561 FLUSH_CURRENT(ctx
, 0);
563 if (buffer
!= GL_DEPTH_STENCIL
) {
564 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfi(buffer=%s)",
565 _mesa_lookup_enum_by_nr(buffer
));
569 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
571 * "ClearBuffer generates an INVALID VALUE error if buffer is
572 * COLOR and drawbuffer is less than zero, or greater than the
573 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
574 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
576 if (drawbuffer
!= 0) {
577 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfi(drawbuffer=%d)",
582 if (ctx
->RasterDiscard
)
586 _mesa_update_state( ctx
);
589 if (ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)
590 mask
|= BUFFER_BIT_DEPTH
;
591 if (ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)
592 mask
|= BUFFER_BIT_STENCIL
;
595 /* save current clear values */
596 const GLclampd clearDepthSave
= ctx
->Depth
.Clear
;
597 const GLuint clearStencilSave
= ctx
->Stencil
.Clear
;
599 /* set new clear values */
600 ctx
->Depth
.Clear
= depth
;
601 ctx
->Stencil
.Clear
= stencil
;
604 ctx
->Driver
.Clear(ctx
, mask
);
607 ctx
->Depth
.Clear
= clearDepthSave
;
608 ctx
->Stencil
.Clear
= clearStencilSave
;