[Mesa-dev] [PATCH] mesa: introduce a clear color union to be used for int/unsigned buffers

Dave Airlie airlied at gmail.com
Tue Sep 13 03:54:45 PDT 2011


From: Dave Airlie <airlied at redhat.com>

This introduces a new gl_clear_color union and moves the current
ClearColorUnclamped to use it, it removes ClearColor completely and
all drivers are modified to expected unclamped floats instead.

also fixes st to use translated color in one place it wasn't.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/mesa/drivers/common/meta.c                |   10 ++--
 src/mesa/drivers/dri/intel/intel_blit.c       |   10 ++--
 src/mesa/drivers/dri/nouveau/nouveau_driver.c |    2 +-
 src/mesa/drivers/dri/nouveau/nouveau_util.h   |   10 +++
 src/mesa/drivers/dri/nouveau/nv20_context.c   |    2 +-
 src/mesa/drivers/dri/r200/r200_state.c        |   11 ++--
 src/mesa/drivers/dri/radeon/radeon_state.c    |   11 ++--
 src/mesa/drivers/windows/gdi/wmesa.c          |    9 ++-
 src/mesa/drivers/x11/xm_dd.c                  |   37 +++++-----
 src/mesa/main/attrib.c                        |    8 +-
 src/mesa/main/blend.c                         |    3 +-
 src/mesa/main/clear.c                         |   94 ++++++++++--------------
 src/mesa/main/dd.h                            |    3 +-
 src/mesa/main/get.c                           |   11 ++-
 src/mesa/main/mtypes.h                        |    9 ++-
 src/mesa/state_tracker/st_cb_clear.c          |   14 ++--
 src/mesa/state_tracker/st_format.c            |    9 +++
 src/mesa/state_tracker/st_format.h            |    3 +
 src/mesa/swrast/s_clear.c                     |   47 +++++++------
 19 files changed, 163 insertions(+), 140 deletions(-)

diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 2ebcd35..f34d88f 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -1569,10 +1569,10 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
 
       /* vertex colors */
       for (i = 0; i < 4; i++) {
-         verts[i].r = ctx->Color.ClearColorUnclamped[0];
-         verts[i].g = ctx->Color.ClearColorUnclamped[1];
-         verts[i].b = ctx->Color.ClearColorUnclamped[2];
-         verts[i].a = ctx->Color.ClearColorUnclamped[3];
+         verts[i].r = ctx->Color.ClearColorUnclamped.f[0];
+         verts[i].g = ctx->Color.ClearColorUnclamped.f[1];
+         verts[i].b = ctx->Color.ClearColorUnclamped.f[2];
+         verts[i].a = ctx->Color.ClearColorUnclamped.f[3];
       }
 
       /* upload new vertex data */
