clear.c revision af69d88d
1c1f859d4Smrg/* 2c1f859d4Smrg * Mesa 3-D graphics library 3c1f859d4Smrg * 4c1f859d4Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5c1f859d4Smrg * 6c1f859d4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7c1f859d4Smrg * copy of this software and associated documentation files (the "Software"), 8c1f859d4Smrg * to deal in the Software without restriction, including without limitation 9c1f859d4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10c1f859d4Smrg * and/or sell copies of the Software, and to permit persons to whom the 11c1f859d4Smrg * Software is furnished to do so, subject to the following conditions: 12c1f859d4Smrg * 13c1f859d4Smrg * The above copyright notice and this permission notice shall be included 14c1f859d4Smrg * in all copies or substantial portions of the Software. 15c1f859d4Smrg * 16c1f859d4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17c1f859d4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18c1f859d4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 23c1f859d4Smrg */ 24c1f859d4Smrg 25c1f859d4Smrg 26c1f859d4Smrg/** 27c1f859d4Smrg * \file clear.c 28c1f859d4Smrg * glClearColor, glClearIndex, glClear() functions. 29c1f859d4Smrg */ 30c1f859d4Smrg 31c1f859d4Smrg 32c1f859d4Smrg 33c1f859d4Smrg#include "glheader.h" 34c1f859d4Smrg#include "clear.h" 35c1f859d4Smrg#include "context.h" 36c1f859d4Smrg#include "colormac.h" 37cdc920a0Smrg#include "enums.h" 383464ebd5Sriastradh#include "macros.h" 393464ebd5Sriastradh#include "mtypes.h" 40c1f859d4Smrg#include "state.h" 41c1f859d4Smrg 42c1f859d4Smrg 43c1f859d4Smrg 44c1f859d4Smrgvoid GLAPIENTRY 45c1f859d4Smrg_mesa_ClearIndex( GLfloat c ) 46c1f859d4Smrg{ 47c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 48c1f859d4Smrg 49c1f859d4Smrg ctx->Color.ClearIndex = (GLuint) c; 50c1f859d4Smrg} 51c1f859d4Smrg 52c1f859d4Smrg 53c1f859d4Smrg/** 54c1f859d4Smrg * Specify the clear values for the color buffers. 55c1f859d4Smrg * 56c1f859d4Smrg * \param red red color component. 57c1f859d4Smrg * \param green green color component. 58c1f859d4Smrg * \param blue blue color component. 59c1f859d4Smrg * \param alpha alpha component. 60c1f859d4Smrg * 61c1f859d4Smrg * \sa glClearColor(). 62c1f859d4Smrg * 63c1f859d4Smrg * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a 64c1f859d4Smrg * change, flushes the vertices and notifies the driver via the 65c1f859d4Smrg * dd_function_table::ClearColor callback. 66c1f859d4Smrg */ 67c1f859d4Smrgvoid GLAPIENTRY 68c1f859d4Smrg_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) 69c1f859d4Smrg{ 70c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 713464ebd5Sriastradh 72af69d88dSmrg ctx->Color.ClearColor.f[0] = red; 73af69d88dSmrg ctx->Color.ClearColor.f[1] = green; 74af69d88dSmrg ctx->Color.ClearColor.f[2] = blue; 75af69d88dSmrg ctx->Color.ClearColor.f[3] = alpha; 76c1f859d4Smrg} 77c1f859d4Smrg 78c1f859d4Smrg 793464ebd5Sriastradh/** 803464ebd5Sriastradh * GL_EXT_texture_integer 813464ebd5Sriastradh */ 823464ebd5Sriastradhvoid GLAPIENTRY 833464ebd5Sriastradh_mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a) 843464ebd5Sriastradh{ 853464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 863464ebd5Sriastradh 87af69d88dSmrg ctx->Color.ClearColor.i[0] = r; 88af69d88dSmrg ctx->Color.ClearColor.i[1] = g; 89af69d88dSmrg ctx->Color.ClearColor.i[2] = b; 90af69d88dSmrg ctx->Color.ClearColor.i[3] = a; 913464ebd5Sriastradh} 923464ebd5Sriastradh 933464ebd5Sriastradh 943464ebd5Sriastradh/** 953464ebd5Sriastradh * GL_EXT_texture_integer 963464ebd5Sriastradh */ 973464ebd5Sriastradhvoid GLAPIENTRY 983464ebd5Sriastradh_mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a) 993464ebd5Sriastradh{ 1003464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 1013464ebd5Sriastradh 102af69d88dSmrg ctx->Color.ClearColor.ui[0] = r; 103af69d88dSmrg ctx->Color.ClearColor.ui[1] = g; 104af69d88dSmrg ctx->Color.ClearColor.ui[2] = b; 105af69d88dSmrg ctx->Color.ClearColor.ui[3] = a; 106af69d88dSmrg} 1073464ebd5Sriastradh 1083464ebd5Sriastradh 109af69d88dSmrg/** 110af69d88dSmrg * Returns true if color writes are enabled for the given color attachment. 111af69d88dSmrg * 112af69d88dSmrg * Beyond checking ColorMask, this uses _mesa_format_has_color_component to 113af69d88dSmrg * ignore components that don't actually exist in the format (such as X in 114af69d88dSmrg * XRGB). 115af69d88dSmrg */ 116af69d88dSmrgstatic bool 117af69d88dSmrgcolor_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx) 118af69d88dSmrg{ 119af69d88dSmrg struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[idx]; 120af69d88dSmrg GLuint c; 121af69d88dSmrg GLubyte colorMask = 0; 122af69d88dSmrg 123af69d88dSmrg if (rb) { 124af69d88dSmrg for (c = 0; c < 4; c++) { 125af69d88dSmrg if (_mesa_format_has_color_component(rb->Format, c)) 126af69d88dSmrg colorMask |= ctx->Color.ColorMask[idx][c]; 127af69d88dSmrg } 1283464ebd5Sriastradh } 129af69d88dSmrg 130af69d88dSmrg return colorMask != 0; 1313464ebd5Sriastradh} 1323464ebd5Sriastradh 1333464ebd5Sriastradh 134c1f859d4Smrg/** 135c1f859d4Smrg * Clear buffers. 136c1f859d4Smrg * 137c1f859d4Smrg * \param mask bit-mask indicating the buffers to be cleared. 138c1f859d4Smrg * 1393464ebd5Sriastradh * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState 140c1f859d4Smrg * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin, 141c1f859d4Smrg * etc. If the rasterization mode is set to GL_RENDER then requests the driver 142c1f859d4Smrg * to clear the buffers, via the dd_function_table::Clear callback. 143c1f859d4Smrg */ 144c1f859d4Smrgvoid GLAPIENTRY 145c1f859d4Smrg_mesa_Clear( GLbitfield mask ) 146c1f859d4Smrg{ 147c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 148af69d88dSmrg FLUSH_VERTICES(ctx, 0); 149c1f859d4Smrg 150c1f859d4Smrg FLUSH_CURRENT(ctx, 0); 151c1f859d4Smrg 152c1f859d4Smrg if (MESA_VERBOSE & VERBOSE_API) 153c1f859d4Smrg _mesa_debug(ctx, "glClear 0x%x\n", mask); 154c1f859d4Smrg 155c1f859d4Smrg if (mask & ~(GL_COLOR_BUFFER_BIT | 156c1f859d4Smrg GL_DEPTH_BUFFER_BIT | 157c1f859d4Smrg GL_STENCIL_BUFFER_BIT | 158c1f859d4Smrg GL_ACCUM_BUFFER_BIT)) { 159c1f859d4Smrg /* invalid bit set */ 160c1f859d4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask); 161c1f859d4Smrg return; 162c1f859d4Smrg } 163c1f859d4Smrg 164af69d88dSmrg /* Accumulation buffers were removed in core contexts, and they never 165af69d88dSmrg * existed in OpenGL ES. 166af69d88dSmrg */ 167af69d88dSmrg if ((mask & GL_ACCUM_BUFFER_BIT) != 0 168af69d88dSmrg && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) { 169af69d88dSmrg _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)"); 170af69d88dSmrg return; 171af69d88dSmrg } 172af69d88dSmrg 173c1f859d4Smrg if (ctx->NewState) { 174c1f859d4Smrg _mesa_update_state( ctx ); /* update _Xmin, etc */ 175c1f859d4Smrg } 176c1f859d4Smrg 177c1f859d4Smrg if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 178c1f859d4Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 179c1f859d4Smrg "glClear(incomplete framebuffer)"); 180c1f859d4Smrg return; 181c1f859d4Smrg } 182c1f859d4Smrg 183af69d88dSmrg if (ctx->RasterDiscard) 184c1f859d4Smrg return; 185c1f859d4Smrg 186c1f859d4Smrg if (ctx->RenderMode == GL_RENDER) { 187c1f859d4Smrg GLbitfield bufferMask; 188c1f859d4Smrg 189c1f859d4Smrg /* don't clear depth buffer if depth writing disabled */ 190c1f859d4Smrg if (!ctx->Depth.Mask) 191c1f859d4Smrg mask &= ~GL_DEPTH_BUFFER_BIT; 192c1f859d4Smrg 193c1f859d4Smrg /* Build the bitmask to send to device driver's Clear function. 194c1f859d4Smrg * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4 195c1f859d4Smrg * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the 196c1f859d4Smrg * BUFFER_BIT_COLORn flags. 197c1f859d4Smrg */ 198c1f859d4Smrg bufferMask = 0; 199c1f859d4Smrg if (mask & GL_COLOR_BUFFER_BIT) { 200c1f859d4Smrg GLuint i; 201c1f859d4Smrg for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { 202af69d88dSmrg GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; 203af69d88dSmrg 204af69d88dSmrg if (buf >= 0 && color_buffer_writes_enabled(ctx, i)) { 205af69d88dSmrg bufferMask |= 1 << buf; 206af69d88dSmrg } 207c1f859d4Smrg } 208c1f859d4Smrg } 209c1f859d4Smrg 210c1f859d4Smrg if ((mask & GL_DEPTH_BUFFER_BIT) 211c1f859d4Smrg && ctx->DrawBuffer->Visual.haveDepthBuffer) { 212c1f859d4Smrg bufferMask |= BUFFER_BIT_DEPTH; 213c1f859d4Smrg } 214c1f859d4Smrg 215c1f859d4Smrg if ((mask & GL_STENCIL_BUFFER_BIT) 216c1f859d4Smrg && ctx->DrawBuffer->Visual.haveStencilBuffer) { 217c1f859d4Smrg bufferMask |= BUFFER_BIT_STENCIL; 218c1f859d4Smrg } 219c1f859d4Smrg 220c1f859d4Smrg if ((mask & GL_ACCUM_BUFFER_BIT) 221c1f859d4Smrg && ctx->DrawBuffer->Visual.haveAccumBuffer) { 222c1f859d4Smrg bufferMask |= BUFFER_BIT_ACCUM; 223c1f859d4Smrg } 224c1f859d4Smrg 225c1f859d4Smrg ASSERT(ctx->Driver.Clear); 226c1f859d4Smrg ctx->Driver.Clear(ctx, bufferMask); 227c1f859d4Smrg } 228c1f859d4Smrg} 229cdc920a0Smrg 230cdc920a0Smrg 231cdc920a0Smrg/** Returned by make_color_buffer_mask() for errors */ 232cdc920a0Smrg#define INVALID_MASK ~0x0 233cdc920a0Smrg 234cdc920a0Smrg 235cdc920a0Smrg/** 236cdc920a0Smrg * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of 237cdc920a0Smrg * BUFFER_BIT_x values. 238cdc920a0Smrg * Return INVALID_MASK if the drawbuffer value is invalid. 239cdc920a0Smrg */ 240cdc920a0Smrgstatic GLbitfield 2413464ebd5Sriastradhmake_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer) 242cdc920a0Smrg{ 243cdc920a0Smrg const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment; 244cdc920a0Smrg GLbitfield mask = 0x0; 245cdc920a0Smrg 246af69d88dSmrg /* From the GL 4.0 specification: 247af69d88dSmrg * If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is 248af69d88dSmrg * specified by passing i as the parameter drawbuffer, and value 249af69d88dSmrg * points to a four-element vector specifying the R, G, B, and A 250af69d88dSmrg * color to clear that draw buffer to. If the draw buffer is one 251af69d88dSmrg * of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying 252af69d88dSmrg * multiple buffers, each selected buffer is cleared to the same 253af69d88dSmrg * value. 254af69d88dSmrg * 255af69d88dSmrg * Note that "drawbuffer" and "draw buffer" have different meaning. 256af69d88dSmrg * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's 257af69d88dSmrg * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK, 258af69d88dSmrg * etc. 259af69d88dSmrg */ 260af69d88dSmrg if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) { 261af69d88dSmrg return INVALID_MASK; 262af69d88dSmrg } 263af69d88dSmrg 264af69d88dSmrg switch (ctx->DrawBuffer->ColorDrawBuffer[drawbuffer]) { 265cdc920a0Smrg case GL_FRONT: 266cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 267cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 268cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 269cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 270cdc920a0Smrg break; 271cdc920a0Smrg case GL_BACK: 272cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 273cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 274cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 275cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 276cdc920a0Smrg break; 277cdc920a0Smrg case GL_LEFT: 278cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 279cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 280cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 281cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 282cdc920a0Smrg break; 283cdc920a0Smrg case GL_RIGHT: 284cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 285cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 286cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 287cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 288cdc920a0Smrg break; 289cdc920a0Smrg case GL_FRONT_AND_BACK: 290cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 291cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 292cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 293cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 294cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 295cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 296cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 297cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 298cdc920a0Smrg break; 299cdc920a0Smrg default: 300af69d88dSmrg { 301af69d88dSmrg GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer]; 302af69d88dSmrg 303af69d88dSmrg if (buf >= 0 && att[buf].Renderbuffer) { 304af69d88dSmrg mask |= 1 << buf; 305af69d88dSmrg } 306cdc920a0Smrg } 307cdc920a0Smrg } 308cdc920a0Smrg 309cdc920a0Smrg return mask; 310cdc920a0Smrg} 311cdc920a0Smrg 312cdc920a0Smrg 313cdc920a0Smrg 314cdc920a0Smrg/** 315cdc920a0Smrg * New in GL 3.0 316cdc920a0Smrg * Clear signed integer color buffer or stencil buffer (not depth). 317cdc920a0Smrg */ 318cdc920a0Smrgvoid GLAPIENTRY 319cdc920a0Smrg_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) 320cdc920a0Smrg{ 321cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 322af69d88dSmrg FLUSH_VERTICES(ctx, 0); 323cdc920a0Smrg 324cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 325cdc920a0Smrg 326cdc920a0Smrg if (ctx->NewState) { 327cdc920a0Smrg _mesa_update_state( ctx ); 328cdc920a0Smrg } 329cdc920a0Smrg 330cdc920a0Smrg switch (buffer) { 331cdc920a0Smrg case GL_STENCIL: 332af69d88dSmrg /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: 333af69d88dSmrg * 334af69d88dSmrg * "ClearBuffer generates an INVALID VALUE error if buffer is 335af69d88dSmrg * COLOR and drawbuffer is less than zero, or greater than the 336af69d88dSmrg * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, 337af69d88dSmrg * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." 338af69d88dSmrg */ 339cdc920a0Smrg if (drawbuffer != 0) { 340cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 341cdc920a0Smrg drawbuffer); 342cdc920a0Smrg return; 343cdc920a0Smrg } 344af69d88dSmrg else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer && !ctx->RasterDiscard) { 345cdc920a0Smrg /* Save current stencil clear value, set to 'value', do the 346cdc920a0Smrg * stencil clear and restore the clear value. 347cdc920a0Smrg * XXX in the future we may have a new ctx->Driver.ClearBuffer() 348cdc920a0Smrg * hook instead. 349cdc920a0Smrg */ 350cdc920a0Smrg const GLuint clearSave = ctx->Stencil.Clear; 351cdc920a0Smrg ctx->Stencil.Clear = *value; 352cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL); 353cdc920a0Smrg ctx->Stencil.Clear = clearSave; 354cdc920a0Smrg } 355cdc920a0Smrg break; 356cdc920a0Smrg case GL_COLOR: 357cdc920a0Smrg { 358cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 359cdc920a0Smrg if (mask == INVALID_MASK) { 360cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 361cdc920a0Smrg drawbuffer); 362cdc920a0Smrg return; 363cdc920a0Smrg } 364af69d88dSmrg else if (mask && !ctx->RasterDiscard) { 365af69d88dSmrg union gl_color_union clearSave; 366af69d88dSmrg 367cdc920a0Smrg /* save color */ 368af69d88dSmrg clearSave = ctx->Color.ClearColor; 369cdc920a0Smrg /* set color */ 370af69d88dSmrg COPY_4V(ctx->Color.ClearColor.i, value); 371cdc920a0Smrg /* clear buffer(s) */ 372cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 373cdc920a0Smrg /* restore color */ 374af69d88dSmrg ctx->Color.ClearColor = clearSave; 375cdc920a0Smrg } 376cdc920a0Smrg } 377cdc920a0Smrg break; 378af69d88dSmrg case GL_DEPTH: 379af69d88dSmrg /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: 380af69d88dSmrg * 381af69d88dSmrg * "The result of ClearBuffer is undefined if no conversion between 382af69d88dSmrg * the type of the specified value and the type of the buffer being 383af69d88dSmrg * cleared is defined (for example, if ClearBufferiv is called for a 384af69d88dSmrg * fixed- or floating-point buffer, or if ClearBufferfv is called 385af69d88dSmrg * for a signed or unsigned integer buffer). This is not an error." 386af69d88dSmrg * 387af69d88dSmrg * In this case we take "undefined" and "not an error" to mean "ignore." 388af69d88dSmrg * Note that we still need to generate an error for the invalid 389af69d88dSmrg * drawbuffer case (see the GL_STENCIL case above). 390af69d88dSmrg */ 391af69d88dSmrg if (drawbuffer != 0) { 392af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 393af69d88dSmrg drawbuffer); 394af69d88dSmrg return; 395af69d88dSmrg } 396af69d88dSmrg return; 397cdc920a0Smrg default: 398cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)", 399cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 400cdc920a0Smrg return; 401cdc920a0Smrg } 402cdc920a0Smrg} 403cdc920a0Smrg 404cdc920a0Smrg 405cdc920a0Smrg/** 406cdc920a0Smrg * New in GL 3.0 407cdc920a0Smrg * Clear unsigned integer color buffer (not depth, not stencil). 408cdc920a0Smrg */ 409cdc920a0Smrgvoid GLAPIENTRY 410cdc920a0Smrg_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) 411cdc920a0Smrg{ 412cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 413cdc920a0Smrg 414af69d88dSmrg FLUSH_VERTICES(ctx, 0); 415cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 416cdc920a0Smrg 417cdc920a0Smrg if (ctx->NewState) { 418cdc920a0Smrg _mesa_update_state( ctx ); 419cdc920a0Smrg } 420cdc920a0Smrg 421cdc920a0Smrg switch (buffer) { 422cdc920a0Smrg case GL_COLOR: 423cdc920a0Smrg { 424cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 425cdc920a0Smrg if (mask == INVALID_MASK) { 4263464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)", 427cdc920a0Smrg drawbuffer); 428cdc920a0Smrg return; 429cdc920a0Smrg } 430af69d88dSmrg else if (mask && !ctx->RasterDiscard) { 431af69d88dSmrg union gl_color_union clearSave; 432af69d88dSmrg 433cdc920a0Smrg /* save color */ 434af69d88dSmrg clearSave = ctx->Color.ClearColor; 435cdc920a0Smrg /* set color */ 436af69d88dSmrg COPY_4V(ctx->Color.ClearColor.ui, value); 437cdc920a0Smrg /* clear buffer(s) */ 438cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 439cdc920a0Smrg /* restore color */ 440af69d88dSmrg ctx->Color.ClearColor = clearSave; 441cdc920a0Smrg } 442cdc920a0Smrg } 443cdc920a0Smrg break; 444af69d88dSmrg case GL_DEPTH: 445af69d88dSmrg case GL_STENCIL: 446af69d88dSmrg /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: 447af69d88dSmrg * 448af69d88dSmrg * "The result of ClearBuffer is undefined if no conversion between 449af69d88dSmrg * the type of the specified value and the type of the buffer being 450af69d88dSmrg * cleared is defined (for example, if ClearBufferiv is called for a 451af69d88dSmrg * fixed- or floating-point buffer, or if ClearBufferfv is called 452af69d88dSmrg * for a signed or unsigned integer buffer). This is not an error." 453af69d88dSmrg * 454af69d88dSmrg * In this case we take "undefined" and "not an error" to mean "ignore." 455af69d88dSmrg * Even though we could do something sensible for GL_STENCIL, page 263 456af69d88dSmrg * (page 279 of the PDF) says: 457af69d88dSmrg * 458af69d88dSmrg * "Only ClearBufferiv should be used to clear stencil buffers." 459af69d88dSmrg * 460af69d88dSmrg * Note that we still need to generate an error for the invalid 461af69d88dSmrg * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv). 462af69d88dSmrg */ 463af69d88dSmrg if (drawbuffer != 0) { 464af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)", 465af69d88dSmrg drawbuffer); 466af69d88dSmrg return; 467af69d88dSmrg } 468af69d88dSmrg return; 469cdc920a0Smrg default: 470cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)", 471cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 472cdc920a0Smrg return; 473cdc920a0Smrg } 474cdc920a0Smrg} 475cdc920a0Smrg 476cdc920a0Smrg 477cdc920a0Smrg/** 478cdc920a0Smrg * New in GL 3.0 479cdc920a0Smrg * Clear fixed-pt or float color buffer or depth buffer (not stencil). 480cdc920a0Smrg */ 481cdc920a0Smrgvoid GLAPIENTRY 482cdc920a0Smrg_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) 483cdc920a0Smrg{ 484cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 485cdc920a0Smrg 486af69d88dSmrg FLUSH_VERTICES(ctx, 0); 487cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 488cdc920a0Smrg 489cdc920a0Smrg if (ctx->NewState) { 490cdc920a0Smrg _mesa_update_state( ctx ); 491cdc920a0Smrg } 492cdc920a0Smrg 493cdc920a0Smrg switch (buffer) { 494cdc920a0Smrg case GL_DEPTH: 495af69d88dSmrg /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: 496af69d88dSmrg * 497af69d88dSmrg * "ClearBuffer generates an INVALID VALUE error if buffer is 498af69d88dSmrg * COLOR and drawbuffer is less than zero, or greater than the 499af69d88dSmrg * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, 500af69d88dSmrg * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." 501af69d88dSmrg */ 502cdc920a0Smrg if (drawbuffer != 0) { 503cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", 504cdc920a0Smrg drawbuffer); 505cdc920a0Smrg return; 506cdc920a0Smrg } 507af69d88dSmrg else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer && !ctx->RasterDiscard) { 508cdc920a0Smrg /* Save current depth clear value, set to 'value', do the 509cdc920a0Smrg * depth clear and restore the clear value. 510cdc920a0Smrg * XXX in the future we may have a new ctx->Driver.ClearBuffer() 511cdc920a0Smrg * hook instead. 512cdc920a0Smrg */ 513cdc920a0Smrg const GLclampd clearSave = ctx->Depth.Clear; 514cdc920a0Smrg ctx->Depth.Clear = *value; 515cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH); 516cdc920a0Smrg ctx->Depth.Clear = clearSave; 517cdc920a0Smrg } 518cdc920a0Smrg /* clear depth buffer to value */ 519cdc920a0Smrg break; 520cdc920a0Smrg case GL_COLOR: 521cdc920a0Smrg { 522cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 523cdc920a0Smrg if (mask == INVALID_MASK) { 524cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", 525cdc920a0Smrg drawbuffer); 526cdc920a0Smrg return; 527cdc920a0Smrg } 528af69d88dSmrg else if (mask && !ctx->RasterDiscard) { 529af69d88dSmrg union gl_color_union clearSave; 530af69d88dSmrg 531cdc920a0Smrg /* save color */ 532af69d88dSmrg clearSave = ctx->Color.ClearColor; 533cdc920a0Smrg /* set color */ 534af69d88dSmrg COPY_4V(ctx->Color.ClearColor.f, value); 535cdc920a0Smrg /* clear buffer(s) */ 536cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 537cdc920a0Smrg /* restore color */ 538af69d88dSmrg ctx->Color.ClearColor = clearSave; 539cdc920a0Smrg } 540cdc920a0Smrg } 541cdc920a0Smrg break; 542af69d88dSmrg case GL_STENCIL: 543af69d88dSmrg /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: 544af69d88dSmrg * 545af69d88dSmrg * "The result of ClearBuffer is undefined if no conversion between 546af69d88dSmrg * the type of the specified value and the type of the buffer being 547af69d88dSmrg * cleared is defined (for example, if ClearBufferiv is called for a 548af69d88dSmrg * fixed- or floating-point buffer, or if ClearBufferfv is called 549af69d88dSmrg * for a signed or unsigned integer buffer). This is not an error." 550af69d88dSmrg * 551af69d88dSmrg * In this case we take "undefined" and "not an error" to mean "ignore." 552af69d88dSmrg * Note that we still need to generate an error for the invalid 553af69d88dSmrg * drawbuffer case (see the GL_DEPTH case above). 554af69d88dSmrg */ 555af69d88dSmrg if (drawbuffer != 0) { 556af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", 557af69d88dSmrg drawbuffer); 558af69d88dSmrg return; 559af69d88dSmrg } 560af69d88dSmrg return; 561cdc920a0Smrg default: 562cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)", 563cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 564cdc920a0Smrg return; 565cdc920a0Smrg } 566cdc920a0Smrg} 567cdc920a0Smrg 568cdc920a0Smrg 569cdc920a0Smrg/** 570cdc920a0Smrg * New in GL 3.0 571cdc920a0Smrg * Clear depth/stencil buffer only. 572cdc920a0Smrg */ 573cdc920a0Smrgvoid GLAPIENTRY 574cdc920a0Smrg_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, 575cdc920a0Smrg GLfloat depth, GLint stencil) 576cdc920a0Smrg{ 577cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 578af69d88dSmrg GLbitfield mask = 0; 579cdc920a0Smrg 580af69d88dSmrg FLUSH_VERTICES(ctx, 0); 581cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 582cdc920a0Smrg 583cdc920a0Smrg if (buffer != GL_DEPTH_STENCIL) { 584cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)", 585cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 586cdc920a0Smrg return; 587cdc920a0Smrg } 588cdc920a0Smrg 589af69d88dSmrg /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: 590af69d88dSmrg * 591af69d88dSmrg * "ClearBuffer generates an INVALID VALUE error if buffer is 592af69d88dSmrg * COLOR and drawbuffer is less than zero, or greater than the 593af69d88dSmrg * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, 594af69d88dSmrg * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." 595af69d88dSmrg */ 596cdc920a0Smrg if (drawbuffer != 0) { 597cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)", 598cdc920a0Smrg drawbuffer); 599cdc920a0Smrg return; 600cdc920a0Smrg } 601cdc920a0Smrg 602af69d88dSmrg if (ctx->RasterDiscard) 603af69d88dSmrg return; 604af69d88dSmrg 605cdc920a0Smrg if (ctx->NewState) { 606cdc920a0Smrg _mesa_update_state( ctx ); 607cdc920a0Smrg } 608cdc920a0Smrg 609af69d88dSmrg if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer) 610af69d88dSmrg mask |= BUFFER_BIT_DEPTH; 611af69d88dSmrg if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer) 612af69d88dSmrg mask |= BUFFER_BIT_STENCIL; 613af69d88dSmrg 614af69d88dSmrg if (mask) { 615cdc920a0Smrg /* save current clear values */ 616cdc920a0Smrg const GLclampd clearDepthSave = ctx->Depth.Clear; 617cdc920a0Smrg const GLuint clearStencilSave = ctx->Stencil.Clear; 618cdc920a0Smrg 619cdc920a0Smrg /* set new clear values */ 620cdc920a0Smrg ctx->Depth.Clear = depth; 621cdc920a0Smrg ctx->Stencil.Clear = stencil; 622cdc920a0Smrg 623cdc920a0Smrg /* clear buffers */ 624af69d88dSmrg ctx->Driver.Clear(ctx, mask); 625cdc920a0Smrg 626cdc920a0Smrg /* restore */ 627cdc920a0Smrg ctx->Depth.Clear = clearDepthSave; 628cdc920a0Smrg ctx->Stencil.Clear = clearStencilSave; 629cdc920a0Smrg } 630cdc920a0Smrg} 631