[Mesa-dev] [PATCH v2 5/5] st/xa: handle xrgb->a better

Rob Clark robdclark at gmail.com
Tue Apr 8 13:48:53 PDT 2014


From: Rob Clark <robclark at freedesktop.org>

Detect the edge cases where texture fetch is unneeded (due to alpha
channel being wired to 1.0 and non-alpha components thrown out).

Signed-off-by: Rob Clark <robclark at freedesktop.org>
---
 src/gallium/state_trackers/xa/xa_composite.c | 13 +++++++--
 src/gallium/state_trackers/xa/xa_priv.h      | 10 +++++++
 src/gallium/state_trackers/xa/xa_tgsi.c      | 43 +++++++++++++++++++---------
 3 files changed, 51 insertions(+), 15 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c
index b70fd47..7f7e3e4 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -315,6 +315,7 @@ 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_color = FALSE;
 
@@ -335,6 +336,9 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
 	    vs_traits |= VS_COMPOSITE;
 	}
 
+	if (is_xrgb_to_alpha(dst_pic, src_pic))
+	    ctx->has_solid_color = TRUE;
+
 	fs_traits |= picture_format_fixups(src_pic, 0);
     }
 
@@ -351,6 +355,8 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
 	    xa_pixel_to_float4(mask_pic->src_pict->solid_fill.color,
 		    ctx->solid_mask);
 	    ctx->has_solid_mask = TRUE;
+	} else if (is_xrgb_to_alpha(dst_pic, mask_pic)) {
+	    ctx->has_solid_mask = TRUE;
 	}
 
 	if (mask_pic->component_alpha) {
@@ -387,6 +393,7 @@ bind_samplers(struct xa_context *ctx,
     struct pipe_context *pipe = ctx->pipe;
     struct xa_picture *src_pic = comp->src;
     struct xa_picture *mask_pic = comp->mask;
+    struct xa_picture *dst_pic = comp->dst;
     unsigned n = 0;
 
     /* unref old sampler views: */
@@ -395,7 +402,8 @@ bind_samplers(struct xa_context *ctx,
     memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
     memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
 
-    if (src_pic && !is_solid_fill(src_pic)) {
+    if (src_pic && !is_solid_fill(src_pic) &&
+	    !is_xrgb_to_alpha(dst_pic, src_pic)) {
 	unsigned src_wrap = xa_repeat_to_gallium(src_pic->wrap);
 	int filter;
 
@@ -418,7 +426,8 @@ bind_samplers(struct xa_context *ctx,
 	n++;
     }
 
-    if (mask_pic && !is_solid_fill(mask_pic)) {
+    if (mask_pic && !is_solid_fill(mask_pic) &&
+	    !is_xrgb_to_alpha(dst_pic, mask_pic)) {
 	unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap);
 	int filter;
 
diff --git a/src/gallium/state_trackers/xa/xa_priv.h b/src/gallium/state_trackers/xa/xa_priv.h
index 1ef810e..723ea4a 100644
--- a/src/gallium/state_trackers/xa/xa_priv.h
+++ b/src/gallium/state_trackers/xa/xa_priv.h
@@ -233,6 +233,16 @@ is_solid_fill(struct xa_picture *pic)
     return pic->src_pict && (pic->src_pict->type == xa_src_pict_solid_fill);
 }
 
+/* a8 dst and xRGB src (or mask) is a special case.  The texture fetch
+ * is optimized out.
+ */
+static INLINE int
+is_xrgb_to_alpha(struct xa_picture *dst, struct xa_picture *src)
+{
+    return (dst->pict_format == xa_format_a8) &&
+	    (xa_format_a(src->pict_format) == 0);
+}
+
 /*
  * xa_tgsi.c
  */
diff --git a/src/gallium/state_trackers/xa/xa_tgsi.c b/src/gallium/state_trackers/xa/xa_tgsi.c
index e96bc53..b7e0fe1 100644
--- a/src/gallium/state_trackers/xa/xa_tgsi.c
+++ b/src/gallium/state_trackers/xa/xa_tgsi.c
@@ -479,10 +479,12 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
 	imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
     }
     if (is_composite) {
-	src_sampler = ureg_DECL_sampler(ureg, n++);
-	src_input = ureg_DECL_fs_input(ureg,
-				       TGSI_SEMANTIC_GENERIC, 0,
-				       TGSI_INTERPOLATE_PERSPECTIVE);
+	if (!(dst_luminance && src_set_alpha)) {
+	    src_sampler = ureg_DECL_sampler(ureg, n++);
+	    src_input = ureg_DECL_fs_input(ureg,
+					   TGSI_SEMANTIC_GENERIC, 0,
+					   TGSI_INTERPOLATE_PERSPECTIVE);
+	}
     } else if (is_fill) {
 	if (is_solid)
 	    src_input = ureg_DECL_fs_input(ureg,
@@ -502,10 +504,12 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
 				       TGSI_SEMANTIC_COLOR, 1,
 				       TGSI_INTERPOLATE_PERSPECTIVE);
     } else if (has_mask) {
-	mask_sampler = ureg_DECL_sampler(ureg, n++);
-	mask_pos = ureg_DECL_fs_input(ureg,
-				      TGSI_SEMANTIC_GENERIC, 1,
-				      TGSI_INTERPOLATE_PERSPECTIVE);
+	if (!(dst_luminance && mask_set_alpha)) {
+	    mask_sampler = ureg_DECL_sampler(ureg, n++);
+	    mask_pos = ureg_DECL_fs_input(ureg,
+					  TGSI_SEMANTIC_GENERIC, 1,
+					  TGSI_INTERPOLATE_PERSPECTIVE);
+	}
     }
 #if 0				/* unused right now */
     dst_sampler = ureg_DECL_sampler(ureg, 2);
@@ -519,14 +523,22 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
 	    src = ureg_DECL_temporary(ureg);
 	else
 	    src = out;
-	xrender_tex(ureg, src, src_input, src_sampler, imm0,
+
+	if (dst_luminance && src_set_alpha) {
+	    ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_W),
+		    ureg_scalar(imm0, TGSI_SWIZZLE_W));
+	} else {
+	    xrender_tex(ureg, src, src_input, src_sampler, imm0,
 		    src_repeat_none, src_swizzle, src_set_alpha);
+	}
     } else if (is_fill) {
 	if (is_solid) {
-	    if (has_mask || src_luminance || dst_luminance)
-		src = ureg_dst(src_input);
-	    else
+	    if (has_mask || src_luminance || dst_luminance) {
+		src = ureg_DECL_temporary(ureg);
+		ureg_MOV(ureg, src, src_input);
+	    } else {
 		ureg_MOV(ureg, out, src_input);
+	    }
 	} else if (is_lingrad || is_radgrad) {
 	    struct ureg_src coords, const0124, matrow0, matrow1, matrow2;
 
@@ -565,8 +577,13 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
 	mask = ureg_dst(mask_pos);
     } else if (has_mask) {
 	mask = ureg_DECL_temporary(ureg);
-	xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
+	if (dst_luminance && mask_set_alpha) {
+	    ureg_MOV(ureg, ureg_writemask(mask, TGSI_WRITEMASK_W),
+		    ureg_scalar(imm0, TGSI_SWIZZLE_W));
+	} else {
+	    xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
 		    mask_repeat_none, mask_swizzle, mask_set_alpha);
+	}
     }
 
     if (has_mask) {
-- 
1.9.0



More information about the mesa-dev mailing list