@@ -1679,7 +1679,7 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
 
    _mesa_UseProgramObjectARB(clear->ShaderProg);
    _mesa_Uniform4fvARB(clear->ColorLocation, 1,
-		       ctx->Color.ClearColorUnclamped);
+		       ctx->Color.ClearColorUnclamped.f);
 
    _mesa_BindVertexArray(clear->ArrayObj);
    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index b18dd29..970099b 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -320,12 +320,12 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
 	 clear_val = clear_depth_value;
       } else {
 	 uint8_t clear[4];
-	 GLclampf *color = ctx->Color.ClearColor;
+	 GLfloat *color = ctx->Color.ClearColorUnclamped.f;
 
-	 CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]);
-	 CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]);
-	 CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]);
-	 CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]);
+	 UNCLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]);
+	 UNCLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]);
+	 UNCLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]);
+	 UNCLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]);
 
 	 switch (irb->Base.Format) {
 	 case MESA_FORMAT_ARGB8888:
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
index 8b6aa82..e025389 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
@@ -100,7 +100,7 @@ nouveau_clear(struct gl_context *ctx, GLbitfield buffers)
 
 		if (buf & BUFFER_BITS_COLOR) {
 			mask = pack_rgba_i(s->format, ctx->Color.ColorMask[0]);
-			value = pack_rgba_f(s->format, ctx->Color.ClearColor);
+			value = pack_rgba_clamp_f(s->format, ctx->Color.ClearColorUnclamped.f);
 
 			if (mask)
 				context_drv(ctx)->surface_fill(
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_util.h b/src/mesa/drivers/dri/nouveau/nouveau_util.h
index 6d01934..8cfe26d 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_util.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_util.h
@@ -79,6 +79,16 @@ pack_rgba_f(gl_format f, float c[])
 }
 
 static inline unsigned
+pack_rgba_clamp_f(gl_format f, float c[])
+{
+	return pack_rgba_i(f, (uint8_t []) {
+			   UNCLAMPED_FLOAT_TO_UBYTE(c[RCOMP]),
+			   UNCLAMPED_FLOAT_TO_UBYTE(c[GCOMP]),
+			   UNCLAMPED_FLOAT_TO_UBYTE(c[BCOMP]),
+			   UNCLAMPED_FLOAT_TO_UBYTE(c[ACOMP]) });
+}
+
+static inline unsigned
 pack_zs_f(gl_format f, float z, uint8_t s)
 {
 	return pack_zs_i(f, FLOAT_TO_UINT(z), s);
diff --git a/src/mesa/drivers/dri/nouveau/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_context.c
index 2766851..ea77381 100644
--- a/src/mesa/drivers/dri/nouveau/nv20_context.c
+++ b/src/mesa/drivers/dri/nouveau/nv20_context.c
@@ -59,7 +59,7 @@ nv20_clear(struct gl_context *ctx, GLbitfield buffers)
 			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_A;
 
 		BEGIN_RING(chan, kelvin, NV20_3D_CLEAR_VALUE, 1);
-		OUT_RING(chan, pack_rgba_f(s->format, ctx->Color.ClearColor));
+		OUT_RING(chan, pack_rgba_clamp_f(s->format, ctx->Color.ClearColorUnclamped.f));
 
 		buffers &= ~BUFFER_BITS_COLOR;
 	}
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index 0a1e0b4..b10dd2d 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -1724,7 +1724,8 @@ void r200UpdateViewportOffset( struct gl_context *ctx )
  * Miscellaneous
  */
 
-static void r200ClearColor( struct gl_context *ctx, const GLfloat c[4] )
+static void r200ClearColor( struct gl_context *ctx,
+                            const union gl_clear_color c )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLubyte color[4];
@@ -1733,10 +1734,10 @@ static void r200ClearColor( struct gl_context *ctx, const GLfloat c[4] )
    rrb = radeon_get_colorbuffer(&rmesa->radeon);
    if (!rrb)
      return;
-   CLAMPED_FLOAT_TO_UBYTE(color[0], c[0]);
-   CLAMPED_FLOAT_TO_UBYTE(color[1], c[1]);
-   CLAMPED_FLOAT_TO_UBYTE(color[2], c[2]);
-   CLAMPED_FLOAT_TO_UBYTE(color[3], c[3]);
+   UNCLAMPED_FLOAT_TO_UBYTE(color[0], c.f[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(color[1], c.f[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(color[2], c.f[2]);
+   UNCLAMPED_FLOAT_TO_UBYTE(color[3], c.f[3]);
    rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
                                              color[0], color[1],
                                              color[2], color[3] );
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index a93e618..4943bbe 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -1508,7 +1508,8 @@ void radeonUpdateViewportOffset( struct gl_context *ctx )
  * Miscellaneous
  */
 
-static void radeonClearColor( struct gl_context *ctx, const GLfloat color[4] )
+static void radeonClearColor( struct gl_context *ctx,
+                              const union gl_clear_color color )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
    GLubyte c[4];
@@ -1518,10 +1519,10 @@ static void radeonClearColor( struct gl_context *ctx, const GLfloat color[4] )
    if (!rrb)
      return;
      
-   CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
-   CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
-   CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
-   CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
+   UNCLAMPED_FLOAT_TO_UBYTE(c[0], color.f[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(c[1], color.f[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(c[2], color.f[2]);
+   UNCLAMPED_FLOAT_TO_UBYTE(c[3], color.f[3]);
    rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
 					       c[0], c[1], c[2], c[3] );
 }
diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c
index 35a150d..4d7b0c4 100644
--- a/src/mesa/drivers/windows/gdi/wmesa.c
+++ b/src/mesa/drivers/windows/gdi/wmesa.c
@@ -249,14 +249,15 @@ static void wmesa_flush(struct gl_context *ctx)
 /*
  * Set the color used to clear the color buffer.
  */
-static void clear_color(struct gl_context *ctx, const GLfloat color[4])
+static void clear_color(struct gl_context *ctx,
+                        const union gl_clear_color color)
 {
     WMesaContext pwc = wmesa_context(ctx);
     GLubyte col[3];
 
-    CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
-    CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
-    CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
+    UNCLAMPED_FLOAT_TO_UBYTE(col[0], color.f[0]);
+    UNCLAMPED_FLOAT_TO_UBYTE(col[1], color.f[1]);
+    UNCLAMPED_FLOAT_TO_UBYTE(col[2], color.f[2]);
     pwc->clearColorRef = RGB(col[0], col[1], col[2]);
     DeleteObject(pwc->clearPen);
     DeleteObject(pwc->clearBrush);
diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c
index 81d000b..e315aa2 100644
--- a/src/mesa/drivers/x11/xm_dd.c
+++ b/src/mesa/drivers/x11/xm_dd.c
@@ -104,16 +104,17 @@ finish_or_flush( struct gl_context *ctx )
 
 
 static void
-clear_color( struct gl_context *ctx, const GLfloat color[4] )
+clear_color( struct gl_context *ctx,
+             const union gl_clear_color color )
 {
    if (ctx->DrawBuffer->Name == 0) {
       const XMesaContext xmesa = XMESA_CONTEXT(ctx);
       XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
 
-      CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]);
-      CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]);
-      CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]);
-      CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]);
+      UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color.f[0]);
+      UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color.f[1]);
+      UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color.f[2]);
+      UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color.f[3]);
       xmesa->clearpixel = xmesa_color_to_pixel( ctx,
                                                 xmesa->clearcolor[0],
                                                 xmesa->clearcolor[1],
@@ -770,17 +771,18 @@ enable( struct gl_context *ctx, GLenum pname, GLboolean state )
 
 
 static void
-clear_color_HPCR_ximage( struct gl_context *ctx, const GLfloat color[4] )
+clear_color_HPCR_ximage( struct gl_context *ctx,
+                         const union gl_clear_color color )
 {
    int i;
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
 
-   CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]);
-   CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]);
-   CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]);
-   CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]);
+   UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color.f[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color.f[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color.f[2]);
+   UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color.f[3]);
 
