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.
45 _mesa_ClearIndex( GLfloat c
)
47 GET_CURRENT_CONTEXT(ctx
);
48 ASSERT_OUTSIDE_BEGIN_END(ctx
);
50 if (ctx
->Color
.ClearIndex
== (GLuint
) c
)
53 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
54 ctx
->Color
.ClearIndex
= (GLuint
) c
;
59 * Specify the clear values for the color buffers.
61 * \param red red color component.
62 * \param green green color component.
63 * \param blue blue color component.
64 * \param alpha alpha component.
68 * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a
69 * change, flushes the vertices and notifies the driver via the
70 * dd_function_table::ClearColor callback.
73 _mesa_ClearColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
76 GET_CURRENT_CONTEXT(ctx
);
77 ASSERT_OUTSIDE_BEGIN_END(ctx
);
84 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
.f
))
85 return; /* no change */
87 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
88 COPY_4V(ctx
->Color
.ClearColor
.f
, tmp
);
93 * GL_EXT_texture_integer
96 _mesa_ClearColorIiEXT(GLint r
, GLint g
, GLint b
, GLint a
)
99 GET_CURRENT_CONTEXT(ctx
);
100 ASSERT_OUTSIDE_BEGIN_END(ctx
);
107 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
.i
))
108 return; /* no change */
110 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
111 COPY_4V(ctx
->Color
.ClearColor
.i
, tmp
);
116 * GL_EXT_texture_integer
119 _mesa_ClearColorIuiEXT(GLuint r
, GLuint g
, GLuint b
, GLuint a
)
122 GET_CURRENT_CONTEXT(ctx
);
123 ASSERT_OUTSIDE_BEGIN_END(ctx
);
130 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
.ui
))
131 return; /* no change */
133 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
134 COPY_4V(ctx
->Color
.ClearColor
.ui
, tmp
);
141 * \param mask bit-mask indicating the buffers to be cleared.
143 * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState
144 * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin,
145 * etc. If the rasterization mode is set to GL_RENDER then requests the driver
146 * to clear the buffers, via the dd_function_table::Clear callback.
149 _mesa_Clear( GLbitfield mask
)
151 GET_CURRENT_CONTEXT(ctx
);
152 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
154 FLUSH_CURRENT(ctx
, 0);
156 if (MESA_VERBOSE
& VERBOSE_API
)
157 _mesa_debug(ctx
, "glClear 0x%x\n", mask
);
159 if (mask
& ~(GL_COLOR_BUFFER_BIT
|
160 GL_DEPTH_BUFFER_BIT
|
161 GL_STENCIL_BUFFER_BIT
|
162 GL_ACCUM_BUFFER_BIT
)) {
163 /* invalid bit set */
164 _mesa_error( ctx
, GL_INVALID_VALUE
, "glClear(0x%x)", mask
);
168 /* Accumulation buffers were removed in core contexts, and they never
169 * existed in OpenGL ES.
171 if ((mask
& GL_ACCUM_BUFFER_BIT
) != 0
172 && (ctx
->API
== API_OPENGL_CORE
|| _mesa_is_gles(ctx
))) {
173 _mesa_error( ctx
, GL_INVALID_VALUE
, "glClear(GL_ACCUM_BUFFER_BIT)");
178 _mesa_update_state( ctx
); /* update _Xmin, etc */
181 if (ctx
->DrawBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
182 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
183 "glClear(incomplete framebuffer)");
187 if (ctx
->DrawBuffer
->Width
== 0 || ctx
->DrawBuffer
->Height
== 0 ||
188 ctx
->DrawBuffer
->_Xmin
>= ctx
->DrawBuffer
->_Xmax
||
189 ctx
->DrawBuffer
->_Ymin
>= ctx
->DrawBuffer
->_Ymax
)
192 if (ctx
->RasterDiscard
)
195 if (ctx
->RenderMode
== GL_RENDER
) {
196 GLbitfield bufferMask
;
198 /* don't clear depth buffer if depth writing disabled */
199 if (!ctx
->Depth
.Mask
)
200 mask
&= ~GL_DEPTH_BUFFER_BIT
;
202 /* Build the bitmask to send to device driver's Clear function.
203 * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
204 * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
205 * BUFFER_BIT_COLORn flags.
208 if (mask
& GL_COLOR_BUFFER_BIT
) {
210 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
211 bufferMask
|= (1 << ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[i
]);
215 if ((mask
& GL_DEPTH_BUFFER_BIT
)
216 && ctx
->DrawBuffer
->Visual
.haveDepthBuffer
) {
217 bufferMask
|= BUFFER_BIT_DEPTH
;
220 if ((mask
& GL_STENCIL_BUFFER_BIT
)
221 && ctx
->DrawBuffer
->Visual
.haveStencilBuffer
) {
222 bufferMask
|= BUFFER_BIT_STENCIL
;
225 if ((mask
& GL_ACCUM_BUFFER_BIT
)
226 && ctx
->DrawBuffer
->Visual
.haveAccumBuffer
) {
227 bufferMask
|= BUFFER_BIT_ACCUM
;
230 ASSERT(ctx
->Driver
.Clear
);
231 ctx
->Driver
.Clear(ctx
, bufferMask
);
236 /** Returned by make_color_buffer_mask() for errors */
237 #define INVALID_MASK ~0x0
241 * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
242 * BUFFER_BIT_x values.
243 * Return INVALID_MASK if the drawbuffer value is invalid.
246 make_color_buffer_mask(struct gl_context
*ctx
, GLint drawbuffer
)
248 const struct gl_renderbuffer_attachment
*att
= ctx
->DrawBuffer
->Attachment
;
249 GLbitfield mask
= 0x0;
251 switch (drawbuffer
) {
253 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
254 mask
|= BUFFER_BIT_FRONT_LEFT
;
255 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
256 mask
|= BUFFER_BIT_FRONT_RIGHT
;
259 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
260 mask
|= BUFFER_BIT_BACK_LEFT
;
261 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
262 mask
|= BUFFER_BIT_BACK_RIGHT
;
265 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
266 mask
|= BUFFER_BIT_FRONT_LEFT
;
267 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
268 mask
|= BUFFER_BIT_BACK_LEFT
;
271 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
272 mask
|= BUFFER_BIT_FRONT_RIGHT
;
273 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
274 mask
|= BUFFER_BIT_BACK_RIGHT
;
276 case GL_FRONT_AND_BACK
:
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_FRONT_RIGHT
].Renderbuffer
)
282 mask
|= BUFFER_BIT_FRONT_RIGHT
;
283 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
284 mask
|= BUFFER_BIT_BACK_RIGHT
;
287 if (drawbuffer
< 0 || drawbuffer
>= (GLint
)ctx
->Const
.MaxDrawBuffers
) {
290 else if (att
[BUFFER_COLOR0
+ drawbuffer
].Renderbuffer
) {
291 mask
|= (BUFFER_BIT_COLOR0
<< drawbuffer
);
302 * Clear signed integer color buffer or stencil buffer (not depth).
305 _mesa_ClearBufferiv(GLenum buffer
, GLint drawbuffer
, const GLint
*value
)
307 GET_CURRENT_CONTEXT(ctx
);
308 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
310 FLUSH_CURRENT(ctx
, 0);
313 _mesa_update_state( ctx
);
318 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
320 * "ClearBuffer generates an INVALID VALUE error if buffer is
321 * COLOR and drawbuffer is less than zero, or greater than the
322 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
323 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
325 if (drawbuffer
!= 0) {
326 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
330 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
&& !ctx
->RasterDiscard
) {
331 /* Save current stencil clear value, set to 'value', do the
332 * stencil clear and restore the clear value.
333 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
336 const GLuint clearSave
= ctx
->Stencil
.Clear
;
337 ctx
->Stencil
.Clear
= *value
;
338 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_STENCIL
);
339 ctx
->Stencil
.Clear
= clearSave
;
344 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
345 if (mask
== INVALID_MASK
) {
346 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
350 else if (mask
&& !ctx
->RasterDiscard
) {
351 union gl_color_union clearSave
;
354 clearSave
= ctx
->Color
.ClearColor
;
356 COPY_4V(ctx
->Color
.ClearColor
.i
, value
);
357 /* clear buffer(s) */
358 ctx
->Driver
.Clear(ctx
, mask
);
360 ctx
->Color
.ClearColor
= clearSave
;
365 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
367 * "The result of ClearBuffer is undefined if no conversion between
368 * the type of the specified value and the type of the buffer being
369 * cleared is defined (for example, if ClearBufferiv is called for a
370 * fixed- or floating-point buffer, or if ClearBufferfv is called
371 * for a signed or unsigned integer buffer). This is not an error."
373 * In this case we take "undefined" and "not an error" to mean "ignore."
374 * Note that we still need to generate an error for the invalid
375 * drawbuffer case (see the GL_STENCIL case above).
377 if (drawbuffer
!= 0) {
378 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
384 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferiv(buffer=%s)",
385 _mesa_lookup_enum_by_nr(buffer
));
393 * Clear unsigned integer color buffer (not depth, not stencil).
396 _mesa_ClearBufferuiv(GLenum buffer
, GLint drawbuffer
, const GLuint
*value
)
398 GET_CURRENT_CONTEXT(ctx
);
399 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
401 FLUSH_CURRENT(ctx
, 0);
404 _mesa_update_state( ctx
);
410 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
411 if (mask
== INVALID_MASK
) {
412 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
416 else if (mask
&& !ctx
->RasterDiscard
) {
417 union gl_color_union clearSave
;
420 clearSave
= ctx
->Color
.ClearColor
;
422 COPY_4V(ctx
->Color
.ClearColor
.ui
, value
);
423 /* clear buffer(s) */
424 ctx
->Driver
.Clear(ctx
, mask
);
426 ctx
->Color
.ClearColor
= clearSave
;
432 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
434 * "The result of ClearBuffer is undefined if no conversion between
435 * the type of the specified value and the type of the buffer being
436 * cleared is defined (for example, if ClearBufferiv is called for a
437 * fixed- or floating-point buffer, or if ClearBufferfv is called
438 * for a signed or unsigned integer buffer). This is not an error."
440 * In this case we take "undefined" and "not an error" to mean "ignore."
441 * Even though we could do something sensible for GL_STENCIL, page 263
442 * (page 279 of the PDF) says:
444 * "Only ClearBufferiv should be used to clear stencil buffers."
446 * Note that we still need to generate an error for the invalid
447 * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
449 if (drawbuffer
!= 0) {
450 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
456 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferuiv(buffer=%s)",
457 _mesa_lookup_enum_by_nr(buffer
));
465 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
468 _mesa_ClearBufferfv(GLenum buffer
, GLint drawbuffer
, const GLfloat
*value
)
470 GET_CURRENT_CONTEXT(ctx
);
471 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
473 FLUSH_CURRENT(ctx
, 0);
476 _mesa_update_state( ctx
);
481 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
483 * "ClearBuffer generates an INVALID VALUE error if buffer is
484 * COLOR and drawbuffer is less than zero, or greater than the
485 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
486 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
488 if (drawbuffer
!= 0) {
489 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
493 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
&& !ctx
->RasterDiscard
) {
494 /* Save current depth clear value, set to 'value', do the
495 * depth clear and restore the clear value.
496 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
499 const GLclampd clearSave
= ctx
->Depth
.Clear
;
500 ctx
->Depth
.Clear
= *value
;
501 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_DEPTH
);
502 ctx
->Depth
.Clear
= clearSave
;
504 /* clear depth buffer to value */
508 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
509 if (mask
== INVALID_MASK
) {
510 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
514 else if (mask
&& !ctx
->RasterDiscard
) {
515 union gl_color_union clearSave
;
518 clearSave
= ctx
->Color
.ClearColor
;
520 COPY_4V(ctx
->Color
.ClearColor
.f
, value
);
521 /* clear buffer(s) */
522 ctx
->Driver
.Clear(ctx
, mask
);
524 ctx
->Color
.ClearColor
= clearSave
;
529 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
531 * "The result of ClearBuffer is undefined if no conversion between
532 * the type of the specified value and the type of the buffer being
533 * cleared is defined (for example, if ClearBufferiv is called for a
534 * fixed- or floating-point buffer, or if ClearBufferfv is called
535 * for a signed or unsigned integer buffer). This is not an error."
537 * In this case we take "undefined" and "not an error" to mean "ignore."
538 * Note that we still need to generate an error for the invalid
539 * drawbuffer case (see the GL_DEPTH case above).
541 if (drawbuffer
!= 0) {
542 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
548 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfv(buffer=%s)",
549 _mesa_lookup_enum_by_nr(buffer
));
557 * Clear depth/stencil buffer only.
560 _mesa_ClearBufferfi(GLenum buffer
, GLint drawbuffer
,
561 GLfloat depth
, GLint stencil
)
563 GET_CURRENT_CONTEXT(ctx
);
566 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
568 FLUSH_CURRENT(ctx
, 0);
570 if (buffer
!= GL_DEPTH_STENCIL
) {
571 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfi(buffer=%s)",
572 _mesa_lookup_enum_by_nr(buffer
));
576 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
578 * "ClearBuffer generates an INVALID VALUE error if buffer is
579 * COLOR and drawbuffer is less than zero, or greater than the
580 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
581 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
583 if (drawbuffer
!= 0) {
584 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfi(drawbuffer=%d)",
589 if (ctx
->RasterDiscard
)
593 _mesa_update_state( ctx
);
596 if (ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)
597 mask
|= BUFFER_BIT_DEPTH
;
598 if (ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)
599 mask
|= BUFFER_BIT_STENCIL
;
602 /* save current clear values */
603 const GLclampd clearDepthSave
= ctx
->Depth
.Clear
;
604 const GLuint clearStencilSave
= ctx
->Stencil
.Clear
;
606 /* set new clear values */
607 ctx
->Depth
.Clear
= depth
;
608 ctx
->Stencil
.Clear
= stencil
;
611 ctx
->Driver
.Clear(ctx
, mask
);
614 ctx
->Depth
.Clear
= clearDepthSave
;
615 ctx
->Stencil
.Clear
= clearStencilSave
;