From 4885cd4ff71b184ef38d709f365dd8d46d437960 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 2 May 2010 21:37:24 +0100 Subject: softpipe: Fix alpha blending for formats without alpha channel. Don't use the dst alpha channel from the tile cache when it does not exist in the true format. --- src/gallium/drivers/softpipe/sp_quad_blend.c | 168 +++++++++++++++++---------- 1 file changed, 108 insertions(+), 60 deletions(-) (limited to 'src/gallium/drivers/softpipe/sp_quad_blend.c') diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index ead489393e..00187febf0 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -33,6 +33,7 @@ #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_format.h" #include "sp_context.h" #include "sp_quad.h" #include "sp_tile_cache.h" @@ -224,7 +225,8 @@ static void blend_quad(struct quad_stage *qs, float (*quadColor)[4], float (*dest)[4], - unsigned cbuf) + unsigned cbuf, + boolean has_dst_alpha) { static const float zero[4] = { 0, 0, 0, 0 }; static const float one[4] = { 1, 1, 1, 1 }; @@ -259,24 +261,34 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ break; case PIPE_BLENDFACTOR_DST_ALPHA: - { - const float *alpha = dest[3]; - VEC4_MUL(source[0], quadColor[0], alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], alpha); /* B */ - } - break; + if (has_dst_alpha) { + const float *alpha = dest[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + else { + VEC4_COPY(source[0], quadColor[0]); /* R */ + VEC4_COPY(source[1], quadColor[1]); /* G */ + VEC4_COPY(source[2], quadColor[2]); /* B */ + } + break; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - { - const float *alpha = quadColor[3]; - float diff[4], temp[4]; - VEC4_SUB(diff, one, dest[3]); - VEC4_MIN(temp, alpha, diff); - VEC4_MUL(source[0], quadColor[0], temp); /* R */ - VEC4_MUL(source[1], quadColor[1], temp); /* G */ - VEC4_MUL(source[2], quadColor[2], temp); /* B */ - } - break; + if (has_dst_alpha) { + const float *alpha = quadColor[3]; + float diff[4], temp[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(temp, alpha, diff); + VEC4_MUL(source[0], quadColor[0], temp); /* R */ + VEC4_MUL(source[1], quadColor[1], temp); /* G */ + VEC4_MUL(source[2], quadColor[2], temp); /* B */ + } + else { + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + } + break; case PIPE_BLENDFACTOR_CONST_COLOR: { float comp[4]; @@ -329,14 +341,19 @@ blend_quad(struct quad_stage *qs, } break; case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, dest[3]); - VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ - } - break; + if (has_dst_alpha) { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + else { + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + } + break; case PIPE_BLENDFACTOR_INV_DST_COLOR: { float inv_comp[4]; @@ -399,7 +416,10 @@ blend_quad(struct quad_stage *qs, case PIPE_BLENDFACTOR_DST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ + if (has_dst_alpha) + VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ + else + VEC4_COPY(source[3], quadColor[3]); /* A */ break; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: /* multiply alpha by 1.0 */ @@ -429,12 +449,15 @@ blend_quad(struct quad_stage *qs, case PIPE_BLENDFACTOR_INV_DST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, dest[3]); - VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ - } - break; + if (has_dst_alpha) { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + else { + VEC4_COPY(source[3], zero); /* A */ + } + break; case PIPE_BLENDFACTOR_INV_CONST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_INV_CONST_ALPHA: @@ -468,9 +491,14 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ break; case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ - VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ - VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ + if (has_dst_alpha) { + VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ + } + else { + /* dest = dest * 1 NO-OP, leave dest as-is */ + } break; case PIPE_BLENDFACTOR_DST_COLOR: VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ @@ -478,15 +506,20 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ break; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - { - const float *alpha = quadColor[3]; - float diff[4], temp[4]; - VEC4_SUB(diff, one, dest[3]); - VEC4_MIN(temp, alpha, diff); - VEC4_MUL(dest[0], quadColor[0], temp); /* R */ - VEC4_MUL(dest[1], quadColor[1], temp); /* G */ - VEC4_MUL(dest[2], quadColor[2], temp); /* B */ - } + if (has_dst_alpha) { + const float *alpha = quadColor[3]; + float diff[4], temp[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(temp, alpha, diff); + VEC4_MUL(dest[0], quadColor[0], temp); /* R */ + VEC4_MUL(dest[1], quadColor[1], temp); /* G */ + VEC4_MUL(dest[2], quadColor[2], temp); /* B */ + } + else { + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + } break; case PIPE_BLENDFACTOR_CONST_COLOR: { @@ -539,13 +572,18 @@ blend_quad(struct quad_stage *qs, } break; case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[3]); /* A */ - VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ - VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ - VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ - } + if (has_dst_alpha) { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + else { + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + } break; case PIPE_BLENDFACTOR_INV_DST_COLOR: { @@ -605,7 +643,12 @@ blend_quad(struct quad_stage *qs, case PIPE_BLENDFACTOR_DST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ + if (has_dst_alpha) { + VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ + } + else { + /* dest = dest * 1 NO-OP, leave dest as-is */ + } break; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: /* dest = dest * 1 NO-OP, leave dest as-is */ @@ -634,12 +677,15 @@ blend_quad(struct quad_stage *qs, case PIPE_BLENDFACTOR_INV_DST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[3]); /* A */ - VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ - } - break; + if (has_dst_alpha) { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ + } + else { + VEC4_COPY(dest[3], zero); /* A */ + } + break; case PIPE_BLENDFACTOR_INV_CONST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_INV_CONST_ALPHA: @@ -751,6 +797,8 @@ blend_fallback(struct quad_stage *qs, = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], quads[0]->input.x0, quads[0]->input.y0); + boolean has_dst_alpha + = util_format_has_alpha(softpipe->framebuffer.cbufs[cbuf]->format); uint q, i, j; for (q = 0; q < nr; q++) { @@ -774,7 +822,7 @@ blend_fallback(struct quad_stage *qs, logicop_quad( qs, quadColor, dest ); } else if (blend->rt[blend_buf].blend_enable) { - blend_quad( qs, quadColor, dest, cbuf ); + blend_quad( qs, quadColor, dest, cbuf, has_dst_alpha ); } if (blend->rt[blend_buf].colormask != 0xf) -- cgit v1.2.3