mesa: begin implementation of GL_ARB_draw_buffers_blend
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index fc67bee..3c6ecb8 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -231,13 +231,14 @@
ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor);
ctx->Driver.BlendEquationSeparate(ctx,
- ctx->Color.BlendEquationRGB,
- ctx->Color.BlendEquationA);
+ ctx->Color.Blend[0].EquationRGB,
+ ctx->Color.Blend[0].EquationA);
ctx->Driver.BlendFuncSeparate(ctx,
- ctx->Color.BlendSrcRGB,
- ctx->Color.BlendDstRGB,
- ctx->Color.BlendSrcA, ctx->Color.BlendDstA);
+ ctx->Color.Blend[0].SrcRGB,
+ ctx->Color.Blend[0].DstRGB,
+ ctx->Color.Blend[0].SrcA,
+ ctx->Color.Blend[0].DstA);
if (ctx->Driver.ColorMaskIndexed) {
GLuint i;
diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c
index 7c3fbb1..6040abf 100644
--- a/src/mesa/drivers/dri/i810/i810state.c
+++ b/src/mesa/drivers/dri/i810/i810state.c
@@ -95,7 +95,7 @@
GLuint a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND;
GLboolean fallback = GL_FALSE;
- switch (ctx->Color.BlendSrcRGB) {
+ switch (ctx->Color.Blend[0].SrcRGB) {
case GL_ZERO: a |= SDM_SRC_ZERO; break;
case GL_ONE: a |= SDM_SRC_ONE; break;
case GL_SRC_COLOR: a |= SDM_SRC_SRC_COLOR; break;
@@ -124,7 +124,7 @@
return;
}
- switch (ctx->Color.BlendDstRGB) {
+ switch (ctx->Color.Blend[0].DstRGB) {
case GL_ZERO: a |= SDM_DST_ZERO; break;
case GL_ONE: a |= SDM_DST_ONE; break;
case GL_SRC_COLOR: a |= SDM_DST_SRC_COLOR; break;
diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c
index 147192a..ef5b8d9 100644
--- a/src/mesa/drivers/dri/i915/i830_state.c
+++ b/src/mesa/drivers/dri/i915/i830_state.c
@@ -291,10 +291,10 @@
funcRGB =
- SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcRGB))
- | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstRGB));
+ SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].SrcRGB))
+ | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].DstRGB));
- switch (ctx->Color.BlendEquationRGB) {
+ switch (ctx->Color.Blend[0].EquationRGB) {
case GL_FUNC_ADD:
eqnRGB = BLENDFUNC_ADD;
break;
@@ -314,15 +314,15 @@
break;
default:
fprintf(stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB);
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationRGB);
return;
}
- funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcA))
- | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstA));
+ funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].SrcA))
+ | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].DstA));
- switch (ctx->Color.BlendEquationA) {
+ switch (ctx->Color.Blend[0].EquationA) {
case GL_FUNC_ADD:
eqnA = BLENDFUNC_ADD;
break;
@@ -342,7 +342,7 @@
break;
default:
fprintf(stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationA);
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationA);
return;
}
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 9508fba..63c6e78 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -267,12 +267,12 @@
~(S6_CBUF_SRC_BLEND_FACT_MASK |
S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK));
- GLuint eqRGB = ctx->Color.BlendEquationRGB;
- GLuint eqA = ctx->Color.BlendEquationA;
- GLuint srcRGB = ctx->Color.BlendSrcRGB;
- GLuint dstRGB = ctx->Color.BlendDstRGB;
- GLuint srcA = ctx->Color.BlendSrcA;
- GLuint dstA = ctx->Color.BlendDstA;
+ GLuint eqRGB = ctx->Color.Blend[0].EquationRGB;
+ GLuint eqA = ctx->Color.Blend[0].EquationA;
+ GLuint srcRGB = ctx->Color.Blend[0].SrcRGB;
+ GLuint dstRGB = ctx->Color.Blend[0].DstRGB;
+ GLuint srcA = ctx->Color.Blend[0].SrcA;
+ GLuint dstA = ctx->Color.Blend[0].DstA;
if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
srcRGB = dstRGB = GL_ONE;
diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c
index d286c9d..c986970 100644
--- a/src/mesa/drivers/dri/i965/brw_cc.c
+++ b/src/mesa/drivers/dri/i965/brw_cc.c
@@ -141,12 +141,12 @@
cc.cc2.logicop_enable = 1;
cc.cc5.logicop_func = intel_translate_logic_op(ctx->Color.LogicOp);
} else if (ctx->Color.BlendEnabled) {
- GLenum eqRGB = ctx->Color.BlendEquationRGB;
- GLenum eqA = ctx->Color.BlendEquationA;
- GLenum srcRGB = ctx->Color.BlendSrcRGB;
- GLenum dstRGB = ctx->Color.BlendDstRGB;
- GLenum srcA = ctx->Color.BlendSrcA;
- GLenum dstA = ctx->Color.BlendDstA;
+ GLenum eqRGB = ctx->Color.Blend[0].EquationRGB;
+ GLenum eqA = ctx->Color.Blend[0].EquationA;
+ GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
+ GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
+ GLenum srcA = ctx->Color.Blend[0].SrcA;
+ GLenum dstA = ctx->Color.Blend[0].DstA;
/* If the renderbuffer is XRGB, we have to frob the blend function to
* force the destination alpha to 1.0. This means replacing GL_DST_ALPHA
diff --git a/src/mesa/drivers/dri/i965/gen6_cc.c b/src/mesa/drivers/dri/i965/gen6_cc.c
index dbcdc5b..f51afa4 100644
--- a/src/mesa/drivers/dri/i965/gen6_cc.c
+++ b/src/mesa/drivers/dri/i965/gen6_cc.c
@@ -66,12 +66,12 @@
/* _NEW_COLOR */
key->color_blend = ctx->Color.BlendEnabled;
if (key->color_blend) {
- key->blend_eq_rgb = ctx->Color.BlendEquationRGB;
- key->blend_eq_a = ctx->Color.BlendEquationA;
- key->blend_src_rgb = ctx->Color.BlendSrcRGB;
- key->blend_dst_rgb = ctx->Color.BlendDstRGB;
- key->blend_src_a = ctx->Color.BlendSrcA;
- key->blend_dst_a = ctx->Color.BlendDstA;
+ key->blend_eq_rgb = ctx->Color.Blend[0].EquationRGB;
+ key->blend_eq_a = ctx->Color.Blend[0].EquationA;
+ key->blend_src_rgb = ctx->Color.Blend[0].SrcRGB;
+ key->blend_dst_rgb = ctx->Color.Blend[0].DstRGB;
+ key->blend_src_a = ctx->Color.Blend[0].SrcA;
+ key->blend_dst_a = ctx->Color.Blend[0].DstA;
}
/* _NEW_COLOR */
diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c
index d5c3577..f97256e 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel.c
@@ -66,12 +66,12 @@
}
if (ctx->Color.BlendEnabled &&
- (effective_func(ctx->Color.BlendSrcRGB, src_alpha_is_one) != GL_ONE ||
- effective_func(ctx->Color.BlendDstRGB, src_alpha_is_one) != GL_ZERO ||
- ctx->Color.BlendEquationRGB != GL_FUNC_ADD ||
- effective_func(ctx->Color.BlendSrcA, src_alpha_is_one) != GL_ONE ||
- effective_func(ctx->Color.BlendDstA, src_alpha_is_one) != GL_ZERO ||
- ctx->Color.BlendEquationA != GL_FUNC_ADD)) {
+ (effective_func(ctx->Color.Blend[0].SrcRGB, src_alpha_is_one) != GL_ONE ||
+ effective_func(ctx->Color.Blend[0].DstRGB, src_alpha_is_one) != GL_ZERO ||
+ ctx->Color.Blend[0].EquationRGB != GL_FUNC_ADD ||
+ effective_func(ctx->Color.Blend[0].SrcA, src_alpha_is_one) != GL_ONE ||
+ effective_func(ctx->Color.Blend[0].DstA, src_alpha_is_one) != GL_ZERO ||
+ ctx->Color.Blend[0].EquationA != GL_FUNC_ADD)) {
DBG("fallback due to blend\n");
return GL_FALSE;
}
diff --git a/src/mesa/drivers/dri/mach64/mach64_state.c b/src/mesa/drivers/dri/mach64/mach64_state.c
index 8e79595..c1a4e63 100644
--- a/src/mesa/drivers/dri/mach64/mach64_state.c
+++ b/src/mesa/drivers/dri/mach64/mach64_state.c
@@ -102,7 +102,7 @@
MACH64_ALPHA_BLEND_DST_MASK |
MACH64_ALPHA_BLEND_SAT);
- switch ( ctx->Color.BlendSrcRGB ) {
+ switch ( ctx->Color.Blend[0].SrcRGB ) {
case GL_ZERO:
s |= MACH64_ALPHA_BLEND_SRC_ZERO;
break;
@@ -135,7 +135,7 @@
FALLBACK( mmesa, MACH64_FALLBACK_BLEND_FUNC, GL_TRUE );
}
- switch ( ctx->Color.BlendDstRGB ) {
+ switch ( ctx->Color.Blend[0].DstRGB ) {
case GL_ZERO:
s |= MACH64_ALPHA_BLEND_DST_ZERO;
break;
diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c
index 25d7de2..2fac2b4 100644
--- a/src/mesa/drivers/dri/mga/mgastate.c
+++ b/src/mesa/drivers/dri/mga/mgastate.c
@@ -141,7 +141,7 @@
GLuint src;
GLuint dst;
- switch (ctx->Color.BlendSrcRGB) {
+ switch (ctx->Color.Blend[0].SrcRGB) {
case GL_ZERO:
src = AC_src_zero; break;
case GL_SRC_ALPHA:
@@ -169,7 +169,7 @@
break;
}
- switch (ctx->Color.BlendDstRGB) {
+ switch (ctx->Color.Blend[0].DstRGB) {
case GL_SRC_ALPHA:
dst = AC_dst_src_alpha; break;
case GL_ONE_MINUS_SRC_ALPHA:
diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_raster.c b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c
index 98f2f98..ecfbdfe 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_state_raster.c
+++ b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c
@@ -264,8 +264,8 @@
NV04_MULTITEX_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE;
/* Alpha blending. */
- blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 |
- get_blend_func(ctx->Color.BlendSrcRGB) << 24;
+ blend |= get_blend_func(ctx->Color.Blend[0].DstRGB) << 28 |
+ get_blend_func(ctx->Color.Blend[0].SrcRGB) << 24;
if (ctx->Color.BlendEnabled)
blend |= NV04_MULTITEX_TRIANGLE_BLEND_BLEND_ENABLE;
@@ -296,8 +296,8 @@
NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE;
/* Alpha blending. */
- blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 |
- get_blend_func(ctx->Color.BlendSrcRGB) << 24;
+ blend |= get_blend_func(ctx->Color.Blend[0].DstRGB) << 28 |
+ get_blend_func(ctx->Color.Blend[0].SrcRGB) << 24;
if (ctx->Color.BlendEnabled)
blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE;
diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_raster.c b/src/mesa/drivers/dri/nouveau/nv10_state_raster.c
index bb1084e..50021b0 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_state_raster.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_state_raster.c
@@ -68,7 +68,7 @@
OUT_RINGb(chan, ctx->Color.BlendEnabled);
BEGIN_RING(chan, celsius, NV10_3D_BLEND_EQUATION, 1);
- OUT_RING(chan, nvgl_blend_eqn(ctx->Color.BlendEquationRGB));
+ OUT_RING(chan, nvgl_blend_eqn(ctx->Color.Blend[0].EquationRGB));
}
void
@@ -78,8 +78,8 @@
struct nouveau_grobj *celsius = context_eng3d(ctx);
BEGIN_RING(chan, celsius, NV10_3D_BLEND_FUNC_SRC, 2);
- OUT_RING(chan, nvgl_blend_func(ctx->Color.BlendSrcRGB));
- OUT_RING(chan, nvgl_blend_func(ctx->Color.BlendDstRGB));
+ OUT_RING(chan, nvgl_blend_func(ctx->Color.Blend[0].SrcRGB));
+ OUT_RING(chan, nvgl_blend_func(ctx->Color.Blend[0].DstRGB));
}
void
diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c
index 4a49e8f..d6725cd 100644
--- a/src/mesa/drivers/dri/r128/r128_state.c
+++ b/src/mesa/drivers/dri/r128/r128_state.c
@@ -178,12 +178,12 @@
(R128_ALPHA_BLEND_MASK << R128_ALPHA_BLEND_DST_SHIFT)
| R128_ALPHA_COMB_FCN_MASK);
- a |= blend_factor( rmesa, ctx->Color.BlendSrcRGB, GL_TRUE )
+ a |= blend_factor( rmesa, ctx->Color.Blend[0].SrcRGB, GL_TRUE )
<< R128_ALPHA_BLEND_SRC_SHIFT;
- a |= blend_factor( rmesa, ctx->Color.BlendDstRGB, GL_FALSE )
+ a |= blend_factor( rmesa, ctx->Color.Blend[0].DstRGB, GL_FALSE )
<< R128_ALPHA_BLEND_DST_SHIFT;
- switch (ctx->Color.BlendEquationRGB) {
+ switch (ctx->Color.Blend[0].EquationRGB) {
case GL_FUNC_ADD:
a |= R128_ALPHA_COMB_ADD_CLAMP;
break;
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index b523edcb..0a1e0b4 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -245,10 +245,10 @@
}
}
- func = (blend_factor( ctx->Color.BlendSrcRGB, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
- (blend_factor( ctx->Color.BlendDstRGB, GL_FALSE ) << R200_DST_BLEND_SHIFT);
+ func = (blend_factor( ctx->Color.Blend[0].SrcRGB, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
+ (blend_factor( ctx->Color.Blend[0].DstRGB, GL_FALSE ) << R200_DST_BLEND_SHIFT);
- switch(ctx->Color.BlendEquationRGB) {
+ switch(ctx->Color.Blend[0].EquationRGB) {
case GL_FUNC_ADD:
eqn = R200_COMB_FCN_ADD_CLAMP;
break;
@@ -275,7 +275,7 @@
default:
fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB );
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationRGB );
return;
}
@@ -284,10 +284,10 @@
return;
}
- funcA = (blend_factor( ctx->Color.BlendSrcA, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
- (blend_factor( ctx->Color.BlendDstA, GL_FALSE ) << R200_DST_BLEND_SHIFT);
+ funcA = (blend_factor( ctx->Color.Blend[0].SrcA, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
+ (blend_factor( ctx->Color.Blend[0].DstA, GL_FALSE ) << R200_DST_BLEND_SHIFT);
- switch(ctx->Color.BlendEquationA) {
+ switch(ctx->Color.Blend[0].EquationA) {
case GL_FUNC_ADD:
eqnA = R200_COMB_FCN_ADD_CLAMP;
break;
@@ -314,7 +314,7 @@
default:
fprintf( stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationA );
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationA );
return;
}
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index ab8c1df..9df9101 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -220,12 +220,12 @@
}
func =
- (blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE) <<
- R300_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstRGB,
+ (blend_factor(ctx->Color.Blend[0].SrcRGB, GL_TRUE) <<
+ R300_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.Blend[0].DstRGB,
GL_FALSE) <<
R300_DST_BLEND_SHIFT);
- switch (ctx->Color.BlendEquationRGB) {
+ switch (ctx->Color.Blend[0].EquationRGB) {
case GL_FUNC_ADD:
eqn = R300_COMB_FCN_ADD_CLAMP;
break;
@@ -253,17 +253,17 @@
default:
fprintf(stderr,
"[%s:%u] Invalid RGB blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB);
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationRGB);
return;
}
funcA =
- (blend_factor(ctx->Color.BlendSrcA, GL_TRUE) <<
- R300_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstA,
+ (blend_factor(ctx->Color.Blend[0].SrcA, GL_TRUE) <<
+ R300_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.Blend[0].DstA,
GL_FALSE) <<
R300_DST_BLEND_SHIFT);
- switch (ctx->Color.BlendEquationA) {
+ switch (ctx->Color.Blend[0].EquationA) {
case GL_FUNC_ADD:
eqnA = R300_COMB_FCN_ADD_CLAMP;
break;
@@ -291,7 +291,7 @@
default:
fprintf(stderr,
"[%s:%u] Invalid A blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationA);
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationA);
return;
}
diff --git a/src/mesa/drivers/dri/r600/evergreen_state.c b/src/mesa/drivers/dri/r600/evergreen_state.c
index 648cda0..006e500 100644
--- a/src/mesa/drivers/dri/r600/evergreen_state.c
+++ b/src/mesa/drivers/dri/r600/evergreen_state.c
@@ -363,13 +363,13 @@
}
SETfield(blend_reg,
- evergreenblend_factor(ctx->Color.BlendSrcRGB, GL_TRUE),
+ evergreenblend_factor(ctx->Color.Blend[0].SrcRGB, GL_TRUE),
COLOR_SRCBLEND_shift, COLOR_SRCBLEND_mask);
SETfield(blend_reg,
- evergreenblend_factor(ctx->Color.BlendDstRGB, GL_FALSE),
+ evergreenblend_factor(ctx->Color.Blend[0].DstRGB, GL_FALSE),
COLOR_DESTBLEND_shift, COLOR_DESTBLEND_mask);
- switch (ctx->Color.BlendEquationRGB) {
+ switch (ctx->Color.Blend[0].EquationRGB) {
case GL_FUNC_ADD:
eqn = COMB_DST_PLUS_SRC;
break;
@@ -401,20 +401,20 @@
default:
fprintf(stderr,
"[%s:%u] Invalid RGB blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB);
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationRGB);
return;
}
SETfield(blend_reg,
eqn, COLOR_COMB_FCN_shift, COLOR_COMB_FCN_mask);
SETfield(blend_reg,
- evergreenblend_factor(ctx->Color.BlendSrcA, GL_TRUE),
+ evergreenblend_factor(ctx->Color.Blend[0].SrcA, GL_TRUE),
ALPHA_SRCBLEND_shift, ALPHA_SRCBLEND_mask);
SETfield(blend_reg,
- evergreenblend_factor(ctx->Color.BlendDstA, GL_FALSE),
+ evergreenblend_factor(ctx->Color.Blend[0].DstA, GL_FALSE),
ALPHA_DESTBLEND_shift, ALPHA_DESTBLEND_mask);
- switch (ctx->Color.BlendEquationA) {
+ switch (ctx->Color.Blend[0].EquationA) {
case GL_FUNC_ADD:
eqnA = COMB_DST_PLUS_SRC;
break;
@@ -445,7 +445,7 @@
default:
fprintf(stderr,
"[%s:%u] Invalid A blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationA);
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationA);
return;
}
diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c
index bd04a63..f877069 100644
--- a/src/mesa/drivers/dri/r600/r700_state.c
+++ b/src/mesa/drivers/dri/r600/r700_state.c
@@ -474,13 +474,13 @@
}
SETfield(blend_reg,
- blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE),
+ blend_factor(ctx->Color.Blend[0].SrcRGB, GL_TRUE),
COLOR_SRCBLEND_shift, COLOR_SRCBLEND_mask);
SETfield(blend_reg,
- blend_factor(ctx->Color.BlendDstRGB, GL_FALSE),
+ blend_factor(ctx->Color.Blend[0].DstRGB, GL_FALSE),
COLOR_DESTBLEND_shift, COLOR_DESTBLEND_mask);
- switch (ctx->Color.BlendEquationRGB) {
+ switch (ctx->Color.Blend[0].EquationRGB) {
case GL_FUNC_ADD:
eqn = COMB_DST_PLUS_SRC;
break;
@@ -512,20 +512,20 @@
default:
fprintf(stderr,
"[%s:%u] Invalid RGB blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB);
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationRGB);
return;
}
SETfield(blend_reg,
eqn, COLOR_COMB_FCN_shift, COLOR_COMB_FCN_mask);
SETfield(blend_reg,
- blend_factor(ctx->Color.BlendSrcA, GL_TRUE),
+ blend_factor(ctx->Color.Blend[0].SrcA, GL_TRUE),
ALPHA_SRCBLEND_shift, ALPHA_SRCBLEND_mask);
SETfield(blend_reg,
- blend_factor(ctx->Color.BlendDstA, GL_FALSE),
+ blend_factor(ctx->Color.Blend[0].DstA, GL_FALSE),
ALPHA_DESTBLEND_shift, ALPHA_DESTBLEND_mask);
- switch (ctx->Color.BlendEquationA) {
+ switch (ctx->Color.Blend[0].EquationA) {
case GL_FUNC_ADD:
eqnA = COMB_DST_PLUS_SRC;
break;
@@ -556,7 +556,7 @@
default:
fprintf(stderr,
"[%s:%u] Invalid A blend equation (0x%04x).\n",
- __FUNCTION__, __LINE__, ctx->Color.BlendEquationA);
+ __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationA);
return;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index cae12f1..ca42aa3 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -136,7 +136,7 @@
RADEON_STATECHANGE( rmesa, ctx );
rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
- && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) {
+ && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
} else {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
@@ -153,7 +153,7 @@
~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
GLboolean fallback = GL_FALSE;
- switch ( ctx->Color.BlendSrcRGB ) {
+ switch ( ctx->Color.Blend[0].SrcRGB ) {
case GL_ZERO:
b |= RADEON_SRC_BLEND_GL_ZERO;
break;
@@ -200,7 +200,7 @@
break;
}
- switch ( ctx->Color.BlendDstRGB ) {
+ switch ( ctx->Color.Blend[0].DstRGB ) {
case GL_ZERO:
b |= RADEON_DST_BLEND_GL_ZERO;
break;
@@ -1602,7 +1602,7 @@
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
}
if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
- && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) {
+ && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
} else {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
@@ -1612,12 +1612,12 @@
*/
if (state) {
ctx->Driver.BlendEquationSeparate( ctx,
- ctx->Color.BlendEquationRGB,
- ctx->Color.BlendEquationA );
- ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.BlendSrcRGB,
- ctx->Color.BlendDstRGB,
- ctx->Color.BlendSrcA,
- ctx->Color.BlendDstA );
+ ctx->Color.Blend[0].EquationRGB,
+ ctx->Color.Blend[0].EquationA );
+ ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
+ ctx->Color.Blend[0].DstRGB,
+ ctx->Color.Blend[0].SrcA,
+ ctx->Color.Blend[0].DstA );
}
else {
FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
@@ -1741,7 +1741,7 @@
case GL_COLOR_LOGIC_OP:
RADEON_STATECHANGE( rmesa, ctx );
if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
- && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) {
+ && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
} else {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c
index 0906f85..1feffa0 100644
--- a/src/mesa/drivers/dri/savage/savagestate.c
+++ b/src/mesa/drivers/dri/savage/savagestate.c
@@ -136,7 +136,7 @@
* blend modes
*/
if(ctx->Color.BlendEnabled){
- switch (ctx->Color.BlendDstRGB)
+ switch (ctx->Color.Blend[0].DstRGB)
{
case GL_ZERO:
imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
@@ -192,7 +192,7 @@
break;
}
- switch (ctx->Color.BlendSrcRGB)
+ switch (ctx->Color.Blend[0].SrcRGB)
{
case GL_ZERO:
imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_Zero;
@@ -310,7 +310,7 @@
* blend modes
*/
if(ctx->Color.BlendEnabled){
- switch (ctx->Color.BlendDstRGB)
+ switch (ctx->Color.Blend[0].DstRGB)
{
case GL_ZERO:
imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
@@ -366,7 +366,7 @@
break;
}
- switch (ctx->Color.BlendSrcRGB)
+ switch (ctx->Color.Blend[0].SrcRGB)
{
case GL_ZERO:
imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_Zero;
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c
index 3f6822d..b26b2c7 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_state.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c
@@ -84,7 +84,7 @@
if ( ctx->Color.BlendEnabled
&& (fxMesa->Fallback & TDFX_FALLBACK_BLEND) == 0 ) {
- switch ( ctx->Color.BlendSrcRGB ) {
+ switch ( ctx->Color.Blend[0].SrcRGB ) {
case GL_ZERO:
srcRGB = GR_BLEND_ZERO;
break;
@@ -126,7 +126,7 @@
srcRGB = GR_BLEND_ONE;
}
- switch ( ctx->Color.BlendSrcA ) {
+ switch ( ctx->Color.Blend[0].SrcA ) {
case GL_ZERO:
srcA = GR_BLEND_ZERO;
break;
@@ -156,7 +156,7 @@
srcA = GR_BLEND_ONE;
}
- switch ( ctx->Color.BlendDstRGB ) {
+ switch ( ctx->Color.Blend[0].DstRGB ) {
case GL_ZERO:
dstRGB = GR_BLEND_ZERO;
break;
@@ -195,7 +195,7 @@
dstRGB = GR_BLEND_ZERO;
}
- switch ( ctx->Color.BlendDstA ) {
+ switch ( ctx->Color.Blend[0].DstA ) {
case GL_ZERO:
dstA = GR_BLEND_ZERO;
break;
@@ -222,7 +222,7 @@
dstA = GR_BLEND_ZERO;
}
- switch ( ctx->Color.BlendEquationRGB ) {
+ switch ( ctx->Color.Blend[0].EquationRGB ) {
case GL_FUNC_SUBTRACT:
eqRGB = GR_BLEND_OP_SUB;
break;
@@ -235,7 +235,7 @@
break;
}
- switch ( ctx->Color.BlendEquationA ) {
+ switch ( ctx->Color.Blend[0].EquationA ) {
case GL_FUNC_SUBTRACT:
eqA = GR_BLEND_OP_SUB;
break;
diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c
index 0333521..774f439 100644
--- a/src/mesa/drivers/dri/unichrome/via_state.c
+++ b/src/mesa/drivers/dri/unichrome/via_state.c
@@ -552,7 +552,7 @@
if (VIA_DEBUG & DEBUG_STATE)
fprintf(stderr, "%s in\n", __FUNCTION__);
- switch (ctx->Color.BlendSrcRGB) {
+ switch (ctx->Color.Blend[0].SrcRGB) {
case GL_SRC_ALPHA_SATURATE:
case GL_CONSTANT_COLOR:
case GL_ONE_MINUS_CONSTANT_COLOR:
@@ -564,7 +564,7 @@
break;
}
- switch (ctx->Color.BlendDstRGB) {
+ switch (ctx->Color.Blend[0].DstRGB) {
case GL_CONSTANT_COLOR:
case GL_ONE_MINUS_CONSTANT_COLOR:
case GL_CONSTANT_ALPHA:
@@ -757,14 +757,14 @@
*/
ctx->Driver.BlendEquationSeparate( ctx,
- ctx->Color.BlendEquationRGB,
- ctx->Color.BlendEquationA);
+ ctx->Color.Blend[0].EquationRGB,
+ ctx->Color.Blend[0].EquationA);
ctx->Driver.BlendFuncSeparate( ctx,
- ctx->Color.BlendSrcRGB,
- ctx->Color.BlendDstRGB,
- ctx->Color.BlendSrcA,
- ctx->Color.BlendDstA);
+ ctx->Color.Blend[0].SrcRGB,
+ ctx->Color.Blend[0].DstRGB,
+ ctx->Color.Blend[0].SrcA,
+ ctx->Color.Blend[0].DstA);
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height );
@@ -953,8 +953,8 @@
static void viaChooseColorState(struct gl_context *ctx)
{
struct via_context *vmesa = VIA_CONTEXT(ctx);
- GLenum s = ctx->Color.BlendSrcRGB;
- GLenum d = ctx->Color.BlendDstRGB;
+ GLenum s = ctx->Color.Blend[0].SrcRGB;
+ GLenum d = ctx->Color.Blend[0].DstRGB;
/* The HW's blending equation is:
* (Ca * FCa + Cbias + Cb * FCb) << Cshift
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index adfec3b..7fd1287 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -954,20 +954,39 @@
_mesa_set_enable(ctx, GL_BLEND, (color->BlendEnabled & 1));
}
}
- _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB,
- color->BlendDstRGB,
- color->BlendSrcA,
- color->BlendDstA);
- /* This special case is because glBlendEquationSeparateEXT
- * cannot take GL_LOGIC_OP as a parameter.
- */
- if ( color->BlendEquationRGB == color->BlendEquationA ) {
- _mesa_BlendEquation(color->BlendEquationRGB);
- }
- else {
- _mesa_BlendEquationSeparateEXT(color->BlendEquationRGB,
- color->BlendEquationA);
- }
+ if (ctx->Color._BlendFuncPerBuffer ||
+ ctx->Color._BlendEquationPerBuffer) {
+ /* set blend per buffer */
+ GLuint buf;
+ for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
+ _mesa_BlendFuncSeparatei(buf, color->Blend[buf].SrcRGB,
+ color->Blend[buf].DstRGB,
+ color->Blend[buf].SrcA,
+ color->Blend[buf].DstA);
+ _mesa_BlendEquationSeparatei(buf,
+ color->Blend[buf].EquationRGB,
+ color->Blend[buf].EquationA);
+ }
+ }
+ else {
+ /* set same blend modes for all buffers */
+ _mesa_BlendFuncSeparateEXT(color->Blend[0].SrcRGB,
+ color->Blend[0].DstRGB,
+ color->Blend[0].SrcA,
+ color->Blend[0].DstA);
+ /* This special case is because glBlendEquationSeparateEXT
+ * cannot take GL_LOGIC_OP as a parameter.
+ */
+ if (color->Blend[0].EquationRGB ==
+ color->Blend[0].EquationA) {
+ _mesa_BlendEquation(color->Blend[0].EquationRGB);
+ }
+ else {
+ _mesa_BlendEquationSeparateEXT(
+ color->Blend[0].EquationRGB,
+ color->Blend[0].EquationA);
+ }
+ }
_mesa_BlendColor(color->BlendColor[0],
color->BlendColor[1],
color->BlendColor[2],
diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
index ec778b7..43e2f7f 100644
--- a/src/mesa/main/blend.c
+++ b/src/mesa/main/blend.c
@@ -37,6 +37,110 @@
#include "mtypes.h"
+
+/**
+ * Check if given blend source factor is legal.
+ * \return GL_TRUE if legal, GL_FALSE otherwise.
+ */
+static GLboolean
+legal_src_factor(const struct gl_context *ctx, GLenum factor)
+{
+ switch (factor) {
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ return ctx->Extensions.NV_blend_square;
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_SRC_ALPHA_SATURATE:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Check if given blend destination factor is legal.
+ * \return GL_TRUE if legal, GL_FALSE otherwise.
+ */
+static GLboolean
+legal_dst_factor(const struct gl_context *ctx, GLenum factor)
+{
+ switch (factor) {
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ return ctx->Extensions.NV_blend_square;
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Check if src/dest RGB/A blend factors are legal. If not generate
+ * a GL error.
+ * \return GL_TRUE if factors are legal, GL_FALSE otherwise.
+ */
+static GLboolean
+validate_blend_factors(struct gl_context *ctx, const char *func,
+ GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ if (!legal_src_factor(ctx, sfactorRGB)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(sfactorRGB = %s)", func,
+ _mesa_lookup_enum_by_nr(sfactorRGB));
+ return GL_FALSE;
+ }
+
+ if (!legal_dst_factor(ctx, dfactorRGB)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(dfactorRGB = %s)", func,
+ _mesa_lookup_enum_by_nr(dfactorRGB));
+ return GL_FALSE;
+ }
+
+ if (sfactorA != sfactorRGB && !legal_src_factor(ctx, sfactorA)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(sfactorA = %s)", func,
+ _mesa_lookup_enum_by_nr(sfactorA));
+ return GL_FALSE;
+ }
+
+ if (dfactorA != dfactorRGB && !legal_dst_factor(ctx, dfactorA)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(dfactorA = %s)", func,
+ _mesa_lookup_enum_by_nr(dfactorA));
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+
/**
* Specify the blending operation.
*
@@ -53,21 +157,19 @@
/**
- * Process GL_EXT_blend_func_separate().
+ * Set the separate blend source/dest factors for all draw buffers.
*
* \param sfactorRGB RGB source factor operator.
* \param dfactorRGB RGB destination factor operator.
* \param sfactorA alpha source factor operator.
* \param dfactorA alpha destination factor operator.
- *
- * Verifies the parameters and updates gl_colorbuffer_attrib.
- * On a change, flush the vertices and notify the driver via
- * dd_function_table::BlendFuncSeparate.
*/
void GLAPIENTRY
_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
GLenum sfactorA, GLenum dfactorA )
{
+ GLuint buf, numBuffers;
+ GLboolean changed;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -78,165 +180,130 @@
_mesa_lookup_enum_by_nr(sfactorA),
_mesa_lookup_enum_by_nr(dfactorA));
- switch (sfactorRGB) {
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- if (!ctx->Extensions.NV_blend_square) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)");
- return;
- }
- /* fall-through */
- case GL_ZERO:
- case GL_ONE:
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_SRC_ALPHA_SATURATE:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)");
- return;
+ if (!validate_blend_factors(ctx, "glBlendFuncSeparate",
+ sfactorRGB, dfactorRGB,
+ sfactorA, dfactorA)) {
+ return;
}
- switch (dfactorRGB) {
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- if (!ctx->Extensions.NV_blend_square) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)");
- return;
- }
- /* fall-through */
- case GL_ZERO:
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)");
- return;
- }
+ numBuffers = ctx->Extensions.ARB_draw_buffers_blend
+ ? ctx->Const.MaxDrawBuffers : 1;
- switch (sfactorA) {
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- if (!ctx->Extensions.NV_blend_square) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)");
- return;
- }
- /* fall-through */
- case GL_ZERO:
- case GL_ONE:
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_SRC_ALPHA_SATURATE:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
+ changed = GL_FALSE;
+ for (buf = 0; buf < numBuffers; buf++) {
+ if (ctx->Color.Blend[buf].SrcRGB != sfactorRGB ||
+ ctx->Color.Blend[buf].DstRGB != dfactorRGB ||
+ ctx->Color.Blend[buf].SrcA != sfactorA ||
+ ctx->Color.Blend[buf].DstA != dfactorA) {
+ changed = GL_TRUE;
break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)");
- return;
+ }
}
-
- switch (dfactorA) {
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- if (!ctx->Extensions.NV_blend_square) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)");
- return;
- }
- /* fall-through */
- case GL_ZERO:
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)" );
- return;
- }
-
- if (ctx->Color.BlendSrcRGB == sfactorRGB &&
- ctx->Color.BlendDstRGB == dfactorRGB &&
- ctx->Color.BlendSrcA == sfactorA &&
- ctx->Color.BlendDstA == dfactorA)
+ if (!changed)
return;
FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.BlendSrcRGB = sfactorRGB;
- ctx->Color.BlendDstRGB = dfactorRGB;
- ctx->Color.BlendSrcA = sfactorA;
- ctx->Color.BlendDstA = dfactorA;
+ for (buf = 0; buf < numBuffers; buf++) {
+ ctx->Color.Blend[buf].SrcRGB = sfactorRGB;
+ ctx->Color.Blend[buf].DstRGB = dfactorRGB;
+ ctx->Color.Blend[buf].SrcA = sfactorA;
+ ctx->Color.Blend[buf].DstA = dfactorA;
+ }
+ ctx->Color._BlendFuncPerBuffer = GL_FALSE;
if (ctx->Driver.BlendFuncSeparate) {
- (*ctx->Driver.BlendFuncSeparate)( ctx, sfactorRGB, dfactorRGB,
- sfactorA, dfactorA );
+ ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB,
+ sfactorA, dfactorA);
}
}
#if _HAVE_FULL_GL
-static GLboolean
-_mesa_validate_blend_equation( struct gl_context *ctx,
- GLenum mode, GLboolean is_separate )
+
+/**
+ * Set blend source/dest factors for one color buffer/target.
+ */
+void GLAPIENTRY
+_mesa_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
{
- switch (mode) {
- case GL_FUNC_ADD:
- break;
- case GL_MIN:
- case GL_MAX:
- if (!ctx->Extensions.EXT_blend_minmax) {
- return GL_FALSE;
- }
- break;
- /* glBlendEquationSeparate cannot take GL_LOGIC_OP as a parameter.
- */
- case GL_LOGIC_OP:
- if (!ctx->Extensions.EXT_blend_logic_op || is_separate) {
- return GL_FALSE;
- }
- break;
- case GL_FUNC_SUBTRACT:
- case GL_FUNC_REVERSE_SUBTRACT:
- if (!ctx->Extensions.EXT_blend_subtract) {
- return GL_FALSE;
- }
- break;
- default:
- return GL_FALSE;
+ _mesa_BlendFuncSeparatei(buf, sfactor, dfactor, sfactor, dfactor);
+}
+
+
+/**
+ * Set separate blend source/dest factors for one color buffer/target.
+ */
+void GLAPIENTRY
+_mesa_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.ARB_draw_buffers_blend) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBlendFunc[Separate]i()");
+ return;
}
- return GL_TRUE;
+ if (buf >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)",
+ buf);
+ return;
+ }
+
+ if (!validate_blend_factors(ctx, "glBlendFuncSeparatei",
+ sfactorRGB, dfactorRGB,
+ sfactorA, dfactorA)) {
+ return;
+ }
+
+ if (ctx->Color.Blend[buf].SrcRGB == sfactorRGB &&
+ ctx->Color.Blend[buf].DstRGB == dfactorRGB &&
+ ctx->Color.Blend[buf].SrcA == sfactorA &&
+ ctx->Color.Blend[buf].DstA == dfactorA)
+ return; /* no change */
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+
+ ctx->Color.Blend[buf].SrcRGB = sfactorRGB;
+ ctx->Color.Blend[buf].DstRGB = dfactorRGB;
+ ctx->Color.Blend[buf].SrcA = sfactorA;
+ ctx->Color.Blend[buf].DstA = dfactorA;
+ ctx->Color._BlendFuncPerBuffer = GL_TRUE;
+
+ if (ctx->Driver.BlendFuncSeparatei) {
+ ctx->Driver.BlendFuncSeparatei(ctx, buf, sfactorRGB, dfactorRGB,
+ sfactorA, dfactorA);
+ }
+}
+
+
+/**
+ * Check if given blend equation is legal.
+ * \return GL_TRUE if legal, GL_FALSE otherwise.
+ */
+static GLboolean
+legal_blend_equation(const struct gl_context *ctx,
+ GLenum mode, GLboolean is_separate)
+{
+ switch (mode) {
+ case GL_FUNC_ADD:
+ return GL_TRUE;
+ case GL_MIN:
+ case GL_MAX:
+ return ctx->Extensions.EXT_blend_minmax;
+ case GL_LOGIC_OP:
+ /* glBlendEquationSeparate cannot take GL_LOGIC_OP as a parameter.
+ */
+ return ctx->Extensions.EXT_blend_logic_op && !is_separate;
+ case GL_FUNC_SUBTRACT:
+ case GL_FUNC_REVERSE_SUBTRACT:
+ return ctx->Extensions.EXT_blend_subtract;
+ default:
+ return GL_FALSE;
+ }
}
@@ -244,6 +311,8 @@
void GLAPIENTRY
_mesa_BlendEquation( GLenum mode )
{
+ GLuint buf, numBuffers;
+ GLboolean changed;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -251,27 +320,80 @@
_mesa_debug(ctx, "glBlendEquation %s\n",
_mesa_lookup_enum_by_nr(mode));
- if ( ! _mesa_validate_blend_equation( ctx, mode, GL_FALSE ) ) {
+ if (!legal_blend_equation(ctx, mode, GL_FALSE)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
return;
}
- if ( (ctx->Color.BlendEquationRGB == mode) &&
- (ctx->Color.BlendEquationA == mode) )
+ numBuffers = ctx->Extensions.ARB_draw_buffers_blend
+ ? ctx->Const.MaxDrawBuffers : 1;
+
+ changed = GL_FALSE;
+ for (buf = 0; buf < numBuffers; buf++) {
+ if (ctx->Color.Blend[buf].EquationRGB != mode ||
+ ctx->Color.Blend[buf].EquationA != mode) {
+ changed = GL_TRUE;
+ break;
+ }
+ }
+ if (!changed)
return;
FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.BlendEquationRGB = mode;
- ctx->Color.BlendEquationA = mode;
+ for (buf = 0; buf < numBuffers; buf++) {
+ ctx->Color.Blend[buf].EquationRGB = mode;
+ ctx->Color.Blend[buf].EquationA = mode;
+ }
+ ctx->Color._BlendEquationPerBuffer = GL_FALSE;
if (ctx->Driver.BlendEquationSeparate)
(*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode );
}
+/**
+ * Set blend equation for one color buffer/target.
+ */
+void GLAPIENTRY
+_mesa_BlendEquationi(GLuint buf, GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glBlendEquationi(%u, %s)\n",
+ buf, _mesa_lookup_enum_by_nr(mode));
+
+ if (buf >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)",
+ buf);
+ return;
+ }
+
+ if (!legal_blend_equation(ctx, mode, GL_FALSE)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationi");
+ return;
+ }
+
+ if (ctx->Color.Blend[buf].EquationRGB == mode &&
+ ctx->Color.Blend[buf].EquationA == mode)
+ return; /* no change */
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.Blend[buf].EquationRGB = mode;
+ ctx->Color.Blend[buf].EquationA = mode;
+ ctx->Color._BlendEquationPerBuffer = GL_TRUE;
+
+ if (ctx->Driver.BlendEquationSeparatei)
+ ctx->Driver.BlendEquationSeparatei(ctx, buf, mode, mode);
+}
+
+
void GLAPIENTRY
_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA )
{
+ GLuint buf, numBuffers;
+ GLboolean changed;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -286,29 +408,88 @@
return;
}
- if ( ! _mesa_validate_blend_equation( ctx, modeRGB, GL_TRUE ) ) {
+ if (!legal_blend_equation(ctx, modeRGB, GL_TRUE)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeRGB)");
return;
}
- if ( ! _mesa_validate_blend_equation( ctx, modeA, GL_TRUE ) ) {
+ if (!legal_blend_equation(ctx, modeA, GL_TRUE)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeA)");
return;
}
+ numBuffers = ctx->Extensions.ARB_draw_buffers_blend
+ ? ctx->Const.MaxDrawBuffers : 1;
- if ( (ctx->Color.BlendEquationRGB == modeRGB) &&
- (ctx->Color.BlendEquationA == modeA) )
+ changed = GL_FALSE;
+ for (buf = 0; buf < numBuffers; buf++) {
+ if (ctx->Color.Blend[buf].EquationRGB != modeRGB ||
+ ctx->Color.Blend[buf].EquationA != modeA) {
+ changed = GL_TRUE;
+ break;
+ }
+ }
+ if (!changed)
return;
FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.BlendEquationRGB = modeRGB;
- ctx->Color.BlendEquationA = modeA;
+ for (buf = 0; buf < numBuffers; buf++) {
+ ctx->Color.Blend[buf].EquationRGB = modeRGB;
+ ctx->Color.Blend[buf].EquationA = modeA;
+ }
+ ctx->Color._BlendEquationPerBuffer = GL_FALSE;
if (ctx->Driver.BlendEquationSeparate)
- (*ctx->Driver.BlendEquationSeparate)( ctx, modeRGB, modeA );
+ ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA);
}
-#endif
+
+
+/**
+ * Set separate blend equations for one color buffer/target.
+ */
+void
+_mesa_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glBlendEquationSeparatei %u, %s %s\n", buf,
+ _mesa_lookup_enum_by_nr(modeRGB),
+ _mesa_lookup_enum_by_nr(modeA));
+
+ if (buf >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBlendEquationSeparatei(buffer=%u)",
+ buf);
+ return;
+ }
+
+ if (!legal_blend_equation(ctx, modeRGB, GL_TRUE)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeRGB)");
+ return;
+ }
+
+ if (!legal_blend_equation(ctx, modeA, GL_TRUE)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeA)");
+ return;
+ }
+
+ if (ctx->Color.Blend[buf].EquationRGB == modeRGB &&
+ ctx->Color.Blend[buf].EquationA == modeA)
+ return; /* no change */
+
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
+ ctx->Color.Blend[buf].EquationRGB = modeRGB;
+ ctx->Color.Blend[buf].EquationA = modeA;
+ ctx->Color._BlendEquationPerBuffer = GL_TRUE;
+
+ if (ctx->Driver.BlendEquationSeparatei)
+ ctx->Driver.BlendEquationSeparatei(ctx, buf, modeRGB, modeA);
+}
+
+
+
+#endif /* _HAVE_FULL_GL */
/**
@@ -593,6 +774,8 @@
*/
void _mesa_init_color( struct gl_context * ctx )
{
+ GLuint i;
+
/* Color buffer group */
ctx->Color.IndexMask = ~0u;
memset(ctx->Color.ColorMask, 0xff, sizeof(ctx->Color.ColorMask));
@@ -602,12 +785,14 @@
ctx->Color.AlphaFunc = GL_ALWAYS;
ctx->Color.AlphaRef = 0;
ctx->Color.BlendEnabled = 0x0;
- ctx->Color.BlendSrcRGB = GL_ONE;
- ctx->Color.BlendDstRGB = GL_ZERO;
- ctx->Color.BlendSrcA = GL_ONE;
- ctx->Color.BlendDstA = GL_ZERO;
- ctx->Color.BlendEquationRGB = GL_FUNC_ADD;
- ctx->Color.BlendEquationA = GL_FUNC_ADD;
+ for (i = 0; i < Elements(ctx->Color.Blend); i++) {
+ ctx->Color.Blend[i].SrcRGB = GL_ONE;
+ ctx->Color.Blend[i].DstRGB = GL_ZERO;
+ ctx->Color.Blend[i].SrcA = GL_ONE;
+ ctx->Color.Blend[i].DstA = GL_ZERO;
+ ctx->Color.Blend[i].EquationRGB = GL_FUNC_ADD;
+ ctx->Color.Blend[i].EquationA = GL_FUNC_ADD;
+ }
ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
ctx->Color.IndexLogicOpEnabled = GL_FALSE;
ctx->Color.ColorLogicOpEnabled = GL_FALSE;
diff --git a/src/mesa/main/blend.h b/src/mesa/main/blend.h
index f72c779..39e7c9f 100644
--- a/src/mesa/main/blend.h
+++ b/src/mesa/main/blend.h
@@ -48,13 +48,30 @@
extern void GLAPIENTRY
+_mesa_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor);
+
+
+extern void GLAPIENTRY
+_mesa_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA);
+
+
+extern void GLAPIENTRY
_mesa_BlendEquation( GLenum mode );
extern void GLAPIENTRY
+_mesa_BlendEquationi(GLuint buf, GLenum mode);
+
+
+extern void GLAPIENTRY
_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA );
+extern void
+_mesa_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA);
+
+
extern void GLAPIENTRY
_mesa_BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
index 42d98a3..8fb9b4c 100644
--- a/src/mesa/main/context.h
+++ b/src/mesa/main/context.h
@@ -320,7 +320,7 @@
*/
#define RGBA_LOGICOP_ENABLED(CTX) \
((CTX)->Color.ColorLogicOpEnabled || \
- ((CTX)->Color.BlendEnabled && (CTX)->Color.BlendEquationRGB == GL_LOGIC_OP))
+ ((CTX)->Color.BlendEnabled && (CTX)->Color.Blend[0].EquationRGB == GL_LOGIC_OP))
#endif /* CONTEXT_H */
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index c62969e..2eede42 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -635,10 +635,15 @@
void (*BlendColor)(struct gl_context *ctx, const GLfloat color[4]);
/** Set the blend equation */
void (*BlendEquationSeparate)(struct gl_context *ctx, GLenum modeRGB, GLenum modeA);
+ void (*BlendEquationSeparatei)(struct gl_context *ctx, GLuint buffer,
+ GLenum modeRGB, GLenum modeA);
/** Specify pixel arithmetic */
void (*BlendFuncSeparate)(struct gl_context *ctx,
GLenum sfactorRGB, GLenum dfactorRGB,
GLenum sfactorA, GLenum dfactorA);
+ void (*BlendFuncSeparatei)(struct gl_context *ctx, GLuint buffer,
+ GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA);
/** Specify clear values for the color buffers */
void (*ClearColor)(struct gl_context *ctx, const GLfloat color[4]);
/** Specify the clear value for the depth buffer */
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 2440499..8ca1339 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -80,6 +80,7 @@
{ "GL_ARB_depth_clamp", o(ARB_depth_clamp), GL },
{ "GL_ARB_depth_texture", o(ARB_depth_texture), GL },
{ "GL_ARB_draw_buffers", o(ARB_draw_buffers), GL },
+ { "GL_ARB_draw_buffers_blend", o(ARB_draw_buffers_blend), GL },
{ "GL_ARB_draw_elements_base_vertex", o(ARB_draw_elements_base_vertex), GL },
{ "GL_ARB_draw_instanced", o(ARB_draw_instanced), GL },
{ "GL_ARB_explicit_attrib_location", o(ARB_explicit_attrib_location), GL },
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index ba273ce..6f47eca 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -372,7 +372,7 @@
API_OPENGL_BIT | API_OPENGLES_BIT | API_OPENGLES2_BIT, NO_EXTRA},
{ GL_ALPHA_BITS, BUFFER_INT(Visual.alphaBits), extra_new_buffers },
{ GL_BLEND, CONTEXT_BIT0(Color.BlendEnabled), NO_EXTRA },
- { GL_BLEND_SRC, CONTEXT_ENUM(Color.BlendSrcRGB), NO_EXTRA },
+ { GL_BLEND_SRC, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA },
{ GL_BLUE_BITS, BUFFER_INT(Visual.blueBits), extra_new_buffers },
{ GL_COLOR_CLEAR_VALUE, CONTEXT_FIELD(Color.ClearColor[0], TYPE_FLOATN_4), NO_EXTRA },
{ GL_COLOR_WRITEMASK, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
@@ -435,15 +435,15 @@
extra_ARB_texture_cube_map }, /* XXX: OES_texture_cube_map */
/* XXX: OES_blend_subtract */
- { GL_BLEND_SRC_RGB_EXT, CONTEXT_ENUM(Color.BlendSrcRGB), NO_EXTRA },
- { GL_BLEND_DST_RGB_EXT, CONTEXT_ENUM(Color.BlendDstRGB), NO_EXTRA },
- { GL_BLEND_SRC_ALPHA_EXT, CONTEXT_ENUM(Color.BlendSrcA), NO_EXTRA },
- { GL_BLEND_DST_ALPHA_EXT, CONTEXT_ENUM(Color.BlendDstA), NO_EXTRA },
+ { GL_BLEND_SRC_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA },
+ { GL_BLEND_DST_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
+ { GL_BLEND_SRC_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].SrcA), NO_EXTRA },
+ { GL_BLEND_DST_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].DstA), NO_EXTRA },
/* GL_BLEND_EQUATION_RGB, which is what we're really after, is
* defined identically to GL_BLEND_EQUATION. */
- { GL_BLEND_EQUATION, CONTEXT_ENUM(Color.BlendEquationRGB), NO_EXTRA },
- { GL_BLEND_EQUATION_ALPHA_EXT, CONTEXT_ENUM(Color.BlendEquationA), NO_EXTRA },
+ { GL_BLEND_EQUATION, CONTEXT_ENUM(Color.Blend[0].EquationRGB), NO_EXTRA },
+ { GL_BLEND_EQUATION_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].EquationA), NO_EXTRA },
/* GL_ARB_texture_compression */
{ GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
@@ -512,7 +512,7 @@
{ GL_ALPHA_TEST, CONTEXT_BOOL(Color.AlphaEnabled), NO_EXTRA },
{ GL_ALPHA_TEST_FUNC, CONTEXT_ENUM(Color.AlphaFunc), NO_EXTRA },
{ GL_ALPHA_TEST_REF, CONTEXT_FIELD(Color.AlphaRef, TYPE_FLOATN), NO_EXTRA },
- { GL_BLEND_DST, CONTEXT_ENUM(Color.BlendDstRGB), NO_EXTRA },
+ { GL_BLEND_DST, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
{ GL_CLIP_PLANE0, CONTEXT_BIT0(Transform.ClipPlanesEnabled), NO_EXTRA },
{ GL_CLIP_PLANE1, CONTEXT_BIT1(Transform.ClipPlanesEnabled), NO_EXTRA },
{ GL_CLIP_PLANE2, CONTEXT_BIT2(Transform.ClipPlanesEnabled), NO_EXTRA },
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 7b4c116..55c5fd2 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -719,13 +719,20 @@
*/
/*@{*/
GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */
- GLenum BlendSrcRGB; /**< Blending source operator */
- GLenum BlendDstRGB; /**< Blending destination operator */
- GLenum BlendSrcA; /**< GL_INGR_blend_func_separate */
- GLenum BlendDstA; /**< GL_INGR_blend_func_separate */
- GLenum BlendEquationRGB; /**< Blending equation */
- GLenum BlendEquationA; /**< GL_EXT_blend_equation_separate */
GLfloat BlendColor[4]; /**< Blending color */
+ struct
+ {
+ GLenum SrcRGB; /**< RGB blend source term */
+ GLenum DstRGB; /**< RGB blend dest term */
+ GLenum SrcA; /**< Alpha blend source term */
+ GLenum DstA; /**< Alpha blend dest term */
+ GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */
+ GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */
+ } Blend[MAX_DRAW_BUFFERS];
+ /** Are the blend func terms currently different for each buffer/target? */
+ GLboolean _BlendFuncPerBuffer;
+ /** Are the blend equations currently different for each buffer/target? */
+ GLboolean _BlendEquationPerBuffer;
/*@}*/
/**
@@ -2679,6 +2686,7 @@
GLboolean ARB_depth_clamp;
GLboolean ARB_depth_texture;
GLboolean ARB_draw_buffers;
+ GLboolean ARB_draw_buffers_blend;
GLboolean ARB_draw_elements_base_vertex;
GLboolean ARB_draw_instanced;
GLboolean ARB_fragment_coord_conventions;
diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c
index a8ec4ad..8a3609e 100644
--- a/src/mesa/state_tracker/st_atom_blend.c
+++ b/src/mesa/state_tracker/st_atom_blend.c
@@ -169,13 +169,18 @@
}
/**
- * Figure out if blend enables are different per rt.
+ * Figure out if blend enables/state are different per rt.
*/
static GLboolean
blend_per_rt(struct gl_context *ctx)
{
if (ctx->Color.BlendEnabled &&
(ctx->Color.BlendEnabled != ((1 << ctx->Const.MaxDrawBuffers) - 1))) {
+ /* This can only happen if GL_EXT_draw_buffers2 is enabled */
+ return GL_TRUE;
+ }
+ if (ctx->Color._BlendFuncPerBuffer || ctx->Color._BlendEquationPerBuffer) {
+ /* this can only happen if GL_ARB_draw_buffers_blend is enabled */
return GL_TRUE;
}
return GL_FALSE;
@@ -202,7 +207,7 @@
don't happen. */
if (st->ctx->Color.ColorLogicOpEnabled ||
(st->ctx->Color.BlendEnabled &&
- st->ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) {
+ st->ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) {
/* logicop enabled */
blend->logicop_enable = 1;
blend->logicop_func = translate_logicop(st->ctx->Color.LogicOp);
@@ -213,28 +218,36 @@
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) {
+ blend->rt[i].rgb_func =
+ translate_blend(st->ctx->Color.Blend[i].EquationRGB);
+
+ if (st->ctx->Color.Blend[i].EquationRGB == GL_MIN ||
+ st->ctx->Color.Blend[i].EquationRGB == 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].rgb_src_factor =
+ translate_blend(st->ctx->Color.Blend[i].SrcRGB);
+ blend->rt[i].rgb_dst_factor =
+ translate_blend(st->ctx->Color.Blend[i].DstRGB);
}
- blend->rt[i].alpha_func = translate_blend(st->ctx->Color.BlendEquationA);
- if (st->ctx->Color.BlendEquationA == GL_MIN ||
- st->ctx->Color.BlendEquationA == GL_MAX) {
+ blend->rt[i].alpha_func =
+ translate_blend(st->ctx->Color.Blend[i].EquationA);
+
+ if (st->ctx->Color.Blend[i].EquationA == GL_MIN ||
+ st->ctx->Color.Blend[i].EquationA == 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);
+ blend->rt[i].alpha_src_factor =
+ translate_blend(st->ctx->Color.Blend[i].SrcA);
+ blend->rt[i].alpha_dst_factor =
+ translate_blend(st->ctx->Color.Blend[i].DstA);
}
}
}
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 6798675..aead592 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -438,11 +438,9 @@
ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
}
-#if 0 /* not yet */
if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) {
ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE;
}
-#endif
if (screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
#if 0 /* XXX re-enable when GLSL compiler again supports geometry shaders */
diff --git a/src/mesa/swrast/s_blend.c b/src/mesa/swrast/s_blend.c
index d61baba..7939212 100644
--- a/src/mesa/swrast/s_blend.c
+++ b/src/mesa/swrast/s_blend.c
@@ -75,10 +75,10 @@
{
GLint bytes;
- ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB == GL_ZERO);
- ASSERT(ctx->Color.BlendDstRGB == GL_ONE);
+ ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ZERO);
+ ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE);
(void) ctx;
/* just memcpy */
@@ -101,10 +101,10 @@
blend_replace(struct gl_context *ctx, GLuint n, const GLubyte mask[],
GLvoid *src, const GLvoid *dst, GLenum chanType)
{
- ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB == GL_ONE);
- ASSERT(ctx->Color.BlendDstRGB == GL_ZERO);
+ ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE);
+ ASSERT(ctx->Color.Blend[0].DstRGB == GL_ZERO);
(void) ctx;
(void) n;
(void) mask;
@@ -125,12 +125,12 @@
const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);
- ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);
- ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
ASSERT(chanType == GL_UNSIGNED_BYTE);
(void) ctx;
@@ -170,12 +170,12 @@
const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);
- ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);
- ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
ASSERT(chanType == GL_UNSIGNED_SHORT);
(void) ctx;
@@ -208,12 +208,12 @@
const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);
- ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);
- ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
+ ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
ASSERT(chanType == GL_FLOAT);
(void) ctx;
@@ -248,10 +248,10 @@
{
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.BlendSrcRGB == GL_ONE);
- ASSERT(ctx->Color.BlendDstRGB == GL_ONE);
+ ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
+ ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE);
+ ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE);
(void) ctx;
if (chanType == GL_UNSIGNED_BYTE) {
@@ -313,8 +313,8 @@
GLvoid *src, const GLvoid *dst, GLenum chanType)
{
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB == GL_MIN);
- ASSERT(ctx->Color.BlendEquationA == GL_MIN);
+ ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MIN);
+ ASSERT(ctx->Color.Blend[0].EquationA == GL_MIN);
(void) ctx;
if (chanType == GL_UNSIGNED_BYTE) {
@@ -366,8 +366,8 @@
GLvoid *src, const GLvoid *dst, GLenum chanType)
{
GLuint i;
- ASSERT(ctx->Color.BlendEquationRGB == GL_MAX);
- ASSERT(ctx->Color.BlendEquationA == GL_MAX);
+ ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MAX);
+ ASSERT(ctx->Color.Blend[0].EquationA == GL_MAX);
(void) ctx;
if (chanType == GL_UNSIGNED_BYTE) {
@@ -500,7 +500,7 @@
*/
/* Source RGB factor */
- switch (ctx->Color.BlendSrcRGB) {
+ switch (ctx->Color.Blend[0].SrcRGB) {
case GL_ZERO:
sR = sG = sB = 0.0F;
break;
@@ -570,7 +570,7 @@
}
/* Source Alpha factor */
- switch (ctx->Color.BlendSrcA) {
+ switch (ctx->Color.Blend[0].SrcA) {
case GL_ZERO:
sA = 0.0F;
break;
@@ -624,7 +624,7 @@
}
/* Dest RGB factor */
- switch (ctx->Color.BlendDstRGB) {
+ switch (ctx->Color.Blend[0].DstRGB) {
case GL_ZERO:
dR = dG = dB = 0.0F;
break;
@@ -687,7 +687,7 @@
}
/* Dest Alpha factor */
- switch (ctx->Color.BlendDstA) {
+ switch (ctx->Color.Blend[0].DstA) {
case GL_ZERO:
dA = 0.0F;
break;
@@ -738,7 +738,7 @@
}
/* compute the blended RGB */
- switch (ctx->Color.BlendEquationRGB) {
+ switch (ctx->Color.Blend[0].EquationRGB) {
case GL_FUNC_ADD:
r = Rs * sR + Rd * dR;
g = Gs * sG + Gd * dG;
@@ -775,7 +775,7 @@
}
/* compute the blended alpha */
- switch (ctx->Color.BlendEquationA) {
+ switch (ctx->Color.Blend[0].EquationA) {
case GL_FUNC_ADD:
a = As * sA + Ad * dA;
break;
@@ -907,13 +907,13 @@
_swrast_choose_blend_func(struct gl_context *ctx, GLenum chanType)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const GLenum eq = ctx->Color.BlendEquationRGB;
- const GLenum srcRGB = ctx->Color.BlendSrcRGB;
- const GLenum dstRGB = ctx->Color.BlendDstRGB;
- const GLenum srcA = ctx->Color.BlendSrcA;
- const GLenum dstA = ctx->Color.BlendDstA;
+ const GLenum eq = ctx->Color.Blend[0].EquationRGB;
+ const GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
+ const GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
+ const GLenum srcA = ctx->Color.Blend[0].SrcA;
+ const GLenum dstA = ctx->Color.Blend[0].DstA;
- if (ctx->Color.BlendEquationRGB != ctx->Color.BlendEquationA) {
+ if (ctx->Color.Blend[0].EquationRGB != ctx->Color.Blend[0].EquationA) {
swrast->BlendFunc = blend_general;
}
else if (eq == GL_MIN) {