Fix GL_MIN and GL_MAX blend equations (set blend factors accordingly). Fix errors...
authorRoland Scheidegger <rscheidegger@gmx.ch>
Fri, 14 May 2004 13:01:08 +0000 (13:01 +0000)
committerRoland Scheidegger <rscheidegger@gmx.ch>
Fri, 14 May 2004 13:01:08 +0000 (13:01 +0000)
src/mesa/drivers/dri/r200/r200_reg.h
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r200/r200_state_init.c

index 8e9126342f1ec677c031c8601ac54ada69ec052d..685fc5c0319bff4792be49102d0e5b1901d86e51 100644 (file)
@@ -69,39 +69,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define     R200_COMB_FCN_MAX                     (5  << 12)
 #define     R200_COMB_FCN_RSUB_CLAMP              (6  << 12)
 #define     R200_COMB_FCN_RSUB_NOCLAMP            (7  << 12)
-#define     R200_SRC_BLEND_GL_ZERO                (32 << 16)
-#define     R200_SRC_BLEND_GL_ONE                 (33 << 16)
-#define     R200_SRC_BLEND_GL_SRC_COLOR           (34 << 16)
-#define     R200_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16)
-#define     R200_SRC_BLEND_GL_DST_COLOR           (36 << 16)
-#define     R200_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16)
-#define     R200_SRC_BLEND_GL_SRC_ALPHA           (38 << 16)
-#define     R200_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16)
-#define     R200_SRC_BLEND_GL_DST_ALPHA           (40 << 16)
-#define     R200_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16)
-#define     R200_SRC_BLEND_GL_SRC_ALPHA_SATURATE  (42 << 16)
-#define     R200_SRC_BLEND_GL_CONST_COLOR           (43 << 16)
-#define     R200_SRC_BLEND_GL_ONE_MINUS_CONST_COLOR (44 << 16)
-#define     R200_SRC_BLEND_GL_CONST_ALPHA           (45 << 16)
-#define     R200_SRC_BLEND_GL_ONE_MINUS_CONST_ALPHA (46 << 16)
-#define     R200_SRC_BLEND_MASK                     (63 << 16)
-#define     R200_DST_BLEND_GL_ZERO                (32 << 24)
-#define     R200_DST_BLEND_GL_ONE                 (33 << 24)
-#define     R200_DST_BLEND_GL_SRC_COLOR           (34 << 24)
-#define     R200_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24)
-#define     R200_DST_BLEND_GL_DST_COLOR           (36 << 24)
-#define     R200_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24)
-#define     R200_DST_BLEND_GL_SRC_ALPHA           (38 << 24)
-#define     R200_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24)
-#define     R200_DST_BLEND_GL_DST_ALPHA           (40 << 24)
-#define     R200_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24)
-#define     R200_DST_BLEND_GL_CONST_COLOR         (43 << 24)
-#define     R200_DST_BLEND_GL_ONE_MINUS_CONST_COLOR (44 << 24)
-#define     R200_DST_BLEND_GL_CONST_ALPHA           (45 << 24)
-#define     R200_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA (46 << 24)
-#define     R200_DST_BLEND_MASK                     (63 << 24)
-#define R200_RB3D_DEPTHOFFSET             0x1c24 
-#define R200_RB3D_DEPTHPITCH              0x1c28 
+#define       R200_BLEND_GL_ZERO                  (32)
+#define       R200_BLEND_GL_ONE                   (33)
+#define       R200_BLEND_GL_SRC_COLOR             (34)
+#define       R200_BLEND_GL_ONE_MINUS_SRC_COLOR   (35)
+#define       R200_BLEND_GL_DST_COLOR             (36)
+#define       R200_BLEND_GL_ONE_MINUS_DST_COLOR   (37)
+#define       R200_BLEND_GL_SRC_ALPHA             (38)
+#define       R200_BLEND_GL_ONE_MINUS_SRC_ALPHA   (39)
+#define       R200_BLEND_GL_DST_ALPHA             (40)
+#define       R200_BLEND_GL_ONE_MINUS_DST_ALPHA   (41)
+#define       R200_BLEND_GL_SRC_ALPHA_SATURATE    (42) /* src factor only */
+#define       R200_BLEND_GL_CONST_COLOR           (43)
+#define       R200_BLEND_GL_ONE_MINUS_CONST_COLOR (44)
+#define       R200_BLEND_GL_CONST_ALPHA           (45)
+#define       R200_BLEND_GL_ONE_MINUS_CONST_ALPHA (46)
+#define       R200_BLEND_MASK                     (63)
+#define     R200_SRC_BLEND_SHIFT                  (16)
+#define     R200_DST_BLEND_SHIFT                  (24)
+#define R200_RB3D_DEPTHOFFSET             0x1c24
+#define R200_RB3D_DEPTHPITCH              0x1c28
 #define     R200_DEPTHPITCH_MASK         0x00001ff8
 #define     R200_DEPTH_ENDIAN_NO_SWAP    (0 << 18)
 #define     R200_DEPTH_ENDIAN_WORD_SWAP  (1 << 18)
