fix GL_LINE_LOOP with drivers using own render pipeline stage (#12410, #13527)
[mesa.git] / src / mesa / drivers / dri / mga / mgastate.c
index 0d304966d7e43bcb8796ba159315936fe94ae81b..88f2175cc3e45ef3ad3008991513b3756814fdfb 100644 (file)
@@ -24,7 +24,6 @@
  * Authors:
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
-/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.13 2002/10/30 12:51:36 alanh Exp $ */
 
 
 #include "mtypes.h"
 #include "mgaregs.h"
 
 #include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
 #include "tnl/tnl.h"
 #include "tnl/t_context.h"
 #include "tnl/t_pipeline.h"
 #include "swrast_setup/swrast_setup.h"
 
+#include "xmlpool.h"
+#include "drirenderbuffer.h"
 
-static void updateSpecularLighting( GLcontext *ctx );
 
+static void updateSpecularLighting( GLcontext *ctx );
 
-/* Some outstanding problems with accelerating logic ops...
- */
-#if defined(ACCEL_ROP)
 static const GLuint mgarop_NoBLK[16] = {
    DC_atype_rpl  | 0x00000000, DC_atype_rstr | 0x00080000,
    DC_atype_rstr | 0x00040000, DC_atype_rpl  | 0x000c0000,
@@ -65,8 +63,6 @@ static const GLuint mgarop_NoBLK[16] = {
    DC_atype_rpl  | 0x00030000, DC_atype_rstr | 0x000b0000,
    DC_atype_rstr | 0x00070000, DC_atype_rpl  | 0x000f0000
 };
-#endif
-
 
 /* =============================================================
  * Alpha blending
@@ -111,27 +107,37 @@ static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
       break;
    }
 
-   FLUSH_BATCH( mmesa );
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
    mmesa->hw.alpha_func = a | MGA_FIELD( AC_atref, refByte );
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
 }
 
-static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode)
+static void updateBlendLogicOp(GLcontext *ctx)
 {
-   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLboolean logicOp = RGBA_LOGICOP_ENABLED(ctx);
 
-   /* BlendEquation sets ColorLogicOpEnabled in an unexpected 
-    * manner.  
-    */
-   FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
-            (ctx->Color.ColorLogicOpEnabled && 
-             ctx->Color.LogicOp != GL_COPY));
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
+
+   mmesa->hw.blend_func_enable =
+      (ctx->Color.BlendEnabled && !logicOp) ? ~0 : 0;
+
+   FALLBACK( ctx, MGA_FALLBACK_BLEND,
+             ctx->Color.BlendEnabled && !logicOp &&
+             mmesa->hw.blend_func == (AC_src_src_alpha_sat | AC_dst_zero) );
 }
 
-static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+static void mgaDDBlendEquationSeparate(GLcontext *ctx, 
+                                      GLenum modeRGB, GLenum modeA)
+{
+   assert( modeRGB == modeA );
+   updateBlendLogicOp( ctx );
+}
+
+static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
+                                   GLenum dfactorRGB, GLenum sfactorA,
+                                   GLenum dfactorA )
 {
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
-   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
    GLuint   src;
    GLuint   dst;
 
@@ -150,11 +156,11 @@ static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
    case GL_ONE_MINUS_SRC_ALPHA:
       src = AC_src_om_src_alpha; break;
    case GL_DST_ALPHA:
-      src = (mgaScreen->cpp == 4) 
+      src = (ctx->Visual.alphaBits > 0)
          ? AC_src_dst_alpha : AC_src_one;
       break;
    case GL_ONE_MINUS_DST_ALPHA:
-      src = (mgaScreen->cpp == 4)
+      src = (ctx->Visual.alphaBits > 0)
          ? AC_src_om_dst_alpha : AC_src_zero;
       break;
    case GL_SRC_ALPHA_SATURATE:
@@ -178,28 +184,23 @@ static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
    case GL_ONE_MINUS_SRC_COLOR:
       dst = AC_dst_om_src_color; break;
    case GL_DST_ALPHA:
-      dst = (mgaScreen->cpp == 4)
+      dst = (ctx->Visual.alphaBits > 0)
          ? AC_dst_dst_alpha : AC_dst_one;
       break;
    case GL_ONE_MINUS_DST_ALPHA:
-      dst = (mgaScreen->cpp == 4)
+      dst = (ctx->Visual.alphaBits > 0)
          ? AC_dst_om_dst_alpha : AC_dst_zero;
       break;
    }
 
