/*
 * Copyright 2000-2001 VA Linux Systems, Inc.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 * license, and/or sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *    Keith Whitwell <keith@tungstengraphics.com>
 */


#include "mtypes.h"
#include "colormac.h"
#include "dd.h"

#include "mm.h"
#include "mgacontext.h"
#include "mgadd.h"
#include "mgastate.h"
#include "mgatex.h"
#include "mgavb.h"
#include "mgatris.h"
#include "mgaioctl.h"
#include "mgaregs.h"

#include "swrast/swrast.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 const GLuint mgarop_NoBLK[16] = {
   DC_atype_rpl  | 0x00000000, DC_atype_rstr | 0x00080000,
   DC_atype_rstr | 0x00040000, DC_atype_rpl  | 0x000c0000,
   DC_atype_rstr | 0x00020000, DC_atype_rstr | 0x000a0000,
   DC_atype_rstr | 0x00060000, DC_atype_rstr | 0x000e0000,
   DC_atype_rstr | 0x00010000, DC_atype_rstr | 0x00090000,
   DC_atype_rstr | 0x00050000, DC_atype_rstr | 0x000d0000,
   DC_atype_rpl  | 0x00030000, DC_atype_rstr | 0x000b0000,
   DC_atype_rstr | 0x00070000, DC_atype_rpl  | 0x000f0000
};

/* =============================================================
 * Alpha blending
 */

static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   GLubyte refByte;
   GLuint  a;

   CLAMPED_FLOAT_TO_UBYTE(refByte, ref);

   switch ( func ) {
   case GL_NEVER:
      a = AC_atmode_alt;
      refByte = 0;
      break;
   case GL_LESS:
      a = AC_atmode_alt;
      break;
   case GL_GEQUAL:
      a = AC_atmode_agte;
      break;
   case GL_LEQUAL:
      a = AC_atmode_alte;
      break;
   case GL_GREATER:
      a = AC_atmode_agt;
      break;
   case GL_NOTEQUAL:
      a = AC_atmode_ane;
      break;
   case GL_EQUAL:
      a = AC_atmode_ae;
      break;
   case GL_ALWAYS:
      a = AC_atmode_noacmp;
      break;
   default:
      a = 0;
      break;
   }

   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
   mmesa->hw.alpha_func = a | MGA_FIELD( AC_atref, refByte );
}

static void updateBlendLogicOp(GLcontext *ctx)
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   GLboolean logicOp = RGBA_LOGICOP_ENABLED(ctx);

   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 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);
   GLuint   src;
   GLuint   dst;

   switch (ctx->Color.BlendSrcRGB) {
   case GL_ZERO:
      src = AC_src_zero; break;
   case GL_SRC_ALPHA:
      src = AC_src_src_alpha; break;
   case GL_ONE:
   default:		/* never happens */
      src = AC_src_one; break;
   case GL_DST_COLOR:
      src = AC_src_dst_color; break;
   case GL_ONE_MINUS_DST_COLOR:
      src = AC_src_om_dst_color; break;
   case GL_ONE_MINUS_SRC_ALPHA:
      src = AC_src_om_src_alpha; break;
   case GL_DST_ALPHA:
      src = (ctx->Visual.alphaBits > 0)
	  ? AC_src_dst_alpha : AC_src_one;
      break;
   case GL_ONE_MINUS_DST_ALPHA:
      src = (ctx->Visual.alphaBits > 0)
	  ? AC_src_om_dst_alpha : AC_src_zero;
      break;
   case GL_SRC_ALPHA_SATURATE:
      src = (ctx->Visual.alphaBits > 0)
	  ? AC_src_src_alpha_sat : AC_src_zero;
      break;
   }

   switch (ctx->Color.BlendDstRGB) {
   case GL_SRC_ALPHA:
      dst = AC_dst_src_alpha; break;
   case GL_ONE_MINUS_SRC_ALPHA:
      dst = AC_dst_om_src_alpha; break;
   default:		/* never happens */
   case GL_ZERO:
      dst = AC_dst_zero; break;
   case GL_ONE:
      dst = AC_dst_one; break;
   case GL_SRC_COLOR:
      dst = AC_dst_src_color; break;
   case GL_ONE_MINUS_SRC_COLOR:
      dst = AC_dst_om_src_color; break;
   case GL_DST_ALPHA:
      dst = (ctx->Visual.alphaBits > 0)
	  ? AC_dst_dst_alpha : AC_dst_one;
      break;
   case GL_ONE_MINUS_DST_ALPHA:
      dst = (ctx->Visual.alphaBits > 0)
	  ? AC_dst_om_dst_alpha : AC_dst_zero;
      break;
   }

   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
   mmesa->hw.blend_func = (src | dst);

   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
 */

