summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2010-05-02 21:37:24 +0100
committerJosé Fonseca <[email protected]>2010-05-03 00:13:36 +0100
commit4885cd4ff71b184ef38d709f365dd8d46d437960 (patch)
tree80480072cde85e9b1cdc4efc17146394ebe952a8 /src
parent59253a79d823a4cfd1d65466c0a165d6d4c43a92 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_blend.c168
1 files changed, 108 insertions, 60 deletions
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
index ead489393ef..00187febf0c 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)