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