summaryrefslogtreecommitdiff
path: root/src/mesa/state_tracker/st_atom_blend.c
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@vmware.com>2010-01-25 19:27:05 +0100
committerRoland Scheidegger <sroland@vmware.com>2010-01-25 19:27:05 +0100
commit5fae36147e1067ac8b1eb5bcade2f9b1dbf29aa4 (patch)
treecd1b28cbd46c2961b1e8d253a06f6c29f57c512d /src/mesa/state_tracker/st_atom_blend.c
parent0d3a6a505d537b879f31be0ed14fa8577717efaf (diff)
st/mesa: handle EXT_draw_buffers2 per rendertarget blend enables / colormasks
uses the new gallium per-rt blend functionality
Diffstat (limited to 'src/mesa/state_tracker/st_atom_blend.c')
-rw-r--r--src/mesa/state_tracker/st_atom_blend.c93
1 files changed, 62 insertions, 31 deletions
diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c
index 75c1418335..809b10d479 100644
--- a/src/mesa/state_tracker/st_atom_blend.c
+++ b/src/mesa/state_tracker/st_atom_blend.c
@@ -152,14 +152,40 @@ translate_logicop(GLenum logicop)
}
}
+static boolean
+colormask_perrt(GLcontext *ctx)
+{
+ /* XXX this is ugly beyond belief */
+ unsigned i;
+ for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) {
+ if (!TEST_EQ_4V(ctx->Color.ColorMask[0], ctx->Color.ColorMask[i])) {
+ return true;
+ }
+ }
+ return false;
+}
static void
update_blend( struct st_context *st )
{
struct pipe_blend_state *blend = &st->state.blend;
+ unsigned num_state = 1;
+ unsigned i;
memset(blend, 0, sizeof(*blend));
+ if ((st->ctx->Color.BlendEnabled &&
+ (st->ctx->Color.BlendEnabled != ((1 << st->ctx->Const.MaxDrawBuffers) - 1))) ||
+ colormask_perrt(st->ctx)) {
+ num_state = st->ctx->Const.MaxDrawBuffers;
+ blend->independent_blend_enable = 1;
+ }
+ /* Note it is impossible to correctly deal with EXT_blend_logic_op and
+ EXT_draw_buffers2/EXT_blend_equation_separate at the same time.
+ These combinations would require support for per-rt logicop enables
+ and separate alpha/rgb logicop/blend support respectively. Neither
+ possible in gallium nor most hardware. Assume these combinations
+ don't happen. */
if (st->ctx->Color.ColorLogicOpEnabled ||
(st->ctx->Color.BlendEnabled &&
st->ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) {
@@ -169,30 +195,33 @@ update_blend( struct st_context *st )
}
else if (st->ctx->Color.BlendEnabled) {
/* blending enabled */
- blend->rt[0].blend_enable = 1;
-
- blend->rt[0].rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB);
- if (st->ctx->Color.BlendEquationRGB == GL_MIN ||
- st->ctx->Color.BlendEquationRGB == GL_MAX) {
- /* Min/max are special */
- blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
- }
- else {
- blend->rt[0].rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB);
- blend->rt[0].rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB);
- }
+ for (i = 0; i < num_state; i++) {
- blend->rt[0].alpha_func = translate_blend(st->ctx->Color.BlendEquationA);
- if (st->ctx->Color.BlendEquationA == GL_MIN ||
- st->ctx->Color.BlendEquationA == GL_MAX) {
- /* Min/max are special */
- blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
- }
- else {
- blend->rt[0].alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA);
- blend->rt[0].alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA);
+ blend->rt[i].blend_enable = (st->ctx->Color.BlendEnabled >> i) & 0x1;
+
+ blend->rt[i].rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB);
+ if (st->ctx->Color.BlendEquationRGB == GL_MIN ||
+ st->ctx->Color.BlendEquationRGB == GL_MAX) {
+ /* Min/max are special */
+ blend->rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ }
+ else {
+ blend->rt[i].rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB);
+ blend->rt[i].rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB);
+ }
+
+ blend->rt[i].alpha_func = translate_blend(st->ctx->Color.BlendEquationA);
+ if (st->ctx->Color.BlendEquationA == GL_MIN ||
+ st->ctx->Color.BlendEquationA == GL_MAX) {
+ /* Min/max are special */
+ blend->rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ }
+ else {
+ blend->rt[i].alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA);
+ blend->rt[i].alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA);
+ }
}
}
else {
@@ -200,14 +229,16 @@ update_blend( struct st_context *st )
}
/* Colormask - maybe reverse these bits? */
- if (st->ctx->Color.ColorMask[0][0])
- blend->rt[0].colormask |= PIPE_MASK_R;
- if (st->ctx->Color.ColorMask[0][1])
- blend->rt[0].colormask |= PIPE_MASK_G;
- if (st->ctx->Color.ColorMask[0][2])
- blend->rt[0].colormask |= PIPE_MASK_B;
- if (st->ctx->Color.ColorMask[0][3])
- blend->rt[0].colormask |= PIPE_MASK_A;
+ for (i = 0; i < num_state; i++) {
+ if (st->ctx->Color.ColorMask[i][0])
+ blend->rt[i].colormask |= PIPE_MASK_R;
+ if (st->ctx->Color.ColorMask[i][1])
+ blend->rt[i].colormask |= PIPE_MASK_G;
+ if (st->ctx->Color.ColorMask[i][2])
+ blend->rt[i].colormask |= PIPE_MASK_B;
+ if (st->ctx->Color.ColorMask[i][3])
+ blend->rt[i].colormask |= PIPE_MASK_A;
+ }
if (st->ctx->Color.DitherFlag)
blend->dither = 1;