s/Tungsten Graphics/VMware/
[mesa.git] / src / mesa / state_tracker / st_cb_clear.c
index e731b6b5e2e0ea460cccbc763f8baa170538b421..28f9c83d5d3fb8e90c9619aaa42238f7832cc9dc 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007 VMware, Inc.
  * All Rights Reserved.
  * Copyright 2009 VMware, Inc.  All Rights Reserved.
  * 
@@ -19,7 +19,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -28,7 +28,7 @@
 
  /*
   * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Keith Whitwell <keithw@vmware.com>
   *   Brian Paul
   *   Michel Dänzer
   */
@@ -37,6 +37,7 @@
 #include "main/accum.h"
 #include "main/formats.h"
 #include "main/macros.h"
+#include "main/glformats.h"
 #include "program/prog_instruction.h"
 #include "st_context.h"
 #include "st_atom.h"
@@ -50,6 +51,7 @@
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 #include "util/u_format.h"
+#include "util/u_framebuffer.h"
 #include "util/u_inlines.h"
 #include "util/u_simple_shaders.h"
 #include "util/u_draw_quad.h"
 void
 st_init_clear(struct st_context *st)
 {
-   struct pipe_screen *pscreen = st->pipe->screen;
-
    memset(&st->clear, 0, sizeof(st->clear));
 
-   st->clear.raster.gl_rasterization_rules = 1;
+   st->clear.raster.half_pixel_center = 1;
+   st->clear.raster.bottom_edge_rule = 1;
    st->clear.raster.depth_clip = 1;
-   st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE);
 }
 
 
@@ -98,7 +98,10 @@ static INLINE void
 set_fragment_shader(struct st_context *st)
 {
    if (!st->clear.fs)
-      st->clear.fs = util_make_fragment_passthrough_shader(st->pipe);
+      st->clear.fs =
+         util_make_fragment_passthrough_shader(st->pipe, TGSI_SEMANTIC_GENERIC,
+                                               TGSI_INTERPOLATE_CONSTANT,
+                                               TRUE);
 
    cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
 }
@@ -116,7 +119,7 @@ set_vertex_shader(struct st_context *st)
    if (!st->clear.vs)
    {
       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
-                                      TGSI_SEMANTIC_COLOR };
+                                      TGSI_SEMANTIC_GENERIC };
       const uint semantic_indexes[] = { 0, 0 };
       st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2,
                                                          semantic_names,
@@ -127,6 +130,26 @@ set_vertex_shader(struct st_context *st)
 }
 
 
+static void
+set_vertex_shader_layered(struct st_context *st)
+{
+   struct pipe_context *pipe = st->pipe;
+
+   if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) ||
+       !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) {
+      assert(!"Got layered clear, but the VS layer output is unsupported");
+      set_vertex_shader(st);
+      return;
+   }
+
+   if (!st->clear.vs_layered) {
+      st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe);
+   }
+
+   cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered);
+}
+
+
 /**
  * Draw a screen-aligned quadrilateral.
  * Coords are clip coords with y=0=bottom.
@@ -134,16 +157,19 @@ set_vertex_shader(struct st_context *st)
 static void
 draw_quad(struct st_context *st,
           float x0, float y0, float x1, float y1, GLfloat z,
+          unsigned num_instances,
           const union pipe_color_union *color)
 {
-   struct pipe_context *pipe = st->pipe;
-   struct pipe_resource *vbuf = NULL;
-   GLuint i, offset;
+   struct cso_context *cso = st->cso_context;
+   struct pipe_vertex_buffer vb = {0};
+   GLuint i;
    float (*vertices)[2][4];  /**< vertex pos + color */
 
-   u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]), &offset, &vbuf,
-                 (void**)&vertices);
-   if (!vbuf) {
+   vb.stride = 8 * sizeof(float);
+
+   if (u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]),
+                      &vb.buffer_offset, &vb.buffer,
+                      (void **) &vertices) != PIPE_OK) {
       return;
    }
 
