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 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
29 * glClearColor, glClearIndex, glClear() functions.
46 _mesa_ClearIndex( GLfloat c
)
48 GET_CURRENT_CONTEXT(ctx
);
50 ctx
->Color
.ClearIndex
= (GLuint
) c
;
55 * Specify the clear values for the color buffers.
57 * \param red red color component.
58 * \param green green color component.
59 * \param blue blue color component.
60 * \param alpha alpha component.
64 * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a
65 * change, flushes the vertices and notifies the driver via the
66 * dd_function_table::ClearColor callback.
69 _mesa_ClearColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
71 GET_CURRENT_CONTEXT(ctx
);
73 ctx
->Color
.ClearColor
.f
[0] = red
;
74 ctx
->Color
.ClearColor
.f
[1] = green
;
75 ctx
->Color
.ClearColor
.f
[2] = blue
;
76 ctx
->Color
.ClearColor
.f
[3] = alpha
;
81 * GL_EXT_texture_integer
84 _mesa_ClearColorIiEXT(GLint r
, GLint g
, GLint b
, GLint a
)
86 GET_CURRENT_CONTEXT(ctx
);
88 ctx
->Color
.ClearColor
.i
[0] = r
;
89 ctx
->Color
.ClearColor
.i
[1] = g
;
90 ctx
->Color
.ClearColor
.i
[2] = b
;
91 ctx
->Color
.ClearColor
.i
[3] = a
;
96 * GL_EXT_texture_integer
99 _mesa_ClearColorIuiEXT(GLuint r
, GLuint g
, GLuint b
, GLuint a
)
101 GET_CURRENT_CONTEXT(ctx
);
103 ctx
->Color
.ClearColor
.ui
[0] = r
;
104 ctx
->Color
.ClearColor
.ui
[1] = g
;
105 ctx
->Color
.ClearColor
.ui
[2] = b
;
106 ctx
->Color
.ClearColor
.ui
[3] = a
;
113 * \param mask bit-mask indicating the buffers to be cleared.
115 * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState
116 * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin,
117 * etc. If the rasterization mode is set to GL_RENDER then requests the driver
118 * to clear the buffers, via the dd_function_table::Clear callback.
121 _mesa_Clear( GLbitfield mask
)
123 GET_CURRENT_CONTEXT(ctx
);
124 FLUSH_VERTICES(ctx
, 0);
126 FLUSH_CURRENT(ctx
, 0);
128 if (MESA_VERBOSE
& VERBOSE_API
)
129 _mesa_debug(ctx
, "glClear 0x%x\n", mask
);
131 if (mask
& ~(GL_COLOR_BUFFER_BIT
|
132 GL_DEPTH_BUFFER_BIT
|
133 GL_STENCIL_BUFFER_BIT
|
134 GL_ACCUM_BUFFER_BIT
)) {
135 /* invalid bit set */
136 _mesa_error( ctx
, GL_INVALID_VALUE
, "glClear(0x%x)", mask
);
140 /* Accumulation buffers were removed in core contexts, and they never
141 * existed in OpenGL ES.
143 if ((mask
& GL_ACCUM_BUFFER_BIT
) != 0
144 && (ctx
->API
== API_OPENGL_CORE
|| _mesa_is_gles(ctx
))) {
145 _mesa_error( ctx
, GL_INVALID_VALUE
, "glClear(GL_ACCUM_BUFFER_BIT)");
150 _mesa_update_state( ctx
); /* update _Xmin, etc */
153 if (ctx
->DrawBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
154 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
155 "glClear(incomplete framebuffer)");
159 if (ctx
->DrawBuffer
->Width
== 0 || ctx
->DrawBuffer
->Height
== 0 ||
160 ctx
->DrawBuffer
->_Xmin
>= ctx
->DrawBuffer
->_Xmax
||
161 ctx
->DrawBuffer
->_Ymin
>= ctx
->DrawBuffer
->_Ymax
)
164 if (ctx
->RasterDiscard
)
167 if (ctx
->RenderMode
== GL_RENDER
) {
168 GLbitfield bufferMask
;
170 /* don't clear depth buffer if depth writing disabled */
171 if (!ctx
->Depth
.Mask
)
172 mask
&= ~GL_DEPTH_BUFFER_BIT
;
174 /* Build the bitmask to send to device driver's Clear function.
175 * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
176 * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
177 * BUFFER_BIT_COLORn flags.
180 if (mask
& GL_COLOR_BUFFER_BIT
) {
182 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
183 bufferMask
|= (1 << ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[i
]);
187 if ((mask
& GL_DEPTH_BUFFER_BIT
)
188 && ctx
->DrawBuffer
->Visual
.haveDepthBuffer
) {
189 bufferMask
|= BUFFER_BIT_DEPTH
;
192 if ((mask
& GL_STENCIL_BUFFER_BIT
)
193 && ctx
->DrawBuffer
->Visual
.haveStencilBuffer
) {
194 bufferMask
|= BUFFER_BIT_STENCIL
;
197 if ((mask
& GL_ACCUM_BUFFER_BIT
)
198 && ctx
->DrawBuffer
->Visual
.haveAccumBuffer
) {
199 bufferMask
|= BUFFER_BIT_ACCUM
;
202 ASSERT(ctx
->Driver
.Clear
);
203 ctx
->Driver
.Clear(ctx
, bufferMask
);
208 /** Returned by make_color_buffer_mask() for errors */
209 #define INVALID_MASK ~0x0
213 * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
214 * BUFFER_BIT_x values.
215 * Return INVALID_MASK if the drawbuffer value is invalid.
218 make_color_buffer_mask(struct gl_context
*ctx
, GLint drawbuffer
)
220 const struct gl_renderbuffer_attachment
*att
= ctx
->DrawBuffer
->Attachment
;
221 GLbitfield mask
= 0x0;
223 switch (drawbuffer
) {
225 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
226 mask
|= BUFFER_BIT_FRONT_LEFT
;
227 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
228 mask
|= BUFFER_BIT_FRONT_RIGHT
;
231 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
232 mask
|= BUFFER_BIT_BACK_LEFT
;
233 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
234 mask
|= BUFFER_BIT_BACK_RIGHT
;
237 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
238 mask
|= BUFFER_BIT_FRONT_LEFT
;
239 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
240 mask
|= BUFFER_BIT_BACK_LEFT
;
243 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
244 mask
|= BUFFER_BIT_FRONT_RIGHT
;
245 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
246 mask
|= BUFFER_BIT_BACK_RIGHT
;
248 case GL_FRONT_AND_BACK
:
249 if (att
[BUFFER_FRONT_LEFT
].Renderbuffer
)
250 mask
|= BUFFER_BIT_FRONT_LEFT
;
251 if (att
[BUFFER_BACK_LEFT
].Renderbuffer
)
252 mask
|= BUFFER_BIT_BACK_LEFT
;
253 if (att
[BUFFER_FRONT_RIGHT
].Renderbuffer
)
254 mask
|= BUFFER_BIT_FRONT_RIGHT
;
255 if (att
[BUFFER_BACK_RIGHT
].Renderbuffer
)
256 mask
|= BUFFER_BIT_BACK_RIGHT
;
259 if (drawbuffer
< 0 || drawbuffer
>= (GLint
)ctx
->Const
.MaxDrawBuffers
) {
262 else if (att
[BUFFER_COLOR0
+ drawbuffer
].Renderbuffer
) {
263 mask
|= (BUFFER_BIT_COLOR0
<< drawbuffer
);
274 * Clear signed integer color buffer or stencil buffer (not depth).
277 _mesa_ClearBufferiv(GLenum buffer
, GLint drawbuffer
, const GLint
*value
)
279 GET_CURRENT_CONTEXT(ctx
);
280 FLUSH_VERTICES(ctx
, 0);
282 FLUSH_CURRENT(ctx
, 0);
285 _mesa_update_state( ctx
);
290 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
292 * "ClearBuffer generates an INVALID VALUE error if buffer is
293 * COLOR and drawbuffer is less than zero, or greater than the
294 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
295 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
297 if (drawbuffer
!= 0) {
298 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
302 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
&& !ctx
->RasterDiscard
) {
303 /* Save current stencil clear value, set to 'value', do the
304 * stencil clear and restore the clear value.
305 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
308 const GLuint clearSave
= ctx
->Stencil
.Clear
;
309 ctx
->Stencil
.Clear
= *value
;
310 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_STENCIL
);
311 ctx
->Stencil
.Clear
= clearSave
;
316 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
317 if (mask
== INVALID_MASK
) {
318 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
322 else if (mask
&& !ctx
->RasterDiscard
) {
323 union gl_color_union clearSave
;
326 clearSave
= ctx
->Color
.ClearColor
;
328 COPY_4V(ctx
->Color
.ClearColor
.i
, value
);
329 /* clear buffer(s) */
330 ctx
->Driver
.Clear(ctx
, mask
);
332 ctx
->Color
.ClearColor
= clearSave
;
337 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
339 * "The result of ClearBuffer is undefined if no conversion between
340 * the type of the specified value and the type of the buffer being
341 * cleared is defined (for example, if ClearBufferiv is called for a
342 * fixed- or floating-point buffer, or if ClearBufferfv is called
343 * for a signed or unsigned integer buffer). This is not an error."
345 * In this case we take "undefined" and "not an error" to mean "ignore."
346 * Note that we still need to generate an error for the invalid
347 * drawbuffer case (see the GL_STENCIL case above).
349 if (drawbuffer
!= 0) {
350 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
356 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferiv(buffer=%s)",
357 _mesa_lookup_enum_by_nr(buffer
));
365 * Clear unsigned integer color buffer (not depth, not stencil).
368 _mesa_ClearBufferuiv(GLenum buffer
, GLint drawbuffer
, const GLuint
*value
)
370 GET_CURRENT_CONTEXT(ctx
);
372 FLUSH_VERTICES(ctx
, 0);
373 FLUSH_CURRENT(ctx
, 0);
376 _mesa_update_state( ctx
);
382 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
383 if (mask
== INVALID_MASK
) {
384 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
388 else if (mask
&& !ctx
->RasterDiscard
) {
389 union gl_color_union clearSave
;
392 clearSave
= ctx
->Color
.ClearColor
;
394 COPY_4V(ctx
->Color
.ClearColor
.ui
, value
);
395 /* clear buffer(s) */
396 ctx
->Driver
.Clear(ctx
, mask
);
398 ctx
->Color
.ClearColor
= clearSave
;
404 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
406 * "The result of ClearBuffer is undefined if no conversion between
407 * the type of the specified value and the type of the buffer being
408 * cleared is defined (for example, if ClearBufferiv is called for a
409 * fixed- or floating-point buffer, or if ClearBufferfv is called
410 * for a signed or unsigned integer buffer). This is not an error."
412 * In this case we take "undefined" and "not an error" to mean "ignore."
413 * Even though we could do something sensible for GL_STENCIL, page 263
414 * (page 279 of the PDF) says:
416 * "Only ClearBufferiv should be used to clear stencil buffers."
418 * Note that we still need to generate an error for the invalid
419 * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
421 if (drawbuffer
!= 0) {
422 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
428 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferuiv(buffer=%s)",
429 _mesa_lookup_enum_by_nr(buffer
));
437 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
440 _mesa_ClearBufferfv(GLenum buffer
, GLint drawbuffer
, const GLfloat
*value
)
442 GET_CURRENT_CONTEXT(ctx
);
444 FLUSH_VERTICES(ctx
, 0);
445 FLUSH_CURRENT(ctx
, 0);
448 _mesa_update_state( ctx
);
453 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
455 * "ClearBuffer generates an INVALID VALUE error if buffer is
456 * COLOR and drawbuffer is less than zero, or greater than the
457 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
458 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
460 if (drawbuffer
!= 0) {
461 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
465 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
&& !ctx
->RasterDiscard
) {
466 /* Save current depth clear value, set to 'value', do the
467 * depth clear and restore the clear value.
468 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
471 const GLclampd clearSave
= ctx
->Depth
.Clear
;
472 ctx
->Depth
.Clear
= *value
;
473 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_DEPTH
);
474 ctx
->Depth
.Clear
= clearSave
;
476 /* clear depth buffer to value */
480 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
481 if (mask
== INVALID_MASK
) {
482 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
486 else if (mask
&& !ctx
->RasterDiscard
) {
487 union gl_color_union clearSave
;
490 clearSave
= ctx
->Color
.ClearColor
;
492 COPY_4V(ctx
->Color
.ClearColor
.f
, value
);
493 /* clear buffer(s) */
494 ctx
->Driver
.Clear(ctx
, mask
);
496 ctx
->Color
.ClearColor
= clearSave
;
501 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
503 * "The result of ClearBuffer is undefined if no conversion between
504 * the type of the specified value and the type of the buffer being
505 * cleared is defined (for example, if ClearBufferiv is called for a
506 * fixed- or floating-point buffer, or if ClearBufferfv is called
507 * for a signed or unsigned integer buffer). This is not an error."
509 * In this case we take "undefined" and "not an error" to mean "ignore."
510 * Note that we still need to generate an error for the invalid
511 * drawbuffer case (see the GL_DEPTH case above).
513 if (drawbuffer
!= 0) {
514 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
520 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfv(buffer=%s)",
521 _mesa_lookup_enum_by_nr(buffer
));
529 * Clear depth/stencil buffer only.
532 _mesa_ClearBufferfi(GLenum buffer
, GLint drawbuffer
,
533 GLfloat depth
, GLint stencil
)
535 GET_CURRENT_CONTEXT(ctx
);
538 FLUSH_VERTICES(ctx
, 0);
539 FLUSH_CURRENT(ctx
, 0);
541 if (buffer
!= GL_DEPTH_STENCIL
) {
542 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfi(buffer=%s)",
543 _mesa_lookup_enum_by_nr(buffer
));
547 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
549 * "ClearBuffer generates an INVALID VALUE error if buffer is
550 * COLOR and drawbuffer is less than zero, or greater than the
551 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
552 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
554 if (drawbuffer
!= 0) {
555 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfi(drawbuffer=%d)",
560 if (ctx
->RasterDiscard
)
564 _mesa_update_state( ctx
);
567 if (ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)
568 mask
|= BUFFER_BIT_DEPTH
;
569 if (ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
)
570 mask
|= BUFFER_BIT_STENCIL
;
573 /* save current clear values */
574 const GLclampd clearDepthSave
= ctx
->Depth
.Clear
;
575 const GLuint clearStencilSave
= ctx
->Stencil
.Clear
;
577 /* set new clear values */
578 ctx
->Depth
.Clear
= depth
;
579 ctx
->Stencil
.Clear
= stencil
;
582 ctx
->Driver
.Clear(ctx
, mask
);
585 ctx
->Depth
.Clear
= clearDepthSave
;
586 ctx
->Stencil
.Clear
= clearStencilSave
;