[Mesa-dev] [PATCH 3/3] st/xa: Support Component Alpha with trivial blending

Thomas Hellstrom thellstrom at vmware.com
Tue Nov 13 17:46:47 UTC 2018


Support Component Alpha for those composite operations that do not require
per-channel alpha blending.

Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Reviewed-by: Brian Paul <brianp at vmware.com>
---
 src/gallium/state_trackers/xa/xa_composite.c | 33 ++++++++++++--------
 src/gallium/state_trackers/xa/xa_priv.h      |  1 +
 src/gallium/state_trackers/xa/xa_tgsi.c      | 18 ++++++++---
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c
index b0746327522..34d78027e27 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -111,12 +111,6 @@ blend_for_op(struct xa_composite_blend *blend,
     int i;
     boolean supported = FALSE;
 
-    /*
-     * No component alpha yet.
-     */
-    if (mask_pic && mask_pic->component_alpha)
-	return FALSE;
-
     /*
      * our default in case something goes wrong
      */
@@ -130,6 +124,12 @@ blend_for_op(struct xa_composite_blend *blend,
 	}
     }
 
+    /*
+     * No component alpha yet.
+     */
+    if (mask_pic && mask_pic->component_alpha && blend->alpha_src)
+	return FALSE;
+
     if (!dst_pic->srf)
 	return supported;
 
@@ -224,15 +224,9 @@ xa_src_pict_is_accelerated(const union xa_source_pict *src_pic)
 XA_EXPORT int
 xa_composite_check_accelerated(const struct xa_composite *comp)
 {
-    struct xa_composite_blend blend;
     struct xa_picture *src_pic = comp->src;
     struct xa_picture *mask_pic = comp->mask;
-
-    /*
-     * No component alpha yet.
-     */
-    if (mask_pic && mask_pic->component_alpha)
-	return -XA_ERR_INVAL;
+    struct xa_composite_blend blend;
 
     if (!xa_is_filter_accelerated(src_pic) ||
 	!xa_is_filter_accelerated(comp->mask)) {
@@ -246,6 +240,12 @@ xa_composite_check_accelerated(const struct xa_composite *comp)
     if (!blend_for_op(&blend, comp->op, comp->src, comp->mask, comp->dst))
 	return -XA_ERR_INVAL;
 
+    /*
+     * No component alpha yet.
+     */
+    if (mask_pic && mask_pic->component_alpha && blend.alpha_src)
+	return -XA_ERR_INVAL;
+
     return XA_ERR_NONE;
 }
 
@@ -382,10 +382,15 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
     struct xa_shader shader;
     struct xa_picture *src_pic = comp->src;
     struct xa_picture *mask_pic = comp->mask;
+    struct xa_picture *dst_pic = comp->dst;
 
     ctx->has_solid_src = FALSE;
     ctx->has_solid_mask = FALSE;
 
+    if (dst_pic && xa_format_type(dst_pic->pict_format) !=
+        xa_format_type(xa_surface_format(dst_pic->srf)))
+       return -XA_ERR_INVAL;
+
     if (src_pic) {
 	if (src_pic->wrap == xa_wrap_clamp_to_border && src_pic->has_transform)
 	    fs_traits |= FS_SRC_REPEAT_NONE;
@@ -405,6 +410,8 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
     if (mask_pic) {
 	vs_traits |= VS_MASK;
 	fs_traits |= FS_MASK;
+        if (mask_pic->component_alpha)
+           fs_traits |= FS_CA;
         if (mask_pic->src_pict) {
             if (!xa_handle_src_pict(ctx, mask_pic->src_pict, true))
                 return -XA_ERR_INVAL;
diff --git a/src/gallium/state_trackers/xa/xa_priv.h b/src/gallium/state_trackers/xa/xa_priv.h
index 09a858ff972..f368de3b81f 100644
--- a/src/gallium/state_trackers/xa/xa_priv.h
+++ b/src/gallium/state_trackers/xa/xa_priv.h
@@ -166,6 +166,7 @@ enum xa_fs_traits {
     FS_SRC_LUMINANCE = 1 << 11,
     FS_MASK_LUMINANCE = 1 << 12,
     FS_DST_LUMINANCE = 1 << 13,
+    FS_CA = 1 << 14,
 };
 
 struct xa_shader {
diff --git a/src/gallium/state_trackers/xa/xa_tgsi.c b/src/gallium/state_trackers/xa/xa_tgsi.c
index 5f2608aee55..ed3e0895d98 100644
--- a/src/gallium/state_trackers/xa/xa_tgsi.c
+++ b/src/gallium/state_trackers/xa/xa_tgsi.c
@@ -82,6 +82,7 @@ print_fs_traits(int fs_traits)
 	"FS_SRC_LUMINANCE",	/* = 1 << 11, */
 	"FS_MASK_LUMINANCE",	/* = 1 << 12, */
 	"FS_DST_LUMINANCE",     /* = 1 << 13, */
+        "FS_CA",                /* = 1 << 14, */
     };
     int i, k;
 
@@ -107,12 +108,20 @@ src_in_mask(struct ureg_program *ureg,
 	    struct ureg_dst dst,
 	    struct ureg_src src,
 	    struct ureg_src mask,
-	    unsigned mask_luminance)
+	    unsigned mask_luminance, boolean component_alpha)
 {
     if (mask_luminance)
-        ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X));
-    else
+        if (component_alpha) {
+            ureg_MOV(ureg, dst, src);
+            ureg_MUL(ureg, ureg_writemask(dst, TGSI_WRITEMASK_W),
+                     src, ureg_scalar(mask, TGSI_SWIZZLE_X));
+        } else {
+            ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X));
+        }
+    else if (!component_alpha)
         ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_W));
+    else
+        ureg_MUL(ureg, dst, src, mask);
 }
 
 static struct ureg_src
@@ -347,6 +356,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
     unsigned dst_luminance = (fs_traits & FS_DST_LUMINANCE) != 0;
     unsigned is_src_src = (fs_traits & FS_SRC_SRC) != 0;
     unsigned is_mask_src = (fs_traits & FS_MASK_SRC) != 0;
+    boolean component_alpha = (fs_traits & FS_CA) != 0;
     unsigned cur_sampler = 0;
     unsigned cur_constant = 0;
 
@@ -391,7 +401,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
                    &cur_sampler);
 
 	src_in_mask(ureg, (dst_luminance) ? src : out, ureg_src(src),
-		    ureg_src(mask), mask_luminance);
+		    ureg_src(mask), mask_luminance, component_alpha);
 
 	ureg_release_temporary(ureg, mask);
     }
-- 
2.19.0.rc1



More information about the mesa-dev mailing list