index 1dd352a53d5ae52a9fd68cdaa943e24ae54a6a63..70ce8b4e0de5452945f0248837fdeb317f437bb7 100644 (file)
@@ -104,156 +104,160 @@ static void r200AlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
    rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
 }
 
-static void r200BlendEquationSeparate( GLcontext *ctx, 
-                                      GLenum modeRGB, GLenum modeA )
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~R200_COMB_FCN_MASK;
-
-   assert( modeRGB == modeA );
-
-   switch ( modeRGB ) {
-   case GL_FUNC_ADD:
-   case GL_LOGIC_OP:
-      b |= R200_COMB_FCN_ADD_CLAMP;
-      break;
-
-   case GL_FUNC_SUBTRACT:
-      b |= R200_COMB_FCN_SUB_CLAMP;
-      break;
-
-   case GL_FUNC_REVERSE_SUBTRACT:
-      b |= R200_COMB_FCN_RSUB_CLAMP;
-      break;
-
-   case GL_MIN:
-      b |= R200_COMB_FCN_MIN;
-      break;
-
-   case GL_MAX:
-      b |= R200_COMB_FCN_MAX;
-      break;
-
-   default:
-      break;
-   }
-
-   R200_STATECHANGE( rmesa, ctx );
-   rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
-   if ( ctx->Color._LogicOpEnabled ) {
-      rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_ROP_ENABLE;
-   } else {
-      rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ROP_ENABLE;
-   }
-}
-
-static void r200BlendFuncSeparate( GLcontext *ctx,
-                                    GLenum sfactorRGB, GLenum dfactorRGB,
-                                    GLenum sfactorA, GLenum dfactorA )
+/**
+ * Calculate the hardware blend factor setting.  This same function is used
+ * for source and destination of both alpha and RGB.
+ *
+ * \returns
+ * The hardware register value for the specified blend factor.  This value
+ * will need to be shifted into the correct position for either source or
+ * destination factor.
+ *
+ * \todo
+ * Since the two cases where source and destination are handled differently
+ * are essentially error cases, they should never happen.  Determine if these
+ * cases can be removed.
+ */
+static int blend_factor( GLenum factor, GLboolean is_src )
 {
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & 
-      ~(R200_SRC_BLEND_MASK | R200_DST_BLEND_MASK);
+   int func;
 
-   switch ( ctx->Color.BlendSrcRGB ) {
+   switch ( factor ) {
    case GL_ZERO:
-      b |= R200_SRC_BLEND_GL_ZERO;
+      func = R200_BLEND_GL_ZERO;
       break;
    case GL_ONE:
-      b |= R200_SRC_BLEND_GL_ONE;
+      func = R200_BLEND_GL_ONE;
       break;
    case GL_DST_COLOR:
-      b |= R200_SRC_BLEND_GL_DST_COLOR;
+      func = R200_BLEND_GL_DST_COLOR;
       break;
    case GL_ONE_MINUS_DST_COLOR:
-      b |= R200_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
+      func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
       break;
    case GL_SRC_COLOR:
-      b |= R200_SRC_BLEND_GL_SRC_COLOR;
+      func = R200_BLEND_GL_SRC_COLOR;
       break;
    case GL_ONE_MINUS_SRC_COLOR:
-      b |= R200_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR;
+      func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
       break;
    case GL_SRC_ALPHA:
-      b |= R200_SRC_BLEND_GL_SRC_ALPHA;
+      func = R200_BLEND_GL_SRC_ALPHA;
       break;
    case GL_ONE_MINUS_SRC_ALPHA:
-      b |= R200_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
+      func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
       break;
    case GL_DST_ALPHA:
-      b |= R200_SRC_BLEND_GL_DST_ALPHA;
+      func = R200_BLEND_GL_DST_ALPHA;
       break;
    case GL_ONE_MINUS_DST_ALPHA:
-      b |= R200_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
+      func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
       break;
    case GL_SRC_ALPHA_SATURATE:
-      b |= R200_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
+      func = (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE : R200_BLEND_GL_ZERO;
       break;
    case GL_CONSTANT_COLOR:
-      b |= R200_SRC_BLEND_GL_CONST_COLOR;
+      func = R200_BLEND_GL_CONST_COLOR;
       break;
    case GL_ONE_MINUS_CONSTANT_COLOR:
-      b |= R200_SRC_BLEND_GL_ONE_MINUS_CONST_COLOR;
+      func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
       break;
    case GL_CONSTANT_ALPHA:
-      b |= R200_SRC_BLEND_GL_CONST_ALPHA;
+      func = R200_BLEND_GL_CONST_ALPHA;
       break;
    case GL_ONE_MINUS_CONSTANT_ALPHA:
-      b |= R200_SRC_BLEND_GL_ONE_MINUS_CONST_ALPHA;
+      func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
       break;
    default:
-      break;
+      func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
    }
+   return func;
+}
 
-   switch ( ctx->Color.BlendDstRGB ) {
-   case GL_ZERO:
-      b |= R200_DST_BLEND_GL_ZERO;
-      break;
-   case GL_ONE:
-      b |= R200_DST_BLEND_GL_ONE;
-      break;
-   case GL_SRC_COLOR:
-      b |= R200_DST_BLEND_GL_SRC_COLOR;
-      break;
-   case GL_ONE_MINUS_SRC_COLOR:
-      b |= R200_DST_BLEND_GL_ONE_MINUS_SRC_COLOR;
-      break;
-   case GL_SRC_ALPHA:
-      b |= R200_DST_BLEND_GL_SRC_ALPHA;
-      break;
-   case GL_ONE_MINUS_SRC_ALPHA:
-      b |= R200_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
-      break;
-   case GL_DST_COLOR:
-      b |= R200_DST_BLEND_GL_DST_COLOR;
-      break;
-   case GL_ONE_MINUS_DST_COLOR:
-      b |= R200_DST_BLEND_GL_ONE_MINUS_DST_COLOR;
-      break;
-   case GL_DST_ALPHA:
-      b |= R200_DST_BLEND_GL_DST_ALPHA;
-      break;
-   case GL_ONE_MINUS_DST_ALPHA:
-      b |= R200_DST_BLEND_GL_ONE_MINUS_DST_ALPHA;
+/**
+ * Sets both the blend equation and the blend function.
+ * This is done in a single
+ * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
+ * change the interpretation of the blend function.
+ * Also, make sure that blend function and blend equation are set to their default
+ * value if color blending is not enabled, since at least blend equations GL_MIN
+ * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
+ * unknown reasons.
+ */
+static void r200_set_blend_state( GLcontext * ctx )
+{
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+   GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
+      ~(R200_ROP_ENABLE | R200_ALPHA_BLEND_ENABLE);
+
+   int func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
+      (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
+   int eqn = R200_COMB_FCN_ADD_CLAMP;
+
+   R200_STATECHANGE( rmesa, ctx );
+
+   if (ctx->Color._LogicOpEnabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ROP_ENABLE;
+      rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
+      return;
+   } else if (ctx->Color.BlendEnabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ALPHA_BLEND_ENABLE;
+   }
+   else {
+      rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
+      rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
+      return;
+   }
+
+   func = (blend_factor( ctx->Color.BlendSrcRGB, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
+      (blend_factor( ctx->Color.BlendDstRGB, GL_FALSE ) << R200_DST_BLEND_SHIFT);
+
+   switch(ctx->Color.BlendEquationRGB) {
+   case GL_FUNC_ADD:
+   case GL_LOGIC_OP:
+      eqn = R200_COMB_FCN_ADD_CLAMP;
       break;
-   case GL_CONSTANT_COLOR:
-      b |= R200_DST_BLEND_GL_CONST_COLOR;
+
+   case GL_FUNC_SUBTRACT:
+      eqn = R200_COMB_FCN_SUB_CLAMP;
       break;
-   case GL_ONE_MINUS_CONSTANT_COLOR:
-      b |= R200_DST_BLEND_GL_ONE_MINUS_CONST_COLOR;
+
+   case GL_FUNC_REVERSE_SUBTRACT:
+      eqn = R200_COMB_FCN_RSUB_CLAMP;
       break;
-   case GL_CONSTANT_ALPHA:
-      b |= R200_DST_BLEND_GL_CONST_ALPHA;
+
+   case GL_MIN:
+      eqn = R200_COMB_FCN_MIN;
+      func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
+         (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
       break;
-   case GL_ONE_MINUS_CONSTANT_ALPHA:
-      b |= R200_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA;
+
+   case GL_MAX:
+      eqn = R200_COMB_FCN_MAX;
+      func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
+         (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
       break;
+
    default:
-      break;
+      fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
+         __func__, __LINE__, ctx->Color.BlendEquationRGB );
+      return;
    }
 
-   R200_STATECHANGE( rmesa, ctx );
-   rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
+   rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
+}
+
+static void r200BlendEquationSeparate( GLcontext *ctx,
+                                      GLenum modeRGB, GLenum modeA )
+{
+      r200_set_blend_state( ctx );
+}
+
+static void r200BlendFuncSeparate( GLcontext *ctx,
+                                    GLenum sfactorRGB, GLenum dfactorRGB,
+                                    GLenum sfactorA, GLenum dfactorA )
+{
+      r200_set_blend_state( ctx );
 }
 
 
@@ -1738,17 +1742,8 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state )
       break;
 
    case GL_BLEND:
-      R200_STATECHANGE( rmesa, ctx );
-      if (state) {
-        rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_ALPHA_BLEND_ENABLE;
-      } else {
-        rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ALPHA_BLEND_ENABLE;
-      }
-      if ( ctx->Color._LogicOpEnabled ) {
-        rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_ROP_ENABLE;
-      } else {
-        rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ROP_ENABLE;
-      }
+   case GL_COLOR_LOGIC_OP:
+      r200_set_blend_state( ctx );
       break;
 
    case GL_CLIP_PLANE0:
@@ -1864,15 +1859,6 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state )
       }
       break;
 
-   case GL_COLOR_LOGIC_OP:
-      R200_STATECHANGE( rmesa, ctx );
-      if ( ctx->Color._LogicOpEnabled ) {
-        rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_ROP_ENABLE;
-      } else {
-        rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ROP_ENABLE;
-      }
-      break;
-      
    case GL_NORMALIZE:
       R200_STATECHANGE( rmesa, tcl );
       if ( state ) {
index d9896c99dbc4ee5b906663756e5249d24177c8f3..4e073f2fc52458c30d85903184861a38ffebe1d7 100644 (file)
@@ -367,8 +367,8 @@ void r200InitState( r200ContextPtr rmesa )
    rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000;
 
    rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = (R200_COMB_FCN_ADD_CLAMP |
-                                           R200_SRC_BLEND_GL_ONE |
-                                           R200_DST_BLEND_GL_ZERO );
+                                           (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
+                                           (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT));
 
    rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHOFFSET] =
       rmesa->r200Screen->depthOffset + rmesa->r200Screen->fbLocation;