From: Rob Clark <robcl...@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 <robcl...@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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to