From c8cb5ed93c8e7343390f188bbf1a8459380a5739 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 17 Sep 2015 03:22:53 -0700 Subject: st/xa: Fixups for PIPE_FORMAT_R8_UNORM A8 usage v2. Check for PIPE_FORMAT_R8_UNORM when setting up the copy shader. Also re-enable the dest alpha blending with A8 destination that actually turned out to be correct. Verified using rendercheck that the composite operators overreverse, in, out, atop, atopreverse and xor seem to work fine with a8 destiation. v2: Fix a copy-paste error. Reported-by: Jose Fonseca Signed-off-by: Thomas Hellstrom Reviewed-by: Jose Fonseca --- src/gallium/state_trackers/xa/xa_composite.c | 34 ++++++++++++++++++++-------- src/gallium/state_trackers/xa/xa_renderer.c | 6 +++-- 2 files changed, 29 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c index e81eebaf541..bcb27ea1825 100644 --- a/src/gallium/state_trackers/xa/xa_composite.c +++ b/src/gallium/state_trackers/xa/xa_composite.c @@ -78,6 +78,27 @@ static const struct xa_composite_blend xa_blends[] = { 0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE}, }; +/* + * The alpha value stored in a L8 texture is read by the + * hardware as color, and R8 is read as red. The source alpha value + * at the end of the fragment shader is stored in all color channels, + * so the correct approach is to blend using DST_COLOR instead of + * DST_ALPHA and then output any color channel (L8) or the red channel (R8). + */ +static unsigned +xa_convert_blend_for_luminance(unsigned factor) +{ + switch(factor) { + case PIPE_BLENDFACTOR_DST_ALPHA: + return PIPE_BLENDFACTOR_DST_COLOR; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + return PIPE_BLENDFACTOR_INV_DST_COLOR; + default: + break; + } + return factor; +} + static boolean blend_for_op(struct xa_composite_blend *blend, enum xa_composite_op op, @@ -111,16 +132,11 @@ blend_for_op(struct xa_composite_blend *blend, if (!dst_pic->srf) return supported; - /* - * None of the hardware formats we might use for dst A8 are - * suitable for dst_alpha blending, since they present the - * alpha channel either in all color channels (L8_UNORM) or - * in the red channel only (R8_UNORM) - */ if ((dst_pic->srf->tex->format == PIPE_FORMAT_L8_UNORM || - dst_pic->srf->tex->format == PIPE_FORMAT_R8_UNORM) && - blend->alpha_dst) - return FALSE; + dst_pic->srf->tex->format == PIPE_FORMAT_R8_UNORM)) { + blend->rgb_src = xa_convert_blend_for_luminance(blend->rgb_src); + blend->rgb_dst = xa_convert_blend_for_luminance(blend->rgb_dst); + } /* * If there's no dst alpha channel, adjust the blend op so that we'll treat diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c index fda07e5b68e..bc55f877c48 100644 --- a/src/gallium/state_trackers/xa/xa_renderer.c +++ b/src/gallium/state_trackers/xa/xa_renderer.c @@ -465,9 +465,11 @@ renderer_copy_prepare(struct xa_context *r, } /* shaders */ - if (src_texture->format == PIPE_FORMAT_L8_UNORM) + if (src_texture->format == PIPE_FORMAT_L8_UNORM || + src_texture->format == PIPE_FORMAT_R8_UNORM) fs_traits |= FS_SRC_LUMINANCE; - if (dst_surface->format == PIPE_FORMAT_L8_UNORM) + if (dst_surface->format == PIPE_FORMAT_L8_UNORM || + dst_surface->format == PIPE_FORMAT_R8_UNORM) fs_traits |= FS_DST_LUMINANCE; if (xa_format_a(dst_xa_format) != 0 && xa_format_a(src_xa_format) == 0) -- cgit v1.2.3