clear.c revision cdc920a0
1c1f859d4Smrg/* 2c1f859d4Smrg * Mesa 3-D graphics library 3c1f859d4Smrg * Version: 7.1 4c1f859d4Smrg * 5c1f859d4Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6c1f859d4Smrg * 7c1f859d4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8c1f859d4Smrg * copy of this software and associated documentation files (the "Software"), 9c1f859d4Smrg * to deal in the Software without restriction, including without limitation 10c1f859d4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11c1f859d4Smrg * and/or sell copies of the Software, and to permit persons to whom the 12c1f859d4Smrg * Software is furnished to do so, subject to the following conditions: 13c1f859d4Smrg * 14c1f859d4Smrg * The above copyright notice and this permission notice shall be included 15c1f859d4Smrg * in all copies or substantial portions of the Software. 16c1f859d4Smrg * 17c1f859d4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18c1f859d4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19c1f859d4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20c1f859d4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21c1f859d4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22c1f859d4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR 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" 38c1f859d4Smrg#include "state.h" 39c1f859d4Smrg 40c1f859d4Smrg 41c1f859d4Smrg 42c1f859d4Smrg#if _HAVE_FULL_GL 43c1f859d4Smrgvoid GLAPIENTRY 44c1f859d4Smrg_mesa_ClearIndex( GLfloat c ) 45c1f859d4Smrg{ 46c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 47c1f859d4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 48c1f859d4Smrg 49c1f859d4Smrg if (ctx->Color.ClearIndex == (GLuint) c) 50c1f859d4Smrg return; 51c1f859d4Smrg 52c1f859d4Smrg FLUSH_VERTICES(ctx, _NEW_COLOR); 53c1f859d4Smrg ctx->Color.ClearIndex = (GLuint) c; 54c1f859d4Smrg} 55c1f859d4Smrg#endif 56c1f859d4Smrg 57c1f859d4Smrg 58c1f859d4Smrg/** 59c1f859d4Smrg * Specify the clear values for the color buffers. 60c1f859d4Smrg * 61c1f859d4Smrg * \param red red color component. 62c1f859d4Smrg * \param green green color component. 63c1f859d4Smrg * \param blue blue color component. 64c1f859d4Smrg * \param alpha alpha component. 65c1f859d4Smrg * 66c1f859d4Smrg * \sa glClearColor(). 67c1f859d4Smrg * 68c1f859d4Smrg * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a 69c1f859d4Smrg * change, flushes the vertices and notifies the driver via the 70c1f859d4Smrg * dd_function_table::ClearColor callback. 71c1f859d4Smrg */ 72c1f859d4Smrgvoid GLAPIENTRY 73c1f859d4Smrg_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) 74c1f859d4Smrg{ 75c1f859d4Smrg GLfloat tmp[4]; 76c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 77c1f859d4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 78c1f859d4Smrg 79c1f859d4Smrg tmp[0] = CLAMP(red, 0.0F, 1.0F); 80c1f859d4Smrg tmp[1] = CLAMP(green, 0.0F, 1.0F); 81c1f859d4Smrg tmp[2] = CLAMP(blue, 0.0F, 1.0F); 82c1f859d4Smrg tmp[3] = CLAMP(alpha, 0.0F, 1.0F); 83c1f859d4Smrg 84c1f859d4Smrg if (TEST_EQ_4V(tmp, ctx->Color.ClearColor)) 85c1f859d4Smrg return; /* no change */ 86c1f859d4Smrg 87c1f859d4Smrg FLUSH_VERTICES(ctx, _NEW_COLOR); 88c1f859d4Smrg COPY_4V(ctx->Color.ClearColor, tmp); 89c1f859d4Smrg 90cdc920a0Smrg if (ctx->Driver.ClearColor) { 91c1f859d4Smrg /* it's OK to call glClearColor in CI mode but it should be a NOP */ 92c1f859d4Smrg (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor); 93c1f859d4Smrg } 94c1f859d4Smrg} 95c1f859d4Smrg 96c1f859d4Smrg 97c1f859d4Smrg/** 98c1f859d4Smrg * Clear buffers. 99c1f859d4Smrg * 100c1f859d4Smrg * \param mask bit-mask indicating the buffers to be cleared. 101c1f859d4Smrg * 102c1f859d4Smrg * Flushes the vertices and verifies the parameter. If __GLcontextRec::NewState 103c1f859d4Smrg * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin, 104c1f859d4Smrg * etc. If the rasterization mode is set to GL_RENDER then requests the driver 105c1f859d4Smrg * to clear the buffers, via the dd_function_table::Clear callback. 106c1f859d4Smrg */ 107c1f859d4Smrgvoid GLAPIENTRY 108c1f859d4Smrg_mesa_Clear( GLbitfield mask ) 109c1f859d4Smrg{ 110c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 111c1f859d4Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 112c1f859d4Smrg 113c1f859d4Smrg FLUSH_CURRENT(ctx, 0); 114c1f859d4Smrg 115c1f859d4Smrg if (MESA_VERBOSE & VERBOSE_API) 116c1f859d4Smrg _mesa_debug(ctx, "glClear 0x%x\n", mask); 117c1f859d4Smrg 118c1f859d4Smrg if (mask & ~(GL_COLOR_BUFFER_BIT | 119c1f859d4Smrg GL_DEPTH_BUFFER_BIT | 120c1f859d4Smrg GL_STENCIL_BUFFER_BIT | 121c1f859d4Smrg GL_ACCUM_BUFFER_BIT)) { 122c1f859d4Smrg /* invalid bit set */ 123c1f859d4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask); 124c1f859d4Smrg return; 125c1f859d4Smrg } 126c1f859d4Smrg 127c1f859d4Smrg if (ctx->NewState) { 128c1f859d4Smrg _mesa_update_state( ctx ); /* update _Xmin, etc */ 129c1f859d4Smrg } 130c1f859d4Smrg 131c1f859d4Smrg if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 132c1f859d4Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 133c1f859d4Smrg "glClear(incomplete framebuffer)"); 134c1f859d4Smrg return; 135c1f859d4Smrg } 136c1f859d4Smrg 137c1f859d4Smrg if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 || 138c1f859d4Smrg ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax || 139c1f859d4Smrg ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax) 140c1f859d4Smrg return; 141c1f859d4Smrg 142c1f859d4Smrg if (ctx->RenderMode == GL_RENDER) { 143c1f859d4Smrg GLbitfield bufferMask; 144c1f859d4Smrg 145c1f859d4Smrg /* don't clear depth buffer if depth writing disabled */ 146c1f859d4Smrg if (!ctx->Depth.Mask) 147c1f859d4Smrg mask &= ~GL_DEPTH_BUFFER_BIT; 148c1f859d4Smrg 149c1f859d4Smrg /* Build the bitmask to send to device driver's Clear function. 150c1f859d4Smrg * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4 151c1f859d4Smrg * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the 152c1f859d4Smrg * BUFFER_BIT_COLORn flags. 153c1f859d4Smrg */ 154c1f859d4Smrg bufferMask = 0; 155c1f859d4Smrg if (mask & GL_COLOR_BUFFER_BIT) { 156c1f859d4Smrg GLuint i; 157c1f859d4Smrg for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { 158c1f859d4Smrg bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]); 159c1f859d4Smrg } 160c1f859d4Smrg } 161c1f859d4Smrg 162c1f859d4Smrg if ((mask & GL_DEPTH_BUFFER_BIT) 163c1f859d4Smrg && ctx->DrawBuffer->Visual.haveDepthBuffer) { 164c1f859d4Smrg bufferMask |= BUFFER_BIT_DEPTH; 165c1f859d4Smrg } 166c1f859d4Smrg 167c1f859d4Smrg if ((mask & GL_STENCIL_BUFFER_BIT) 168c1f859d4Smrg && ctx->DrawBuffer->Visual.haveStencilBuffer) { 169c1f859d4Smrg bufferMask |= BUFFER_BIT_STENCIL; 170c1f859d4Smrg } 171c1f859d4Smrg 172c1f859d4Smrg if ((mask & GL_ACCUM_BUFFER_BIT) 173c1f859d4Smrg && ctx->DrawBuffer->Visual.haveAccumBuffer) { 174c1f859d4Smrg bufferMask |= BUFFER_BIT_ACCUM; 175c1f859d4Smrg } 176c1f859d4Smrg 177c1f859d4Smrg ASSERT(ctx->Driver.Clear); 178c1f859d4Smrg ctx->Driver.Clear(ctx, bufferMask); 179c1f859d4Smrg } 180c1f859d4Smrg} 181cdc920a0Smrg 182cdc920a0Smrg 183cdc920a0Smrg/** Returned by make_color_buffer_mask() for errors */ 184cdc920a0Smrg#define INVALID_MASK ~0x0 185cdc920a0Smrg 186cdc920a0Smrg 187cdc920a0Smrg/** 188cdc920a0Smrg * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of 189cdc920a0Smrg * BUFFER_BIT_x values. 190cdc920a0Smrg * Return INVALID_MASK if the drawbuffer value is invalid. 191cdc920a0Smrg */ 192cdc920a0Smrgstatic GLbitfield 193cdc920a0Smrgmake_color_buffer_mask(GLcontext *ctx, GLint drawbuffer) 194cdc920a0Smrg{ 195cdc920a0Smrg const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment; 196cdc920a0Smrg GLbitfield mask = 0x0; 197cdc920a0Smrg 198cdc920a0Smrg switch (drawbuffer) { 199cdc920a0Smrg case GL_FRONT: 200cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 201cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 202cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 203cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 204cdc920a0Smrg break; 205cdc920a0Smrg case GL_BACK: 206cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 207cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 208cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 209cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 210cdc920a0Smrg break; 211cdc920a0Smrg case GL_LEFT: 212cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 213cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 214cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 215cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 216cdc920a0Smrg break; 217cdc920a0Smrg case GL_RIGHT: 218cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 219cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 220cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 221cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 222cdc920a0Smrg break; 223cdc920a0Smrg case GL_FRONT_AND_BACK: 224cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 225cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 226cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 227cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 228cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 229cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 230cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 231cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 232cdc920a0Smrg break; 233cdc920a0Smrg default: 234cdc920a0Smrg if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) { 235cdc920a0Smrg mask = INVALID_MASK; 236cdc920a0Smrg } 237cdc920a0Smrg else if (att[BUFFER_COLOR0 + drawbuffer].Renderbuffer) { 238cdc920a0Smrg mask |= (BUFFER_BIT_COLOR0 << drawbuffer); 239cdc920a0Smrg } 240cdc920a0Smrg } 241cdc920a0Smrg 242cdc920a0Smrg return mask; 243cdc920a0Smrg} 244cdc920a0Smrg 245cdc920a0Smrg 246cdc920a0Smrg 247cdc920a0Smrg/** 248cdc920a0Smrg * New in GL 3.0 249cdc920a0Smrg * Clear signed integer color buffer or stencil buffer (not depth). 250cdc920a0Smrg */ 251cdc920a0Smrgvoid GLAPIENTRY 252cdc920a0Smrg_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) 253cdc920a0Smrg{ 254cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 255cdc920a0Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 256cdc920a0Smrg 257cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 258cdc920a0Smrg 259cdc920a0Smrg if (ctx->NewState) { 260cdc920a0Smrg _mesa_update_state( ctx ); 261cdc920a0Smrg } 262cdc920a0Smrg 263cdc920a0Smrg switch (buffer) { 264cdc920a0Smrg case GL_STENCIL: 265cdc920a0Smrg if (drawbuffer != 0) { 266cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 267cdc920a0Smrg drawbuffer); 268cdc920a0Smrg return; 269cdc920a0Smrg } 270cdc920a0Smrg else { 271cdc920a0Smrg /* Save current stencil clear value, set to 'value', do the 272cdc920a0Smrg * stencil clear and restore the clear value. 273cdc920a0Smrg * XXX in the future we may have a new ctx->Driver.ClearBuffer() 274cdc920a0Smrg * hook instead. 275cdc920a0Smrg */ 276cdc920a0Smrg const GLuint clearSave = ctx->Stencil.Clear; 277cdc920a0Smrg ctx->Stencil.Clear = *value; 278cdc920a0Smrg if (ctx->Driver.ClearStencil) 279cdc920a0Smrg ctx->Driver.ClearStencil(ctx, *value); 280cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL); 281cdc920a0Smrg ctx->Stencil.Clear = clearSave; 282cdc920a0Smrg if (ctx->Driver.ClearStencil) 283cdc920a0Smrg ctx->Driver.ClearStencil(ctx, clearSave); 284cdc920a0Smrg } 285cdc920a0Smrg break; 286cdc920a0Smrg case GL_COLOR: 287cdc920a0Smrg { 288cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 289cdc920a0Smrg if (mask == INVALID_MASK) { 290cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 291cdc920a0Smrg drawbuffer); 292cdc920a0Smrg return; 293cdc920a0Smrg } 294cdc920a0Smrg else if (mask) { 295cdc920a0Smrg /* XXX note: we're putting the integer clear values into the 296cdc920a0Smrg * floating point state var. This will not always work. We'll 297cdc920a0Smrg * need a new ctx->Driver.ClearBuffer() hook.... 298cdc920a0Smrg */ 299cdc920a0Smrg GLclampf clearSave[4]; 300cdc920a0Smrg /* save color */ 301cdc920a0Smrg COPY_4V(clearSave, ctx->Color.ClearColor); 302cdc920a0Smrg /* set color */ 303cdc920a0Smrg COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); 304cdc920a0Smrg if (ctx->Driver.ClearColor) 305cdc920a0Smrg ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); 306cdc920a0Smrg /* clear buffer(s) */ 307cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 308cdc920a0Smrg /* restore color */ 309cdc920a0Smrg COPY_4V(ctx->Color.ClearColor, clearSave); 310cdc920a0Smrg if (ctx->Driver.ClearColor) 311cdc920a0Smrg ctx->Driver.ClearColor(ctx, clearSave); 312cdc920a0Smrg } 313cdc920a0Smrg } 314cdc920a0Smrg break; 315cdc920a0Smrg default: 316cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)", 317cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 318cdc920a0Smrg return; 319cdc920a0Smrg } 320cdc920a0Smrg} 321cdc920a0Smrg 322cdc920a0Smrg 323cdc920a0Smrg/** 324cdc920a0Smrg * New in GL 3.0 325cdc920a0Smrg * Clear unsigned integer color buffer (not depth, not stencil). 326cdc920a0Smrg */ 327cdc920a0Smrgvoid GLAPIENTRY 328cdc920a0Smrg_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) 329cdc920a0Smrg{ 330cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 331cdc920a0Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 332cdc920a0Smrg 333cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 334cdc920a0Smrg 335cdc920a0Smrg if (ctx->NewState) { 336cdc920a0Smrg _mesa_update_state( ctx ); 337cdc920a0Smrg } 338cdc920a0Smrg 339cdc920a0Smrg switch (buffer) { 340cdc920a0Smrg case GL_COLOR: 341cdc920a0Smrg { 342cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 343cdc920a0Smrg if (mask == INVALID_MASK) { 344cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 345cdc920a0Smrg drawbuffer); 346cdc920a0Smrg return; 347cdc920a0Smrg } 348cdc920a0Smrg else if (mask) { 349cdc920a0Smrg /* XXX note: we're putting the uint clear values into the 350cdc920a0Smrg * floating point state var. This will not always work. We'll 351cdc920a0Smrg * need a new ctx->Driver.ClearBuffer() hook.... 352cdc920a0Smrg */ 353cdc920a0Smrg GLclampf clearSave[4]; 354cdc920a0Smrg /* save color */ 355cdc920a0Smrg COPY_4V(clearSave, ctx->Color.ClearColor); 356cdc920a0Smrg /* set color */ 357cdc920a0Smrg COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); 358cdc920a0Smrg if (ctx->Driver.ClearColor) 359cdc920a0Smrg ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); 360cdc920a0Smrg /* clear buffer(s) */ 361cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 362cdc920a0Smrg /* restore color */ 363cdc920a0Smrg COPY_4V(ctx->Color.ClearColor, clearSave); 364cdc920a0Smrg if (ctx->Driver.ClearColor) 365cdc920a0Smrg ctx->Driver.ClearColor(ctx, clearSave); 366cdc920a0Smrg } 367cdc920a0Smrg } 368cdc920a0Smrg break; 369cdc920a0Smrg default: 370cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)", 371cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 372cdc920a0Smrg return; 373cdc920a0Smrg } 374cdc920a0Smrg} 375cdc920a0Smrg 376cdc920a0Smrg 377cdc920a0Smrg/** 378cdc920a0Smrg * New in GL 3.0 379cdc920a0Smrg * Clear fixed-pt or float color buffer or depth buffer (not stencil). 380cdc920a0Smrg */ 381cdc920a0Smrgvoid GLAPIENTRY 382cdc920a0Smrg_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) 383cdc920a0Smrg{ 384cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 385cdc920a0Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 386cdc920a0Smrg 387cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 388cdc920a0Smrg 389cdc920a0Smrg if (ctx->NewState) { 390cdc920a0Smrg _mesa_update_state( ctx ); 391cdc920a0Smrg } 392cdc920a0Smrg 393cdc920a0Smrg switch (buffer) { 394cdc920a0Smrg case GL_DEPTH: 395cdc920a0Smrg if (drawbuffer != 0) { 396cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", 397cdc920a0Smrg drawbuffer); 398cdc920a0Smrg return; 399cdc920a0Smrg } 400cdc920a0Smrg else { 401cdc920a0Smrg /* Save current depth clear value, set to 'value', do the 402cdc920a0Smrg * depth clear and restore the clear value. 403cdc920a0Smrg * XXX in the future we may have a new ctx->Driver.ClearBuffer() 404cdc920a0Smrg * hook instead. 405cdc920a0Smrg */ 406cdc920a0Smrg const GLclampd clearSave = ctx->Depth.Clear; 407cdc920a0Smrg ctx->Depth.Clear = *value; 408cdc920a0Smrg if (ctx->Driver.ClearDepth) 409cdc920a0Smrg ctx->Driver.ClearDepth(ctx, *value); 410cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH); 411cdc920a0Smrg ctx->Depth.Clear = clearSave; 412cdc920a0Smrg if (ctx->Driver.ClearDepth) 413cdc920a0Smrg ctx->Driver.ClearDepth(ctx, clearSave); 414cdc920a0Smrg } 415cdc920a0Smrg /* clear depth buffer to value */ 416cdc920a0Smrg break; 417cdc920a0Smrg case GL_COLOR: 418cdc920a0Smrg { 419cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 420cdc920a0Smrg if (mask == INVALID_MASK) { 421cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", 422cdc920a0Smrg drawbuffer); 423cdc920a0Smrg return; 424cdc920a0Smrg } 425cdc920a0Smrg else if (mask) { 426cdc920a0Smrg GLclampf clearSave[4]; 427cdc920a0Smrg /* save color */ 428cdc920a0Smrg COPY_4V(clearSave, ctx->Color.ClearColor); 429cdc920a0Smrg /* set color */ 430cdc920a0Smrg COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); 431cdc920a0Smrg if (ctx->Driver.ClearColor) 432cdc920a0Smrg ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); 433cdc920a0Smrg /* clear buffer(s) */ 434cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 435cdc920a0Smrg /* restore color */ 436cdc920a0Smrg COPY_4V(ctx->Color.ClearColor, clearSave); 437cdc920a0Smrg if (ctx->Driver.ClearColor) 438cdc920a0Smrg ctx->Driver.ClearColor(ctx, clearSave); 439cdc920a0Smrg } 440cdc920a0Smrg } 441cdc920a0Smrg break; 442cdc920a0Smrg default: 443cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)", 444cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 445cdc920a0Smrg return; 446cdc920a0Smrg } 447cdc920a0Smrg} 448cdc920a0Smrg 449cdc920a0Smrg 450cdc920a0Smrg/** 451cdc920a0Smrg * New in GL 3.0 452cdc920a0Smrg * Clear depth/stencil buffer only. 453cdc920a0Smrg */ 454cdc920a0Smrgvoid GLAPIENTRY 455cdc920a0Smrg_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, 456cdc920a0Smrg GLfloat depth, GLint stencil) 457cdc920a0Smrg{ 458cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 459cdc920a0Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 460cdc920a0Smrg 461cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 462cdc920a0Smrg 463cdc920a0Smrg if (buffer != GL_DEPTH_STENCIL) { 464cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)", 465cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 466cdc920a0Smrg return; 467cdc920a0Smrg } 468cdc920a0Smrg 469cdc920a0Smrg if (drawbuffer != 0) { 470cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)", 471cdc920a0Smrg drawbuffer); 472cdc920a0Smrg return; 473cdc920a0Smrg } 474cdc920a0Smrg 475cdc920a0Smrg if (ctx->NewState) { 476cdc920a0Smrg _mesa_update_state( ctx ); 477cdc920a0Smrg } 478cdc920a0Smrg 479cdc920a0Smrg { 480cdc920a0Smrg /* save current clear values */ 481cdc920a0Smrg const GLclampd clearDepthSave = ctx->Depth.Clear; 482cdc920a0Smrg const GLuint clearStencilSave = ctx->Stencil.Clear; 483cdc920a0Smrg 484cdc920a0Smrg /* set new clear values */ 485cdc920a0Smrg ctx->Depth.Clear = depth; 486cdc920a0Smrg ctx->Stencil.Clear = stencil; 487cdc920a0Smrg if (ctx->Driver.ClearDepth) 488cdc920a0Smrg ctx->Driver.ClearDepth(ctx, depth); 489cdc920a0Smrg if (ctx->Driver.ClearStencil) 490cdc920a0Smrg ctx->Driver.ClearStencil(ctx, stencil); 491cdc920a0Smrg 492cdc920a0Smrg /* clear buffers */ 493cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); 494cdc920a0Smrg 495cdc920a0Smrg /* restore */ 496cdc920a0Smrg ctx->Depth.Clear = clearDepthSave; 497cdc920a0Smrg ctx->Stencil.Clear = clearStencilSave; 498cdc920a0Smrg if (ctx->Driver.ClearDepth) 499cdc920a0Smrg ctx->Driver.ClearDepth(ctx, clearDepthSave); 500cdc920a0Smrg if (ctx->Driver.ClearStencil) 501cdc920a0Smrg ctx->Driver.ClearStencil(ctx, clearStencilSave); 502cdc920a0Smrg } 503cdc920a0Smrg} 504