static void mgaDDDepthFunc(GLcontext *ctx, GLenum func)
{
   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
   int zmode;

   switch (func) {
   case GL_NEVER:
      /* can't do this in h/w, we'll use a s/w fallback */
      FALLBACK (ctx, MGA_FALLBACK_DEPTH, ctx->Depth.Test);

      /* FALLTHROUGH */
   case GL_ALWAYS:
      zmode = DC_zmode_nozcmp; break;
   case GL_LESS:
      zmode = DC_zmode_zlt; break;
   case GL_LEQUAL:
      zmode = DC_zmode_zlte; break;
   case GL_EQUAL:
      zmode = DC_zmode_ze; break;
   case GL_GREATER:
      zmode = DC_zmode_zgt; break;
   case GL_GEQUAL:
      zmode = DC_zmode_zgte; break;
   case GL_NOTEQUAL:
      zmode = DC_zmode_zne; break;
   default:
      zmode = 0; break;
   }

   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
   mmesa->hw.zmode &= DC_zmode_MASK;
   mmesa->hw.zmode |= zmode;
}

static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag)
{
   mgaContextPtr mmesa = MGA_CONTEXT( ctx );


   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
   mmesa->hw.zmode &= DC_atype_MASK;
   mmesa->hw.zmode |= (flag) ? DC_atype_zi : DC_atype_i;
}


static void mgaDDClearDepth(GLcontext *ctx, GLclampd d)
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);

   /* Select the Z depth.  The ~ is used because the _MASK values in the
    * MGA driver are used to mask OFF the selected bits.  In this case,
    * we want to mask off everything except the MA_zwidth bits.
    */
   switch (mmesa->setup.maccess & ~MA_zwidth_MASK) {
   case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break;
   case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break;
   case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break;
   default: return;
   }
}


/* =============================================================
 * Fog
 */


static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);

   if (pname == GL_FOG_COLOR) {
      GLuint color = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F), 
				    (GLubyte)(ctx->Fog.Color[1]*255.0F), 
				    (GLubyte)(ctx->Fog.Color[2]*255.0F));

      MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT);   
      mmesa->setup.fogcolor = color;
   }
}


/* =============================================================
 * Scissoring
 */


void mgaUpdateClipping(const GLcontext *ctx)
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);

   if (mmesa->driDrawable)
   {
      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;
      int y2 = y1 + ctx->Scissor.Height;

      if (x1 < 0) x1 = 0;
      if (y1 < 0) y1 = 0;
      if (x2 < 0) x2 = 0;
      if (y2 < 0) y2 = 0;

      mmesa->scissor_rect.x1 = x1;
      mmesa->scissor_rect.y1 = y1;
      mmesa->scissor_rect.x2 = x2;
      mmesa->scissor_rect.y2 = y2;

      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
   }
}


static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y,
			  GLsizei w, GLsizei h )
{
   if ( ctx->Scissor.Enabled ) {
      FLUSH_BATCH( MGA_CONTEXT(ctx) );	/* don't pipeline cliprect changes */
      mgaUpdateClipping( ctx );
   }
}


/* =============================================================
 * Culling
 */


#define _CULL_DISABLE 0
#define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16))
#define _CULL_POSITIVE (1<<11)

static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);

   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
   if (ctx->Polygon.CullFlag && 
       ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) 
   {
      mmesa->hw.cull = _CULL_NEGATIVE;

      if (ctx->Polygon.CullFaceMode == GL_FRONT)
	 mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);

      if (ctx->Polygon.FrontFace != GL_CCW)
	 mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);

      mmesa->hw.cull_dualtex = mmesa->hw.cull ^
	  (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */
   }
   else {
      mmesa->hw.cull = _CULL_DISABLE;
      mmesa->hw.cull_dualtex = _CULL_DISABLE;
   }
}


