mesa: begin implementation of GL_ARB_draw_buffers_blend
authorBrian Paul <brianp@vmware.com>
Tue, 11 Jan 2011 22:07:38 +0000 (15:07 -0700)
committerBrian Paul <brianp@vmware.com>
Sun, 16 Jan 2011 01:35:39 +0000 (18:35 -0700)
31 files changed:
src/mesa/drivers/common/driverfuncs.c
src/mesa/drivers/dri/i810/i810state.c
src/mesa/drivers/dri/i915/i830_state.c
src/mesa/drivers/dri/i915/i915_state.c
src/mesa/drivers/dri/i965/brw_cc.c
src/mesa/drivers/dri/i965/gen6_cc.c
src/mesa/drivers/dri/intel/intel_pixel.c
src/mesa/drivers/dri/mach64/mach64_state.c
src/mesa/drivers/dri/mga/mgastate.c
src/mesa/drivers/dri/nouveau/nv04_state_raster.c
src/mesa/drivers/dri/nouveau/nv10_state_raster.c
src/mesa/drivers/dri/r128/r128_state.c
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r600/evergreen_state.c
src/mesa/drivers/dri/r600/r700_state.c
src/mesa/drivers/dri/radeon/radeon_state.c
src/mesa/drivers/dri/savage/savagestate.c
src/mesa/drivers/dri/tdfx/tdfx_state.c
src/mesa/drivers/dri/unichrome/via_state.c
src/mesa/main/attrib.c
src/mesa/main/blend.c
src/mesa/main/blend.h
src/mesa/main/context.h
src/mesa/main/dd.h
src/mesa/main/extensions.c
src/mesa/main/get.c
src/mesa/main/mtypes.h
src/mesa/state_tracker/st_atom_blend.c
src/mesa/state_tracker/st_extensions.c
src/mesa/swrast/s_blend.c

index fc67bee98c6faa9fd7d93144b2f49090f44bbc4a..3c6ecb83f0aa18cbc1f7dd78da0160e8a2a19784 100644 (file)
@@ -231,13 +231,14 @@ _mesa_init_driver_state(struct gl_context *ctx)
    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;
