[Mesa-dev] [PATCH] st/xa: Fixups for PIPE_FORMAT_R8_UNORM A8 usage

Thomas Hellstrom thellstrom at vmware.com
Thu Sep 17 05:14:04 PDT 2015


Check for PIPE_FORMAT_R8_UNORM when setting up the copy shader.
Also re-enable the dest alpha blending with A8 destination that
actually turned out to be correct.

Verified using rendercheck that the composite operators
overreverse, in, out, atop, atopreverse and xor seem to work fine
with a8 destiation.

Reported-by: Jose Fonseca <jfonseca at vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
---
 src/gallium/state_trackers/xa/xa_composite.c | 34 ++++++++++++++++++++--------
 src/gallium/state_trackers/xa/xa_renderer.c  |  6 +++--
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c
index e81eeba..bcb27ea 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -78,6 +78,27 @@ static const struct xa_composite_blend xa_blends[] = {
       0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE},
 };
 
+/*
+ * The alpha value stored in a L8 texture is read by the
+ * hardware as color, and R8 is read as red. The source alpha value
+ * at the end of the fragment shader is stored in all color channels,
+ * so the correct approach is to blend using DST_COLOR instead of
+ * DST_ALPHA and then output any color channel (L8) or the red channel (R8).
+ */
+static unsigned
+xa_convert_blend_for_luminance(unsigned factor)
+{
+    switch(factor) {
+    case PIPE_BLENDFACTOR_DST_ALPHA:
+	return PIPE_BLENDFACTOR_DST_COLOR;
+    case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+	return PIPE_BLENDFACTOR_INV_DST_COLOR;
+    default:
+	break;
+    }
+    return factor;
+}
+
 static boolean
 blend_for_op(struct xa_composite_blend *blend,
 	     enum xa_composite_op op,
@@ -111,16 +132,11 @@ blend_for_op(struct xa_composite_blend *blend,
     if (!dst_pic->srf)
 	return supported;
 
-    /*
-     * None of the hardware formats we might use for dst A8 are
-     * suitable for dst_alpha blending, since they present the
-     * alpha channel either in all color channels (L8_UNORM) or
-     * in the red channel only (R8_UNORM)
-     */
     if ((dst_pic->srf->tex->format == PIPE_FORMAT_L8_UNORM ||
-         dst_pic->srf->tex->format == PIPE_FORMAT_R8_UNORM) &&
-        blend->alpha_dst)
-        return FALSE;
+         dst_pic->srf->tex->format == PIPE_FORMAT_R8_UNORM)) {
+        blend->rgb_src = xa_convert_blend_for_luminance(blend->rgb_src);
+        blend->rgb_dst = xa_convert_blend_for_luminance(blend->rgb_dst);
+    }
 
     /*
      * If there's no dst alpha channel, adjust the blend op so that we'll treat
diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c
index fda07e5..006ccf6 100644
--- a/src/gallium/state_trackers/xa/xa_renderer.c
+++ b/src/gallium/state_trackers/xa/xa_renderer.c
@@ -465,9 +465,11 @@ renderer_copy_prepare(struct xa_context *r,
     }
 
     /* shaders */
-    if (src_texture->format == PIPE_FORMAT_L8_UNORM)
+    if (src_texture->format == PIPE_FORMAT_L8_UNORM ||
+        src_texture->format == PIPE_FORMAT_R8_UNORM)
 	fs_traits |= FS_SRC_LUMINANCE;
-    if (dst_surface->format == PIPE_FORMAT_L8_UNORM)
+    if (dst_surface->format == PIPE_FORMAT_L8_UNORM ||
+        src_texture->format == PIPE_FORMAT_R8_UNORM)
 	fs_traits |= FS_DST_LUMINANCE;
     if (xa_format_a(dst_xa_format) != 0 &&
 	xa_format_a(src_xa_format) == 0)
-- 
2.1.0



More information about the mesa-dev mailing list