/* =============================================================
 * Masks
 */

static void mgaDDColorMask(GLcontext *ctx, 
			   GLboolean r, GLboolean g, 
			   GLboolean b, GLboolean a )
{
   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;


   GLuint mask = mgaPackColor(mgaScreen->cpp,
			      ctx->Color.ColorMask[RCOMP],
			      ctx->Color.ColorMask[GCOMP],
			      ctx->Color.ColorMask[BCOMP],
			      ctx->Color.ColorMask[ACOMP]);

   if (mgaScreen->cpp == 2)
      mask = mask | (mask << 16);

   if (mmesa->setup.plnwt != mask) {
      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
      mmesa->setup.plnwt = mask;      
   }
}


/* =============================================================
 * Polygon state
 */

static int mgaStipples[16] = {
   0xffff,
   0xa5a5,
   0x5a5a,
   0xa0a0,
   0x5050,
   0x0a0a,
   0x0505,
   0x8020,
   0x0401,
   0x1040,
   0x0208,
   0x0802,
   0x4010,
   0x0104,
   0x2080,
   0x0000
};

/**
 * The MGA supports a subset of possible 4x4 stipples natively, GL
 * wants 32x32.  Fortunately stipple is usually a repeating pattern.
 *
 * \param ctx GL rendering context to be affected
 * \param mask Pointer to the 32x32 stipple mask
 */

static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   const GLubyte *m = mask;
   GLubyte p[4];
   int i,j,k;
   int active = (ctx->Polygon.StippleFlag && 
		 mmesa->raster_primitive == GL_TRIANGLES);
   GLuint stipple;

   FLUSH_BATCH(mmesa);
   mmesa->haveHwStipple = 0;

   if (active) {
      mmesa->dirty |= MGA_UPLOAD_CONTEXT;
      mmesa->setup.dwgctl &= ~(0xf<<20);
   }

   p[0] = mask[0] & 0xf; p[0] |= p[0] << 4;
   p[1] = mask[4] & 0xf; p[1] |= p[1] << 4;
   p[2] = mask[8] & 0xf; p[2] |= p[2] << 4;
   p[3] = mask[12] & 0xf; p[3] |= p[3] << 4;

   for (k = 0 ; k < 8 ; k++)
      for (j = 0 ; j < 4; j++)
	 for (i = 0 ; i < 4 ; i++)
	    if (*m++ != p[j]) {
	       return;
	    }

   stipple = ( ((p[0] & 0xf) << 0) |
	       ((p[1] & 0xf) << 4) |
	       ((p[2] & 0xf) << 8) |
	       ((p[3] & 0xf) << 12) );

   for (i = 0 ; i < 16 ; i++)
      if (mgaStipples[i] == stipple) {
	 mmesa->poly_stipple = i<<20;
	 mmesa->haveHwStipple = 1;
	 break;
      }
   
   if (active) {
      mmesa->setup.dwgctl &= ~(0xf<<20);
      mmesa->setup.dwgctl |= mmesa->poly_stipple;
   }
}


/* =============================================================
 * Rendering attributes
 *
 * We really don't want to recalculate all this every time we bind a
 * texture.  These things shouldn't change all that often, so it makes
 * sense to break them out of the core texture state update routines.
 */

static void updateSpecularLighting( GLcontext *ctx )
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   unsigned int specen;

   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;
   }
}


/* =============================================================
 * Materials
 */


static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
			      const GLfloat *param)
{
   if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
      FLUSH_BATCH( MGA_CONTEXT(ctx) );
      updateSpecularLighting( ctx );
   }
}


/* =============================================================
 * Stencil
 */


static void
mgaDDStencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref,
                         GLuint mask)
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   GLuint  stencil;
   GLuint  stencilctl;

   stencil = MGA_FIELD( S_sref, ref ) | MGA_FIELD( S_smsk, mask );
   switch (func)
   {
   case GL_NEVER:
      stencilctl = SC_smode_snever;
      break;
   case GL_LESS:
      stencilctl = SC_smode_slt;
      break;
   case GL_LEQUAL:
      stencilctl = SC_smode_slte;
      break;
   case GL_GREATER:
      stencilctl = SC_smode_sgt;
      break;
   case GL_GEQUAL:
      stencilctl = SC_smode_sgte;
      break;
   case GL_NOTEQUAL:
      stencilctl = SC_smode_sne;
      break;
   case GL_EQUAL:
      stencilctl = SC_smode_se;
      break;
   case GL_ALWAYS:
   default:
      stencilctl = SC_smode_salways;
      break;
   }

   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;
}

