st/xa: Fixups for PIPE_FORMAT_R8_UNORM A8 usage v2.
authorThomas Hellstrom <thellstrom@vmware.com>
Thu, 17 Sep 2015 10:22:53 +0000 (03:22 -0700)
committerThomas Hellstrom <thellstrom@vmware.com>
Thu, 24 Sep 2015 11:47:48 +0000 (04:47 -0700)
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.

v2: Fix a copy-paste error.

Reported-by: Jose Fonseca <jfonseca@vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
src/gallium/state_trackers/xa/xa_composite.c
src/gallium/state_trackers/xa/xa_renderer.c

index e81eebaf54175f8a4f4c7cb94a0d06fae49db1ff..bcb27ea182526faa9fc52ccfa7ed51999406f8b7 100644 (file)
@@ -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
index fda07e5b68e7d40f175127f16aa6156f8e245f99..bc55f877c4872e034cdd25061b111fcc8767bdb5 100644 (file)
@@ -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 ||
+        dst_surface->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)