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.
45 _mesa_ClearIndex( GLfloat c
)
47 GET_CURRENT_CONTEXT(ctx
);
49 ctx
->Color
.ClearIndex
= (GLuint
) c
;
54 * Specify the clear values for the color buffers.
56 * \param red red color component.
57 * \param green green color component.
58 * \param blue blue color component.
59 * \param alpha alpha component.
63 * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a
64 * change, flushes the vertices and notifies the driver via the
65 * dd_function_table::ClearColor callback.
68 _mesa_ClearColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
70 GET_CURRENT_CONTEXT(ctx
);
72 ctx
->Color
.ClearColor
.f
[0] = red
;
73 ctx
->Color
.ClearColor
.f
[1] = green
;
74 ctx
->Color
.ClearColor
.f
[2] = blue
;
75 ctx
->Color
.ClearColor
.f
[3] = alpha
;
80 * GL_EXT_texture_integer
83 _mesa_ClearColorIiEXT(GLint r
, GLint g
, GLint b
, GLint a
)
85 GET_CURRENT_CONTEXT(ctx
);
87 ctx
->Color
.ClearColor
.i
[0] = r
;
88 ctx
->Color
.ClearColor
.i
[1] = g
;
89 ctx
->Color
.ClearColor
.i
[2] = b
;
90 ctx
->Color
.ClearColor
.i
[3] = a
;
95 * GL_EXT_texture_integer
98 _mesa_ClearColorIuiEXT(GLuint r
, GLuint g
, GLuint b
, GLuint a
)
100 GET_CURRENT_CONTEXT(ctx
);
102 ctx
->Color
.ClearColor
.ui
[0] = r
;
103 ctx
->Color
.ClearColor
.ui
[1] = g
;
104 ctx
->Color
.ClearColor
.ui
[2] = b
;
105 ctx
->Color
.ClearColor
.ui
[3] = a
;
112 * \param mask bit-mask indicating the buffers to be cleared.
114 * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState
115 * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin,
116 * etc. If the rasterization mode is set to GL_RENDER then requests the driver
117 * to clear the buffers, via the dd_function_table::Clear callback.
120 _mesa_Clear( GLbitfield mask
)
122 GET_CURRENT_CONTEXT(ctx
);
123 FLUSH_VERTICES(ctx
, 0);
125 FLUSH_CURRENT(ctx
, 0);
127 if (MESA_VERBOSE
& VERBOSE_API
)
128 _mesa_debug(ctx
, "glClear 0x%x\n", mask
);
130 if (mask
& ~(GL_COLOR_BUFFER_BIT
|
131 GL_DEPTH_BUFFER_BIT
|
132 GL_STENCIL_BUFFER_BIT
|
133 GL_ACCUM_BUFFER_BIT
)) {
134 /* invalid bit set */
135 _mesa_error( ctx
, GL_INVALID_VALUE
, "glClear(0x%x)", mask
);
139 /* Accumulation buffers were removed in core contexts, and they never
140 * existed in OpenGL ES.
142 if ((mask
& GL_ACCUM_BUFFER_BIT
) != 0
143 && (ctx
->API
== API_OPENGL_CORE
|| _mesa_is_gles(ctx
))) {
144 _mesa_error( ctx
, GL_INVALID_VALUE
, "glClear(GL_ACCUM_BUFFER_BIT)");
149 _mesa_update_state( ctx
); /* update _Xmin, etc */
152 if (ctx
->DrawBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
153 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
154 "glClear(incomplete framebuffer)");
158 if (ctx
->DrawBuffer
->Width
== 0 || ctx
->DrawBuffer
->Height
== 0 ||
159 ctx
->DrawBuffer
->_Xmin
>= ctx
->DrawBuffer
->_Xmax
||
160 ctx
->DrawBuffer
->_Ymin
>= ctx
->DrawBuffer
->_Ymax
)
163 if (ctx
->RasterDiscard
)
166 if (ctx
->RenderMode
== GL_RENDER
) {
167 GLbitfield bufferMask
;
169 /* don't clear depth buffer if depth writing disabled */
170 if (!ctx
->Depth
.Mask
)
171 mask
&= ~GL_DEPTH_BUFFER_BIT
;
173 /* Build the bitmask to send to device driver's Clear function.
174 * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
175 * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
176 * BUFFER_BIT_COLORn flags.
179 if (mask
& GL_COLOR_BUFFER_BIT
) {
181 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
182 GLint buf
= ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[i
];
185 bufferMask
|= 1 << buf
;
190 if ((mask
& GL_DEPTH_BUFFER_BIT
)
191 && ctx
->DrawBuffer
->Visual
.haveDepthBuffer
) {
192 bufferMask
|= BUFFER_BIT_DEPTH
;
195 if ((mask
& GL_STENCIL_BUFFER_BIT
)
196 && ctx
->DrawBuffer
->Visual
.haveStencilBuffer
) {
197 bufferMask
|= BUFFER_BIT_STENCIL
;
200 if ((mask
& GL_ACCUM_BUFFER_BIT
)
201 && ctx
->DrawBuffer
->Visual
.haveAccumBuffer
) {
202 bufferMask
|= BUFFER_BIT_ACCUM
;
205 ASSERT(ctx
->Driver
.Clear
);
206 ctx
->Driver
.Clear(ctx
, bufferMask
);
211 /** Returned by make_color_buffer_mask() for errors */
212 #define INVALID_MASK ~0x0
216 * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
217 * BUFFER_BIT_x values.
218 * Return INVALID_MASK if the drawbuffer value is invalid.
221 make_color_buffer_mask(struct gl_context
*ctx
, GLint drawbuffer
)
223 const struct gl_renderbuffer_attachment
*att
= ctx
->DrawBuffer
->Attachment
;
224 GLbitfield mask
= 0x0;
226 /* From the GL 4.0 specification:
227 * If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is
228 * specified by passing i as the parameter drawbuffer, and value
229 * points to a four-element vector specifying the R, G, B, and A
230 * color to clear that draw buffer to. If the draw buffer is one
231 * of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
232 * multiple buffers, each selected buffer is cleared to the same
235 * Note that "drawbuffer" and "draw buffer" have different meaning.
236 * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's
237 * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK,
240 if (drawbuffer
< 0 || drawbuffer
>= (GLint
)ctx
->Const
.MaxDrawBuffers
) {
244 switch (ctx
->DrawBuffer
->ColorDrawBuffer
[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
;
281 GLint buf
= ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[drawbuffer
];
283 if (buf
>= 0 && att
[buf
].Renderbuffer
) {
296 * Clear signed integer color buffer or stencil buffer (not depth).
299 _mesa_ClearBufferiv(GLenum buffer
, GLint drawbuffer
, const GLint
*value
)
301 GET_CURRENT_CONTEXT(ctx
);
302 FLUSH_VERTICES(ctx
, 0);
304 FLUSH_CURRENT(ctx
, 0);
307 _mesa_update_state( ctx
);
312 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
314 * "ClearBuffer generates an INVALID VALUE error if buffer is
315 * COLOR and drawbuffer is less than zero, or greater than the
316 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
317 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
319 if (drawbuffer
!= 0) {
320 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
324 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
&& !ctx
->RasterDiscard
) {
325 /* Save current stencil clear value, set to 'value', do the
326 * stencil clear and restore the clear value.
327 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
330 const GLuint clearSave
= ctx
->Stencil
.Clear
;
331 ctx
->Stencil
.Clear
= *value
;
332 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_STENCIL
);
333 ctx
->Stencil
.Clear
= clearSave
;
338 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
339 if (mask
== INVALID_MASK
) {
340 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
344 else if (mask
&& !ctx
->RasterDiscard
) {
345 union gl_color_union clearSave
;
348 clearSave
= ctx
->Color
.ClearColor
;
350 COPY_4V(ctx
->Color
.ClearColor
.i
, value
);
351 /* clear buffer(s) */
352 ctx
->Driver
.Clear(ctx
, mask
);
354 ctx
->Color
.ClearColor
= clearSave
;
359 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
361 * "The result of ClearBuffer is undefined if no conversion between
362 * the type of the specified value and the type of the buffer being
363 * cleared is defined (for example, if ClearBufferiv is called for a
364 * fixed- or floating-point buffer, or if ClearBufferfv is called
365 * for a signed or unsigned integer buffer). This is not an error."
367 * In this case we take "undefined" and "not an error" to mean "ignore."
368 * Note that we still need to generate an error for the invalid
369 * drawbuffer case (see the GL_STENCIL case above).
371 if (drawbuffer
!= 0) {
372 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferiv(drawbuffer=%d)",
378 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferiv(buffer=%s)",
379 _mesa_lookup_enum_by_nr(buffer
));
387 * Clear unsigned integer color buffer (not depth, not stencil).
390 _mesa_ClearBufferuiv(GLenum buffer
, GLint drawbuffer
, const GLuint
*value
)
392 GET_CURRENT_CONTEXT(ctx
);
394 FLUSH_VERTICES(ctx
, 0);
395 FLUSH_CURRENT(ctx
, 0);
398 _mesa_update_state( ctx
);
404 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
405 if (mask
== INVALID_MASK
) {
406 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
410 else if (mask
&& !ctx
->RasterDiscard
) {
411 union gl_color_union clearSave
;
414 clearSave
= ctx
->Color
.ClearColor
;
416 COPY_4V(ctx
->Color
.ClearColor
.ui
, value
);
417 /* clear buffer(s) */
418 ctx
->Driver
.Clear(ctx
, mask
);
420 ctx
->Color
.ClearColor
= clearSave
;
426 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
428 * "The result of ClearBuffer is undefined if no conversion between
429 * the type of the specified value and the type of the buffer being
430 * cleared is defined (for example, if ClearBufferiv is called for a
431 * fixed- or floating-point buffer, or if ClearBufferfv is called
432 * for a signed or unsigned integer buffer). This is not an error."
434 * In this case we take "undefined" and "not an error" to mean "ignore."
435 * Even though we could do something sensible for GL_STENCIL, page 263
436 * (page 279 of the PDF) says:
438 * "Only ClearBufferiv should be used to clear stencil buffers."
440 * Note that we still need to generate an error for the invalid
441 * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
443 if (drawbuffer
!= 0) {
444 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferuiv(drawbuffer=%d)",
450 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferuiv(buffer=%s)",
451 _mesa_lookup_enum_by_nr(buffer
));
459 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
462 _mesa_ClearBufferfv(GLenum buffer
, GLint drawbuffer
, const GLfloat
*value
)
464 GET_CURRENT_CONTEXT(ctx
);
466 FLUSH_VERTICES(ctx
, 0);
467 FLUSH_CURRENT(ctx
, 0);
470 _mesa_update_state( ctx
);
475 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
477 * "ClearBuffer generates an INVALID VALUE error if buffer is
478 * COLOR and drawbuffer is less than zero, or greater than the
479 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
480 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
482 if (drawbuffer
!= 0) {
483 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
487 else if (ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
&& !ctx
->RasterDiscard
) {
488 /* Save current depth clear value, set to 'value', do the
489 * depth clear and restore the clear value.
490 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
493 const GLclampd clearSave
= ctx
->Depth
.Clear
;
494 ctx
->Depth
.Clear
= *value
;
495 ctx
->Driver
.Clear(ctx
, BUFFER_BIT_DEPTH
);
496 ctx
->Depth
.Clear
= clearSave
;
498 /* clear depth buffer to value */
502 const GLbitfield mask
= make_color_buffer_mask(ctx
, drawbuffer
);
503 if (mask
== INVALID_MASK
) {
504 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
508 else if (mask
&& !ctx
->RasterDiscard
) {
509 union gl_color_union clearSave
;
512 clearSave
= ctx
->Color
.ClearColor
;
514 COPY_4V(ctx
->Color
.ClearColor
.f
, value
);
515 /* clear buffer(s) */
516 ctx
->Driver
.Clear(ctx
, mask
);
518 ctx
->Color
.ClearColor
= clearSave
;
523 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
525 * "The result of ClearBuffer is undefined if no conversion between
526 * the type of the specified value and the type of the buffer being
527 * cleared is defined (for example, if ClearBufferiv is called for a
528 * fixed- or floating-point buffer, or if ClearBufferfv is called
529 * for a signed or unsigned integer buffer). This is not an error."
531 * In this case we take "undefined" and "not an error" to mean "ignore."
532 * Note that we still need to generate an error for the invalid
533 * drawbuffer case (see the GL_DEPTH case above).
535 if (drawbuffer
!= 0) {
536 _mesa_error(ctx
, GL_INVALID_VALUE
, "glClearBufferfv(drawbuffer=%d)",
542 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfv(buffer=%s)",
543 _mesa_lookup_enum_by_nr(buffer
));
551 * Clear depth/stencil buffer only.
554 _mesa_ClearBufferfi(GLenum buffer
, GLint drawbuffer
,
555 GLfloat depth
, GLint stencil
)
557 GET_CURRENT_CONTEXT(ctx
);
560 FLUSH_VERTICES(ctx
, 0);
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
;