static void
mgaDDStencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);

   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
   mmesa->hw.stencil &= S_swtmsk_MASK;
   mmesa->hw.stencil |= MGA_FIELD( S_swtmsk, mask );
}

static void
mgaDDStencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail,
                       GLenum zpass)
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   GLuint  stencilctl;

   stencilctl = 0;
   switch (ctx->Stencil.FailFunc[0])
   {
   case GL_KEEP:
      stencilctl |= SC_sfailop_keep;
      break;
   case GL_ZERO:
      stencilctl |= SC_sfailop_zero;
      break;
   case GL_REPLACE:
      stencilctl |= SC_sfailop_replace;
      break;
   case GL_INCR:
      stencilctl |= SC_sfailop_incrsat;
      break;
   case GL_DECR:
      stencilctl |= SC_sfailop_decrsat;
      break;
   case GL_INCR_WRAP:
      stencilctl |= SC_sfailop_incr;
      break;
   case GL_DECR_WRAP:
      stencilctl |= SC_sfailop_decr;
      break;
   case GL_INVERT:
      stencilctl |= SC_sfailop_invert;
      break;
   default:
      break;
   }

   switch (ctx->Stencil.ZFailFunc[0])
   {
   case GL_KEEP:
      stencilctl |= SC_szfailop_keep;
      break;
   case GL_ZERO:
      stencilctl |= SC_szfailop_zero;
      break;
   case GL_REPLACE:
      stencilctl |= SC_szfailop_replace;
      break;
   case GL_INCR:
      stencilctl |= SC_szfailop_incrsat;
      break;
   case GL_DECR:
      stencilctl |= SC_szfailop_decrsat;
      break;
   case GL_INCR_WRAP:
      stencilctl |= SC_szfailop_incr;
      break;
   case GL_DECR_WRAP:
      stencilctl |= SC_szfailop_decr;
      break;
   case GL_INVERT:
      stencilctl |= SC_szfailop_invert;
      break;
   default:
      break;
   }

   switch (ctx->Stencil.ZPassFunc[0])
   {
   case GL_KEEP:
      stencilctl |= SC_szpassop_keep;
      break;
   case GL_ZERO:
      stencilctl |= SC_szpassop_zero;
      break;
   case GL_REPLACE:
      stencilctl |= SC_szpassop_replace;
      break;
   case GL_INCR:
      stencilctl |= SC_szpassop_incrsat;
      break;
   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;
   default:
      break;
   }

   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
   mmesa->hw.stencilctl &= (SC_sfailop_MASK & SC_szfailop_MASK 
			    & SC_szpassop_MASK);
   mmesa->hw.stencilctl |= stencilctl;
}


/* =============================================================
 * Window position and viewport transformation
 */

void mgaCalcViewport( GLcontext *ctx )
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   const GLfloat *v = ctx->Viewport._WindowMap.m;
   GLfloat *m = mmesa->hw_viewport;

   /* See also mga_translate_vertex.
    */
   m[MAT_SX] =   v[MAT_SX];
   m[MAT_TX] =   v[MAT_TX] + mmesa->drawX + SUBPIXEL_X;
   m[MAT_SY] = - v[MAT_SY];
   m[MAT_TY] = - v[MAT_TY] + mmesa->driDrawable->h + mmesa->drawY + SUBPIXEL_Y;
   m[MAT_SZ] =   v[MAT_SZ] * mmesa->depth_scale;
   m[MAT_TZ] =   v[MAT_TZ] * mmesa->depth_scale;

   mmesa->SetupNewInputs = ~0;
}

static void mgaViewport( GLcontext *ctx, 
			  GLint x, GLint y, 
			  GLsizei width, GLsizei height )
{
   mgaCalcViewport( ctx );
}

static void mgaDepthRange( GLcontext *ctx, 
			    GLclampd nearval, GLclampd farval )
{
   mgaCalcViewport( ctx );
}


/* =============================================================
 * Miscellaneous
 */

