Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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 "enums.h"
  37. #include "fbobject.h"
  38. #include "get.h"
  39. #include "macros.h"
  40. #include "mtypes.h"
  41. #include "state.h"
  42.  
  43.  
  44.  
  45. void GLAPIENTRY
  46. _mesa_ClearIndex( GLfloat c )
  47. {
  48.    GET_CURRENT_CONTEXT(ctx);
  49.  
  50.    ctx->Color.ClearIndex = (GLuint) c;
  51. }
  52.  
  53.  
  54. /**
  55.  * Specify the clear values for the color buffers.
  56.  *
  57.  * \param red red color component.
  58.  * \param green green color component.
  59.  * \param blue blue color component.
  60.  * \param alpha alpha component.
  61.  *
  62.  * \sa glClearColor().
  63.  */
  64. void GLAPIENTRY
  65. _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
  66. {
  67.    GET_CURRENT_CONTEXT(ctx);
  68.  
  69.    ctx->Color.ClearColor.f[0] = red;
  70.    ctx->Color.ClearColor.f[1] = green;
  71.    ctx->Color.ClearColor.f[2] = blue;
  72.    ctx->Color.ClearColor.f[3] = alpha;
  73. }
  74.  
  75.  
  76. /**
  77.  * GL_EXT_texture_integer
  78.  */
  79. void GLAPIENTRY
  80. _mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a)
  81. {
  82.    GET_CURRENT_CONTEXT(ctx);
  83.  
  84.    ctx->Color.ClearColor.i[0] = r;
  85.    ctx->Color.ClearColor.i[1] = g;
  86.    ctx->Color.ClearColor.i[2] = b;
  87.    ctx->Color.ClearColor.i[3] = a;
  88. }
  89.  
  90.  
  91. /**
  92.  * GL_EXT_texture_integer
  93.  */
  94. void GLAPIENTRY
  95. _mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a)
  96. {
  97.    GET_CURRENT_CONTEXT(ctx);
  98.  
  99.    ctx->Color.ClearColor.ui[0] = r;
  100.    ctx->Color.ClearColor.ui[1] = g;
  101.    ctx->Color.ClearColor.ui[2] = b;
  102.    ctx->Color.ClearColor.ui[3] = a;
  103. }
  104.  
  105.  
  106. /**
  107.  * Returns true if color writes are enabled for the given color attachment.
  108.  *
  109.  * Beyond checking ColorMask, this uses _mesa_format_has_color_component to
  110.  * ignore components that don't actually exist in the format (such as X in
  111.  * XRGB).
  112.  */
  113. static bool
  114. color_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx)
  115. {
  116.    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[idx];
  117.    GLuint c;
  118.    GLubyte colorMask = 0;
  119.  
  120.    if (rb) {
  121.       for (c = 0; c < 4; c++) {
  122.          if (_mesa_format_has_color_component(rb->Format, c))
  123.             colorMask |= ctx->Color.ColorMask[idx][c];
  124.       }
  125.    }
  126.  
  127.    return colorMask != 0;
  128. }
  129.  
  130.  
  131. /**
  132.  * Clear buffers.
  133.  *
  134.  * \param mask bit-mask indicating the buffers to be cleared.
  135.  *
  136.  * Flushes the vertices and verifies the parameter.
  137.  * If __struct gl_contextRec::NewState is set then calls _mesa_update_state()
  138.  * to update gl_frame_buffer::_Xmin, etc.  If the rasterization mode is set to
  139.  * GL_RENDER then requests the driver to clear the buffers, via the
  140.  * dd_function_table::Clear callback.
  141.  */
  142. void GLAPIENTRY
  143. _mesa_Clear( GLbitfield mask )
  144. {
  145.    GET_CURRENT_CONTEXT(ctx);
  146.    FLUSH_VERTICES(ctx, 0);
  147.  
  148.    FLUSH_CURRENT(ctx, 0);
  149.  
  150.    if (MESA_VERBOSE & VERBOSE_API)
  151.       _mesa_debug(ctx, "glClear 0x%x\n", mask);
  152.  
  153.    if (mask & ~(GL_COLOR_BUFFER_BIT |
  154.                 GL_DEPTH_BUFFER_BIT |
  155.                 GL_STENCIL_BUFFER_BIT |
  156.                 GL_ACCUM_BUFFER_BIT)) {
  157.       /* invalid bit set */
  158.       _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask);
  159.       return;
  160.    }
  161.  
  162.    /* Accumulation buffers were removed in core contexts, and they never
  163.     * existed in OpenGL ES.
  164.     */
  165.    if ((mask & GL_ACCUM_BUFFER_BIT) != 0
  166.        && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) {
  167.       _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)");
  168.       return;
  169.    }
  170.  
  171.    if (ctx->NewState) {
  172.       _mesa_update_state( ctx );        /* update _Xmin, etc */
  173.    }
  174.  
  175.    if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  176.       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
  177.                   "glClear(incomplete framebuffer)");
  178.       return;
  179.    }
  180.  
  181.    if (ctx->RasterDiscard)
  182.       return;
  183.  
  184.    if (ctx->RenderMode == GL_RENDER) {
  185.       GLbitfield bufferMask;
  186.  
  187.       /* don't clear depth buffer if depth writing disabled */
  188.       if (!ctx->Depth.Mask)
  189.          mask &= ~GL_DEPTH_BUFFER_BIT;
  190.  
  191.       /* Build the bitmask to send to device driver's Clear function.
  192.        * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
  193.        * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
  194.        * BUFFER_BIT_COLORn flags.
  195.        */
  196.       bufferMask = 0;
  197.       if (mask & GL_COLOR_BUFFER_BIT) {
  198.          GLuint i;
  199.          for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
  200.             GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
  201.  
  202.             if (buf >= 0 && color_buffer_writes_enabled(ctx, i)) {
  203.                bufferMask |= 1 << buf;
  204.             }
  205.          }
  206.       }
  207.  
  208.       if ((mask & GL_DEPTH_BUFFER_BIT)
  209.           && ctx->DrawBuffer->Visual.haveDepthBuffer) {
  210.          bufferMask |= BUFFER_BIT_DEPTH;
  211.       }
  212.  
  213.       if ((mask & GL_STENCIL_BUFFER_BIT)
  214.           && ctx->DrawBuffer->Visual.haveStencilBuffer) {
  215.          bufferMask |= BUFFER_BIT_STENCIL;
  216.       }
  217.  
  218.       if ((mask & GL_ACCUM_BUFFER_BIT)
  219.           && ctx->DrawBuffer->Visual.haveAccumBuffer) {
  220.          bufferMask |= BUFFER_BIT_ACCUM;
  221.       }
  222.  
  223.       assert(ctx->Driver.Clear);
  224.       ctx->Driver.Clear(ctx, bufferMask);
  225.    }
  226. }
  227.  
  228.  
  229. /** Returned by make_color_buffer_mask() for errors */
  230. #define INVALID_MASK ~0x0U
  231.  
  232.  
  233. /**
  234.  * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
  235.  * BUFFER_BIT_x values.
  236.  * Return INVALID_MASK if the drawbuffer value is invalid.
  237.  */
  238. static GLbitfield
  239. make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer)
  240. {
  241.    const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
  242.    GLbitfield mask = 0x0;
  243.  
  244.    /* From the GL 4.0 specification:
  245.     *   If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is
  246.     *   specified by passing i as the parameter drawbuffer, and value
  247.     *   points to a four-element vector specifying the R, G, B, and A
  248.     *   color to clear that draw buffer to. If the draw buffer is one
  249.     *   of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
  250.     *   multiple buffers, each selected buffer is cleared to the same
  251.     *   value.
  252.     *
  253.     * Note that "drawbuffer" and "draw buffer" have different meaning.
  254.     * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's
  255.     * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK,
  256.     * etc.
  257.     */
  258.    if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) {
  259.       return INVALID_MASK;
  260.    }
  261.  
  262.    switch (ctx->DrawBuffer->ColorDrawBuffer[drawbuffer]) {
  263.    case GL_FRONT:
  264.       if (att[BUFFER_FRONT_LEFT].Renderbuffer)
  265.          mask |= BUFFER_BIT_FRONT_LEFT;
  266.       if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
  267.          mask |= BUFFER_BIT_FRONT_RIGHT;
  268.       break;
  269.    case GL_BACK:
  270.       if (att[BUFFER_BACK_LEFT].Renderbuffer)
  271.          mask |= BUFFER_BIT_BACK_LEFT;
  272.       if (att[BUFFER_BACK_RIGHT].Renderbuffer)
  273.          mask |= BUFFER_BIT_BACK_RIGHT;
  274.       break;
  275.    case GL_LEFT:
  276.       if (att[BUFFER_FRONT_LEFT].Renderbuffer)
  277.          mask |= BUFFER_BIT_FRONT_LEFT;
  278.       if (att[BUFFER_BACK_LEFT].Renderbuffer)
  279.          mask |= BUFFER_BIT_BACK_LEFT;
  280.       break;
  281.    case GL_RIGHT:
  282.       if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
  283.          mask |= BUFFER_BIT_FRONT_RIGHT;
  284.       if (att[BUFFER_BACK_RIGHT].Renderbuffer)
  285.          mask |= BUFFER_BIT_BACK_RIGHT;
  286.       break;
  287.    case GL_FRONT_AND_BACK:
  288.       if (att[BUFFER_FRONT_LEFT].Renderbuffer)
  289.          mask |= BUFFER_BIT_FRONT_LEFT;
  290.       if (att[BUFFER_BACK_LEFT].Renderbuffer)
  291.          mask |= BUFFER_BIT_BACK_LEFT;
  292.       if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
  293.          mask |= BUFFER_BIT_FRONT_RIGHT;
  294.       if (att[BUFFER_BACK_RIGHT].Renderbuffer)
  295.          mask |= BUFFER_BIT_BACK_RIGHT;
  296.       break;
  297.    default:
  298.       {
  299.          GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer];
  300.  
  301.          if (buf >= 0 && att[buf].Renderbuffer) {
  302.             mask |= 1 << buf;
  303.          }
  304.       }
  305.    }
  306.  
  307.    return mask;
  308. }
  309.  
  310.  
  311.  
  312. /**
  313.  * New in GL 3.0
  314.  * Clear signed integer color buffer or stencil buffer (not depth).
  315.  */
  316. void GLAPIENTRY
  317. _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
  318. {
  319.    GET_CURRENT_CONTEXT(ctx);
  320.    FLUSH_VERTICES(ctx, 0);
  321.  
  322.    FLUSH_CURRENT(ctx, 0);
  323.  
  324.    if (ctx->NewState) {
  325.       _mesa_update_state( ctx );
  326.    }
  327.  
  328.    switch (buffer) {
  329.    case GL_STENCIL:
  330.       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
  331.        *
  332.        *     "ClearBuffer generates an INVALID VALUE error if buffer is
  333.        *     COLOR and drawbuffer is less than zero, or greater than the
  334.        *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
  335.        *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
  336.        */
  337.       if (drawbuffer != 0) {
  338.          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
  339.                      drawbuffer);
  340.          return;
  341.       }
  342.       else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer
  343.                && !ctx->RasterDiscard) {
  344.          /* Save current stencil clear value, set to 'value', do the
  345.           * stencil clear and restore the clear value.
  346.           * XXX in the future we may have a new ctx->Driver.ClearBuffer()
  347.           * hook instead.
  348.           */
  349.          const GLuint clearSave = ctx->Stencil.Clear;
  350.          ctx->Stencil.Clear = *value;
  351.          ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL);
  352.          ctx->Stencil.Clear = clearSave;
  353.       }
  354.       break;
  355.    case GL_COLOR:
  356.       {
  357.          const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
  358.          if (mask == INVALID_MASK) {
  359.             _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
  360.                         drawbuffer);
  361.             return;
  362.          }
  363.          else if (mask && !ctx->RasterDiscard) {
  364.             union gl_color_union clearSave;
  365.  
  366.             /* save color */
  367.             clearSave = ctx->Color.ClearColor;
  368.             /* set color */
  369.             COPY_4V(ctx->Color.ClearColor.i, value);
  370.             /* clear buffer(s) */
  371.             ctx->Driver.Clear(ctx, mask);
  372.             /* restore color */
  373.             ctx->Color.ClearColor = clearSave;
  374.          }
  375.       }
  376.       break;
  377.    case GL_DEPTH:
  378.       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
  379.        *
  380.        *     "The result of ClearBuffer is undefined if no conversion between
  381.        *     the type of the specified value and the type of the buffer being
  382.        *     cleared is defined (for example, if ClearBufferiv is called for a
  383.        *     fixed- or floating-point buffer, or if ClearBufferfv is called
  384.        *     for a signed or unsigned integer buffer). This is not an error."
  385.        *
  386.        * In this case we take "undefined" and "not an error" to mean "ignore."
  387.        * Note that we still need to generate an error for the invalid
  388.        * drawbuffer case (see the GL_STENCIL case above).
  389.        */
  390.       if (drawbuffer != 0) {
  391.          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
  392.                      drawbuffer);
  393.          return;
  394.       }
  395.       return;
  396.    default:
  397.       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
  398.                   _mesa_lookup_enum_by_nr(buffer));
  399.       return;
  400.    }
  401. }
  402.  
  403.  
  404. /**
  405.  * The ClearBuffer framework is so complicated and so riddled with the
  406.  * assumption that the framebuffer is bound that, for now, we will just fake
  407.  * direct state access clearing for the user.
  408.  */
  409. void GLAPIENTRY
  410. _mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer,
  411.                               GLint drawbuffer, const GLint *value)
  412. {
  413.    GLint oldfb;
  414.  
  415.    GET_CURRENT_CONTEXT(ctx);
  416.    if (!ctx->Extensions.ARB_direct_state_access) {
  417.       _mesa_error(ctx, GL_INVALID_OPERATION,
  418.                   "glClearNamedFramebufferiv(GL_ARB_direct_state_access "
  419.                   "is not supported)");
  420.       return;
  421.    }
  422.  
  423.    _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
  424.    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
  425.    _mesa_ClearBufferiv(buffer, drawbuffer, value);
  426.    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
  427. }
  428.  
  429.  
  430. /**
  431.  * New in GL 3.0
  432.  * Clear unsigned integer color buffer (not depth, not stencil).
  433.  */
  434. void GLAPIENTRY
  435. _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
  436. {
  437.    GET_CURRENT_CONTEXT(ctx);
  438.  
  439.    FLUSH_VERTICES(ctx, 0);
  440.    FLUSH_CURRENT(ctx, 0);
  441.  
  442.    if (ctx->NewState) {
  443.       _mesa_update_state( ctx );
  444.    }
  445.  
  446.    switch (buffer) {
  447.    case GL_COLOR:
  448.       {
  449.          const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
  450.          if (mask == INVALID_MASK) {
  451.             _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
  452.                         drawbuffer);
  453.             return;
  454.          }
  455.          else if (mask && !ctx->RasterDiscard) {
  456.             union gl_color_union clearSave;
  457.  
  458.             /* save color */
  459.             clearSave = ctx->Color.ClearColor;
  460.             /* set color */
  461.             COPY_4V(ctx->Color.ClearColor.ui, value);
  462.             /* clear buffer(s) */
  463.             ctx->Driver.Clear(ctx, mask);
  464.             /* restore color */
  465.             ctx->Color.ClearColor = clearSave;
  466.          }
  467.       }
  468.       break;
  469.    case GL_DEPTH:
  470.    case GL_STENCIL:
  471.       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
  472.        *
  473.        *     "The result of ClearBuffer is undefined if no conversion between
  474.        *     the type of the specified value and the type of the buffer being
  475.        *     cleared is defined (for example, if ClearBufferiv is called for a
  476.        *     fixed- or floating-point buffer, or if ClearBufferfv is called
  477.        *     for a signed or unsigned integer buffer). This is not an error."
  478.        *
  479.        * In this case we take "undefined" and "not an error" to mean "ignore."
  480.        * Even though we could do something sensible for GL_STENCIL, page 263
  481.        * (page 279 of the PDF) says:
  482.        *
  483.        *     "Only ClearBufferiv should be used to clear stencil buffers."
  484.        *
  485.        * Note that we still need to generate an error for the invalid
  486.        * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
  487.        */
  488.       if (drawbuffer != 0) {
  489.          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
  490.                      drawbuffer);
  491.          return;
  492.       }
  493.       return;
  494.    default:
  495.       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
  496.                   _mesa_lookup_enum_by_nr(buffer));
  497.       return;
  498.    }
  499. }
  500.  
  501.  
  502. /**
  503.  * The ClearBuffer framework is so complicated and so riddled with the
  504.  * assumption that the framebuffer is bound that, for now, we will just fake
  505.  * direct state access clearing for the user.
  506.  */
  507. void GLAPIENTRY
  508. _mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer,
  509.                                GLint drawbuffer, const GLuint *value)
  510. {
  511.    GLint oldfb;
  512.  
  513.    GET_CURRENT_CONTEXT(ctx);
  514.    if (!ctx->Extensions.ARB_direct_state_access) {
  515.       _mesa_error(ctx, GL_INVALID_OPERATION,
  516.                   "glClearNamedFramebufferuiv(GL_ARB_direct_state_access "
  517.                   "is not supported)");
  518.       return;
  519.    }
  520.  
  521.    _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
  522.    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
  523.    _mesa_ClearBufferuiv(buffer, drawbuffer, value);
  524.    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
  525. }
  526.  
  527.  
  528. /**
  529.  * New in GL 3.0
  530.  * Clear fixed-pt or float color buffer or depth buffer (not stencil).
  531.  */
  532. void GLAPIENTRY
  533. _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
  534. {
  535.    GET_CURRENT_CONTEXT(ctx);
  536.  
  537.    FLUSH_VERTICES(ctx, 0);
  538.    FLUSH_CURRENT(ctx, 0);
  539.  
  540.    if (ctx->NewState) {
  541.       _mesa_update_state( ctx );
  542.    }
  543.  
  544.    switch (buffer) {
  545.    case GL_DEPTH:
  546.       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
  547.        *
  548.        *     "ClearBuffer generates an INVALID VALUE error if buffer is
  549.        *     COLOR and drawbuffer is less than zero, or greater than the
  550.        *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
  551.        *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
  552.        */
  553.       if (drawbuffer != 0) {
  554.          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
  555.                      drawbuffer);
  556.          return;
  557.       }
  558.       else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer
  559.                && !ctx->RasterDiscard) {
  560.          /* Save current depth clear value, set to 'value', do the
  561.           * depth clear and restore the clear value.
  562.           * XXX in the future we may have a new ctx->Driver.ClearBuffer()
  563.           * hook instead.
  564.           */
  565.          const GLclampd clearSave = ctx->Depth.Clear;
  566.          ctx->Depth.Clear = *value;
  567.          ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH);
  568.          ctx->Depth.Clear = clearSave;
  569.       }
  570.       /* clear depth buffer to value */
  571.       break;
  572.    case GL_COLOR:
  573.       {
  574.          const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
  575.          if (mask == INVALID_MASK) {
  576.             _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
  577.                         drawbuffer);
  578.             return;
  579.          }
  580.          else if (mask && !ctx->RasterDiscard) {
  581.             union gl_color_union clearSave;
  582.  
  583.             /* save color */
  584.             clearSave = ctx->Color.ClearColor;
  585.             /* set color */
  586.             COPY_4V(ctx->Color.ClearColor.f, value);
  587.             /* clear buffer(s) */
  588.             ctx->Driver.Clear(ctx, mask);
  589.             /* restore color */
  590.             ctx->Color.ClearColor = clearSave;
  591.          }
  592.       }
  593.       break;
  594.    case GL_STENCIL:
  595.       /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
  596.        *
  597.        *     "The result of ClearBuffer is undefined if no conversion between
  598.        *     the type of the specified value and the type of the buffer being
  599.        *     cleared is defined (for example, if ClearBufferiv is called for a
  600.        *     fixed- or floating-point buffer, or if ClearBufferfv is called
  601.        *     for a signed or unsigned integer buffer). This is not an error."
  602.        *
  603.        * In this case we take "undefined" and "not an error" to mean "ignore."
  604.        * Note that we still need to generate an error for the invalid
  605.        * drawbuffer case (see the GL_DEPTH case above).
  606.        */
  607.       if (drawbuffer != 0) {
  608.          _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
  609.                      drawbuffer);
  610.          return;
  611.       }
  612.       return;
  613.    default:
  614.       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
  615.                   _mesa_lookup_enum_by_nr(buffer));
  616.       return;
  617.    }
  618. }
  619.  
  620.  
  621. /**
  622.  * The ClearBuffer framework is so complicated and so riddled with the
  623.  * assumption that the framebuffer is bound that, for now, we will just fake
  624.  * direct state access clearing for the user.
  625.  */
  626. void GLAPIENTRY
  627. _mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer,
  628.                               GLint drawbuffer, const GLfloat *value)
  629. {
  630.    GLint oldfb;
  631.  
  632.    GET_CURRENT_CONTEXT(ctx);
  633.    if (!ctx->Extensions.ARB_direct_state_access) {
  634.       _mesa_error(ctx, GL_INVALID_OPERATION,
  635.                   "glClearNamedFramebufferfv(GL_ARB_direct_state_access "
  636.                   "is not supported)");
  637.       return;
  638.    }
  639.  
  640.    _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
  641.    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
  642.    _mesa_ClearBufferfv(buffer, drawbuffer, value);
  643.    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
  644. }
  645.  
  646.  
  647. /**
  648.  * New in GL 3.0
  649.  * Clear depth/stencil buffer only.
  650.  */
  651. void GLAPIENTRY
  652. _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
  653.                     GLfloat depth, GLint stencil)
  654. {
  655.    GET_CURRENT_CONTEXT(ctx);
  656.    GLbitfield mask = 0;
  657.  
  658.    FLUSH_VERTICES(ctx, 0);
  659.    FLUSH_CURRENT(ctx, 0);
  660.  
  661.    if (buffer != GL_DEPTH_STENCIL) {
  662.       _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
  663.                   _mesa_lookup_enum_by_nr(buffer));
  664.       return;
  665.    }
  666.  
  667.    /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
  668.     *
  669.     *     "ClearBuffer generates an INVALID VALUE error if buffer is
  670.     *     COLOR and drawbuffer is less than zero, or greater than the
  671.     *     value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
  672.     *     STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
  673.     */
  674.    if (drawbuffer != 0) {
  675.       _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)",
  676.                   drawbuffer);
  677.       return;
  678.    }
  679.  
  680.    if (ctx->RasterDiscard)
  681.       return;
  682.  
  683.    if (ctx->NewState) {
  684.       _mesa_update_state( ctx );
  685.    }
  686.  
  687.    if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer)
  688.       mask |= BUFFER_BIT_DEPTH;
  689.    if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer)
  690.       mask |= BUFFER_BIT_STENCIL;
  691.  
  692.    if (mask) {
  693.       /* save current clear values */
  694.       const GLclampd clearDepthSave = ctx->Depth.Clear;
  695.       const GLuint clearStencilSave = ctx->Stencil.Clear;
  696.  
  697.       /* set new clear values */
  698.       ctx->Depth.Clear = depth;
  699.       ctx->Stencil.Clear = stencil;
  700.  
  701.       /* clear buffers */
  702.       ctx->Driver.Clear(ctx, mask);
  703.  
  704.       /* restore */
  705.       ctx->Depth.Clear = clearDepthSave;
  706.       ctx->Stencil.Clear = clearStencilSave;
  707.    }
  708. }
  709.  
  710.  
  711. /**
  712.  * The ClearBuffer framework is so complicated and so riddled with the
  713.  * assumption that the framebuffer is bound that, for now, we will just fake
  714.  * direct state access clearing for the user.
  715.  */
  716. void GLAPIENTRY
  717. _mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
  718.                               GLfloat depth, GLint stencil)
  719. {
  720.    GLint oldfb;
  721.  
  722.    GET_CURRENT_CONTEXT(ctx);
  723.    if (!ctx->Extensions.ARB_direct_state_access) {
  724.       _mesa_error(ctx, GL_INVALID_OPERATION,
  725.                   "glClearNamedFramebufferfi(GL_ARB_direct_state_access "
  726.                   "is not supported)");
  727.       return;
  728.    }
  729.  
  730.    _mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
  731.    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
  732.    _mesa_ClearBufferfi(buffer, 0, depth, stencil);
  733.    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
  734. }
  735.