-   FLUSH_BATCH( mmesa );
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
    mmesa->hw.blend_func = (src | dst);
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
-}
 
-static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
-                                   GLenum dfactorRGB, GLenum sfactorA,
-                                   GLenum dfactorA )
-{
-   mgaDDBlendFunc( ctx, sfactorRGB, dfactorRGB );
+   FALLBACK( ctx, MGA_FALLBACK_BLEND,
+             ctx->Color.BlendEnabled && !RGBA_LOGICOP_ENABLED(ctx) &&
+             mmesa->hw.blend_func == (AC_src_src_alpha_sat | AC_dst_zero) );
 }
 
-
 /* =============================================================
  * Depth testing
  */
@@ -233,10 +234,9 @@ static void mgaDDDepthFunc(GLcontext *ctx, GLenum func)
       zmode = 0; break;
    }
 
-   FLUSH_BATCH( mmesa );
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
    mmesa->hw.zmode &= DC_zmode_MASK;
    mmesa->hw.zmode |= zmode;
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
 }
 
 static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag)
@@ -244,10 +244,9 @@ static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag)
    mgaContextPtr mmesa = MGA_CONTEXT( ctx );
 
 
-   FLUSH_BATCH( mmesa );
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
    mmesa->hw.zmode &= DC_atype_MASK;
    mmesa->hw.zmode |= (flag) ? DC_atype_zi : DC_atype_i;
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
 }
 
 
@@ -302,8 +301,8 @@ void mgaUpdateClipping(const GLcontext *ctx)
       int x1 = mmesa->driDrawable->x + ctx->Scissor.X;
       int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h
         - (ctx->Scissor.Y + ctx->Scissor.Height);
-      int x2 = x1 + ctx->Scissor.Width - 1;
-      int y2 = y1 + ctx->Scissor.Height - 1;
+      int x2 = x1 + ctx->Scissor.Width;
+      int y2 = y1 + ctx->Scissor.Height;
 
       if (x1 < 0) x1 = 0;
       if (y1 < 0) y1 = 0;
@@ -343,8 +342,7 @@ static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
 {
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
 
-
-   FLUSH_BATCH( mmesa );
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
    if (ctx->Polygon.CullFlag && 
        ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) 
    {
@@ -363,8 +361,6 @@ static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
       mmesa->hw.cull = _CULL_DISABLE;
       mmesa->hw.cull_dualtex = _CULL_DISABLE;
    }
-
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
 }
 
 
@@ -401,7 +397,7 @@ static void mgaDDColorMask(GLcontext *ctx,
  */
 
 static int mgaStipples[16] = {
-   0xffff1,  /* See above note */
+   0xffff,
    0xa5a5,
    0x5a5a,
    0xa0a0,
@@ -425,9 +421,6 @@ static int mgaStipples[16] = {
  *
  * \param ctx GL rendering context to be affected
  * \param mask Pointer to the 32x32 stipple mask
- *
- * \note the fully opaque pattern (0xffff) has been disabled in order
- * to work around a conformance issue.
  */
 
 static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
@@ -492,14 +485,11 @@ static void updateSpecularLighting( GLcontext *ctx )
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
    unsigned int specen;
 
-   specen = (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
-            ctx->Light.Enabled) ? TMC_specen_enable : 0;
+   specen = NEED_SECONDARY_COLOR(ctx) ? TMC_specen_enable : 0;
 
    if ( specen != mmesa->hw.specen ) {
       mmesa->hw.specen = specen;
       mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1;
-      
-      mgaChooseVertexState( ctx );
    }
 }
 
@@ -519,27 +509,20 @@ static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
 }
 
 
-static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
-{
-   /* FIXME: This used to FLUSH_BATCH and set MGA_NEW_TEXTURE in new_state,
-    * FIXME: so I'm not sure what to do here now.
-    */
-}
-
-
 /* =============================================================
  * Stencil
  */
 
 
-static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
-                            GLuint mask)
+static void
+mgaDDStencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref,
+                         GLuint mask)
 {
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
    GLuint  stencil;
    GLuint  stencilctl;
 
-   stencil = (ref << S_sref_SHIFT) | (mask << S_smsk_SHIFT);
+   stencil = MGA_FIELD( S_sref, ref ) | MGA_FIELD( S_smsk, mask );
    switch (func)
    {
    case GL_NEVER:
@@ -569,26 +552,26 @@ static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
       break;
    }
 
-   FLUSH_BATCH( mmesa );
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
    mmesa->hw.stencil &= (S_sref_MASK & S_smsk_MASK);
    mmesa->hw.stencil |= stencil;
    mmesa->hw.stencilctl &= SC_smode_MASK;
    mmesa->hw.stencilctl |= stencilctl;
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
 }
 
