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