static void mgaDDClearColor(GLcontext *ctx, 
			    const GLfloat color[4] )
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   GLubyte c[4];
   CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
   CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
   CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
   CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);

   mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp,
				     c[0], c[1], c[2], c[3]);
}


/* Fallback to swrast for select and feedback.
 */
static void mgaRenderMode( GLcontext *ctx, GLenum mode )
{
   FALLBACK( ctx, MGA_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
}


static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode )
{
   mgaContextPtr mmesa = MGA_CONTEXT( ctx );

   MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
   mmesa->hw.rop = mgarop_NoBLK[ opcode & 0x0f ];
}


static void mga_set_cliprects(mgaContextPtr mmesa)
{
   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;

   if ((mmesa->draw_buffer != MGA_FRONT)
       || (driDrawable->numBackClipRects == 0)) {
      if (driDrawable->numClipRects == 0) {
	  static drm_clip_rect_t 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;
   } else {
      mmesa->numClipRects = driDrawable->numBackClipRects;
      mmesa->pClipRects = driDrawable->pBackClipRects;
      mmesa->drawX = driDrawable->backX;
      mmesa->drawY = driDrawable->backY;
   }

   mmesa->setup.dstorg = mmesa->drawOffset;
   mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
}


void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
{
   __DRIdrawablePrivate *const driDrawable = mmesa->driDrawable;
   __DRIdrawablePrivate *const driReadable = mmesa->driReadable;

   mmesa->dirty_cliprects = 0;	

   driUpdateFramebufferSize(mmesa->glCtx, driDrawable);
   if (driDrawable != driReadable) {
      driUpdateFramebufferSize(mmesa->glCtx, driReadable);
   }

   mga_set_cliprects(mmesa);

   mgaUpdateClipping( mmesa->glCtx );
   mgaCalcViewport( mmesa->glCtx );
}


static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode )
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);

   FLUSH_BATCH( mmesa );

   if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
      /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
      FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE );
      return;
   }

   switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
   case BUFFER_FRONT_LEFT:
      mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset;
      mmesa->draw_buffer = MGA_FRONT;
      break;
   case BUFFER_BACK_LEFT:
      mmesa->setup.dstorg = mmesa->mgaScreen->backOffset;
      mmesa->draw_buffer = MGA_BACK;
      break;
   default:
      FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE );
      return;
   }

   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
   mga_set_cliprects(mmesa);
   FALLBACK(ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE);
}


static void mgaDDReadBuffer(GLcontext *ctx, GLenum mode )
{
   /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
}


/* =============================================================
 * State enable/disable
 */


