Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  * Copyright 2009 VMware, Inc.  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
  9.  * "Software"), to deal in the Software without restriction, including
  10.  * without limitation the rights to use, copy, modify, merge, publish,
  11.  * distribute, sub license, and/or sell copies of the Software, and to
  12.  * permit persons to whom the Software is furnished to do so, subject to
  13.  * the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice (including the
  16.  * next paragraph) shall be included in all copies or substantial portions
  17.  * of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  22.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  23.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  24.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  25.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26.  *
  27.  **************************************************************************/
  28.  
  29.  /*
  30.   * Authors:
  31.   *   Keith Whitwell <keith@tungstengraphics.com>
  32.   *   Brian Paul
  33.   *   Michel Dänzer
  34.   */
  35.  
  36. #include "main/glheader.h"
  37. #include "main/formats.h"
  38. #include "main/macros.h"
  39. #include "program/prog_instruction.h"
  40. #include "st_context.h"
  41. #include "st_atom.h"
  42. #include "st_cb_accum.h"
  43. #include "st_cb_clear.h"
  44. #include "st_cb_fbo.h"
  45. #include "st_format.h"
  46. #include "st_program.h"
  47.  
  48. #include "pipe/p_context.h"
  49. #include "pipe/p_shader_tokens.h"
  50. #include "pipe/p_state.h"
  51. #include "pipe/p_defines.h"
  52. #include "util/u_format.h"
  53. #include "util/u_inlines.h"
  54. #include "util/u_simple_shaders.h"
  55. #include "util/u_draw_quad.h"
  56.  
  57. #include "cso_cache/cso_context.h"
  58.  
  59.  
  60. /**
  61.  * Do per-context initialization for glClear.
  62.  */
  63. void
  64. st_init_clear(struct st_context *st)
  65. {
  66.    struct pipe_context *pipe = st->pipe;
  67.    struct pipe_screen *pscreen = st->pipe->screen;
  68.  
  69.    memset(&st->clear, 0, sizeof(st->clear));
  70.  
  71.    st->clear.raster.gl_rasterization_rules = 1;
  72.    st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE);
  73.  
  74.    /* fragment shader state: color pass-through program */
  75.    st->clear.fs = util_make_fragment_passthrough_shader(pipe);
  76.  
  77.    /* vertex shader state: color/position pass-through */
  78.    {
  79.       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
  80.                                       TGSI_SEMANTIC_COLOR };
  81.       const uint semantic_indexes[] = { 0, 0 };
  82.       st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2,
  83.                                                          semantic_names,
  84.                                                          semantic_indexes);
  85.    }
  86. }
  87.  
  88.  
  89. /**
  90.  * Free per-context state for glClear.
  91.  */
  92. void
  93. st_destroy_clear(struct st_context *st)
  94. {
  95.    if (st->clear.fs) {
  96.       cso_delete_fragment_shader(st->cso_context, st->clear.fs);
  97.       st->clear.fs = NULL;
  98.    }
  99.    if (st->clear.vs) {
  100.       cso_delete_vertex_shader(st->cso_context, st->clear.vs);
  101.       st->clear.vs = NULL;
  102.    }
  103.    if (st->clear.vbuf) {
  104.       pipe_resource_reference(&st->clear.vbuf, NULL);
  105.       st->clear.vbuf = NULL;
  106.    }
  107. }
  108.  
  109.  
  110. /**
  111.  * Draw a screen-aligned quadrilateral.
  112.  * Coords are clip coords with y=0=bottom.
  113.  */
  114. static void
  115. draw_quad(struct st_context *st,
  116.           float x0, float y0, float x1, float y1, GLfloat z,
  117.           const GLfloat color[4])
  118. {
  119.    struct pipe_context *pipe = st->pipe;
  120.  
  121.    /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
  122.     * no_flush) updates to buffers where we know there is no conflict
  123.     * with previous data.  Currently using max_slots > 1 will cause
  124.     * synchronous rendering if the driver flushes its command buffers
  125.     * between one bitmap and the next.  Our flush hook below isn't
  126.     * sufficient to catch this as the driver doesn't tell us when it
  127.     * flushes its own command buffers.  Until this gets fixed, pay the
  128.     * price of allocating a new buffer for each bitmap cache-flush to
  129.     * avoid synchronous rendering.
  130.     */
  131.    const GLuint max_slots = 1; /* 1024 / sizeof(st->clear.vertices); */
  132.    GLuint i;
  133.  
  134.    if (st->clear.vbuf_slot >= max_slots) {
  135.       pipe_resource_reference(&st->clear.vbuf, NULL);
  136.       st->clear.vbuf_slot = 0;
  137.    }
  138.  
  139.    if (!st->clear.vbuf) {
  140.       st->clear.vbuf = pipe_buffer_create(pipe->screen,
  141.                                           PIPE_BIND_VERTEX_BUFFER,
  142.                                           max_slots * sizeof(st->clear.vertices));
  143.    }
  144.  
  145.    /* positions */
  146.    st->clear.vertices[0][0][0] = x0;
  147.    st->clear.vertices[0][0][1] = y0;
  148.  
  149.    st->clear.vertices[1][0][0] = x1;
  150.    st->clear.vertices[1][0][1] = y0;
  151.  
  152.    st->clear.vertices[2][0][0] = x1;
  153.    st->clear.vertices[2][0][1] = y1;
  154.  
  155.    st->clear.vertices[3][0][0] = x0;
  156.    st->clear.vertices[3][0][1] = y1;
  157.  
  158.    /* same for all verts: */
  159.    for (i = 0; i < 4; i++) {
  160.       st->clear.vertices[i][0][2] = z;
  161.       st->clear.vertices[i][0][3] = 1.0;
  162.       st->clear.vertices[i][1][0] = color[0];
  163.       st->clear.vertices[i][1][1] = color[1];
  164.       st->clear.vertices[i][1][2] = color[2];
  165.       st->clear.vertices[i][1][3] = color[3];
  166.    }
  167.  
  168.    /* put vertex data into vbuf */
  169.    pipe_buffer_write_nooverlap(st->pipe, st->clear.vbuf,
  170.                                            st->clear.vbuf_slot
  171.                                              * sizeof(st->clear.vertices),
  172.                                            sizeof(st->clear.vertices),
  173.                                            st->clear.vertices);
  174.  
  175.    /* draw */
  176.    util_draw_vertex_buffer(pipe,
  177.                            st->clear.vbuf,
  178.                            st->clear.vbuf_slot * sizeof(st->clear.vertices),
  179.                            PIPE_PRIM_TRIANGLE_FAN,
  180.                            4,  /* verts */
  181.                            2); /* attribs/vert */
  182.  
  183.    /* Increment slot */
  184.    st->clear.vbuf_slot++;
  185. }
  186.  
  187.  
  188.  
  189. /**
  190.  * Do glClear by drawing a quadrilateral.
  191.  * The vertices of the quad will be computed from the
  192.  * ctx->DrawBuffer->_X/Ymin/max fields.
  193.  */
  194. static void
  195. clear_with_quad(struct gl_context *ctx,
  196.                 GLboolean color, GLboolean depth, GLboolean stencil)
  197. {
  198.    struct st_context *st = st_context(ctx);
  199.    const struct gl_framebuffer *fb = ctx->DrawBuffer;
  200.    const GLfloat fb_width = (GLfloat) fb->Width;
  201.    const GLfloat fb_height = (GLfloat) fb->Height;
  202.    const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
  203.    const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
  204.    const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
  205.    const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
  206.    float clearColor[4];
  207.  
  208.    /*
  209.    printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__,
  210.           color ? "color, " : "",
  211.           depth ? "depth, " : "",
  212.           stencil ? "stencil" : "",
  213.           x0, y0,
  214.           x1, y1);
  215.    */
  216.  
  217.    cso_save_blend(st->cso_context);
  218.    cso_save_stencil_ref(st->cso_context);
  219.    cso_save_depth_stencil_alpha(st->cso_context);
  220.    cso_save_rasterizer(st->cso_context);
  221.    cso_save_viewport(st->cso_context);
  222.    cso_save_clip(st->cso_context);
  223.    cso_save_fragment_shader(st->cso_context);
  224.    cso_save_vertex_shader(st->cso_context);
  225.    cso_save_vertex_elements(st->cso_context);
  226.  
  227.    /* blend state: RGBA masking */
  228.    {
  229.       struct pipe_blend_state blend;
  230.       memset(&blend, 0, sizeof(blend));
  231.       blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
  232.       blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
  233.       blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
  234.       blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
  235.       if (color) {
  236.          if (ctx->Color.ColorMask[0][0])
  237.             blend.rt[0].colormask |= PIPE_MASK_R;
  238.          if (ctx->Color.ColorMask[0][1])
  239.             blend.rt[0].colormask |= PIPE_MASK_G;
  240.          if (ctx->Color.ColorMask[0][2])
  241.             blend.rt[0].colormask |= PIPE_MASK_B;
  242.          if (ctx->Color.ColorMask[0][3])
  243.             blend.rt[0].colormask |= PIPE_MASK_A;
  244.          if (st->ctx->Color.DitherFlag)
  245.             blend.dither = 1;
  246.       }
  247.       cso_set_blend(st->cso_context, &blend);
  248.    }
  249.  
  250.    /* depth_stencil state: always pass/set to ref value */
  251.    {
  252.       struct pipe_depth_stencil_alpha_state depth_stencil;
  253.       memset(&depth_stencil, 0, sizeof(depth_stencil));
  254.       if (depth) {
  255.          depth_stencil.depth.enabled = 1;
  256.          depth_stencil.depth.writemask = 1;
  257.          depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
  258.       }
  259.  
  260.       if (stencil) {
  261.          struct pipe_stencil_ref stencil_ref;
  262.          memset(&stencil_ref, 0, sizeof(stencil_ref));
  263.          depth_stencil.stencil[0].enabled = 1;
  264.          depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
  265.          depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
  266.          depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
  267.          depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
  268.          depth_stencil.stencil[0].valuemask = 0xff;
  269.          depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
  270.          stencil_ref.ref_value[0] = ctx->Stencil.Clear;
  271.          cso_set_stencil_ref(st->cso_context, &stencil_ref);
  272.       }
  273.  
  274.       cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
  275.    }
  276.  
  277.    cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
  278.  
  279.    cso_set_rasterizer(st->cso_context, &st->clear.raster);
  280.  
  281.    /* viewport state: viewport matching window dims */
  282.    {
  283.       const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
  284.       struct pipe_viewport_state vp;
  285.       vp.scale[0] = 0.5f * fb_width;
  286.       vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f);
  287.       vp.scale[2] = 1.0f;
  288.       vp.scale[3] = 1.0f;
  289.       vp.translate[0] = 0.5f * fb_width;
  290.       vp.translate[1] = 0.5f * fb_height;
  291.       vp.translate[2] = 0.0f;
  292.       vp.translate[3] = 0.0f;
  293.       cso_set_viewport(st->cso_context, &vp);
  294.    }
  295.  
  296.    cso_set_clip(st->cso_context, &st->clear.clip);
  297.    cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
  298.    cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
  299.  
  300.    st_translate_color(ctx->Color.ClearColor,
  301.                       ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
  302.                       clearColor);
  303.  
  304.    /* draw quad matching scissor rect */
  305.    draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, clearColor);
  306.  
  307.    /* Restore pipe state */
  308.    cso_restore_blend(st->cso_context);
  309.    cso_restore_stencil_ref(st->cso_context);
  310.    cso_restore_depth_stencil_alpha(st->cso_context);
  311.    cso_restore_rasterizer(st->cso_context);
  312.    cso_restore_viewport(st->cso_context);
  313.    cso_restore_clip(st->cso_context);
  314.    cso_restore_fragment_shader(st->cso_context);
  315.    cso_restore_vertex_shader(st->cso_context);
  316.    cso_restore_vertex_elements(st->cso_context);
  317. }
  318.  
  319.  
  320. /**
  321.  * Determine if we need to clear the depth buffer by drawing a quad.
  322.  */
  323. static INLINE GLboolean
  324. check_clear_color_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb)
  325. {
  326.    if (ctx->Scissor.Enabled &&
  327.        (ctx->Scissor.X != 0 ||
  328.         ctx->Scissor.Y != 0 ||
  329.         ctx->Scissor.Width < rb->Width ||
  330.         ctx->Scissor.Height < rb->Height))
  331.       return GL_TRUE;
  332.  
  333.    if (!ctx->Color.ColorMask[0][0] ||
  334.        !ctx->Color.ColorMask[0][1] ||
  335.        !ctx->Color.ColorMask[0][2] ||
  336.        !ctx->Color.ColorMask[0][3])
  337.       return GL_TRUE;
  338.  
  339.    return GL_FALSE;
  340. }
  341.  
  342.  
  343. /**
  344.  * Determine if we need to clear the combiend depth/stencil buffer by
  345.  * drawing a quad.
  346.  */
  347. static INLINE GLboolean
  348. check_clear_depth_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb)
  349. {
  350.    const GLuint stencilMax = 0xff;
  351.    GLboolean maskStencil
  352.       = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
  353.  
  354.    assert(rb->Format == MESA_FORMAT_S8 ||
  355.           rb->Format == MESA_FORMAT_Z24_S8 ||
  356.           rb->Format == MESA_FORMAT_S8_Z24);
  357.  
  358.    if (ctx->Scissor.Enabled &&
  359.        (ctx->Scissor.X != 0 ||
  360.         ctx->Scissor.Y != 0 ||
  361.         ctx->Scissor.Width < rb->Width ||
  362.         ctx->Scissor.Height < rb->Height))
  363.       return GL_TRUE;
  364.  
  365.    if (maskStencil)
  366.       return GL_TRUE;
  367.  
  368.    return GL_FALSE;
  369. }
  370.  
  371.  
  372. /**
  373.  * Determine if we need to clear the depth buffer by drawing a quad.
  374.  */
  375. static INLINE GLboolean
  376. check_clear_depth_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb,
  377.                             boolean ds_separate)
  378. {
  379.    const struct st_renderbuffer *strb = st_renderbuffer(rb);
  380.    const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
  381.  
  382.    if (ctx->Scissor.Enabled &&
  383.        (ctx->Scissor.X != 0 ||
  384.         ctx->Scissor.Y != 0 ||
  385.         ctx->Scissor.Width < rb->Width ||
  386.         ctx->Scissor.Height < rb->Height))
  387.       return GL_TRUE;
  388.  
  389.    if (!ds_separate && isDS && ctx->DrawBuffer->Visual.stencilBits > 0)
  390.       return GL_TRUE;
  391.  
  392.    return GL_FALSE;
  393. }
  394.  
  395.  
  396. /**
  397.  * Determine if we need to clear the stencil buffer by drawing a quad.
  398.  */
  399. static INLINE GLboolean
  400. check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb,
  401.                               boolean ds_separate)
  402. {
  403.    const struct st_renderbuffer *strb = st_renderbuffer(rb);
  404.    const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
  405.    const GLuint stencilMax = 0xff;
  406.    const GLboolean maskStencil
  407.       = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
  408.  
  409.    assert(rb->Format == MESA_FORMAT_S8 ||
  410.           rb->Format == MESA_FORMAT_Z24_S8 ||
  411.           rb->Format == MESA_FORMAT_S8_Z24);
  412.  
  413.    if (maskStencil)
  414.       return GL_TRUE;
  415.  
  416.    if (ctx->Scissor.Enabled &&
  417.        (ctx->Scissor.X != 0 ||
  418.         ctx->Scissor.Y != 0 ||
  419.         ctx->Scissor.Width < rb->Width ||
  420.         ctx->Scissor.Height < rb->Height))
  421.       return GL_TRUE;
  422.  
  423.    /* This is correct, but it is necessary to look at the depth clear
  424.     * value held in the surface when it comes time to issue the clear,
  425.     * rather than taking depth and stencil clear values from the
  426.     * current state.
  427.     */
  428.    if (!ds_separate && isDS && ctx->DrawBuffer->Visual.depthBits > 0)
  429.       return GL_TRUE;
  430.  
  431.    return GL_FALSE;
  432. }
  433.  
  434.  
  435.  
  436. /**
  437.  * Called when we need to flush.
  438.  */
  439. void
  440. st_flush_clear(struct st_context *st)
  441. {
  442.    /* Release vertex buffer to avoid synchronous rendering if we were
  443.     * to map it in the next frame.
  444.     */
  445.    pipe_resource_reference(&st->clear.vbuf, NULL);
  446.    st->clear.vbuf_slot = 0;
  447. }
  448.  
  449.  
  450.  
  451. /**
  452.  * Called via ctx->Driver.Clear()
  453.  */
  454. static void
  455. st_Clear(struct gl_context *ctx, GLbitfield mask)
  456. {
  457.    static const GLbitfield BUFFER_BITS_DS
  458.       = (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
  459.    struct st_context *st = st_context(ctx);
  460.    struct gl_renderbuffer *depthRb
  461.       = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
  462.    struct gl_renderbuffer *stencilRb
  463.       = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
  464.    GLbitfield quad_buffers = 0x0;
  465.    GLbitfield clear_buffers = 0x0;
  466.    GLuint i;
  467.  
  468.    /* This makes sure the pipe has the latest scissor, etc values */
  469.    st_validate_state( st );
  470.  
  471.    if (mask & BUFFER_BITS_COLOR) {
  472.       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
  473.          GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
  474.  
  475.          if (mask & (1 << b)) {
  476.             struct gl_renderbuffer *rb
  477.                = ctx->DrawBuffer->Attachment[b].Renderbuffer;
  478.             struct st_renderbuffer *strb = st_renderbuffer(rb);
  479.  
  480.             if (!strb || !strb->surface)
  481.                continue;
  482.  
  483.             if (check_clear_color_with_quad( ctx, rb ))
  484.                quad_buffers |= PIPE_CLEAR_COLOR;
  485.             else
  486.                clear_buffers |= PIPE_CLEAR_COLOR;
  487.          }
  488.       }
  489.    }
  490.  
  491.    if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) {
  492.       /* clearing combined depth + stencil */
  493.       struct st_renderbuffer *strb = st_renderbuffer(depthRb);
  494.  
  495.       if (strb->surface) {
  496.          if (check_clear_depth_stencil_with_quad(ctx, depthRb))
  497.             quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
  498.          else
  499.             clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
  500.       }
  501.    }
  502.    else {
  503.       /* separate depth/stencil clears */
  504.       /* I don't think truly separate buffers are actually possible in gallium or hw? */
  505.       if (mask & BUFFER_BIT_DEPTH) {
  506.          struct st_renderbuffer *strb = st_renderbuffer(depthRb);
  507.  
  508.          if (strb->surface) {
  509.             if (check_clear_depth_with_quad(ctx, depthRb,
  510.                                             st->clear.enable_ds_separate))
  511.                quad_buffers |= PIPE_CLEAR_DEPTH;
  512.             else
  513.                clear_buffers |= PIPE_CLEAR_DEPTH;
  514.          }
  515.       }
  516.       if (mask & BUFFER_BIT_STENCIL) {
  517.          struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
  518.  
  519.          if (strb->surface) {
  520.             if (check_clear_stencil_with_quad(ctx, stencilRb,
  521.                                               st->clear.enable_ds_separate))
  522.                quad_buffers |= PIPE_CLEAR_STENCIL;
  523.             else
  524.                clear_buffers |= PIPE_CLEAR_STENCIL;
  525.          }
  526.       }
  527.    }
  528.  
  529.    /*
  530.     * If we're going to use clear_with_quad() for any reason, use it for
  531.     * everything possible.
  532.     */
  533.    if (quad_buffers) {
  534.       quad_buffers |= clear_buffers;
  535.       clear_with_quad(ctx,
  536.                       quad_buffers & PIPE_CLEAR_COLOR,
  537.                       quad_buffers & PIPE_CLEAR_DEPTH,
  538.                       quad_buffers & PIPE_CLEAR_STENCIL);
  539.    } else if (clear_buffers) {
  540.       /* driver cannot know it can clear everything if the buffer
  541.        * is a combined depth/stencil buffer but this wasn't actually
  542.        * required from the visual. Hence fix this up to avoid potential
  543.        * read-modify-write in the driver.
  544.        */
  545.       float clearColor[4];
  546.  
  547.       if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) &&
  548.           ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
  549.           (depthRb == stencilRb) &&
  550.           (ctx->DrawBuffer->Visual.depthBits == 0 ||
  551.            ctx->DrawBuffer->Visual.stencilBits == 0))
  552.          clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
  553.  
  554.       st_translate_color(ctx->Color.ClearColor,
  555.                          ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
  556.                          clearColor);
  557.  
  558.       st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColor,
  559.                       ctx->Depth.Clear, ctx->Stencil.Clear);
  560.    }
  561.    if (mask & BUFFER_BIT_ACCUM)
  562.       st_clear_accum_buffer(ctx,
  563.                             ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
  564. }
  565.  
  566.  
  567. void
  568. st_init_clear_functions(struct dd_function_table *functions)
  569. {
  570.    functions->Clear = st_Clear;
  571. }
  572.