Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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