[Mesa-dev] [PATCH] st/xorg: add some support for non 32-bit color solid fills

Marcin Slusarz marcin.slusarz at gmail.com
Mon May 16 15:12:59 PDT 2011


On Mon, May 16, 2011 at 10:51:58PM +0200, Roland Scheidegger wrote:
> Hmm not sure about the 8-bit case. Is that really mono and ok if we use
> red channel? And I guess it doesn't make a difference if you'd use 1.0
> as color[3] instead of 0 (just seems that would be more correct)?

Something is definitely wrong in a8 handling and I'm not sure yet what.
With this patch applied, a8 fill test pass, but blend don't.
I'll figure this out, but not now...

> Also, you're passing in bpp to xorg_pixel_to_float4 but don't actually
> use it.

Yes, that comes from previous version ot the patch which used bpp.
I'm attaching fixed version.

> Otherwise, doesn't really look hacky to me - unless we could get other
> channel ordering or something similar...

It makes assumptions about how color components are ordered and what are
their widths - e.g. it can't distinguish r5g6b5 from a1r5g5b5.

---
From: Marcin Slusarz <marcin.slusarz at gmail.com>
Subject: [PATCH] st/xorg: add some support for non 32-bit color solid fills

It's a hack, but it allows rendercheck to pass all fill and most blend tests.
(without it all blend tests fail)
---
 src/gallium/state_trackers/xorg/xorg_composite.c |   69 ++++++++++++++-------
 src/gallium/state_trackers/xorg/xorg_composite.h |    5 +-
 src/gallium/state_trackers/xorg/xorg_exa.c       |   15 +++++-
 3 files changed, 63 insertions(+), 26 deletions(-)

diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index f696b72..13acd1c 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -51,19 +51,52 @@ static const struct xorg_composite_blend xorg_blends[] = {
 };
 
 
-static INLINE void
-pixel_to_float4(Pixel pixel, float *color)
+boolean xorg_pixel_to_float4(Pixel pixel, unsigned char depth, float *color)
 {
    CARD32	    r, g, b, a;
 
-   a = (pixel >> 24) & 0xff;
-   r = (pixel >> 16) & 0xff;
-   g = (pixel >>  8) & 0xff;
-   b = (pixel >>  0) & 0xff;
-   color[0] = ((float)r) / 255.;
-   color[1] = ((float)g) / 255.;
-   color[2] = ((float)b) / 255.;
-   color[3] = ((float)a) / 255.;
+   if (depth == 32) {
+      a = (pixel >> 24) & 0xff;
+      r = (pixel >> 16) & 0xff;
+      g = (pixel >>  8) & 0xff;
+      b = (pixel >>  0) & 0xff;
+      color[0] = ((float)r) / 255.;
+      color[1] = ((float)g) / 255.;
+      color[2] = ((float)b) / 255.;
+      color[3] = ((float)a) / 255.;
+   } else if (depth == 24) {
+      r = (pixel >> 16) & 0xff;
+      g = (pixel >>  8) & 0xff;
+      b = (pixel >>  0) & 0xff;
+      color[0] = ((float)r) / 255.;
+      color[1] = ((float)g) / 255.;
+      color[2] = ((float)b) / 255.;
+      color[3] = 0;
+   } else if (depth == 8) {
+      r = pixel & 0xff;
+      color[0] = ((float)r) / 255.;
+      color[1] = 0;
+      color[2] = 0;
+      color[3] = 0;
+   } else if (depth == 16) {
+      r = (pixel >> 11) & 0x1f;
+      g = (pixel >>  5) & 0x3f;
+      b = (pixel >>  0) & 0x1f;
+      color[0] = ((float)r) / 31.;
+      color[1] = ((float)g) / 63.;
+      color[2] = ((float)b) / 31.;
+      color[3] = 0;
+   } else if (depth == 15) {
+      r = (pixel >> 10) & 0x1f;
+      g = (pixel >>  5) & 0x1f;
+      b = (pixel >>  0) & 0x1f;
+      color[0] = ((float)r) / 31.;
+      color[1] = ((float)g) / 31.;
+      color[2] = ((float)b) / 31.;
+      color[3] = 0;
+   } else
+      return FALSE;
+   return TRUE;
 }
 
 static boolean
@@ -310,8 +343,8 @@ bind_shaders(struct exa_context *exa, int op,
             fs_traits |= FS_SOLID_FILL;
             vs_traits |= VS_SOLID_FILL;
             debug_assert(pSrcPicture->format == PICT_a8r8g8b8);
-            pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
-                            exa->solid_color);
+            xorg_pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
+                            32, exa->solid_color);
             exa->has_solid_color = TRUE;
          } else {
             debug_assert("!gradients not supported");
@@ -526,24 +559,14 @@ void xorg_composite(struct exa_context *exa,
 }
 
 boolean xorg_solid_bind_state(struct exa_context *exa,
-                              struct exa_pixmap_priv *pixmap,
-                              Pixel fg)
+                              struct exa_pixmap_priv *pixmap)
 {
    struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pixmap);
    unsigned vs_traits, fs_traits;
    struct xorg_shader shader;
 
-   pixel_to_float4(fg, exa->solid_color);
    exa->has_solid_color = TRUE;
 
-#if 0
-   debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
-                (fg >> 24) & 0xff, (fg >> 16) & 0xff,
-                (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
-                exa->solid_color[0], exa->solid_color[1],
-                exa->solid_color[2], exa->solid_color[3]);
-#endif
-
    vs_traits = VS_SOLID_FILL;
    fs_traits = FS_SOLID_FILL;
 
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.h b/src/gallium/state_trackers/xorg/xorg_composite.h
index ec71ebf..bff0a3b 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.h
+++ b/src/gallium/state_trackers/xorg/xorg_composite.h
@@ -22,9 +22,10 @@ void xorg_composite(struct exa_context *exa,
                     int srcX, int srcY, int maskX, int maskY,
                     int dstX, int dstY, int width, int height);
 
+boolean xorg_pixel_to_float4(Pixel pixel, unsigned char depth, float *color);
+
 boolean xorg_solid_bind_state(struct exa_context *exa,
-                              struct exa_pixmap_priv *pixmap,
-                              Pixel fg);
+                              struct exa_pixmap_priv *pixmap);
 void xorg_solid(struct exa_context *exa,
                 struct exa_pixmap_priv *pixmap,
                 int x0, int y0, int x1, int y1);
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index b072f53..0048061 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -347,6 +347,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
     modesettingPtr ms = modesettingPTR(pScrn);
     struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
     struct exa_context *exa = ms->exa;
+    unsigned char depth;
 
     exa_debug_printf("ExaPrepareSolid(0x%x)\n", fg);
 
@@ -371,7 +372,19 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
 	XORG_FALLBACK("format %s", util_format_name(priv->tex->format));
     }
 
-    return xorg_solid_bind_state(exa, priv, fg);
+    depth = pPixmap->drawable.depth;
+    if (!xorg_pixel_to_float4(fg, depth, exa->solid_color))
+	XORG_FALLBACK("unsupported depth %d", depth);
+
+#if 0
+   debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
+                (fg >> 24) & 0xff, (fg >> 16) & 0xff,
+                (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
+                exa->solid_color[0], exa->solid_color[1],
+                exa->solid_color[2], exa->solid_color[3]);
+#endif
+
+    return xorg_solid_bind_state(exa, priv);
 }
 
 static void
-- 
1.7.4.1




More information about the mesa-dev mailing list