index 7c3fbb1424d6534bb4ccdeab3c65169985bfacc0..6040abf7fac40e73a55782e2095cfb2c7c519b16 100644 (file)
@@ -95,7 +95,7 @@ static void i810BlendFuncSeparate( struct gl_context *ctx, GLenum sfactorRGB,
    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 @@ static void i810BlendFuncSeparate( struct gl_context *ctx, GLenum sfactorRGB,
       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;
index 147192adc7a72ef9eb9a24436ee72995c6c74947..ef5b8d971da21e345240c9ceb7a57e80e351ae3c 100644 (file)
@@ -291,10 +291,10 @@ i830_set_blend_state(struct gl_context * ctx)
 
 
    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 @@ i830_set_blend_state(struct gl_context * ctx)
       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 @@ i830_set_blend_state(struct gl_context * ctx)
       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;
    }
 
index 9508fbaf9426e5f3e421981a4f4fc9991cc48c79..63c6e78ebe979af0a9c0ec64859d27fa59517ad3 100644 (file)
@@ -267,12 +267,12 @@ i915UpdateBlendState(struct gl_context * ctx)
                   ~(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;
index d286c9dbdc719efaf9085881db10a08512ba102b..c986970a757d9ab9aa4906140d0ed2040a1f79d4 100644 (file)
@@ -141,12 +141,12 @@ static void upload_cc_unit(struct brw_context *brw)
       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
index dbcdc5b86936ddc7687dfc9d4c702b48e81572a9..f51afa40716d4675038775fc4ad84d54070289d5 100644 (file)
@@ -66,12 +66,12 @@ blend_state_populate_key(struct brw_context *brw,
    /* _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 */
index d5c35775ce4a4409b92970cb6a7713c01ae2a1e7..f97256e59bb455a389a46fd94841bd5b0927ad85 100644 (file)
@@ -66,12 +66,12 @@ intel_check_blit_fragment_ops(struct gl_context * ctx, GLboolean src_alpha_is_on
    }
 
    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;
    }
index 8e795955c2cdebc9ea0bb33ff569698e1889b288..c1a4e63204f7ddfeddd4ec8c3559e0d953cc134c 100644 (file)
@@ -102,7 +102,7 @@ static void mach64UpdateAlphaMode( struct gl_context *ctx )
             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 @@ static void mach64UpdateAlphaMode( struct gl_context *ctx )
          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;
index 25d7de28fe8380c452e8a4d881c884b20e0c245c..2fac2b49cd2e69e68d29cd4a39fa387865067bda 100644 (file)
@@ -141,7 +141,7 @@ static void mgaDDBlendFuncSeparate( struct gl_context *ctx, GLenum sfactorRGB,
    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 @@ static void mgaDDBlendFuncSeparate( struct gl_context *ctx, GLenum sfactorRGB,
       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:
index 98f2f98f1d0f9b48353dbe7dfc76fc47ee8f2244..ecfbdfedff6641391bbe94f48fdfbab7ccd94917 100644 (file)
@@ -264,8 +264,8 @@ nv04_emit_blend(struct gl_context *ctx, int emit)
                        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_emit_blend(struct gl_context *ctx, int emit)
                        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;
index bb1084ed11b04263da42cd949b74be082b31a466..50021b0a7bf7b2244cfacb4ca31309b855539217 100644 (file)
@@ -68,7 +68,7 @@ nv10_emit_blend_equation(struct gl_context *ctx, int emit)
        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 @@ nv10_emit_blend_func(struct gl_context *ctx, int emit)
        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
index 4a49e8fc70f1aa5a6a806729614ec2668ffdec7b..d6725cdd0ecf80b79dff3bc6e24077906366fd1c 100644 (file)
@@ -178,12 +178,12 @@ static void r128UpdateAlphaMode( struct gl_context *ctx )
             (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;
index b523edcb5d9a83cd478f6e1e1a6dfc9c275d85a4..0a1e0b4757751306020ac8755550d99cc84a4954 100644 (file)
@@ -245,10 +245,10 @@ static void r200_set_blend_state( struct gl_context * ctx )
       }
    }
 
-   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 @@ static void r200_set_blend_state( struct gl_context * ctx )
 
    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 @@ static void r200_set_blend_state( struct gl_context * ctx )
       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 @@ static void r200_set_blend_state( struct gl_context * ctx )
 
    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;
    }
 
index ab8c1df5f748bc6c765abd09144567ee072d41e1..9df9101bcd3cc30fb6a5e4fc0a50419303efb3c6 100644 (file)
@@ -220,12 +220,12 @@ static void r300SetBlendState(struct gl_context * ctx)
        }
 
        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 @@ static void r300SetBlendState(struct gl_context * ctx)
        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 @@ static void r300SetBlendState(struct gl_context * ctx)
        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;
        }
 
index 648cda0078e242cc50bdeee53cddcd90d55dee3a..006e50007b6895ad8cb66cc0db2710e161ad78d6 100644 (file)
@@ -363,13 +363,13 @@ static void evergreenSetBlendState(struct gl_context * ctx) //diff : CB_COLOR_CO
        }
 
        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 @@ static void evergreenSetBlendState(struct gl_context * ctx) //diff : CB_COLOR_CO
        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 @@ static void evergreenSetBlendState(struct gl_context * ctx) //diff : CB_COLOR_CO
        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;
        }
 
index bd04a633b48d50f381198f49e3b3d7cbd8f1280d..f8770690ff60d01b483e8cef03c9af0274c2193f 100644 (file)
@@ -474,13 +474,13 @@ static void r700SetBlendState(struct gl_context * ctx)
        }
 
        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 @@ static void r700SetBlendState(struct gl_context * ctx)
        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 @@ static void r700SetBlendState(struct gl_context * ctx)
        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;
        }
 