-static void mgaDDStencilMask(GLcontext *ctx, GLuint mask)
+static void
+mgaDDStencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
 {
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
 
-   FLUSH_BATCH( mmesa );
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
    mmesa->hw.stencil &= S_swtmsk_MASK;
-   mmesa->hw.stencil |= (mask << S_swtmsk_SHIFT);
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+   mmesa->hw.stencil |= MGA_FIELD( S_swtmsk, mask );
 }
 
-static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
-                          GLenum zpass)
+static void
+mgaDDStencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail,
+                       GLenum zpass)
 {
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
    GLuint  stencilctl;
@@ -671,6 +654,12 @@ static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
    case GL_DECR:
       stencilctl |= SC_szpassop_decrsat;
       break;
+   case GL_INCR_WRAP:
+      stencilctl |= SC_szpassop_incr;
+      break;
+   case GL_DECR_WRAP:
+      stencilctl |= SC_szpassop_decr;
+      break;
    case GL_INVERT:
       stencilctl |= SC_szpassop_invert;
       break;
@@ -678,11 +667,10 @@ static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
       break;
    }
 
-   FLUSH_BATCH( mmesa );
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
    mmesa->hw.stencilctl &= (SC_sfailop_MASK & SC_szfailop_MASK 
                            & SC_szpassop_MASK);
    mmesa->hw.stencilctl |= stencilctl;
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
 }
 
 
@@ -753,45 +741,19 @@ static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode )
 {
    mgaContextPtr mmesa = MGA_CONTEXT( ctx );
 
-   FLUSH_BATCH( mmesa );
-#if defined(ACCEL_ROP)
+   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
    mmesa->hw.rop = mgarop_NoBLK[ opcode & 0x0f ];
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
-#else
-   FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
-            (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) );
-#endif
-}
-
-
-static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa )
-{
-   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
-
-   if (driDrawable->numClipRects == 0) {
-       static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
-       mmesa->numClipRects = 1;
-       mmesa->pClipRects = &zeroareacliprect;
-   } else {
-       mmesa->numClipRects = driDrawable->numClipRects;
-       mmesa->pClipRects = driDrawable->pClipRects;
-   }
-   mmesa->drawX = driDrawable->x;
-   mmesa->drawY = driDrawable->y;
-
-   mmesa->setup.dstorg = mmesa->drawOffset;
-   mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
 }
 
 
-static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa )
+static void mga_set_cliprects(mgaContextPtr mmesa)
 {
    __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
 
-   if (driDrawable->numBackClipRects == 0)
-   {
+   if ((mmesa->draw_buffer != MGA_FRONT)
+       || (driDrawable->numBackClipRects == 0)) {
       if (driDrawable->numClipRects == 0) {
-         static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
+         static drm_clip_rect_t zeroareacliprect = {0,0,0,0};
          mmesa->numClipRects = 1;
          mmesa->pClipRects = &zeroareacliprect;
       } else {
@@ -814,24 +776,20 @@ static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa )
 
 void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
 {
-   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
-   MGASAREAPrivPtr sarea = mmesa->sarea;
-
+   __DRIdrawablePrivate *const driDrawable = mmesa->driDrawable;
+   __DRIdrawablePrivate *const driReadable = mmesa->driReadable;
 
-   DRI_VALIDATE_DRAWABLE_INFO(mmesa->driScreen, driDrawable); 
    mmesa->dirty_cliprects = 0; 
 
-   if (mmesa->draw_buffer == MGA_FRONT)
-      mgaXMesaSetFrontClipRects( mmesa );
-   else
-      mgaXMesaSetBackClipRects( mmesa );
+   driUpdateFramebufferSize(mmesa->glCtx, driDrawable);
+   if (driDrawable != driReadable) {
+      driUpdateFramebufferSize(mmesa->glCtx, driReadable);
+   }
 
-   sarea->req_draw_buffer = mmesa->draw_buffer;
+   mga_set_cliprects(mmesa);
 
    mgaUpdateClipping( mmesa->glCtx );
    mgaCalcViewport( mmesa->glCtx );
-
-   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
 }
 
 
@@ -844,20 +802,14 @@ static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode )
    /*
     * _DrawDestMask is easier to cope with than <mode>.
     */
-   switch ( ctx->Color._DrawDestMask ) {
-   case FRONT_LEFT_BIT:
+   switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
+   case BUFFER_BIT_FRONT_LEFT:
       mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset;
-      mmesa->dirty |= MGA_UPLOAD_CONTEXT;
       mmesa->draw_buffer = MGA_FRONT;
-      mgaXMesaSetFrontClipRects( mmesa );
-      FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
       break;
-   case BACK_LEFT_BIT:
+   case BUFFER_BIT_BACK_LEFT:
       mmesa->setup.dstorg = mmesa->mgaScreen->backOffset;
       mmesa->draw_buffer = MGA_BACK;
-      mmesa->dirty |= MGA_UPLOAD_CONTEXT;
-      mgaXMesaSetBackClipRects( mmesa );
-      FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
       break;
    default:
       /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
@@ -865,10 +817,9 @@ static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode )
       return;
    }
 
-   /* We want to update the s/w rast state too so that r200SetBuffer()
-    * gets called.
-    */
-   _swrast_DrawBuffer(ctx, mode);
+   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+   mga_set_cliprects(mmesa);
+   FALLBACK(ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE);
 }
 
 
