st/mesa: need to translate clear color according to surface's base format
authorBrian Paul <brianp@vmware.com>
Mon, 21 Feb 2011 23:54:23 +0000 (16:54 -0700)
committerBrian Paul <brianp@vmware.com>
Mon, 21 Feb 2011 23:58:42 +0000 (16:58 -0700)
When clearing a GL_LUMINANCE_ALPHA buffer, for example, we need to convert
the clear color (R,G,B,A) to (R,R,R,A).  We were doing this for texture border
colors but not renderbuffers.  Move the translation function to st_format.c
and share it.

This fixes the piglit fbo-clear-formats test.

NOTE: This is a candidate for the 7.9 and 7.10 branches.

src/mesa/state_tracker/st_atom_sampler.c
src/mesa/state_tracker/st_cb_clear.c
src/mesa/state_tracker/st_format.c
src/mesa/state_tracker/st_format.h

index b67068df373d7a358c701a08b7714efceda81404..474cbd5897d1861c8f4584d3cf7be7d0d8f52bac 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "st_context.h"
 #include "st_cb_texture.h"
+#include "st_format.h"
 #include "st_atom.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
@@ -117,49 +118,6 @@ gl_filter_to_img_filter(GLenum filter)
 }
 
 
-static void
-xlate_border_color(const GLfloat *colorIn, GLenum baseFormat, GLfloat *colorOut)
-{
-   switch (baseFormat) {
-   case GL_RED:
-      colorOut[0] = colorIn[0];
-      colorOut[1] = 0.0F;
-      colorOut[2] = 0.0F;
-      colorOut[3] = 1.0F;
-      break;
-   case GL_RG:
-      colorOut[0] = colorIn[0];
-      colorOut[1] = colorIn[1];
-      colorOut[2] = 0.0F;
-      colorOut[3] = 1.0F;
-      break;
-   case GL_RGB:
-      colorOut[0] = colorIn[0];
-      colorOut[1] = colorIn[1];
-      colorOut[2] = colorIn[2];
-      colorOut[3] = 1.0F;
-      break;
-   case GL_ALPHA:
-      colorOut[0] = colorOut[1] = colorOut[2] = 0.0;
-      colorOut[3] = colorIn[3];
-      break;
-   case GL_LUMINANCE:
-      colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
-      colorOut[3] = 1.0;
-      break;
-   case GL_LUMINANCE_ALPHA:
-      colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
-      colorOut[3] = colorIn[3];
-      break;
-   case GL_INTENSITY:
-      colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0];
-      break;
-   default:
-      COPY_4V(colorOut, colorIn);
-   }
-}
-
-
 static void 
 update_samplers(struct st_context *st)
 {
@@ -223,7 +181,7 @@ update_samplers(struct st_context *st)
             assert(sampler->min_lod <= sampler->max_lod);
          }
 
-         xlate_border_color(texobj->BorderColor.f,
+         st_translate_color(texobj->BorderColor.f,
                             teximg ? teximg->_BaseFormat : GL_RGBA,
                             sampler->border_color);
 
index d2e0cd73c760c18c4fa7b3e71db443a3c138a202..d81e554b294f873c4002a2981ad2a89210c03303 100644 (file)
@@ -42,6 +42,7 @@
 #include "st_cb_accum.h"
 #include "st_cb_clear.h"
 #include "st_cb_fbo.h"
+#include "st_format.h"
 #include "st_program.h"
 
 #include "pipe/p_context.h"
@@ -204,6 +205,7 @@ 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;
+   float clearColor[4];
 
    /*
    printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, 
@@ -298,9 +300,12 @@ clear_with_quad(struct gl_context *ctx,
    cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
    cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
 
-   /* draw quad matching scissor rect (XXX verify coord round-off) */
-   draw_quad(st, x0, y0, x1, y1,
-             (GLfloat) ctx->Depth.Clear, ctx->Color.ClearColor);
+   st_translate_color(ctx->Color.ClearColor,
+                      ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
+                      clearColor);
+
+   /* draw quad matching scissor rect */
+   draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, clearColor);
 
    /* Restore pipe state */
    cso_restore_blend(st->cso_context);
@@ -541,12 +546,19 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
        * required from the visual. Hence fix this up to avoid potential
        * read-modify-write in the driver.
        */
+      float clearColor[4];
+
       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;
+
+      st_translate_color(ctx->Color.ClearColor,
+                         ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
+                         clearColor);
+
       st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColor,
                       ctx->Depth.Clear, ctx->Stencil.Clear);
    }
index 3f9c322d9a1120d93e65bcca107fd4e8f3d29eb1..577ee6189bdc819e1bf5083f61bdea71a834f1ff 100644 (file)
@@ -1095,3 +1095,55 @@ st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2)
 
    return GL_FALSE;
 }
+
+
+
+/**
+ * This is used for translating texture border color and the clear
+ * color.  For example, the clear color is interpreted according to
+ * the renderbuffer's base format.  For example, if clearing a
+ * GL_LUMINANCE buffer, ClearColor[0] = luminance and ClearColor[1] =
+ * alpha.  Similarly for texture border colors.
+ */
+void
+st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
+                   GLfloat colorOut[4])
+{
+   switch (baseFormat) {
+   case GL_RED:
+      colorOut[0] = colorIn[0];
+      colorOut[1] = 0.0F;
+      colorOut[2] = 0.0F;
+      colorOut[3] = 1.0F;
+      break;
+   case GL_RG:
+      colorOut[0] = colorIn[0];
+      colorOut[1] = colorIn[1];
+      colorOut[2] = 0.0F;
+      colorOut[3] = 1.0F;
+      break;
+   case GL_RGB:
+      colorOut[0] = colorIn[0];
+      colorOut[1] = colorIn[1];
+      colorOut[2] = colorIn[2];
+      colorOut[3] = 1.0F;
+      break;
+   case GL_ALPHA:
+      colorOut[0] = colorOut[1] = colorOut[2] = 0.0;
+      colorOut[3] = colorIn[3];
+      break;
+   case GL_LUMINANCE:
+      colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
+      colorOut[3] = 1.0;
+      break;
+   case GL_LUMINANCE_ALPHA:
+      colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
+      colorOut[3] = colorIn[3];
+      break;
+   case GL_INTENSITY:
+      colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0];
+      break;
+   default:
+      COPY_4V(colorOut, colorIn);
+   }
+}
index fe195c1069b1d04d688bb8a8e60db3a6f1eeac00..0fb570f6ee495299777c5df4413f6485becb11e6 100644 (file)
@@ -77,4 +77,10 @@ st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type);
 extern GLboolean
 st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2);
 
+
+extern void
+st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
+                   GLfloat colorOut[4]);
+
+
 #endif /* ST_FORMAT_H */