@@ -173,14 +199,10 @@ draw_quad(struct st_context *st,
    u_upload_unmap(st->uploader);
 
    /* draw */
-   util_draw_vertex_buffer(pipe,
-                           st->cso_context,
-                           vbuf, offset,
-                           PIPE_PRIM_TRIANGLE_FAN,
-                           4,  /* verts */
-                           2); /* attribs/vert */
-
-   pipe_resource_reference(&vbuf, NULL);
+   cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, &vb);
+   cso_draw_arrays_instanced(cso, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
+                             0, num_instances);
+   pipe_resource_reference(&vb.buffer, NULL);
 }
 
 
@@ -191,8 +213,7 @@ draw_quad(struct st_context *st,
  * ctx->DrawBuffer->_X/Ymin/max fields.
  */
 static void
-clear_with_quad(struct gl_context *ctx,
-                GLboolean color, GLboolean depth, GLboolean stencil)
+clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
 {
    struct st_context *st = st_context(ctx);
    const struct gl_framebuffer *fb = ctx->DrawBuffer;
@@ -202,7 +223,8 @@ clear_with_quad(struct gl_context *ctx,
    const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
    const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
    const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
-   union pipe_color_union clearColor;
+   unsigned num_layers =
+      util_framebuffer_get_num_layers(&st->state.framebuffer);
 
    /*
    printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, 
@@ -224,25 +246,33 @@ clear_with_quad(struct gl_context *ctx,
    cso_save_vertex_shader(st->cso_context);
    cso_save_geometry_shader(st->cso_context);
    cso_save_vertex_elements(st->cso_context);
-   cso_save_vertex_buffers(st->cso_context);
+   cso_save_aux_vertex_buffer_slot(st->cso_context);
 
    /* blend state: RGBA masking */
    {
       struct pipe_blend_state blend;
       memset(&blend, 0, sizeof(blend));
-      blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      if (color) {
-         if (ctx->Color.ColorMask[0][0])
-            blend.rt[0].colormask |= PIPE_MASK_R;
-         if (ctx->Color.ColorMask[0][1])
-            blend.rt[0].colormask |= PIPE_MASK_G;
-         if (ctx->Color.ColorMask[0][2])
-            blend.rt[0].colormask |= PIPE_MASK_B;
-         if (ctx->Color.ColorMask[0][3])
-            blend.rt[0].colormask |= PIPE_MASK_A;
+      if (clear_buffers & PIPE_CLEAR_COLOR) {
+         int num_buffers = ctx->Extensions.EXT_draw_buffers2 ?
+                           ctx->DrawBuffer->_NumColorDrawBuffers : 1;
+         int i;
+
+         blend.independent_blend_enable = num_buffers > 1;
+
+         for (i = 0; i < num_buffers; i++) {
+            if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))
+               continue;
+
+            if (ctx->Color.ColorMask[i][0])
+               blend.rt[i].colormask |= PIPE_MASK_R;
+            if (ctx->Color.ColorMask[i][1])
+               blend.rt[i].colormask |= PIPE_MASK_G;
+            if (ctx->Color.ColorMask[i][2])
+               blend.rt[i].colormask |= PIPE_MASK_B;
+            if (ctx->Color.ColorMask[i][3])
+               blend.rt[i].colormask |= PIPE_MASK_A;
+         }
+
          if (st->ctx->Color.DitherFlag)
             blend.dither = 1;
       }
@@ -253,13 +283,13 @@ clear_with_quad(struct gl_context *ctx,
    {
       struct pipe_depth_stencil_alpha_state depth_stencil;
       memset(&depth_stencil, 0, sizeof(depth_stencil));
-      if (depth) {
+      if (clear_buffers & PIPE_CLEAR_DEPTH) {
          depth_stencil.depth.enabled = 1;
          depth_stencil.depth.writemask = 1;
          depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
       }
 
-      if (stencil) {
+      if (clear_buffers & PIPE_CLEAR_STENCIL) {
          struct pipe_stencil_ref stencil_ref;
          memset(&stencil_ref, 0, sizeof(stencil_ref));
          depth_stencil.stencil[0].enabled = 1;
@@ -297,17 +327,20 @@ clear_with_quad(struct gl_context *ctx,
    }
 
    set_fragment_shader(st);
-   set_vertex_shader(st);
    cso_set_geometry_shader_handle(st->cso_context, NULL);
 
-   if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
-      st_translate_color(ctx->Color.ClearColor.f,
-                               ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
-                               clearColor.f);
-   }
+   if (num_layers > 1)
+      set_vertex_shader_layered(st);
+   else
+      set_vertex_shader(st);
+
+   /* We can't translate the clear color to the colorbuffer format,
+    * because different colorbuffers may have different formats.
+    */
 
    /* draw quad matching scissor rect */
-   draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, &clearColor);
+   draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers,
+             (union pipe_color_union*)&ctx->Color.ClearColor);
 
    /* Restore pipe state */
    cso_restore_blend(st->cso_context);
@@ -320,119 +353,74 @@ clear_with_quad(struct gl_context *ctx,
    cso_restore_vertex_shader(st->cso_context);
    cso_restore_geometry_shader(st->cso_context);
    cso_restore_vertex_elements(st->cso_context);
-   cso_restore_vertex_buffers(st->cso_context);
+   cso_restore_aux_vertex_buffer_slot(st->cso_context);
    cso_restore_stream_outputs(st->cso_context);
 }
 
 
 /**
- * Determine if we need to clear the depth buffer by drawing a quad.
+ * Return if the scissor must be enabled during the clear.
  */
 static INLINE GLboolean
-check_clear_color_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb)
+is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
 {
-   if (ctx->Scissor.Enabled &&
-       (ctx->Scissor.X != 0 ||
-        ctx->Scissor.Y != 0 ||
-        ctx->Scissor.Width < rb->Width ||
-        ctx->Scissor.Height < rb->Height))
-      return GL_TRUE;
-
-   if (!ctx->Color.ColorMask[0][0] ||
-       !ctx->Color.ColorMask[0][1] ||
-       !ctx->Color.ColorMask[0][2] ||
-       !ctx->Color.ColorMask[0][3])
-      return GL_TRUE;
-
-   return GL_FALSE;
+   return ctx->Scissor.Enabled &&
+          (ctx->Scissor.X > 0 ||
+           ctx->Scissor.Y > 0 ||
+           (unsigned) ctx->Scissor.Width < rb->Width ||
+           (unsigned) ctx->Scissor.Height < rb->Height);
 }
 
 
 /**
- * Determine if we need to clear the combiend depth/stencil buffer by
- * drawing a quad.
+ * Return if all of the color channels are masked.
  */
 static INLINE GLboolean
-check_clear_depth_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb)
+is_color_disabled(struct gl_context *ctx, int i)
 {
-   const GLuint stencilMax = 0xff;
-   GLboolean maskStencil
-      = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
-
-   assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
-
-   if (ctx->Scissor.Enabled &&
-       (ctx->Scissor.X != 0 ||
-        ctx->Scissor.Y != 0 ||
-        ctx->Scissor.Width < rb->Width ||
-        ctx->Scissor.Height < rb->Height))
-      return GL_TRUE;
-
-   if (maskStencil)
-      return GL_TRUE;
-
-   return GL_FALSE;
+   return !ctx->Color.ColorMask[i][0] &&
+          !ctx->Color.ColorMask[i][1] &&
+          !ctx->Color.ColorMask[i][2] &&
+          !ctx->Color.ColorMask[i][3];
 }
 
 
 /**
- * Determine if we need to clear the depth buffer by drawing a quad.
+ * Return if any of the color channels are masked.
  */
 static INLINE GLboolean
-check_clear_depth_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb,
-                            boolean ds_separate)
+is_color_masked(struct gl_context *ctx, int i)
 {
-   const struct st_renderbuffer *strb = st_renderbuffer(rb);
-   const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
-
-   if (ctx->Scissor.Enabled &&
-       (ctx->Scissor.X != 0 ||
-        ctx->Scissor.Y != 0 ||
-        ctx->Scissor.Width < rb->Width ||
-        ctx->Scissor.Height < rb->Height))
-      return GL_TRUE;
-
-   if (!ds_separate && isDS && ctx->DrawBuffer->Visual.stencilBits > 0)
-      return GL_TRUE;
-
-   return GL_FALSE;
+   return !ctx->Color.ColorMask[i][0] ||
+          !ctx->Color.ColorMask[i][1] ||
+          !ctx->Color.ColorMask[i][2] ||
+          !ctx->Color.ColorMask[i][3];
 }
 
 
 /**
- * Determine if we need to clear the stencil buffer by drawing a quad.
+ * Return if all of the stencil bits are masked.
  */
 static INLINE GLboolean
-check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb,
-                              boolean ds_separate)
+is_stencil_disabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
 {
-   const struct st_renderbuffer *strb = st_renderbuffer(rb);
-   const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
    const GLuint stencilMax = 0xff;
-   const GLboolean maskStencil
-      = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
 
    assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
+   return (ctx->Stencil.WriteMask[0] & stencilMax) == 0;
+}
 
-   if (maskStencil) 
-      return GL_TRUE;
-
-   if (ctx->Scissor.Enabled &&
-       (ctx->Scissor.X != 0 ||
-        ctx->Scissor.Y != 0 ||
-        ctx->Scissor.Width < rb->Width ||
-        ctx->Scissor.Height < rb->Height))
-      return GL_TRUE;
 
-   /* This is correct, but it is necessary to look at the depth clear
-    * value held in the surface when it comes time to issue the clear,
-    * rather than taking depth and stencil clear values from the
-    * current state.
-    */
-   if (!ds_separate && isDS && ctx->DrawBuffer->Visual.depthBits > 0)
-      return GL_TRUE;
+/**
+ * Return if any of the stencil bits are masked.
+ */
+static INLINE GLboolean
+is_stencil_masked(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+   const GLuint stencilMax = 0xff;
 
-   return GL_FALSE;
+   assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
+   return (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
 }
 
 
@@ -442,8 +430,6 @@ check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb
 static void
 st_Clear(struct gl_context *ctx, GLbitfield mask)
 {
-   static const GLbitfield BUFFER_BITS_DS
-      = (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
    struct st_context *st = st_context(ctx);
    struct gl_renderbuffer *depthRb
       = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
@@ -458,94 +444,73 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
 
    if (mask & BUFFER_BITS_COLOR) {
       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
-         GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
+         GLint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
 
-         if (mask & (1 << b)) {
+         if (b >= 0 && mask & (1 << b)) {
             struct gl_renderbuffer *rb
                = ctx->DrawBuffer->Attachment[b].Renderbuffer;
             struct st_renderbuffer *strb = st_renderbuffer(rb);
+            int colormask_index = ctx->Extensions.EXT_draw_buffers2 ? i : 0;
 
             if (!strb || !strb->surface)
                continue;
 
-            if (check_clear_color_with_quad( ctx, rb ))
-               quad_buffers |= PIPE_CLEAR_COLOR;
+            if (is_color_disabled(ctx, colormask_index))
+               continue;
+
+            if (is_scissor_enabled(ctx, rb) ||
+                is_color_masked(ctx, colormask_index))
+               quad_buffers |= PIPE_CLEAR_COLOR0 << i;
             else
-               clear_buffers |= PIPE_CLEAR_COLOR;
+               clear_buffers |= PIPE_CLEAR_COLOR0 << i;
          }
       }
    }
 
-   if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) {
-      /* clearing combined depth + stencil */
+   if (mask & BUFFER_BIT_DEPTH) {
       struct st_renderbuffer *strb = st_renderbuffer(depthRb);
 
-      if (strb->surface) {
-         if (check_clear_depth_stencil_with_quad(ctx, depthRb))
-            quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+      if (strb->surface && ctx->Depth.Mask) {
+         if (is_scissor_enabled(ctx, depthRb))
+            quad_buffers |= PIPE_CLEAR_DEPTH;
          else
-            clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
+            clear_buffers |= PIPE_CLEAR_DEPTH;
       }
    }
-   else {
-      /* separate depth/stencil clears */
-      /* I don't think truly separate buffers are actually possible in gallium or hw? */
-      if (mask & BUFFER_BIT_DEPTH) {
-         struct st_renderbuffer *strb = st_renderbuffer(depthRb);
-
-         if (strb->surface) {
-            if (check_clear_depth_with_quad(ctx, depthRb,
-                                            st->clear.enable_ds_separate))
-               quad_buffers |= PIPE_CLEAR_DEPTH;
-            else
-               clear_buffers |= PIPE_CLEAR_DEPTH;
-         }
-      }
-      if (mask & BUFFER_BIT_STENCIL) {
-         struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
+   if (mask & BUFFER_BIT_STENCIL) {
+      struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
 
-         if (strb->surface) {
-            if (check_clear_stencil_with_quad(ctx, stencilRb,
-                                              st->clear.enable_ds_separate))
-               quad_buffers |= PIPE_CLEAR_STENCIL;
-            else
-               clear_buffers |= PIPE_CLEAR_STENCIL;
-         }
+      if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) {
+         if (is_scissor_enabled(ctx, stencilRb) ||
+             is_stencil_masked(ctx, stencilRb))
+            quad_buffers |= PIPE_CLEAR_STENCIL;
+         else
+            clear_buffers |= PIPE_CLEAR_STENCIL;
       }
    }
 
-   /*
-    * If we're going to use clear_with_quad() for any reason, use it for
-    * everything possible.
+   /* Always clear depth and stencil together.
+    * This can only happen when the stencil writemask is not a full mask.
+    */
+   if (quad_buffers & PIPE_CLEAR_DEPTHSTENCIL &&
+       clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+      quad_buffers |= clear_buffers & PIPE_CLEAR_DEPTHSTENCIL;
+      clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
+   }
+
+   /* Only use quad-based clearing for the renderbuffers which cannot
+    * use pipe->clear. We want to always use pipe->clear for the other
+    * renderbuffers, because it's likely to be faster.
     */
    if (quad_buffers) {
-      quad_buffers |= clear_buffers;
-      clear_with_quad(ctx,
-                      quad_buffers & PIPE_CLEAR_COLOR,
-                      quad_buffers & PIPE_CLEAR_DEPTH,
-                      quad_buffers & PIPE_CLEAR_STENCIL);
-   } else if (clear_buffers) {
-      /* driver cannot know it can clear everything if the buffer
-       * is a combined depth/stencil buffer but this wasn't actually
-       * required from the visual. Hence fix this up to avoid potential
-       * read-modify-write in the driver.
+      clear_with_quad(ctx, quad_buffers);
+   }
+   if (clear_buffers) {
+      /* We can't translate the clear color to the colorbuffer format,
+       * because different colorbuffers may have different formats.
        */
-      union pipe_color_union clearColor;
-
-      if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) &&
-          ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
-          (depthRb == stencilRb) &&
-          (ctx->DrawBuffer->Visual.depthBits == 0 ||
-           ctx->DrawBuffer->Visual.stencilBits == 0))
-         clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
-
-      if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
-         st_translate_color(ctx->Color.ClearColor.f,
-                           ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
-                           clearColor.f);
-      }
-
-      st->pipe->clear(st->pipe, clear_buffers, &clearColor,
+      st->pipe->clear(st->pipe, clear_buffers,
+                      (union pipe_color_union*)&ctx->Color.ClearColor,
                       ctx->Depth.Clear, ctx->Stencil.Clear);
    }
    if (mask & BUFFER_BIT_ACCUM)