summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}