@@ -888,22 +839,24 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
    mgaContextPtr mmesa = MGA_CONTEXT( ctx );
 
    switch(cap) {
-   case GL_ALPHA_TEST:
-      FLUSH_BATCH( mmesa );
-      mmesa->hw.alpha_func_enable = (state) ? ~0 : 0;
+   case GL_DITHER:
+      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
+      if (!ctx->Color.DitherFlag)
+        mmesa->setup.maccess |= MA_nodither_enable;
+      else
+        mmesa->setup.maccess &= ~MA_nodither_enable;
       break;
-   case GL_BLEND:
+   case GL_LIGHTING:
+   case GL_COLOR_SUM_EXT:
       FLUSH_BATCH( mmesa );
-      mmesa->hw.blend_func_enable = (state) ? ~0 : 0;
-
-      /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
-       */
-      FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
-               (ctx->Color.ColorLogicOpEnabled && 
-                ctx->Color.LogicOp != GL_COPY));
+      updateSpecularLighting( ctx );
+      break;
+   case GL_ALPHA_TEST:
+      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
+      mmesa->hw.alpha_func_enable = (state) ? ~0 : 0;
       break;
    case GL_DEPTH_TEST:
-      FLUSH_BATCH( mmesa );
+      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
       FALLBACK (ctx, MGA_FALLBACK_DEPTH,
                ctx->Depth.Func == GL_NEVER && ctx->Depth.Test);
       break;
@@ -920,8 +873,6 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
         mmesa->setup.maccess |= MA_fogen_enable;
       else
         mmesa->setup.maccess &= ~MA_fogen_enable;
-      
-      mgaChooseVertexState( ctx );
       break;
    case GL_CULL_FACE:
       mgaDDCullFaceFrontFace( ctx, 0 );
@@ -932,22 +883,20 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
       break;
    case GL_POLYGON_STIPPLE:
       if (mmesa->haveHwStipple && mmesa->raster_primitive == GL_TRIANGLES) {
-        FLUSH_BATCH(mmesa);
-        mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+        MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
         mmesa->setup.dwgctl &= ~(0xf<<20);
         if (state)
            mmesa->setup.dwgctl |= mmesa->poly_stipple;
       }
       break;
+
+   case GL_BLEND:
    case GL_COLOR_LOGIC_OP:
-      FLUSH_BATCH( mmesa );
-#if !defined(ACCEL_ROP)
-      FALLBACK( ctx, MGA_FALLBACK_LOGICOP, 
-               (state && ctx->Color.LogicOp != GL_COPY));
-#endif
+      updateBlendLogicOp( ctx );
       break;
+
    case GL_STENCIL_TEST:
-      FLUSH_BATCH( mmesa );
+      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
       if (mmesa->hw_stencil) {
         mmesa->hw.stencil_enable = ( state ) ? ~0 : 0;
       }