-   if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) {
+   if (color.f[0] == 0.0 && color.f[1] == 0.0 && color.f[2] == 0.0) {
       /* black is black */
       memset( xmesa->xm_visual->hpcr_clear_ximage_pattern, 0x0 ,
               sizeof(xmesa->xm_visual->hpcr_clear_ximage_pattern));
@@ -804,17 +806,18 @@ clear_color_HPCR_ximage( struct gl_context *ctx, const GLfloat color[4] )
 
 
 static void
-clear_color_HPCR_pixmap( struct gl_context *ctx, const GLfloat color[4] )
+clear_color_HPCR_pixmap( struct gl_context *ctx,
+                         const union gl_clear_color color )
 {
    int i;
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
 
-   CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]);
-   CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]);
-   CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]);
-   CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]);
+   UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color.f[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color.f[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color.f[2]);
+   UNCLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color.f[3]);
 
-   if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) {
+   if (color.f[0] == 0.0 && color.f[1] == 0.0 && color.f[2] == 0.0) {
       /* black is black */
       for (i=0; i<16; i++) {
          XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 0, 0);
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 5731004..0a7f7de 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -884,10 +884,10 @@ _mesa_PopAttrib(void)
 
                color = (const struct gl_colorbuffer_attrib *) attr->data;
                _mesa_ClearIndex((GLfloat) color->ClearIndex);
-               _mesa_ClearColor(color->ClearColorUnclamped[0],
-                                color->ClearColorUnclamped[1],
-                                color->ClearColorUnclamped[2],
-                                color->ClearColorUnclamped[3]);
+               _mesa_ClearColor(color->ClearColorUnclamped.f[0],
+                                color->ClearColorUnclamped.f[1],
+                                color->ClearColorUnclamped.f[2],
+                                color->ClearColorUnclamped.f[3]);
                _mesa_IndexMask(color->IndexMask);
                if (!ctx->Extensions.EXT_draw_buffers2) {
                   _mesa_ColorMask((GLboolean) (color->ColorMask[0][0] != 0),
diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
index 1856f00..5e1fbb0 100644
--- a/src/mesa/main/blend.c
+++ b/src/mesa/main/blend.c
@@ -795,8 +795,7 @@ void _mesa_init_color( struct gl_context * ctx )
    ctx->Color.IndexMask = ~0u;
    memset(ctx->Color.ColorMask, 0xff, sizeof(ctx->Color.ColorMask));
    ctx->Color.ClearIndex = 0;
-   ASSIGN_4V( ctx->Color.ClearColor, 0, 0, 0, 0 );
-   ASSIGN_4V( ctx->Color.ClearColorUnclamped, 0, 0, 0, 0 );
+   ASSIGN_4V( ctx->Color.ClearColorUnclamped.f, 0, 0, 0, 0 );
    ctx->Color.AlphaEnabled = GL_FALSE;
    ctx->Color.AlphaFunc = GL_ALWAYS;
    ctx->Color.AlphaRef = 0;
diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c
index fa95e45..75e71eb 100644
--- a/src/mesa/main/clear.c
+++ b/src/mesa/main/clear.c
@@ -83,23 +83,18 @@ _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
    tmp[2] = blue;
    tmp[3] = alpha;
 
-   if (TEST_EQ_4V(tmp, ctx->Color.ClearColorUnclamped))
+   if (TEST_EQ_4V(tmp, ctx->Color.ClearColorUnclamped.f))
       return; /* no change */
 
    FLUSH_VERTICES(ctx, _NEW_COLOR);
-   COPY_4V(ctx->Color.ClearColorUnclamped, tmp);
-
-   ctx->Color.ClearColor[0] = CLAMP(tmp[0], 0.0F, 1.0F);
-   ctx->Color.ClearColor[1] = CLAMP(tmp[1], 0.0F, 1.0F);
-   ctx->Color.ClearColor[2] = CLAMP(tmp[2], 0.0F, 1.0F);
-   ctx->Color.ClearColor[3] = CLAMP(tmp[3], 0.0F, 1.0F);
+   COPY_4V(ctx->Color.ClearColorUnclamped.f, tmp);
 
    if (ctx->Driver.ClearColor) {
       /* it's OK to call glClearColor in CI mode but it should be a NOP */
       /* we pass the clamped color, since all drivers that need this don't
        * support GL_ARB_color_buffer_float
        */
-      (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor);
+      (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColorUnclamped);
    }
 }
 
@@ -110,27 +105,24 @@ _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
 void GLAPIENTRY
 _mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a)
 {
-   GLfloat tmp[4];
+   GLint tmp[4];
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   tmp[0] = (GLfloat) r;
-   tmp[1] = (GLfloat) g;
-   tmp[2] = (GLfloat) b;
-   tmp[3] = (GLfloat) a;
+   tmp[0] = r;
+   tmp[1] = g;
+   tmp[2] = b;
+   tmp[3] = a;
 
-   if (TEST_EQ_4V(tmp, ctx->Color.ClearColor))
+   if (TEST_EQ_4V(tmp, ctx->Color.ClearColorUnclamped.i))
       return; /* no change */
 
    FLUSH_VERTICES(ctx, _NEW_COLOR);
+   COPY_4V(ctx->Color.ClearColorUnclamped.i, tmp);
 
-   /* XXX we should eventually have a float/int/uint union for
-    * the ctx->Color.ClearColor state.
-    */
-   COPY_4V(ctx->Color.ClearColor, tmp);
-
+   /* these should be NOP calls for drivers supporting EXT_texture_integer */
    if (ctx->Driver.ClearColor) {
-      ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
+      ctx->Driver.ClearColor(ctx, ctx->Color.ClearColorUnclamped);
    }
 }
 
@@ -141,27 +133,24 @@ _mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a)
 void GLAPIENTRY
 _mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a)
 {
-   GLfloat tmp[4];
+   GLuint tmp[4];
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   tmp[0] = (GLfloat) r;
-   tmp[1] = (GLfloat) g;
-   tmp[2] = (GLfloat) b;
-   tmp[3] = (GLfloat) a;
+   tmp[0] = r;
+   tmp[1] = g;
+   tmp[2] = b;
+   tmp[3] = a;
 
-   if (TEST_EQ_4V(tmp, ctx->Color.ClearColor))
+   if (TEST_EQ_4V(tmp, ctx->Color.ClearColorUnclamped.ui))
       return; /* no change */
 
    FLUSH_VERTICES(ctx, _NEW_COLOR);
+   COPY_4V(ctx->Color.ClearColorUnclamped.ui, tmp);
 
-   /* XXX we should eventually have a float/int/uint union for
-    * the ctx->Color.ClearColor state.
-    */
-   COPY_4V(ctx->Color.ClearColor, tmp);
-
+   /* these should be NOP calls for drivers supporting EXT_texture_integer */
    if (ctx->Driver.ClearColor) {
-      ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
+      ctx->Driver.ClearColor(ctx, ctx->Color.ClearColorUnclamped);
    }
 }
 