static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
{
   mgaContextPtr mmesa = MGA_CONTEXT( ctx );

   switch(cap) {
   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_LIGHTING:
   case GL_COLOR_SUM_EXT:
      FLUSH_BATCH( mmesa );
      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:
      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
      FALLBACK (ctx, MGA_FALLBACK_DEPTH,
		ctx->Depth.Func == GL_NEVER && ctx->Depth.Test);
      break;

   case GL_SCISSOR_TEST:
      FLUSH_BATCH( mmesa );
      mmesa->scissor = state;
      mgaUpdateClipping( ctx );
      break;

   case GL_FOG:
      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
      if (ctx->Fog.Enabled) 
	 mmesa->setup.maccess |= MA_fogen_enable;
      else
	 mmesa->setup.maccess &= ~MA_fogen_enable;
      break;
   case GL_CULL_FACE:
      mgaDDCullFaceFrontFace( ctx, 0 );
      break;
   case GL_TEXTURE_1D:
   case GL_TEXTURE_2D:
   case GL_TEXTURE_3D:
      break;
   case GL_POLYGON_STIPPLE:
      if (mmesa->haveHwStipple && mmesa->raster_primitive == GL_TRIANGLES) {
	 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:
      updateBlendLogicOp( ctx );
      break;

   case GL_STENCIL_TEST:
      MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
      if (mmesa->hw_stencil) {
	 mmesa->hw.stencil_enable = ( state ) ? ~0 : 0;
      }
      else {
	 FALLBACK( ctx, MGA_FALLBACK_STENCIL, state );
      }
   default:
      break;
   }
}


/* =============================================================
 */

static void mgaDDPrintDirty( const char *msg, GLuint state )
{
   fprintf(stderr, "%s (0x%03x): %s%s%s%s%s%s%s\n",
	   msg,
	   (unsigned int) state,
	   (state & MGA_WAIT_AGE)          ? "wait-age " : "",
	   (state & MGA_UPLOAD_TEX0IMAGE)  ? "upload-tex0-img " : "",
	   (state & MGA_UPLOAD_TEX1IMAGE)  ? "upload-tex1-img " : "",
	   (state & MGA_UPLOAD_CONTEXT)    ? "upload-ctx " : "",
	   (state & MGA_UPLOAD_TEX0)       ? "upload-tex0 " : "",
	   (state & MGA_UPLOAD_TEX1)       ? "upload-tex1 " : "",
	   (state & MGA_UPLOAD_PIPE)       ? "upload-pipe " : ""
      );
}

/* Push the state into the sarea and/or texture memory.
 */
void mgaEmitHwStateLocked( mgaContextPtr mmesa )
{
   drm_mga_sarea_t *sarea = mmesa->sarea;
   GLcontext * ctx = mmesa->glCtx;

   if (MGA_DEBUG & DEBUG_VERBOSE_MSG)
      mgaDDPrintDirty( __FUNCTION__, mmesa->dirty );

   if (mmesa->dirty & MGA_UPLOAD_CONTEXT) {
      mmesa->setup.wflag = _CULL_DISABLE;
      if (mmesa->raster_primitive == GL_TRIANGLES) {
	 if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
	      ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) {
	    mmesa->setup.wflag = mmesa->hw.cull_dualtex;
	 }
	 else {
	    mmesa->setup.wflag = mmesa->hw.cull;
	 }
      }

      mmesa->setup.stencil = mmesa->hw.stencil 
	  & mmesa->hw.stencil_enable;
      mmesa->setup.stencilctl = mmesa->hw.stencilctl
	  & mmesa->hw.stencil_enable;

      /* If depth testing is not enabled, then use the no Z-compare / no
       * Z-write mode.  Otherwise, use whatever is set in hw.zmode.
       */
      mmesa->setup.dwgctl &= (DC_zmode_MASK & DC_atype_MASK);
      mmesa->setup.dwgctl |= (ctx->Depth.Test)
	  ? mmesa->hw.zmode : (DC_zmode_nozcmp | DC_atype_i);

      mmesa->setup.dwgctl &= DC_bop_MASK;
      mmesa->setup.dwgctl |= RGBA_LOGICOP_ENABLED(ctx)
	  ? mmesa->hw.rop : mgarop_NoBLK[ GL_COPY & 0x0f ];

      mmesa->setup.alphactrl &= AC_src_MASK & AC_dst_MASK & AC_atmode_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;

      memcpy( &sarea->context_state, &mmesa->setup, sizeof(mmesa->setup));
   }

   if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) {
      memcpy(&sarea->tex_state[0],
	     &mmesa->CurrentTexObj[0]->setup,
	     sizeof(sarea->tex_state[0]));
   }

   if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) {
      memcpy(&sarea->tex_state[1],
	     &mmesa->CurrentTexObj[1]->setup,
	     sizeof(sarea->tex_state[1]));
   }

   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->warp_pipe = mmesa->vertex_format;
      mmesa->sarea->vertsize = mmesa->vertex_size;
   }

   mmesa->sarea->dirty |= mmesa->dirty;
   mmesa->dirty &= MGA_UPLOAD_CLIPRECTS;
}

/* =============================================================
 */


static void mgaDDValidateState( GLcontext *ctx )
{
   mgaContextPtr mmesa = MGA_CONTEXT( ctx );

   FLUSH_BATCH( mmesa );

   if (mmesa->NewGLState & _NEW_TEXTURE) {
      mgaUpdateTextureState(ctx);
   }

   if (!mmesa->Fallback) {
      if (mmesa->NewGLState & _MGA_NEW_RASTERSETUP) {
         mgaChooseVertexState( ctx );
      }

      if (mmesa->NewGLState & _MGA_NEW_RENDERSTATE) {
         mgaChooseRenderState( ctx );
      }
   }

   mmesa->NewGLState = 0;
}


static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state )
{
   _swrast_InvalidateState( ctx, new_state );
   _swsetup_InvalidateState( ctx, new_state );
   _vbo_InvalidateState( ctx, new_state );
   _tnl_InvalidateState( ctx, new_state );
   MGA_CONTEXT(ctx)->NewGLState |= new_state;
}