@@ -982,7 +931,7 @@ static void mgaDDPrintDirty( const char *msg, GLuint state )
  */
 void mgaEmitHwStateLocked( mgaContextPtr mmesa )
 {
-   MGASAREAPrivPtr sarea = mmesa->sarea;
+   drm_mga_sarea_t *sarea = mmesa->sarea;
    GLcontext * ctx = mmesa->glCtx;
 
    if (MGA_DEBUG & DEBUG_VERBOSE_MSG)
@@ -1012,76 +961,50 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa )
       mmesa->setup.dwgctl |= (ctx->Depth.Test)
          ? mmesa->hw.zmode : (DC_zmode_nozcmp | DC_atype_i);
 
-#if defined(ACCEL_ROP)
       mmesa->setup.dwgctl &= DC_bop_MASK;
-      mmesa->setup.dwgctl |= (ctx->Color.ColorLogicOpEnabled)
+      mmesa->setup.dwgctl |= RGBA_LOGICOP_ENABLED(ctx)
          ? mmesa->hw.rop : mgarop_NoBLK[ GL_COPY & 0x0f ];
-#endif
 
       mmesa->setup.alphactrl &= AC_src_MASK & AC_dst_MASK & AC_atmode_MASK
-         & AC_atref_MASK & AC_alphasel_MASK;
+        & AC_atref_MASK & AC_alphasel_MASK;
       mmesa->setup.alphactrl |= 
-         ((mmesa->hw.alpha_func & mmesa->hw.alpha_func_enable)
-          | ((mmesa->hw.blend_func & mmesa->hw.blend_func_enable)
-             | ((AC_src_one | AC_dst_zero) & ~mmesa->hw.blend_func_enable))
-          | mmesa->hw.alpha_sel
-          | (AC_amode_alpha_channel
-             | AC_astipple_disable 
-             | AC_aten_disable 
-             | AC_atmode_noacmp));
-
-      memcpy( &sarea->ContextState, &mmesa->setup, sizeof(mmesa->setup));
+        (mmesa->hw.alpha_func & mmesa->hw.alpha_func_enable) |
+        (mmesa->hw.blend_func & mmesa->hw.blend_func_enable) |
+        ((AC_src_one | AC_dst_zero) & ~mmesa->hw.blend_func_enable) |
+        mmesa->hw.alpha_sel;
+
+      memcpy( &sarea->context_state, &mmesa->setup, sizeof(mmesa->setup));
    }
 
    if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) {
-      mmesa->CurrentTexObj[0]->setup.texctl2 &= ~TMC_specen_enable;
-      mmesa->CurrentTexObj[0]->setup.texctl2 |= mmesa->hw.specen;
-
-      memcpy(&sarea->TexState[0],
+      memcpy(&sarea->tex_state[0],
             &mmesa->CurrentTexObj[0]->setup,
-            sizeof(sarea->TexState[0]));
+            sizeof(sarea->tex_state[0]));
    }
 
    if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) {
-      mmesa->CurrentTexObj[1]->setup.texctl2 &= ~TMC_specen_enable;
-      mmesa->CurrentTexObj[1]->setup.texctl2 |= mmesa->hw.specen;
-
-      memcpy(&sarea->TexState[1],
+      memcpy(&sarea->tex_state[1],
             &mmesa->CurrentTexObj[1]->setup,
-            sizeof(sarea->TexState[1]));
+            sizeof(sarea->tex_state[1]));
    }
 
-   if ( (sarea->TexState[0].texctl2 & TMC_borderen_MASK) !=
-       (sarea->TexState[1].texctl2 & TMC_borderen_MASK) ) {
-      const int borderen = sarea->TexState[1].texctl2 & ~TMC_borderen_MASK;
-
-      memcpy( &sarea->TexState[1], &sarea->TexState[0],
-             sizeof(sarea->TexState[0]) );
-      sarea->TexState[1].texctl2 |= borderen;
-      mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0;
+   if (mmesa->dirty & (MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1)) {
+      sarea->tex_state[0].texctl2 &= ~TMC_specen_enable;
+      sarea->tex_state[1].texctl2 &= ~TMC_specen_enable;
+      sarea->tex_state[0].texctl2 |= mmesa->hw.specen;
+      sarea->tex_state[1].texctl2 |= mmesa->hw.specen;
    }
 
    if (mmesa->dirty & MGA_UPLOAD_PIPE) {
 /*        mmesa->sarea->wacceptseq = mmesa->hw_primitive; */
-      mmesa->sarea->WarpPipe = mmesa->vertex_format;
+      mmesa->sarea->warp_pipe = mmesa->vertex_format;
       mmesa->sarea->vertsize = mmesa->vertex_size;
    }
 
    mmesa->sarea->dirty |= mmesa->dirty;
    mmesa->dirty &= MGA_UPLOAD_CLIPRECTS;
-
-   /* This is a bit of a hack but seems to be the best place to ensure
-    * that separate specular is disabled when not needed.
-    */
-   if (ctx->Texture._EnabledUnits == 0 ||
-       !ctx->Light.Enabled ||
-       ctx->Light.Model.ColorControl == GL_SINGLE_COLOR) {
-      sarea->TexState[0].texctl2 &= ~TMC_specen_enable;
-      sarea->TexState[1].texctl2 &= ~TMC_specen_enable;
-   }
 }
 