index cae12f192c346ad625508b862e4396e40f30208b..ca42aa3947464cc6c41cb499b568f9746a761956 100644 (file)
@@ -136,7 +136,7 @@ static void radeonBlendEquationSeparate( struct gl_context *ctx,
       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 @@ static void radeonBlendFuncSeparate( struct gl_context *ctx,
       ~(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 @@ static void radeonBlendFuncSeparate( struct gl_context *ctx,
       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 @@ static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
         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 @@ static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
        */
       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 @@ static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
    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;
index 0906f85b1fa5c93427a8ebd69aeb8db066a02b0b..1feffa0b0a299423043dc278fed8070a9fec52ea 100644 (file)
@@ -136,7 +136,7 @@ static void savageBlendFunc_s4(struct gl_context *ctx)
      * 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 @@ static void savageBlendFunc_s4(struct gl_context *ctx)
                 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 @@ static void savageBlendFunc_s3d(struct gl_context *ctx)
      * 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 @@ static void savageBlendFunc_s3d(struct gl_context *ctx)
                 break;
         }
 
-        switch (ctx->Color.BlendSrcRGB)
+        switch (ctx->Color.Blend[0].SrcRGB)
         {
             case GL_ZERO:
                 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_Zero;
index 3f6822d4574d31d2ad448256c8cf161400c29b61..b26b2c710b910457dac92d9b3f46dbf7dd0a494a 100644 (file)
@@ -84,7 +84,7 @@ static void tdfxUpdateAlphaMode( struct gl_context *ctx )
 
    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 @@ static void tdfxUpdateAlphaMode( struct gl_context *ctx )
         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 @@ static void tdfxUpdateAlphaMode( struct gl_context *ctx )
         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 @@ static void tdfxUpdateAlphaMode( struct gl_context *ctx )
         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 @@ static void tdfxUpdateAlphaMode( struct gl_context *ctx )
         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 @@ static void tdfxUpdateAlphaMode( struct gl_context *ctx )
         break;
       }
 
-      switch ( ctx->Color.BlendEquationA ) {
+      switch ( ctx->Color.Blend[0].EquationA ) {
       case GL_FUNC_SUBTRACT:
         eqA = GR_BLEND_OP_SUB;
         break;
index 033352188d4da4a6cc2abe9742cbb38d1189f628..774f439bfb6c46471d16b5611162c91b4c8cc75e 100644 (file)
@@ -552,7 +552,7 @@ static void viaBlendFunc(struct gl_context *ctx, GLenum sfactor, GLenum dfactor)
     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 @@ static void viaBlendFunc(struct gl_context *ctx, GLenum sfactor, GLenum dfactor)
         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 @@ void viaInitState(struct gl_context *ctx)
     */
 
    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 GLboolean viaChooseTextureState(struct gl_context *ctx)
 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
index adfec3b0d5a9cf9d6e65a9d1a615159186ef02da..7fd1287368fa3e3c92d312195e29104fc0042d7e 100644 (file)
@@ -954,20 +954,39 @@ _mesa_PopAttrib(void)
                      _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],
index ec778b7244dd8968f92aaf11248a14502db1a2e1..43e2f7f8617518ca043c60b414891123ac229cff 100644 (file)
 #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 @@ _mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
 
 
 /**
- * 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_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
                   _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:
+   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].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 (dfactorRGB)");
-         return;
+      }
    }
+   if (!changed)
+      return;
 
-   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:
-         break;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)");
-         return;
+   FLUSH_VERTICES(ctx, _NEW_COLOR);
+
+   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;
 
-   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->Driver.BlendFuncSeparate) {
+      ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB,
+                                    sfactorA, dfactorA);
    }
+}
+
 
-   if (ctx->Color.BlendSrcRGB == sfactorRGB &&
-       ctx->Color.BlendDstRGB == dfactorRGB &&
-       ctx->Color.BlendSrcA == sfactorA &&
-       ctx->Color.BlendDstA == dfactorA)
+#if _HAVE_FULL_GL
+
+
+/**
+ * Set blend source/dest factors for one color buffer/target.
+ */
+void GLAPIENTRY
+_mesa_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
+{
+   _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;
+   }
+
+   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.BlendSrcRGB = sfactorRGB;
-   ctx->Color.BlendDstRGB = dfactorRGB;
-   ctx->Color.BlendSrcA = sfactorA;
-   ctx->Color.BlendDstA = dfactorA;
+   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.BlendFuncSeparate) {
-      (*ctx->Driver.BlendFuncSeparate)( ctx, sfactorRGB, dfactorRGB,
-                                       sfactorA, dfactorA );
+   if (ctx->Driver.BlendFuncSeparatei) {
+      ctx->Driver.BlendFuncSeparatei(ctx, buf, sfactorRGB, dfactorRGB,
+                                     sfactorA, dfactorA);
    }
 }
 
 
-#if _HAVE_FULL_GL
-
+/**
+ * Check if given blend equation is legal.
+ * \return GL_TRUE if legal, GL_FALSE otherwise.
+ */
 static GLboolean
-_mesa_validate_blend_equation( struct gl_context *ctx,
-                              GLenum mode, GLboolean is_separate )
+legal_blend_equation(const struct gl_context *ctx,
+                     GLenum mode, GLboolean is_separate)
 {
    switch (mode) {
-      case GL_FUNC_ADD:
-         break;
-      case GL_MIN:
-      case GL_MAX:
-         if (!ctx->Extensions.EXT_blend_minmax) {
-            return GL_FALSE;
-         }
-         break;
+   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.
        */
-      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;
+      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;
    }
-
-   return GL_TRUE;
 }
 
 
@@ -244,6 +311,8 @@ _mesa_validate_blend_equation( struct gl_context *ctx,
 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_BlendEquation( GLenum mode )
       _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 @@ _mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA )
       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 @@ _mesa_ClampColorARB(GLenum target, GLenum clamp)
  */
 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 @@ void _mesa_init_color( struct gl_context * ctx )
    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;
index f72c779f1aa962cecc8498dfc8c558485ea0282b..39e7c9fd49b717315a40dbabbd2362315275b7a7 100644 (file)
@@ -47,14 +47,31 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
                             GLenum sfactorA, GLenum dfactorA );
 
 
+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);
 
index 42d98a33a8d6684f911b69827da6752cd9496c05..8fb9b4c6b7a6a99aae843bd91b7e0e1ac63e0619 100644 (file)
@@ -320,7 +320,7 @@ do {                                                                        \
  */
 #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 */
index c62969e9b7ecca0d14cc8b0cb76d1d3cb248c9c2..2eede4268ca68b9a0c62195c3b207a1bd0048b8c 100644 (file)
@@ -635,10 +635,15 @@ struct dd_function_table {
    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 */
index 24404993c69f4e0a9170246b6fffc20904679427..8ca1339c66a6c437dcbfe724f0f9b57c7f263cd6 100644 (file)
@@ -80,6 +80,7 @@ static const struct extension extension_table[] = {
    { "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             },
index ba273cef46130f4cd2713401018746f5ac96117c..6f47eca28cc92dac370ade59cc4b4ebd914707a2 100644 (file)
@@ -372,7 +372,7 @@ static const struct value_desc values[] = {
      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 @@ static const struct value_desc values[] = {
      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 @@ static const struct value_desc values[] = {
    { 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 },
index 7b4c1161f5af47b562d9ba96f4ae0def67da71c5..55c5fd2b84908c4ed27dd4bc5c75dcfd5ddda777 100644 (file)
@@ -719,13 +719,20 @@ struct gl_colorbuffer_attrib
     */
    /*@{*/
    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 @@ struct gl_extensions
    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;
index a8ec4adce775b92a37e22f53af8e7532c79c8c5c..8a3609e569f48f9d6c2cfc82cefe75e355bb2016 100644 (file)
@@ -169,13 +169,18 @@ colormask_per_rt(struct gl_context *ctx)
 }
 
 /**
- * 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 @@ update_blend( struct st_context *st )
       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 @@ update_blend( struct st_context *st )
 
          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);
          }
       }
    }
index 6798675fb89925a97385ed8cecca06383cb76777..aead59271025af79a4a5d5d644a18800252d2e23 100644 (file)
@@ -438,11 +438,9 @@ void st_init_extensions(struct st_context *st)
       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 */
index d61baba0f33bbcf944cacb19fc75afe2e6e7bb0f..793921250ad874c23a70ce1ec704f52673e82a91 100644 (file)
@@ -75,10 +75,10 @@ blend_noop(struct gl_context *ctx, GLuint n, const GLubyte mask[],
 {
    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 @@ static void _BLENDAPI
 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 @@ blend_transparency_ubyte(struct gl_context *ctx, GLuint n, const GLubyte mask[],
    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 @@ blend_transparency_ushort(struct gl_context *ctx, GLuint n, const GLubyte mask[]
    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 @@ blend_transparency_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
    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 @@ blend_add(struct gl_context *ctx, GLuint n, const GLubyte mask[],
 {
    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 @@ blend_min(struct gl_context *ctx, GLuint n, const GLubyte mask[],
           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 @@ blend_max(struct gl_context *ctx, GLuint n, const GLubyte mask[],
           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 @@ blend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
           */
 
          /* 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 @@ blend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
          }
 
          /* Source Alpha factor */
-         switch (ctx->Color.BlendSrcA) {
+         switch (ctx->Color.Blend[0].SrcA) {
             case GL_ZERO:
                sA = 0.0F;
                break;
@@ -624,7 +624,7 @@ blend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
          }
 
          /* 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 @@ blend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
          }
 
          /* Dest Alpha factor */
-         switch (ctx->Color.BlendDstA) {
+         switch (ctx->Color.Blend[0].DstA) {
             case GL_ZERO:
                dA = 0.0F;
                break;
@@ -738,7 +738,7 @@ blend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
          }
 
          /* 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 @@ blend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
          }
 
          /* 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 @@ void
 _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) {