clear.c revision 3464ebd5
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" 383464ebd5Sriastradh#include "macros.h" 393464ebd5Sriastradh#include "mtypes.h" 40c1f859d4Smrg#include "state.h" 41c1f859d4Smrg 42c1f859d4Smrg 43c1f859d4Smrg 44c1f859d4Smrg#if _HAVE_FULL_GL 45c1f859d4Smrgvoid GLAPIENTRY 46c1f859d4Smrg_mesa_ClearIndex( GLfloat c ) 47c1f859d4Smrg{ 48c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 49c1f859d4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 50c1f859d4Smrg 51c1f859d4Smrg if (ctx->Color.ClearIndex == (GLuint) c) 52c1f859d4Smrg return; 53c1f859d4Smrg 54c1f859d4Smrg FLUSH_VERTICES(ctx, _NEW_COLOR); 55c1f859d4Smrg ctx->Color.ClearIndex = (GLuint) c; 56c1f859d4Smrg} 57c1f859d4Smrg#endif 58c1f859d4Smrg 59c1f859d4Smrg 60c1f859d4Smrg/** 61c1f859d4Smrg * Specify the clear values for the color buffers. 62c1f859d4Smrg * 63c1f859d4Smrg * \param red red color component. 64c1f859d4Smrg * \param green green color component. 65c1f859d4Smrg * \param blue blue color component. 66c1f859d4Smrg * \param alpha alpha component. 67c1f859d4Smrg * 68c1f859d4Smrg * \sa glClearColor(). 69c1f859d4Smrg * 70c1f859d4Smrg * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a 71c1f859d4Smrg * change, flushes the vertices and notifies the driver via the 72c1f859d4Smrg * dd_function_table::ClearColor callback. 73c1f859d4Smrg */ 74c1f859d4Smrgvoid GLAPIENTRY 75c1f859d4Smrg_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) 76c1f859d4Smrg{ 77c1f859d4Smrg GLfloat tmp[4]; 78c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 79c1f859d4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 80c1f859d4Smrg 813464ebd5Sriastradh tmp[0] = red; 823464ebd5Sriastradh tmp[1] = green; 833464ebd5Sriastradh tmp[2] = blue; 843464ebd5Sriastradh tmp[3] = alpha; 85c1f859d4Smrg 863464ebd5Sriastradh if (TEST_EQ_4V(tmp, ctx->Color.ClearColorUnclamped)) 87c1f859d4Smrg return; /* no change */ 88c1f859d4Smrg 89c1f859d4Smrg FLUSH_VERTICES(ctx, _NEW_COLOR); 903464ebd5Sriastradh COPY_4V(ctx->Color.ClearColorUnclamped, tmp); 913464ebd5Sriastradh 923464ebd5Sriastradh ctx->Color.ClearColor[0] = CLAMP(tmp[0], 0.0F, 1.0F); 933464ebd5Sriastradh ctx->Color.ClearColor[1] = CLAMP(tmp[1], 0.0F, 1.0F); 943464ebd5Sriastradh ctx->Color.ClearColor[2] = CLAMP(tmp[2], 0.0F, 1.0F); 953464ebd5Sriastradh ctx->Color.ClearColor[3] = CLAMP(tmp[3], 0.0F, 1.0F); 96c1f859d4Smrg 97cdc920a0Smrg if (ctx->Driver.ClearColor) { 98c1f859d4Smrg /* it's OK to call glClearColor in CI mode but it should be a NOP */ 993464ebd5Sriastradh /* we pass the clamped color, since all drivers that need this don't 1003464ebd5Sriastradh * support GL_ARB_color_buffer_float 1013464ebd5Sriastradh */ 102c1f859d4Smrg (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor); 103c1f859d4Smrg } 104c1f859d4Smrg} 105c1f859d4Smrg 106c1f859d4Smrg 1073464ebd5Sriastradh/** 1083464ebd5Sriastradh * GL_EXT_texture_integer 1093464ebd5Sriastradh */ 1103464ebd5Sriastradhvoid GLAPIENTRY 1113464ebd5Sriastradh_mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a) 1123464ebd5Sriastradh{ 1133464ebd5Sriastradh GLfloat tmp[4]; 1143464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 1153464ebd5Sriastradh ASSERT_OUTSIDE_BEGIN_END(ctx); 1163464ebd5Sriastradh 1173464ebd5Sriastradh tmp[0] = (GLfloat) r; 1183464ebd5Sriastradh tmp[1] = (GLfloat) g; 1193464ebd5Sriastradh tmp[2] = (GLfloat) b; 1203464ebd5Sriastradh tmp[3] = (GLfloat) a; 1213464ebd5Sriastradh 1223464ebd5Sriastradh if (TEST_EQ_4V(tmp, ctx->Color.ClearColor)) 1233464ebd5Sriastradh return; /* no change */ 1243464ebd5Sriastradh 1253464ebd5Sriastradh FLUSH_VERTICES(ctx, _NEW_COLOR); 1263464ebd5Sriastradh 1273464ebd5Sriastradh /* XXX we should eventually have a float/int/uint union for 1283464ebd5Sriastradh * the ctx->Color.ClearColor state. 1293464ebd5Sriastradh */ 1303464ebd5Sriastradh COPY_4V(ctx->Color.ClearColor, tmp); 1313464ebd5Sriastradh 1323464ebd5Sriastradh if (ctx->Driver.ClearColor) { 1333464ebd5Sriastradh ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); 1343464ebd5Sriastradh } 1353464ebd5Sriastradh} 1363464ebd5Sriastradh 1373464ebd5Sriastradh 1383464ebd5Sriastradh/** 1393464ebd5Sriastradh * GL_EXT_texture_integer 1403464ebd5Sriastradh */ 1413464ebd5Sriastradhvoid GLAPIENTRY 1423464ebd5Sriastradh_mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a) 1433464ebd5Sriastradh{ 1443464ebd5Sriastradh GLfloat tmp[4]; 1453464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 1463464ebd5Sriastradh ASSERT_OUTSIDE_BEGIN_END(ctx); 1473464ebd5Sriastradh 1483464ebd5Sriastradh tmp[0] = (GLfloat) r; 1493464ebd5Sriastradh tmp[1] = (GLfloat) g; 1503464ebd5Sriastradh tmp[2] = (GLfloat) b; 1513464ebd5Sriastradh tmp[3] = (GLfloat) a; 1523464ebd5Sriastradh 1533464ebd5Sriastradh if (TEST_EQ_4V(tmp, ctx->Color.ClearColor)) 1543464ebd5Sriastradh return; /* no change */ 1553464ebd5Sriastradh 1563464ebd5Sriastradh FLUSH_VERTICES(ctx, _NEW_COLOR); 1573464ebd5Sriastradh 1583464ebd5Sriastradh /* XXX we should eventually have a float/int/uint union for 1593464ebd5Sriastradh * the ctx->Color.ClearColor state. 1603464ebd5Sriastradh */ 1613464ebd5Sriastradh COPY_4V(ctx->Color.ClearColor, tmp); 1623464ebd5Sriastradh 1633464ebd5Sriastradh if (ctx->Driver.ClearColor) { 1643464ebd5Sriastradh ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); 1653464ebd5Sriastradh } 1663464ebd5Sriastradh} 1673464ebd5Sriastradh 1683464ebd5Sriastradh 169c1f859d4Smrg/** 170c1f859d4Smrg * Clear buffers. 171c1f859d4Smrg * 172c1f859d4Smrg * \param mask bit-mask indicating the buffers to be cleared. 173c1f859d4Smrg * 1743464ebd5Sriastradh * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState 175c1f859d4Smrg * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin, 176c1f859d4Smrg * etc. If the rasterization mode is set to GL_RENDER then requests the driver 177c1f859d4Smrg * to clear the buffers, via the dd_function_table::Clear callback. 178c1f859d4Smrg */ 179c1f859d4Smrgvoid GLAPIENTRY 180c1f859d4Smrg_mesa_Clear( GLbitfield mask ) 181c1f859d4Smrg{ 182c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 183c1f859d4Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 184c1f859d4Smrg 185c1f859d4Smrg FLUSH_CURRENT(ctx, 0); 186c1f859d4Smrg 187c1f859d4Smrg if (MESA_VERBOSE & VERBOSE_API) 188c1f859d4Smrg _mesa_debug(ctx, "glClear 0x%x\n", mask); 189c1f859d4Smrg 190c1f859d4Smrg if (mask & ~(GL_COLOR_BUFFER_BIT | 191c1f859d4Smrg GL_DEPTH_BUFFER_BIT | 192c1f859d4Smrg GL_STENCIL_BUFFER_BIT | 193c1f859d4Smrg GL_ACCUM_BUFFER_BIT)) { 194c1f859d4Smrg /* invalid bit set */ 195c1f859d4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask); 196c1f859d4Smrg return; 197c1f859d4Smrg } 198c1f859d4Smrg 199c1f859d4Smrg if (ctx->NewState) { 200c1f859d4Smrg _mesa_update_state( ctx ); /* update _Xmin, etc */ 201c1f859d4Smrg } 202c1f859d4Smrg 203c1f859d4Smrg if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 204c1f859d4Smrg _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 205c1f859d4Smrg "glClear(incomplete framebuffer)"); 206c1f859d4Smrg return; 207c1f859d4Smrg } 208c1f859d4Smrg 209c1f859d4Smrg if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 || 210c1f859d4Smrg ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax || 211c1f859d4Smrg ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax) 212c1f859d4Smrg return; 213c1f859d4Smrg 214c1f859d4Smrg if (ctx->RenderMode == GL_RENDER) { 215c1f859d4Smrg GLbitfield bufferMask; 216c1f859d4Smrg 217c1f859d4Smrg /* don't clear depth buffer if depth writing disabled */ 218c1f859d4Smrg if (!ctx->Depth.Mask) 219c1f859d4Smrg mask &= ~GL_DEPTH_BUFFER_BIT; 220c1f859d4Smrg 221c1f859d4Smrg /* Build the bitmask to send to device driver's Clear function. 222c1f859d4Smrg * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4 223c1f859d4Smrg * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the 224c1f859d4Smrg * BUFFER_BIT_COLORn flags. 225c1f859d4Smrg */ 226c1f859d4Smrg bufferMask = 0; 227c1f859d4Smrg if (mask & GL_COLOR_BUFFER_BIT) { 228c1f859d4Smrg GLuint i; 229c1f859d4Smrg for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { 230c1f859d4Smrg bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]); 231c1f859d4Smrg } 232c1f859d4Smrg } 233c1f859d4Smrg 234c1f859d4Smrg if ((mask & GL_DEPTH_BUFFER_BIT) 235c1f859d4Smrg && ctx->DrawBuffer->Visual.haveDepthBuffer) { 236c1f859d4Smrg bufferMask |= BUFFER_BIT_DEPTH; 237c1f859d4Smrg } 238c1f859d4Smrg 239c1f859d4Smrg if ((mask & GL_STENCIL_BUFFER_BIT) 240c1f859d4Smrg && ctx->DrawBuffer->Visual.haveStencilBuffer) { 241c1f859d4Smrg bufferMask |= BUFFER_BIT_STENCIL; 242c1f859d4Smrg } 243c1f859d4Smrg 244c1f859d4Smrg if ((mask & GL_ACCUM_BUFFER_BIT) 245c1f859d4Smrg && ctx->DrawBuffer->Visual.haveAccumBuffer) { 246c1f859d4Smrg bufferMask |= BUFFER_BIT_ACCUM; 247c1f859d4Smrg } 248c1f859d4Smrg 249c1f859d4Smrg ASSERT(ctx->Driver.Clear); 250c1f859d4Smrg ctx->Driver.Clear(ctx, bufferMask); 251c1f859d4Smrg } 252c1f859d4Smrg} 253cdc920a0Smrg 254cdc920a0Smrg 255cdc920a0Smrg/** Returned by make_color_buffer_mask() for errors */ 256cdc920a0Smrg#define INVALID_MASK ~0x0 257cdc920a0Smrg 258cdc920a0Smrg 259cdc920a0Smrg/** 260cdc920a0Smrg * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of 261cdc920a0Smrg * BUFFER_BIT_x values. 262cdc920a0Smrg * Return INVALID_MASK if the drawbuffer value is invalid. 263cdc920a0Smrg */ 264cdc920a0Smrgstatic GLbitfield 2653464ebd5Sriastradhmake_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer) 266cdc920a0Smrg{ 267cdc920a0Smrg const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment; 268cdc920a0Smrg GLbitfield mask = 0x0; 269cdc920a0Smrg 270cdc920a0Smrg switch (drawbuffer) { 271cdc920a0Smrg case GL_FRONT: 272cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 273cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 274cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 275cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 276cdc920a0Smrg break; 277cdc920a0Smrg case GL_BACK: 278cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 279cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 280cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 281cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 282cdc920a0Smrg break; 283cdc920a0Smrg case GL_LEFT: 284cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 285cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 286cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 287cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 288cdc920a0Smrg break; 289cdc920a0Smrg case GL_RIGHT: 290cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 291cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 292cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 293cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 294cdc920a0Smrg break; 295cdc920a0Smrg case GL_FRONT_AND_BACK: 296cdc920a0Smrg if (att[BUFFER_FRONT_LEFT].Renderbuffer) 297cdc920a0Smrg mask |= BUFFER_BIT_FRONT_LEFT; 298cdc920a0Smrg if (att[BUFFER_BACK_LEFT].Renderbuffer) 299cdc920a0Smrg mask |= BUFFER_BIT_BACK_LEFT; 300cdc920a0Smrg if (att[BUFFER_FRONT_RIGHT].Renderbuffer) 301cdc920a0Smrg mask |= BUFFER_BIT_FRONT_RIGHT; 302cdc920a0Smrg if (att[BUFFER_BACK_RIGHT].Renderbuffer) 303cdc920a0Smrg mask |= BUFFER_BIT_BACK_RIGHT; 304cdc920a0Smrg break; 305cdc920a0Smrg default: 306cdc920a0Smrg if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) { 307cdc920a0Smrg mask = INVALID_MASK; 308cdc920a0Smrg } 309cdc920a0Smrg else if (att[BUFFER_COLOR0 + drawbuffer].Renderbuffer) { 310cdc920a0Smrg mask |= (BUFFER_BIT_COLOR0 << drawbuffer); 311cdc920a0Smrg } 312cdc920a0Smrg } 313cdc920a0Smrg 314cdc920a0Smrg return mask; 315cdc920a0Smrg} 316cdc920a0Smrg 317cdc920a0Smrg 318cdc920a0Smrg 319cdc920a0Smrg/** 320cdc920a0Smrg * New in GL 3.0 321cdc920a0Smrg * Clear signed integer color buffer or stencil buffer (not depth). 322cdc920a0Smrg */ 323cdc920a0Smrgvoid GLAPIENTRY 324cdc920a0Smrg_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) 325cdc920a0Smrg{ 326cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 327cdc920a0Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 328cdc920a0Smrg 329cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 330cdc920a0Smrg 331cdc920a0Smrg if (ctx->NewState) { 332cdc920a0Smrg _mesa_update_state( ctx ); 333cdc920a0Smrg } 334cdc920a0Smrg 335cdc920a0Smrg switch (buffer) { 336cdc920a0Smrg case GL_STENCIL: 337cdc920a0Smrg if (drawbuffer != 0) { 338cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 339cdc920a0Smrg drawbuffer); 340cdc920a0Smrg return; 341cdc920a0Smrg } 342cdc920a0Smrg else { 343cdc920a0Smrg /* Save current stencil clear value, set to 'value', do the 344cdc920a0Smrg * stencil clear and restore the clear value. 345cdc920a0Smrg * XXX in the future we may have a new ctx->Driver.ClearBuffer() 346cdc920a0Smrg * hook instead. 347cdc920a0Smrg */ 348cdc920a0Smrg const GLuint clearSave = ctx->Stencil.Clear; 349cdc920a0Smrg ctx->Stencil.Clear = *value; 350cdc920a0Smrg if (ctx->Driver.ClearStencil) 351cdc920a0Smrg ctx->Driver.ClearStencil(ctx, *value); 352cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL); 353cdc920a0Smrg ctx->Stencil.Clear = clearSave; 354cdc920a0Smrg if (ctx->Driver.ClearStencil) 355cdc920a0Smrg ctx->Driver.ClearStencil(ctx, clearSave); 356cdc920a0Smrg } 357cdc920a0Smrg break; 358cdc920a0Smrg case GL_COLOR: 359cdc920a0Smrg { 360cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 361cdc920a0Smrg if (mask == INVALID_MASK) { 362cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", 363cdc920a0Smrg drawbuffer); 364cdc920a0Smrg return; 365cdc920a0Smrg } 366cdc920a0Smrg else if (mask) { 367cdc920a0Smrg /* XXX note: we're putting the integer clear values into the 368cdc920a0Smrg * floating point state var. This will not always work. We'll 369cdc920a0Smrg * need a new ctx->Driver.ClearBuffer() hook.... 370cdc920a0Smrg */ 371cdc920a0Smrg GLclampf clearSave[4]; 372cdc920a0Smrg /* save color */ 373cdc920a0Smrg COPY_4V(clearSave, ctx->Color.ClearColor); 374cdc920a0Smrg /* set color */ 375cdc920a0Smrg COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); 376cdc920a0Smrg if (ctx->Driver.ClearColor) 377cdc920a0Smrg ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); 378cdc920a0Smrg /* clear buffer(s) */ 379cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 380cdc920a0Smrg /* restore color */ 381cdc920a0Smrg COPY_4V(ctx->Color.ClearColor, clearSave); 382cdc920a0Smrg if (ctx->Driver.ClearColor) 383cdc920a0Smrg ctx->Driver.ClearColor(ctx, clearSave); 384cdc920a0Smrg } 385cdc920a0Smrg } 386cdc920a0Smrg break; 387cdc920a0Smrg default: 388cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)", 389cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 390cdc920a0Smrg return; 391cdc920a0Smrg } 392cdc920a0Smrg} 393cdc920a0Smrg 394cdc920a0Smrg 395cdc920a0Smrg/** 396cdc920a0Smrg * New in GL 3.0 397cdc920a0Smrg * Clear unsigned integer color buffer (not depth, not stencil). 398cdc920a0Smrg */ 399cdc920a0Smrgvoid GLAPIENTRY 400cdc920a0Smrg_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) 401cdc920a0Smrg{ 402cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 403cdc920a0Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 404cdc920a0Smrg 405cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 406cdc920a0Smrg 407cdc920a0Smrg if (ctx->NewState) { 408cdc920a0Smrg _mesa_update_state( ctx ); 409cdc920a0Smrg } 410cdc920a0Smrg 411cdc920a0Smrg switch (buffer) { 412cdc920a0Smrg case GL_COLOR: 413cdc920a0Smrg { 414cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 415cdc920a0Smrg if (mask == INVALID_MASK) { 4163464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)", 417cdc920a0Smrg drawbuffer); 418cdc920a0Smrg return; 419cdc920a0Smrg } 420cdc920a0Smrg else if (mask) { 421cdc920a0Smrg /* XXX note: we're putting the uint clear values into the 422cdc920a0Smrg * floating point state var. This will not always work. We'll 423cdc920a0Smrg * need a new ctx->Driver.ClearBuffer() hook.... 424cdc920a0Smrg */ 425cdc920a0Smrg GLclampf clearSave[4]; 426cdc920a0Smrg /* save color */ 427cdc920a0Smrg COPY_4V(clearSave, ctx->Color.ClearColor); 428cdc920a0Smrg /* set color */ 429cdc920a0Smrg COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); 430cdc920a0Smrg if (ctx->Driver.ClearColor) 431cdc920a0Smrg ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); 432cdc920a0Smrg /* clear buffer(s) */ 433cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 434cdc920a0Smrg /* restore color */ 435cdc920a0Smrg COPY_4V(ctx->Color.ClearColor, clearSave); 436cdc920a0Smrg if (ctx->Driver.ClearColor) 437cdc920a0Smrg ctx->Driver.ClearColor(ctx, clearSave); 438cdc920a0Smrg } 439cdc920a0Smrg } 440cdc920a0Smrg break; 441cdc920a0Smrg default: 442cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)", 443cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 444cdc920a0Smrg return; 445cdc920a0Smrg } 446cdc920a0Smrg} 447cdc920a0Smrg 448cdc920a0Smrg 449cdc920a0Smrg/** 450cdc920a0Smrg * New in GL 3.0 451cdc920a0Smrg * Clear fixed-pt or float color buffer or depth buffer (not stencil). 452cdc920a0Smrg */ 453cdc920a0Smrgvoid GLAPIENTRY 454cdc920a0Smrg_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) 455cdc920a0Smrg{ 456cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 457cdc920a0Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 458cdc920a0Smrg 459cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 460cdc920a0Smrg 461cdc920a0Smrg if (ctx->NewState) { 462cdc920a0Smrg _mesa_update_state( ctx ); 463cdc920a0Smrg } 464cdc920a0Smrg 465cdc920a0Smrg switch (buffer) { 466cdc920a0Smrg case GL_DEPTH: 467cdc920a0Smrg if (drawbuffer != 0) { 468cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", 469cdc920a0Smrg drawbuffer); 470cdc920a0Smrg return; 471cdc920a0Smrg } 472cdc920a0Smrg else { 473cdc920a0Smrg /* Save current depth clear value, set to 'value', do the 474cdc920a0Smrg * depth clear and restore the clear value. 475cdc920a0Smrg * XXX in the future we may have a new ctx->Driver.ClearBuffer() 476cdc920a0Smrg * hook instead. 477cdc920a0Smrg */ 478cdc920a0Smrg const GLclampd clearSave = ctx->Depth.Clear; 479cdc920a0Smrg ctx->Depth.Clear = *value; 480cdc920a0Smrg if (ctx->Driver.ClearDepth) 481cdc920a0Smrg ctx->Driver.ClearDepth(ctx, *value); 482cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH); 483cdc920a0Smrg ctx->Depth.Clear = clearSave; 484cdc920a0Smrg if (ctx->Driver.ClearDepth) 485cdc920a0Smrg ctx->Driver.ClearDepth(ctx, clearSave); 486cdc920a0Smrg } 487cdc920a0Smrg /* clear depth buffer to value */ 488cdc920a0Smrg break; 489cdc920a0Smrg case GL_COLOR: 490cdc920a0Smrg { 491cdc920a0Smrg const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); 492cdc920a0Smrg if (mask == INVALID_MASK) { 493cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", 494cdc920a0Smrg drawbuffer); 495cdc920a0Smrg return; 496cdc920a0Smrg } 497cdc920a0Smrg else if (mask) { 498cdc920a0Smrg GLclampf clearSave[4]; 499cdc920a0Smrg /* save color */ 500cdc920a0Smrg COPY_4V(clearSave, ctx->Color.ClearColor); 501cdc920a0Smrg /* set color */ 502cdc920a0Smrg COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); 503cdc920a0Smrg if (ctx->Driver.ClearColor) 504cdc920a0Smrg ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); 505cdc920a0Smrg /* clear buffer(s) */ 506cdc920a0Smrg ctx->Driver.Clear(ctx, mask); 507cdc920a0Smrg /* restore color */ 508cdc920a0Smrg COPY_4V(ctx->Color.ClearColor, clearSave); 509cdc920a0Smrg if (ctx->Driver.ClearColor) 510cdc920a0Smrg ctx->Driver.ClearColor(ctx, clearSave); 511cdc920a0Smrg } 512cdc920a0Smrg } 513cdc920a0Smrg break; 514cdc920a0Smrg default: 515cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)", 516cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 517cdc920a0Smrg return; 518cdc920a0Smrg } 519cdc920a0Smrg} 520cdc920a0Smrg 521cdc920a0Smrg 522cdc920a0Smrg/** 523cdc920a0Smrg * New in GL 3.0 524cdc920a0Smrg * Clear depth/stencil buffer only. 525cdc920a0Smrg */ 526cdc920a0Smrgvoid GLAPIENTRY 527cdc920a0Smrg_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, 528cdc920a0Smrg GLfloat depth, GLint stencil) 529cdc920a0Smrg{ 530cdc920a0Smrg GET_CURRENT_CONTEXT(ctx); 531cdc920a0Smrg ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 532cdc920a0Smrg 533cdc920a0Smrg FLUSH_CURRENT(ctx, 0); 534cdc920a0Smrg 535cdc920a0Smrg if (buffer != GL_DEPTH_STENCIL) { 536cdc920a0Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)", 537cdc920a0Smrg _mesa_lookup_enum_by_nr(buffer)); 538cdc920a0Smrg return; 539cdc920a0Smrg } 540cdc920a0Smrg 541cdc920a0Smrg if (drawbuffer != 0) { 542cdc920a0Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)", 543cdc920a0Smrg drawbuffer); 544cdc920a0Smrg return; 545cdc920a0Smrg } 546cdc920a0Smrg 547cdc920a0Smrg if (ctx->NewState) { 548cdc920a0Smrg _mesa_update_state( ctx ); 549cdc920a0Smrg } 550cdc920a0Smrg 551cdc920a0Smrg { 552cdc920a0Smrg /* save current clear values */ 553cdc920a0Smrg const GLclampd clearDepthSave = ctx->Depth.Clear; 554cdc920a0Smrg const GLuint clearStencilSave = ctx->Stencil.Clear; 555cdc920a0Smrg 556cdc920a0Smrg /* set new clear values */ 557cdc920a0Smrg ctx->Depth.Clear = depth; 558cdc920a0Smrg ctx->Stencil.Clear = stencil; 559cdc920a0Smrg if (ctx->Driver.ClearDepth) 560cdc920a0Smrg ctx->Driver.ClearDepth(ctx, depth); 561cdc920a0Smrg if (ctx->Driver.ClearStencil) 562cdc920a0Smrg ctx->Driver.ClearStencil(ctx, stencil); 563cdc920a0Smrg 564cdc920a0Smrg /* clear buffers */ 565cdc920a0Smrg ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); 566cdc920a0Smrg 567cdc920a0Smrg /* restore */ 568cdc920a0Smrg ctx->Depth.Clear = clearDepthSave; 569cdc920a0Smrg ctx->Stencil.Clear = clearStencilSave; 570cdc920a0Smrg if (ctx->Driver.ClearDepth) 571cdc920a0Smrg ctx->Driver.ClearDepth(ctx, clearDepthSave); 572cdc920a0Smrg if (ctx->Driver.ClearStencil) 573cdc920a0Smrg ctx->Driver.ClearStencil(ctx, clearStencilSave); 574cdc920a0Smrg } 575cdc920a0Smrg} 576