-
 /* =============================================================
  */
 
@@ -1089,21 +1012,21 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa )
 static void mgaDDValidateState( GLcontext *ctx )
 {
    mgaContextPtr mmesa = MGA_CONTEXT( ctx );
-   int new_state = mmesa->NewGLState;
-
 
    FLUSH_BATCH( mmesa );
 
-   if (mmesa->NewGLState & _MGA_NEW_RASTERSETUP) {
-      mgaChooseVertexState( ctx );
+   if (mmesa->NewGLState & _NEW_TEXTURE) {
+      mgaUpdateTextureState(ctx);
    }
 
-   if (mmesa->NewGLState & _MGA_NEW_RENDERSTATE) {
-      mgaChooseRenderState( ctx );
-   }
+   if (!mmesa->Fallback) {
+      if (mmesa->NewGLState & _MGA_NEW_RASTERSETUP) {
+         mgaChooseVertexState( ctx );
+      }
 
-   if (new_state & _NEW_TEXTURE) {
-      mgaUpdateTextureState(ctx);
+      if (mmesa->NewGLState & _MGA_NEW_RENDERSTATE) {
+         mgaChooseRenderState( ctx );
+      }
    }
 
    mmesa->NewGLState = 0;
@@ -1114,7 +1037,7 @@ static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state )
 {
    _swrast_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );
-   _ac_InvalidateState( ctx, new_state );
+   _vbo_InvalidateState( ctx, new_state );
    _tnl_InvalidateState( ctx, new_state );
    MGA_CONTEXT(ctx)->NewGLState |= new_state;
 }
@@ -1160,6 +1083,9 @@ void mgaInitState( mgaContextPtr mmesa )
                           MA_tlutload_disable |
                           MA_nodither_disable |
                           MA_dit555_disable);
+   if (driQueryOptioni (&mmesa->optionCache, "color_reduction") !=
+       DRI_CONF_COLOR_REDUCTION_DITHER)
+      mmesa->setup.maccess |= MA_nodither_enable;
 
    switch (mmesa->mgaScreen->cpp) {
    case 2:
@@ -1186,14 +1112,21 @@ void mgaInitState( mgaContextPtr mmesa )
       break;
    }
 
+   mmesa->hw.blend_func = AC_src_one | AC_dst_zero;
+   mmesa->hw.blend_func_enable = 0;
+   mmesa->hw.alpha_func = AC_atmode_noacmp | MGA_FIELD( AC_atref, 0x00 );
+   mmesa->hw.alpha_func_enable = 0;
+   mmesa->hw.rop = mgarop_NoBLK[ GL_COPY & 0x0f ];
    mmesa->hw.zmode = DC_zmode_zlt | DC_atype_zi;
-   mmesa->hw.stencil = (0x0ff << S_smsk_SHIFT) | (0x0ff << S_swtmsk_SHIFT);
+   mmesa->hw.stencil = MGA_FIELD( S_sref, 0x00) | MGA_FIELD( S_smsk, 0xff ) |
+      MGA_FIELD( S_swtmsk, 0xff );
    mmesa->hw.stencilctl = SC_smode_salways | SC_sfailop_keep 
-       | SC_szfailop_keep | SC_szpassop_keep;
+      | SC_szfailop_keep | SC_szpassop_keep;
    mmesa->hw.stencil_enable = 0;