static void mgaRunPipeline( GLcontext *ctx )
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);

   if (mmesa->NewGLState) {
      mgaDDValidateState( ctx );
   }

   if (mmesa->dirty) {
       mgaEmitHwStateLocked( mmesa );
   }

   _tnl_run_pipeline( ctx );
}


void mgaInitState( mgaContextPtr mmesa )
{
   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
   GLcontext *ctx = mmesa->glCtx;

   if (ctx->Visual.doubleBufferMode) {
      /* use back buffer by default */
      mmesa->draw_buffer = MGA_BACK;
      mmesa->drawOffset = mmesa->mgaScreen->backOffset;
      mmesa->readOffset = mmesa->mgaScreen->backOffset;
      mmesa->setup.dstorg = mgaScreen->backOffset;
   } else {
      /* use front buffer by default */
      mmesa->draw_buffer = MGA_FRONT;
      mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
      mmesa->readOffset = mmesa->mgaScreen->frontOffset;
      mmesa->setup.dstorg = mgaScreen->frontOffset;
   }

   mmesa->setup.maccess = (MA_memreset_disable |
			   MA_fogen_disable |
			   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:
      mmesa->setup.maccess |= MA_pwidth_16;
      break;
   case 4:
      mmesa->setup.maccess |= MA_pwidth_32;
      break;
   default:
      fprintf( stderr, "Error: unknown cpp %d, exiting...\n",
	       mmesa->mgaScreen->cpp );
      exit( 1 );
   }

   switch (mmesa->glCtx->Visual.depthBits) {
   case 16:
      mmesa->setup.maccess |= MA_zwidth_16;
      break;
   case 24:
      mmesa->setup.maccess |= MA_zwidth_24;
      break;
   case 32:
      mmesa->setup.maccess |= MA_zwidth_32;
      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 = 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;
   mmesa->hw.stencil_enable = 0;
   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 |
			  DC_solid_disable |
			  DC_arzero_disable |
			  DC_sgnzero_disable |
			  DC_shftzero_enable |
			  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_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),
					  (GLubyte)(ctx->Fog.Color[2]*255.0F));

   mmesa->setup.wflag = 0;
   mmesa->setup.tdualstage0 = 0;
   mmesa->setup.tdualstage1 = 0;
   mmesa->setup.fcol = 0;
   mmesa->dirty |= MGA_UPLOAD_CONTEXT;

   mmesa->envcolor[0] = 0;
   mmesa->envcolor[1] = 0;
}


void mgaDDInitStateFuncs( GLcontext *ctx )
{
   ctx->Driver.UpdateState = mgaDDInvalidateState;
   ctx->Driver.Enable = mgaDDEnable;
   ctx->Driver.LightModelfv = mgaDDLightModelfv;
   ctx->Driver.AlphaFunc = mgaDDAlphaFunc;
   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.CullFace = mgaDDCullFaceFrontFace;
   ctx->Driver.FrontFace = mgaDDCullFaceFrontFace;
   ctx->Driver.ColorMask = mgaDDColorMask;

   ctx->Driver.DrawBuffer = mgaDDDrawBuffer;
   ctx->Driver.ReadBuffer = mgaDDReadBuffer;
   ctx->Driver.ClearColor = mgaDDClearColor;
   ctx->Driver.ClearDepth = mgaDDClearDepth;
   ctx->Driver.LogicOpcode = mgaDDLogicOp;

   ctx->Driver.PolygonStipple = mgaDDPolygonStipple;

   ctx->Driver.StencilFuncSeparate = mgaDDStencilFuncSeparate;
   ctx->Driver.StencilMaskSeparate = mgaDDStencilMaskSeparate;
   ctx->Driver.StencilOpSeparate = mgaDDStencilOpSeparate;

   ctx->Driver.DepthRange = mgaDepthRange;
   ctx->Driver.Viewport = mgaViewport;
   ctx->Driver.RenderMode = mgaRenderMode;

   ctx->Driver.ClearIndex = 0;
   ctx->Driver.IndexMask = 0;

   TNL_CONTEXT(ctx)->Driver.RunPipeline = mgaRunPipeline;
}
