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 337ec681f3Smrg#include "glformats.h" 34c1f859d4Smrg#include "glheader.h" 35c1f859d4Smrg#include "clear.h" 36c1f859d4Smrg#include "context.h" 37cdc920a0Smrg#include "enums.h" 3801e04c3fSmrg#include "fbobject.h" 3901e04c3fSmrg#include "get.h" 403464ebd5Sriastradh#include "macros.h" 413464ebd5Sriastradh#include "mtypes.h" 42c1f859d4Smrg#include "state.h" 43c1f859d4Smrg 44c1f859d4Smrg 45c1f859d4Smrg 46c1f859d4Smrgvoid GLAPIENTRY 47c1f859d4Smrg_mesa_ClearIndex( GLfloat c ) 48c1f859d4Smrg{ 49c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 50c1f859d4Smrg 517ec681f3Smrg ctx->PopAttribState |= GL_COLOR_BUFFER_BIT; 52c1f859d4Smrg ctx->Color.ClearIndex = (GLuint) c; 53c1f859d4Smrg} 54c1f859d4Smrg 55c1f859d4Smrg 56c1f859d4Smrg/** 57c1f859d4Smrg * Specify the clear values for the color buffers. 58c1f859d4Smrg * 59c1f859d4Smrg * \param red red color component. 60c1f859d4Smrg * \param green green color component. 61c1f859d4Smrg * \param blue blue color component. 62c1f859d4Smrg * \param alpha alpha component. 63c1f859d4Smrg * 64c1f859d4Smrg * \sa glClearColor(). 65c1f859d4Smrg */ 66c1f859d4Smrgvoid GLAPIENTRY 67c1f859d4Smrg_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) 68c1f859d4Smrg{ 69c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 703464ebd5Sriastradh 717ec681f3Smrg ctx->PopAttribState |= GL_COLOR_BUFFER_BIT; 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 877ec681f3Smrg ctx->PopAttribState |= GL_COLOR_BUFFER_BIT; 88af69d88dSmrg ctx->Color.ClearColor.i[0] = r; 89af69d88dSmrg ctx->Color.ClearColor.i[1] = g; 90af69d88dSmrg ctx->Color.ClearColor.i[2] = b; 91af69d88dSmrg ctx->Color.ClearColor.i[3] = a; 923464ebd5Sriastradh} 933464ebd5Sriastradh 943464ebd5Sriastradh 953464ebd5Sriastradh/** 963464ebd5Sriastradh * GL_EXT_texture_integer 973464ebd5Sriastradh */ 983464ebd5Sriastradhvoid GLAPIENTRY 993464ebd5Sriastradh_mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a) 1003464ebd5Sriastradh{ 1013464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 1023464ebd5Sriastradh 1037ec681f3Smrg ctx->PopAttribState |= GL_COLOR_BUFFER_BIT; 104af69d88dSmrg ctx->Color.ClearColor.ui[0] = r; 105af69d88dSmrg ctx->Color.ClearColor.ui[1] = g; 106af69d88dSmrg ctx->Color.ClearColor.ui[2] = b; 107af69d88dSmrg ctx->Color.ClearColor.ui[3] = a; 108af69d88dSmrg} 1093464ebd5Sriastradh 1103464ebd5Sriastradh 111af69d88dSmrg/** 112af69d88dSmrg * Returns true if color writes are enabled for the given color attachment. 113af69d88dSmrg * 114af69d88dSmrg * Beyond checking ColorMask, this uses _mesa_format_has_color_component to 115af69d88dSmrg * ignore components that don't actually exist in the format (such as X in 116af69d88dSmrg * XRGB). 117af69d88dSmrg */ 118af69d88dSmrgstatic bool 119af69d88dSmrgcolor_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx) 120af69d88dSmrg{ 121af69d88dSmrg struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[idx]; 122af69d88dSmrg GLuint c; 123af69d88dSmrg 124af69d88dSmrg if (rb) { 125af69d88dSmrg for (c = 0; c < 4; c++) { 12601e04c3fSmrg if (GET_COLORMASK_BIT(ctx->Color.ColorMask, idx, c) && 12701e04c3fSmrg _mesa_format_has_color_component(rb->Format, c)) { 12801e04c3fSmrg return true; 12901e04c3fSmrg } 130af69d88dSmrg } 1313464ebd5Sriastradh } 132af69d88dSmrg 13301e04c3fSmrg return false; 1343464ebd5Sriastradh} 1353464ebd5Sriastradh 1363464ebd5Sriastradh 137c1f859d4Smrg/** 138c1f859d4Smrg * Clear buffers. 13901e04c3fSmrg * 140c1f859d4Smrg * \param mask bit-mask indicating the buffers to be cleared. 141c1f859d4Smrg * 14201e04c3fSmrg * Flushes the vertices and verifies the parameter. 14301e04c3fSmrg * If __struct gl_contextRec::NewState is set then calls _mesa_update_state() 14401e04c3fSmrg * to update gl_frame_buffer::_Xmin, etc. If the rasterization mode is set to 14501e04c3fSmrg * GL_RENDER then requests the driver to clear the buffers, via the 14601e04c3fSmrg * dd_function_table::Clear callback. 14701e04c3fSmrg */ 14801e04c3fSmrgstatic ALWAYS_INLINE void 14901e04c3fSmrgclear(struct gl_context *ctx, GLbitfield mask, bool no_error) 150c1f859d4Smrg{ 1517ec681f3Smrg FLUSH_VERTICES(ctx, 0, 0); 152c1f859d4Smrg 15301e04c3fSmrg if (!no_error) { 15401e04c3fSmrg if (mask & ~(GL_COLOR_BUFFER_BIT | 15501e04c3fSmrg GL_DEPTH_BUFFER_BIT | 15601e04c3fSmrg GL_STENCIL_BUFFER_BIT | 15701e04c3fSmrg GL_ACCUM_BUFFER_BIT)) { 15801e04c3fSmrg _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask); 15901e04c3fSmrg return; 16001e04c3fSmrg } 161c1f859d4Smrg 16201e04c3fSmrg /* Accumulation buffers were removed in core contexts, and they never 16301e04c3fSmrg * existed in OpenGL ES. 16401e04c3fSmrg */ 16501e04c3fSmrg if ((mask & GL_ACCUM_BUFFER_BIT) != 0 16601e04c3fSmrg && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) { 16701e04c3fSmrg _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)"); 16801e04c3fSmrg return; 16901e04c3fSmrg } 170af69d88dSmrg } 171af69d88dSmrg 172c1f859d4Smrg if (ctx->NewState) { 173c1f859d4Smrg _mesa_update_state( ctx ); /* update _Xmin, etc */ 174c1f859d4Smrg } 175c1f859d4Smrg 17601e04c3fSmrg if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 177c1f859d4Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 178c1f859d4Smrg "glClear(incomplete framebuffer)"); 179c1f859d4Smrg return; 180c1f859d4Smrg } 181c1f859d4Smrg 182af69d88dSmrg if (ctx->RasterDiscard) 183c1f859d4Smrg return; 184c1f859d4Smrg 185c1f859d4Smrg if (ctx->RenderMode == GL_RENDER) { 186c1f859d4Smrg GLbitfield bufferMask; 187c1f859d4Smrg 188c1f859d4Smrg /* don't clear depth buffer if depth writing disabled */ 189c1f859d4Smrg if (!ctx->Depth.Mask) 190c1f859d4Smrg mask &= ~GL_DEPTH_BUFFER_BIT; 191c1f859d4Smrg 192c1f859d4Smrg /* Build the bitmask to send to device driver's Clear function. 193c1f859d4Smrg * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4 194c1f859d4Smrg * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the 195c1f859d4Smrg * BUFFER_BIT_COLORn flags. 196c1f859d4Smrg */ 197c1f859d4Smrg bufferMask = 0; 198c1f859d4Smrg if (mask & GL_COLOR_BUFFER_BIT) { 199c1f859d4Smrg GLuint i; 200c1f859d4Smrg for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { 20101e04c3fSmrg gl_buffer_index buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; 202af69d88dSmrg 20301e04c3fSmrg if (buf != BUFFER_NONE && color_buffer_writes_enabled(ctx, i)) { 204af69d88dSmrg bufferMask |= 1 << buf; 205af69d88dSmrg } 206c1f859d4Smrg } 207c1f859d4Smrg } 208c1f859d4Smrg 209c1f859d4Smrg if ((mask & GL_DEPTH_BUFFER_BIT) 2107ec681f3Smrg && ctx->DrawBuffer->Visual.depthBits > 0) { 211c1f859d4Smrg bufferMask |= BUFFER_BIT_DEPTH; 212c1f859d4Smrg } 213c1f859d4Smrg 214c1f859d4Smrg if ((mask & GL_STENCIL_BUFFER_BIT) 2157ec681f3Smrg && ctx->DrawBuffer->Visual.stencilBits > 0) { 216c1f859d4Smrg bufferMask |= BUFFER_BIT_STENCIL; 217c1f859d4Smrg } 218c1f859d4Smrg 219c1f859d4Smrg if ((mask & GL_ACCUM_BUFFER_BIT) 2207ec681f3Smrg && ctx->DrawBuffer->Visual.accumRedBits > 0) { 221c1f859d4Smrg bufferMask |= BUFFER_BIT_ACCUM; 222c1f859d4Smrg } 223c1f859d4Smrg 22401e04c3fSmrg assert(ctx->Driver.Clear); 225c1f859d4Smrg ctx->Driver.Clear(ctx, bufferMask); 226c1f859d4Smrg } 227c1f859d4Smrg} 228cdc920a0Smrg 229cdc920a0Smrg 23001e04c3fSmrgvoid GLAPIENTRY 23101e04c3fSmrg_mesa_Clear_no_error(GLbitfield mask) 23201e04c3fSmrg{ 23301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 23401e04c3fSmrg clear(ctx, mask, true); 23501e04c3fSmrg} 23601e04c3fSmrg 23701e04c3fSmrg 23801e04c3fSmrgvoid GLAPIENTRY 23901e04c3fSmrg_mesa_Clear(GLbitfield mask) 24001e04c3fSmrg{ 24101e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 24201e04c3fSmrg 24301e04c3fSmrg if (MESA_VERBOSE & VERBOSE_API) 24401e04c3fSmrg _mesa_debug(ctx, "glClear 0x%x\n", mask); 24501e04c3fSmrg 24601e04c3fSmrg clear(ctx, mask, false); 24701e04c3fSmrg} 24801e04c3fSmrg 24901e04c3fSmrg 250cdc920a0Smrg/** Returned by make_color_buffer_mask() for errors */ 25101e04c3fSmrg#define INVALID_MASK ~0x0U 252cdc920a0Smrg 253cdc920a0Smrg 254cdc920a0Smrg/** 255cdc920a0Smrg * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of 256cdc920a0Smrg * BUFFER_BIT_x values. 257cdc920a0Smrg * Return INVALID_MASK if the drawbuffer value is invalid. 258cdc920a0Smrg */ 259cdc920a0Smrgstatic GLbitfield 2603464ebd5Sriastradhmake_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer) 261cdc920a0Smrg{ 262cdc920a0Smrg const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment; 263cdc920a0Smrg GLbitfield mask = 0x0; 264cdc920a0Smrg 265af69d88dSmrg /* From the GL 4.0 specification: 266af69d88dSmrg * If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is 267af69d88dSmrg * specified by passing i as the parameter drawbuffer, and value 268af69d88dSmrg * points to a four-element vector specifying the R, G, B, and A 269af69d88dSmrg * color to clear that draw buffer to. If the draw buffer is one 270af69d88dSmrg * of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying 271af69d88dSmrg * multiple buffers, each selected buffer is cleared to the same 272af69d88dSmrg * value. 273af69d88dSmrg * 274af69d88dSmrg * Note that "drawbuffer" and "draw buffer" have different meaning. 275af69d88dSmrg * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's 276af69d88dSmrg * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK, 277af69d88dSmrg * etc. 278af69d88dSmrg */ 279af69d88dSmrg if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) { 280af69d88dSmrg return INVALID_MASK; 281af69d88dSmrg } 282af69d88dSmrg 283af69d88dSmrg switch (ctx->DrawBuffer->ColorDrawBuffer[drawbuffer]) { 284cdc920a0Smrg case GL_FRONT: 285cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 286cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 287cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 288cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 289cdc920a0Smrg break; 290cdc920a0Smrg case GL_BACK: 29101e04c3fSmrg /* For GLES contexts with a single buffered configuration, we actually 29201e04c3fSmrg * only have a front renderbuffer, so any clear calls to GL_BACK should 29301e04c3fSmrg * affect that buffer. See draw_buffer_enum_to_bitmask for details. 29401e04c3fSmrg */ 29501e04c3fSmrg if (_mesa_is_gles(ctx)) 29601e04c3fSmrg if (!ctx->DrawBuffer->Visual.doubleBufferMode) 29701e04c3fSmrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 29801e04c3fSmrg mask |= BUFFER_BIT_FRONT_LEFT; 299cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 300cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 301cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 302cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 303cdc920a0Smrg break; 304cdc920a0Smrg case GL_LEFT: 305cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 306cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 307cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 308cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 309cdc920a0Smrg break; 310cdc920a0Smrg case GL_RIGHT: 311cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 312cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 313cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 314cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 315cdc920a0Smrg break; 316cdc920a0Smrg case GL_FRONT_AND_BACK: 317cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 318cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 319cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 320cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 321cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 322cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 323cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 324cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 325cdc920a0Smrg break; 326cdc920a0Smrg default: 327af69d88dSmrg { 32801e04c3fSmrg gl_buffer_index buf = 32901e04c3fSmrg ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer]; 330af69d88dSmrg 33101e04c3fSmrg if (buf != BUFFER_NONE && att[buf].Renderbuffer) { 332af69d88dSmrg mask |= 1 << buf; 333af69d88dSmrg } 334cdc920a0Smrg } 335cdc920a0Smrg } 336cdc920a0Smrg 337cdc920a0Smrg return mask; 338cdc920a0Smrg} 339cdc920a0Smrg 340cdc920a0Smrg 341cdc920a0Smrg 342cdc920a0Smrg/** 343cdc920a0Smrg * New in GL 3.0 344cdc920a0Smrg * Clear signed integer color buffer or stencil buffer (not depth). 345cdc920a0Smrg */ 34601e04c3fSmrgstatic ALWAYS_INLINE void 34701e04c3fSmrgclear_bufferiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, 34801e04c3fSmrg const GLint *value, bool no_error) 349cdc920a0Smrg{ 3507ec681f3Smrg FLUSH_VERTICES(ctx, 0, 0); 351cdc920a0Smrg 352cdc920a0Smrg if (ctx->NewState) { 353cdc920a0Smrg _mesa_update_state( ctx ); 354cdc920a0Smrg } 355cdc920a0Smrg 3567ec681f3Smrg if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 3577ec681f3Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 3587ec681f3Smrg "glClearBufferiv(incomplete framebuffer)"); 3597ec681f3Smrg return; 3607ec681f3Smrg } 3617ec681f3Smrg 362cdc920a0Smrg switch (buffer) { 363cdc920a0Smrg case GL_STENCIL: 364af69d88dSmrg /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: 365af69d88dSmrg * 366af69d88dSmrg * "ClearBuffer generates an INVALID VALUE error if buffer is 367af69d88dSmrg * COLOR and drawbuffer is less than zero, or greater than the 368af69d88dSmrg * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, 369af69d88dSmrg * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." 370af69d88dSmrg */ 37101e04c3fSmrg if (!no_error && drawbuffer != 0) { 372cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 373cdc920a0Smrg drawbuffer); 374cdc920a0Smrg return; 375cdc920a0Smrg } 37601e04c3fSmrg else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer 37701e04c3fSmrg && !ctx->RasterDiscard) { 378cdc920a0Smrg /* Save current stencil clear value, set to 'value', do the 379cdc920a0Smrg * stencil clear and restore the clear value. 380cdc920a0Smrg * XXX in the future we may have a new ctx->Driver.ClearBuffer() 381cdc920a0Smrg * hook instead. 382cdc920a0Smrg */ 383cdc920a0Smrg const GLuint clearSave = ctx->Stencil.Clear; 384cdc920a0Smrg ctx->Stencil.Clear = *value; 385cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL); 386cdc920a0Smrg ctx->Stencil.Clear = clearSave; 387cdc920a0Smrg } 388cdc920a0Smrg break; 389cdc920a0Smrg case GL_COLOR: 390cdc920a0Smrg { 391cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 39201e04c3fSmrg if (!no_error && mask == INVALID_MASK) { 393cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 394cdc920a0Smrg drawbuffer); 395cdc920a0Smrg return; 396cdc920a0Smrg } 397af69d88dSmrg else if (mask && !ctx->RasterDiscard) { 398af69d88dSmrg union gl_color_union clearSave; 399af69d88dSmrg 400cdc920a0Smrg /* save color */ 401af69d88dSmrg clearSave = ctx->Color.ClearColor; 402cdc920a0Smrg /* set color */ 403af69d88dSmrg COPY_4V(ctx->Color.ClearColor.i, value); 404cdc920a0Smrg /* clear buffer(s) */ 405cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 406cdc920a0Smrg /* restore color */ 407af69d88dSmrg ctx->Color.ClearColor = clearSave; 408cdc920a0Smrg } 409cdc920a0Smrg } 410cdc920a0Smrg break; 411cdc920a0Smrg default: 41201e04c3fSmrg if (!no_error) { 41301e04c3fSmrg /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' 41401e04c3fSmrg * of the OpenGL 4.5 spec states: 41501e04c3fSmrg * 41601e04c3fSmrg * "An INVALID_ENUM error is generated by ClearBufferiv and 41701e04c3fSmrg * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL." 41801e04c3fSmrg */ 41901e04c3fSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)", 42001e04c3fSmrg _mesa_enum_to_string(buffer)); 42101e04c3fSmrg } 422cdc920a0Smrg return; 423cdc920a0Smrg } 424cdc920a0Smrg} 425cdc920a0Smrg 426cdc920a0Smrg 42701e04c3fSmrgvoid GLAPIENTRY 42801e04c3fSmrg_mesa_ClearBufferiv_no_error(GLenum buffer, GLint drawbuffer, const GLint *value) 42901e04c3fSmrg{ 43001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 43101e04c3fSmrg clear_bufferiv(ctx, buffer, drawbuffer, value, true); 43201e04c3fSmrg} 43301e04c3fSmrg 43401e04c3fSmrg 43501e04c3fSmrgvoid GLAPIENTRY 43601e04c3fSmrg_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) 43701e04c3fSmrg{ 43801e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 43901e04c3fSmrg clear_bufferiv(ctx, buffer, drawbuffer, value, false); 44001e04c3fSmrg} 44101e04c3fSmrg 44201e04c3fSmrg 443cdc920a0Smrg/** 44401e04c3fSmrg * The ClearBuffer framework is so complicated and so riddled with the 44501e04c3fSmrg * assumption that the framebuffer is bound that, for now, we will just fake 44601e04c3fSmrg * direct state access clearing for the user. 447cdc920a0Smrg */ 448cdc920a0Smrgvoid GLAPIENTRY 44901e04c3fSmrg_mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, 45001e04c3fSmrg GLint drawbuffer, const GLint *value) 451cdc920a0Smrg{ 45201e04c3fSmrg GLint oldfb; 45301e04c3fSmrg 45401e04c3fSmrg _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb); 45501e04c3fSmrg _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); 45601e04c3fSmrg _mesa_ClearBufferiv(buffer, drawbuffer, value); 45701e04c3fSmrg _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb); 45801e04c3fSmrg} 45901e04c3fSmrg 460cdc920a0Smrg 46101e04c3fSmrg/** 46201e04c3fSmrg * New in GL 3.0 46301e04c3fSmrg * Clear unsigned integer color buffer (not depth, not stencil). 46401e04c3fSmrg */ 46501e04c3fSmrgstatic ALWAYS_INLINE void 46601e04c3fSmrgclear_bufferuiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, 46701e04c3fSmrg const GLuint *value, bool no_error) 46801e04c3fSmrg{ 4697ec681f3Smrg FLUSH_VERTICES(ctx, 0, 0); 470cdc920a0Smrg 471cdc920a0Smrg if (ctx->NewState) { 472cdc920a0Smrg _mesa_update_state( ctx ); 473cdc920a0Smrg } 474cdc920a0Smrg 4757ec681f3Smrg if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) { 4767ec681f3Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION, 4777ec681f3Smrg "glClearBufferuiv(incomplete framebuffer)"); 4787ec681f3Smrg return; 4797ec681f3Smrg } 4807ec681f3Smrg 481cdc920a0Smrg switch (buffer) { 482cdc920a0Smrg case GL_COLOR: 483cdc920a0Smrg { 484cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 48501e04c3fSmrg if (!no_error && mask == INVALID_MASK) { 4863464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)", 487cdc920a0Smrg drawbuffer); 488cdc920a0Smrg return; 489cdc920a0Smrg } 490af69d88dSmrg else if (mask && !ctx->RasterDiscard) { 491af69d88dSmrg union gl_color_union clearSave; 492af69d88dSmrg 493cdc920a0Smrg /* save color */ 494af69d88dSmrg clearSave = ctx->Color.ClearColor; 495cdc920a0Smrg /* set color */ 496af69d88dSmrg COPY_4V(ctx->Color.ClearColor.ui, value); 497cdc920a0Smrg /* clear buffer(s) */ 498cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 499cdc920a0Smrg /* restore color */ 500af69d88dSmrg ctx->Color.ClearColor = clearSave; 501cdc920a0Smrg } 502cdc920a0Smrg } 503cdc920a0Smrg break; 504cdc920a0Smrg default: 50501e04c3fSmrg if (!no_error) { 50601e04c3fSmrg /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' 50701e04c3fSmrg * of the OpenGL 4.5 spec states: 50801e04c3fSmrg * 50901e04c3fSmrg * "An INVALID_ENUM error is generated by ClearBufferuiv and 51001e04c3fSmrg * ClearNamedFramebufferuiv if buffer is not COLOR." 51101e04c3fSmrg */ 51201e04c3fSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)", 51301e04c3fSmrg _mesa_enum_to_string(buffer)); 51401e04c3fSmrg } 515cdc920a0Smrg return; 516cdc920a0Smrg } 517cdc920a0Smrg} 518cdc920a0Smrg 519cdc920a0Smrg 52001e04c3fSmrgvoid GLAPIENTRY 52101e04c3fSmrg_mesa_ClearBufferuiv_no_error(GLenum buffer, GLint drawbuffer, 52201e04c3fSmrg const GLuint *value) 52301e04c3fSmrg{ 52401e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 52501e04c3fSmrg clear_bufferuiv(ctx, buffer, drawbuffer, value, true); 52601e04c3fSmrg} 52701e04c3fSmrg 52801e04c3fSmrg 52901e04c3fSmrgvoid GLAPIENTRY 53001e04c3fSmrg_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) 53101e04c3fSmrg{ 53201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 53301e04c3fSmrg clear_bufferuiv(ctx, buffer, drawbuffer, value, false); 53401e04c3fSmrg} 53501e04c3fSmrg 53601e04c3fSmrg 537cdc920a0Smrg/** 53801e04c3fSmrg * The ClearBuffer framework is so complicated and so riddled with the 53901e04c3fSmrg * assumption that the framebuffer is bound that, for now, we will just fake 54001e04c3fSmrg * direct state access clearing for the user. 541cdc920a0Smrg */ 542cdc920a0Smrgvoid GLAPIENTRY 54301e04c3fSmrg_mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, 54401e04c3fSmrg GLint drawbuffer, const GLuint *value) 545cdc920a0Smrg{ 54601e04c3fSmrg GLint oldfb; 547cdc920a0Smrg 54801e04c3fSmrg _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb); 54901e04c3fSmrg _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); 55001e04c3fSmrg _mesa_ClearBufferuiv(buffer, drawbuffer, value); 55101e04c3fSmrg _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb); 55201e04c3fSmrg} 55301e04c3fSmrg 55401e04c3fSmrg 55501e04c3fSmrg/** 55601e04c3fSmrg * New in GL 3.0 55701e04c3fSmrg * Clear fixed-pt or float color buffer or depth buffer (not stencil). 55801e04c3fSmrg */ 55901e04c3fSmrgstatic ALWAYS_INLINE void 56001e04c3fSmrgclear_bufferfv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, 56101e04c3fSmrg const GLfloat *value, bool no_error) 56201e04c3fSmrg{ 5637ec681f3Smrg FLUSH_VERTICES(ctx, 0, 0); 564cdc920a0Smrg 565cdc920a0Smrg if (ctx->NewState) { 566cdc920a0Smrg _mesa_update_state( ctx ); 567cdc920a0Smrg } 568cdc920a0Smrg 5697ec681f3Smrg if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) { 5707ec681f3Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION, 5717ec681f3Smrg "glClearBufferfv(incomplete framebuffer)"); 5727ec681f3Smrg return; 5737ec681f3Smrg } 5747ec681f3Smrg 575cdc920a0Smrg switch (buffer) { 576cdc920a0Smrg case GL_DEPTH: 577af69d88dSmrg /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: 578af69d88dSmrg * 579af69d88dSmrg * "ClearBuffer generates an INVALID VALUE error if buffer is 580af69d88dSmrg * COLOR and drawbuffer is less than zero, or greater than the 581af69d88dSmrg * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, 582af69d88dSmrg * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." 583af69d88dSmrg */ 58401e04c3fSmrg if (!no_error && drawbuffer != 0) { 585cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", 586cdc920a0Smrg drawbuffer); 587cdc920a0Smrg return; 588cdc920a0Smrg } 58901e04c3fSmrg else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer 59001e04c3fSmrg && !ctx->RasterDiscard) { 591cdc920a0Smrg /* Save current depth clear value, set to 'value', do the 592cdc920a0Smrg * depth clear and restore the clear value. 593cdc920a0Smrg * XXX in the future we may have a new ctx->Driver.ClearBuffer() 594cdc920a0Smrg * hook instead. 595cdc920a0Smrg */ 596cdc920a0Smrg const GLclampd clearSave = ctx->Depth.Clear; 5977ec681f3Smrg 5987ec681f3Smrg /* Page 263 (page 279 of the PDF) of the OpenGL 3.0 spec says: 5997ec681f3Smrg * 6007ec681f3Smrg * "If buffer is DEPTH, drawbuffer must be zero, and value points 6017ec681f3Smrg * to the single depth value to clear the depth buffer to. 6027ec681f3Smrg * Clamping and type conversion for fixed-point depth buffers are 6037ec681f3Smrg * performed in the same fashion as for ClearDepth." 6047ec681f3Smrg */ 6057ec681f3Smrg const struct gl_renderbuffer *rb = 6067ec681f3Smrg ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 6077ec681f3Smrg const bool is_float_depth = 6087ec681f3Smrg _mesa_has_depth_float_channel(rb->InternalFormat); 6097ec681f3Smrg ctx->Depth.Clear = is_float_depth ? *value : SATURATE(*value); 6107ec681f3Smrg 611cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH); 612cdc920a0Smrg ctx->Depth.Clear = clearSave; 613cdc920a0Smrg } 614cdc920a0Smrg /* clear depth buffer to value */ 615cdc920a0Smrg break; 616cdc920a0Smrg case GL_COLOR: 617cdc920a0Smrg { 618cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 61901e04c3fSmrg if (!no_error && mask == INVALID_MASK) { 620cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", 621cdc920a0Smrg drawbuffer); 622cdc920a0Smrg return; 623cdc920a0Smrg } 624af69d88dSmrg else if (mask && !ctx->RasterDiscard) { 625af69d88dSmrg union gl_color_union clearSave; 626af69d88dSmrg 627cdc920a0Smrg /* save color */ 628af69d88dSmrg clearSave = ctx->Color.ClearColor; 629cdc920a0Smrg /* set color */ 630af69d88dSmrg COPY_4V(ctx->Color.ClearColor.f, value); 631cdc920a0Smrg /* clear buffer(s) */ 632cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 633cdc920a0Smrg /* restore color */ 634af69d88dSmrg ctx->Color.ClearColor = clearSave; 635cdc920a0Smrg } 636cdc920a0Smrg } 637cdc920a0Smrg break; 638cdc920a0Smrg default: 63901e04c3fSmrg if (!no_error) { 64001e04c3fSmrg /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' 64101e04c3fSmrg * of the OpenGL 4.5 spec states: 64201e04c3fSmrg * 64301e04c3fSmrg * "An INVALID_ENUM error is generated by ClearBufferfv and 64401e04c3fSmrg * ClearNamedFramebufferfv if buffer is not COLOR or DEPTH." 64501e04c3fSmrg */ 64601e04c3fSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)", 64701e04c3fSmrg _mesa_enum_to_string(buffer)); 64801e04c3fSmrg } 649cdc920a0Smrg return; 650cdc920a0Smrg } 651cdc920a0Smrg} 652cdc920a0Smrg 653cdc920a0Smrg 65401e04c3fSmrgvoid GLAPIENTRY 65501e04c3fSmrg_mesa_ClearBufferfv_no_error(GLenum buffer, GLint drawbuffer, 65601e04c3fSmrg const GLfloat *value) 65701e04c3fSmrg{ 65801e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 65901e04c3fSmrg clear_bufferfv(ctx, buffer, drawbuffer, value, true); 66001e04c3fSmrg} 66101e04c3fSmrg 66201e04c3fSmrg 66301e04c3fSmrgvoid GLAPIENTRY 66401e04c3fSmrg_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) 66501e04c3fSmrg{ 66601e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 66701e04c3fSmrg clear_bufferfv(ctx, buffer, drawbuffer, value, false); 66801e04c3fSmrg} 66901e04c3fSmrg 67001e04c3fSmrg 67101e04c3fSmrg/** 67201e04c3fSmrg * The ClearBuffer framework is so complicated and so riddled with the 67301e04c3fSmrg * assumption that the framebuffer is bound that, for now, we will just fake 67401e04c3fSmrg * direct state access clearing for the user. 67501e04c3fSmrg */ 67601e04c3fSmrgvoid GLAPIENTRY 67701e04c3fSmrg_mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, 67801e04c3fSmrg GLint drawbuffer, const GLfloat *value) 67901e04c3fSmrg{ 68001e04c3fSmrg GLint oldfb; 68101e04c3fSmrg 68201e04c3fSmrg _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb); 68301e04c3fSmrg _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); 68401e04c3fSmrg _mesa_ClearBufferfv(buffer, drawbuffer, value); 68501e04c3fSmrg _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb); 68601e04c3fSmrg} 68701e04c3fSmrg 68801e04c3fSmrg 689cdc920a0Smrg/** 690cdc920a0Smrg * New in GL 3.0 691cdc920a0Smrg * Clear depth/stencil buffer only. 692cdc920a0Smrg */ 69301e04c3fSmrgstatic ALWAYS_INLINE void 69401e04c3fSmrgclear_bufferfi(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, 69501e04c3fSmrg GLfloat depth, GLint stencil, bool no_error) 696cdc920a0Smrg{ 697af69d88dSmrg GLbitfield mask = 0; 698cdc920a0Smrg 6997ec681f3Smrg FLUSH_VERTICES(ctx, 0, 0); 700cdc920a0Smrg 70101e04c3fSmrg if (!no_error) { 70201e04c3fSmrg if (buffer != GL_DEPTH_STENCIL) { 70301e04c3fSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)", 70401e04c3fSmrg _mesa_enum_to_string(buffer)); 70501e04c3fSmrg return; 70601e04c3fSmrg } 707cdc920a0Smrg 70801e04c3fSmrg /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: 70901e04c3fSmrg * 71001e04c3fSmrg * "ClearBuffer generates an INVALID VALUE error if buffer is 71101e04c3fSmrg * COLOR and drawbuffer is less than zero, or greater than the 71201e04c3fSmrg * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, 71301e04c3fSmrg * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." 71401e04c3fSmrg */ 71501e04c3fSmrg if (drawbuffer != 0) { 71601e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)", 71701e04c3fSmrg drawbuffer); 71801e04c3fSmrg return; 71901e04c3fSmrg } 720cdc920a0Smrg } 721cdc920a0Smrg 722af69d88dSmrg if (ctx->RasterDiscard) 723af69d88dSmrg return; 724af69d88dSmrg 725cdc920a0Smrg if (ctx->NewState) { 726cdc920a0Smrg _mesa_update_state( ctx ); 727cdc920a0Smrg } 728cdc920a0Smrg 7297ec681f3Smrg if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 7307ec681f3Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 7317ec681f3Smrg "glClearBufferfi(incomplete framebuffer)"); 7327ec681f3Smrg return; 7337ec681f3Smrg } 7347ec681f3Smrg 735af69d88dSmrg if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer) 736af69d88dSmrg mask |= BUFFER_BIT_DEPTH; 737af69d88dSmrg if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer) 738af69d88dSmrg mask |= BUFFER_BIT_STENCIL; 739af69d88dSmrg 740af69d88dSmrg if (mask) { 741cdc920a0Smrg /* save current clear values */ 742cdc920a0Smrg const GLclampd clearDepthSave = ctx->Depth.Clear; 743cdc920a0Smrg const GLuint clearStencilSave = ctx->Stencil.Clear; 744cdc920a0Smrg 7457ec681f3Smrg /* set new clear values 7467ec681f3Smrg * 7477ec681f3Smrg * Page 263 (page 279 of the PDF) of the OpenGL 3.0 spec says: 7487ec681f3Smrg * 7497ec681f3Smrg * "depth and stencil are the values to clear the depth and stencil 7507ec681f3Smrg * buffers to, respectively. Clamping and type conversion for 7517ec681f3Smrg * fixed-point depth buffers are performed in the same fashion as 7527ec681f3Smrg * for ClearDepth." 7537ec681f3Smrg */ 7547ec681f3Smrg const struct gl_renderbuffer *rb = 7557ec681f3Smrg ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 7567ec681f3Smrg const bool has_float_depth = rb && 7577ec681f3Smrg _mesa_has_depth_float_channel(rb->InternalFormat); 7587ec681f3Smrg ctx->Depth.Clear = has_float_depth ? depth : SATURATE(depth); 759cdc920a0Smrg ctx->Stencil.Clear = stencil; 760cdc920a0Smrg 761cdc920a0Smrg /* clear buffers */ 762af69d88dSmrg ctx->Driver.Clear(ctx, mask); 763cdc920a0Smrg 764cdc920a0Smrg /* restore */ 765cdc920a0Smrg ctx->Depth.Clear = clearDepthSave; 766cdc920a0Smrg ctx->Stencil.Clear = clearStencilSave; 767cdc920a0Smrg } 768cdc920a0Smrg} 76901e04c3fSmrg 77001e04c3fSmrg 77101e04c3fSmrgvoid GLAPIENTRY 77201e04c3fSmrg_mesa_ClearBufferfi_no_error(GLenum buffer, GLint drawbuffer, 77301e04c3fSmrg GLfloat depth, GLint stencil) 77401e04c3fSmrg{ 77501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 77601e04c3fSmrg clear_bufferfi(ctx, buffer, drawbuffer, depth, stencil, true); 77701e04c3fSmrg} 77801e04c3fSmrg 77901e04c3fSmrg 78001e04c3fSmrgvoid GLAPIENTRY 78101e04c3fSmrg_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, 78201e04c3fSmrg GLfloat depth, GLint stencil) 78301e04c3fSmrg{ 78401e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 78501e04c3fSmrg clear_bufferfi(ctx, buffer, drawbuffer, depth, stencil, false); 78601e04c3fSmrg} 78701e04c3fSmrg 78801e04c3fSmrg 78901e04c3fSmrg/** 79001e04c3fSmrg * The ClearBuffer framework is so complicated and so riddled with the 79101e04c3fSmrg * assumption that the framebuffer is bound that, for now, we will just fake 79201e04c3fSmrg * direct state access clearing for the user. 79301e04c3fSmrg */ 79401e04c3fSmrgvoid GLAPIENTRY 79501e04c3fSmrg_mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, 79601e04c3fSmrg GLint drawbuffer, GLfloat depth, GLint stencil) 79701e04c3fSmrg{ 79801e04c3fSmrg GLint oldfb; 79901e04c3fSmrg 80001e04c3fSmrg _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb); 80101e04c3fSmrg _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); 80201e04c3fSmrg _mesa_ClearBufferfi(buffer, drawbuffer, depth, stencil); 80301e04c3fSmrg _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb); 80401e04c3fSmrg} 805