@@ -364,21 +353,18 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
             return;
          }
          else if (mask) {
-            /* XXX note: we're putting the integer clear values into the
-             * floating point state var.  This will not always work.  We'll
-             * need a new ctx->Driver.ClearBuffer() hook....
-             */
-            GLclampf clearSave[4];
+            union gl_clear_color clearSave;
+
             /* save color */
-            COPY_4V(clearSave, ctx->Color.ClearColor);
+            clearSave = ctx->Color.ClearColorUnclamped;
             /* set color */
-            COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf);
+            COPY_4V(ctx->Color.ClearColorUnclamped.i, value);
             if (ctx->Driver.ClearColor)
-               ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
+               ctx->Driver.ClearColor(ctx, ctx->Color.ClearColorUnclamped);
             /* clear buffer(s) */
             ctx->Driver.Clear(ctx, mask);
             /* restore color */
-            COPY_4V(ctx->Color.ClearColor, clearSave);
+            ctx->Color.ClearColorUnclamped = clearSave;
             if (ctx->Driver.ClearColor)
                ctx->Driver.ClearColor(ctx, clearSave);
          }
@@ -418,21 +404,18 @@ _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
             return;
          }
          else if (mask) {
-            /* XXX note: we're putting the uint clear values into the
-             * floating point state var.  This will not always work.  We'll
-             * need a new ctx->Driver.ClearBuffer() hook....
-             */
-            GLclampf clearSave[4];
+            union gl_clear_color clearSave;
+
             /* save color */
-            COPY_4V(clearSave, ctx->Color.ClearColor);
+            clearSave = ctx->Color.ClearColorUnclamped;
             /* set color */
-            COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf);
+            COPY_4V(ctx->Color.ClearColorUnclamped.ui, value);
             if (ctx->Driver.ClearColor)
