From c9085f6d3b5cd99a5635af725a1fa932e5bc19c9 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 13 Nov 2018 14:10:56 +0100 Subject: [PATCH] st/xa: Support Component Alpha with trivial blending Support Component Alpha for those composite operations that do not require per-channel alpha blending. Signed-off-by: Thomas Hellstrom Reviewed-by: Brian Paul Reviewed-by: Sinclair Yeh --- 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); }