diff options
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r-- | src/gallium/state_trackers/xa/xa_composite.c | 34 | ||||
-rw-r--r-- | src/gallium/state_trackers/xa/xa_renderer.c | 6 |
2 files changed, 29 insertions, 11 deletions
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) |