-               ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
+               ctx->Driver.ClearColor(ctx, ctx->Color.ClearColorUnclamped);
             /* clear buffer(s) */
             ctx->Driver.Clear(ctx, mask);
             /* restore color */
-            COPY_4V(ctx->Color.ClearColor, clearSave);
+            ctx->Color.ClearColorUnclamped = clearSave;
             if (ctx->Driver.ClearColor)
                ctx->Driver.ClearColor(ctx, clearSave);
          }
@@ -495,17 +478,18 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
             return;
          }
          else if (mask) {
-            GLclampf clearSave[4];
+            union gl_clear_color clearSave;
+
             /* save color */
-            COPY_4V(clearSave, ctx->Color.ClearColor);
+            clearSave = ctx->Color.ClearColorUnclamped;
             /* set color */
-            COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf);
+            COPY_4V_CAST(ctx->Color.ClearColorUnclamped.f, value, GLclampf);
             if (ctx->Driver.ClearColor)
-               ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
+               ctx->Driver.ClearColor(ctx, ctx->Color.ClearColorUnclamped);
             /* clear buffer(s) */
             ctx->Driver.Clear(ctx, mask);
             /* restore color */
-            COPY_4V(ctx->Color.ClearColor, clearSave);
+            ctx->Color.ClearColorUnclamped = clearSave;
             if (ctx->Driver.ClearColor)
                ctx->Driver.ClearColor(ctx, clearSave);
          }
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index b77e4f0..9d49386 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -589,7 +589,8 @@ struct dd_function_table {
                               GLenum sfactorRGB, GLenum dfactorRGB,
                               GLenum sfactorA, GLenum dfactorA);
    /** Specify clear values for the color buffers */
