summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Barbieri <luca@luca-barbieri.com>2010-08-26 18:22:14 +0200
committerLuca Barbieri <luca@luca-barbieri.com>2010-09-05 18:11:24 +0200
commit2020034159dfa82cc23f2e3434c2927ac8f4c5a5 (patch)
tree4505e50439563389bd98a686c781dfb61240a2f1
parent737c0c6b7d591ac0fc969a7590e1691eeef0ce5e (diff)
softpipe: rework blending to work properly
This changes makes softpipe clamp blend source, destination input, source factor and destination factor if the target is fixed point. Also, it makes it support an unclamped blend color properly. Note this is NOT related to vertex/fragment clamping and is independent of these controls, and only dependent on the type of _each_ color buffer. This is supposed to be the behavior specified by OpenGL 4.1 and ARB_color_buffer_float. Not sure about other APIs.
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h12
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_blend.c282
-rw-r--r--src/gallium/drivers/softpipe/sp_state_blend.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_state_surface.c28
4 files changed, 158 insertions, 170 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 9361a3df09..adc46280a0 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -70,7 +70,7 @@ struct softpipe_context {
struct sp_so_state *so;
/** Other rendering state */
- struct pipe_blend_color blend_color;
+ struct pipe_blend_color blend_color[2]; /* [0] is unclamped, [1] is clamped */
struct pipe_stencil_ref stencil_ref;
struct pipe_clip_state clip;
struct pipe_resource *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
@@ -152,6 +152,16 @@ struct softpipe_context {
struct quad_stage *first; /**< points to one of the above stages */
} quad;
+ /** Per-colorbuffer derived state: used for blending
+ * (but only depending on fb, not blend state) */
+ struct
+ {
+ boolean has_dest_alpha;
+ boolean clamp_blend_source_factors_and_results;
+ boolean clamp_blend_dest;
+ boolean perform_logicop;
+ } cbuf_derived[PIPE_MAX_COLOR_BUFS];
+
/** TGSI exec things */
struct {
struct sp_sampler_varient *geom_samplers_list[PIPE_MAX_GEOMETRY_SAMPLERS];
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
index 6af1b2d061..650c3badb2 100644
--- a/src/gallium/drivers/softpipe/sp_quad_blend.c
+++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
@@ -219,26 +219,50 @@ logicop_quad(struct quad_stage *qs,
}
}
-
-
/**
* Do blending for a 2x2 quad for one color buffer.
* \param quadColor the incoming quad colors
* \param dest the destination/framebuffer quad colors
* \param blend_index which set of blending terms to use
* \param has_dst_alpha does the dest color buffer have an alpha channel?
+ * \param clamp_blend_source_factors_and_results should we clamp the blend source, factors and result?
+ * \param clamp_blend_source_factors_and_results should we clamp the blend destination before using it as input?
*/
static void
blend_quad(struct quad_stage *qs,
float (*quadColor)[4],
- float (*dest)[4],
+ float (*raw_dest)[4],
unsigned blend_index,
- boolean has_dst_alpha)
+ boolean has_dst_alpha,
+ boolean clamp_blend_source_factors_and_results,
+ boolean clamp_blend_dest)
{
static const float zero[4] = { 0, 0, 0, 0 };
static const float one[4] = { 1, 1, 1, 1 };
struct softpipe_context *softpipe = qs->softpipe;
float source[4][QUAD_SIZE] = { { 0 } };
+ float clamped_dest[4][QUAD_SIZE] = { { 0 } };
+ float (*dest)[4] = raw_dest;
+
+ if(clamp_blend_source_factors_and_results)
+ {
+ unsigned i, j;
+ for (j = 0; j < QUAD_SIZE; j++)
+ for (i = 0; i < 4; i++)
+ quadColor[i][j] = CLAMP(quadColor[i][j], 0.0f, 1.0f);
+ }
+
+ /* this is only TRUE for weird cases like SNORM targets, since
+ * otherwise we either must not do this, or it superfluous to do so
+ */
+ if(clamp_blend_dest)
+ {
+ unsigned i, j;
+ for (j = 0; j < QUAD_SIZE; j++)
+ for (i = 0; i < 4; i++)
+ clamped_dest[i][j] = CLAMP(raw_dest[i][j], 0.0f, 1.0f);
+ dest = clamped_dest;
+ }
/*
* Compute src/first term RGB
@@ -299,18 +323,18 @@ blend_quad(struct quad_stage *qs,
case PIPE_BLENDFACTOR_CONST_COLOR:
{
float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
+ VEC4_SCALAR(comp, softpipe->blend_color[clamp_blend_source_factors_and_results].color[0]); /* R */
VEC4_MUL(source[0], quadColor[0], comp); /* R */
- VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
+ VEC4_SCALAR(comp, softpipe->blend_color[clamp_blend_source_factors_and_results].color[1]); /* G */
VEC4_MUL(source[1], quadColor[1], comp); /* G */
- VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
+ VEC4_SCALAR(comp, softpipe->blend_color[clamp_blend_source_factors_and_results].color[2]); /* B */
VEC4_MUL(source[2], quadColor[2], comp); /* B */
}
break;
case PIPE_BLENDFACTOR_CONST_ALPHA:
{
float alpha[4];
- VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
+ VEC4_SCALAR(alpha, softpipe->blend_color[clamp_blend_source_factors_and_results].color[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 */
@@ -376,20 +400,20 @@ blend_quad(struct quad_stage *qs,
{
float inv_comp[4];
/* R */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[0]);
VEC4_MUL(source[0], quadColor[0], inv_comp);
/* G */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[1]);
VEC4_MUL(source[1], quadColor[1], inv_comp);
/* B */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[2]);
VEC4_MUL(source[2], quadColor[2], inv_comp);
}
break;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
{
float inv_alpha[4];
- VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[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 */
@@ -437,7 +461,7 @@ blend_quad(struct quad_stage *qs,
case PIPE_BLENDFACTOR_CONST_ALPHA:
{
float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+ VEC4_SCALAR(comp, softpipe->blend_color[clamp_blend_source_factors_and_results].color[3]); /* A */
VEC4_MUL(source[3], quadColor[3], comp); /* A */
}
break;
@@ -471,7 +495,7 @@ blend_quad(struct quad_stage *qs,
{
float inv_comp[4];
/* A */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[3]);
VEC4_MUL(source[3], quadColor[3], inv_comp);
}
break;
@@ -531,18 +555,18 @@ blend_quad(struct quad_stage *qs,
case PIPE_BLENDFACTOR_CONST_COLOR:
{
float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
+ VEC4_SCALAR(comp, softpipe->blend_color[clamp_blend_source_factors_and_results].color[0]); /* R */
VEC4_MUL(dest[0], dest[0], comp); /* R */
- VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
+ VEC4_SCALAR(comp, softpipe->blend_color[clamp_blend_source_factors_and_results].color[1]); /* G */
VEC4_MUL(dest[1], dest[1], comp); /* G */
- VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
+ VEC4_SCALAR(comp, softpipe->blend_color[clamp_blend_source_factors_and_results].color[2]); /* B */
VEC4_MUL(dest[2], dest[2], comp); /* B */
}
break;
case PIPE_BLENDFACTOR_CONST_ALPHA:
{
float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+ VEC4_SCALAR(comp, softpipe->blend_color[clamp_blend_source_factors_and_results].color[3]); /* A */
VEC4_MUL(dest[0], dest[0], comp); /* R */
VEC4_MUL(dest[1], dest[1], comp); /* G */
VEC4_MUL(dest[2], dest[2], comp); /* B */
@@ -607,20 +631,20 @@ blend_quad(struct quad_stage *qs,
{
float inv_comp[4];
/* R */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[0]);
VEC4_MUL(dest[0], dest[0], inv_comp);
/* G */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[1]);
VEC4_MUL(dest[1], dest[1], inv_comp);
/* B */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[2]);
VEC4_MUL(dest[2], dest[2], inv_comp);
}
break;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
{
float inv_comp[4];
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[3]);
VEC4_MUL(dest[0], dest[0], inv_comp);
VEC4_MUL(dest[1], dest[1], inv_comp);
VEC4_MUL(dest[2], dest[2], inv_comp);
@@ -665,7 +689,7 @@ blend_quad(struct quad_stage *qs,
case PIPE_BLENDFACTOR_CONST_ALPHA:
{
float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+ VEC4_SCALAR(comp, softpipe->blend_color[clamp_blend_source_factors_and_results].color[3]); /* A */
VEC4_MUL(dest[3], dest[3], comp); /* A */
}
break;
@@ -698,7 +722,7 @@ blend_quad(struct quad_stage *qs,
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
{
float inv_comp[4];
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color[clamp_blend_source_factors_and_results].color[3]);
VEC4_MUL(dest[3], dest[3], inv_comp);
}
break;
@@ -706,24 +730,56 @@ blend_quad(struct quad_stage *qs,
assert(0 && "invalid alpha dst factor");
}
+ /* NOTE: we cannot rely on the float->ubyte conversion for
+ * the final clamping here, because we cache tiles, and must avoid
+ * reading back unclamped values from a cached tile
+ */
+
/*
* Combine RGB terms
*/
switch (softpipe->blend->rt[blend_index].rgb_func) {
case PIPE_BLEND_ADD:
- VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
- VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
- VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
+ if(clamp_blend_source_factors_and_results)
+ {
+ VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
+ }
+ else
+ {
+ VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */
+ }
break;
case PIPE_BLEND_SUBTRACT:
- VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */
- VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */
- VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */
+ if(clamp_blend_source_factors_and_results)
+ {
+ VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */
+ }
+ else
+ {
+ VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */
+ }
break;
case PIPE_BLEND_REVERSE_SUBTRACT:
- VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */
- VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */
- VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */
+ if(clamp_blend_source_factors_and_results)
+ {
+ VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */
+ VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */
+ VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */
+ }
+ else
+ {
+ VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */
+ VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */
+ VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */
+ }
break;
case PIPE_BLEND_MIN:
VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
@@ -744,13 +800,22 @@ blend_quad(struct quad_stage *qs,
*/
switch (softpipe->blend->rt[blend_index].alpha_func) {
case PIPE_BLEND_ADD:
- VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
+ if(clamp_blend_source_factors_and_results)
+ VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
+ else
+ VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */
break;
case PIPE_BLEND_SUBTRACT:
- VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */
+ if(clamp_blend_source_factors_and_results)
+ VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */
+ else
+ VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */
break;
case PIPE_BLEND_REVERSE_SUBTRACT:
- VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */
+ if(clamp_blend_source_factors_and_results)
+ VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */
+ else
+ VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */
break;
case PIPE_BLEND_MIN:
VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */
@@ -804,8 +869,6 @@ 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++) {
@@ -824,12 +887,16 @@ blend_fallback(struct quad_stage *qs,
}
}
-
if (blend->logicop_enable) {
- logicop_quad( qs, quadColor, dest );
+ /* yes, this must disable blend even if we don't actually perform it */
+ if(softpipe->cbuf_derived[cbuf].perform_logicop)
+ logicop_quad( qs, quadColor, dest );
}
else if (blend->rt[blend_buf].blend_enable) {
- blend_quad( qs, quadColor, dest, blend_buf, has_dst_alpha );
+ blend_quad( qs, quadColor, dest, blend_buf,
+ softpipe->cbuf_derived[cbuf].has_dest_alpha,
+ softpipe->cbuf_derived[cbuf].clamp_blend_source_factors_and_results,
+ softpipe->cbuf_derived[cbuf].clamp_blend_dest );
}
if (blend->rt[blend_buf].colormask != 0xf)
@@ -850,115 +917,8 @@ blend_fallback(struct quad_stage *qs,
}
}
-
-static void
-blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs,
- struct quad_header *quads[],
- unsigned nr)
-{
- static const float one[4] = { 1, 1, 1, 1 };
- float one_minus_alpha[QUAD_SIZE];
- float dest[4][QUAD_SIZE];
- float source[4][QUAD_SIZE];
- uint i, j, q;
-
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
- quads[0]->input.x0,
- quads[0]->input.y0);
-
- for (q = 0; q < nr; q++) {
- struct quad_header *quad = quads[q];
- float (*quadColor)[4] = quad->output.color[0];
- const float *alpha = quadColor[3];
- const int itx = (quad->input.x0 & (TILE_SIZE-1));
- const int ity = (quad->input.y0 & (TILE_SIZE-1));
-
- /* get/swizzle dest colors */
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = itx + (j & 1);
- int y = ity + (j >> 1);
- for (i = 0; i < 4; i++) {
- dest[i][j] = tile->data.color[y][x][i];
- }
- }
-
- VEC4_MUL(source[0], quadColor[0], alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], alpha); /* B */
- VEC4_MUL(source[3], quadColor[3], alpha); /* A */
-
- VEC4_SUB(one_minus_alpha, one, alpha);
- VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
- VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
- VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
- VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* B */
-
- VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
- VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
- VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
- VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
-
- for (j = 0; j < QUAD_SIZE; j++) {
- if (quad->inout.mask & (1 << j)) {
- int x = itx + (j & 1);
- int y = ity + (j >> 1);
- for (i = 0; i < 4; i++) { /* loop over color chans */
- tile->data.color[y][x][i] = quadColor[i][j];
- }
- }
- }
- }
-}
-
static void
-blend_single_add_one_one(struct quad_stage *qs,
- struct quad_header *quads[],
- unsigned nr)
-{
- float dest[4][QUAD_SIZE];
- uint i, j, q;
-
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
- quads[0]->input.x0,
- quads[0]->input.y0);
-
- for (q = 0; q < nr; q++) {
- struct quad_header *quad = quads[q];
- float (*quadColor)[4] = quad->output.color[0];
- const int itx = (quad->input.x0 & (TILE_SIZE-1));
- const int ity = (quad->input.y0 & (TILE_SIZE-1));
-
- /* get/swizzle dest colors */
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = itx + (j & 1);
- int y = ity + (j >> 1);
- for (i = 0; i < 4; i++) {
- dest[i][j] = tile->data.color[y][x][i];
- }
- }
-
- VEC4_ADD_SAT(quadColor[0], quadColor[0], dest[0]); /* R */
- VEC4_ADD_SAT(quadColor[1], quadColor[1], dest[1]); /* G */
- VEC4_ADD_SAT(quadColor[2], quadColor[2], dest[2]); /* B */
- VEC4_ADD_SAT(quadColor[3], quadColor[3], dest[3]); /* A */
-
- for (j = 0; j < QUAD_SIZE; j++) {
- if (quad->inout.mask & (1 << j)) {
- int x = itx + (j & 1);
- int y = ity + (j >> 1);
- for (i = 0; i < 4; i++) { /* loop over color chans */
- tile->data.color[y][x][i] = quadColor[i][j];
- }
- }
- }
- }
-}
-
-
-static void
-single_output_color(struct quad_stage *qs,
+single_output_color(struct quad_stage *qs,
struct quad_header *quads[],
unsigned nr)
{
@@ -1004,32 +964,18 @@ choose_blend_quad(struct quad_stage *qs,
const struct pipe_blend_state *blend = softpipe->blend;
qs->run = blend_fallback;
-
+
if (softpipe->framebuffer.nr_cbufs == 0) {
qs->run = blend_noop;
}
else if (!softpipe->blend->logicop_enable &&
softpipe->blend->rt[0].colormask == 0xf &&
- softpipe->framebuffer.nr_cbufs == 1)
+ softpipe->framebuffer.nr_cbufs == 1
+ )
{
- if (!blend->rt[0].blend_enable) {
+ if (!blend->rt[0].blend_enable)
+ /* if blending is disabled, being fixed-point does not cause any clamping */
qs->run = single_output_color;
- }
- else if (blend->rt[0].rgb_src_factor == blend->rt[0].alpha_src_factor &&
- blend->rt[0].rgb_dst_factor == blend->rt[0].alpha_dst_factor &&
- blend->rt[0].rgb_func == blend->rt[0].alpha_func)
- {
- if (blend->rt[0].alpha_func == PIPE_BLEND_ADD) {
- if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
- blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_ONE) {
- qs->run = blend_single_add_one_one;
- }
- else if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA &&
- blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA)
- qs->run = blend_single_add_src_alpha_inv_src_alpha;
-
- }
- }
}
qs->run(qs, quads, nr);
diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c
index 2a203f44e5..fe295d5a73 100644
--- a/src/gallium/drivers/softpipe/sp_state_blend.c
+++ b/src/gallium/drivers/softpipe/sp_state_blend.c
@@ -29,6 +29,7 @@
*/
#include "util/u_memory.h"
+#include "util/u_math.h"
#include "draw/draw_context.h"
#include "sp_context.h"
#include "sp_state.h"
@@ -64,10 +65,13 @@ void softpipe_set_blend_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color )
{
struct softpipe_context *softpipe = softpipe_context(pipe);
+ unsigned i;
draw_flush(softpipe->draw);
- softpipe->blend_color = *blend_color;
+ softpipe->blend_color[0] = *blend_color;
+ for(i = 0; i < 4; ++i)
+ softpipe->blend_color[1].color[i] = CLAMP(softpipe->blend_color[0].color[i], 0.0f, 1.0f);
softpipe->dirty |= SP_NEW_BLEND;
}
diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c
index 2db6faeca4..f2945909bd 100644
--- a/src/gallium/drivers/softpipe/sp_state_surface.c
+++ b/src/gallium/drivers/softpipe/sp_state_surface.c
@@ -100,5 +100,33 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
sp->framebuffer.width = fb->width;
sp->framebuffer.height = fb->height;
+ /* find out how to do blending for this framebuffer, in case we want to do so */
+ for (i = 0; i < fb->nr_cbufs; i++)
+ {
+ const struct util_format_description* desc = util_format_description(fb->cbufs[i]->format);
+ unsigned chan;
+
+ sp->cbuf_derived[i].has_dest_alpha = util_format_has_alpha(fb->cbufs[i]->format);
+ sp->cbuf_derived[i].clamp_blend_source_factors_and_results = FALSE;
+ sp->cbuf_derived[i].clamp_blend_dest = FALSE;
+ sp->cbuf_derived[i].perform_logicop = TRUE;
+
+ for(chan = 0; chan < desc->nr_channels; ++chan)
+ {
+ if(desc->channel[chan].type == UTIL_FORMAT_TYPE_FLOAT)
+ sp->cbuf_derived[i].perform_logicop = FALSE;
+ else
+ {
+ sp->cbuf_derived[i].clamp_blend_source_factors_and_results = TRUE;
+ /* we can skip this for unsigned normalized, since they are
+ * already in the [0, 1] range
+ */
+ if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED
+ || !desc->channel[chan].normalized)
+ sp->cbuf_derived[i].clamp_blend_dest = TRUE;
+ }
+ }
+ }
+
sp->dirty |= SP_NEW_FRAMEBUFFER;
}