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
);
49 if (ctx
->Color
.ClearIndex
== (GLuint
) c
)
52 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
53 ctx
->Color
.ClearIndex
= (GLuint
) c
;
58 * Specify the clear values for the color buffers.
60 * \param red red color component.
61 * \param green green color component.
62 * \param blue blue color component.
63 * \param alpha alpha component.
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.
72 _mesa_ClearColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
75 GET_CURRENT_CONTEXT(ctx
);
82 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
.f
))
83 return; /* no change */
85 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
86 COPY_4V(ctx
->Color
.ClearColor
.f
, tmp
);
91 * GL_EXT_texture_integer
94 _mesa_ClearColorIiEXT(GLint r
, GLint g
, GLint b
, GLint a
)
97 GET_CURRENT_CONTEXT(ctx
);
104 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
.i
))
105 return; /* no change */
107 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
108 COPY_4V(ctx
->Color
.ClearColor
.i
, tmp
);
113 * GL_EXT_texture_integer
116 _mesa_ClearColorIuiEXT(GLuint r
, GLuint g
, GLuint b
, GLuint a
)
119 GET_CURRENT_CONTEXT(ctx
);
126 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
.ui
))
127 return; /* no change */
129 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
130 COPY_4V(ctx
->Color
.ClearColor
.ui
, tmp
);
137 * \param mask bit-mask indicating the buffers to be cleared.
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.
145 _mesa_Clear( GLbitfield mask
)
147 GET_CURRENT_CONTEXT(ctx
);
148 FLUSH_VERTICES(ctx
, 0);
150 FLUSH_CURRENT(ctx
, 0);
152 if (MESA_VERBOSE
& VERBOSE_API
)
153 _mesa_debug(ctx
, "glClear 0x%x\n", mask
);
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
);
164 /* Accumulation buffers were removed in core contexts, and they never
165 * existed in OpenGL ES.
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)");
174 _mesa_update_state( ctx
); /* update _Xmin, etc */
177 if (ctx
->DrawBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
178 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
179 "glClear(incomplete framebuffer)");
183 if (ctx
->DrawBuffer
->Width
== 0 || ctx
->DrawBuffer
->Height
== 0 ||
184 ctx
->DrawBuffer
->_Xmin
>= ctx
->DrawBuffer
->_Xmax
||
185 ctx
->DrawBuffer
->_Ymin
>= ctx
->DrawBuffer
->_Ymax
)
188 if (ctx
->RasterDiscard
)
191 if (ctx
->RenderMode
== GL_RENDER
) {
192 GLbitfield bufferMask
;
194 /* don't clear depth buffer if depth writing disabled */
195 if (!ctx
->Depth
.Mask
)
196 mask
&= ~GL_DEPTH_BUFFER_BIT
;
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.
204 if (mask
& GL_COLOR_BUFFER_BIT
) {
206 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
207 bufferMask
|= (1 << ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[i
]);
211 if ((mask
& GL_DEPTH_BUFFER_BIT
)
212 && ctx
->DrawBuffer
->Visual
.haveDepthBuffer
) {
213 bufferMask
|= BUFFER_BIT_DEPTH
;
216 if ((mask
& GL_STENCIL_BUFFER_BIT
)
217 && ctx
->DrawBuffer
->Visual
.haveStencilBuffer
) {
218 bufferMask
|= BUFFER_BIT_STENCIL
;
221 if ((mask
& GL_ACCUM_BUFFER_BIT
)
222 && ctx
->DrawBuffer
->Visual
.haveAccumBuffer
) {
223 bufferMask
|= BUFFER_BIT_ACCUM
;
226 ASSERT(ctx
->Driver
.Clear
);
227 ctx
->Driver
.Clear(ctx
, bufferMask
);
232 /** Returned by make_color_buffer_mask() for errors */
233 #define INVALID_MASK ~0x0
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.
242 make_color_buffer_mask(struct gl_context
*ctx
, GLint drawbuffer
)
244 const struct gl_renderbuffer_attachment
*att
= ctx
->DrawBuffer
->Attachment
;
245 GLbitfield mask
= 0x0;
247 switch (drawbuffer
) {
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
;
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
;
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
;
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
;
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
;
283 if (drawbuffer
< 0 || drawbuffer
>= (GLint
)ctx
->Const
.MaxDrawBuffers
) {
286 else if (att
[BUFFER_COLOR0
+ drawbuffer
].Renderbuffer
) {
287 mask
|= (BUFFER_BIT_COLOR0
<< drawbuffer
);
298 * Clear signed integer color buffer or stencil buffer (not depth).
301 _mesa_ClearBufferiv(GLenum buffer
, GLint drawbuffer
, const GLint
*value
)
303 GET_CURRENT_CONTEXT(ctx
);
304 FLUSH_VERTICES(ctx
, 0);
306 FLUSH_CURRENT(ctx
, 0);
309 _mesa_update_state( ctx
);
314 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
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."
321 if (drawbuffer
!= 0) {
322 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
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()
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
;
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)",
346 else if (mask
&& !ctx
->RasterDiscard
) {
347 union gl_color_union clearSave
;
350 clearSave
= ctx
->Color
.ClearColor
;
352 COPY_4V(ctx
->Color
.ClearColor
.i
, value
);
353 /* clear buffer(s) */
354 ctx
->Driver
.Clear(ctx
, mask
);
356 ctx
->Color
.ClearColor
= clearSave
;
361 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
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."
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).
373 if (drawbuffer
!= 0) {
374 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
380 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferiv(buffer=%s)",
381 _mesa_lookup_enum_by_nr(buffer
));
389 * Clear unsigned integer color buffer (not depth, not stencil).
392 _mesa_ClearBufferuiv(GLenum buffer
, GLint drawbuffer
, const GLuint
*value
)
394 GET_CURRENT_CONTEXT(ctx
);
396 FLUSH_VERTICES(ctx
, 0);
397 FLUSH_CURRENT(ctx
, 0);
400 _mesa_update_state( ctx
);
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)",
412 else if (mask
&& !ctx
->RasterDiscard
) {
413 union gl_color_union clearSave
;
416 clearSave
= ctx
->Color
.ClearColor
;
418 COPY_4V(ctx
->Color
.ClearColor
.ui
, value
);
419 /* clear buffer(s) */
420 ctx
->Driver
.Clear(ctx
, mask
);
422 ctx
->Color
.ClearColor
= clearSave
;
428 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
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."
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:
440 * "Only ClearBufferiv should be used to clear stencil buffers."
442 * Note that we still need to generate an error for the invalid
443 * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
445 if (drawbuffer
!= 0) {
446 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
452 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferuiv(buffer=%s)",
453 _mesa_lookup_enum_by_nr(buffer
));
461 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
464 _mesa_ClearBufferfv(GLenum buffer
, GLint drawbuffer
, const GLfloat
*value
)
466 GET_CURRENT_CONTEXT(ctx
);
468 FLUSH_VERTICES(ctx
, 0);
469 FLUSH_CURRENT(ctx
, 0);
472 _mesa_update_state( ctx
);
477 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
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."
484 if (drawbuffer
!= 0) {
485 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
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()
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
;
500 /* clear depth buffer to value */
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)",
510 else if (mask
&& !ctx
->RasterDiscard
) {
511 union gl_color_union clearSave
;
514 clearSave
= ctx
->Color
.ClearColor
;
516 COPY_4V(ctx
->Color
.ClearColor
.f
, value
);
517 /* clear buffer(s) */
518 ctx
->Driver
.Clear(ctx
, mask
);
520 ctx
->Color
.ClearColor
= clearSave
;
525 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
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."
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).
537 if (drawbuffer
!= 0) {
538 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
544 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfv(buffer=%s)",
545 _mesa_lookup_enum_by_nr(buffer
));
553 * Clear depth/stencil buffer only.
556 _mesa_ClearBufferfi(GLenum buffer
, GLint drawbuffer
,
557 GLfloat depth
, GLint stencil
)
559 GET_CURRENT_CONTEXT(ctx
);
562 FLUSH_VERTICES(ctx
, 0);
563 FLUSH_CURRENT(ctx
, 0);
565 if (buffer
!= GL_DEPTH_STENCIL
) {
566 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfi(buffer=%s)",
567 _mesa_lookup_enum_by_nr(buffer
));
571 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
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."
578 if (drawbuffer
!= 0) {
579 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfi(drawbuffer=%d)",
584 if (ctx
->RasterDiscard
)
588 _mesa_update_state( ctx
);
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
;
597 /* save current clear values */
598 const GLclampd clearDepthSave
= ctx
->Depth
.Clear
;
599 const GLuint clearStencilSave
= ctx
->Stencil
.Clear
;
601 /* set new clear values */
602 ctx
->Depth
.Clear
= depth
;
603 ctx
->Stencil
.Clear
= stencil
;
606 ctx
->Driver
.Clear(ctx
, mask
);
609 ctx
->Depth
.Clear
= clearDepthSave
;
610 ctx
->Stencil
.Clear
= clearStencilSave
;