-   void (*ClearColor)(struct gl_context *ctx, const GLfloat color[4]);
+   void (*ClearColor)(struct gl_context *ctx,
+                      const union gl_clear_color color);
    /** Specify the clear value for the depth buffer */
    void (*ClearDepth)(struct gl_context *ctx, GLclampd d);
    /** Specify the clear value for the stencil buffer */
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 069254b..29c3ecd 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -1673,10 +1673,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
          COPY_4FV(v->value_float_4, ctx->Fog.ColorUnclamped);
       break;
    case GL_COLOR_CLEAR_VALUE:
-      if(ctx->Color._ClampFragmentColor)
-         COPY_4FV(v->value_float_4, ctx->Color.ClearColor);
-      else
-         COPY_4FV(v->value_float_4, ctx->Color.ClearColorUnclamped);
+      if(ctx->Color._ClampFragmentColor) {
+         v->value_float_4[0] = CLAMP(ctx->Color.ClearColorUnclamped.f[0], 0.0F, 1.0F);
+         v->value_float_4[1] = CLAMP(ctx->Color.ClearColorUnclamped.f[1], 0.0F, 1.0F);
+         v->value_float_4[2] = CLAMP(ctx->Color.ClearColorUnclamped.f[2], 0.0F, 1.0F);
+         v->value_float_4[3] = CLAMP(ctx->Color.ClearColorUnclamped.f[3], 0.0F, 1.0F);
+      } else
+         COPY_4FV(v->value_float_4, ctx->Color.ClearColorUnclamped.f);
       break;
    case GL_BLEND_COLOR_EXT:
       if(ctx->Color._ClampFragmentColor)
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index ae500b4..5aea041 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -719,6 +719,11 @@ struct gl_accum_attrib
    GLfloat ClearColor[4];	/**< Accumulation buffer clear color */
 };
 
+union gl_clear_color {
+   GLfloat f[4];
+   GLint i[4];
+   GLuint ui[4];
+};
 
 /**
  * Color buffer attribute group (GL_COLOR_BUFFER_BIT).
@@ -726,9 +731,7 @@ struct gl_accum_attrib
 struct gl_colorbuffer_attrib
 {
    GLuint ClearIndex;			/**< Index to use for glClear */
-   GLfloat ClearColorUnclamped[4];              /**< Color to use for glClear*/
-   GLclampf ClearColor[4];               /**< Color to use for glClear */
-
+   union gl_clear_color ClearColorUnclamped;  /**< Color to use for glClear*/
    GLuint IndexMask;			/**< Color index write mask */
    GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */
 
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 117000b..f32286c 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -323,9 +323,9 @@ clear_with_quad(struct gl_context *ctx,
    set_vertex_shader(st);
 
    if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
-      st_translate_color(ctx->Color.ClearColorUnclamped,
-                         ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
-                         clearColor);
+      st_translate_clear_color(ctx->Color.ClearColorUnclamped,
+                               ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
+                               clearColor);
    }
 
    /* draw quad matching scissor rect */