-   mmesa->hw.cull = _CULL_NEGATIVE;
-   mmesa->hw.cull_dualtex = _CULL_POSITIVE;
+   mmesa->hw.cull = _CULL_DISABLE;
+   mmesa->hw.cull_dualtex = _CULL_DISABLE;
    mmesa->hw.specen = 0;
+   mmesa->hw.alpha_sel = AC_alphasel_diffused;
 
    mmesa->setup.dwgctl = (DC_opcod_trap |
                          DC_linear_xy |
@@ -1201,22 +1134,17 @@ void mgaInitState( mgaContextPtr mmesa )
                          DC_arzero_disable |
                          DC_sgnzero_disable |
                          DC_shftzero_enable |
-                         (0xC << DC_bop_SHIFT) |
-                         (0x0 << DC_trans_SHIFT) |
+                         MGA_FIELD( DC_bop, 0xC ) |
+                         MGA_FIELD( DC_trans, 0x0 ) |
                          DC_bltmod_bmonolef |
                          DC_pattern_disable |
                          DC_transc_disable |
                          DC_clipdis_disable);
 
-
    mmesa->setup.plnwt = ~0;
-   mmesa->setup.alphactrl = ( AC_src_one |
-                             AC_dst_zero |
-                             AC_amode_FCOL |
-                             AC_astipple_disable |
-                             AC_aten_disable |
-                             AC_atmode_noacmp |
-                             AC_alphasel_fromtex );
+   mmesa->setup.alphactrl = (AC_amode_alpha_channel |
+                            AC_astipple_disable |
+                            AC_aten_disable);
 
    mmesa->setup.fogcolor = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F),
                                          (GLubyte)(ctx->Fog.Color[1]*255.0F),
@@ -1227,6 +1155,9 @@ void mgaInitState( mgaContextPtr mmesa )
    mmesa->setup.tdualstage1 = 0;
    mmesa->setup.fcol = 0;
    mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+
+   mmesa->envcolor[0] = 0;
+   mmesa->envcolor[1] = 0;
 }
 
 
@@ -1236,14 +1167,12 @@ void mgaDDInitStateFuncs( GLcontext *ctx )
    ctx->Driver.Enable = mgaDDEnable;
    ctx->Driver.LightModelfv = mgaDDLightModelfv;
    ctx->Driver.AlphaFunc = mgaDDAlphaFunc;
-   ctx->Driver.BlendEquation = mgaDDBlendEquation;
-   ctx->Driver.BlendFunc = mgaDDBlendFunc;
+   ctx->Driver.BlendEquationSeparate = mgaDDBlendEquationSeparate;
    ctx->Driver.BlendFuncSeparate = mgaDDBlendFuncSeparate;
    ctx->Driver.DepthFunc = mgaDDDepthFunc;
    ctx->Driver.DepthMask = mgaDDDepthMask;
    ctx->Driver.Fogfv = mgaDDFogfv;
    ctx->Driver.Scissor = mgaDDScissor;
-   ctx->Driver.ShadeModel = mgaDDShadeModel;
    ctx->Driver.CullFace = mgaDDCullFaceFrontFace;
    ctx->Driver.FrontFace = mgaDDCullFaceFrontFace;
    ctx->Driver.ColorMask = mgaDDColorMask;
@@ -1256,9 +1185,9 @@ void mgaDDInitStateFuncs( GLcontext *ctx )
 
    ctx->Driver.PolygonStipple = mgaDDPolygonStipple;
 
-   ctx->Driver.StencilFunc = mgaDDStencilFunc;
-   ctx->Driver.StencilMask = mgaDDStencilMask;
-   ctx->Driver.StencilOp = mgaDDStencilOp;
+   ctx->Driver.StencilFuncSeparate = mgaDDStencilFuncSeparate;
+   ctx->Driver.StencilMaskSeparate = mgaDDStencilMaskSeparate;
+   ctx->Driver.StencilOpSeparate = mgaDDStencilOpSeparate;
 
    ctx->Driver.DepthRange = mgaDepthRange;
    ctx->Driver.Viewport = mgaViewport;
@@ -1267,12 +1196,5 @@ void mgaDDInitStateFuncs( GLcontext *ctx )
    ctx->Driver.ClearIndex = 0;
    ctx->Driver.IndexMask = 0;
 
-   /* Swrast hooks for imaging extensions:
-    */
-   ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
-   ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
-   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
-   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
-
    TNL_CONTEXT(ctx)->Driver.RunPipeline = mgaRunPipeline;
 }