2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
28 * glClearColor, glClearIndex, glClear() functions.
44 _mesa_ClearIndex( GLfloat c
)
46 GET_CURRENT_CONTEXT(ctx
);
48 ctx
->Color
.ClearIndex
= (GLuint
) c
;
53 * Specify the clear values for the color buffers.
55 * \param red red color component.
56 * \param green green color component.
57 * \param blue blue color component.
58 * \param alpha alpha component.
63 _mesa_ClearColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
65 GET_CURRENT_CONTEXT(ctx
);
67 ctx
->Color
.ClearColor
.f
[0] = red
;
68 ctx
->Color
.ClearColor
.f
[1] = green
;
69 ctx
->Color
.ClearColor
.f
[2] = blue
;
70 ctx
->Color
.ClearColor
.f
[3] = alpha
;
75 * GL_EXT_texture_integer
78 _mesa_ClearColorIiEXT(GLint r
, GLint g
, GLint b
, GLint a
)
80 GET_CURRENT_CONTEXT(ctx
);
82 ctx
->Color
.ClearColor
.i
[0] = r
;
83 ctx
->Color
.ClearColor
.i
[1] = g
;
84 ctx
->Color
.ClearColor
.i
[2] = b
;
85 ctx
->Color
.ClearColor
.i
[3] = a
;
90 * GL_EXT_texture_integer
93 _mesa_ClearColorIuiEXT(GLuint r
, GLuint g
, GLuint b
, GLuint a
)
95 GET_CURRENT_CONTEXT(ctx
);
97 ctx
->Color
.ClearColor
.ui
[0] = r
;
98 ctx
->Color
.ClearColor
.ui
[1] = g
;
99 ctx
->Color
.ClearColor
.ui
[2] = b
;
100 ctx
->Color
.ClearColor
.ui
[3] = a
;
105 * Returns true if color writes are enabled for the given color attachment.
107 * Beyond checking ColorMask, this uses _mesa_format_has_color_component to
108 * ignore components that don't actually exist in the format (such as X in
112 color_buffer_writes_enabled(const struct gl_context
*ctx
, unsigned idx
)
114 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[idx
];
116 GLubyte colorMask
= 0;
119 for (c
= 0; c
< 4; c
++) {
120 if (_mesa_format_has_color_component(rb
->Format
, c
))
121 colorMask
|= ctx
->Color
.ColorMask
[idx
][c
];
125 return colorMask
!= 0;
132 * \param mask bit-mask indicating the buffers to be cleared.
134 * Flushes the vertices and verifies the parameter.
135 * If __struct gl_contextRec::NewState is set then calls _mesa_update_state()
136 * to update gl_frame_buffer::_Xmin, etc. If the rasterization mode is set to
137 * GL_RENDER then requests the driver to clear the buffers, via the
138 * dd_function_table::Clear callback.
141 _mesa_Clear( GLbitfield mask
)
143 GET_CURRENT_CONTEXT(ctx
);
144 FLUSH_VERTICES(ctx
, 0);
146 FLUSH_CURRENT(ctx
, 0);
148 if (MESA_VERBOSE
& VERBOSE_API
)
149 _mesa_debug(ctx
, "glClear 0x%x\n", mask
);
151 if (mask
& ~(GL_COLOR_BUFFER_BIT
|
152 GL_DEPTH_BUFFER_BIT
|
153 GL_STENCIL_BUFFER_BIT
|
154 GL_ACCUM_BUFFER_BIT
)) {
155 /* invalid bit set */
156 _mesa_error( ctx
, GL_INVALID_VALUE
, "glClear(0x%x)", mask
);
160 /* Accumulation buffers were removed in core contexts, and they never
161 * existed in OpenGL ES.
163 if ((mask
& GL_ACCUM_BUFFER_BIT
) != 0
164 && (ctx
->API
== API_OPENGL_CORE
|| _mesa_is_gles(ctx
))) {
165 _mesa_error( ctx
, GL_INVALID_VALUE
, "glClear(GL_ACCUM_BUFFER_BIT)");
170 _mesa_update_state( ctx
); /* update _Xmin, etc */
173 if (ctx
->DrawBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
174 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
175 "glClear(incomplete framebuffer)");
179 if (ctx
->RasterDiscard
)
182 if (ctx
->RenderMode
== GL_RENDER
) {
183 GLbitfield bufferMask
;
185 /* don't clear depth buffer if depth writing disabled */
186 if (!ctx
->Depth
.Mask
)
187 mask
&= ~GL_DEPTH_BUFFER_BIT
;
189 /* Build the bitmask to send to device driver's Clear function.
190 * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
191 * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
192 * BUFFER_BIT_COLORn flags.
195 if (mask
& GL_COLOR_BUFFER_BIT
) {
197 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
198 GLint buf
= ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[i
];
200 if (buf
>= 0 && color_buffer_writes_enabled(ctx
, i
)) {
201 bufferMask
|= 1 << buf
;
206 if ((mask
& GL_DEPTH_BUFFER_BIT
)
207 && ctx
->DrawBuffer
->Visual
.haveDepthBuffer
) {
208 bufferMask
|= BUFFER_BIT_DEPTH
;
211 if ((mask
& GL_STENCIL_BUFFER_BIT
)
212 && ctx
->DrawBuffer
->Visual
.haveStencilBuffer
) {
213 bufferMask
|= BUFFER_BIT_STENCIL
;
216 if ((mask
& GL_ACCUM_BUFFER_BIT
)
217 && ctx
->DrawBuffer
->Visual
.haveAccumBuffer
) {
218 bufferMask
|= BUFFER_BIT_ACCUM
;
221 assert(ctx
->Driver
.Clear
);
222 ctx
->Driver
.Clear(ctx
, bufferMask
);
227 /** Returned by make_color_buffer_mask() for errors */
228 #define INVALID_MASK ~0x0U
232 * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
233 * BUFFER_BIT_x values.
234 * Return INVALID_MASK if the drawbuffer value is invalid.
237 make_color_buffer_mask(struct gl_context
*ctx
, GLint drawbuffer
)
239 const struct gl_renderbuffer_attachment
*att
= ctx
->DrawBuffer
->Attachment
;
240 GLbitfield mask
= 0x0;
242 /* From the GL 4.0 specification:
243 * If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is
244 * specified by passing i as the parameter drawbuffer, and value
245 * points to a four-element vector specifying the R, G, B, and A
246 * color to clear that draw buffer to. If the draw buffer is one
247 * of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
248 * multiple buffers, each selected buffer is cleared to the same
251 * Note that "drawbuffer" and "draw buffer" have different meaning.
252 * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's
253 * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK,
256 if (drawbuffer
< 0 || drawbuffer
>= (GLint
)ctx
->Const
.MaxDrawBuffers
) {
260 switch (ctx
->DrawBuffer
->ColorDrawBuffer
[drawbuffer
]) {
262 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
263 mask
|= BUFFER_BIT_FRONT_LEFT
;
264 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
265 mask
|= BUFFER_BIT_FRONT_RIGHT
;
268 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
269 mask
|= BUFFER_BIT_BACK_LEFT
;
270 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
271 mask
|= BUFFER_BIT_BACK_RIGHT
;
274 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
275 mask
|= BUFFER_BIT_FRONT_LEFT
;
276 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
277 mask
|= BUFFER_BIT_BACK_LEFT
;
280 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
281 mask
|= BUFFER_BIT_FRONT_RIGHT
;
282 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
283 mask
|= BUFFER_BIT_BACK_RIGHT
;
285 case GL_FRONT_AND_BACK
:
286 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
287 mask
|= BUFFER_BIT_FRONT_LEFT
;
288 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
289 mask
|= BUFFER_BIT_BACK_LEFT
;
290 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
291 mask
|= BUFFER_BIT_FRONT_RIGHT
;
292 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
293 mask
|= BUFFER_BIT_BACK_RIGHT
;
297 GLint buf
= ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[drawbuffer
];
299 if (buf
>= 0 && att
[buf
].Renderbuffer
) {
312 * Clear signed integer color buffer or stencil buffer (not depth).
315 _mesa_ClearBufferiv(GLenum buffer
, GLint drawbuffer
, const GLint
*value
)
317 GET_CURRENT_CONTEXT(ctx
);
318 FLUSH_VERTICES(ctx
, 0);
320 FLUSH_CURRENT(ctx
, 0);
323 _mesa_update_state( ctx
);
328 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
330 * "ClearBuffer generates an INVALID VALUE error if buffer is
331 * COLOR and drawbuffer is less than zero, or greater than the
332 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
333 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
335 if (drawbuffer
!= 0) {
336 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
340 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
341 && !ctx
->RasterDiscard
) {
342 /* Save current stencil clear value, set to 'value', do the
343 * stencil clear and restore the clear value.
344 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
347 const GLuint clearSave
= ctx
->Stencil
.Clear
;
348 ctx
->Stencil
.Clear
= *value
;
349 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_STENCIL
);
350 ctx
->Stencil
.Clear
= clearSave
;
355 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
356 if (mask
== INVALID_MASK
) {
357 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
361 else if (mask
&& !ctx
->RasterDiscard
) {
362 union gl_color_union clearSave
;
365 clearSave
= ctx
->Color
.ClearColor
;
367 COPY_4V(ctx
->Color
.ClearColor
.i
, value
);
368 /* clear buffer(s) */
369 ctx
->Driver
.Clear(ctx
, mask
);
371 ctx
->Color
.ClearColor
= clearSave
;
376 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
378 * "The result of ClearBuffer is undefined if no conversion between
379 * the type of the specified value and the type of the buffer being
380 * cleared is defined (for example, if ClearBufferiv is called for a
381 * fixed- or floating-point buffer, or if ClearBufferfv is called
382 * for a signed or unsigned integer buffer). This is not an error."
384 * In this case we take "undefined" and "not an error" to mean "ignore."
385 * Note that we still need to generate an error for the invalid
386 * drawbuffer case (see the GL_STENCIL case above).
388 if (drawbuffer
!= 0) {
389 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
395 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferiv(buffer=%s)",
396 _mesa_lookup_enum_by_nr(buffer
));
404 * Clear unsigned integer color buffer (not depth, not stencil).
407 _mesa_ClearBufferuiv(GLenum buffer
, GLint drawbuffer
, const GLuint
*value
)
409 GET_CURRENT_CONTEXT(ctx
);
411 FLUSH_VERTICES(ctx
, 0);
412 FLUSH_CURRENT(ctx
, 0);
415 _mesa_update_state( ctx
);
421 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
422 if (mask
== INVALID_MASK
) {
423 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
427 else if (mask
&& !ctx
->RasterDiscard
) {
428 union gl_color_union clearSave
;
431 clearSave
= ctx
->Color
.ClearColor
;
433 COPY_4V(ctx
->Color
.ClearColor
.ui
, value
);
434 /* clear buffer(s) */
435 ctx
->Driver
.Clear(ctx
, mask
);
437 ctx
->Color
.ClearColor
= clearSave
;
443 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
445 * "The result of ClearBuffer is undefined if no conversion between
446 * the type of the specified value and the type of the buffer being
447 * cleared is defined (for example, if ClearBufferiv is called for a
448 * fixed- or floating-point buffer, or if ClearBufferfv is called
449 * for a signed or unsigned integer buffer). This is not an error."
451 * In this case we take "undefined" and "not an error" to mean "ignore."
452 * Even though we could do something sensible for GL_STENCIL, page 263
453 * (page 279 of the PDF) says:
455 * "Only ClearBufferiv should be used to clear stencil buffers."
457 * Note that we still need to generate an error for the invalid
458 * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
460 if (drawbuffer
!= 0) {
461 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
467 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferuiv(buffer=%s)",
468 _mesa_lookup_enum_by_nr(buffer
));
476 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
479 _mesa_ClearBufferfv(GLenum buffer
, GLint drawbuffer
, const GLfloat
*value
)
481 GET_CURRENT_CONTEXT(ctx
);
483 FLUSH_VERTICES(ctx
, 0);
484 FLUSH_CURRENT(ctx
, 0);
487 _mesa_update_state( ctx
);
492 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
494 * "ClearBuffer generates an INVALID VALUE error if buffer is
495 * COLOR and drawbuffer is less than zero, or greater than the
496 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
497 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
499 if (drawbuffer
!= 0) {
500 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
504 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
505 && !ctx
->RasterDiscard
) {
506 /* Save current depth clear value, set to 'value', do the
507 * depth clear and restore the clear value.
508 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
511 const GLclampd clearSave
= ctx
->Depth
.Clear
;
512 ctx
->Depth
.Clear
= *value
;
513 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_DEPTH
);
514 ctx
->Depth
.Clear
= clearSave
;
516 /* clear depth buffer to value */
520 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
521 if (mask
== INVALID_MASK
) {
522 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
526 else if (mask
&& !ctx
->RasterDiscard
) {
527 union gl_color_union clearSave
;
530 clearSave
= ctx
->Color
.ClearColor
;
532 COPY_4V(ctx
->Color
.ClearColor
.f
, value
);
533 /* clear buffer(s) */
534 ctx
->Driver
.Clear(ctx
, mask
);
536 ctx
->Color
.ClearColor
= clearSave
;
541 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
543 * "The result of ClearBuffer is undefined if no conversion between
544 * the type of the specified value and the type of the buffer being
545 * cleared is defined (for example, if ClearBufferiv is called for a
546 * fixed- or floating-point buffer, or if ClearBufferfv is called
547 * for a signed or unsigned integer buffer). This is not an error."
549 * In this case we take "undefined" and "not an error" to mean "ignore."
550 * Note that we still need to generate an error for the invalid
551 * drawbuffer case (see the GL_DEPTH case above).
553 if (drawbuffer
!= 0) {
554 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
560 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfv(buffer=%s)",
561 _mesa_lookup_enum_by_nr(buffer
));
569 * Clear depth/stencil buffer only.
572 _mesa_ClearBufferfi(GLenum buffer
, GLint drawbuffer
,
573 GLfloat depth
, GLint stencil
)
575 GET_CURRENT_CONTEXT(ctx
);
578 FLUSH_VERTICES(ctx
, 0);
579 FLUSH_CURRENT(ctx
, 0);
581 if (buffer
!= GL_DEPTH_STENCIL
) {
582 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfi(buffer=%s)",
583 _mesa_lookup_enum_by_nr(buffer
));
587 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
589 * "ClearBuffer generates an INVALID VALUE error if buffer is
590 * COLOR and drawbuffer is less than zero, or greater than the
591 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
592 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
594 if (drawbuffer
!= 0) {
595 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfi(drawbuffer=%d)",
600 if (ctx
->RasterDiscard
)
604 _mesa_update_state( ctx
);
607 if (ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)
608 mask
|= BUFFER_BIT_DEPTH
;
609 if (ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)
610 mask
|= BUFFER_BIT_STENCIL
;
613 /* save current clear values */
614 const GLclampd clearDepthSave
= ctx
->Depth
.Clear
;
615 const GLuint clearStencilSave
= ctx
->Stencil
.Clear
;
617 /* set new clear values */
618 ctx
->Depth
.Clear
= depth
;
619 ctx
->Stencil
.Clear
= stencil
;
622 ctx
->Driver
.Clear(ctx
, mask
);
625 ctx
->Depth
.Clear
= clearDepthSave
;
626 ctx
->Stencil
.Clear
= clearStencilSave
;