@@ -582,12 +582,12 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
          clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
 
       if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
-         st_translate_color(ctx->Color.ClearColor,
-                            ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
-                            clearColor);
+         st_translate_clear_color(ctx->Color.ClearColorUnclamped,
+                                  ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
+                                  clearColor);
       }
 
-      st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColorUnclamped,
+      st->pipe->clear(st->pipe, clear_buffers, clearColor,
                       ctx->Depth.Clear, ctx->Stencil.Clear);
    }
    if (mask & BUFFER_BIT_ACCUM)
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index bd4f086..b2c1d6c 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -1486,3 +1486,12 @@ st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
       COPY_4V(colorOut, colorIn);
    }
 }
+
+void
+st_translate_clear_color(const union gl_clear_color colorIn,
+                         GLenum baseFormat,
+                         GLfloat colorOut[4])
+{
+   st_translate_color(colorIn.f, baseFormat, colorOut);
+}
+
diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h
index 1c1f596..6c04529 100644
--- a/src/mesa/state_tracker/st_format.h
+++ b/src/mesa/state_tracker/st_format.h
@@ -83,5 +83,8 @@ extern void
 st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
                    GLfloat colorOut[4]);
 
+void
+st_translate_clear_color(const union gl_clear_color colorIn, 
+                         GLenum baseFormat, GLfloat colorOut[4]);
 
 #endif /* ST_FORMAT_H */
diff --git a/src/mesa/swrast/s_clear.c b/src/mesa/swrast/s_clear.c
index 9e9b531..6072e6e 100644
--- a/src/mesa/swrast/s_clear.c
+++ b/src/mesa/swrast/s_clear.c
@@ -60,20 +60,20 @@ clear_rgba_buffer_with_masking(struct gl_context *ctx, struct gl_renderbuffer *r
    span.array->ChanType = rb->DataType;
    if (span.array->ChanType == GL_UNSIGNED_BYTE) {
       GLubyte clearColor[4];
-      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[RCOMP], ctx->Color.ClearColor[0]);
-      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[GCOMP], ctx->Color.ClearColor[1]);
-      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[BCOMP], ctx->Color.ClearColor[2]);
-      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[ACOMP], ctx->Color.ClearColor[3]);
+      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[RCOMP], ctx->Color.ClearColorUnclamped.f[0]);
+      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[GCOMP], ctx->Color.ClearColorUnclamped.f[1]);
+      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[BCOMP], ctx->Color.ClearColorUnclamped.f[2]);
+      UNCLAMPED_FLOAT_TO_UBYTE(clearColor[ACOMP], ctx->Color.ClearColorUnclamped.f[3]);
       for (i = 0; i < width; i++) {
          COPY_4UBV(span.array->rgba[i], clearColor);
       }
    }
    else if (span.array->ChanType == GL_UNSIGNED_SHORT) {
       GLushort clearColor[4];
-      UNCLAMPED_FLOAT_TO_USHORT(clearColor[RCOMP], ctx->Color.ClearColor[0]);
-      UNCLAMPED_FLOAT_TO_USHORT(clearColor[GCOMP], ctx->Color.ClearColor[1]);
-      UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor[2]);
-      UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor[3]);
+      UNCLAMPED_FLOAT_TO_USHORT(clearColor[RCOMP], ctx->Color.ClearColorUnclamped.f[0]);
+      UNCLAMPED_FLOAT_TO_USHORT(clearColor[GCOMP], ctx->Color.ClearColorUnclamped.f[1]);
+      UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColorUnclamped.f[2]);
+      UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColorUnclamped.f[3]);
       for (i = 0; i < width; i++) {
          COPY_4V_CAST(span.array->rgba[i], clearColor, GLchan);
       }
@@ -81,10 +81,10 @@ clear_rgba_buffer_with_masking(struct gl_context *ctx, struct gl_renderbuffer *r
    else {
       ASSERT(span.array->ChanType == GL_FLOAT);
       for (i = 0; i < width; i++) {
-         CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColor[0]);
-         CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColor[1]);
-         CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColor[2]);
-         CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColor[3]);
+         UNCLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColorUnclamped.f[0]);
+         UNCLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColorUnclamped.f[1]);
+         UNCLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColorUnclamped.f[2]);
+         UNCLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColorUnclamped.f[3]);
       }
    }
 
@@ -115,6 +115,7 @@ clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint buf
    GLubyte clear8[4];
    GLushort clear16[4];
    GLvoid *clearVal;
+   GLfloat clearFloat[4];
    GLint i;
 
    ASSERT(ctx->Color.ColorMask[buf][0] &&
@@ -126,21 +127,25 @@ clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint buf
 
    switch (rb->DataType) {
       case GL_UNSIGNED_BYTE:
-         UNCLAMPED_FLOAT_TO_UBYTE(clear8[0], ctx->Color.ClearColor[0]);
-         UNCLAMPED_FLOAT_TO_UBYTE(clear8[1], ctx->Color.ClearColor[1]);
-         UNCLAMPED_FLOAT_TO_UBYTE(clear8[2], ctx->Color.ClearColor[2]);
-         UNCLAMPED_FLOAT_TO_UBYTE(clear8[3], ctx->Color.ClearColor[3]);
+         UNCLAMPED_FLOAT_TO_UBYTE(clear8[0], ctx->Color.ClearColorUnclamped.f[0]);
+         UNCLAMPED_FLOAT_TO_UBYTE(clear8[1], ctx->Color.ClearColorUnclamped.f[1]);
+         UNCLAMPED_FLOAT_TO_UBYTE(clear8[2], ctx->Color.ClearColorUnclamped.f[2]);
+         UNCLAMPED_FLOAT_TO_UBYTE(clear8[3], ctx->Color.ClearColorUnclamped.f[3]);
          clearVal = clear8;
          break;
       case GL_UNSIGNED_SHORT:
-         UNCLAMPED_FLOAT_TO_USHORT(clear16[0], ctx->Color.ClearColor[0]);
-         UNCLAMPED_FLOAT_TO_USHORT(clear16[1], ctx->Color.ClearColor[1]);
-         UNCLAMPED_FLOAT_TO_USHORT(clear16[2], ctx->Color.ClearColor[2]);
-         UNCLAMPED_FLOAT_TO_USHORT(clear16[3], ctx->Color.ClearColor[3]);
+         UNCLAMPED_FLOAT_TO_USHORT(clear16[0], ctx->Color.ClearColorUnclamped.f[0]);
+         UNCLAMPED_FLOAT_TO_USHORT(clear16[1], ctx->Color.ClearColorUnclamped.f[1]);
+         UNCLAMPED_FLOAT_TO_USHORT(clear16[2], ctx->Color.ClearColorUnclamped.f[2]);
+         UNCLAMPED_FLOAT_TO_USHORT(clear16[3], ctx->Color.ClearColorUnclamped.f[3]);
          clearVal = clear16;
          break;
       case GL_FLOAT:
-         clearVal = ctx->Color.ClearColor;
+         clearFloat[0] = CLAMP(ctx->Color.ClearColorUnclamped.f[0], 0.0F, 1.0F);
+         clearFloat[1] = CLAMP(ctx->Color.ClearColorUnclamped.f[1], 0.0F, 1.0F);
+         clearFloat[2] = CLAMP(ctx->Color.ClearColorUnclamped.f[2], 0.0F, 1.0F);
+         clearFloat[3] = CLAMP(ctx->Color.ClearColorUnclamped.f[3], 0.0F, 1.0F);
+         clearVal = clearFloat;
          break;
       default:
          _mesa_problem(ctx, "Bad rb DataType in clear_color_buffer");
-- 
1.7.6



More information about the mesa-dev mailing list