mga driver, brought over by Jon Smirl
authorKeith Whitwell <keith@tungstengraphics.com>
Wed, 6 Aug 2003 18:01:13 +0000 (18:01 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Wed, 6 Aug 2003 18:01:13 +0000 (18:01 +0000)
35 files changed:
src/mesa/drivers/dri/mga/Makefile.X11 [new file with mode: 0644]
src/mesa/drivers/dri/mga/README [new file with mode: 0644]
src/mesa/drivers/dri/mga/mga_xmesa.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mga_xmesa.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgabuffers.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgabuffers.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgacontext.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgadd.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgadd.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgaioctl.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgaioctl.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgapixel.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgapixel.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgaregs.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgarender.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgaspan.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgaspan.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgastate.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgastate.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgatex.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgatex.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgatexcnv.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgatexmem.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgatris.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgatris.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgavb.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/mgavb.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/server/mga.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/server/mga_bios.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/server/mga_common.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/server/mga_dri.c [new file with mode: 0644]
src/mesa/drivers/dri/mga/server/mga_dri.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/server/mga_macros.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/server/mga_reg.h [new file with mode: 0644]
src/mesa/drivers/dri/mga/server/mga_sarea.h [new file with mode: 0644]

diff --git a/src/mesa/drivers/dri/mga/Makefile.X11 b/src/mesa/drivers/dri/mga/Makefile.X11
new file mode 100644 (file)
index 0000000..c69d6e5
--- /dev/null
@@ -0,0 +1,116 @@
+# $Id: Makefile.X11,v 1.1 2003/08/06 18:01:13 keithw Exp $
+
+# Mesa 3-D graphics library
+# Version:  5.0
+# Copyright (C) 1995-2002  Brian Paul
+
+TOP = ../../../../..
+
+SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver
+MINIGLX_INCLUDES = -I$(TOP)/src/miniglx 
+
+DEFINES += \
+       -D_HAVE_SWRAST=1 \
+       -D_HAVE_SWTNL=1 \
+       -D_HAVE_SANITY=1 \
+       -D_HAVE_CODEGEN=1 \
+       -D_HAVE_LIGHTING=1 \
+       -D_HAVE_TEXGEN=1 \
+       -D_HAVE_USERCLIP=1
+
+MINIGLX_SOURCES = server/mga_dri.c 
+
+DRIVER_SOURCES = mgabuffers.c \
+                mgadd.c \
+                mgaioctl.c \
+                mgarender.c \
+                mgastate.c \
+                mgatris.c \
+                ../common/mm.c 
+
+FULL_DRIVER_SOURCES =  \
+                mgapixel.c \
+                mgaspan.c \
+                mgatex.c \
+                mgatexcnv.c \
+                mgatexmem.c \
+                mgavb.c \
+                mga_xmesa.c
+
+
+INCLUDES = $(MINIGLX_INCLUDES) \
+          $(SHARED_INCLUDES)
+
+
+C_SOURCES = $(MINIGLX_SOURCES) \
+           $(FULL_DRIVER_SOURCES) \
+           $(DRIVER_SOURCES) 
+
+MESA_MODULES = $(TOP)/src/mesa/mesa.a
+
+
+ifeq ($(WINDOW_SYSTEM),dri)
+WINOBJ=$(MESABUILDDIR)/dri/dri.a
+WINLIB=
+else
+WINOBJ=
+WINLIB=-L$(MESA)/src/miniglx
+endif
+
+ASM_SOURCES = 
+OBJECTS = $(C_SOURCES:.c=.o) \
+         $(ASM_SOURCES:.S=.o) 
+
+
+
+### Include directories
+
+INCLUDE_DIRS = \
+       -I$(TOP)/include \
+       -I$(TOP)/src/mesa \
+       -I$(TOP)/src/mesa/main \
+       -I$(TOP)/src/mesa/glapi \
+       -I$(TOP)/src/mesa/math \
+       -I$(TOP)/src/mesa/transform \
+       -I$(TOP)/src/mesa/swrast \
+       -I$(TOP)/src/mesa/swrast_setup
+
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+.S.o:
+       $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES)  $< -o $@
+
+
+##### TARGETS #####
+
+targets: mga_dri.so
+
+mga_dri.so:  $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.X11
+       rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc -lm
+       rm -f $(TOP)/lib/mga_dri.so && \
+       install mga_dri.so $(TOP)/lib/mga_dri.so
+
+# Run 'make -f Makefile.X11 dep' to update the dependencies if you change
+# what's included by any source file.
+dep: $(C_SOURCES) $(ASM_SOURCES)
+       makedepend -fdepend -Y $(SHARED_INCLUDES) \
+               $(C_SOURCES) $(ASM_SOURCES)
+
+
+# Emacs tags
+tags:
+       etags `find . -name \*.[ch]` `find ../include`
+
+
+# Remove .o and backup files
+clean:
+       -rm -f *.o *~ *.o *~ *.so
+
+
+include $(TOP)/Make-config
+
+include depend
diff --git a/src/mesa/drivers/dri/mga/README b/src/mesa/drivers/dri/mga/README
new file mode 100644 (file)
index 0000000..a7133fa
--- /dev/null
@@ -0,0 +1,26 @@
+MGA DRI driver ported from XF86DRI to FBDRI
+by Denis Oliver Kropp <dok@directfb.org>
+
+
+INFO
+
+This driver has been ported from the head branch of XFree86 to
+the embedded-1-branch of Mesa.
+
+
+STATUS
+
+Already working very well as far as I've tested it (16/32 bit).
+glxgears runs at 935 fps (G550 32MB AGP 4x, Athlon 1.33) vs 744 fps with XFree.
+Other demos (terrain, fire, etc.) have been successfully tested as well.
+
+
+TODO
+
+- mgaEngineShutdown
+- mgaEngineRestore
+- SGRAM detection
+- remove some unused bits from server/*
+- subset driver support
+- mgaWaitForVBlank
+- deinitialization (from MGADRICloseScreen) a la radeonDestroyScreen
diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c
new file mode 100644 (file)
index 0000000..de1bcc2
--- /dev/null
@@ -0,0 +1,616 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.19 2003/03/26 20:43:49 tsi Exp $ */
+/*
+ * 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 <stdio.h>
+
+#include "mga_common.h"
+#include "mga_xmesa.h"
+#include "context.h"
+#include "matrix.h"
+/*#include "mmath.h"*/
+#include "simple_list.h"
+/*#include "mem.h"*/
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "array_cache/acache.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "mgadd.h"
+#include "mgastate.h"
+#include "mgatex.h"
+#include "mgaspan.h"
+#include "mgaioctl.h"
+#include "mgatris.h"
+#include "mgavb.h"
+#include "mgabuffers.h"
+#include "mgapixel.h"
+
+#include "mga_xmesa.h"
+
+#include "mga_dri.h"
+
+
+#ifndef MGA_DEBUG
+int MGA_DEBUG = (0
+/*              | DEBUG_ALWAYS_SYNC */
+/*              | DEBUG_VERBOSE_MSG */
+/*              | DEBUG_VERBOSE_LRU */
+/*              | DEBUG_VERBOSE_DRI */
+/*              | DEBUG_VERBOSE_IOCTL */
+/*              | DEBUG_VERBOSE_2D */
+/*              | DEBUG_VERBOSE_FALLBACK */
+   );
+#endif
+
+
+static GLboolean
+mgaInitDriver(__DRIscreenPrivate *sPriv)
+{
+   mgaScreenPrivate *mgaScreen;
+   MGADRIPtr         serverInfo = (MGADRIPtr)sPriv->pDevPriv;
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
+      fprintf(stderr, "mgaInitDriver\n");
+
+   /* Check that the DRM driver version is compatible */
+   if (sPriv->drmMajor != 3 ||
+       sPriv->drmMinor < 0) {
+      __driUtilMessage("MGA DRI driver expected DRM driver version 3.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch);
+      return GL_FALSE;
+   }
+
+
+   /* Allocate the private area */
+   mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate));
+   if (!mgaScreen) {
+      __driUtilMessage("Couldn't malloc screen struct");
+      return GL_FALSE;
+   }
+
+   mgaScreen->sPriv = sPriv;
+   sPriv->private = (void *)mgaScreen;
+
+   if (sPriv->drmMinor >= 1) {
+      int ret;
+      drmMGAGetParam gp;
+
+      gp.param = MGA_PARAM_IRQ_NR;
+      gp.value = (int *) &mgaScreen->irq;
+
+      ret = drmCommandWriteRead( sPriv->fd, DRM_MGA_GETPARAM,
+                                   &gp, sizeof(gp));
+      if (ret) {
+           fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret);
+           FREE(mgaScreen);
+           sPriv->private = NULL;
+           return GL_FALSE;
+      }
+   }
+   
+   if (serverInfo->chipset != MGA_CARD_TYPE_G200 &&
+       serverInfo->chipset != MGA_CARD_TYPE_G400) {
+      FREE(mgaScreen);
+      sPriv->private = NULL;
+      __driUtilMessage("Unrecognized chipset");
+      return GL_FALSE;
+   }
+
+
+   mgaScreen->chipset = serverInfo->chipset;
+   mgaScreen->width = serverInfo->width;
+   mgaScreen->height = serverInfo->height;
+   mgaScreen->mem = serverInfo->mem;
+   mgaScreen->cpp = serverInfo->cpp;
+
+   mgaScreen->agpMode = serverInfo->agpMode;
+
+   mgaScreen->frontPitch = serverInfo->frontPitch;
+   mgaScreen->frontOffset = serverInfo->frontOffset;
+   mgaScreen->backOffset = serverInfo->backOffset;
+   mgaScreen->backPitch  =  serverInfo->backPitch;
+   mgaScreen->depthOffset = serverInfo->depthOffset;
+   mgaScreen->depthPitch  =  serverInfo->depthPitch;
+
+   mgaScreen->mmio.handle = serverInfo->registers.handle;
+   mgaScreen->mmio.size = serverInfo->registers.size;
+   if ( drmMap( sPriv->fd,
+               mgaScreen->mmio.handle, mgaScreen->mmio.size,
+               &mgaScreen->mmio.map ) < 0 ) {
+      FREE( mgaScreen );
+      sPriv->private = NULL;
+      __driUtilMessage( "Couldn't map MMIO registers" );
+      return GL_FALSE;
+   }
+
+   mgaScreen->primary.handle = serverInfo->primary.handle;
+   mgaScreen->primary.size = serverInfo->primary.size;
+   mgaScreen->buffers.handle = serverInfo->buffers.handle;
+   mgaScreen->buffers.size = serverInfo->buffers.size;
+
+#if 0
+   mgaScreen->agp.handle = serverInfo->agp;
+   mgaScreen->agp.size = serverInfo->agpSize;
+
+   if (drmMap(sPriv->fd,
+             mgaScreen->agp.handle,
+             mgaScreen->agp.size,
+             (drmAddress *)&mgaScreen->agp.map) != 0)
+   {
+      Xfree(mgaScreen);
+      sPriv->private = NULL;
+      __driUtilMessage("Couldn't map agp region");
+      return GL_FALSE;
+   }
+#endif
+
+   mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset;
+   mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset |
+                                            PDEA_pagpxfer_enable | 1);
+
+   mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize;
+   mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize;
+
+   mgaScreen->logTextureGranularity[MGA_CARD_HEAP] =
+      serverInfo->logTextureGranularity;
+   mgaScreen->logTextureGranularity[MGA_AGP_HEAP] =
+      serverInfo->logAgpTextureGranularity;
+
+   mgaScreen->texVirtual[MGA_CARD_HEAP] = (char *)(mgaScreen->sPriv->pFB +
+                                          serverInfo->textureOffset);
+   if (drmMap(sPriv->fd,
+              serverInfo->agpTextureOffset,
+              serverInfo->agpTextureSize,
+              (drmAddress *)&mgaScreen->texVirtual[MGA_AGP_HEAP]) != 0)
+   {
+      free(mgaScreen);
+      sPriv->private = NULL;
+      __driUtilMessage("Couldn't map agptexture region");
+      return GL_FALSE;
+   }
+
+#if 0
+   mgaScreen->texVirtual[MGA_AGP_HEAP] = (mgaScreen->agp.map +
+                                         serverInfo->agpTextureOffset);
+#endif
+
+   mgaScreen->mAccess = serverInfo->mAccess;
+
+   /* For calculating setupdma addresses.
+    */
+   mgaScreen->dmaOffset = serverInfo->buffers.handle;
+
+   mgaScreen->bufs = drmMapBufs(sPriv->fd);
+   if (!mgaScreen->bufs) {
+      /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
+      FREE(mgaScreen);
+      sPriv->private = NULL;
+      __driUtilMessage("Couldn't map dma buffers");
+      return GL_FALSE;
+   }
+   mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset;
+
+   return GL_TRUE;
+}
+
+
+static void
+mgaDestroyScreen(__DRIscreenPrivate *sPriv)
+{
+   mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private;
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
+      fprintf(stderr, "mgaDestroyScreen\n");
+
+   /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
+   free(mgaScreen);
+   sPriv->private = NULL;
+}
+
+
+extern const struct gl_pipeline_stage _mga_render_stage;
+
+static const struct gl_pipeline_stage *mga_pipeline[] = {
+   &_tnl_vertex_transform_stage, 
+   &_tnl_normal_transform_stage, 
+   &_tnl_lighting_stage,       
+   &_tnl_fog_coordinate_stage,
+   &_tnl_texgen_stage, 
+   &_tnl_texture_transform_stage, 
+                               /* REMOVE: point attenuation stage */
+#if 0
+   &_mga_render_stage,         /* ADD: unclipped rastersetup-to-dma */
+                                /* Need new ioctl for wacceptseq */
+#endif
+   &_tnl_render_stage,         
+   0,
+};
+
+
+static GLboolean
+mgaCreateContext( const __GLcontextModes *mesaVis,
+                  __DRIcontextPrivate *driContextPriv,
+                  void *sharedContextPrivate )
+{
+   int i;
+   GLcontext *ctx, *shareCtx;
+   mgaContextPtr mmesa;
+   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private;
+   MGASAREAPrivPtr saPriv=(MGASAREAPrivPtr)(((char*)sPriv->pSAREA)+
+                                             mgaScreen->sarea_priv_offset);
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
+      fprintf(stderr, "mgaCreateContext\n");
+
+   /* allocate mga context */
+   mmesa = (mgaContextPtr) CALLOC(sizeof(mgaContext));
+   if (!mmesa) {
+      return GL_FALSE;
+   }
+
+   /* Allocate the Mesa context */
+   if (sharedContextPrivate)
+      shareCtx = ((mgaContextPtr) sharedContextPrivate)->glCtx;
+   else 
+      shareCtx = NULL;
+   mmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, mmesa, GL_TRUE);
+   if (!mmesa->glCtx) {
+      FREE(mmesa);
+      return GL_FALSE;
+   }
+   driContextPriv->driverPrivate = mmesa;
+
+   /* Init mga state */
+   mmesa->hHWContext = driContextPriv->hHWContext;
+   mmesa->driFd = sPriv->fd;
+   mmesa->driHwLock = &sPriv->pSAREA->lock;
+
+   mmesa->mgaScreen = mgaScreen;
+   mmesa->driScreen = sPriv;
+   mmesa->sarea = (void *)saPriv;
+   mmesa->glBuffer = NULL;
+
+   make_empty_list(&mmesa->SwappedOut);
+
+   mmesa->lastTexHeap = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1;
+
+   for (i = 0 ; i < mmesa->lastTexHeap ; i++) {
+      mmesa->texHeap[i] = mmInit( 0, mgaScreen->textureSize[i]);
+      make_empty_list(&mmesa->TexObjList[i]);
+   }
+
+   /* Set the maximum texture size small enough that we can guarentee
+    * that both texture units can bind a maximal texture and have them
+    * on the card at once.
+    */
+   ctx = mmesa->glCtx;
+   { 
+      int nr = 2;
+
+      if (mgaScreen->chipset == MGA_CARD_TYPE_G200)
+        nr = 1;
+
+      if (mgaScreen->textureSize[0] < nr*1024*1024) {
+        ctx->Const.MaxTextureLevels = 9;
+      } else if (mgaScreen->textureSize[0] < nr*4*1024*1024) {
+        ctx->Const.MaxTextureLevels = 10;
+      } else {
+        ctx->Const.MaxTextureLevels = 11;
+      }
+
+      ctx->Const.MaxTextureUnits = nr;
+   }
+
+   ctx->Const.MinLineWidth = 1.0;
+   ctx->Const.MinLineWidthAA = 1.0;
+   ctx->Const.MaxLineWidth = 10.0;
+   ctx->Const.MaxLineWidthAA = 10.0;
+   ctx->Const.LineWidthGranularity = 1.0;
+
+   mmesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
+
+   switch (mesaVis->depthBits) {
+   case 16: 
+      mmesa->depth_scale = 1.0/(GLdouble)0xffff; 
+      mmesa->depth_clear_mask = ~0;
+      mmesa->ClearDepth = 0xffff;
+      break;
+   case 24:
+      mmesa->depth_scale = 1.0/(GLdouble)0xffffff;
+      if (mmesa->hw_stencil) {
+        mmesa->depth_clear_mask = 0xffffff00;
+        mmesa->stencil_clear_mask = 0x000000ff;
+      } else
+        mmesa->depth_clear_mask = ~0;
+      mmesa->ClearDepth = 0xffffff00;
+      break;
+   case 32:
+      mmesa->depth_scale = 1.0/(GLdouble)0xffffffff;
+      mmesa->depth_clear_mask = ~0;
+      mmesa->ClearDepth = 0xffffffff;
+      break;
+   };
+
+   mmesa->haveHwStipple = GL_FALSE;
+   mmesa->RenderIndex = -1;            /* impossible value */
+   mmesa->new_state = ~0;
+   mmesa->dirty = ~0;
+   mmesa->vertex_format = 0;   
+   mmesa->CurrentTexObj[0] = 0;
+   mmesa->CurrentTexObj[1] = 0;
+   mmesa->tmu_source[0] = 0;
+   mmesa->tmu_source[1] = 1;
+
+   mmesa->texAge[0] = 0;
+   mmesa->texAge[1] = 0;
+   
+   /* Initialize the software rasterizer and helper modules.
+    */
+   _swrast_CreateContext( ctx );
+   _ac_CreateContext( ctx );
+   _tnl_CreateContext( ctx );
+   
+   _swsetup_CreateContext( ctx );
+
+   /* Install the customized pipeline:
+    */
+   _tnl_destroy_pipeline( ctx );
+   _tnl_install_pipeline( ctx, mga_pipeline );
+
+   /* Configure swrast to match hardware characteristics:
+    */
+   _swrast_allow_pixel_fog( ctx, GL_FALSE );
+   _swrast_allow_vertex_fog( ctx, GL_TRUE );
+
+   mmesa->primary_offset = mmesa->mgaScreen->primary.handle;
+
+   ctx->DriverCtx = (void *) mmesa;
+   mmesa->glCtx = ctx;
+
+   mgaDDExtensionsInit( ctx );
+
+   mgaDDInitStateFuncs( ctx );
+   mgaDDInitTextureFuncs( ctx );
+   mgaDDInitSpanFuncs( ctx );
+   mgaDDInitDriverFuncs( ctx );
+   mgaDDInitIoctlFuncs( ctx );
+   mgaDDInitPixelFuncs( ctx );
+   mgaDDInitTriFuncs( ctx );
+
+   mgaInitVB( ctx );
+   mgaInitState( mmesa );
+
+   driContextPriv->driverPrivate = (void *) mmesa;
+
+   return GL_TRUE;
+}
+
+static void
+mgaDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+   mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
+      fprintf(stderr, "mgaDestroyContext\n");
+
+   assert(mmesa); /* should never be null */
+   if (mmesa) {
+      _swsetup_DestroyContext( mmesa->glCtx );
+      _tnl_DestroyContext( mmesa->glCtx );
+      _ac_DestroyContext( mmesa->glCtx );
+      _swrast_DestroyContext( mmesa->glCtx );
+
+      mgaFreeVB( mmesa->glCtx );
+
+      /* free the Mesa context */
+      mmesa->glCtx->DriverCtx = NULL;
+      _mesa_destroy_context(mmesa->glCtx);
+      /* free the mga context */
+      FREE(mmesa);
+   }
+}
+
+
+static GLboolean
+mgaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
+                 __DRIdrawablePrivate *driDrawPriv,
+                 const __GLcontextModes *mesaVis,
+                 GLboolean isPixmap )
+{
+   if (isPixmap) {
+      return GL_FALSE; /* not implemented */
+   }
+   else {
+      GLboolean swStencil = (mesaVis->stencilBits > 0 && 
+                            mesaVis->depthBits != 24);
+
+      driDrawPriv->driverPrivate = (void *) 
+         _mesa_create_framebuffer(mesaVis,
+                                  GL_FALSE,  /* software depth buffer? */
+                                  swStencil,
+                                  mesaVis->accumRedBits > 0,
+                                  mesaVis->alphaBits > 0 );
+
+      return (driDrawPriv->driverPrivate != NULL);
+   }
+}
+
+
+static void
+mgaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+}
+
+
+static GLboolean
+mgaUnbindContext(__DRIcontextPrivate *driContextPriv)
+{
+   mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
+   if (mmesa)
+      mmesa->dirty = ~0;
+
+   return GL_TRUE;
+}
+
+static GLboolean
+mgaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    return GL_TRUE;
+}
+
+static GLboolean
+mgaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+    return GL_TRUE;
+}
+
+
+/* This looks buggy to me - the 'b' variable isn't used anywhere...
+ * Hmm - It seems that the drawable is already hooked in to
+ * driDrawablePriv.
+ *
+ * But why are we doing context initialization here???
+ */
+static GLboolean
+mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
+               __DRIdrawablePrivate *driDrawPriv,
+               __DRIdrawablePrivate *driReadPriv)
+{
+   fprintf(stderr, "%s\n", __FUNCTION__);
+
+   if (driContextPriv) {
+      mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
+
+      if (mmesa->driDrawable != driDrawPriv) {
+        mmesa->driDrawable = driDrawPriv;
+        mmesa->dirty = ~0; 
+        mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); 
+      }
+
+      _mesa_make_current2(mmesa->glCtx,
+                          (GLframebuffer *) driDrawPriv->driverPrivate,
+                          (GLframebuffer *) driReadPriv->driverPrivate);
+
+      if (!mmesa->glCtx->Viewport.Width)
+        _mesa_set_viewport(mmesa->glCtx, 0, 0,
+                            driDrawPriv->w, driDrawPriv->h);
+
+   }
+   else {
+      _mesa_make_current(NULL, NULL);
+   }
+
+   return GL_TRUE;
+}
+
+void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
+{
+   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+   MGASAREAPrivPtr sarea = mmesa->sarea;
+   int me = mmesa->hHWContext;
+   int i;
+
+   fprintf(stderr, "%s\n", __FUNCTION__);
+
+   drmGetLock(mmesa->driFd, mmesa->hHWContext, flags);
+   
+   fprintf(stderr, 
+          "mmesa->lastStamp %d dpriv->lastStamp %d *(dpriv->pStamp) %d\n",
+          mmesa->lastStamp, 
+          dPriv->lastStamp,
+          *(dPriv->pStamp));
+   
+   /* The window might have moved, so we might need to get new clip
+    * rects.
+    *
+    * NOTE: This releases and regrabs the hw lock to allow the X server
+    * to respond to the DRI protocol request for new drawable info.
+    * Since the hardware state depends on having the latest drawable
+    * clip rects, all state checking must be done _after_ this call.
+    */
+   DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
+
+   if ( mmesa->lastStamp == 0 ||
+       mmesa->lastStamp != dPriv->lastStamp ) {
+      mmesa->lastStamp = dPriv->lastStamp;
+      mmesa->SetupNewInputs |= VERT_BIT_CLIP;
+      mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
+      mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) );
+   }
+
+   mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
+
+   mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;
+
+   if (sarea->ctxOwner != me) {
+      mmesa->dirty |= (MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0 |
+                      MGA_UPLOAD_TEX1 | MGA_UPLOAD_PIPE);
+      sarea->ctxOwner=me;
+   }
+
+   for (i = 0 ; i < mmesa->lastTexHeap ; i++)
+      if (sarea->texAge[i] != mmesa->texAge[i])
+        mgaAgeTextures( mmesa, i );
+
+   sarea->last_quiescent = -1; /* just kill it for now */
+}
+
+
+
+static const struct __DriverAPIRec mgaAPI = {
+   mgaInitDriver,
+   mgaDestroyScreen,
+   mgaCreateContext,
+   mgaDestroyContext,
+   mgaCreateBuffer,
+   mgaDestroyBuffer,
+   mgaSwapBuffers,
+   mgaMakeCurrent,
+   mgaUnbindContext,
+   mgaOpenFullScreen,
+   mgaCloseFullScreen
+};
+
+
+
+/*
+ * This is the bootstrap function for the driver.
+ * The __driCreateScreen name is the symbol that libGL.so fetches.
+ * Return:  pointer to a __DRIscreenPrivate.
+ */
+void *__driCreateScreen(struct DRIDriverRec *driver,
+                        struct DRIDriverContextRec *driverContext)
+{
+   __DRIscreenPrivate *psp;
+   psp = __driUtilCreateScreen(driver, driverContext, &mgaAPI);
+   return (void *) psp;
+}
diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.h b/src/mesa/drivers/dri/mga/mga_xmesa.h
new file mode 100644 (file)
index 0000000..eda996f
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v 1.12 2002/12/16 16:18:52 dawes Exp $ */
+
+#ifndef _MGA_INIT_H_
+#define _MGA_INIT_H_
+
+#include <sys/time.h>
+#include <linux/types.h>
+#include "dri_util.h"
+#include "mtypes.h"
+#include "mgaregs.h"
+#include "mga_common.h"
+
+typedef struct mga_screen_private_s {
+
+   int chipset;
+   int width;
+   int height;
+   int mem;
+
+   int cpp;                    /* for front and back buffers */
+   GLint agpMode;
+   unsigned int irq;           /* IRQ number (0 means none) */
+
+   unsigned int mAccess;
+
+   unsigned int frontOffset;
+   unsigned int frontPitch;
+   unsigned int backOffset;
+   unsigned int backPitch;
+
+   unsigned int depthOffset;
+   unsigned int depthPitch;
+   int depthCpp;
+
+   unsigned int dmaOffset;
+
+   unsigned int textureOffset[DRM_MGA_NR_TEX_HEAPS];
+   unsigned int textureSize[DRM_MGA_NR_TEX_HEAPS];
+   int logTextureGranularity[DRM_MGA_NR_TEX_HEAPS];
+   char *texVirtual[DRM_MGA_NR_TEX_HEAPS];
+
+
+   __DRIscreenPrivate *sPriv;
+   drmBufMapPtr  bufs;
+
+   drmRegion mmio;
+   drmRegion status;
+   drmRegion primary;
+   drmRegion buffers;
+   unsigned int sarea_priv_offset;
+} mgaScreenPrivate;
+
+
+#include "mgacontext.h"
+
+extern void mgaGetLock( mgaContextPtr mmesa, GLuint flags );
+extern void mgaEmitHwStateLocked( mgaContextPtr mmesa );
+extern void mgaEmitScissorValues( mgaContextPtr mmesa, int box_nr, int emit );
+
+#define GET_DISPATCH_AGE( mmesa ) mmesa->sarea->last_dispatch
+#define GET_ENQUEUE_AGE( mmesa ) mmesa->sarea->last_enqueue
+
+
+
+/* Lock the hardware and validate our state.
+ */
+#define LOCK_HARDWARE( mmesa )                                 \
+  do {                                                         \
+    char __ret=0;                                              \
+    DRM_CAS(mmesa->driHwLock, mmesa->hHWContext,               \
+           (DRM_LOCK_HELD|mmesa->hHWContext), __ret);          \
+    if (__ret)                                                 \
+        mgaGetLock( mmesa, 0 );                                        \
+  } while (0)
+
+
+/*
+ */
+#define LOCK_HARDWARE_QUIESCENT( mmesa ) do {                          \
+       LOCK_HARDWARE( mmesa );                                         \
+       UPDATE_LOCK( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH );      \
+} while (0)
+
+
+/* Unlock the hardware using the global current context
+ */
+#define UNLOCK_HARDWARE(mmesa)                                 \
+    DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
+
+
+/* Freshen our snapshot of the drawables
+ */
+#define REFRESH_DRAWABLE_INFO( mmesa )         \
+do {                                           \
+   LOCK_HARDWARE( mmesa );                     \
+   mmesa->lastX = mmesa->drawX;                \
+   mmesa->lastY = mmesa->drawY;                \
+   UNLOCK_HARDWARE( mmesa );                   \
+} while (0)
+
+
+#define GET_DRAWABLE_LOCK( mmesa ) while(0)
+#define RELEASE_DRAWABLE_LOCK( mmesa ) while(0)
+
+
+/* The 2D driver macros are busted -- we can't use them here as they
+ * rely on the 2D driver data structures rather than taking an explicit
+ * base address.
+ */
+#define MGA_BASE( reg )                ((unsigned long)(mmesa->mgaScreen->mmio.map))
+#define MGA_ADDR( reg )                (MGA_BASE(reg) + reg)
+
+#define MGA_DEREF( reg )       *(volatile __u32 *)MGA_ADDR( reg )
+#define MGA_READ( reg )                MGA_DEREF( reg )
+#define MGA_WRITE( reg, val )  do { MGA_DEREF( reg ) = val; } while (0)
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgabuffers.c b/src/mesa/drivers/dri/mga/mgabuffers.c
new file mode 100644 (file)
index 0000000..1983356
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.13 2002/11/05 17:46:08 tsi Exp $ */
+
+#include <stdio.h>
+#include "mgacontext.h"
+#include "mgabuffers.h"
+#include "mgastate.h"
+#include "mgaioctl.h"
+#include "mgatris.h"
+
+static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa )
+{
+   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+
+/*   fprintf( stderr, "%s\n", __FUNCTION__ );*/
+
+   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 )
+{
+   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+
+/*   fprintf( stderr, "%s\n", __FUNCTION__ );*/
+
+   if (driDrawable->numBackClipRects == 0)
+   {
+      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;
+   } 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;
+}
+
+
+
+#if 0
+static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa )
+{
+   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+   __DRIscreenPrivate *driScreen = mmesa->driScreen;
+   MGASAREAPrivPtr sarea = mmesa->sarea;
+   int i = 0, top = 0;
+
+
+   if (sarea->exported_buffers & MGA_BACK) {
+
+      driDrawable->numBackClipRects = sarea->exported_nback;
+      driDrawable->pBackClipRects = mmesa->tmp_boxes[0];
+
+      top = sarea->exported_nback;
+      for (i = 0 ; i < top ; i++)
+        driDrawable->pBackClipRects[i] =
+           *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]);
+   }
+
+
+   if (sarea->exported_buffers & MGA_FRONT)
+   {
+      int start = top;
+
+      driDrawable->numClipRects = sarea->exported_nfront;
+      driDrawable->pClipRects = mmesa->tmp_boxes[1];
+
+      top += sarea->exported_nfront;
+      for ( ; i < top ; i++)
+        driDrawable->pClipRects[i-start] =
+           *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]);
+
+   }
+
+
+
+   driDrawable->index = sarea->exported_index;
+   driDrawable->lastStamp = sarea->exported_stamp;
+   driDrawable->x = sarea->exported_front_x;
+   driDrawable->y = sarea->exported_front_y;
+   driDrawable->backX = sarea->exported_back_x;
+   driDrawable->backY = sarea->exported_back_y;
+   driDrawable->w = sarea->exported_w;
+   driDrawable->h = sarea->exported_h;
+   driDrawable->pStamp =
+      &(driScreen->pSAREA->drawableTable[driDrawable->index].stamp);
+
+   mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK) & ~(sarea->exported_buffers);
+}
+#endif
+
+#if 0
+static void printSareaRects( mgaContextPtr mmesa )
+{
+   __DRIscreenPrivate *driScreen = mmesa->driScreen;
+   MGASAREAPrivPtr sarea = mmesa->sarea;
+   int i;
+
+   fprintf(stderr, "sarea->exported: %d\n", sarea->exported_drawable);
+   fprintf(stderr, "sarea->exported_index: %d\n", sarea->exported_index);
+   fprintf(stderr, "sarea->exported_stamp: %d\n", sarea->exported_stamp);
+   fprintf(stderr, "sarea->exported_front_x: %d\n", sarea->exported_front_x);
+   fprintf(stderr, "sarea->exported_front_y: %d\n", sarea->exported_front_y);
+   fprintf(stderr, "sarea->exported_back_x: %d\n", sarea->exported_back_x);
+   fprintf(stderr, "sarea->exported_back_y: %d\n", sarea->exported_back_y);
+   fprintf(stderr, "sarea->exported_w: %d\n", sarea->exported_w);
+   fprintf(stderr, "sarea->exported_h: %d\n", sarea->exported_h);
+   fprintf(stderr, "sarea->exported_buffers: %d\n", sarea->exported_buffers);
+   fprintf(stderr, "sarea->exported_nfront: %d\n", sarea->exported_nfront);
+   fprintf(stderr, "sarea->exported_nback: %d\n", sarea->exported_nback);
+
+   i = 0;
+   if (sarea->exported_buffers & MGA_BACK)
+      for ( ; i < sarea->exported_nback ; i++)
+        fprintf(stderr, "back %d: %d,%d-%d,%d\n", i,
+                sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1,
+                sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2);
+
+   if (sarea->exported_buffers & MGA_FRONT) {
+      int start = i;
+      int top = i + sarea->exported_nfront;
+      for ( ; i < top ; i++)
+        fprintf(stderr, "front %d: %d,%d-%d,%d\n",
+                i - start,
+                sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1,
+                sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2);
+   }
+
+   fprintf(stderr, "drawableTable[%d].stamp: %d\n",
+          sarea->exported_index,
+          driScreen->pSAREA->drawableTable[sarea->exported_index].stamp);
+}
+
+static void printMmesaRects( mgaContextPtr mmesa )
+{
+   __DRIscreenPrivate *driScreen = mmesa->driScreen;
+   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+   int nr = mmesa->numClipRects;
+   int i;
+
+   fprintf(stderr, "driDrawable->draw: %ld\n", driDrawable->draw);
+   fprintf(stderr, "driDrawable->index: %d\n", driDrawable->index);
+   fprintf(stderr, "driDrawable->lastStamp: %d\n", driDrawable->lastStamp);
+   fprintf(stderr, "mmesa->drawX: %d\n", mmesa->drawX);
+   fprintf(stderr, "mmesa->drawY: %d\n", mmesa->drawY);
+   fprintf(stderr, "driDrawable->w: %d\n", driDrawable->w);
+   fprintf(stderr, "driDrawable->h: %d\n", driDrawable->h);
+
+   for (i = 0 ; i < nr ; i++)
+      fprintf(stderr, "box %d: %d,%d-%d,%d\n", i,
+             mmesa->pClipRects[i].x1, mmesa->pClipRects[i].y1,
+             mmesa->pClipRects[i].x2, mmesa->pClipRects[i].y2);
+
+   fprintf(stderr, "mmesa->draw_buffer: %d\n", mmesa->draw_buffer);
+   fprintf(stderr, "drawableTable[%d].stamp: %d\n",
+          driDrawable->index,
+          driScreen->pSAREA->drawableTable[driDrawable->index].stamp);
+}
+#endif
+
+
+
+void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
+{
+   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+   MGASAREAPrivPtr sarea = mmesa->sarea;
+
+/*   fprintf(stderr, "%s\n", __FUNCTION__);*/
+
+   DRI_VALIDATE_DRAWABLE_INFO(driScreen, driDrawable); 
+   mmesa->dirty_cliprects = 0; 
+
+   if (mmesa->draw_buffer == MGA_FRONT)
+      mgaXMesaSetFrontClipRects( mmesa );
+   else
+      mgaXMesaSetBackClipRects( mmesa );
+
+#if 0
+   printMmesaRects(mmesa); 
+#endif
+
+   sarea->req_draw_buffer = mmesa->draw_buffer;
+
+   mgaUpdateClipping( mmesa->glCtx );
+   mgaCalcViewport( mmesa->glCtx );
+
+   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+}
+
+
+void mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   if (mode == GL_FRONT_LEFT) 
+   {
+      mmesa->readOffset = mmesa->mgaScreen->frontOffset;
+      mmesa->read_buffer = MGA_FRONT;
+   } 
+   else 
+   {
+      mmesa->readOffset = mmesa->mgaScreen->backOffset;
+      mmesa->read_buffer = MGA_BACK;
+   }
+}
+
+void mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+
+/*   fprintf( stderr, "%s %d\n", __FUNCTION__, mode);*/
+
+   /*
+    * _DrawDestMask is easier to cope with than <mode>.
+    */
+   switch ( ctx->Color._DrawDestMask ) {
+     case FRONT_LEFT_BIT:
+       mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
+       mmesa->readOffset = mmesa->mgaScreen->frontOffset;
+       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:
+       mmesa->drawOffset = mmesa->mgaScreen->backOffset;
+       mmesa->readOffset = mmesa->mgaScreen->backOffset;
+       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:
+       FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE );
+       break;
+   }
+}
+
diff --git a/src/mesa/drivers/dri/mga/mgabuffers.h b/src/mesa/drivers/dri/mga/mgabuffers.h
new file mode 100644 (file)
index 0000000..2307f13
--- /dev/null
@@ -0,0 +1,37 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.h,v 1.7 2002/10/30 12:51:35 alanh Exp $ */
+/*
+ * 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>
+ */
+
+#ifndef MGA_BUFFERS_H
+#define MGA_BUFFERS_H
+
+void mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode );
+void mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode );
+
+void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers );
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h
new file mode 100644 (file)
index 0000000..3065ea9
--- /dev/null
@@ -0,0 +1,309 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.7 2002/12/16 16:18:52 dawes Exp $*/
+/*
+ * 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>
+ */
+
+#ifndef MGALIB_INC
+#define MGALIB_INC
+
+/*#include <X11/Xlibint.h>*/
+#include "dri_util.h"
+#include "mtypes.h"
+#include "xf86drm.h"
+#include "mm.h"
+/*#include "mem.h"*/
+#include "mga_sarea.h"
+
+
+#define MGA_SET_FIELD(reg,mask,val)  reg = ((reg) & (mask)) | ((val) & ~(mask))
+#define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK))
+#define MGA_GET_FIELD(field, val) ((val & ~(field ## _MASK)) >> (field ## _SHIFT))
+
+#define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G200)
+#define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400)
+
+
+/* SoftwareFallback
+ *    - texture env GL_BLEND -- can be fixed
+ *    - 1D and 3D textures
+ *    - incomplete textures
+ *    - GL_DEPTH_FUNC == GL_NEVER not in h/w
+ */
+#define MGA_FALLBACK_TEXTURE        0x1
+#define MGA_FALLBACK_DRAW_BUFFER    0x2
+#define MGA_FALLBACK_READ_BUFFER    0x4
+#define MGA_FALLBACK_LOGICOP        0x8
+#define MGA_FALLBACK_RENDERMODE     0x10
+#define MGA_FALLBACK_STENCIL        0x20
+#define MGA_FALLBACK_DEPTH          0x40
+
+
+/* For mgaCtx->new_state.
+ */
+#define MGA_NEW_DEPTH   0x1
+#define MGA_NEW_ALPHA   0x2
+#define MGA_NEW_CLIP    0x8
+#define MGA_NEW_TEXTURE 0x20
+#define MGA_NEW_CULL    0x40
+#define MGA_NEW_WARP    0x80
+#define MGA_NEW_STENCIL 0x100
+#define MGA_NEW_CONTEXT 0x200
+
+/* Use the templated vertex formats:
+ */
+#define TAG(x) mga##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+typedef struct mga_context_t mgaContext;
+typedef struct mga_context_t *mgaContextPtr;
+
+typedef void (*mga_tri_func)( mgaContextPtr, mgaVertex *, mgaVertex *,
+                              mgaVertex * );
+typedef void (*mga_line_func)( mgaContextPtr, mgaVertex *, mgaVertex * );
+typedef void (*mga_point_func)( mgaContextPtr, mgaVertex * );
+
+
+
+/* Reasons why the GL_BLEND fallback mightn't work:
+ */
+#define MGA_BLEND_ENV_COLOR 0x1
+#define MGA_BLEND_MULTITEX  0x2
+
+struct mga_texture_object_s;
+struct mga_screen_private_s;
+
+#define MGA_TEX_MAXLEVELS 5
+
+typedef struct mga_texture_object_s
+{
+   struct mga_texture_object_s *next;
+   struct mga_texture_object_s *prev;
+   struct gl_texture_object *tObj;
+   struct mga_context_t *ctx;
+   PMemBlock   MemBlock;
+   GLuint              offsets[MGA_TEX_MAXLEVELS];
+   int             lastLevel;
+   GLuint         dirty_images;
+   GLuint              totalSize;
+   int         texelBytes;
+   GLuint      age;
+   int             bound;
+   int             heap;       /* agp or card */
+
+   mga_texture_regs_t setup;
+} mgaTextureObject_t;
+
+struct mga_context_t {
+
+   GLcontext *glCtx;
+   unsigned int lastStamp;     /* fullscreen breaks dpriv->laststamp,
+                                * need to shadow it here. */
+
+   /* Bookkeeping for texturing
+    */
+   int lastTexHeap;
+   struct mga_texture_object_s TexObjList[MGA_NR_TEX_HEAPS];
+   struct mga_texture_object_s SwappedOut;
+   struct mga_texture_object_s *CurrentTexObj[2];
+   memHeap_t *texHeap[MGA_NR_TEX_HEAPS];
+   int c_texupload;
+   int c_texusage;
+   int tex_thrash;
+
+
+   /* Map GL texture units onto hardware.
+    */
+   GLuint tmu_source[2];
+   
+   GLboolean default32BitTextures;
+
+   /* Manage fallbacks
+    */
+   GLuint Fallback;  
+
+
+   /* Temporaries for translating away float colors:
+    */
+   struct gl_client_array UbyteColor;
+   struct gl_client_array UbyteSecondaryColor;
+
+   /* Support for limited GL_BLEND fallback
+    */
+   unsigned int blend_flags;
+   unsigned int envcolor;
+
+   /* Rasterization state 
+    */
+   GLuint SetupNewInputs;
+   GLuint SetupIndex;
+   GLuint RenderIndex;
+   
+   GLuint hw_primitive;
+   GLenum raster_primitive;
+   GLenum render_primitive;
+
+   char *verts;
+   GLint vertex_stride_shift;
+   GLuint vertex_format;               
+   GLuint vertex_size;
+
+   /* Fallback rasterization functions 
+    */
+   mga_point_func draw_point;
+   mga_line_func draw_line;
+   mga_tri_func draw_tri;
+
+
+   /* Manage driver and hardware state
+    */
+   GLuint        new_gl_state; 
+   GLuint        new_state; 
+   GLuint        dirty;
+
+   mga_context_regs_t setup;
+
+   GLuint        ClearColor;
+   GLuint        ClearDepth;
+   GLuint        poly_stipple;
+   GLfloat       depth_scale;
+
+   GLuint        depth_clear_mask;
+   GLuint        stencil_clear_mask;
+   GLuint        hw_stencil;
+   GLuint        haveHwStipple;
+   GLfloat       hw_viewport[16];
+
+   /* Dma buffers
+    */
+   drmBufPtr  vertex_dma_buffer;
+   drmBufPtr  iload_buffer;
+
+   /* VBI
+    */
+   GLuint vbl_seq;
+
+   /* Drawable, cliprect and scissor information
+    */
+   int dirty_cliprects;                /* which sets of cliprects are uptodate? */
+   int draw_buffer;            /* which buffer are we rendering to */
+   unsigned int drawOffset;            /* draw buffer address in  space */
+   int read_buffer;
+   int readOffset;
+   int drawX, drawY;           /* origin of drawable in draw buffer */
+   int lastX, lastY;           /* detect DSTORG bug */
+   GLuint numClipRects;                /* cliprects for the draw buffer */
+   XF86DRIClipRectPtr pClipRects;
+   XF86DRIClipRectRec draw_rect;
+   XF86DRIClipRectRec scissor_rect;
+   int scissor;
+
+   XF86DRIClipRectRec tmp_boxes[2][MGA_NR_SAREA_CLIPRECTS];
+
+
+   /* Texture aging and DMA based aging.
+    */
+   unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age  */
+   unsigned int dirtyAge;              /* buffer age for synchronization */
+
+   GLuint primary_offset;
+
+   /* Mirrors of some DRI state.
+    */
+   GLframebuffer *glBuffer;
+   drmContext hHWContext;
+   drmLock *driHwLock;
+   int driFd;
+   __DRIdrawablePrivate *driDrawable;
+   __DRIscreenPrivate *driScreen;
+   struct mga_screen_private_s *mgaScreen;
+   MGASAREAPrivPtr sarea;
+};
+
+#define MGA_CONTEXT(ctx) ((mgaContextPtr)(ctx->DriverCtx))
+
+#define MGAPACKCOLOR555(r,g,b,a) \
+  ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+    ((a) ? 0x8000 : 0))
+
+#define MGAPACKCOLOR565(r,g,b) \
+  ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define MGAPACKCOLOR88(l, a) \
+  (((l) << 8) | (a))
+
+#define MGAPACKCOLOR888(r,g,b) \
+  (((r) << 16) | ((g) << 8) | (b))
+
+#define MGAPACKCOLOR8888(r,g,b,a) \
+  (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define MGAPACKCOLOR4444(r,g,b,a) \
+  ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+
+#define MGA_DEBUG 0
+#ifndef MGA_DEBUG
+extern int MGA_DEBUG;
+#endif
+
+#define DEBUG_ALWAYS_SYNC      0x1
+#define DEBUG_VERBOSE_MSG      0x2
+#define DEBUG_VERBOSE_LRU      0x4
+#define DEBUG_VERBOSE_DRI      0x8
+#define DEBUG_VERBOSE_IOCTL    0x10
+#define DEBUG_VERBOSE_2D       0x20
+#define DEBUG_VERBOSE_FALLBACK 0x40
+
+static __inline__ GLuint mgaPackColor(GLuint cpp,
+                                     GLubyte r, GLubyte g,
+                                     GLubyte b, GLubyte a)
+{
+  switch (cpp) {
+  case 2:
+    return MGAPACKCOLOR565(r,g,b);
+  case 4:
+    return MGAPACKCOLOR8888(r,g,b,a);
+  default:
+    return 0;
+  }
+}
+
+
+/*
+ * Subpixel offsets for window coordinates:
+ */
+#define SUBPIXEL_X (-0.5F)
+#define SUBPIXEL_Y (-0.5F + 0.125)
+
+
+#define MGA_WA_TRIANGLES     0x18000000
+#define MGA_WA_TRISTRIP_T0   0x02010200
+#define MGA_WA_TRIFAN_T0     0x01000408
+#define MGA_WA_TRISTRIP_T0T1 0x02010400
+#define MGA_WA_TRIFAN_T0T1   0x01000810
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgadd.c b/src/mesa/drivers/dri/mga/mgadd.c
new file mode 100644 (file)
index 0000000..6ce50e6
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.c,v 1.14 2002/10/30 12:51:35 alanh Exp $ */
+
+
+#include "mtypes.h"
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mm.h"
+#include "mgacontext.h"
+#include "mgadd.h"
+#include "mgastate.h"
+#include "mgaspan.h"
+#include "mgatex.h"
+#include "mgatris.h"
+#include "mgavb.h"
+#include "mga_xmesa.h"
+#include "extensions.h"
+#if defined(USE_X86_ASM)
+#include "X86/common_x86_asm.h"
+#endif
+
+#define MGA_DATE       "20020221"
+
+
+/***************************************
+ * Mesa's Driver Functions
+ ***************************************/
+
+
+static const GLubyte *mgaDDGetString( GLcontext *ctx, GLenum name )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   static char buffer[128];
+
+   switch ( name ) {
+   case GL_VENDOR:
+      return (GLubyte *) "VA Linux Systems Inc.";
+
+   case GL_RENDERER:
+      sprintf( buffer, "Mesa DRI %s " MGA_DATE,
+              MGA_IS_G400(mmesa) ? "G400" :
+              MGA_IS_G200(mmesa) ? "G200" : "MGA" );
+
+      /* Append any AGP-specific information.
+       */
+      switch ( mmesa->mgaScreen->agpMode ) {
+      case 1:
+        strncat( buffer, " AGP 1x", 7 );
+        break;
+      case 2:
+        strncat( buffer, " AGP 2x", 7 );
+        break;
+      case 4:
+        strncat( buffer, " AGP 4x", 7 );
+        break;
+      }
+
+      /* Append any CPU-specific information.
+       */
+#ifdef USE_X86_ASM
+      if ( _mesa_x86_cpu_features ) {
+        strncat( buffer, " x86", 4 );
+      }
+#endif
+#ifdef USE_MMX_ASM
+      if ( cpu_has_mmx ) {
+        strncat( buffer, "/MMX", 4 );
+      }
+#endif
+#ifdef USE_3DNOW_ASM
+      if ( cpu_has_3dnow ) {
+        strncat( buffer, "/3DNow!", 7 );
+      }
+#endif
+#ifdef USE_SSE_ASM
+      if ( cpu_has_xmm ) {
+        strncat( buffer, "/SSE", 4 );
+      }
+#endif
+      return (GLubyte *)buffer;
+
+   default:
+      return NULL;
+   }
+}
+
+
+
+static void mgaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   /* Need to lock to make sure the driDrawable is uptodate.  This
+    * information is used to resize Mesa's software buffers, so it has
+    * to be correct.
+    */
+   LOCK_HARDWARE( mmesa );
+   *width = mmesa->driDrawable->w;
+   *height = mmesa->driDrawable->h;
+   UNLOCK_HARDWARE( mmesa );
+}
+
+void mgaDDExtensionsInit( GLcontext *ctx )
+{
+   /* paletted_textures currently doesn't work, but we could fix them later */
+   /*
+   _mesa_enable_extension( ctx, "GL_EXT_shared_texture_palette" );
+   _mesa_enable_extension( ctx, "GL_EXT_paletted_texture" );
+   */
+
+   _mesa_enable_extension( ctx, "GL_ARB_texture_compression" );
+   _mesa_enable_extension( ctx, "GL_ARB_multisample" );
+
+   _mesa_enable_extension( ctx, "GL_SGIS_generate_mipmap" );
+
+   /* Turn on multitexture and texenv_add for the G400.
+    */
+   if (MGA_IS_G400(MGA_CONTEXT(ctx))) {
+      _mesa_enable_extension( ctx, "GL_ARB_multitexture" );
+      _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" );
+
+      _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" );
+
+#if defined (MESA_packed_depth_stencil)
+      _mesa_enable_extension( ctx, "GL_MESA_packed_depth_stencil" );
+#endif
+
+#if defined (MESA_experimetal_agp_allocator)
+      if (!getenv("MGA_DISABLE_AGP_ALLOCATOR"))  
+        _mesa_enable_extension( ctx, "GL_MESA_experimental_agp_allocator" );
+#endif
+   }
+}
+
+
+
+void mgaDDInitDriverFuncs( GLcontext *ctx )
+{
+   ctx->Driver.GetBufferSize = mgaBufferSize;
+   ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+   ctx->Driver.GetString = mgaDDGetString;
+}
diff --git a/src/mesa/drivers/dri/mga/mgadd.h b/src/mesa/drivers/dri/mga/mgadd.h
new file mode 100644 (file)
index 0000000..6072e6c
--- /dev/null
@@ -0,0 +1,37 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.h,v 1.3 2002/10/30 12:51:35 alanh Exp $ */
+/*
+ * 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>
+ */
+
+#ifndef MGADD_INC
+#define MGADD_INC
+
+#include "context.h"
+
+void mgaDDInitDriverFuncs( GLcontext *ctx );
+void mgaDDExtensionsInit( GLcontext *ctx );
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c
new file mode 100644 (file)
index 0000000..f88c878
--- /dev/null
@@ -0,0 +1,693 @@
+/*
+ * 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>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.16 2002/12/16 16:18:52 dawes Exp $ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "mtypes.h"
+#include "macros.h"
+#include "dd.h"
+#include "swrast/swrast.h"
+
+#include "mm.h"
+#include "mgacontext.h"
+#include "mgadd.h"
+#include "mgastate.h"
+#include "mgatex.h"
+#include "mgavb.h"
+#include "mgaioctl.h"
+#include "mgatris.h"
+#include "mgabuffers.h"
+
+
+#include "xf86drm.h"
+#include "mga_common.h"
+
+static void mga_iload_dma_ioctl(mgaContextPtr mmesa,
+                               unsigned long dest,
+                               int length)
+{
+   drmBufPtr buf = mmesa->iload_buffer;
+   drmMGAIload iload;
+   int ret, i;
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+      fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n",
+             buf->idx, (int) dest, length);
+
+   iload.idx = buf->idx;
+   iload.dstorg = dest;
+   iload.length = length;
+
+   i = 0;
+   do {
+      ret = drmCommandWrite( mmesa->driFd, DRM_MGA_ILOAD, 
+                             &iload, sizeof(drmMGAIload) );
+   } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );
+
+   if ( ret < 0 ) {
+      printf("send iload retcode = %d\n", ret);
+      exit(1);
+   }
+
+   mmesa->iload_buffer = 0;
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+      fprintf(stderr, "finished iload dma put\n");
+
+}
+
+drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa )
+{
+   int idx = 0;
+   int size = 0;
+   drmDMAReq dma;
+   int retcode;
+   drmBufPtr buf;
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+      fprintf(stderr,  "Getting dma buffer\n");
+
+   dma.context = mmesa->hHWContext;
+   dma.send_count = 0;
+   dma.send_list = NULL;
+   dma.send_sizes = NULL;
+   dma.flags = 0;
+   dma.request_count = 1;
+   dma.request_size = MGA_BUFFER_SIZE;
+   dma.request_list = &idx;
+   dma.request_sizes = &size;
+   dma.granted_count = 0;
+
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+      fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n",
+          dma.context, dma.request_count,
+          dma.request_size);
+
+   while (1) {
+      retcode = drmDMA(mmesa->driFd, &dma);
+
+      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+        fprintf(stderr, "retcode %d sz %d idx %d count %d\n",
+                retcode,
+                dma.request_sizes[0],
+                dma.request_list[0],
+                dma.granted_count);
+
+      if (retcode == 0 &&
+         dma.request_sizes[0] &&
+         dma.granted_count)
+        break;
+
+      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+        fprintf(stderr, "\n\nflush");
+
+      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
+   }
+
+   buf = &(mmesa->mgaScreen->bufs->list[idx]);
+   buf->used = 0;
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+      fprintf(stderr,
+          "drmDMA (get) returns size[0] 0x%x idx[0] %d\n"
+          "dma_buffer now: buf idx: %d size: %d used: %d addr %p\n",
+          dma.request_sizes[0], dma.request_list[0],
+          buf->idx, buf->total,
+          buf->used, buf->address);
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+      fprintf(stderr, "finished getbuffer\n");
+
+   return buf;
+}
+
+
+
+
+static void
+mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+            GLint cx, GLint cy, GLint cw, GLint ch )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+   GLuint flags = 0;
+   GLuint clear_color = mmesa->ClearColor;
+   GLuint clear_depth = 0;
+   GLuint color_mask = 0;
+   GLuint depth_mask = 0;
+   int ret;
+   int i;
+   static int nrclears;
+   drmMGAClearRec clear;
+
+   FLUSH_BATCH( mmesa );
+
+   if ( mask & DD_FRONT_LEFT_BIT ) {
+      flags |= MGA_FRONT;
+      color_mask = mmesa->setup.plnwt;
+      mask &= ~DD_FRONT_LEFT_BIT;
+   }
+
+   if ( mask & DD_BACK_LEFT_BIT ) {
+      flags |= MGA_BACK;
+      color_mask = mmesa->setup.plnwt;
+      mask &= ~DD_BACK_LEFT_BIT;
+   }
+
+   if ( (mask & DD_DEPTH_BIT) && ctx->Depth.Mask ) {
+      flags |= MGA_DEPTH;
+      clear_depth = (mmesa->ClearDepth & mmesa->depth_clear_mask);
+      depth_mask |= mmesa->depth_clear_mask;
+      mask &= ~DD_DEPTH_BIT;
+   }
+
+   if ( (mask & DD_STENCIL_BIT) && mmesa->hw_stencil ) {
+      flags |= MGA_DEPTH;
+      clear_depth |= (ctx->Stencil.Clear & mmesa->stencil_clear_mask);
+      depth_mask |= mmesa->stencil_clear_mask;
+      mask &= ~DD_STENCIL_BIT;
+   }
+
+   if ( flags ) {
+      LOCK_HARDWARE( mmesa );
+
+      if ( mmesa->dirty_cliprects )
+        mgaUpdateRects( mmesa, (MGA_FRONT | MGA_BACK) );
+
+      /* flip top to bottom */
+      cy = dPriv->h-cy-ch;
+      cx += mmesa->drawX;
+      cy += mmesa->drawY;
+
+      if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
+        fprintf( stderr, "Clear, bufs %x nbox %d\n",
+                 (int)flags, (int)mmesa->numClipRects );
+
+      for (i = 0 ; i < mmesa->numClipRects ; )
+      {
+        int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects);
+        XF86DRIClipRectPtr box = mmesa->pClipRects;
+        XF86DRIClipRectPtr b = mmesa->sarea->boxes;
+        int n = 0;
+
+        if (!all) {
+           for ( ; i < nr ; i++) {
+              GLint x = box[i].x1;
+              GLint y = box[i].y1;
+              GLint w = box[i].x2 - x;
+              GLint h = box[i].y2 - y;
+
+              if (x < cx) w -= cx - x, x = cx;
+              if (y < cy) h -= cy - y, y = cy;
+              if (x + w > cx + cw) w = cx + cw - x;
+              if (y + h > cy + ch) h = cy + ch - y;
+              if (w <= 0) continue;
+              if (h <= 0) continue;
+
+              b->x1 = x;
+              b->y1 = y;
+              b->x2 = x + w;
+              b->y2 = y + h;
+              b++;
+              n++;
+           }
+        } else {
+           for ( ; i < nr ; i++) {
+              *b++ = *(XF86DRIClipRectPtr)&box[i];
+              n++;
+           }
+        }
+
+
+        if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
+           fprintf( stderr,
+                    "DRM_IOCTL_MGA_CLEAR flag 0x%x color %x depth %x nbox %d\n",
+                    flags, clear_color, clear_depth, mmesa->sarea->nbox );
+
+        mmesa->sarea->nbox = n;
+
+         clear.flags = flags;
+         clear.clear_color = clear_color;
+         clear.clear_depth = clear_depth;
+         clear.color_mask = color_mask;
+         clear.depth_mask = depth_mask;
+         ret = drmCommandWrite( mmesa->driFd, DRM_MGA_CLEAR,
+                                 &clear, sizeof(drmMGAClearRec));
+        if ( ret ) {
+           fprintf( stderr, "send clear retcode = %d\n", ret );
+           exit( 1 );
+        }
+        if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
+           fprintf( stderr, "finished clear %d\n", ++nrclears );
+      }
+
+      UNLOCK_HARDWARE( mmesa );
+      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS|MGA_UPLOAD_CONTEXT;
+   }
+
+   if (mask) 
+      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
+}
+
+
+int nrswaps;
+
+
+void mgaWaitForVBlank( mgaContextPtr mmesa )
+{
+#if 0
+    drmVBlank vbl;
+    int ret;
+
+    if ( !mmesa->mgaScreen->irq )
+       return;
+
+    if ( getenv("LIBGL_SYNC_REFRESH") ) {
+       /* Wait for until the next vertical blank */
+       vbl.request.type = DRM_VBLANK_RELATIVE;
+       vbl.request.sequence = 1;
+    } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) {
+       /* Wait for at least one vertical blank since the last call */
+       vbl.request.type = DRM_VBLANK_ABSOLUTE;
+       vbl.request.sequence = mmesa->vbl_seq + 1;
+    } else {
+       return;
+    }
+
+    if ((ret = drmWaitVBlank( mmesa->driFd, &vbl ))) {
+       fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be"
+               " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH"
+               " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret);
+       exit(1);
+    }
+
+    mmesa->vbl_seq = vbl.reply.sequence;
+#endif
+}
+
+
+/*
+ * Copy the back buffer to the front buffer.
+ */
+void mgaSwapBuffers(__DRIdrawablePrivate *dPriv)
+{
+   mgaContextPtr mmesa;
+   XF86DRIClipRectPtr pbox;
+   GLint nbox;
+   GLint ret, wait = 0;
+   GLint i;
+   GLuint last_frame, last_wrap;
+
+   assert(dPriv);
+   assert(dPriv->driContextPriv);
+   assert(dPriv->driContextPriv->driverPrivate);
+
+   mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;
+
+   FLUSH_BATCH( mmesa );
+
+   mgaWaitForVBlank( mmesa );
+
+   LOCK_HARDWARE( mmesa );
+
+   last_frame = mmesa->sarea->last_frame.head;
+   last_wrap = mmesa->sarea->last_frame.wrap;
+
+   /* FIXME: Add a timeout to this loop...
+    */
+   while ( 1 ) {
+      if ( last_wrap < mmesa->sarea->last_wrap ||
+          ( last_wrap == mmesa->sarea->last_wrap &&
+            last_frame <= (MGA_READ( MGAREG_PRIMADDRESS ) -
+                           mmesa->primary_offset) ) ) {
+        break;
+      }
+      if ( 0 ) {
+        wait++;
+        fprintf( stderr, "   last: head=0x%06x wrap=%d\n",
+                 last_frame, last_wrap );
+        fprintf( stderr, "   head: head=0x%06lx wrap=%d\n",
+                 (long)(MGA_READ( MGAREG_PRIMADDRESS ) - mmesa->primary_offset),
+                 mmesa->sarea->last_wrap );
+      }
+      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
+
+      for ( i = 0 ; i < 1024 ; i++ ) {
+        /* Don't just hammer the register... */
+      }
+   }
+   if ( wait )
+      fprintf( stderr, "\n" );
+
+   /* Use the frontbuffer cliprects
+    */
+   if (mmesa->dirty_cliprects & MGA_FRONT)
+      mgaUpdateRects( mmesa, MGA_FRONT );
+
+
+   pbox = dPriv->pClipRects;
+   nbox = dPriv->numClipRects;
+
+   for (i = 0 ; i < nbox ; )
+   {
+      int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+      XF86DRIClipRectPtr b = mmesa->sarea->boxes;
+
+      mmesa->sarea->nbox = nr - i;
+
+      for ( ; i < nr ; i++)
+        *b++ = pbox[i];
+
+      if (0)
+        fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n");
+
+      ret = drmCommandNone( mmesa->driFd, DRM_MGA_SWAP );
+      if ( ret ) {
+        printf("send swap retcode = %d\n", ret);
+        exit(1);
+      }
+   }
+
+   UNLOCK_HARDWARE( mmesa );
+
+   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+}
+
+
+/* This is overkill
+ */
+void mgaDDFinish( GLcontext *ctx  )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   FLUSH_BATCH( mmesa );
+
+   if (1/*mmesa->sarea->last_quiescent != mmesa->sarea->last_enqueue*/) {
+      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+        fprintf(stderr, "mgaRegetLockQuiescent\n");
+
+      LOCK_HARDWARE( mmesa );
+      UPDATE_LOCK( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH );
+      UNLOCK_HARDWARE( mmesa );
+
+      mmesa->sarea->last_quiescent = mmesa->sarea->last_enqueue;
+   }
+}
+
+void mgaWaitAgeLocked( mgaContextPtr mmesa, int age  )
+{
+   if (GET_DISPATCH_AGE(mmesa) < age) {
+      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
+   }
+}
+
+
+void mgaWaitAge( mgaContextPtr mmesa, int age  )
+{
+   if (GET_DISPATCH_AGE(mmesa) < age) {
+      LOCK_HARDWARE(mmesa);
+      if (GET_DISPATCH_AGE(mmesa) < age) {
+        UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
+      }
+      UNLOCK_HARDWARE(mmesa);
+   }
+}
+
+
+static int intersect_rect( XF86DRIClipRectPtr out,
+                          XF86DRIClipRectPtr a,
+                          XF86DRIClipRectPtr b )
+{
+   *out = *a;
+   if (b->x1 > out->x1) out->x1 = b->x1;
+   if (b->y1 > out->y1) out->y1 = b->y1;
+   if (b->x2 < out->x2) out->x2 = b->x2;
+   if (b->y2 < out->y2) out->y2 = b->y2;
+   if (out->x1 > out->x2) return 0;
+   if (out->y1 > out->y2) return 0;
+   return 1;
+}
+
+
+
+
+static void age_mmesa( mgaContextPtr mmesa, int age )
+{
+   if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->age = age;
+   if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->age = age;
+}
+
+#ifdef __i386__
+static int __break_vertex = 0;
+#endif
+
+void mgaFlushVerticesLocked( mgaContextPtr mmesa )
+{
+   XF86DRIClipRectPtr pbox = mmesa->pClipRects;
+   int nbox = mmesa->numClipRects;
+   drmBufPtr buffer = mmesa->vertex_dma_buffer;
+   drmMGAVertex vertex;
+   int i;
+
+   mmesa->vertex_dma_buffer = 0;
+
+   if (!buffer)
+      return;
+
+   if (mmesa->dirty_cliprects & mmesa->draw_buffer)
+      mgaUpdateRects( mmesa, mmesa->draw_buffer );
+
+   if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS)
+      mgaEmitHwStateLocked( mmesa );
+
+   /* FIXME: Workaround bug in kernel module.
+    */
+   mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;
+
+   if (!nbox)
+      buffer->used = 0;
+
+   if (nbox >= MGA_NR_SAREA_CLIPRECTS)
+      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+
+#if 0
+   if (!buffer->used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS))
+   {
+      if (nbox == 1)
+        mmesa->sarea->nbox = 0;
+      else
+        mmesa->sarea->nbox = nbox;
+
+      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+        fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox);
+
+      vertex.idx = buffer->idx;
+      vertex.used = buffer->used;
+      vertex.discard = 1;
+      drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, 
+                       &vertex, sizeof(drmMGAVertex) );
+
+      age_mmesa(mmesa, mmesa->sarea->last_enqueue);
+   }
+   else
+#endif
+   {
+      for (i = 0 ; i < nbox ; )
+      {
+        int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
+        XF86DRIClipRectPtr b = mmesa->sarea->boxes;
+        int discard = 0;
+
+        if (mmesa->scissor) {
+           mmesa->sarea->nbox = 0;
+
+           for ( ; i < nr ; i++) {
+              *b = pbox[i];
+              if (intersect_rect(b, b, &mmesa->scissor_rect)) {
+                 mmesa->sarea->nbox++;
+                 b++;
+              }
+           }
+
+           /* Culled?
+            */
+           if (!mmesa->sarea->nbox) {
+              if (nr < nbox) continue;
+              buffer->used = 0;
+           }
+        } else {
+           mmesa->sarea->nbox = nr - i;
+           for ( ; i < nr ; i++)
+              *b++ = pbox[i];
+        }
+
+        /* Finished with the buffer?
+         */
+        if (nr == nbox)
+           discard = 1;
+
+        mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS;
+
+         vertex.idx = buffer->idx;
+         vertex.used = buffer->used;
+         vertex.discard = discard;
+         drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, 
+                          &vertex, sizeof(drmMGAVertex) );
+
+        age_mmesa(mmesa, mmesa->sarea->last_enqueue);
+      }
+   }
+
+   /* Do we really need to do this ? */
+#ifdef __i386__
+   if ( __break_vertex ) {
+      __asm__ __volatile__ ( "int $3" );
+   }
+#endif
+
+   mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS;
+}
+
+void mgaFlushVertices( mgaContextPtr mmesa )
+{
+   LOCK_HARDWARE( mmesa );
+   mgaFlushVerticesLocked( mmesa );
+   UNLOCK_HARDWARE( mmesa );
+}
+
+
+void mgaFireILoadLocked( mgaContextPtr mmesa,
+                        GLuint offset, GLuint length )
+{
+   if (!mmesa->iload_buffer) {
+      fprintf(stderr, "mgaFireILoad: no buffer\n");
+      return;
+   }
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+      fprintf(stderr, "mgaFireILoad idx %d ofs 0x%x length %d\n",
+             mmesa->iload_buffer->idx, (int)offset, (int)length );
+
+   mga_iload_dma_ioctl( mmesa, offset, length );
+}
+
+void mgaGetILoadBufferLocked( mgaContextPtr mmesa )
+{
+   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+      fprintf(stderr, "mgaGetIloadBuffer (buffer now %p)\n",
+          mmesa->iload_buffer);
+
+   mmesa->iload_buffer = mga_get_buffer_ioctl( mmesa );
+}
+
+drmBufPtr mgaGetBufferLocked( mgaContextPtr mmesa )
+{
+   return mga_get_buffer_ioctl( mmesa );
+}
+
+
+
+void mgaDDFlush( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
+
+   FLUSH_BATCH( mmesa );
+
+   /* This may be called redundantly - dispatch_age may trail what
+    * has actually been sent and processed by the hardware.
+    */
+   if (1 || GET_DISPATCH_AGE( mmesa ) < mmesa->sarea->last_enqueue) {
+      LOCK_HARDWARE( mmesa );
+      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );
+      UNLOCK_HARDWARE( mmesa );
+   }
+}
+
+
+
+
+void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer )
+{
+   drmMGAVertex vertex;
+
+   if (!buffer) return;
+
+   vertex.idx = buffer->idx;
+   vertex.used = 0;
+   vertex.discard = 1;
+   drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, 
+                    &vertex, sizeof(drmMGAVertex) );
+}
+
+int mgaFlushDMA( int fd, drmLockFlags flags )
+{
+   drmMGALock lock;
+   int ret, i = 0;
+
+   memset( &lock, 0, sizeof(drmMGALock) );
+
+   if ( flags & DRM_LOCK_QUIESCENT )    lock.flags |= DRM_LOCK_QUIESCENT;
+   if ( flags & DRM_LOCK_FLUSH )        lock.flags |= DRM_LOCK_FLUSH;
+   if ( flags & DRM_LOCK_FLUSH_ALL )    lock.flags |= DRM_LOCK_FLUSH_ALL;
+
+   do {
+      ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(drmMGALock) );
+   } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY );
+
+   if ( ret == 0 )
+      return 0;
+   if ( errno != EBUSY )
+      return -errno;
+
+   if ( lock.flags & DRM_LOCK_QUIESCENT ) {
+      /* Only keep trying if we need quiescence.
+       */
+      lock.flags &= ~(DRM_LOCK_FLUSH | DRM_LOCK_FLUSH_ALL);
+
+      do {
+         ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(drmMGALock) );
+      } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY );
+   }
+
+   if ( ret == 0 ) {
+      return 0;
+   } else {
+      return -errno;
+   }
+}
+
+void mgaDDInitIoctlFuncs( GLcontext *ctx )
+{
+   ctx->Driver.Clear = mgaDDClear;
+   ctx->Driver.Flush = mgaDDFlush;
+   ctx->Driver.Finish = mgaDDFinish;
+}
diff --git a/src/mesa/drivers/dri/mga/mgaioctl.h b/src/mesa/drivers/dri/mga/mgaioctl.h
new file mode 100644 (file)
index 0000000..b7cf44d
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v 1.11 2002/10/30 12:51:36 alanh Exp $ */
+
+#ifndef MGA_IOCTL_H
+#define MGA_IOCTL_H
+
+#include "mgacontext.h"
+#include "mga_xmesa.h"
+
+void mgaSwapBuffers( __DRIdrawablePrivate *dPriv );
+
+GLuint *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords );
+
+
+void mgaGetILoadBufferLocked( mgaContextPtr mmesa );
+drmBufPtr mgaGetBufferLocked( mgaContextPtr mmesa );
+
+void mgaWaitForVBlank( mgaContextPtr mmesa );
+
+void mgaFireILoadLocked( mgaContextPtr mmesa,
+                        GLuint offset, GLuint length );
+
+void mgaWaitAgeLocked( mgaContextPtr mmesa, int age );
+void mgaWaitAge( mgaContextPtr mmesa, int age );
+
+void mgaFlushVertices( mgaContextPtr mmesa );
+void mgaFlushVerticesLocked( mgaContextPtr mmesa );
+void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer );
+int mgaFlushDMA( int fd, drmLockFlags flags );
+
+void mgaDDFlush( GLcontext *ctx );
+void mgaDDFinish( GLcontext *ctx );
+
+void mgaDDInitIoctlFuncs( GLcontext *ctx );
+
+#define FLUSH_BATCH(mmesa) do {                                                \
+        if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)                             \
+              fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__);    \
+       if (mmesa->vertex_dma_buffer) mgaFlushVertices(mmesa);          \
+} while (0)
+
+#define MGA_STATECHANGE(mmesa, flag) do {      \
+   FLUSH_BATCH(mmesa);                         \
+   mmesa->dirty |= flag;                       \
+} while (0)
+
+
+extern drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa );
+
+static __inline
+GLuint *mgaAllocDmaLow( mgaContextPtr mmesa, int bytes )
+{
+   GLuint *head;
+
+   if (!mmesa->vertex_dma_buffer) {
+      LOCK_HARDWARE( mmesa );
+      mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa );
+      UNLOCK_HARDWARE( mmesa );
+   } else if (mmesa->vertex_dma_buffer->used + bytes >
+             mmesa->vertex_dma_buffer->total) {
+      LOCK_HARDWARE( mmesa );
+      mgaFlushVerticesLocked( mmesa );
+      mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa );
+      UNLOCK_HARDWARE( mmesa );
+   }
+
+   head = (GLuint *)((char *)mmesa->vertex_dma_buffer->address +
+                     mmesa->vertex_dma_buffer->used);
+
+   mmesa->vertex_dma_buffer->used += bytes;
+   return head;
+}
+
+
+#define UPDATE_LOCK( mmesa, flags )                                    \
+do {                                                                   \
+   GLint ret = mgaFlushDMA( mmesa->driFd, flags );                     \
+   if ( ret < 0 ) {                                                    \
+      drmCommandNone( mmesa->driFd, DRM_MGA_RESET );                   \
+      UNLOCK_HARDWARE( mmesa );                                                \
+      fprintf( stderr, "%s: flush ret=%d\n", __FUNCTION__, ret );      \
+      /*fprintf( stderr, "drmMGAFlushDMA: return = %d\n", ret );*/     \
+      exit( 1 );                                                       \
+   }                                                                   \
+} while (0)
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgapixel.c b/src/mesa/drivers/dri/mga/mgapixel.c
new file mode 100644 (file)
index 0000000..0bc4b3f
--- /dev/null
@@ -0,0 +1,690 @@
+/*
+ * Copyright 2000 Compaq Computer Inc. and 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>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.c,v 1.9 2002/11/05 17:46:08 tsi Exp $ */
+
+#include "enums.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "texutil.h"
+#include "mgadd.h"
+#include "mgacontext.h"
+#include "mgaioctl.h"
+#include "mgapixel.h"
+#include "mgabuffers.h"
+
+#include "xf86drm.h"
+#include "mga_common.h"
+
+#include "swrast/swrast.h"
+
+#define IS_AGP_MEM( mmesa, p )                                           \
+   ((unsigned long)mmesa->mgaScreen->buffers.map <= ((unsigned long)p) && \
+    (unsigned long)mmesa->mgaScreen->buffers.map +                       \
+    (unsigned long)mmesa->mgaScreen->buffers.size > ((unsigned long)p))
+#define AGP_OFFSET( mmesa, p )                                           \
+     (((unsigned long)p) - (unsigned long)mmesa->mgaScreen->buffers.map)
+
+
+#if defined(MESA_packed_depth_stencil)
+static GLboolean
+check_depth_stencil_24_8( const GLcontext *ctx, GLenum type,
+                         const struct gl_pixelstore_attrib *packing,
+                         const void *pixels, GLint sz,
+                         GLint pitch )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   return ( type == GL_UNSIGNED_INT_24_8_MESA &&
+           ctx->Visual->DepthBits == 24 &&
+           ctx->Visual->StencilBits == 8 &&
+           mmesa->mgaScreen->cpp == 4 &&
+           mmesa->hw_stencil &&
+           !ctx->Pixel.IndexShift &&
+           !ctx->Pixel.IndexOffset &&
+           !ctx->Pixel.MapStencilFlag &&
+           ctx->Pixel.DepthBias == 0.0 &&
+           ctx->Pixel.DepthScale == 1.0 &&
+           !packing->SwapBytes &&
+           pitch % 32 == 0 &&
+           pitch < 4096 );
+}
+#endif
+
+
+static GLboolean
+check_depth( const GLcontext *ctx, GLenum type,
+            const struct gl_pixelstore_attrib *packing,
+            const void *pixels, GLint sz, GLint pitch )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   if ( IS_AGP_MEM( mmesa, pixels ) &&
+       !( ( type == GL_UNSIGNED_INT && mmesa->mgaScreen->cpp == 4 ) ||
+          ( type == GL_UNSIGNED_SHORT && mmesa->mgaScreen->cpp == 2 ) ) )
+      return GL_FALSE;
+
+   return ( ctx->Pixel.DepthBias == 0.0 &&
+           ctx->Pixel.DepthScale == 1.0 &&
+           !packing->SwapBytes &&
+           pitch % 32 == 0 &&
+           pitch < 4096 );
+}
+
+
+static GLboolean
+check_color( const GLcontext *ctx, GLenum type, GLenum format,
+            const struct gl_pixelstore_attrib *packing,
+            const void *pixels, GLint sz, GLint pitch )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLuint cpp = mmesa->mgaScreen->cpp;
+
+   /* Can't do conversions on agp reads/draws.
+    */
+   if ( IS_AGP_MEM( mmesa, pixels ) &&
+       !( pitch % 32 == 0 && pitch < 4096 &&
+          ( ( type == GL_UNSIGNED_BYTE &&
+              cpp == 4 && format == GL_BGRA ) ||
+            ( type == GL_UNSIGNED_INT_8_8_8_8 &&
+              cpp == 4 && format == GL_BGRA ) ||
+            ( type == GL_UNSIGNED_SHORT_5_6_5_REV &&
+              cpp == 2 && format == GL_RGB ) ) ) )
+      return GL_FALSE;
+
+   return (!ctx->_ImageTransferState &&
+          !packing->SwapBytes &&
+          !packing->LsbFirst);
+}
+
+static GLboolean
+check_color_per_fragment_ops( const GLcontext *ctx )
+{
+   return (!(       ctx->Color.AlphaEnabled ||
+                   ctx->Depth.Test ||
+                   ctx->Fog.Enabled ||
+                   ctx->Scissor.Enabled ||
+                   ctx->Stencil.Enabled ||
+                   !ctx->Color.ColorMask[0] ||
+                   !ctx->Color.ColorMask[1] ||
+                   !ctx->Color.ColorMask[2] ||
+                   !ctx->Color.ColorMask[3] ||
+                   ctx->Color.ColorLogicOpEnabled ||
+                   ctx->Texture.Unit[0]._ReallyEnabled ||
+                   ctx->Depth.OcclusionTest
+           ) &&
+          ctx->Current.RasterPosValid &&
+          ctx->Pixel.ZoomX == 1.0F &&
+          (ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F));
+}
+
+static GLboolean
+check_depth_per_fragment_ops( const GLcontext *ctx )
+{
+   return ( ctx->Current.RasterPosValid &&
+           ctx->Color.ColorMask[RCOMP] == 0 &&
+           ctx->Color.ColorMask[BCOMP] == 0 &&
+           ctx->Color.ColorMask[GCOMP] == 0 &&
+           ctx->Color.ColorMask[ACOMP] == 0 &&
+           ctx->Pixel.ZoomX == 1.0F &&
+           ( ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F ) );
+}
+
+/* In addition to the requirements for depth:
+ */
+#if defined(MESA_packed_depth_stencil)
+static GLboolean
+check_stencil_per_fragment_ops( const GLcontext *ctx )
+{
+   return ( !ctx->Pixel.IndexShift &&
+           !ctx->Pixel.IndexOffset );
+}
+#endif
+
+
+static GLboolean
+clip_pixelrect( const GLcontext *ctx,
+               const GLframebuffer *buffer,
+               GLint *x, GLint *y,
+               GLsizei *width, GLsizei *height,
+               GLint *skipPixels, GLint *skipRows,
+               GLint *size )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   *width = MIN2(*width, MAX_WIDTH); /* redundant? */
+
+   /* left clipping */
+   if (*x < buffer->_Xmin) {
+      *skipPixels += (buffer->_Xmin - *x);
+      *width -= (buffer->_Xmin - *x);
+      *x = buffer->_Xmin;
+   }
+
+   /* right clipping */
+   if (*x + *width > buffer->_Xmax)
+      *width -= (*x + *width - buffer->_Xmax - 1);
+
+   if (*width <= 0)
+      return GL_FALSE;
+
+   /* bottom clipping */
+   if (*y < buffer->_Ymin) {
+      *skipRows += (buffer->_Ymin - *y);
+      *height -= (buffer->_Ymin - *y);
+      *y = buffer->_Ymin;
+   }
+
+   /* top clipping */
+   if (*y + *height > buffer->_Ymax)
+      *height -= (*y + *height - buffer->_Ymax - 1);
+
+   if (*height <= 0)
+      return GL_FALSE;
+
+   *size = ((*y + *height - 1) * mmesa->mgaScreen->frontPitch +
+           (*x + *width - 1) * mmesa->mgaScreen->cpp);
+
+   return GL_TRUE;
+}
+
+static GLboolean
+mgaTryReadPixels( GLcontext *ctx,
+                 GLint x, GLint y, GLsizei width, GLsizei height,
+                 GLenum format, GLenum type,
+                 const struct gl_pixelstore_attrib *pack,
+                 GLvoid *pixels )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLint size, skipPixels, skipRows;
+   GLint pitch = pack->RowLength ? pack->RowLength : width;
+   GLboolean ok;
+
+   GLuint planemask;
+   GLuint source;
+#if 0
+   drmMGABlit blit;
+   GLuint dest;
+   GLint source_pitch, dest_pitch;
+   GLint delta_sx, delta_sy;
+   GLint delta_dx, delta_dy;
+   GLint blit_height, ydir;
+#endif
+
+   if (!clip_pixelrect(ctx, ctx->ReadBuffer,
+                      &x, &y, &width, &height,
+                      &skipPixels, &skipRows, &size)) {
+      return GL_TRUE;
+   }
+
+   /* Only accelerate reading to agp buffers.
+    */
+   if ( !IS_AGP_MEM(mmesa, (char *)pixels) ||
+       !IS_AGP_MEM(mmesa, (char *)pixels + size) )
+      return GL_FALSE;
+
+   switch (format) {
+#if defined(MESA_packed_depth_stencil)
+   case GL_DEPTH_STENCIL_MESA:
+      ok = check_depth_stencil_24_8(ctx, type, pack, pixels, size, pitch);
+      planemask = ~0;
+      source = mmesa->mgaScreen->depthOffset;
+      break;
+#endif
+
+   case GL_DEPTH_COMPONENT:
+      ok = check_depth(ctx, type, pack, pixels, size, pitch);
+
+      /* Can't accelerate at this depth -- planemask does the wrong
+       * thing; it doesn't clear the low order bits in the
+       * destination, instead it leaves them untouched.
+       *
+       * Could get the acclerator to solid fill the destination with
+       * zeros first...  Or get the cpu to do it...
+       */
+      if (ctx->Visual.depthBits == 24)
+        return GL_FALSE;
+
+      planemask = ~0;
+      source = mmesa->mgaScreen->depthOffset;
+      break;
+
+   case GL_RGB:
+   case GL_BGRA:
+      ok = check_color(ctx, type, format, pack, pixels, size, pitch);
+      planemask = ~0;
+      source = (mmesa->draw_buffer == MGA_FRONT ?
+               mmesa->mgaScreen->frontOffset :
+               mmesa->mgaScreen->backOffset);
+      break;
+
+   default:
+      return GL_FALSE;
+   }
+
+   if (!ok) {
+      return GL_FALSE;
+   }
+
+
+   LOCK_HARDWARE( mmesa );
+
+#if 0
+   {
+      __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+      int nbox, retcode, i;
+
+      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
+
+      if (mmesa->dirty_cliprects & MGA_FRONT)
+        mgaUpdateRects( mmesa, MGA_FRONT );
+
+      nbox = dPriv->numClipRects;
+
+      y = dPriv->h - y - height;
+      x += mmesa->drawX;
+      y += mmesa->drawY;
+
+      dest = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels)) |
+             DO_dstmap_sys | DO_dstacc_agp);
+      source_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp;
+      dest_pitch = pitch;
+      delta_sx = 0;
+      delta_sy = 0;
+      delta_dx = -x;
+      delta_dy = -y;
+      blit_height = 2*y + height;
+      ydir = -1;
+
+      if (0) fprintf(stderr, "XX doing readpixel blit src_pitch %d dst_pitch %d\n",
+                    source_pitch, dest_pitch);
+
+
+
+      for (i = 0 ; i < nbox ; )
+      {
+        int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+        XF86DRIClipRectRec *box = dPriv->pClipRects;
+        drm_clip_rect_t *b = mmesa->sarea->boxes;
+        int n = 0;
+
+        for ( ; i < nr ; i++) {
+           GLint bx = box[i].x1;
+           GLint by = box[i].y1;
+           GLint bw = box[i].x2 - bx;
+           GLint bh = box[i].y2 - by;
+
+           if (bx < x) bw -= x - bx, bx = x;
+           if (by < y) bh -= y - by, by = y;
+           if (bx + bw > x + width) bw = x + width - bx;
+           if (by + bh > y + height) bh = y + height - by;
+           if (bw <= 0) continue;
+           if (bh <= 0) continue;
+
+           b->x1 = bx;
+           b->y1 = by;
+           b->x2 = bx + bw;
+           b->y2 = by + bh;
+           b++;
+           n++;
+        }
+
+        mmesa->sarea->nbox = n;
+
+        if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT,
+                                              &blit, sizeof(drmMGABlit)))) {
+           fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode);
+           UNLOCK_HARDWARE( mmesa );
+           exit(1);
+        }
+      }
+
+      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
+   }
+#endif
+
+   UNLOCK_HARDWARE( mmesa );
+
+   return GL_TRUE;
+}
+
+static void
+mgaDDReadPixels( GLcontext *ctx,
+                GLint x, GLint y, GLsizei width, GLsizei height,
+                GLenum format, GLenum type,
+                const struct gl_pixelstore_attrib *pack,
+                GLvoid *pixels )
+{
+   if (!mgaTryReadPixels( ctx, x, y, width, height, format, type, pack, pixels))
+      _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, pixels);
+}
+
+
+
+
+static void do_draw_pix( GLcontext *ctx,
+                        GLint x, GLint y, GLsizei width, GLsizei height,
+                        GLint pitch,
+                        const void *pixels,
+                        GLuint dest, GLuint planemask)
+{
+#if 0
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   drmMGABlit blit;
+   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+   XF86DRIClipRectPtr pbox = dPriv->pClipRects;
+   int nbox = dPriv->numClipRects;
+   int retcode, i;
+
+   y = dPriv->h - y - height;
+   x += mmesa->drawX;
+   y += mmesa->drawY;
+
+   blit.dest = dest;
+   blit.planemask = planemask;
+   blit.source = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels))
+                 | SO_srcmap_sys | SO_srcacc_agp);
+   blit.dest_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp;
+   blit.source_pitch = pitch;
+   blit.delta_sx = -x;
+   blit.delta_sy = -y;
+   blit.delta_dx = 0;
+   blit.delta_dy = 0;
+   if (ctx->Pixel.ZoomY == -1) {
+      blit.height = height;
+      blit.ydir = 1;
+   } else {
+      blit.height = height;
+      blit.ydir = -1;
+   }
+
+   if (0) fprintf(stderr,
+                 "doing drawpixel blit src_pitch %d dst_pitch %d\n",
+                 blit.source_pitch, blit.dest_pitch);
+
+   for (i = 0 ; i < nbox ; )
+   {
+      int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+      XF86DRIClipRectRec *box = mmesa->pClipRects;
+      drm_clip_rect_t *b = mmesa->sarea->boxes;
+      int n = 0;
+
+      for ( ; i < nr ; i++) {
+        GLint bx = box[i].x1;
+        GLint by = box[i].y1;
+        GLint bw = box[i].x2 - bx;
+        GLint bh = box[i].y2 - by;
+
+        if (bx < x) bw -= x - bx, bx = x;
+        if (by < y) bh -= y - by, by = y;
+        if (bx + bw > x + width) bw = x + width - bx;
+        if (by + bh > y + height) bh = y + height - by;
+        if (bw <= 0) continue;
+        if (bh <= 0) continue;
+
+        b->x1 = bx;
+        b->y1 = by;
+        b->x2 = bx + bw;
+        b->y2 = by + bh;
+        b++;
+        n++;
+      }
+
+      mmesa->sarea->nbox = n;
+
+      if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT,
+                                              &blit, sizeof(drmMGABlit)))) {
+        fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode);
+        UNLOCK_HARDWARE( mmesa );
+        exit(1);
+      }
+   }
+#endif
+}
+
+
+
+
+static GLboolean
+mgaTryDrawPixels( GLcontext *ctx,
+                 GLint x, GLint y, GLsizei width, GLsizei height,
+                 GLenum format, GLenum type,
+                 const struct gl_pixelstore_attrib *unpack,
+                 const GLvoid *pixels )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLint size, skipPixels, skipRows;
+   GLint pitch = unpack->RowLength ? unpack->RowLength : width;
+   GLuint dest, planemask;
+   GLuint cpp = mmesa->mgaScreen->cpp;
+
+   if (!clip_pixelrect(ctx, ctx->DrawBuffer,
+                      &x, &y, &width, &height,
+                      &skipPixels, &skipRows, &size)) {
+      return GL_TRUE;
+   }
+
+
+   switch (format) {
+#if defined(MESA_packed_depth_stencil)
+   case GL_DEPTH_STENCIL_MESA:
+      dest = mmesa->mgaScreen->depthOffset;
+      planemask = ~0;
+      if (!check_depth_stencil_24_8(ctx, type, unpack, pixels, size, pitch) ||
+         !check_depth_per_fragment_ops(ctx) ||
+         !check_stencil_per_fragment_ops(ctx))
+        return GL_FALSE;
+      break;
+#endif
+
+   case GL_DEPTH_COMPONENT:
+      dest = mmesa->mgaScreen->depthOffset;
+
+      if (ctx->Visual.depthBits == 24)
+        planemask = ~0xff;
+      else
+        planemask = ~0;
+
+      if (!check_depth(ctx, type, unpack, pixels, size, pitch) ||
+         !check_depth_per_fragment_ops(ctx))
+        return GL_FALSE;
+      break;
+
+   case GL_RGB:
+   case GL_BGRA:
+      dest = (mmesa->draw_buffer == MGA_FRONT ?
+             mmesa->mgaScreen->frontOffset :
+             mmesa->mgaScreen->backOffset);
+
+      planemask = mgaPackColor(cpp,
+                              ctx->Color.ColorMask[RCOMP],
+                              ctx->Color.ColorMask[GCOMP],
+                              ctx->Color.ColorMask[BCOMP],
+                              ctx->Color.ColorMask[ACOMP]);
+
+      if (cpp == 2)
+        planemask |= planemask << 16;
+
+      if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) {
+        return GL_FALSE;
+      }
+      if (!check_color_per_fragment_ops(ctx)) {
+        return GL_FALSE;
+      }
+      break;
+
+   default:
+      return GL_FALSE;
+   }
+
+   LOCK_HARDWARE_QUIESCENT( mmesa );
+
+   if (mmesa->dirty_cliprects & MGA_FRONT)
+      mgaUpdateRects( mmesa, MGA_FRONT );
+
+   if ( IS_AGP_MEM(mmesa, (char *)pixels) &&
+       IS_AGP_MEM(mmesa, (char *)pixels + size) )
+   {
+      do_draw_pix( ctx, x, y, width, height, pitch, pixels,
+                  dest, planemask );
+      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
+   }
+   else
+   {
+      /* Pixels is in regular memory -- get dma buffers and perform
+       * upload through them.
+       */
+/*        drmBufPtr buf = mgaGetBufferLocked(mmesa); */
+      GLuint bufferpitch = (width*cpp+31)&~31;
+
+      char *address = 0; /*  mmesa->mgaScreen->agp.map; */
+
+      do {
+/*      GLuint rows = MIN2( height, MGA_DMA_BUF_SZ / bufferpitch ); */
+        GLuint rows = height;
+
+
+        if (0) fprintf(stderr, "trying to upload %d rows (pitch %d)\n",
+                       rows, bufferpitch);
+
+        /* The texture conversion code is so slow that there is only
+         * negligble speedup when the buffers/images don't exactly
+         * match:
+         */
+#if 0
+        if (cpp == 2) {
+           if (!_mesa_convert_texsubimage2d( MESA_FORMAT_RGB565,
+                                             0, 0, width, rows,
+                                             bufferpitch, format, type,
+                                             unpack, pixels, address )) {
+/*            mgaReleaseBufLocked( mmesa, buf ); */
+              UNLOCK_HARDWARE(mmesa);
+              return GL_FALSE;
+           }
+        } else {
+           if (!_mesa_convert_texsubimage2d( MESA_FORMAT_ARGB8888,
+                                             0, 0, width, rows,
+                                             bufferpitch, format, type,
+                                             unpack, pixels, address )) {
+/*            mgaReleaseBufLocked( mmesa, buf ); */
+              UNLOCK_HARDWARE(mmesa);
+              return GL_FALSE;
+           }
+        }
+#else
+        memcpy( address, pixels, rows*bufferpitch );
+#endif
+
+        do_draw_pix( ctx, x, y, width, rows,
+                     bufferpitch/cpp, address, dest, planemask );
+
+        /* Fix me -- use multiple buffers to avoid flush.
+         */
+        UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
+
+        pixels = (void *)((char *) pixels + rows * pitch);
+        height -= rows;
+        y += rows;
+      } while (height);
+
+/*        mgaReleaseBufLocked( mmesa, buf ); */
+   }
+
+   UNLOCK_HARDWARE( mmesa );
+   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+
+   return GL_TRUE;
+}
+
+static void
+mgaDDDrawPixels( GLcontext *ctx,
+                GLint x, GLint y, GLsizei width, GLsizei height,
+                GLenum format, GLenum type,
+                const struct gl_pixelstore_attrib *unpack,
+                const GLvoid *pixels )
+{
+   if (!mgaTryDrawPixels( ctx, x, y, width, height, format, type,
+                         unpack, pixels ))
+      _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+                         unpack, pixels );
+}
+
+
+
+/* Stub functions - not a real allocator, always returns pointer to
+ * the same block of agp space which isn't used for anything else at
+ * present.
+ */
+#if defined(MESA_hacked_agp_allocator)
+static void mgaDDFreeAgpMemory( GLcontext *ctx, void *ptr )
+{
+   (void) ptr;
+}
+
+static void *mgaDDAllocateAgpMemory( GLcontext *ctx, GLsizei size )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   if (size < mmesa->mgaScreen->textureSize[MGA_AGP_HEAP])
+      return mmesa->mgaScreen->texVirtual[MGA_AGP_HEAP];
+   else
+      return 0;
+}
+
+static GLint mgaDDGetAgpOffset( GLcontext *ctx, const void *ptr )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   if (!IS_AGP_MEM(mmesa, ptr))
+      return -1;
+
+   return AGP_OFFSET(mmesa, ptr);
+}
+#endif
+
+
+void mgaDDInitPixelFuncs( GLcontext *ctx )
+{
+#if defined (MESA_experimetal_agp_allocator)
+   ctx->Driver.AllocateAgpMemory = mgaDDAllocateAgpMemory;
+   ctx->Driver.GetAgpOffset = mgaDDGetAgpOffset;
+   ctx->Driver.FreeAgpMemory = mgaDDFreeAgpMemory;
+#endif
+
+   /* Pixel path fallbacks.
+    */
+   ctx->Driver.Accum = _swrast_Accum;
+   ctx->Driver.Bitmap = _swrast_Bitmap;
+   ctx->Driver.CopyPixels = _swrast_CopyPixels;
+   ctx->Driver.DrawPixels = _swrast_DrawPixels;
+   ctx->Driver.ReadPixels = _swrast_ReadPixels;
+
+   if (getenv("MGA_BLIT_PIXELS")) {
+      ctx->Driver.ReadPixels = mgaDDReadPixels; /* requires agp dest */
+      ctx->Driver.DrawPixels = mgaDDDrawPixels; /* works with agp/normal mem */
+   }
+}
diff --git a/src/mesa/drivers/dri/mga/mgapixel.h b/src/mesa/drivers/dri/mga/mgapixel.h
new file mode 100644 (file)
index 0000000..c44fd76
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2001 Compaq Computer Inc. 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.h,v 1.5 2002/10/30 12:51:36 alanh Exp $ */
+
+#ifndef MGA_PIXELS_H
+#define MGA_PIXELS_H
+
+#include "mtypes.h"
+
+extern void mgaDDInitPixelFuncs( GLcontext *ctx );
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgaregs.h b/src/mesa/drivers/dri/mga/mgaregs.h
new file mode 100644 (file)
index 0000000..f07dc2d
--- /dev/null
@@ -0,0 +1,1381 @@
+/* author: stephen crowley, crow@debian.org */
+
+/*
+ * 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * STEPHEN CROWLEY, OR ANY OTHER CONTRIBUTORS 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.
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaregs.h,v 1.6 2003/01/12 03:55:46 tsi Exp $ */
+
+#ifndef _MGAREGS_H_
+#define _MGAREGS_H_
+
+/*************** (START) AUTOMATICLY GENERATED REGISTER FILE *****************/
+/*
+ * Generated on Wed Jan 26 13:44:46 MST 2000
+ */
+
+
+
+/*
+ * Power Graphic Mode Memory Space Registers
+ */
+
+#define MGAREG_MGA_EXEC                        0x0100
+#define MGAREG_AGP_PLL                         0x1e4c
+
+#    define AGP_PLL_agp2xpllen_MASK    0xfffffffe      /* bit 0 */
+#    define AGP_PLL_agp2xpllen_disable         0x0             
+#    define AGP_PLL_agp2xpllen_enable  0x1             
+
+#define MGAREG_CFG_OR                          0x1e4c
+
+#    define CFG_OR_comp_or_MASK        0xfffffff7      /* bit 3 */
+#    define CFG_OR_comp_or_disable     0x0             
+#    define CFG_OR_comp_or_enable      0x8             
+#    define CFG_OR_compfreq_MASK       0xffffff0f      /* bits 4-7 */
+#    define CFG_OR_compfreq_SHIFT      4               
+#    define CFG_OR_comporup_MASK       0xfffff0ff      /* bits 8-11 */
+#    define CFG_OR_comporup_SHIFT      8               
+#    define CFG_OR_compordn_MASK       0xffff0fff      /* bits 12-15 */
+#    define CFG_OR_compordn_SHIFT      12              
+#    define CFG_OR_e2pq_MASK           0xfffeffff      /* bit 16 */
+#    define CFG_OR_e2pq_disable        0x0             
+#    define CFG_OR_e2pq_enable                 0x10000         
+#    define CFG_OR_e2pqbypcsn_MASK     0xfffdffff      /* bit 17 */
+#    define CFG_OR_e2pqbypcsn_disable  0x0             
+#    define CFG_OR_e2pqbypcsn_enable   0x20000         
+#    define CFG_OR_e2pqbypd_MASK       0xfffbffff      /* bit 18 */
+#    define CFG_OR_e2pqbypd_disable    0x0             
+#    define CFG_OR_e2pqbypd_enable     0x40000         
+#    define CFG_OR_e2pbypclk_MASK      0xfff7ffff      /* bit 19 */
+#    define CFG_OR_e2pbypclk_disable   0x0             
+#    define CFG_OR_e2pbypclk_enable    0x80000         
+#    define CFG_OR_e2pbyp_MASK                 0xffefffff      /* bit 20 */
+#    define CFG_OR_e2pbyp_disable      0x0             
+#    define CFG_OR_e2pbyp_enable       0x100000        
+#    define CFG_OR_rate_cap_or_MASK    0xff1fffff      /* bits 21-23 */
+#    define CFG_OR_rate_cap_or_SHIFT   21              
+#    define CFG_OR_rq_or_MASK          0xe0ffffff      /* bits 24-28 */
+#    define CFG_OR_rq_or_SHIFT                 24              
+
+#define MGAREG_ALPHACTRL                       0x2c7c
+
+#    define AC_src_MASK                0xfffffff0      /* bits 0-3 */
+#    define AC_src_zero                0x0             /* val 0, shift 0 */
+#    define AC_src_one                         0x1             /* val 1, shift 0 */
+#    define AC_src_dst_color           0x2             /* val 2, shift 0 */
+#    define AC_src_om_dst_color        0x3             /* val 3, shift 0 */
+#    define AC_src_src_alpha           0x4             /* val 4, shift 0 */
+#    define AC_src_om_src_alpha        0x5             /* val 5, shift 0 */
+#    define AC_src_dst_alpha           0x6             /* val 6, shift 0 */
+#    define AC_src_om_dst_alpha        0x7             /* val 7, shift 0 */
+#    define AC_src_src_alpha_sat       0x8             /* val 8, shift 0 */
+#    define AC_dst_MASK                0xffffff0f      /* bits 4-7 */
+#    define AC_dst_zero                0x0             /* val 0, shift 4 */
+#    define AC_dst_one                         0x10            /* val 1, shift 4 */
+#    define AC_dst_src_color           0x20            /* val 2, shift 4 */
+#    define AC_dst_om_src_color        0x30            /* val 3, shift 4 */
+#    define AC_dst_src_alpha           0x40            /* val 4, shift 4 */
+#    define AC_dst_om_src_alpha        0x50            /* val 5, shift 4 */
+#    define AC_dst_dst_alpha           0x60            /* val 6, shift 4 */
+#    define AC_dst_om_dst_alpha        0x70            /* val 7, shift 4 */
+#    define AC_amode_MASK              0xfffffcff      /* bits 8-9 */
+#    define AC_amode_FCOL              0x0             /* val 0, shift 8 */
+#    define AC_amode_alpha_channel     0x100           /* val 1, shift 8 */
+#    define AC_amode_video_alpha       0x200           /* val 2, shift 8 */
+#    define AC_amode_RSVD              0x300           /* val 3, shift 8 */
+#    define AC_astipple_MASK           0xfffff7ff      /* bit 11 */
+#    define AC_astipple_disable        0x0             
+#    define AC_astipple_enable                 0x800           
+#    define AC_aten_MASK               0xffffefff      /* bit 12 */
+#    define AC_aten_disable            0x0             
+#    define AC_aten_enable             0x1000          
+#    define AC_atmode_MASK             0xffff1fff      /* bits 13-15 */
+#    define AC_atmode_noacmp           0x0             /* val 0, shift 13 */
+#    define AC_atmode_ae               0x4000          /* val 2, shift 13 */
+#    define AC_atmode_ane              0x6000          /* val 3, shift 13 */
+#    define AC_atmode_alt              0x8000          /* val 4, shift 13 */
+#    define AC_atmode_alte             0xa000          /* val 5, shift 13 */
+#    define AC_atmode_agt              0xc000          /* val 6, shift 13 */
+#    define AC_atmode_agte             0xe000          /* val 7, shift 13 */
+#    define AC_atref_MASK              0xff00ffff      /* bits 16-23 */
+#    define AC_atref_SHIFT             16              
+#    define AC_alphasel_MASK           0xfcffffff      /* bits 24-25 */
+#    define AC_alphasel_fromtex        0x0             /* val 0, shift 24 */
+#    define AC_alphasel_diffused       0x1000000       /* val 1, shift 24 */
+#    define AC_alphasel_modulated      0x2000000       /* val 2, shift 24 */
+#    define AC_alphasel_trans          0x3000000       /* val 3, shift 24 */
+
+#define MGAREG_ALPHASTART                      0x2c70
+#define MGAREG_ALPHAXINC                       0x2c74
+#define MGAREG_ALPHAYINC                       0x2c78
+#define MGAREG_AR0                             0x1c60
+
+#    define AR0_ar0_MASK               0xfffc0000      /* bits 0-17 */
+#    define AR0_ar0_SHIFT              0               
+
+#define MGAREG_AR1                             0x1c64
+
+#    define AR1_ar1_MASK               0xff000000      /* bits 0-23 */
+#    define AR1_ar1_SHIFT              0               
+
+#define MGAREG_AR2                             0x1c68
+
+#    define AR2_ar2_MASK               0xfffc0000      /* bits 0-17 */
+#    define AR2_ar2_SHIFT              0               
+
+#define MGAREG_AR3                             0x1c6c
+
+#    define AR3_ar3_MASK               0xff000000      /* bits 0-23 */
+#    define AR3_ar3_SHIFT              0               
+#    define AR3_spage_MASK             0xf8ffffff      /* bits 24-26 */
+#    define AR3_spage_SHIFT            24              
+
+#define MGAREG_AR4                             0x1c70
+
+#    define AR4_ar4_MASK               0xfffc0000      /* bits 0-17 */
+#    define AR4_ar4_SHIFT              0               
+
+#define MGAREG_AR5                             0x1c74
+
+#    define AR5_ar5_MASK               0xfffc0000      /* bits 0-17 */
+#    define AR5_ar5_SHIFT              0               
+
+#define MGAREG_AR6                             0x1c78
+
+#    define AR6_ar6_MASK               0xfffc0000      /* bits 0-17 */
+#    define AR6_ar6_SHIFT              0               
+
+#define MGAREG_BCOL                            0x1c20
+#define MGAREG_BESA1CORG                       0x3d10
+#define MGAREG_BESA1ORG                        0x3d00
+#define MGAREG_BESA2CORG                       0x3d14
+#define MGAREG_BESA2ORG                        0x3d04
+#define MGAREG_BESB1CORG                       0x3d18
+#define MGAREG_BESB1ORG                        0x3d08
+#define MGAREG_BESB2CORG                       0x3d1c
+#define MGAREG_BESB2ORG                        0x3d0c
+#define MGAREG_BESCTL                          0x3d20
+
+#    define BC_besen_MASK              0xfffffffe      /* bit 0 */
+#    define BC_besen_disable           0x0             
+#    define BC_besen_enable            0x1             
+#    define BC_besv1srcstp_MASK        0xffffffbf      /* bit 6 */
+#    define BC_besv1srcstp_even        0x0             
+#    define BC_besv1srcstp_odd                 0x40            
+#    define BC_besv2srcstp_MASK        0xfffffeff      /* bit 8 */
+#    define BC_besv2srcstp_disable     0x0             
+#    define BC_besv2srcstp_enable      0x100           
+#    define BC_beshfen_MASK            0xfffffbff      /* bit 10 */
+#    define BC_beshfen_disable                 0x0             
+#    define BC_beshfen_enable          0x400           
+#    define BC_besvfen_MASK            0xfffff7ff      /* bit 11 */
+#    define BC_besvfen_disable                 0x0             
+#    define BC_besvfen_enable          0x800           
+#    define BC_beshfixc_MASK           0xffffefff      /* bit 12 */
+#    define BC_beshfixc_weight                 0x0             
+#    define BC_beshfixc_coeff          0x1000          
+#    define BC_bescups_MASK            0xfffeffff      /* bit 16 */
+#    define BC_bescups_disable                 0x0             
+#    define BC_bescups_enable          0x10000         
+#    define BC_bes420pl_MASK           0xfffdffff      /* bit 17 */
+#    define BC_bes420pl_422            0x0             
+#    define BC_bes420pl_420            0x20000         
+#    define BC_besdith_MASK            0xfffbffff      /* bit 18 */
+#    define BC_besdith_disable                 0x0             
+#    define BC_besdith_enable          0x40000         
+#    define BC_beshmir_MASK            0xfff7ffff      /* bit 19 */
+#    define BC_beshmir_disable                 0x0             
+#    define BC_beshmir_enable          0x80000         
+#    define BC_besbwen_MASK            0xffefffff      /* bit 20 */
+#    define BC_besbwen_color           0x0             
+#    define BC_besbwen_bw              0x100000        
+#    define BC_besblank_MASK           0xffdfffff      /* bit 21 */
+#    define BC_besblank_disable        0x0             
+#    define BC_besblank_enable                 0x200000        
+#    define BC_besfselm_MASK           0xfeffffff      /* bit 24 */
+#    define BC_besfselm_soft           0x0             
+#    define BC_besfselm_hard           0x1000000       
+#    define BC_besfsel_MASK            0xf9ffffff      /* bits 25-26 */
+#    define BC_besfsel_a1              0x0             /* val 0, shift 25 */
+#    define BC_besfsel_a2              0x2000000       /* val 1, shift 25 */
+#    define BC_besfsel_b1              0x4000000       /* val 2, shift 25 */
+#    define BC_besfsel_b2              0x6000000       /* val 3, shift 25 */
+
+#define MGAREG_BESGLOBCTL                      0x3dc0
+
+#    define BGC_beshzoom_MASK          0xfffffffe      /* bit 0 */
+#    define BGC_beshzoom_disable       0x0             
+#    define BGC_beshzoom_enable        0x1             
+#    define BGC_beshzoomf_MASK                 0xfffffffd      /* bit 1 */
+#    define BGC_beshzoomf_disable      0x0             
+#    define BGC_beshzoomf_enable       0x2             
+#    define BGC_bescorder_MASK                 0xfffffff7      /* bit 3 */
+#    define BGC_bescorder_even                 0x0             
+#    define BGC_bescorder_odd          0x8             
+#    define BGC_besreghup_MASK                 0xffffffef      /* bit 4 */
+#    define BGC_besreghup_disable      0x0             
+#    define BGC_besreghup_enable       0x10            
+#    define BGC_besvcnt_MASK           0xf000ffff      /* bits 16-27 */
+#    define BGC_besvcnt_SHIFT          16              
+
+#define MGAREG_BESHCOORD                       0x3d28
+
+#    define BHC_besright_MASK          0xfffff800      /* bits 0-10 */
+#    define BHC_besright_SHIFT                 0               
+#    define BHC_besleft_MASK           0xf800ffff      /* bits 16-26 */
+#    define BHC_besleft_SHIFT          16              
+
+#define MGAREG_BESHISCAL                       0x3d30
+
+#    define BHISF_beshiscal_MASK       0xffe00003      /* bits 2-20 */
+#    define BHISF_beshiscal_SHIFT      2               
+
+#define MGAREG_BESHSRCEND                      0x3d3c
+
+#    define BHSE_beshsrcend_MASK       0xfc000003      /* bits 2-25 */
+#    define BHSE_beshsrcend_SHIFT      2               
+
+#define MGAREG_BESHSRCLST                      0x3d50
+
+#    define BHSL_beshsrclst_MASK       0xfc00ffff      /* bits 16-25 */
+#    define BHSL_beshsrclst_SHIFT      16              
+
+#define MGAREG_BESHSRCST                       0x3d38
+
+#    define BHSS_beshsrcst_MASK        0xfc000003      /* bits 2-25 */
+#    define BHSS_beshsrcst_SHIFT       2               
+
+#define MGAREG_BESPITCH                        0x3d24
+
+#    define BP_bespitch_MASK           0xfffff000      /* bits 0-11 */
+#    define BP_bespitch_SHIFT          0               
+
+#define MGAREG_BESSTATUS                       0x3dc4
+
+#    define BS_besstat_MASK            0xfffffffc      /* bits 0-1 */
+#    define BS_besstat_a1              0x0             /* val 0, shift 0 */
+#    define BS_besstat_a2              0x1             /* val 1, shift 0 */
+#    define BS_besstat_b1              0x2             /* val 2, shift 0 */
+#    define BS_besstat_b2              0x3             /* val 3, shift 0 */
+
+#define MGAREG_BESV1SRCLST                     0x3d54
+
+#    define BSF_besv1srclast_MASK      0xfffffc00      /* bits 0-9 */
+#    define BSF_besv1srclast_SHIFT     0               
+
+#define MGAREG_BESV2SRCLST                     0x3d58
+
+#    define BSF_besv2srclst_MASK       0xfffffc00      /* bits 0-9 */
+#    define BSF_besv2srclst_SHIFT      0               
+
+#define MGAREG_BESV1WGHT                       0x3d48
+
+#    define BSF_besv1wght_MASK                 0xffff0003      /* bits 2-15 */
+#    define BSF_besv1wght_SHIFT        2               
+#    define BSF_besv1wghts_MASK        0xfffeffff      /* bit 16 */
+#    define BSF_besv1wghts_disable     0x0             
+#    define BSF_besv1wghts_enable      0x10000         
+
+#define MGAREG_BESV2WGHT                       0x3d4c
+
+#    define BSF_besv2wght_MASK                 0xffff0003      /* bits 2-15 */
+#    define BSF_besv2wght_SHIFT        2               
+#    define BSF_besv2wghts_MASK        0xfffeffff      /* bit 16 */
+#    define BSF_besv2wghts_disable     0x0             
+#    define BSF_besv2wghts_enable      0x10000         
+
+#define MGAREG_BESVCOORD                       0x3d2c
+
+#    define BVC_besbot_MASK            0xfffff800      /* bits 0-10 */
+#    define BVC_besbot_SHIFT           0               
+#    define BVC_bestop_MASK            0xf800ffff      /* bits 16-26 */
+#    define BVC_bestop_SHIFT           16              
+
+#define MGAREG_BESVISCAL                       0x3d34
+
+#    define BVISF_besviscal_MASK       0xffe00003      /* bits 2-20 */
+#    define BVISF_besviscal_SHIFT      2               
+
+#define MGAREG_CODECADDR                       0x3e44
+#define MGAREG_CODECCTL                        0x3e40
+#define MGAREG_CODECHARDPTR                    0x3e4c
+#define MGAREG_CODECHOSTPTR                    0x3e48
+#define MGAREG_CODECLCODE                      0x3e50
+#define MGAREG_CXBNDRY                         0x1c80
+
+#    define CXB_cxleft_MASK            0xfffff000      /* bits 0-11 */
+#    define CXB_cxleft_SHIFT           0               
+#    define CXB_cxright_MASK           0xf000ffff      /* bits 16-27 */
+#    define CXB_cxright_SHIFT          16              
+
+#define MGAREG_CXLEFT                          0x1ca0
+#define MGAREG_CXRIGHT                         0x1ca4
+#define MGAREG_DMAMAP30                        0x1e30
+#define MGAREG_DMAMAP74                        0x1e34
+#define MGAREG_DMAMAPB8                        0x1e38
+#define MGAREG_DMAMAPFC                        0x1e3c
+#define MGAREG_DMAPAD                          0x1c54
+#define MGAREG_DR0_Z32LSB                      0x2c50
+#define MGAREG_DR0_Z32MSB                      0x2c54
+#define MGAREG_DR2_Z32LSB                      0x2c60
+#define MGAREG_DR2_Z32MSB                      0x2c64
+#define MGAREG_DR3_Z32LSB                      0x2c68
+#define MGAREG_DR3_Z32MSB                      0x2c6c
+#define MGAREG_DR0                             0x1cc0
+#define MGAREG_DR2                             0x1cc8
+#define MGAREG_DR3                             0x1ccc
+#define MGAREG_DR4                             0x1cd0
+#define MGAREG_DR6                             0x1cd8
+#define MGAREG_DR7                             0x1cdc
+#define MGAREG_DR8                             0x1ce0
+#define MGAREG_DR10                            0x1ce8
+#define MGAREG_DR11                            0x1cec
+#define MGAREG_DR12                            0x1cf0
+#define MGAREG_DR14                            0x1cf8
+#define MGAREG_DR15                            0x1cfc
+#define MGAREG_DSTORG                          0x2cb8
+
+#    define DO_dstmap_MASK             0xfffffffe      /* bit 0 */
+#    define DO_dstmap_fb               0x0             
+#    define DO_dstmap_sys              0x1             
+#    define DO_dstacc_MASK             0xfffffffd      /* bit 1 */
+#    define DO_dstacc_pci              0x0             
+#    define DO_dstacc_agp              0x2             
+#    define DO_dstorg_MASK             0x7             /* bits 3-31 */
+#    define DO_dstorg_SHIFT            3               
+
+#define MGAREG_DWG_INDIR_WT                    0x1e80
+#define MGAREG_DWGCTL                          0x1c00
+
+#    define DC_opcod_MASK              0xfffffff0      /* bits 0-3 */
+#    define DC_opcod_line_open                 0x0             /* val 0, shift 0 */
+#    define DC_opcod_autoline_open     0x1             /* val 1, shift 0 */
+#    define DC_opcod_line_close        0x2             /* val 2, shift 0 */
+#    define DC_opcod_autoline_close    0x3             /* val 3, shift 0 */
+#    define DC_opcod_trap              0x4             /* val 4, shift 0 */
+#    define DC_opcod_texture_trap      0x6             /* val 6, shift 0 */
+#    define DC_opcod_bitblt            0x8             /* val 8, shift 0 */
+#    define DC_opcod_iload             0x9             /* val 9, shift 0 */
+#    define DC_atype_MASK              0xffffff8f      /* bits 4-6 */
+#    define DC_atype_rpl               0x0             /* val 0, shift 4 */
+#    define DC_atype_rstr              0x10            /* val 1, shift 4 */
+#    define DC_atype_zi                0x30            /* val 3, shift 4 */
+#    define DC_atype_blk               0x40            /* val 4, shift 4 */
+#    define DC_atype_i                         0x70            /* val 7, shift 4 */
+#    define DC_linear_MASK             0xffffff7f      /* bit 7 */
+#    define DC_linear_xy               0x0             
+#    define DC_linear_linear           0x80            
+#    define DC_zmode_MASK              0xfffff8ff      /* bits 8-10 */
+#    define DC_zmode_nozcmp            0x0             /* val 0, shift 8 */
+#    define DC_zmode_ze                0x200           /* val 2, shift 8 */
+#    define DC_zmode_zne               0x300           /* val 3, shift 8 */
+#    define DC_zmode_zlt               0x400           /* val 4, shift 8 */
+#    define DC_zmode_zlte              0x500           /* val 5, shift 8 */
+#    define DC_zmode_zgt               0x600           /* val 6, shift 8 */
+#    define DC_zmode_zgte              0x700           /* val 7, shift 8 */
+#    define DC_solid_MASK              0xfffff7ff      /* bit 11 */
+#    define DC_solid_disable           0x0             
+#    define DC_solid_enable            0x800           
+#    define DC_arzero_MASK             0xffffefff      /* bit 12 */
+#    define DC_arzero_disable          0x0             
+#    define DC_arzero_enable           0x1000          
+#    define DC_sgnzero_MASK            0xffffdfff      /* bit 13 */
+#    define DC_sgnzero_disable                 0x0             
+#    define DC_sgnzero_enable          0x2000          
+#    define DC_shftzero_MASK           0xffffbfff      /* bit 14 */
+#    define DC_shftzero_disable        0x0             
+#    define DC_shftzero_enable                 0x4000          
+#    define DC_bop_MASK                0xfff0ffff      /* bits 16-19 */
+#    define DC_bop_SHIFT               16              
+#    define DC_trans_MASK              0xff0fffff      /* bits 20-23 */
+#    define DC_trans_SHIFT             20              
+#    define DC_bltmod_MASK             0xe1ffffff      /* bits 25-28 */
+#    define DC_bltmod_bmonolef                 0x0             /* val 0, shift 25 */
+#    define DC_bltmod_bmonowf          0x8000000       /* val 4, shift 25 */
+#    define DC_bltmod_bplan            0x2000000       /* val 1, shift 25 */
+#    define DC_bltmod_bfcol            0x4000000       /* val 2, shift 25 */
+#    define DC_bltmod_bu32bgr          0x6000000       /* val 3, shift 25 */
+#    define DC_bltmod_bu32rgb          0xe000000       /* val 7, shift 25 */
+#    define DC_bltmod_bu24bgr          0x16000000      /* val 11, shift 25 */
+#    define DC_bltmod_bu24rgb          0x1e000000      /* val 15, shift 25 */
+#    define DC_pattern_MASK            0xdfffffff      /* bit 29 */
+#    define DC_pattern_disable                 0x0             
+#    define DC_pattern_enable          0x20000000      
+#    define DC_transc_MASK             0xbfffffff      /* bit 30 */
+#    define DC_transc_disable          0x0             
+#    define DC_transc_enable           0x40000000      
+#    define DC_clipdis_MASK            0x7fffffff      /* bit 31 */
+#    define DC_clipdis_disable                 0x0             
+#    define DC_clipdis_enable          0x80000000      
+
+#define MGAREG_DWGSYNC                         0x2c4c
+
+#    define DS_dwgsyncaddr_MASK        0x3             /* bits 2-31 */
+#    define DS_dwgsyncaddr_SHIFT       2               
+
+#define MGAREG_FCOL                            0x1c24
+#define MGAREG_FIFOSTATUS                      0x1e10
+
+#    define FS_fifocount_MASK          0xffffff80      /* bits 0-6 */
+#    define FS_fifocount_SHIFT                 0               
+#    define FS_bfull_MASK              0xfffffeff      /* bit 8 */
+#    define FS_bfull_disable           0x0             
+#    define FS_bfull_enable            0x100           
+#    define FS_bempty_MASK             0xfffffdff      /* bit 9 */
+#    define FS_bempty_disable          0x0             
+#    define FS_bempty_enable           0x200           
+
+#define MGAREG_FOGCOL                          0x1cf4
+#define MGAREG_FOGSTART                        0x1cc4
+#define MGAREG_FOGXINC                         0x1cd4
+#define MGAREG_FOGYINC                         0x1ce4
+#define MGAREG_FXBNDRY                         0x1c84
+
+#    define XA_fxleft_MASK             0xffff0000      /* bits 0-15 */
+#    define XA_fxleft_SHIFT            0               
+#    define XA_fxright_MASK            0xffff          /* bits 16-31 */
+#    define XA_fxright_SHIFT           16              
+
+#define MGAREG_FXLEFT                          0x1ca8
+#define MGAREG_FXRIGHT                         0x1cac
+#define MGAREG_ICLEAR                          0x1e18
+
+#    define IC_softrapiclr_MASK        0xfffffffe      /* bit 0 */
+#    define IC_softrapiclr_disable     0x0             
+#    define IC_softrapiclr_enable      0x1             
+#    define IC_pickiclr_MASK           0xfffffffb      /* bit 2 */
+#    define IC_pickiclr_disable        0x0             
+#    define IC_pickiclr_enable                 0x4             
+#    define IC_vlineiclr_MASK          0xffffffdf      /* bit 5 */
+#    define IC_vlineiclr_disable       0x0             
+#    define IC_vlineiclr_enable        0x20            
+#    define IC_wiclr_MASK              0xffffff7f      /* bit 7 */
+#    define IC_wiclr_disable           0x0             
+#    define IC_wiclr_enable            0x80            
+#    define IC_wciclr_MASK             0xfffffeff      /* bit 8 */
+#    define IC_wciclr_disable          0x0             
+#    define IC_wciclr_enable           0x100           
+
+#define MGAREG_IEN                             0x1e1c
+
+#    define IE_softrapien_MASK                 0xfffffffe      /* bit 0 */
+#    define IE_softrapien_disable      0x0             
+#    define IE_softrapien_enable       0x1             
+#    define IE_pickien_MASK            0xfffffffb      /* bit 2 */
+#    define IE_pickien_disable                 0x0             
+#    define IE_pickien_enable          0x4             
+#    define IE_vlineien_MASK           0xffffffdf      /* bit 5 */
+#    define IE_vlineien_disable        0x0             
+#    define IE_vlineien_enable                 0x20            
+#    define IE_extien_MASK             0xffffffbf      /* bit 6 */
+#    define IE_extien_disable          0x0             
+#    define IE_extien_enable           0x40            
+#    define IE_wien_MASK               0xffffff7f      /* bit 7 */
+#    define IE_wien_disable            0x0             
+#    define IE_wien_enable             0x80            
+#    define IE_wcien_MASK              0xfffffeff      /* bit 8 */
+#    define IE_wcien_disable           0x0             
+#    define IE_wcien_enable            0x100           
+
+#define MGAREG_LEN                             0x1c5c
+#define MGAREG_MACCESS                         0x1c04
+
+#    define MA_pwidth_MASK             0xfffffffc      /* bits 0-1 */
+#    define MA_pwidth_8                0x0             /* val 0, shift 0 */
+#    define MA_pwidth_16               0x1             /* val 1, shift 0 */
+#    define MA_pwidth_32               0x2             /* val 2, shift 0 */
+#    define MA_pwidth_24               0x3             /* val 3, shift 0 */
+#    define MA_zwidth_MASK             0xffffffe7      /* bits 3-4 */
+#    define MA_zwidth_16               0x0             /* val 0, shift 3 */
+#    define MA_zwidth_32               0x8             /* val 1, shift 3 */
+#    define MA_zwidth_15               0x10            /* val 2, shift 3 */
+#    define MA_zwidth_24               0x18            /* val 3, shift 3 */
+#    define MA_memreset_MASK           0xffff7fff      /* bit 15 */
+#    define MA_memreset_disable        0x0             
+#    define MA_memreset_enable                 0x8000          
+#    define MA_fogen_MASK              0xfbffffff      /* bit 26 */
+#    define MA_fogen_disable           0x0             
+#    define MA_fogen_enable            0x4000000       
+#    define MA_tlutload_MASK           0xdfffffff      /* bit 29 */
+#    define MA_tlutload_disable        0x0             
+#    define MA_tlutload_enable                 0x20000000      
+#    define MA_nodither_MASK           0xbfffffff      /* bit 30 */
+#    define MA_nodither_disable        0x0             
+#    define MA_nodither_enable                 0x40000000      
+#    define MA_dit555_MASK             0x7fffffff      /* bit 31 */
+#    define MA_dit555_disable          0x0             
+#    define MA_dit555_enable           0x80000000      
+
+#define MGAREG_MCTLWTST                        0x1c08
+
+#    define MCWS_casltncy_MASK                 0xfffffff8      /* bits 0-2 */
+#    define MCWS_casltncy_SHIFT        0               
+#    define MCWS_rrddelay_MASK                 0xffffffcf      /* bits 4-5 */
+#    define MCWS_rcddelay_MASK                 0xfffffe7f      /* bits 7-8 */
+#    define MCWS_rasmin_MASK           0xffffe3ff      /* bits 10-12 */
+#    define MCWS_rasmin_SHIFT          10              
+#    define MCWS_rpdelay_MASK          0xffff3fff      /* bits 14-15 */
+#    define MCWS_wrdelay_MASK          0xfff3ffff      /* bits 18-19 */
+#    define MCWS_rddelay_MASK          0xffdfffff      /* bit 21 */
+#    define MCWS_rddelay_disable       0x0             
+#    define MCWS_rddelay_enable        0x200000        
+#    define MCWS_smrdelay_MASK                 0xfe7fffff      /* bits 23-24 */
+#    define MCWS_bwcdelay_MASK                 0xf3ffffff      /* bits 26-27 */
+#    define MCWS_bpldelay_MASK                 0x1fffffff      /* bits 29-31 */
+#    define MCWS_bpldelay_SHIFT        29              
+
+#define MGAREG_MEMRDBK                         0x1e44
+
+#    define MRB_mclkbrd0_MASK          0xfffffff0      /* bits 0-3 */
+#    define MRB_mclkbrd0_SHIFT                 0               
+#    define MRB_mclkbrd1_MASK          0xfffffe1f      /* bits 5-8 */
+#    define MRB_mclkbrd1_SHIFT                 5               
+#    define MRB_strmfctl_MASK          0xff3fffff      /* bits 22-23 */
+#    define MRB_mrsopcod_MASK          0xe1ffffff      /* bits 25-28 */
+#    define MRB_mrsopcod_SHIFT                 25              
+
+#define MGAREG_OPMODE                          0x1e54
+
+#    define OM_dmamod_MASK             0xfffffff3      /* bits 2-3 */
+#    define OM_dmamod_general          0x0             /* val 0, shift 2 */
+#    define OM_dmamod_blit             0x4             /* val 1, shift 2 */
+#    define OM_dmamod_vector           0x8             /* val 2, shift 2 */
+#    define OM_dmamod_vertex           0xc             /* val 3, shift 2 */
+#    define OM_dmadatasiz_MASK                 0xfffffcff      /* bits 8-9 */
+#    define OM_dmadatasiz_8            0x0             /* val 0, shift 8 */
+#    define OM_dmadatasiz_16           0x100           /* val 1, shift 8 */
+#    define OM_dmadatasiz_32           0x200           /* val 2, shift 8 */
+#    define OM_dirdatasiz_MASK                 0xfffcffff      /* bits 16-17 */
+#    define OM_dirdatasiz_8            0x0             /* val 0, shift 16 */
+#    define OM_dirdatasiz_16           0x10000         /* val 1, shift 16 */
+#    define OM_dirdatasiz_32           0x20000         /* val 2, shift 16 */
+
+#define MGAREG_PAT0                            0x1c10
+#define MGAREG_PAT1                            0x1c14
+#define MGAREG_PITCH                           0x1c8c
+
+#    define P_iy_MASK                  0xffffe000      /* bits 0-12 */
+#    define P_iy_SHIFT                         0               
+#    define P_ylin_MASK                0xffff7fff      /* bit 15 */
+#    define P_ylin_disable             0x0             
+#    define P_ylin_enable              0x8000          
+
+#define MGAREG_PLNWT                           0x1c1c
+#define MGAREG_PRIMADDRESS                     0x1e58
+
+#    define PDCA_primod_MASK           0xfffffffc      /* bits 0-1 */
+#    define PDCA_primod_general        0x0             /* val 0, shift 0 */
+#    define PDCA_primod_blit           0x1             /* val 1, shift 0 */
+#    define PDCA_primod_vector                 0x2             /* val 2, shift 0 */
+#    define PDCA_primod_vertex                 0x3             /* val 3, shift 0 */
+#    define PDCA_primaddress_MASK      0x3             /* bits 2-31 */
+#    define PDCA_primaddress_SHIFT     2               
+
+#define MGAREG_PRIMEND                         0x1e5c
+
+#    define PDEA_primnostart_MASK      0xfffffffe      /* bit 0 */
+#    define PDEA_primnostart_disable   0x0             
+#    define PDEA_primnostart_enable    0x1             
+#    define PDEA_pagpxfer_MASK                 0xfffffffd      /* bit 1 */
+#    define PDEA_pagpxfer_disable      0x0             
+#    define PDEA_pagpxfer_enable       0x2             
+#    define PDEA_primend_MASK          0x3             /* bits 2-31 */
+#    define PDEA_primend_SHIFT                 2               
+
+#define MGAREG_PRIMPTR                         0x1e50
+
+#    define PLS_primptren0_MASK        0xfffffffe      /* bit 0 */
+#    define PLS_primptren0_disable     0x0             
+#    define PLS_primptren0_enable      0x1             
+#    define PLS_primptren1_MASK        0xfffffffd      /* bit 1 */
+#    define PLS_primptren1_disable     0x0             
+#    define PLS_primptren1_enable      0x2             
+#    define PLS_primptr_MASK           0x7             /* bits 3-31 */
+#    define PLS_primptr_SHIFT          3               
+
+#define MGAREG_RST                             0x1e40
+
+#    define R_softreset_MASK           0xfffffffe      /* bit 0 */
+#    define R_softreset_disable        0x0             
+#    define R_softreset_enable                 0x1             
+#    define R_softextrst_MASK          0xfffffffd      /* bit 1 */
+#    define R_softextrst_disable       0x0             
+#    define R_softextrst_enable        0x2             
+
+#define MGAREG_SECADDRESS                      0x2c40
+
+#    define SDCA_secmod_MASK           0xfffffffc      /* bits 0-1 */
+#    define SDCA_secmod_general        0x0             /* val 0, shift 0 */
+#    define SDCA_secmod_blit           0x1             /* val 1, shift 0 */
+#    define SDCA_secmod_vector                 0x2             /* val 2, shift 0 */
+#    define SDCA_secmod_vertex                 0x3             /* val 3, shift 0 */
+#    define SDCA_secaddress_MASK       0x3             /* bits 2-31 */
+#    define SDCA_secaddress_SHIFT      2               
+
+#define MGAREG_SECEND                          0x2c44
+
+#    define SDEA_sagpxfer_MASK                 0xfffffffd      /* bit 1 */
+#    define SDEA_sagpxfer_disable      0x0             
+#    define SDEA_sagpxfer_enable       0x2             
+#    define SDEA_secend_MASK           0x3             /* bits 2-31 */
+#    define SDEA_secend_SHIFT          2               
+
+#define MGAREG_SETUPADDRESS                    0x2cd0
+
+#    define SETADD_mode_MASK           0xfffffffc      /* bits 0-1 */
+#    define SETADD_mode_vertlist       0x0             /* val 0, shift 0 */
+#    define SETADD_address_MASK        0x3             /* bits 2-31 */
+#    define SETADD_address_SHIFT       2               
+
+#define MGAREG_SETUPEND                        0x2cd4
+
+#    define SETEND_agpxfer_MASK        0xfffffffd      /* bit 1 */
+#    define SETEND_agpxfer_disable     0x0             
+#    define SETEND_agpxfer_enable      0x2             
+#    define SETEND_address_MASK        0x3             /* bits 2-31 */
+#    define SETEND_address_SHIFT       2               
+
+#define MGAREG_SGN                             0x1c58
+
+#    define S_sdydxl_MASK              0xfffffffe      /* bit 0 */
+#    define S_sdydxl_y                         0x0             
+#    define S_sdydxl_x                         0x1             
+#    define S_scanleft_MASK            0xfffffffe      /* bit 0 */
+#    define S_scanleft_disable                 0x0             
+#    define S_scanleft_enable          0x1             
+#    define S_sdxl_MASK                0xfffffffd      /* bit 1 */
+#    define S_sdxl_pos                         0x0             
+#    define S_sdxl_neg                         0x2             
+#    define S_sdy_MASK                         0xfffffffb      /* bit 2 */
+#    define S_sdy_pos                  0x0             
+#    define S_sdy_neg                  0x4             
+#    define S_sdxr_MASK                0xffffffdf      /* bit 5 */
+#    define S_sdxr_pos                         0x0             
+#    define S_sdxr_neg                         0x20            
+#    define S_brkleft_MASK             0xfffffeff      /* bit 8 */
+#    define S_brkleft_disable          0x0             
+#    define S_brkleft_enable           0x100           
+#    define S_errorinit_MASK           0x7fffffff      /* bit 31 */
+#    define S_errorinit_disable        0x0             
+#    define S_errorinit_enable                 0x80000000      
+
+#define MGAREG_SHIFT                           0x1c50
+
+#    define FSC_x_off_MASK             0xfffffff0      /* bits 0-3 */
+#    define FSC_x_off_SHIFT            0               
+#    define FSC_funcnt_MASK            0xffffff80      /* bits 0-6 */
+#    define FSC_funcnt_SHIFT           0               
+#    define FSC_y_off_MASK             0xffffff8f      /* bits 4-6 */
+#    define FSC_y_off_SHIFT            4               
+#    define FSC_funoff_MASK            0xffc0ffff      /* bits 16-21 */
+#    define FSC_funoff_SHIFT           16              
+#    define FSC_stylelen_MASK          0xffc0ffff      /* bits 16-21 */
+#    define FSC_stylelen_SHIFT                 16              
+
+#define MGAREG_SOFTRAP                         0x2c48
+
+#    define STH_softraphand_MASK       0x3             /* bits 2-31 */
+#    define STH_softraphand_SHIFT      2               
+
+#define MGAREG_SPECBSTART                      0x2c98
+#define MGAREG_SPECBXINC                       0x2c9c
+#define MGAREG_SPECBYINC                       0x2ca0
+#define MGAREG_SPECGSTART                      0x2c8c
+#define MGAREG_SPECGXINC                       0x2c90
+#define MGAREG_SPECGYINC                       0x2c94
+#define MGAREG_SPECRSTART                      0x2c80
+#define MGAREG_SPECRXINC                       0x2c84
+#define MGAREG_SPECRYINC                       0x2c88
+#define MGAREG_SRC0                            0x1c30
+#define MGAREG_SRC1                            0x1c34
+#define MGAREG_SRC2                            0x1c38
+#define MGAREG_SRC3                            0x1c3c
+#define MGAREG_SRCORG                          0x2cb4
+
+#    define SO_srcmap_MASK             0xfffffffe      /* bit 0 */
+#    define SO_srcmap_fb               0x0             
+#    define SO_srcmap_sys              0x1             
+#    define SO_srcacc_MASK             0xfffffffd      /* bit 1 */
+#    define SO_srcacc_pci              0x0             
+#    define SO_srcacc_agp              0x2             
+#    define SO_srcorg_MASK             0x7             /* bits 3-31 */
+#    define SO_srcorg_SHIFT            3               
+
+#define MGAREG_STATUS                          0x1e14
+
+#    define STAT_softrapen_MASK        0xfffffffe      /* bit 0 */
+#    define STAT_softrapen_disable     0x0             
+#    define STAT_softrapen_enable      0x1             
+#    define STAT_pickpen_MASK          0xfffffffb      /* bit 2 */
+#    define STAT_pickpen_disable       0x0             
+#    define STAT_pickpen_enable        0x4             
+#    define STAT_vsyncsts_MASK                 0xfffffff7      /* bit 3 */
+#    define STAT_vsyncsts_disable      0x0             
+#    define STAT_vsyncsts_enable       0x8             
+#    define STAT_vsyncpen_MASK                 0xffffffef      /* bit 4 */
+#    define STAT_vsyncpen_disable      0x0             
+#    define STAT_vsyncpen_enable       0x10            
+#    define STAT_vlinepen_MASK                 0xffffffdf      /* bit 5 */
+#    define STAT_vlinepen_disable      0x0             
+#    define STAT_vlinepen_enable       0x20            
+#    define STAT_extpen_MASK           0xffffffbf      /* bit 6 */
+#    define STAT_extpen_disable        0x0             
+#    define STAT_extpen_enable                 0x40            
+#    define STAT_wpen_MASK             0xffffff7f      /* bit 7 */
+#    define STAT_wpen_disable          0x0             
+#    define STAT_wpen_enable           0x80            
+#    define STAT_wcpen_MASK            0xfffffeff      /* bit 8 */
+#    define STAT_wcpen_disable                 0x0             
+#    define STAT_wcpen_enable          0x100           
+#    define STAT_dwgengsts_MASK        0xfffeffff      /* bit 16 */
+#    define STAT_dwgengsts_disable     0x0             
+#    define STAT_dwgengsts_enable      0x10000         
+#    define STAT_endprdmasts_MASK      0xfffdffff      /* bit 17 */
+#    define STAT_endprdmasts_disable   0x0             
+#    define STAT_endprdmasts_enable    0x20000         
+#    define STAT_wbusy_MASK            0xfffbffff      /* bit 18 */
+#    define STAT_wbusy_disable                 0x0             
+#    define STAT_wbusy_enable          0x40000         
+#    define STAT_swflag_MASK           0xfffffff       /* bits 28-31 */
+#    define STAT_swflag_SHIFT          28              
+
+#define MGAREG_STENCIL                         0x2cc8
+
+#    define S_sref_MASK                0xffffff00      /* bits 0-7 */
+#    define S_sref_SHIFT               0               
+#    define S_smsk_MASK                0xffff00ff      /* bits 8-15 */
+#    define S_smsk_SHIFT               8               
+#    define S_swtmsk_MASK              0xff00ffff      /* bits 16-23 */
+#    define S_swtmsk_SHIFT             16              
+
+#define MGAREG_STENCILCTL                      0x2ccc
+
+#    define SC_smode_MASK              0xfffffff8      /* bits 0-2 */
+#    define SC_smode_salways           0x0             /* val 0, shift 0 */
+#    define SC_smode_snever            0x1             /* val 1, shift 0 */
+#    define SC_smode_se                0x2             /* val 2, shift 0 */
+#    define SC_smode_sne               0x3             /* val 3, shift 0 */
+#    define SC_smode_slt               0x4             /* val 4, shift 0 */
+#    define SC_smode_slte              0x5             /* val 5, shift 0 */
+#    define SC_smode_sgt               0x6             /* val 6, shift 0 */
+#    define SC_smode_sgte              0x7             /* val 7, shift 0 */
+#    define SC_sfailop_MASK            0xffffffc7      /* bits 3-5 */
+#    define SC_sfailop_keep            0x0             /* val 0, shift 3 */
+#    define SC_sfailop_zero            0x8             /* val 1, shift 3 */
+#    define SC_sfailop_replace                 0x10            /* val 2, shift 3 */
+#    define SC_sfailop_incrsat                 0x18            /* val 3, shift 3 */
+#    define SC_sfailop_decrsat                 0x20            /* val 4, shift 3 */
+#    define SC_sfailop_invert          0x28            /* val 5, shift 3 */
+#    define SC_sfailop_incr            0x30            /* val 6, shift 3 */
+#    define SC_sfailop_decr            0x38            /* val 7, shift 3 */
+#    define SC_szfailop_MASK           0xfffffe3f      /* bits 6-8 */
+#    define SC_szfailop_keep           0x0             /* val 0, shift 6 */
+#    define SC_szfailop_zero           0x40            /* val 1, shift 6 */
+#    define SC_szfailop_replace        0x80            /* val 2, shift 6 */
+#    define SC_szfailop_incrsat        0xc0            /* val 3, shift 6 */
+#    define SC_szfailop_decrsat        0x100           /* val 4, shift 6 */
+#    define SC_szfailop_invert                 0x140           /* val 5, shift 6 */
+#    define SC_szfailop_incr           0x180           /* val 6, shift 6 */
+#    define SC_szfailop_decr           0x1c0           /* val 7, shift 6 */
+#    define SC_szpassop_MASK           0xfffff1ff      /* bits 9-11 */
+#    define SC_szpassop_keep           0x0             /* val 0, shift 9 */
+#    define SC_szpassop_zero           0x200           /* val 1, shift 9 */
+#    define SC_szpassop_replace        0x400           /* val 2, shift 9 */
+#    define SC_szpassop_incrsat        0x600           /* val 3, shift 9 */
+#    define SC_szpassop_decrsat        0x800           /* val 4, shift 9 */
+#    define SC_szpassop_invert                 0xa00           /* val 5, shift 9 */
+#    define SC_szpassop_incr           0xc00           /* val 6, shift 9 */
+#    define SC_szpassop_decr           0xe00           /* val 7, shift 9 */
+
+#define MGAREG_TDUALSTAGE0                     0x2cf8
+
+#    define TD0_color_arg2_MASK        0xfffffffc      /* bits 0-1 */
+#    define TD0_color_arg2_diffuse     0x0             /* val 0, shift 0 */
+#    define TD0_color_arg2_specular    0x1             /* val 1, shift 0 */
+#    define TD0_color_arg2_fcol        0x2             /* val 2, shift 0 */
+#    define TD0_color_arg2_prevstage   0x3             /* val 3, shift 0 */
+#    define TD0_color_alpha_MASK       0xffffffe3      /* bits 2-4 */
+#    define TD0_color_alpha_diffuse    0x0             /* val 0, shift 2 */
+#    define TD0_color_alpha_fcol       0x4             /* val 1, shift 2 */
+#    define TD0_color_alpha_currtex    0x8             /* val 2, shift 2 */
+#    define TD0_color_alpha_prevtex    0xc             /* val 3, shift 2 */
+#    define TD0_color_alpha_prevstage  0x10            /* val 4, shift 2 */
+#    define TD0_color_arg1_replicatealpha_MASK 0xffffffdf      /* bit 5 */
+#    define TD0_color_arg1_replicatealpha_disable 0x0          
+#    define TD0_color_arg1_replicatealpha_enable 0x20          
+#    define TD0_color_arg1_inv_MASK    0xffffffbf      /* bit 6 */
+#    define TD0_color_arg1_inv_disable         0x0             
+#    define TD0_color_arg1_inv_enable  0x40            
+#    define TD0_color_arg2_replicatealpha_MASK 0xffffff7f      /* bit 7 */
+#    define TD0_color_arg2_replicatealpha_disable 0x0          
+#    define TD0_color_arg2_replicatealpha_enable 0x80          
+#    define TD0_color_arg2_inv_MASK    0xfffffeff      /* bit 8 */
+#    define TD0_color_arg2_inv_disable         0x0             
+#    define TD0_color_arg2_inv_enable  0x100           
+#    define TD0_color_alpha1inv_MASK   0xfffffdff      /* bit 9 */
+#    define TD0_color_alpha1inv_disable 0x0            
+#    define TD0_color_alpha1inv_enable         0x200           
+#    define TD0_color_alpha2inv_MASK   0xfffffbff      /* bit 10 */
+#    define TD0_color_alpha2inv_disable 0x0            
+#    define TD0_color_alpha2inv_enable         0x400           
+#    define TD0_color_arg1mul_MASK     0xfffff7ff      /* bit 11 */
+#    define TD0_color_arg1mul_disable  0x0             /* val 0, shift 11 */
+#    define TD0_color_arg1mul_alpha1   0x800           /* val 1, shift 11 */
+#    define TD0_color_arg2mul_MASK     0xffffefff      /* bit 12 */
+#    define TD0_color_arg2mul_disable  0x0             /* val 0, shift 12 */
+#    define TD0_color_arg2mul_alpha2   0x1000          /* val 1, shift 12 */
+#    define TD0_color_arg1add_MASK     0xffffdfff      /* bit 13 */
+#    define TD0_color_arg1add_disable  0x0             /* val 0, shift 13 */
+#    define TD0_color_arg1add_mulout   0x2000          /* val 1, shift 13 */
+#    define TD0_color_arg2add_MASK     0xffffbfff      /* bit 14 */
+#    define TD0_color_arg2add_disable  0x0             /* val 0, shift 14 */
+#    define TD0_color_arg2add_mulout   0x4000          /* val 1, shift 14 */
+#    define TD0_color_modbright_MASK   0xfffe7fff      /* bits 15-16 */
+#    define TD0_color_modbright_disable 0x0            /* val 0, shift 15 */
+#    define TD0_color_modbright_2x     0x8000          /* val 1, shift 15 */
+#    define TD0_color_modbright_4x     0x10000         /* val 2, shift 15 */
+#    define TD0_color_add_MASK                 0xfffdffff      /* bit 17 */
+#    define TD0_color_add_sub          0x0             /* val 0, shift 17 */
+#    define TD0_color_add_add          0x20000         /* val 1, shift 17 */
+#    define TD0_color_add2x_MASK       0xfffbffff      /* bit 18 */
+#    define TD0_color_add2x_disable    0x0             
+#    define TD0_color_add2x_enable     0x40000         
+#    define TD0_color_addbias_MASK     0xfff7ffff      /* bit 19 */
+#    define TD0_color_addbias_disable  0x0             
+#    define TD0_color_addbias_enable   0x80000         
+#    define TD0_color_blend_MASK       0xffefffff      /* bit 20 */
+#    define TD0_color_blend_disable    0x0             
+#    define TD0_color_blend_enable     0x100000        
+#    define TD0_color_sel_MASK                 0xff9fffff      /* bits 21-22 */
+#    define TD0_color_sel_arg1                 0x0             /* val 0, shift 21 */
+#    define TD0_color_sel_arg2                 0x200000        /* val 1, shift 21 */
+#    define TD0_color_sel_add          0x400000        /* val 2, shift 21 */
+#    define TD0_color_sel_mul          0x600000        /* val 3, shift 21 */
+#    define TD0_alpha_arg1_inv_MASK    0xff7fffff      /* bit 23 */
+#    define TD0_alpha_arg1_inv_disable         0x0             
+#    define TD0_alpha_arg1_inv_enable  0x800000        
+#    define TD0_alpha_arg2_MASK        0xfcffffff      /* bits 24-25 */
+#    define TD0_alpha_arg2_diffuse     0x0             /* val 0, shift 24 */
+#    define TD0_alpha_arg2_fcol        0x1000000       /* val 1, shift 24 */
+#    define TD0_alpha_arg2_prevtex     0x2000000       /* val 2, shift 24 */
+#    define TD0_alpha_arg2_prevstage   0x3000000       /* val 3, shift 24 */
+#    define TD0_alpha_arg2_inv_MASK    0xfbffffff      /* bit 26 */
+#    define TD0_alpha_arg2_inv_disable         0x0             
+#    define TD0_alpha_arg2_inv_enable  0x4000000       
+#    define TD0_alpha_add_MASK                 0xf7ffffff      /* bit 27 */
+#    define TD0_alpha_add_disable      0x0             
+#    define TD0_alpha_add_enable       0x8000000       
+#    define TD0_alpha_addbias_MASK     0xefffffff      /* bit 28 */
+#    define TD0_alpha_addbias_disable  0x0             
+#    define TD0_alpha_addbias_enable   0x10000000      
+#    define TD0_alpha_add2x_MASK       0xdfffffff      /* bit 29 */
+#    define TD0_alpha_add2x_disable    0x0             
+#    define TD0_alpha_add2x_enable     0x20000000      
+#    define TD0_alpha_modbright_MASK   0xcfffffff      /* bits 28-29 */
+#    define TD0_alpha_modbright_disable 0x0            /* val 0, shift 28 */
+#    define TD0_alpha_modbright_2x     0x10000000      /* val 1, shift 28 */
+#    define TD0_alpha_modbright_4x     0x20000000      /* val 2, shift 28 */
+#    define TD0_alpha_sel_MASK                 0x3fffffff      /* bits 30-31 */
+#    define TD0_alpha_sel_arg1                 0x0             /* val 0, shift 30 */
+#    define TD0_alpha_sel_arg2                 0x40000000      /* val 1, shift 30 */
+#    define TD0_alpha_sel_add          0x80000000      /* val 2, shift 30 */
+#    define TD0_alpha_sel_mul          0xc0000000      /* val 3, shift 30 */
+
+#define MGAREG_TDUALSTAGE1                     0x2cfc
+
+#    define TD1_color_arg2_MASK        0xfffffffc      /* bits 0-1 */
+#    define TD1_color_arg2_diffuse     0x0             /* val 0, shift 0 */
+#    define TD1_color_arg2_specular    0x1             /* val 1, shift 0 */
+#    define TD1_color_arg2_fcol        0x2             /* val 2, shift 0 */
+#    define TD1_color_arg2_prevstage   0x3             /* val 3, shift 0 */
+#    define TD1_color_alpha_MASK       0xffffffe3      /* bits 2-4 */
+#    define TD1_color_alpha_diffuse    0x0             /* val 0, shift 2 */
+#    define TD1_color_alpha_fcol       0x4             /* val 1, shift 2 */
+#    define TD1_color_alpha_tex0       0x8             /* val 2, shift 2 */
+#    define TD1_color_alpha_prevtex    0xc             /* val 3, shift 2 */
+#    define TD1_color_alpha_prevstage  0x10            /* val 4, shift 2 */
+#    define TD1_color_arg1_replicatealpha_MASK 0xffffffdf      /* bit 5 */
+#    define TD1_color_arg1_replicatealpha_disable 0x0          
+#    define TD1_color_arg1_replicatealpha_enable 0x20          
+#    define TD1_color_arg1_inv_MASK    0xffffffbf      /* bit 6 */
+#    define TD1_color_arg1_inv_disable         0x0             
+#    define TD1_color_arg1_inv_enable  0x40            
+#    define TD1_color_arg2_replicatealpha_MASK 0xffffff7f      /* bit 7 */
+#    define TD1_color_arg2_replicatealpha_disable 0x0          
+#    define TD1_color_arg2_replicatealpha_enable 0x80          
+#    define TD1_color_arg2_inv_MASK    0xfffffeff      /* bit 8 */
+#    define TD1_color_arg2_inv_disable         0x0             
+#    define TD1_color_arg2_inv_enable  0x100           
+#    define TD1_color_alpha1inv_MASK   0xfffffdff      /* bit 9 */
+#    define TD1_color_alpha1inv_disable 0x0            
+#    define TD1_color_alpha1inv_enable         0x200           
+#    define TD1_color_alpha2inv_MASK   0xfffffbff      /* bit 10 */
+#    define TD1_color_alpha2inv_disable 0x0            
+#    define TD1_color_alpha2inv_enable         0x400           
+#    define TD1_color_arg1mul_MASK     0xfffff7ff      /* bit 11 */
+#    define TD1_color_arg1mul_disable  0x0             /* val 0, shift 11 */
+#    define TD1_color_arg1mul_alpha1   0x800           /* val 1, shift 11 */
+#    define TD1_color_arg2mul_MASK     0xffffefff      /* bit 12 */
+#    define TD1_color_arg2mul_disable  0x0             /* val 0, shift 12 */
+#    define TD1_color_arg2mul_alpha2   0x1000          /* val 1, shift 12 */
+#    define TD1_color_arg1add_MASK     0xffffdfff      /* bit 13 */
+#    define TD1_color_arg1add_disable  0x0             /* val 0, shift 13 */
+#    define TD1_color_arg1add_mulout   0x2000          /* val 1, shift 13 */
+#    define TD1_color_arg2add_MASK     0xffffbfff      /* bit 14 */
+#    define TD1_color_arg2add_disable  0x0             /* val 0, shift 14 */
+#    define TD1_color_arg2add_mulout   0x4000          /* val 1, shift 14 */
+#    define TD1_color_modbright_MASK   0xfffe7fff      /* bits 15-16 */
+#    define TD1_color_modbright_disable 0x0            /* val 0, shift 15 */
+#    define TD1_color_modbright_2x     0x8000          /* val 1, shift 15 */
+#    define TD1_color_modbright_4x     0x10000         /* val 2, shift 15 */
+#    define TD1_color_add_MASK                 0xfffdffff      /* bit 17 */
+#    define TD1_color_add_sub          0x0             /* val 0, shift 17 */
+#    define TD1_color_add_add          0x20000         /* val 1, shift 17 */
+#    define TD1_color_add2x_MASK       0xfffbffff      /* bit 18 */
+#    define TD1_color_add2x_disable    0x0             
+#    define TD1_color_add2x_enable     0x40000         
+#    define TD1_color_addbias_MASK     0xfff7ffff      /* bit 19 */
+#    define TD1_color_addbias_disable  0x0             
+#    define TD1_color_addbias_enable   0x80000         
+#    define TD1_color_blend_MASK       0xffefffff      /* bit 20 */
+#    define TD1_color_blend_disable    0x0             
+#    define TD1_color_blend_enable     0x100000        
+#    define TD1_color_sel_MASK                 0xff9fffff      /* bits 21-22 */
+#    define TD1_color_sel_arg1                 0x0             /* val 0, shift 21 */
+#    define TD1_color_sel_arg2                 0x200000        /* val 1, shift 21 */
+#    define TD1_color_sel_add          0x400000        /* val 2, shift 21 */
+#    define TD1_color_sel_mul          0x600000        /* val 3, shift 21 */
+#    define TD1_alpha_arg1_inv_MASK    0xff7fffff      /* bit 23 */
+#    define TD1_alpha_arg1_inv_disable         0x0             
+#    define TD1_alpha_arg1_inv_enable  0x800000        
+#    define TD1_alpha_arg2_MASK        0xfcffffff      /* bits 24-25 */
+#    define TD1_alpha_arg2_diffuse     0x0             /* val 0, shift 24 */
+#    define TD1_alpha_arg2_fcol        0x1000000       /* val 1, shift 24 */
+#    define TD1_alpha_arg2_prevtex     0x2000000       /* val 2, shift 24 */
+#    define TD1_alpha_arg2_prevstage   0x3000000       /* val 3, shift 24 */
+#    define TD1_alpha_arg2_inv_MASK    0xfbffffff      /* bit 26 */
+#    define TD1_alpha_arg2_inv_disable         0x0             
+#    define TD1_alpha_arg2_inv_enable  0x4000000       
+#    define TD1_alpha_add_MASK                 0xf7ffffff      /* bit 27 */
+#    define TD1_alpha_add_disable      0x0             
+#    define TD1_alpha_add_enable       0x8000000       
+#    define TD1_alpha_addbias_MASK     0xefffffff      /* bit 28 */
+#    define TD1_alpha_addbias_disable  0x0             
+#    define TD1_alpha_addbias_enable   0x10000000      
+#    define TD1_alpha_add2x_MASK       0xdfffffff      /* bit 29 */
+#    define TD1_alpha_add2x_disable    0x0             
+#    define TD1_alpha_add2x_enable     0x20000000      
+#    define TD1_alpha_modbright_MASK   0xcfffffff      /* bits 28-29 */
+#    define TD1_alpha_modbright_disable 0x0            /* val 0, shift 28 */
+#    define TD1_alpha_modbright_2x     0x10000000      /* val 1, shift 28 */
+#    define TD1_alpha_modbright_4x     0x20000000      /* val 2, shift 28 */
+#    define TD1_alpha_sel_MASK                 0x3fffffff      /* bits 30-31 */
+#    define TD1_alpha_sel_arg1                 0x0             /* val 0, shift 30 */
+#    define TD1_alpha_sel_arg2                 0x40000000      /* val 1, shift 30 */
+#    define TD1_alpha_sel_add          0x80000000      /* val 2, shift 30 */
+#    define TD1_alpha_sel_mul          0xc0000000      /* val 3, shift 30 */
+
+#define MGAREG_TEST0                           0x1e48
+
+#    define TST_ramtsten_MASK          0xfffffffe      /* bit 0 */
+#    define TST_ramtsten_disable       0x0             
+#    define TST_ramtsten_enable        0x1             
+#    define TST_ramtstdone_MASK        0xfffffffd      /* bit 1 */
+#    define TST_ramtstdone_disable     0x0             
+#    define TST_ramtstdone_enable      0x2             
+#    define TST_wramtstpass_MASK       0xfffffffb      /* bit 2 */
+#    define TST_wramtstpass_disable    0x0             
+#    define TST_wramtstpass_enable     0x4             
+#    define TST_tcachetstpass_MASK     0xfffffff7      /* bit 3 */
+#    define TST_tcachetstpass_disable  0x0             
+#    define TST_tcachetstpass_enable   0x8             
+#    define TST_tluttstpass_MASK       0xffffffef      /* bit 4 */
+#    define TST_tluttstpass_disable    0x0             
+#    define TST_tluttstpass_enable     0x10            
+#    define TST_luttstpass_MASK        0xffffffdf      /* bit 5 */
+#    define TST_luttstpass_disable     0x0             
+#    define TST_luttstpass_enable      0x20            
+#    define TST_besramtstpass_MASK     0xffffffbf      /* bit 6 */
+#    define TST_besramtstpass_disable  0x0             
+#    define TST_besramtstpass_enable   0x40            
+#    define TST_ringen_MASK            0xfffffeff      /* bit 8 */
+#    define TST_ringen_disable                 0x0             
+#    define TST_ringen_enable          0x100           
+#    define TST_apllbyp_MASK           0xfffffdff      /* bit 9 */
+#    define TST_apllbyp_disable        0x0             
+#    define TST_apllbyp_enable                 0x200           
+#    define TST_hiten_MASK             0xfffffbff      /* bit 10 */
+#    define TST_hiten_disable          0x0             
+#    define TST_hiten_enable           0x400           
+#    define TST_tmode_MASK             0xffffc7ff      /* bits 11-13 */
+#    define TST_tmode_SHIFT            11              
+#    define TST_tclksel_MASK           0xfffe3fff      /* bits 14-16 */
+#    define TST_tclksel_SHIFT          14              
+#    define TST_ringcnten_MASK                 0xfffdffff      /* bit 17 */
+#    define TST_ringcnten_disable      0x0             
+#    define TST_ringcnten_enable       0x20000         
+#    define TST_ringcnt_MASK           0xc003ffff      /* bits 18-29 */
+#    define TST_ringcnt_SHIFT          18              
+#    define TST_ringcntclksl_MASK      0xbfffffff      /* bit 30 */
+#    define TST_ringcntclksl_disable   0x0             
+#    define TST_ringcntclksl_enable    0x40000000      
+#    define TST_biosboot_MASK          0x7fffffff      /* bit 31 */
+#    define TST_biosboot_disable       0x0             
+#    define TST_biosboot_enable        0x80000000      
+
+#define MGAREG_TEXBORDERCOL                    0x2c5c
+#define MGAREG_TEXCTL                          0x2c30
+
+#    define TMC_tformat_MASK           0xfffffff0      /* bits 0-3 */
+#    define TMC_tformat_tw4            0x0             /* val 0, shift 0 */
+#    define TMC_tformat_tw8            0x1             /* val 1, shift 0 */
+#    define TMC_tformat_tw15           0x2             /* val 2, shift 0 */
+#    define TMC_tformat_tw16           0x3             /* val 3, shift 0 */
+#    define TMC_tformat_tw12           0x4             /* val 4, shift 0 */
+#    define TMC_tformat_tw32           0x6             /* val 6, shift 0 */
+#    define TMC_tformat_tw8a           0x7             /* val 7, shift 0 */
+#    define TMC_tformat_tw8al          0x8             /* val 8, shift 0 */
+#    define TMC_tformat_tw422          0xa             /* val 10, shift 0 */
+#    define TMC_tpitchlin_MASK                 0xfffffeff      /* bit 8 */
+#    define TMC_tpitchlin_disable      0x0             
+#    define TMC_tpitchlin_enable       0x100           
+#    define TMC_tpitchext_MASK                 0xfff001ff      /* bits 9-19 */
+#    define TMC_tpitchext_SHIFT        9               
+#    define TMC_tpitch_MASK            0xfff8ffff      /* bits 16-18 */
+#    define TMC_tpitch_SHIFT           16              
+#    define TMC_owalpha_MASK           0xffbfffff      /* bit 22 */
+#    define TMC_owalpha_disable        0x0             
+#    define TMC_owalpha_enable                 0x400000        
+#    define TMC_azeroextend_MASK       0xff7fffff      /* bit 23 */
+#    define TMC_azeroextend_disable    0x0             
+#    define TMC_azeroextend_enable     0x800000        
+#    define TMC_decalckey_MASK                 0xfeffffff      /* bit 24 */
+#    define TMC_decalckey_disable      0x0             
+#    define TMC_decalckey_enable       0x1000000       
+#    define TMC_takey_MASK             0xfdffffff      /* bit 25 */
+#    define TMC_takey_0                0x0             
+#    define TMC_takey_1                0x2000000       
+#    define TMC_tamask_MASK            0xfbffffff      /* bit 26 */
+#    define TMC_tamask_0               0x0             
+#    define TMC_tamask_1               0x4000000       
+#    define TMC_clampv_MASK            0xf7ffffff      /* bit 27 */
+#    define TMC_clampv_disable                 0x0             
+#    define TMC_clampv_enable          0x8000000       
+#    define TMC_clampu_MASK            0xefffffff      /* bit 28 */
+#    define TMC_clampu_disable                 0x0             
+#    define TMC_clampu_enable          0x10000000      
+#    define TMC_tmodulate_MASK                 0xdfffffff      /* bit 29 */
+#    define TMC_tmodulate_disable      0x0             
+#    define TMC_tmodulate_enable       0x20000000      
+#    define TMC_strans_MASK            0xbfffffff      /* bit 30 */
+#    define TMC_strans_disable                 0x0             
+#    define TMC_strans_enable          0x40000000      
+#    define TMC_itrans_MASK            0x7fffffff      /* bit 31 */
+#    define TMC_itrans_disable                 0x0             
+#    define TMC_itrans_enable          0x80000000      
+
+#define MGAREG_TEXCTL2                         0x2c3c
+
+#    define TMC_decalblend_MASK        0xfffffffe      /* bit 0 */
+#    define TMC_decalblend_disable     0x0             
+#    define TMC_decalblend_enable      0x1             
+#    define TMC_idecal_MASK            0xfffffffd      /* bit 1 */
+#    define TMC_idecal_disable                 0x0             
+#    define TMC_idecal_enable          0x2             
+#    define TMC_decaldis_MASK          0xfffffffb      /* bit 2 */
+#    define TMC_decaldis_disable       0x0             
+#    define TMC_decaldis_enable        0x4             
+#    define TMC_ckstransdis_MASK       0xffffffef      /* bit 4 */
+#    define TMC_ckstransdis_disable    0x0             
+#    define TMC_ckstransdis_enable     0x10            
+#    define TMC_borderen_MASK          0xffffffdf      /* bit 5 */
+#    define TMC_borderen_disable       0x0             
+#    define TMC_borderen_enable        0x20            
+#    define TMC_specen_MASK            0xffffffbf      /* bit 6 */
+#    define TMC_specen_disable                 0x0             
+#    define TMC_specen_enable          0x40            
+#    define TMC_dualtex_MASK           0xffffff7f      /* bit 7 */
+#    define TMC_dualtex_disable        0x0             
+#    define TMC_dualtex_enable                 0x80            
+#    define TMC_tablefog_MASK          0xfffffeff      /* bit 8 */
+#    define TMC_tablefog_disable       0x0             
+#    define TMC_tablefog_enable        0x100           
+#    define TMC_bumpmap_MASK           0xfffffdff      /* bit 9 */
+#    define TMC_bumpmap_disable        0x0             
+#    define TMC_bumpmap_enable                 0x200           
+#    define TMC_map1_MASK              0x7fffffff      /* bit 31 */
+#    define TMC_map1_disable           0x0             
+#    define TMC_map1_enable            0x80000000      
+
+#define MGAREG_TEXFILTER                       0x2c58
+
+#    define TF_minfilter_MASK          0xfffffff0      /* bits 0-3 */
+#    define TF_minfilter_nrst          0x0             /* val 0, shift 0 */
+#    define TF_minfilter_bilin                 0x2             /* val 2, shift 0 */
+#    define TF_minfilter_cnst          0x3             /* val 3, shift 0 */
+#    define TF_minfilter_mm1s          0x8             /* val 8, shift 0 */
+#    define TF_minfilter_mm2s          0x9             /* val 9, shift 0 */
+#    define TF_minfilter_mm4s          0xa             /* val 10, shift 0 */
+#    define TF_minfilter_mm8s          0xc             /* val 12, shift 0 */
+#    define TF_magfilter_MASK          0xffffff0f      /* bits 4-7 */
+#    define TF_magfilter_nrst          0x0             /* val 0, shift 4 */
+#    define TF_magfilter_bilin                 0x20            /* val 2, shift 4 */
+#    define TF_magfilter_cnst          0x30            /* val 3, shift 4 */
+#    define TF_avgstride_MASK          0xfff7ffff      /* bit 19 */
+#    define TF_avgstride_disable       0x0             
+#    define TF_avgstride_enable        0x80000         
+#    define TF_filteralpha_MASK        0xffefffff      /* bit 20 */
+#    define TF_filteralpha_disable     0x0             
+#    define TF_filteralpha_enable      0x100000        
+#    define TF_fthres_MASK             0xe01fffff      /* bits 21-28 */
+#    define TF_fthres_SHIFT            21              
+#    define TF_mapnb_MASK              0x1fffffff      /* bits 29-31 */
+#    define TF_mapnb_SHIFT             29              
+
+#define MGAREG_TEXHEIGHT                       0x2c2c
+
+#    define TH_th_MASK                         0xffffffc0      /* bits 0-5 */
+#    define TH_th_SHIFT                0               
+#    define TH_rfh_MASK                0xffff81ff      /* bits 9-14 */
+#    define TH_rfh_SHIFT               9               
+#    define TH_thmask_MASK             0xe003ffff      /* bits 18-28 */
+#    define TH_thmask_SHIFT            18              
+
+#define MGAREG_TEXORG                          0x2c24
+
+#    define TO_texorgmap_MASK          0xfffffffe      /* bit 0 */
+#    define TO_texorgmap_fb            0x0             
+#    define TO_texorgmap_sys           0x1             
+#    define TO_texorgacc_MASK          0xfffffffd      /* bit 1 */
+#    define TO_texorgacc_pci           0x0             
+#    define TO_texorgacc_agp           0x2             
+#    define TO_texorgoffsetsel                 0x4             
+#    define TO_texorg_MASK             0x1f            /* bits 5-31 */
+#    define TO_texorg_SHIFT            5               
+
+#define MGAREG_TEXORG1                         0x2ca4
+#define MGAREG_TEXORG2                         0x2ca8
+#define MGAREG_TEXORG3                         0x2cac
+#define MGAREG_TEXORG4                         0x2cb0
+#define MGAREG_TEXTRANS                        0x2c34
+
+#    define TT_tckey_MASK              0xffff0000      /* bits 0-15 */
+#    define TT_tckey_SHIFT             0               
+#    define TT_tkmask_MASK             0xffff          /* bits 16-31 */
+#    define TT_tkmask_SHIFT            16              
+
+#define MGAREG_TEXTRANSHIGH                    0x2c38
+
+#    define TT_tckeyh_MASK             0xffff0000      /* bits 0-15 */
+#    define TT_tckeyh_SHIFT            0               
+#    define TT_tkmaskh_MASK            0xffff          /* bits 16-31 */
+#    define TT_tkmaskh_SHIFT           16              
+
+#define MGAREG_TEXWIDTH                        0x2c28
+
+#    define TW_tw_MASK                         0xffffffc0      /* bits 0-5 */
+#    define TW_tw_SHIFT                0               
+#    define TW_rfw_MASK                0xffff81ff      /* bits 9-14 */
+#    define TW_rfw_SHIFT               9               
+#    define TW_twmask_MASK             0xe003ffff      /* bits 18-28 */
+#    define TW_twmask_SHIFT            18              
+
+#define MGAREG_TMR0                            0x2c00
+#define MGAREG_TMR1                            0x2c04
+#define MGAREG_TMR2                            0x2c08
+#define MGAREG_TMR3                            0x2c0c
+#define MGAREG_TMR4                            0x2c10
+#define MGAREG_TMR5                            0x2c14
+#define MGAREG_TMR6                            0x2c18
+#define MGAREG_TMR7                            0x2c1c
+#define MGAREG_TMR8                            0x2c20
+#define MGAREG_VBIADDR0                        0x3e08
+#define MGAREG_VBIADDR1                        0x3e0c
+#define MGAREG_VCOUNT                          0x1e20
+#define MGAREG_WACCEPTSEQ                      0x1dd4
+
+#    define WAS_seqdst0_MASK           0xffffffc0      /* bits 0-5 */
+#    define WAS_seqdst0_SHIFT          0               
+#    define WAS_seqdst1_MASK           0xfffff03f      /* bits 6-11 */
+#    define WAS_seqdst1_SHIFT          6               
+#    define WAS_seqdst2_MASK           0xfffc0fff      /* bits 12-17 */
+#    define WAS_seqdst2_SHIFT          12              
+#    define WAS_seqdst3_MASK           0xff03ffff      /* bits 18-23 */
+#    define WAS_seqdst3_SHIFT          18              
+#    define WAS_seqlen_MASK            0xfcffffff      /* bits 24-25 */
+#    define WAS_wfirsttag_MASK                 0xfbffffff      /* bit 26 */
+#    define WAS_wfirsttag_disable      0x0             
+#    define WAS_wfirsttag_enable       0x4000000       
+#    define WAS_wsametag_MASK          0xf7ffffff      /* bit 27 */
+#    define WAS_wsametag_disable       0x0             
+#    define WAS_wsametag_enable        0x8000000       
+#    define WAS_seqoff_MASK            0xefffffff      /* bit 28 */
+#    define WAS_seqoff_disable                 0x0             
+#    define WAS_seqoff_enable          0x10000000      
+
+#define MGAREG_WCODEADDR                       0x1e6c
+
+#    define WMA_wcodeaddr_MASK                 0xff            /* bits 8-31 */
+#    define WMA_wcodeaddr_SHIFT        8               
+
+#define MGAREG_WFLAG                           0x1dc4
+
+#    define WF_walustsflag_MASK        0xffffff00      /* bits 0-7 */
+#    define WF_walustsflag_SHIFT       0               
+#    define WF_walucfgflag_MASK        0xffff00ff      /* bits 8-15 */
+#    define WF_walucfgflag_SHIFT       8               
+#    define WF_wprgflag_MASK           0xffff          /* bits 16-31 */
+#    define WF_wprgflag_SHIFT          16              
+
+#define MGAREG_WFLAG1                          0x1de0
+
+#    define WF1_walustsflag1_MASK      0xffffff00      /* bits 0-7 */
+#    define WF1_walustsflag1_SHIFT     0               
+#    define WF1_walucfgflag1_MASK      0xffff00ff      /* bits 8-15 */
+#    define WF1_walucfgflag1_SHIFT     8               
+#    define WF1_wprgflag1_MASK                 0xffff          /* bits 16-31 */
+#    define WF1_wprgflag1_SHIFT        16              
+
+#define MGAREG_WFLAGNB                         0x1e64
+#define MGAREG_WFLAGNB1                        0x1e08
+#define MGAREG_WGETMSB                         0x1dc8
+
+#    define WGV_wgetmsbmin_MASK        0xffffffe0      /* bits 0-4 */
+#    define WGV_wgetmsbmin_SHIFT       0               
+#    define WGV_wgetmsbmax_MASK        0xffffe0ff      /* bits 8-12 */
+#    define WGV_wgetmsbmax_SHIFT       8               
+#    define WGV_wbrklefttop_MASK       0xfffeffff      /* bit 16 */
+#    define WGV_wbrklefttop_disable    0x0             
+#    define WGV_wbrklefttop_enable     0x10000         
+#    define WGV_wfastcrop_MASK                 0xfffdffff      /* bit 17 */
+#    define WGV_wfastcrop_disable      0x0             
+#    define WGV_wfastcrop_enable       0x20000         
+#    define WGV_wcentersnap_MASK       0xfffbffff      /* bit 18 */
+#    define WGV_wcentersnap_disable    0x0             
+#    define WGV_wcentersnap_enable     0x40000         
+#    define WGV_wbrkrighttop_MASK      0xfff7ffff      /* bit 19 */
+#    define WGV_wbrkrighttop_disable   0x0             
+#    define WGV_wbrkrighttop_enable    0x80000         
+
+#define MGAREG_WIADDR                          0x1dc0
+
+#    define WIA_wmode_MASK             0xfffffffc      /* bits 0-1 */
+#    define WIA_wmode_suspend          0x0             /* val 0, shift 0 */
+#    define WIA_wmode_resume           0x1             /* val 1, shift 0 */
+#    define WIA_wmode_jump             0x2             /* val 2, shift 0 */
+#    define WIA_wmode_start            0x3             /* val 3, shift 0 */
+#    define WIA_wagp_MASK              0xfffffffb      /* bit 2 */
+#    define WIA_wagp_pci               0x0             
+#    define WIA_wagp_agp               0x4             
+#    define WIA_wiaddr_MASK            0x7             /* bits 3-31 */
+#    define WIA_wiaddr_SHIFT           3               
+
+#define MGAREG_WIADDR2                         0x1dd8
+
+#    define WIA2_wmode_MASK            0xfffffffc      /* bits 0-1 */
+#    define WIA2_wmode_suspend                 0x0             /* val 0, shift 0 */
+#    define WIA2_wmode_resume          0x1             /* val 1, shift 0 */
+#    define WIA2_wmode_jump            0x2             /* val 2, shift 0 */
+#    define WIA2_wmode_start           0x3             /* val 3, shift 0 */
+#    define WIA2_wagp_MASK             0xfffffffb      /* bit 2 */
+#    define WIA2_wagp_pci              0x0             
+#    define WIA2_wagp_agp              0x4             
+#    define WIA2_wiaddr_MASK           0x7             /* bits 3-31 */
+#    define WIA2_wiaddr_SHIFT          3               
+
+#define MGAREG_WIADDRNB                        0x1e60
+#define MGAREG_WIADDRNB1                       0x1e04
+#define MGAREG_WIADDRNB2                       0x1e00
+#define MGAREG_WIMEMADDR                       0x1e68
+
+#    define WIMA_wimemaddr_MASK        0xffffff00      /* bits 0-7 */
+#    define WIMA_wimemaddr_SHIFT       0               
+
+#define MGAREG_WIMEMDATA                       0x2000
+#define MGAREG_WIMEMDATA1                      0x2100
+#define MGAREG_WMISC                           0x1e70
+
+#    define WM_wucodecache_MASK        0xfffffffe      /* bit 0 */
+#    define WM_wucodecache_disable     0x0             
+#    define WM_wucodecache_enable      0x1             
+#    define WM_wmaster_MASK            0xfffffffd      /* bit 1 */
+#    define WM_wmaster_disable                 0x0             
+#    define WM_wmaster_enable          0x2             
+#    define WM_wcacheflush_MASK        0xfffffff7      /* bit 3 */
+#    define WM_wcacheflush_disable     0x0             
+#    define WM_wcacheflush_enable      0x8             
+
+#define MGAREG_WR                              0x2d00
+#define MGAREG_WVRTXSZ                         0x1dcc
+
+#    define WVS_wvrtxsz_MASK           0xffffffc0      /* bits 0-5 */
+#    define WVS_wvrtxsz_SHIFT          0               
+#    define WVS_primsz_MASK            0xffffc0ff      /* bits 8-13 */
+#    define WVS_primsz_SHIFT           8               
+
+#define MGAREG_XDST                            0x1cb0
+#define MGAREG_XYEND                           0x1c44
+
+#    define XYEA_x_end_MASK            0xffff0000      /* bits 0-15 */
+#    define XYEA_x_end_SHIFT           0               
+#    define XYEA_y_end_MASK            0xffff          /* bits 16-31 */
+#    define XYEA_y_end_SHIFT           16              
+
+#define MGAREG_XYSTRT                          0x1c40
+
+#    define XYSA_x_start_MASK          0xffff0000      /* bits 0-15 */
+#    define XYSA_x_start_SHIFT                 0               
+#    define XYSA_y_start_MASK          0xffff          /* bits 16-31 */
+#    define XYSA_y_start_SHIFT                 16              
+
+#define MGAREG_YBOT                            0x1c9c
+#define MGAREG_YDST                            0x1c90
+
+#    define YA_ydst_MASK               0xff800000      /* bits 0-22 */
+#    define YA_ydst_SHIFT              0               
+#    define YA_sellin_MASK             0x1fffffff      /* bits 29-31 */
+#    define YA_sellin_SHIFT            29              
+
+#define MGAREG_YDSTLEN                         0x1c88
+
+#    define YDL_length_MASK            0xffff0000      /* bits 0-15 */
+#    define YDL_length_SHIFT           0               
+#    define YDL_yval_MASK              0xffff          /* bits 16-31 */
+#    define YDL_yval_SHIFT             16              
+
+#define MGAREG_YDSTORG                         0x1c94
+#define MGAREG_YTOP                            0x1c98
+#define MGAREG_ZORG                            0x1c0c
+
+#    define ZO_zorgmap_MASK            0xfffffffe      /* bit 0 */
+#    define ZO_zorgmap_fb              0x0             
+#    define ZO_zorgmap_sys             0x1             
+#    define ZO_zorgacc_MASK            0xfffffffd      /* bit 1 */
+#    define ZO_zorgacc_pci             0x0             
+#    define ZO_zorgacc_agp             0x2             
+#    define ZO_zorg_MASK               0x3             /* bits 2-31 */
+#    define ZO_zorg_SHIFT              2               
+
+
+
+
+/**************** (END) AUTOMATICLY GENERATED REGISTER FILE ******************/
+
+#endif         /* _MGAREGS_H_ */
+
diff --git a/src/mesa/drivers/dri/mga/mgarender.c b/src/mesa/drivers/dri/mga/mgarender.c
new file mode 100644 (file)
index 0000000..53614c2
--- /dev/null
@@ -0,0 +1,208 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgarender.c,v 1.4 2002/10/30 12:51:36 alanh Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+                     VA Linux Systems Inc., Fremont, California.
+
+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
+ATI, VA LINUX SYSTEMS AND/OR THEIR 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>
+ *
+ */
+
+
+/*
+ * Render unclipped vertex buffers by emitting vertices directly to
+ * dma buffers.  Use strip/fan hardware primitives where possible.
+ * Simulate missing primitives with indexed vertices.
+ */
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+/*//#include "mem.h"*/
+#include "mtypes.h"
+/*#include "mmath.h" */
+
+#include "tnl/t_context.h"
+
+#include "mgacontext.h"
+#include "mgatris.h"
+#include "mgastate.h"
+#include "mgaioctl.h"
+#include "mgavb.h"
+
+#define HAVE_POINTS      0
+#define HAVE_LINES       0
+#define HAVE_LINE_STRIPS 0
+#define HAVE_TRIANGLES   1
+#define HAVE_TRI_STRIPS  1
+#define HAVE_TRI_STRIP_1 0
+#define HAVE_TRI_FANS    1
+#define HAVE_POLYGONS    0
+#define HAVE_QUADS       0
+#define HAVE_QUAD_STRIPS 0
+
+#define HAVE_ELTS        0     /* for now */
+
+static void mgaDmaPrimitive( GLcontext *ctx, GLenum prim )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLuint hwprim;
+
+   switch (prim) {
+   case GL_TRIANGLES:
+      hwprim = MGA_WA_TRIANGLES;
+      break;
+   case GL_TRIANGLE_STRIP:
+      if (mmesa->vertex_size == 8)
+        hwprim = MGA_WA_TRISTRIP_T0;
+      else
+        hwprim = MGA_WA_TRISTRIP_T0T1;
+      break;
+   case GL_TRIANGLE_FAN:
+      if (mmesa->vertex_size == 8)
+        hwprim = MGA_WA_TRIFAN_T0;
+      else
+        hwprim = MGA_WA_TRIFAN_T0T1;
+      break;
+   default:
+      return;
+   }
+
+   mgaRasterPrimitive( ctx, GL_TRIANGLES, hwprim );
+}
+
+static void VERT_FALLBACK( GLcontext *ctx, GLuint start, GLuint count, 
+                          GLuint flags )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK );
+   tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 );
+   tnl->Driver.Render.PrimTabVerts[flags&PRIM_MODE_MASK]( ctx, start, count, flags );
+   MGA_CONTEXT(ctx)->SetupNewInputs |= VERT_BIT_CLIP;
+}
+
+#define LOCAL_VARS mgaContextPtr mmesa = MGA_CONTEXT(ctx) 
+#define INIT( prim ) do {                      \
+   if (0) fprintf(stderr, "%s\n", __FUNCTION__);       \
+   FLUSH_BATCH(mmesa);                         \
+   mgaDmaPrimitive( ctx, prim );               \
+} while (0)
+#define NEW_PRIMITIVE()  FLUSH_BATCH( mmesa )
+#define NEW_BUFFER()  FLUSH_BATCH( mmesa )
+#define GET_CURRENT_VB_MAX_VERTS() \
+   0 /* fix me */
+#define GET_SUBSEQUENT_VB_MAX_VERTS() \
+   MGA_BUFFER_SIZE / (mmesa->vertex_size * 4)
+#define EMIT_VERTS( ctx, j, nr ) \
+   mga_emit_contiguous_verts(ctx, j, (j)+(nr))
+
+#define TAG(x) mga_##x
+#include "tnl_dd/t_dd_dmatmp.h"
+
+
+
+/**********************************************************************/
+/*                          Render pipeline stage                     */
+/**********************************************************************/
+
+
+static GLboolean mga_run_render( GLcontext *ctx,
+                                 struct gl_pipeline_stage *stage )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb; 
+   GLuint i, length, flags = 0;
+
+   /* Don't handle clipping or indexed vertices or vertex manipulations.
+    */
+   if (VB->ClipOrMask || mmesa->RenderIndex != 0 || VB->Elts) {
+      return GL_TRUE;
+   }
+   
+   tnl->Driver.Render.Start( ctx );
+   mmesa->SetupNewInputs = ~0;      
+
+   for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
+   {
+      flags = VB->Primitive[i];
+      length= VB->PrimitiveLength[i];  
+      if (length)
+        mga_render_tab_verts[flags & PRIM_MODE_MASK]( ctx, i, i + length,
+                                                      flags );
+   } 
+
+   tnl->Driver.Render.Finish( ctx );
+
+   return GL_FALSE;            /* finished the pipe */
+}
+
+
+static void mga_check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
+{
+   GLuint inputs = VERT_BIT_POS | VERT_BIT_CLIP | VERT_BIT_COLOR0;
+
+   if (ctx->RenderMode == GL_RENDER) {
+      if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) 
+        inputs |= VERT_BIT_COLOR1;
+
+      if (ctx->Texture.Unit[0]._ReallyEnabled)
+        inputs |= VERT_BIT_TEX0;
+
+      if (ctx->Texture.Unit[1]._ReallyEnabled)
+        inputs |= VERT_BIT_TEX1;
+
+      if (ctx->Fog.Enabled) 
+        inputs |= VERT_BIT_FOG;
+   }
+
+   stage->inputs = inputs;
+}
+
+
+static void dtr( struct gl_pipeline_stage *stage )
+{
+   (void)stage;
+}
+
+
+const struct gl_pipeline_stage _mga_render_stage = 
+{ 
+   "mga render",
+   (_DD_NEW_SEPARATE_SPECULAR |
+    _NEW_TEXTURE|
+    _NEW_FOG|
+    _NEW_RENDERMODE),          /* re-check (new inputs) */
+   0,                          /* re-run (always runs) */
+   GL_TRUE,                    /* active */
+   0, 0,                       /* inputs (set in check_render), outputs */
+   0, 0,                       /* changed_inputs, private */
+   dtr,                                /* destructor */
+   mga_check_render,           /* check - initially set to alloc data */
+   mga_run_render              /* run */
+};
diff --git a/src/mesa/drivers/dri/mga/mgaspan.c b/src/mesa/drivers/dri/mga/mgaspan.c
new file mode 100644 (file)
index 0000000..8dc971c
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.11 2002/10/30 12:51:36 alanh Exp $ */
+
+#include "mtypes.h"
+#include "mgadd.h"
+#include "mgacontext.h"
+#include "mgaspan.h"
+#include "mgaioctl.h"
+#include "swrast/swrast.h"
+
+#define DBG 0
+
+
+#define LOCAL_VARS                                     \
+   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;   \
+   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;     \
+   __DRIscreenPrivate *sPriv = mmesa->driScreen;       \
+   GLuint pitch = mgaScreen->frontPitch;               \
+   GLuint height = dPriv->h;                           \
+   char *read_buf = (char *)(sPriv->pFB +              \
+                       mmesa->readOffset +             \
+                       dPriv->x * mgaScreen->cpp +     \
+                       dPriv->y * pitch);              \
+   char *buf = (char *)(sPriv->pFB +                   \
+                       mmesa->drawOffset +             \
+                       dPriv->x * mgaScreen->cpp +     \
+                       dPriv->y * pitch);              \
+   GLuint p;                                           \
+   (void) read_buf; (void) buf; (void) p
+   
+
+
+#define LOCAL_DEPTH_VARS                                               \
+   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;                   \
+   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;                     \
+   __DRIscreenPrivate *sPriv = mmesa->driScreen;                       \
+   GLuint pitch = mgaScreen->frontPitch;                               \
+   GLuint height = dPriv->h;                                           \
+   char *buf = (char *)(sPriv->pFB +                                   \
+                       mgaScreen->depthOffset +                        \
+                       dPriv->x * mgaScreen->cpp +                     \
+                       dPriv->y * pitch)
+
+#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS 
+
+#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
+                         _y >= miny && _y < maxy)
+
+#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i )                           \
+   if ( _y < miny || _y >= maxy ) {                                    \
+      _n1 = 0, _x1 = x;                                                        \
+   } else {                                                            \
+      _n1 = _n;                                                                \
+      _x1 = _x;                                                                \
+      if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
+      if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx);                        \
+   }
+
+
+#define HW_LOCK()                              \
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);     \
+   FLUSH_BATCH(mmesa);                         \
+   LOCK_HARDWARE_QUIESCENT(mmesa);
+
+
+#define HW_CLIPLOOP()                                          \
+  do {                                                         \
+    int _nc = mmesa->numClipRects;                             \
+    while (_nc--) {                                            \
+       int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX;    \
+       int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY;    \
+       int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX;    \
+       int maxy = mmesa->pClipRects[_nc].y2 - mmesa->drawY;
+
+#define HW_ENDCLIPLOOP()                       \
+    }                                          \
+  } while (0)
+
+#define HW_UNLOCK()                            \
+    UNLOCK_HARDWARE(mmesa);
+
+
+
+
+
+
+
+/* 16 bit, 565 rgb color spanline and pixel functions
+ */
+#define Y_FLIP(_y) (height - _y - 1)
+
+#undef INIT_MONO_PIXEL
+#define INIT_MONO_PIXEL(p, color) \
+  p = MGAPACKCOLOR565( color[0], color[1], color[2] )
+
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )                               \
+   *(GLushort *)(buf + _x*2 + _y*pitch)  = ( (((int)r & 0xf8) << 8) |  \
+                                            (((int)g & 0xfc) << 3) |   \
+                                            (((int)b & 0xf8) >> 3))
+
+#define WRITE_PIXEL( _x, _y, p )  \
+   *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y )                              \
+do {                                                           \
+   GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch);     \
+   rgba[0] = (((p >> 11) & 0x1f) * 255) / 31;                  \
+   rgba[1] = (((p >>  5) & 0x3f) * 255) / 63;                  \
+   rgba[2] = (((p >>  0) & 0x1f) * 255) / 31;                  \
+   rgba[3] = 255;                                              \
+} while(0)
+
+#define TAG(x) mga##x##_565
+#include "spantmp.h"
+
+
+
+
+
+/* 32 bit, 8888 argb color spanline and pixel functions
+ */
+
+#undef INIT_MONO_PIXEL
+#define INIT_MONO_PIXEL(p, color) \
+  p = MGAPACKCOLOR8888( color[0], color[1], color[2], color[3] )
+
+
+#define WRITE_RGBA(_x, _y, r, g, b, a)                 \
+    *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) |  \
+                                         (g << 8)  |   \
+                                         (b << 0)  |   \
+                                         (a << 24) )
+
+#define WRITE_PIXEL(_x, _y, p)                 \
+    *(GLuint *)(buf + _x*4 + _y*pitch) = p
+
+#define READ_RGBA(rgba, _x, _y)                                        \
+    do {                                                       \
+       GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch);     \
+       rgba[0] = (p >> 16) & 0xff;                             \
+       rgba[1] = (p >> 8)  & 0xff;                             \
+       rgba[2] = (p >> 0)  & 0xff;                             \
+       rgba[3] = 0xff;                                         \
+    } while (0)
+
+#define TAG(x) mga##x##_8888
+#include "spantmp.h"
+
+
+
+
+/* 16 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d )       \
+   *(GLushort *)(buf + _x*2 + _y*pitch) = d;
+
+#define READ_DEPTH( d, _x, _y )                \
+   d = *(GLushort *)(buf + _x*2 + _y*pitch);
+
+#define TAG(x) mga##x##_16
+#include "depthtmp.h"
+
+
+
+
+/* 32 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d )       \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = d;
+
+#define READ_DEPTH( d, _x, _y )                \
+   d = *(GLuint *)(buf + _x*4 + _y*pitch);
+
+#define TAG(x) mga##x##_32
+#include "depthtmp.h"
+
+
+
+/* 24/8 bit interleaved depth/stencil functions
+ */
+#define WRITE_DEPTH( _x, _y, d ) {                     \
+   GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch);    \
+   tmp &= 0xff;                                                \
+   tmp |= (d) << 8;                                    \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = tmp;           \
+}
+
+#define READ_DEPTH( d, _x, _y )        {                               \
+   d = (*(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff) >> 8;      \
+}
+
+#define TAG(x) mga##x##_24_8
+#include "depthtmp.h"
+
+#define WRITE_STENCIL( _x, _y, d ) {                   \
+   GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch);    \
+   tmp &= 0xffffff00;                                  \
+   tmp |= d & 0xff;                                    \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = tmp;           \
+}
+
+#define READ_STENCIL( d, _x, _y )              \
+   d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff;
+
+#define TAG(x) mga##x##_24_8
+#include "stenciltmp.h"
+
+
+
+void mgaDDInitSpanFuncs( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+
+   switch (mmesa->mgaScreen->cpp) {
+   case 2:
+      swdd->WriteRGBASpan = mgaWriteRGBASpan_565;
+      swdd->WriteRGBSpan = mgaWriteRGBSpan_565;
+      swdd->WriteMonoRGBASpan = mgaWriteMonoRGBASpan_565;
+      swdd->WriteRGBAPixels = mgaWriteRGBAPixels_565;
+      swdd->WriteMonoRGBAPixels = mgaWriteMonoRGBAPixels_565;
+      swdd->ReadRGBASpan = mgaReadRGBASpan_565;
+      swdd->ReadRGBAPixels = mgaReadRGBAPixels_565;
+
+      swdd->ReadDepthSpan = mgaReadDepthSpan_16;
+      swdd->WriteDepthSpan = mgaWriteDepthSpan_16;
+      swdd->ReadDepthPixels = mgaReadDepthPixels_16;
+      swdd->WriteDepthPixels = mgaWriteDepthPixels_16;
+      break;
+
+   case 4:
+      swdd->WriteRGBASpan = mgaWriteRGBASpan_8888;
+      swdd->WriteRGBSpan = mgaWriteRGBSpan_8888;
+      swdd->WriteMonoRGBASpan = mgaWriteMonoRGBASpan_8888;
+      swdd->WriteRGBAPixels = mgaWriteRGBAPixels_8888;
+      swdd->WriteMonoRGBAPixels = mgaWriteMonoRGBAPixels_8888;
+      swdd->ReadRGBASpan = mgaReadRGBASpan_8888;
+      swdd->ReadRGBAPixels = mgaReadRGBAPixels_8888;
+      
+      if (!mmesa->hw_stencil) {
+        swdd->ReadDepthSpan = mgaReadDepthSpan_32;
+        swdd->WriteDepthSpan = mgaWriteDepthSpan_32;
+        swdd->ReadDepthPixels = mgaReadDepthPixels_32;
+        swdd->WriteDepthPixels = mgaWriteDepthPixels_32;
+      } else {
+        swdd->ReadDepthSpan = mgaReadDepthSpan_24_8;
+        swdd->WriteDepthSpan = mgaWriteDepthSpan_24_8;
+        swdd->ReadDepthPixels = mgaReadDepthPixels_24_8;
+        swdd->WriteDepthPixels = mgaWriteDepthPixels_24_8;
+
+        swdd->ReadStencilSpan = mgaReadStencilSpan_24_8;
+        swdd->WriteStencilSpan = mgaWriteStencilSpan_24_8;
+        swdd->ReadStencilPixels = mgaReadStencilPixels_24_8;
+        swdd->WriteStencilPixels = mgaWriteStencilPixels_24_8;
+      }
+      break;
+   }
+}
diff --git a/src/mesa/drivers/dri/mga/mgaspan.h b/src/mesa/drivers/dri/mga/mgaspan.h
new file mode 100644 (file)
index 0000000..80583da
--- /dev/null
@@ -0,0 +1,34 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.h,v 1.3 2002/10/30 12:51:36 alanh Exp $ */
+/*
+ * 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>
+ */
+
+#ifndef _MGA_SPAN_H
+#define _MGA_SPAN_H
+
+extern void mgaDDInitSpanFuncs( GLcontext *ctx );
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c
new file mode 100644 (file)
index 0000000..02b98fd
--- /dev/null
@@ -0,0 +1,1131 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.13 2002/10/30 12:51:36 alanh Exp $ */
+
+#include <stdio.h>
+
+#include "mtypes.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 "mgabuffers.h"
+
+#include "swrast/swrast.h"
+#include "array_cache/acache.h"
+#include "tnl/tnl.h"
+#include "swrast_setup/swrast_setup.h"
+
+
+
+/* Some outstanding problems with accelerating logic ops...
+ */
+#if defined(ACCEL_ROP)
+static 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
+};
+#endif
+
+
+static void mgaUpdateStencil(const GLcontext *ctx)
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLuint stencil = 0, stencilctl = 0;
+
+   if (ctx->Stencil.Enabled)
+   {
+      stencil = ctx->Stencil.Ref[0] |
+        ( ctx->Stencil.ValueMask[0] << 8 ) |
+        ( ctx->Stencil.WriteMask[0] << 16 );
+
+      switch (ctx->Stencil.Function[0])
+      {
+      case GL_NEVER:
+        MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_snever);
+        break;
+      case GL_LESS:
+        MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slt);
+        break;
+      case GL_LEQUAL:
+        MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slte);
+        break;
+      case GL_GREATER:
+        MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgt);
+        break;
+      case GL_GEQUAL:
+        MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgte);
+        break;
+      case GL_NOTEQUAL:
+        MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sne);
+        break;
+      case GL_EQUAL:
+        MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_se);
+        break;
+      case GL_ALWAYS:
+        MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_salways);
+      default:
+        break;
+      }
+
+      switch (ctx->Stencil.FailFunc[0])
+      {
+      case GL_KEEP:
+        MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_keep);
+        break;
+      case GL_ZERO:
+        MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_zero);
+        break;
+      case GL_REPLACE:
+        MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_replace);
+        break;
+      case GL_INCR:
+        MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_incrsat);
+        break;
+      case GL_DECR:
+        MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_decrsat);
+        break;
+      case GL_INVERT:
+        MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_invert);
+        break;
+      default:
+        break;
+      }
+
+      switch (ctx->Stencil.ZFailFunc[0])
+      {
+      case GL_KEEP:
+        MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_keep);
+        break;
+      case GL_ZERO:
+        MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_zero);
+        break;
+      case GL_REPLACE:
+        MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_replace);
+        break;
+      case GL_INCR:
+        MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_incrsat);
+        break;
+      case GL_DECR:
+        MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_decrsat);
+        break;
+      case GL_INVERT:
+        MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_invert);
+        break;
+      default:
+        break;
+      }
+
+      switch (ctx->Stencil.ZPassFunc[0])
+      {
+      case GL_KEEP:
+        MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_keep);
+        break;
+      case GL_ZERO:
+        MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_zero);
+        break;
+      case GL_REPLACE:
+        MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_replace);
+        break;
+      case GL_INCR:
+        MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_incrsat);
+        break;
+      case GL_DECR:
+        MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_decrsat);
+        break;
+      case GL_INVERT:
+        MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_invert);
+        break;
+      default:
+        break;
+      }
+   }
+
+   mmesa->setup.stencil = stencil;
+   mmesa->setup.stencilctl = stencilctl;
+   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+}
+
+static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
+                            GLuint mask)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL;
+}
+
+static void mgaDDStencilMask(GLcontext *ctx, GLuint mask)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL;
+}
+
+static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
+                          GLenum zpass)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL;
+}
+
+static void mgaDDClearDepth(GLcontext *ctx, GLclampd d)
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   /* KW: should the ~ be there? */
+   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;
+   }
+}
+
+static void mgaUpdateZMode(const GLcontext *ctx)
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   int zmode = 0;
+
+   if (ctx->Depth.Test) {
+      switch(ctx->Depth.Func)  {
+      case GL_NEVER:
+         /* can't do this in h/w, we'll use a s/w fallback */
+        zmode = DC_zmode_nozcmp;
+         break;
+      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:
+        break;
+      }
+
+      if (ctx->Depth.Mask)
+         zmode |= DC_atype_zi;
+      else
+         zmode |= DC_atype_i;
+   }
+   else {
+      zmode |= DC_zmode_nozcmp;
+      zmode |= DC_atype_i;  /* don't write to zbuffer */
+   }
+
+#if defined(ACCEL_ROP)
+   mmesa->setup.dwgctl &= DC_bop_MASK;
+   if (ctx->Color.ColorLogicOpEnabled)
+      zmode |= mgarop_NoBLK[(ctx->Color.LogicOp)&0xf];
+   else
+      zmode |= mgarop_NoBLK[GL_COPY & 0xf];
+#endif
+
+   mmesa->setup.dwgctl &= DC_zmode_MASK & DC_atype_MASK;
+   mmesa->setup.dwgctl |= zmode;
+   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+}
+
+
+static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+}
+
+
+static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+
+   /* BlendEquation sets ColorLogicOpEnabled in an unexpected 
+    * manner.  
+    */
+   FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
+            (ctx->Color.ColorLogicOpEnabled && 
+             ctx->Color.LogicOp != GL_COPY));
+}
+
+static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+}
+
+static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
+                                   GLenum dfactorRGB, GLenum sfactorA,
+                                   GLenum dfactorA )
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+}
+
+
+
+static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
+                             const GLfloat *param)
+{
+   if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+      FLUSH_BATCH( MGA_CONTEXT(ctx) );
+      MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+   }
+}
+
+
+static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+}
+
+
+static void mgaDDDepthFunc(GLcontext *ctx, GLenum func)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
+}
+
+static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
+}
+
+#if defined(ACCEL_ROP)
+static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode )
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
+}
+#else
+static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode )
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   FALLBACK( ctx, MGA_FALLBACK_LOGICOP, 
+            (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) );
+}
+#endif
+
+
+
+static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   if (pname == GL_FOG_COLOR) {
+      GLuint color = MGAPACKCOLOR888((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;
+   }
+}
+
+
+
+
+/* =============================================================
+ * Alpha blending
+ */
+
+
+static void mgaUpdateAlphaMode(GLcontext *ctx)
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
+   int a = 0;
+
+   /* determine source of alpha for blending and testing */
+   if ( !ctx->Texture.Unit[0]._ReallyEnabled ) {
+      a |= AC_alphasel_diffused;
+   }
+   else {
+      /* G400: Regardless of texture env mode, we use the alpha from the
+       * texture unit (AC_alphasel_fromtex) since it will have already
+       * been modulated by the incoming fragment color, if needed.
+       * We don't want (AC_alphasel_modulate) since that'll effectively
+       * do the modulation twice.
+       */
+      if (MGA_IS_G400(mmesa)) {
+         a |= AC_alphasel_fromtex;
+      }
+      else {
+         /* G200 */
+         switch (ctx->Texture.Unit[0].EnvMode) {
+         case GL_DECAL:
+            a |= AC_alphasel_diffused;
+         case GL_REPLACE:
+            a |= AC_alphasel_fromtex;
+            break;
+         case GL_BLEND:
+         case GL_MODULATE:
+            a |= AC_alphasel_modulated;
+            break;
+         default:
+            break;
+         }
+      }
+   }
+
+
+   /* alpha test control.
+    */
+   if (ctx->Color.AlphaEnabled) {
+      GLubyte ref = ctx->Color.AlphaRef;
+      switch (ctx->Color.AlphaFunc) {
+      case GL_NEVER:
+        a |= AC_atmode_alt;
+        ref = 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:
+        break;
+      }
+      a |= MGA_FIELD(AC_atref,ref);
+   }
+
+   /* blending control */
+   if (ctx->Color.BlendEnabled) {
+      switch (ctx->Color.BlendSrcRGB) {
+      case GL_ZERO:
+        a |= AC_src_zero; break;
+      case GL_SRC_ALPHA:
+        a |= AC_src_src_alpha; break;
+      case GL_ONE:
+        a |= AC_src_one; break;
+      case GL_DST_COLOR:
+        a |= AC_src_dst_color; break;
+      case GL_ONE_MINUS_DST_COLOR:
+        a |= AC_src_om_dst_color; break;
+      case GL_ONE_MINUS_SRC_ALPHA:
+        a |= AC_src_om_src_alpha; break;
+      case GL_DST_ALPHA:
+        if (mgaScreen->cpp == 4)
+           a |= AC_src_dst_alpha;
+        else
+           a |= AC_src_one;
+        break;
+      case GL_ONE_MINUS_DST_ALPHA:
+        if (mgaScreen->cpp == 4)
+           a |= AC_src_om_dst_alpha;
+        else
+           a |= AC_src_zero;
+        break;
+      case GL_SRC_ALPHA_SATURATE:
+         if (ctx->Visual.alphaBits > 0)
+            a |= AC_src_src_alpha_sat;
+         else
+            a |= AC_src_zero;
+        break;
+      default:         /* never happens */
+        break;
+      }
+
+      switch (ctx->Color.BlendDstRGB) {
+      case GL_SRC_ALPHA:
+        a |= AC_dst_src_alpha; break;
+      case GL_ONE_MINUS_SRC_ALPHA:
+        a |= AC_dst_om_src_alpha; break;
+      case GL_ZERO:
+        a |= AC_dst_zero; break;
+      case GL_ONE:
+        a |= AC_dst_one; break;
+      case GL_SRC_COLOR:
+        a |= AC_dst_src_color; break;
+      case GL_ONE_MINUS_SRC_COLOR:
+        a |= AC_dst_om_src_color; break;
+      case GL_DST_ALPHA:
+        if (mgaScreen->cpp == 4)
+           a |= AC_dst_dst_alpha;
+        else
+           a |= AC_dst_one;
+        break;
+      case GL_ONE_MINUS_DST_ALPHA:
+        if (mgaScreen->cpp == 4)
+           a |= AC_dst_om_dst_alpha;
+        else
+           a |= AC_dst_zero;
+        break;
+      default:         /* never happens */
+        break;
+      }
+   } else {
+      a |= AC_src_one|AC_dst_zero;
+   }
+
+   mmesa->setup.alphactrl = (AC_amode_alpha_channel |
+                            AC_astipple_disable |
+                            AC_aten_disable |
+                            AC_atmode_noacmp |
+                            a);
+
+   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+}
+
+
+
+/* =============================================================
+ * Hardware clipping
+ */
+
+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 - 1;
+      int y2 = y1 + ctx->Scissor.Height - 1;
+
+      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;
+
+      if (MGA_DEBUG&DEBUG_VERBOSE_2D)
+        fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n",
+                mmesa->scissor_rect.x1,
+                mmesa->scissor_rect.y1,
+                mmesa->scissor_rect.x2,
+                mmesa->scissor_rect.y2);
+
+      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+   }
+}
+
+
+static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y,
+                         GLsizei w, GLsizei h )
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP;
+}
+
+
+static void mgaDDClearColor(GLcontext *ctx, 
+                           const GLfloat color[4] )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp,
+                                    color[0], color[1], 
+                                    color[2], color[3]);
+}
+
+
+/* =============================================================
+ * Culling
+ */
+
+#define _CULL_DISABLE 0
+#define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16))
+#define _CULL_POSITIVE (1<<11)
+
+
+void mgaUpdateCull( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLuint mode = _CULL_DISABLE;
+
+   if (ctx->Polygon.CullFlag && 
+       mmesa->raster_primitive == GL_TRIANGLES &&       
+       ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) 
+   {
+      mode = _CULL_NEGATIVE;
+      if (ctx->Polygon.CullFaceMode == GL_FRONT)
+        mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
+      if (ctx->Polygon.FrontFace != GL_CCW)
+        mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
+      if ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) &&
+          (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT))
+        mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */
+   }
+
+   mmesa->setup.wflag = mode;
+   mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+}
+
+
+static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum mode)
+{
+   FLUSH_BATCH( MGA_CONTEXT(ctx) );
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL;
+}
+
+
+
+
+/* =============================================================
+ * Color 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 stipple
+ *
+ * The mga supports a subset of possible 4x4 stipples natively, GL
+ * wants 32x32.  Fortunately stipple is usually a repeating pattern.
+ *
+ * Note: the fully opaque pattern (0xffff) has been disabled in order
+ * to work around a conformance issue.
+ */
+static int mgaStipples[16] = {
+   0xffff1,  /* See above note */
+   0xa5a5,
+   0x5a5a,
+   0xa0a0,
+   0x5050,
+   0x0a0a,
+   0x0505,
+   0x8020,
+   0x0401,
+   0x1040,
+   0x0208,
+   0x0802,
+   0x4010,
+   0x0104,
+   0x2080,
+   0x0000
+};
+
+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;
+   }
+}
+
+/* =============================================================
+ */
+
+static void mgaDDPrintDirty( const char *msg, GLuint state )
+{
+   fprintf(stderr, "%s (0x%x): %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 )
+{
+   MGASAREAPrivPtr sarea = mmesa->sarea;
+
+   if (MGA_DEBUG & DEBUG_VERBOSE_MSG)
+      mgaDDPrintDirty( "mgaEmitHwStateLocked", mmesa->dirty );
+
+   if ((mmesa->dirty & MGA_UPLOAD_TEX0IMAGE) && mmesa->CurrentTexObj[0])
+      mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[0]);
+
+   if ((mmesa->dirty & MGA_UPLOAD_TEX1IMAGE) && mmesa->CurrentTexObj[1])
+      mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[1]);
+
+   if (mmesa->dirty & MGA_UPLOAD_CONTEXT) {
+      memcpy( &sarea->ContextState, &mmesa->setup, sizeof(mmesa->setup));
+   }
+
+   if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) {
+      memcpy(&sarea->TexState[0],
+            &mmesa->CurrentTexObj[0]->setup,
+            sizeof(sarea->TexState[0]));
+   }
+
+   if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) {
+      memcpy(&sarea->TexState[1],
+            &mmesa->CurrentTexObj[1]->setup,
+            sizeof(sarea->TexState[1]));
+   }
+
+   if (sarea->TexState[0].texctl2 !=
+       sarea->TexState[1].texctl2) {
+      memcpy(&sarea->TexState[1],
+            &sarea->TexState[0],
+            sizeof(sarea->TexState[0]));
+      mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0;
+   }
+
+   if (mmesa->dirty & MGA_UPLOAD_PIPE) {
+/*        mmesa->sarea->wacceptseq = mmesa->hw_primitive; */
+      mmesa->sarea->WarpPipe = mmesa->vertex_format;
+      mmesa->sarea->vertsize = mmesa->vertex_size;
+   }
+
+   mmesa->sarea->dirty |= mmesa->dirty;
+
+   mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE);
+
+   /* 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 (mmesa->glCtx->Texture.Unit[0]._ReallyEnabled == 0 ||
+       !mmesa->glCtx->Light.Enabled ||
+       mmesa->glCtx->Light.Model.ColorControl == GL_SINGLE_COLOR) {
+      sarea->TexState[0].texctl2 &= ~TMC_specen_enable;
+      sarea->TexState[1].texctl2 &= ~TMC_specen_enable;
+   }
+}
+
+/* Fallback to swrast for select and feedback.
+ */
+static void mgaRenderMode( GLcontext *ctx, GLenum mode )
+{
+   FALLBACK( ctx, MGA_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
+}
+
+
+/* =============================================================
+ */
+
+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 );
+}
+
+/* =============================================================
+ */
+
+static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
+   switch(cap) {
+   case GL_ALPHA_TEST:
+      FLUSH_BATCH( mmesa );
+      mmesa->new_state |= MGA_NEW_ALPHA;
+      break;
+   case GL_BLEND:
+      FLUSH_BATCH( mmesa );
+      mmesa->new_state |= MGA_NEW_ALPHA;
+
+      /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
+       */
+      FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
+               (ctx->Color.ColorLogicOpEnabled && 
+                ctx->Color.LogicOp != GL_COPY));
+      break;
+   case GL_DEPTH_TEST:
+      FLUSH_BATCH( mmesa );
+      mmesa->new_state |= MGA_NEW_DEPTH;
+      FALLBACK (ctx, MGA_FALLBACK_DEPTH,
+               ctx->Depth.Func == GL_NEVER && ctx->Depth.Test);
+      break;
+   case GL_SCISSOR_TEST:
+      FLUSH_BATCH( mmesa );
+      mmesa->scissor = state;
+      mmesa->new_state |= MGA_NEW_CLIP;
+      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:
+      FLUSH_BATCH( mmesa );
+      mmesa->new_state |= MGA_NEW_CULL;
+      break;
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_3D:
+      FLUSH_BATCH( mmesa );
+      mmesa->new_state |= (MGA_NEW_TEXTURE|MGA_NEW_ALPHA);
+      break;
+   case GL_POLYGON_STIPPLE:
+      if (mmesa->haveHwStipple && mmesa->raster_primitive == GL_TRIANGLES) {
+        FLUSH_BATCH(mmesa);
+        mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+        mmesa->setup.dwgctl &= ~(0xf<<20);
+        if (state)
+           mmesa->setup.dwgctl |= mmesa->poly_stipple;
+      }
+      break;
+   case GL_COLOR_LOGIC_OP:
+      FLUSH_BATCH( mmesa );
+#if !defined(ACCEL_ROP)
+      FALLBACK( ctx, MGA_FALLBACK_LOGICOP, 
+               (state && ctx->Color.LogicOp != GL_COPY));
+#else
+      mmesa->new_state |= MGA_NEW_DEPTH;
+#endif
+      break;
+   case GL_STENCIL_TEST:
+      FLUSH_BATCH( mmesa );
+      if (mmesa->hw_stencil)
+        mmesa->new_state |= MGA_NEW_STENCIL;
+      else
+        FALLBACK( ctx, MGA_FALLBACK_STENCIL, state );
+   default:
+      break;
+   }
+}
+
+
+/* =============================================================
+ */
+
+
+
+/* =============================================================
+ */
+
+static void mgaDDPrintState( const char *msg, GLuint state )
+{
+   fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n",
+          msg,
+          state,
+          (state & MGA_NEW_DEPTH)   ? "depth, " : "",
+          (state & MGA_NEW_ALPHA)   ? "alpha, " : "",
+          (state & MGA_NEW_CLIP)    ? "clip, " : "",
+          (state & MGA_NEW_CULL)    ? "cull, " : "",
+          (state & MGA_NEW_TEXTURE) ? "texture, " : "",
+          (state & MGA_NEW_CONTEXT) ? "context, " : "");
+}
+
+void mgaDDUpdateHwState( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   int new_state = mmesa->new_state;
+
+   if (new_state)
+   {
+      FLUSH_BATCH( mmesa );
+
+      mmesa->new_state = 0;
+
+      if (MESA_VERBOSE&VERBOSE_DRIVER)
+        mgaDDPrintState("UpdateHwState", new_state);
+
+      if (new_state & MGA_NEW_DEPTH)
+        mgaUpdateZMode(ctx);
+
+      if (new_state & MGA_NEW_ALPHA)
+        mgaUpdateAlphaMode(ctx);
+
+      if (new_state & MGA_NEW_CLIP)
+        mgaUpdateClipping(ctx);
+
+      if (new_state & MGA_NEW_STENCIL)
+        mgaUpdateStencil(ctx);
+
+      if (new_state & (MGA_NEW_WARP|MGA_NEW_CULL))
+        mgaUpdateCull(ctx);
+
+      if (new_state & (MGA_NEW_WARP|MGA_NEW_TEXTURE))
+        mgaUpdateTextureState(ctx);
+   }
+}
+
+
+static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state )
+{
+   _swrast_InvalidateState( ctx, new_state );
+   _swsetup_InvalidateState( ctx, new_state );
+   _ac_InvalidateState( ctx, new_state );
+   _tnl_InvalidateState( ctx, new_state );
+   MGA_CONTEXT(ctx)->new_gl_state |= new_state;
+}
+
+
+
+void mgaInitState( mgaContextPtr mmesa )
+{
+   mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
+   GLcontext *ctx = mmesa->glCtx;
+
+   if (ctx->Color._DrawDestMask == BACK_LEFT_BIT) {
+      mmesa->draw_buffer = MGA_BACK;
+      mmesa->read_buffer = MGA_BACK;
+      mmesa->drawOffset = mmesa->mgaScreen->backOffset;
+      mmesa->readOffset = mmesa->mgaScreen->backOffset;
+      mmesa->setup.dstorg = mgaScreen->backOffset;
+   } else {
+      mmesa->draw_buffer = MGA_FRONT;
+      mmesa->read_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);
+
+   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_pwidth_32;
+      break;
+   }
+
+   mmesa->setup.dwgctl = (DC_opcod_trap |
+                         DC_atype_i |
+                         DC_linear_xy |
+                         DC_zmode_nozcmp |
+                         DC_solid_disable |
+                         DC_arzero_disable |
+                         DC_sgnzero_disable |
+                         DC_shftzero_enable |
+                         (0xC << DC_bop_SHIFT) |
+                         (0x0 << DC_trans_SHIFT) |
+                         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.fogcolor =
+      MGAPACKCOLOR888((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->new_state = ~0;
+}
+
+
+void mgaDDInitStateFuncs( GLcontext *ctx )
+{
+   ctx->Driver.UpdateState = mgaDDInvalidateState;
+   ctx->Driver.Enable = mgaDDEnable;
+   ctx->Driver.LightModelfv = mgaDDLightModelfv;
+   ctx->Driver.AlphaFunc = mgaDDAlphaFunc;
+   ctx->Driver.BlendEquation = mgaDDBlendEquation;
+   ctx->Driver.BlendFunc = mgaDDBlendFunc;
+   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;
+
+   ctx->Driver.DrawBuffer = mgaDDSetDrawBuffer;
+   ctx->Driver.ReadBuffer = mgaDDSetReadBuffer;
+   ctx->Driver.ClearColor = mgaDDClearColor;
+   ctx->Driver.ClearDepth = mgaDDClearDepth;
+   ctx->Driver.LogicOpcode = mgaDDLogicOp;
+
+   ctx->Driver.PolygonStipple = mgaDDPolygonStipple;
+
+   ctx->Driver.StencilFunc = mgaDDStencilFunc;
+   ctx->Driver.StencilMask = mgaDDStencilMask;
+   ctx->Driver.StencilOp = mgaDDStencilOp;
+
+   ctx->Driver.DepthRange = mgaDepthRange;
+   ctx->Driver.Viewport = mgaViewport;
+   ctx->Driver.RenderMode = mgaRenderMode;
+
+   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;
+}
diff --git a/src/mesa/drivers/dri/mga/mgastate.h b/src/mesa/drivers/dri/mga/mgastate.h
new file mode 100644 (file)
index 0000000..a9f1039
--- /dev/null
@@ -0,0 +1,42 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.h,v 1.5 2002/10/30 12:51:36 alanh Exp $ */
+/*
+ * 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>
+ */
+
+#ifndef _MGA_STATE_H
+#define _MGA_STATE_H
+
+
+extern void mgaInitState( mgaContextPtr mmesa );
+extern void mgaDDInitStateFuncs(GLcontext *ctx);
+extern void mgaDDUpdateHwState( GLcontext *ctx );
+extern void mgaUpdateClipping(const GLcontext *ctx);
+extern void mgaUpdateCull( GLcontext *ctx );
+extern void mgaCalcViewport( GLcontext *ctx );
+
+
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgatex.c b/src/mesa/drivers/dri/mga/mgatex.c
new file mode 100644 (file)
index 0000000..b4ee787
--- /dev/null
@@ -0,0 +1,985 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.14 2002/10/30 12:51:36 alanh Exp $ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/gl.h>
+
+#include "mm.h"
+#include "mgacontext.h"
+#include "mgatex.h"
+#include "mgaregs.h"
+#include "mgatris.h"
+#include "mgaioctl.h"
+
+#include "enums.h"
+#include "simple_list.h"
+/*#include "mem.h"*/
+#include "macros.h"
+#include "texformat.h"
+#include "texstore.h"
+#include "teximage.h"
+
+#include "swrast/swrast.h"
+
+#define TEX_0 1
+#define TEX_1 2
+
+/*
+ * mgaDestroyTexObj
+ * Free all memory associated with a texture and NULL any pointers
+ * to it.
+ */
+void
+mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+   if ( !t ) return;
+
+   /* free the texture memory */
+   if (t->MemBlock) {
+      mmFreeMem( t->MemBlock );
+      t->MemBlock = 0;
+
+      if (mmesa && t->age > mmesa->dirtyAge)
+        mmesa->dirtyAge = t->age;
+   }
+
+   /* free mesa's link */
+   if (t->tObj)
+      t->tObj->DriverData = NULL;
+
+   /* see if it was the driver's current object */
+   if (mmesa) {
+      if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0;
+      if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0;
+   }
+       
+   remove_from_list(t);
+   free( t );
+}
+
+
+/*
+ * mgaSetTexWrappings
+ */
+static void mgaSetTexWrapping( mgaTextureObjectPtr t,
+                              GLenum sWrap,
+                              GLenum tWrap )
+{
+   GLuint val = 0;
+
+   if (sWrap != GL_REPEAT)
+      val |= TMC_clampu_enable;
+
+   if (tWrap != GL_REPEAT)
+      val |= TMC_clampv_enable;
+
+   t->setup.texctl &= ~(TMC_clampu_enable|TMC_clampv_enable);
+   t->setup.texctl |= val;
+}
+
+
+/*
+ * mgaSetTexFilter
+ */
+static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf)
+{
+   GLuint val = 0;
+
+   switch (minf) {
+   case GL_NEAREST: val = TF_minfilter_nrst; break;
+   case GL_LINEAR: val = TF_minfilter_bilin; break;
+   case GL_NEAREST_MIPMAP_NEAREST: val = TF_minfilter_mm1s; break;
+   case GL_LINEAR_MIPMAP_NEAREST: val = TF_minfilter_mm4s; break;
+   case GL_NEAREST_MIPMAP_LINEAR: val = TF_minfilter_mm2s; break;
+   case GL_LINEAR_MIPMAP_LINEAR: val = TF_minfilter_mm8s; break;
+   default: val = TF_minfilter_nrst; break;
+   }
+
+   switch (magf) {
+   case GL_NEAREST: val |= TF_magfilter_nrst; break;
+   case GL_LINEAR: val |= TF_magfilter_bilin; break;
+   default: val |= TF_magfilter_nrst; break;
+   }
+
+   /* See OpenGL 1.2 specification */
+   if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST ||
+                            minf == GL_NEAREST_MIPMAP_LINEAR)) {
+      val |= (0x20 << TF_fthres_SHIFT); /* c = 0.5 */
+   } else {
+      val |= (0x10 << TF_fthres_SHIFT); /* c = 0 */
+   }
+
+
+   t->setup.texfilter &= (TF_minfilter_MASK |
+                         TF_magfilter_MASK |
+                         TF_fthres_MASK);
+   t->setup.texfilter |= val;
+}
+
+/*
+ * mgaSetTexBorderColor
+ */
+static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4])
+{
+   t->setup.texbordercol = MGAPACKCOLOR8888(color[0],color[1],
+                                           color[2],color[3]);
+}
+
+
+static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
+                                struct gl_texture_image *texImage,
+                                GLenum format, GLenum type )
+{
+   const GLboolean do32bpt = mmesa->default32BitTextures;
+   const struct gl_texture_format *texFormat;
+   GLint ret;
+
+   if ( 0 )
+      fprintf( stderr, "internal=%s format=%s type=%s\n",
+              texImage->IntFormat == 3 ? "GL_RGB (3)" :
+              texImage->IntFormat == 4 ? "GL_RGBA (4)" :
+              _mesa_lookup_enum_by_nr( texImage->IntFormat ),
+              _mesa_lookup_enum_by_nr( format ),
+              _mesa_lookup_enum_by_nr( type ) );
+
+#define SET_FORMAT( r, gl )                                            \
+   do {                                                                        \
+      ret = (r);                                                       \
+      texFormat = &(gl);                                               \
+   } while (0)
+
+#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 )                       \
+   do {                                                                        \
+      if ( do32bpt ) {                                                 \
+        ret = (r32);                                                   \
+        texFormat = &(gl32);                                           \
+      } else {                                                         \
+        ret = (r16);                                                   \
+        texFormat = &(gl16);                                           \
+      }                                                                        \
+   } while (0)
+
+   switch ( texImage->IntFormat ) {
+      /* GH: Bias towards GL_RGB, GL_RGBA texture formats.  This has
+       * got to be better than sticking them way down the end of this
+       * huge list.
+       */
+   case 4:
+   case GL_RGBA:
+   case GL_COMPRESSED_RGBA:
+      if ( format == GL_BGRA ) {
+        if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
+           SET_FORMAT( TMC_tformat_tw32, _mesa_texformat_argb8888 );
+           break;
+        } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
+           SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
+           break;
+        } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
+           SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
+           break;
+        }
+      }
+      SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
+                       TMC_tformat_tw12, _mesa_texformat_argb4444 );
+      break;
+
+   case 3:
+   case GL_RGB:
+   case GL_COMPRESSED_RGB:
+      if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
+        SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
+        break;
+      }
+      SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
+                       TMC_tformat_tw16, _mesa_texformat_rgb565 );
+      break;
+
+      /* GH: Okay, keep checking as normal.  Still test for GL_RGB,
+       * GL_RGBA formats first.
+       */
+   case GL_RGBA8:
+   case GL_RGB10_A2:
+   case GL_RGBA12:
+   case GL_RGBA16:
+      SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
+                       TMC_tformat_tw12, _mesa_texformat_argb4444 );
+      break;
+
+   case GL_RGBA4:
+   case GL_RGBA2:
+      SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
+      break;
+
+   case GL_RGB5_A1:
+      SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
+      break;
+
+   case GL_RGB8:
+   case GL_RGB10:
+   case GL_RGB12:
+   case GL_RGB16:
+      SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
+                       TMC_tformat_tw16, _mesa_texformat_rgb565 );
+      break;
+
+   case GL_RGB5:
+   case GL_RGB4:
+   case GL_R3_G3_B2:
+      SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
+      break;
+
+   case GL_ALPHA:
+   case GL_ALPHA4:
+   case GL_ALPHA8:
+   case GL_ALPHA12:
+   case GL_ALPHA16:
+   case GL_COMPRESSED_ALPHA:
+      /* FIXME: This will report incorrect component sizes... */
+      SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
+      break;
+
+   case 1:
+   case GL_LUMINANCE:
+   case GL_LUMINANCE4:
+   case GL_LUMINANCE8:
+   case GL_LUMINANCE12:
+   case GL_LUMINANCE16:
+   case GL_COMPRESSED_LUMINANCE:
+      /* FIXME: This will report incorrect component sizes... */
+      SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
+      break;
+
+   case 2:
+   case GL_LUMINANCE_ALPHA:
+   case GL_LUMINANCE4_ALPHA4:
+   case GL_LUMINANCE6_ALPHA2:
+   case GL_LUMINANCE8_ALPHA8:
+   case GL_LUMINANCE12_ALPHA4:
+   case GL_LUMINANCE12_ALPHA12:
+   case GL_LUMINANCE16_ALPHA16:
+   case GL_COMPRESSED_LUMINANCE_ALPHA:
+      /* FIXME: This will report incorrect component sizes... */
+      SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
+      break;
+
+   case GL_INTENSITY:
+   case GL_INTENSITY4:
+   case GL_INTENSITY8:
+   case GL_INTENSITY12:
+   case GL_INTENSITY16:
+   case GL_COMPRESSED_INTENSITY:
+      /* FIXME: This will report incorrect component sizes... */
+      SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
+      break;
+
+   case GL_COLOR_INDEX:
+   case GL_COLOR_INDEX1_EXT:
+   case GL_COLOR_INDEX2_EXT:
+   case GL_COLOR_INDEX4_EXT:
+   case GL_COLOR_INDEX8_EXT:
+   case GL_COLOR_INDEX12_EXT:
+   case GL_COLOR_INDEX16_EXT:
+      SET_FORMAT( TMC_tformat_tw8, _mesa_texformat_ci8 );
+      break;
+
+   default:
+      fprintf( stderr, "bad texture format in mgaChooseTexFormat() %d",
+              texImage->IntFormat );
+      return -1;
+   }
+
+   texImage->TexFormat = texFormat;
+
+   return ret;
+}
+
+
+/*
+ * mgaCreateTexObj
+ * Allocate space for and load the mesa images into the texture memory block.
+ * This will happen before drawing with a new texture, or drawing with a
+ * texture after it was swapped out or teximaged again.
+ */
+static void mgaCreateTexObj(mgaContextPtr mmesa,
+                           struct gl_texture_object *tObj)
+{
+   const GLint baseLevel = tObj->BaseLevel;
+   struct gl_texture_image *image = tObj->Image[baseLevel];
+   mgaTextureObjectPtr t;
+   int i, ofs;
+   int LastLevel;
+   int s, s2;
+   int tformat;
+
+   if (!image) return;
+
+   tObj->DriverData = t = calloc( 1, sizeof( *t ) );
+   if (!t) {
+      fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" );
+      return;
+   }
+
+   /* FIXME: Use the real DD interface...
+    */
+   tformat = mgaChooseTexFormat( mmesa, image, image->Format,
+                                GL_UNSIGNED_BYTE );
+   t->texelBytes = image->TexFormat->TexelBytes;
+
+   /* We are going to upload all levels that are present, even if
+    * later levels wouldn't be used by the current filtering mode.  This
+    * allows the filtering mode to change without forcing another upload
+    * of the images.
+    */
+   LastLevel = MGA_TEX_MAXLEVELS-1;
+
+   ofs = 0;
+   for ( i = 0 ; i <= LastLevel ; i++ ) {
+      if ( !tObj->Image[i] ) {
+        LastLevel = i - 1;
+        break;
+      }
+
+      t->offsets[i] = ofs;
+      t->dirty_images |= (1<<i);
+
+      ofs += ((MAX2( tObj->Image[i]->Width, 8 ) *
+              MAX2( tObj->Image[i]->Height, 8 ) *
+              t->texelBytes) + 31) & ~31;
+   }
+   t->totalSize = ofs;
+   t->lastLevel = LastLevel;
+   t->tObj = tObj;
+   t->ctx = mmesa;
+   t->age = 0;
+   t->bound = 0;
+   t->MemBlock = 0;
+
+   insert_at_tail(&(mmesa->SwappedOut), t);
+
+
+   /* setup hardware register values */
+   t->setup.texctl = TMC_takey_1 | TMC_tamask_0 | tformat;
+
+   if (image->WidthLog2 >= 3)
+      t->setup.texctl |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT);
+   else
+      t->setup.texctl |= (TMC_tpitchlin_enable |
+                         (image->Width << TMC_tpitchext_SHIFT));
+
+
+   t->setup.texctl2 = TMC_ckstransdis_enable;
+
+   if ( mmesa->glCtx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR )
+      t->setup.texctl2 |= TMC_specen_enable;
+
+
+   t->setup.texfilter = (TF_minfilter_nrst |
+                        TF_magfilter_nrst |
+                        TF_filteralpha_enable |
+                        (0x10 << TF_fthres_SHIFT) |
+                        (LastLevel << TF_mapnb_SHIFT));
+
+   /* warp texture registers */
+   ofs = MGA_IS_G200(mmesa) ? 28 : 11;
+   s = image->Width;
+   s2 = image->WidthLog2;
+   t->setup.texwidth = (MGA_FIELD(TW_twmask, s - 1) |
+                       MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) |
+                       MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 ));
+
+
+   s = image->Height;
+   s2 = image->HeightLog2;
+   t->setup.texheight = (MGA_FIELD(TH_thmask, s - 1) |
+                        MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) |
+                        MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 ));
+
+
+   /* set all the register values for filtering, border, etc */
+   mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
+   mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
+   mgaSetTexBorderColor( t, tObj->_BorderChan );
+}
+
+
+
+
+static void mgaUpdateTextureEnvG200( GLcontext *ctx )
+{
+   struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
+   mgaTextureObjectPtr t;
+
+   if (!tObj || !tObj->DriverData)
+      return;
+
+   t = (mgaTextureObjectPtr)tObj->DriverData;
+
+   t->setup.texctl2 &= ~TMC_decalblend_enable;
+
+   switch (ctx->Texture.Unit[0].EnvMode) {
+   case GL_REPLACE:
+      t->setup.texctl &= ~TMC_tmodulate_enable;
+      break;
+   case GL_MODULATE:
+      t->setup.texctl |= TMC_tmodulate_enable;
+      break;
+   case GL_DECAL:
+      t->setup.texctl &= ~TMC_tmodulate_enable;
+      t->setup.texctl2 |= TMC_decalblend_enable;
+      break;
+   case GL_BLEND:
+      FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
+      break;
+   default:
+      break;
+   }
+}
+
+static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
+   GLuint source = mmesa->tmu_source[unit];
+   struct gl_texture_object *tObj = ctx->Texture.Unit[source]._Current;
+   GLenum format;
+
+   if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj ) 
+      return;
+
+   format = tObj->Image[tObj->BaseLevel]->Format;
+
+   switch (ctx->Texture.Unit[source].EnvMode) {
+   case GL_REPLACE:
+      if (format == GL_RGB || format == GL_LUMINANCE) {
+        *reg = (TD0_color_sel_arg1 |
+                 TD0_alpha_arg2_diffuse |
+                TD0_alpha_sel_arg2 );
+      }
+      else if (format == GL_ALPHA) {
+         *reg = (TD0_color_sel_arg2 |
+                 TD0_color_arg2_diffuse |
+                 TD0_alpha_sel_arg1 );
+      }
+      else {
+         *reg = (TD0_color_sel_arg1 |
+                 TD0_alpha_sel_arg1 );
+      }
+      break;
+
+   case GL_MODULATE:
+      if (unit == 0) {
+        *reg = ( TD0_color_arg2_diffuse |
+                 TD0_color_sel_mul |
+                 TD0_alpha_arg2_diffuse |
+                 TD0_alpha_sel_mul);
+      }
+      else {
+        *reg = ( TD0_color_arg2_prevstage |
+                 TD0_color_alpha_prevstage |
+                 TD0_color_sel_mul |
+                 TD0_alpha_arg2_prevstage |
+                 TD0_alpha_sel_mul);
+      }
+      break;
+   case GL_DECAL:
+      if (format == GL_RGB) {
+         if (unit == 0) {
+            *reg = (TD0_color_sel_arg1 |
+                    TD0_alpha_arg2_diffuse |
+                    TD0_alpha_sel_arg2 );
+         }
+         else {
+            *reg = (TD0_color_sel_arg1 |
+                    TD0_alpha_arg2_prevstage |
+                    TD0_alpha_sel_arg2 );
+         }
+      }
+      else if ( format == GL_RGBA ) {
+#if 0
+         if (unit == 0) {
+            /* this doesn't work */
+            *reg = (TD0_color_arg2_diffuse |
+                    TD0_color_alpha_currtex |
+                    TD0_color_alpha2inv_enable |
+                    TD0_color_arg2mul_alpha2 |
+                    TD0_color_arg1mul_alpha1 |
+                    TD0_color_blend_enable |
+                    TD0_color_arg1add_mulout |
+                    TD0_color_arg2add_mulout |
+                    TD0_color_add_add |
+                    TD0_color_sel_mul |
+                    TD0_alpha_arg2_diffuse |
+                    TD0_alpha_sel_arg2 );
+         }
+         else {
+            *reg = (TD0_color_arg2_prevstage |
+                    TD0_color_alpha_currtex |
+                    TD0_color_alpha2inv_enable |
+                    TD0_color_arg2mul_alpha2 |
+                    TD0_color_arg1mul_alpha1 |
+                    TD0_color_add_add |
+                    TD0_color_sel_add |
+                    TD0_alpha_arg2_prevstage |
+                    TD0_alpha_sel_arg2 );
+         }
+#else
+         /* s/w fallback, pretty sure we can't do in h/w */
+        FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
+        if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
+           fprintf( stderr, "FALLBACK: GL_DECAL RGBA texture, unit=%d\n",
+                    unit );
+#endif
+      }
+      else {
+        if (unit == 0) {
+           *reg = ( TD0_color_arg2_diffuse |
+                    TD0_color_sel_arg2 |
+                    TD0_alpha_arg2_diffuse |
+                    TD0_alpha_sel_arg2);
+        }
+        else {
+           *reg = ( TD0_color_arg2_prevstage |
+                    TD0_color_sel_arg2 |
+                    TD0_alpha_arg2_prevstage |
+                    TD0_alpha_sel_arg2);
+        }
+      }
+      break;
+
+   case GL_ADD:
+      if (unit == 0) {
+         if (format == GL_INTENSITY)
+            *reg = ( TD0_color_arg2_diffuse |
+                     TD0_color_add_add |
+                     TD0_color_sel_add |
+                     TD0_alpha_arg2_diffuse |
+                     TD0_alpha_add_enable |
+                     TD0_alpha_sel_add);
+         else if (format == GL_ALPHA)
+            *reg = ( TD0_color_arg2_diffuse |
+                     TD0_color_sel_mul |
+                     TD0_alpha_arg2_diffuse |
+                     TD0_alpha_sel_mul);
+         else
+            *reg = ( TD0_color_arg2_diffuse |
+                     TD0_color_add_add |
+                     TD0_color_sel_add |
+                     TD0_alpha_arg2_diffuse |
+                     TD0_alpha_sel_mul);
+      }
+      else {
+         if (format == GL_INTENSITY) {
+            *reg = ( TD0_color_arg2_prevstage |
+                     TD0_color_add_add |
+                     TD0_color_sel_add |
+                     TD0_alpha_arg2_prevstage |
+                     TD0_alpha_add_enable |
+                     TD0_alpha_sel_add);
+         }
+         else if (format == GL_ALPHA) {
+            *reg = ( TD0_color_arg2_prevstage |
+                     TD0_color_sel_mul |
+                     TD0_alpha_arg2_prevstage |
+                     TD0_alpha_sel_mul);
+         }
+         else {
+            *reg = ( TD0_color_arg2_prevstage |
+                     TD0_color_alpha_prevstage |
+                     TD0_color_add_add |
+                     TD0_color_sel_add |
+                     TD0_alpha_arg2_prevstage |
+                     TD0_alpha_sel_mul);
+         }
+      }
+      break;
+
+   case GL_BLEND:
+      if (format == GL_ALPHA) {
+        *reg = ( TD0_color_arg2_diffuse |
+                 TD0_color_sel_mul |
+                 TD0_alpha_arg2_diffuse |
+                 TD0_alpha_sel_mul);
+      }
+      else {
+        FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
+        if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
+           fprintf( stderr, "FALLBACK: GL_BLEND envcolor=0x%08x\n",
+                    mmesa->envcolor );
+
+         /* Do singletexture GL_BLEND with 'all ones' env-color
+          * by using both texture units.  Multitexture gl_blend
+          * is a fallback.
+          */
+         if (unit == 0) {
+            /* Part 1: R1 = Rf ( 1 - Rt )
+             *         A1 = Af At
+             */
+            *reg = ( TD0_color_arg2_diffuse |
+                     TD0_color_arg1_inv_enable |
+                     TD0_color_sel_mul |
+                     TD0_alpha_arg2_diffuse |
+                     TD0_alpha_sel_arg1);
+         } else {
+            /* Part 2: R2 = R1 + Rt
+             *         A2 = A1
+             */
+            *reg = ( TD0_color_arg2_prevstage |
+                     TD0_color_add_add |
+                     TD0_color_sel_add |
+                     TD0_alpha_arg2_prevstage |
+                     TD0_alpha_sel_arg2);
+         }
+      }
+      break;
+   default:
+      break;
+   }
+}
+
+
+
+static void mgaUpdateTextureObject( GLcontext *ctx, int hw_unit )
+{
+   mgaTextureObjectPtr t;
+   struct gl_texture_object    *tObj;
+   GLuint enabled;
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   GLuint gl_unit = mmesa->tmu_source[hw_unit];
+
+
+   enabled = ctx->Texture.Unit[gl_unit]._ReallyEnabled;
+   tObj = ctx->Texture.Unit[gl_unit]._Current;
+
+   if (enabled != TEXTURE_2D_BIT) {
+      if (enabled)
+        FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
+      return;
+   }
+
+   if (tObj->Image[tObj->BaseLevel]->Border > 0) {
+      FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
+      if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
+        fprintf( stderr, "FALLBACK: texture border\n" );
+      return;
+   }
+
+   if ( !tObj->DriverData ) {
+      mgaCreateTexObj( mmesa, tObj );
+      if ( !tObj->DriverData ) {
+        FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
+        return;                
+      }
+   }
+
+   t = (mgaTextureObjectPtr)tObj->DriverData;
+
+   if (t->dirty_images)
+      mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << hw_unit);
+
+   mmesa->CurrentTexObj[hw_unit] = t;
+   t->bound |= hw_unit+1;
+
+/*     if (t->MemBlock) */
+/*        mgaUpdateTexLRU( mmesa, t ); */
+
+   t->setup.texctl2 &= ~TMC_dualtex_enable;
+   if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) &&
+       (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) 
+      t->setup.texctl2 |= TMC_dualtex_enable;
+
+   t->setup.texctl2 &= ~TMC_specen_enable;
+   if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+      t->setup.texctl2 |= TMC_specen_enable;
+}
+
+
+
+
+
+
+/* The G400 is now programmed quite differently wrt texture environment.
+ */
+void mgaUpdateTextureState( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_FALSE );
+
+   if (mmesa->CurrentTexObj[0]) {
+      mmesa->CurrentTexObj[0]->bound = 0;
+      mmesa->CurrentTexObj[0] = 0;
+   }
+
+   if (mmesa->CurrentTexObj[1]) {
+      mmesa->CurrentTexObj[1]->bound = 0;
+      mmesa->CurrentTexObj[1] = 0;
+   }
+
+   if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
+      mmesa->tmu_source[0] = 1;
+   } else {
+      mmesa->tmu_source[0] = 0;
+   }
+
+   if (MGA_IS_G400(mmesa)) {
+      mgaUpdateTextureObject( ctx, 0 );
+      mgaUpdateTextureEnvG400( ctx, 0 );
+
+      mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
+      
+      if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) &&
+          (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) {
+        mgaUpdateTextureObject( ctx, 1 );      
+        mgaUpdateTextureEnvG400( ctx, 1 );
+        mmesa->dirty |= MGA_UPLOAD_TEX1;
+      }
+   } else {
+      mgaUpdateTextureObject( ctx, 0 );
+      mgaUpdateTextureEnvG200( ctx );
+   }
+
+   mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0;
+
+   mmesa->setup.dwgctl &= DC_opcod_MASK;
+   mmesa->setup.dwgctl |= (ctx->Texture.Unit[0]._ReallyEnabled
+                          ? DC_opcod_texture_trap
+                          : DC_opcod_trap);
+}
+
+
+
+
+static void mgaDDTexEnv( GLcontext *ctx, GLenum target,
+                        GLenum pname, const GLfloat *param )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+
+   if (pname == GL_TEXTURE_ENV_MODE) {
+      /* force the texture state to be updated */
+      FLUSH_BATCH( MGA_CONTEXT(ctx) );
+      MGA_CONTEXT(ctx)->new_state |= (MGA_NEW_TEXTURE |
+                                     MGA_NEW_ALPHA);
+   }
+   else if (pname == GL_TEXTURE_ENV_COLOR)
+   {
+      struct gl_texture_unit *texUnit =
+        &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+      GLfloat *fc = texUnit->EnvColor;
+      GLubyte c[4];
+      GLuint col;
+
+      COPY_4V(c, fc);
+      col = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] );
+      mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]);
+
+      if (mmesa->setup.fcol != col) {
+        FLUSH_BATCH(mmesa);
+        mmesa->setup.fcol = col;
+        mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+
+        mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR;
+
+        /* Actually just require all four components to be
+         * equal.  This permits a single-pass GL_BLEND.
+         *
+         * More complex multitexture/multipass fallbacks
+         * for blend can be done later.
+         */
+        if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff)
+           mmesa->blend_flags |= MGA_BLEND_ENV_COLOR;
+      }
+   }
+}
+
+
+static void mgaTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+                           GLint internalFormat,
+                           GLint width, GLint height, GLint border,
+                           GLenum format, GLenum type, const GLvoid *pixels,
+                           const struct gl_pixelstore_attrib *packing,
+                           struct gl_texture_object *texObj,
+                           struct gl_texture_image *texImage )
+{
+   mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData;
+   if (t) {
+      mgaDestroyTexObj( MGA_CONTEXT(ctx), t );
+      texObj->DriverData = 0;
+   }
+   _mesa_store_teximage2d( ctx, target, level, internalFormat,
+                          width, height, border, format, type,
+                          pixels, packing, texObj, texImage );
+}
+
+static void mgaTexSubImage2D( GLcontext *ctx, 
+                              GLenum target,
+                              GLint level,     
+                              GLint xoffset, GLint yoffset,
+                              GLsizei width, GLsizei height,
+                              GLenum format, GLenum type,
+                              const GLvoid *pixels,
+                              const struct gl_pixelstore_attrib *packing,
+                              struct gl_texture_object *texObj,
+                              struct gl_texture_image *texImage )
+{
+   mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData;
+   if (t) {
+      mgaDestroyTexObj( MGA_CONTEXT(ctx), t );
+      texObj->DriverData = 0;
+   }
+   _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, 
+                            height, format, type, pixels, packing, texObj,
+                            texImage);
+
+}
+
+
+
+
+/*
+ * mgaTexParameter
+ * This just changes variables and flags for a state update, which
+ * will happen at the next mgaUpdateTextureState
+ */
+static void
+mgaDDTexParameter( GLcontext *ctx, GLenum target,
+                  struct gl_texture_object *tObj,
+                  GLenum pname, const GLfloat *params )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   mgaTextureObjectPtr t;
+
+   t = (mgaTextureObjectPtr) tObj->DriverData;
+
+   /* if we don't have a hardware texture, it will be automatically
+      created with current state before it is used, so we don't have
+      to do anything now */
+   if ( !t || !t->bound || target != GL_TEXTURE_2D ) {
+      return;
+   }
+
+   switch (pname) {
+   case GL_TEXTURE_MIN_FILTER:
+   case GL_TEXTURE_MAG_FILTER:
+      FLUSH_BATCH(mmesa);
+      mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
+      break;
+
+   case GL_TEXTURE_WRAP_S:
+   case GL_TEXTURE_WRAP_T:
+      FLUSH_BATCH(mmesa);
+      mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT);
+      break;
+
+   case GL_TEXTURE_BORDER_COLOR:
+      FLUSH_BATCH(mmesa);
+      mgaSetTexBorderColor(t,tObj->_BorderChan);
+      break;
+
+   default:
+      return;
+   }
+
+   mmesa->new_state |= MGA_NEW_TEXTURE;
+}
+
+
+static void
+mgaDDBindTexture( GLcontext *ctx, GLenum target,
+                 struct gl_texture_object *tObj )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   int unit = ctx->Texture.CurrentUnit;
+
+   FLUSH_BATCH(mmesa);
+
+   if (mmesa->CurrentTexObj[unit]) {
+      mmesa->CurrentTexObj[unit]->bound &= ~(unit+1);
+      mmesa->CurrentTexObj[unit] = 0;
+   }
+
+   /* force the texture state to be updated
+    */
+   MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+}
+
+
+static void
+mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData;
+
+   if ( t ) {
+      if (mmesa) {
+         if (t->bound) {
+            FLUSH_BATCH(mmesa);
+            if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0;
+            if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0;
+         }
+         mmesa->new_state |= MGA_NEW_TEXTURE;
+      }
+
+      mgaDestroyTexObj( mmesa, t );
+   }
+}
+
+
+static GLboolean
+mgaDDIsTextureResident( GLcontext *ctx, struct gl_texture_object *t )
+{
+   mgaTextureObjectPtr mt = (mgaTextureObjectPtr)t->DriverData;
+   return mt && mt->MemBlock;
+}
+
+
+void
+mgaDDInitTextureFuncs( GLcontext *ctx )
+{
+   ctx->Driver.TexEnv = mgaDDTexEnv;
+
+   ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
+   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+   ctx->Driver.TexImage2D = mgaTexImage2D;
+   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+   ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+   ctx->Driver.TexSubImage2D = mgaTexSubImage2D;
+   ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+   ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+   ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+   ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+   ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+   ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+   ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+
+   ctx->Driver.BindTexture = mgaDDBindTexture;
+   ctx->Driver.DeleteTexture = mgaDDDeleteTexture;
+   ctx->Driver.TexParameter = mgaDDTexParameter;
+   ctx->Driver.UpdateTexturePalette = 0;
+   ctx->Driver.IsTextureResident = mgaDDIsTextureResident;
+}
diff --git a/src/mesa/drivers/dri/mga/mgatex.h b/src/mesa/drivers/dri/mga/mgatex.h
new file mode 100644 (file)
index 0000000..c9f87d9
--- /dev/null
@@ -0,0 +1,62 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.h,v 1.7 2002/10/30 12:51:36 alanh Exp $ */
+/*
+ * 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>
+ */
+
+#ifndef MGATEX_INC
+#define MGATEX_INC
+
+#include "mgacontext.h"
+
+typedef struct mga_texture_object_s *mgaTextureObjectPtr;
+
+
+/* Called before a primitive is rendered to make sure the texture
+ * state is properly setup.  Texture residence is checked later
+ * when we grab the lock.
+ */
+void mgaUpdateTextureState( GLcontext *ctx );
+
+void mgaConvertTexture( GLuint *dest, int texelBytes,
+                       struct gl_texture_image *image,
+                       int x, int y, int width, int height );
+
+
+void mgaUploadSubImageLocked( mgaContextPtr mmesa,
+                             mgaTextureObjectPtr t,
+                             int level,
+                             int x, int y, int width, int height );
+
+int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t );
+
+void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t );
+
+void mgaAgeTextures( mgaContextPtr mmesa, int heap );
+
+void mgaDDInitTextureFuncs( GLcontext *ctx );
+
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgatexcnv.c b/src/mesa/drivers/dri/mga/mgatexcnv.c
new file mode 100644 (file)
index 0000000..3a05c7d
--- /dev/null
@@ -0,0 +1,256 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c,v 1.3 2002/10/30 12:51:36 alanh Exp $ */
+/*
+ * 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 <stdlib.h>
+#include <stdio.h>
+
+#include <GL/gl.h>
+
+#include "mm.h"
+#include "mgacontext.h"
+#include "mgatex.h"
+
+
+/*
+ * mgaConvertTexture
+ * Converts a mesa format texture to the appropriate hardware format
+ * Note that sometimes width may be larger than the texture, like 64x1
+ * for an 8x8 texture.  This happens when we have to crutch the pitch
+ * limits of the mga by uploading a block of texels as a single line.
+ */
+void mgaConvertTexture( GLuint *destPtr, int texelBytes,
+                       struct gl_texture_image *image,
+                       int x, int y, int width, int height )
+{
+   register int                i, j;
+   GLubyte             *src;
+   int stride;
+
+   if (0)
+      fprintf(stderr, "texture image %p\n", image->Data);
+
+   if (image->Data == 0)
+      return;
+
+   /* FIXME: g400 luminance_alpha internal format */
+   switch (texelBytes) {
+   case 1:
+      switch (image->Format) {
+      case GL_COLOR_INDEX:
+      case GL_INTENSITY:
+      case GL_LUMINANCE:
+      case GL_ALPHA:
+        src = (GLubyte *)image->Data + ( y * image->Width + x );
+        stride = (image->Width - width);
+        for ( i = height ; i ; i-- ) {
+           for ( j = width >> 2  ; j ; j-- ) {
+
+              *destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 );
+              src += 4;
+           }
+           src += stride;
+        }
+        break;
+      default:
+        goto format_error;
+      }
+      break;
+   case 2:
+      switch (image->Format) {
+      case GL_RGB:
+        src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3;
+        stride = (image->Width - width) * 3;
+        for ( i = height ; i ; i-- ) {
+           for ( j = width >> 1  ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) |
+                 ( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 );
+              src += 6;
+           }
+           src += stride;
+        }
+        break;
+      case GL_RGBA:
+        src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4;
+        stride = (image->Width - width) * 4;
+        for ( i = height ; i ; i-- ) {
+           for ( j = width >> 1  ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) |
+                 ( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 );
+              src += 8;
+           }
+           src += stride;
+        }
+        break;
+      case GL_LUMINANCE:
+        src = (GLubyte *)image->Data + ( y * image->Width + x );
+        stride = (image->Width - width);
+        for ( i = height ; i ; i-- ) {
+           for ( j = width >> 1  ; j ; j-- ) {
+              /* FIXME: should probably use 555 texture to get true grey */
+              *destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) |
+                 ( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 );
+              src += 2;
+           }
+           src += stride;
+        }
+        break;
+      case GL_INTENSITY:
+        src = (GLubyte *)image->Data + ( y * image->Width + x );
+        stride = (image->Width - width);
+        for ( i = height ; i ; i-- ) {
+           for ( j = width >> 1  ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) |
+                 ( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 );
+              src += 2;
+           }
+           src += stride;
+        }
+        break;
+      case GL_ALPHA:
+        src = (GLubyte *)image->Data + ( y * image->Width + x );
+        stride = (image->Width - width);
+        for ( i = height ; i ; i-- ) {
+           for ( j = width >> 1  ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) |
+                 ( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 );
+              src += 2;
+           }
+           src += stride;
+        }
+        break;
+      case GL_LUMINANCE_ALPHA:
+        src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2;
+        stride = (image->Width - width) * 2;
+        for ( i = height ; i ; i-- ) {
+           for ( j = width >> 1  ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) |
+                 ( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 );
+              src += 4;
+           }
+           src += stride;
+        }
+        break;
+      default:
+        goto format_error;
+      }
+      break;
+   case 4:
+      switch (image->Format) {
+      case GL_RGB:
+        src = (GLubyte *)image->Data + (  y * image->Width + x ) * 3;
+        stride = (image->Width - width) * 3;
+        for ( i = height ; i ; i-- ) {
+           for ( j = width ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255);
+              src += 3;
+           }
+           src += stride;
+        }
+        break;
+      case GL_RGBA:
+        src = (GLubyte *)image->Data + (  y * image->Width + x ) * 4;
+        stride = (image->Width - width) * 4;
+        for ( i = height ; i ; i-- ) {
+           for ( j = width  ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]);
+              src += 4;
+           }
+           src += stride;
+        }
+        break;
+      case GL_LUMINANCE:
+        src = (GLubyte *)image->Data + ( y * image->Width + x );
+        stride = (image->Width - width);
+        for ( i = height ; i ; i-- ) {
+           for ( j = width ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255);
+              src += 1;
+           }
+           src += stride;
+        }
+        break;
+      case GL_INTENSITY:
+        src = (GLubyte *)image->Data + (  y * image->Width + x );
+        stride = (image->Width - width);
+        for ( i = height ; i ; i-- ) {
+           for ( j = width ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]);
+              src += 1;
+           }
+           src += stride;
+        }
+        break;
+      case GL_ALPHA:
+        src = (GLubyte *)image->Data + ( y * image->Width + x );
+        stride = (image->Width - width);
+        for ( i = height ; i ; i-- ) {
+           for ( j = width ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]);
+              src += 1;
+           }
+           src += stride;
+        }
+        break;
+      case GL_LUMINANCE_ALPHA:
+        src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2;
+        stride = (image->Width - width) * 2;
+        for ( i = height ; i ; i-- ) {
+           for ( j = width ; j ; j-- ) {
+
+              *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],
+                                            src[0],src[1]);
+              src += 2;
+           }
+           src += stride;
+        }
+        break;
+      default:
+        goto format_error;
+      }
+      break;
+   default:
+      goto format_error;
+   }
+
+   return;
+
+ format_error:
+
+   fprintf(stderr, "Unsupported texelBytes %i, image->Format %i\n",
+          (int)texelBytes, (int)image->Format );
+}
diff --git a/src/mesa/drivers/dri/mga/mgatexmem.c b/src/mesa/drivers/dri/mga/mgatexmem.c
new file mode 100644 (file)
index 0000000..7dbdbc5
--- /dev/null
@@ -0,0 +1,564 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexmem.c,v 1.7 2002/10/30 12:51:36 alanh Exp $ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/gl.h>
+
+#include "mm.h"
+#include "mgacontext.h"
+#include "mgatex.h"
+#include "mgaregs.h"
+#include "mgaioctl.h"
+
+/*#include "mem.h" */
+#include "simple_list.h"
+
+static void
+mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t)
+{
+   if (t->MemBlock) {
+      mmFreeMem(t->MemBlock);
+      t->MemBlock = 0;
+
+      if (t->age > mmesa->dirtyAge)
+        mmesa->dirtyAge = t->age;
+   }
+
+   t->dirty_images = ~0;
+   move_to_tail(&(mmesa->SwappedOut), t);
+}
+
+static void
+mgaPrintLocalLRU( mgaContextPtr mmesa, int heap )
+{
+   mgaTextureObjectPtr t;
+   int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]);
+
+   fprintf(stderr, "\nLocal LRU, heap %d:\n", heap);
+
+   foreach( t, &(mmesa->TexObjList[heap]) ) {
+      if (!t->tObj)
+        fprintf(stderr, "Placeholder %d at %x sz %x\n",
+                t->MemBlock->ofs / sz,
+                t->MemBlock->ofs,
+                t->MemBlock->size);
+      else
+        fprintf(stderr, "Texture (bound %d) at %x sz %x\n",
+                t->bound,
+                t->MemBlock->ofs,
+                t->MemBlock->size);
+   }
+
+   fprintf(stderr, "\n\n");
+}
+
+static void
+mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap )
+{
+   int i, j;
+   drmTextureRegion *list = mmesa->sarea->texList[heap];
+
+   fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list);
+
+   for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_NR_TEX_REGIONS ; i++) {
+      fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+             j, list[j].age, list[j].next, list[j].prev);
+      j = list[j].next;
+      if (j == MGA_NR_TEX_REGIONS) break;
+   }
+
+   if (j != MGA_NR_TEX_REGIONS) {
+      fprintf(stderr, "Loop detected in global LRU\n\n\n");
+      for (i = 0 ; i < MGA_NR_TEX_REGIONS ; i++) {
+        fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+                i, list[i].age, list[i].next, list[i].prev);
+      }
+   }
+
+   fprintf(stderr, "\n\n");
+}
+
+
+static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap )
+{
+   drmTextureRegion *list = mmesa->sarea->texList[heap];
+   int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap];
+   int i;
+
+   mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap];
+
+   if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap);
+
+   /* (Re)initialize the global circular LRU list.  The last element
+    * in the array (MGA_NR_TEX_REGIONS) is the sentinal.  Keeping it
+    * at the end of the array allows it to be addressed rationally
+    * when looking up objects at a particular location in texture
+    * memory.
+    */
+   for (i = 0 ; (i+1) * sz <= mmesa->mgaScreen->textureSize[heap] ; i++) {
+      list[i].prev = i-1;
+      list[i].next = i+1;
+      list[i].age = mmesa->sarea->texAge[heap];
+   }
+
+   i--;
+   list[0].prev = MGA_NR_TEX_REGIONS;
+   list[i].prev = i-1;
+   list[i].next = MGA_NR_TEX_REGIONS;
+   list[MGA_NR_TEX_REGIONS].prev = i;
+   list[MGA_NR_TEX_REGIONS].next = 0;
+
+}
+
+
+static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+   int i;
+   int heap = t->heap;
+   int logsz = mmesa->mgaScreen->logTextureGranularity[heap];
+   int start = t->MemBlock->ofs >> logsz;
+   int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
+   drmTextureRegion *list = mmesa->sarea->texList[heap];
+
+   mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap];
+
+   if (!t->MemBlock) {
+      fprintf(stderr, "no memblock\n\n");
+      return;
+   }
+
+   /* Update our local LRU
+    */
+   move_to_head( &(mmesa->TexObjList[heap]), t );
+
+
+   if (0)
+      fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list);
+
+
+   /* Update the global LRU
+    */
+   for (i = start ; i <= end ; i++) {
+
+      list[i].in_use = 1;
+      list[i].age = mmesa->texAge[heap];
+
+      /* remove_from_list(i)
+       */
+      list[(unsigned)list[i].next].prev = list[i].prev;
+      list[(unsigned)list[i].prev].next = list[i].next;
+
+      /* insert_at_head(list, i)
+       */
+      list[i].prev = MGA_NR_TEX_REGIONS;
+      list[i].next = list[MGA_NR_TEX_REGIONS].next;
+      list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i;
+      list[MGA_NR_TEX_REGIONS].next = i;
+   }
+
+   if (0) {
+      mgaPrintGlobalLRU(mmesa, t->heap);
+      mgaPrintLocalLRU(mmesa, t->heap);
+   }
+}
+
+/* Called for every shared texture region which has increased in age
+ * since we last held the lock.
+ *
+ * Figures out which of our textures have been ejected by other clients,
+ * and pushes a placeholder texture onto the LRU list to represent
+ * the other client's textures.
+ */
+static void mgaTexturesGone( mgaContextPtr mmesa,
+                            GLuint heap,
+                            GLuint offset,
+                            GLuint size,
+                            GLuint in_use )
+{
+   mgaTextureObjectPtr t, tmp;
+
+
+
+   foreach_s ( t, tmp, &(mmesa->TexObjList[heap]) ) {
+
+      if (t->MemBlock->ofs >= offset + size ||
+         t->MemBlock->ofs + t->MemBlock->size <= offset)
+        continue;
+
+
+
+
+      /* It overlaps - kick it off.  Need to hold onto the currently bound
+       * objects, however.
+       */
+      if (t->bound)
+        mgaSwapOutTexObj( mmesa, t );
+      else
+        mgaDestroyTexObj( mmesa, t );
+   }
+
+
+   if (in_use) {
+      t = (mgaTextureObjectPtr) calloc(1, sizeof(*t));
+      if (!t) return;
+
+      t->heap = heap;
+      t->MemBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset);
+      if (!t->MemBlock) {
+        fprintf(stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
+                (int)size, (int)offset);
+        mmDumpMemInfo( mmesa->texHeap[heap]);
+        return;
+      }
+      insert_at_head( &(mmesa->TexObjList[heap]), t );
+   }
+}
+
+
+void mgaAgeTextures( mgaContextPtr mmesa, int heap )
+{
+   MGASAREAPrivPtr sarea = mmesa->sarea;
+   int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]);
+   int idx, nr = 0;
+
+   /* Have to go right round from the back to ensure stuff ends up
+    * LRU in our local list...  Fix with a cursor pointer.
+    */
+   for (idx = sarea->texList[heap][MGA_NR_TEX_REGIONS].prev ;
+       idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ;
+       idx = sarea->texList[heap][idx].prev, nr++)
+   {
+      /* If switching texturing schemes, then the SAREA might not
+       * have been properly cleared, so we need to reset the
+       * global texture LRU.
+       */
+      if ( idx * sz > mmesa->mgaScreen->textureSize[heap] ) {
+         nr = MGA_NR_TEX_REGIONS;
+         break;
+      }
+
+      if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) {
+        mgaTexturesGone(mmesa, heap, idx * sz, sz,
+                        sarea->texList[heap][idx].in_use);
+      }
+   }
+
+   if (nr == MGA_NR_TEX_REGIONS) {
+      mgaTexturesGone(mmesa, heap, 0,
+                     mmesa->mgaScreen->textureSize[heap], 0);
+      mgaResetGlobalLRU( mmesa, heap );
+   }
+
+
+   if (0) {
+      mgaPrintGlobalLRU( mmesa, heap );
+      mgaPrintLocalLRU( mmesa, heap );
+   }
+
+   mmesa->texAge[heap] = sarea->texAge[heap];
+   mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE;
+}
+
+/*
+ * mgaUploadSubImageLocked
+ *
+ * Perform an iload based update of a resident buffer.  This is used for
+ * both initial loading of the entire image, and texSubImage updates.
+ *
+ * Performed with the hardware lock held.
+ */
+void mgaUploadSubImageLocked( mgaContextPtr mmesa,
+                             mgaTextureObjectPtr t,
+                             int level,
+                             int x, int y, int width, int height )
+{
+   int         x2;
+   int         dwords;
+   int         offset;
+   struct gl_texture_image *image;
+   int         texelBytes, texelsPerDword, texelMaccess, length;
+
+   if ( level < 0 || level >= MGA_TEX_MAXLEVELS )
+      return;
+
+   image = t->tObj->Image[level];
+   if ( !image ) return;
+
+
+   if (image->Data == 0) {
+      fprintf(stderr, "null texture image data tObj %p level %d\n",
+             t->tObj, level);
+      return;
+   }
+
+
+   /* find the proper destination offset for this level */
+   offset = (t->MemBlock->ofs +
+            t->offsets[level]);
+
+
+   texelBytes = t->texelBytes;
+   switch( texelBytes ) {
+   case 1:
+      texelsPerDword = 4;
+      texelMaccess = 0;
+      break;
+   case 2:
+      texelsPerDword = 2;
+      texelMaccess = 1;
+      break;
+   case 4:
+      texelsPerDword = 1;
+      texelMaccess = 2;
+      break;
+   default:
+      return;
+   }
+
+
+   /* We can't do a subimage update if pitch is < 32 texels due
+    * to hardware XY addressing limits, so we will need to
+    * linearly upload all modified rows.
+    */
+   if ( image->Width < 32 ) {
+      x = 0;
+      width = image->Width * height;
+      height = 1;
+
+      /* Assume that 1x1 textures aren't going to cause a
+       * bus error if we read up to four texels from that
+       * location:
+       */
+/*        if ( width < texelsPerDword ) { */
+/*      width = texelsPerDword; */
+/*        } */
+   } else {
+      /* pad the size out to dwords.  The image is a pointer
+        to the entire image, so we can safely reference
+        outside the x,y,width,height bounds if we need to */
+      x2 = x + width;
+      x2 = (x2 + (texelsPerDword-1)) & ~(texelsPerDword-1);
+      x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1);
+      width = x2 - x;
+   }
+
+   /* we may not be able to upload the entire texture in one
+      batch due to register limits or dma buffer limits.
+      Recursively split it up. */
+   while ( 1 ) {
+      dwords = height * width / texelsPerDword;
+      if ( dwords * 4 <= MGA_BUFFER_SIZE ) {
+        break;
+      }
+
+      mgaUploadSubImageLocked( mmesa, t, level, x, y,
+                              width, height >> 1 );
+      y += ( height >> 1 );
+      height -= ( height >> 1 );
+   }
+
+   length = dwords * 4;
+
+   /* Fill in the secondary buffer with properly converted texels
+    * from the mesa buffer. */
+   /* FIXME: the sync for direct copy reduces speed.. */
+   if(t->heap == MGA_CARD_HEAP  ) {
+      mgaGetILoadBufferLocked( mmesa );
+      mgaConvertTexture( (GLuint *)mmesa->iload_buffer->address,
+                        texelBytes, image, x, y, width, height );
+      if(length < 64) length = 64;
+
+      if (0)
+        fprintf(stderr, "TexelBytes : %d, offset: %d, length : %d\n",
+                texelBytes,
+                mmesa->mgaScreen->textureOffset[t->heap] +
+                offset +
+                y * width * 4/texelsPerDword,
+                length);
+
+      mgaFireILoadLocked( mmesa,
+                         mmesa->mgaScreen->textureOffset[t->heap] +
+                         offset +
+                         y * width * 4/texelsPerDword,
+                         length);
+   } else {
+      /* This works, is slower for uploads to card space and needs
+       * additional synchronization with the dma stream.
+       */
+       
+      UPDATE_LOCK(mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT);
+      mgaConvertTexture( (GLuint *)
+                        (mmesa->mgaScreen->texVirtual[t->heap] +
+                         offset +
+                         y * width * 4/texelsPerDword),
+                        texelBytes, image, x, y, width, height );
+   }
+}
+
+
+static void mgaUploadTexLevel( mgaContextPtr mmesa,
+                              mgaTextureObjectPtr t,
+                              int l )
+{
+   mgaUploadSubImageLocked( mmesa,
+                           t,
+                           l,
+                           0, 0,
+                           t->tObj->Image[l]->Width,
+                           t->tObj->Image[l]->Height);
+}
+
+
+
+
+#if 0
+static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+       /* NOT DONE */
+}
+#endif
+
+
+static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+   int freeagp, freecard;
+   int fitincard, fitinagp;
+   int totalcard, totalagp;
+   TMemBlock *b;
+
+   totalcard = totalagp = fitincard = fitinagp = freeagp = freecard = 0;
+
+   b = mmesa->texHeap[0];
+   while(b)
+   {
+     totalcard += b->size;
+     if(b->free) if(t->totalSize <= b->size)fitincard = 1;
+     b = b->next;
+   }
+
+   b = mmesa->texHeap[1];
+   while(b)
+   {
+     totalagp += b->size;
+     if(b->free)  if(t->totalSize <= b->size)fitinagp = 1;
+     b = b->next;
+   }
+
+   if(fitincard)return 0;
+   if(fitinagp)return 1;
+
+   if(totalcard && totalagp)
+   {
+     int ages;
+     int ratio = (totalcard > totalagp) ? totalcard / totalagp : totalagp / totalcard;
+     ages = mmesa->sarea->texAge[0] + mmesa->sarea->texAge[1];
+     if( (ages % ratio) == 0)return totalcard > totalagp ? 1 : 0;
+     else return totalcard > totalagp ? 0 : 1;
+   }
+
+   if(totalagp) return 1;
+   return 0;
+}
+
+
+int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+   int heap;
+   int i;
+   int ofs;
+
+   heap = t->heap = mgaChooseTexHeap( mmesa, t );
+
+   /* Do we need to eject LRU texture objects?
+    */
+   if (!t->MemBlock) {
+      while (1)
+      {
+        mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev;
+
+        t->MemBlock = mmAllocMem( mmesa->texHeap[heap],
+                                  t->totalSize,
+                                  6, 0 );
+        if (t->MemBlock)
+           break;
+
+        if (mmesa->TexObjList[heap].prev->bound) {
+           fprintf(stderr, "Hit bound texture in upload\n");
+           return -1;
+        }
+
+        if (mmesa->TexObjList[heap].prev ==
+            &(mmesa->TexObjList[heap]))
+        {
+           fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
+           mmDumpMemInfo( mmesa->texHeap[heap] );
+           return -1;
+        }
+
+        mgaDestroyTexObj( mmesa, tmp );
+      }
+
+      ofs = t->MemBlock->ofs
+        + mmesa->mgaScreen->textureOffset[heap]
+        ;
+
+      t->setup.texorg  = ofs;
+      t->setup.texorg1 = ofs + t->offsets[1];
+      t->setup.texorg2 = ofs + t->offsets[2];
+      t->setup.texorg3 = ofs + t->offsets[3];
+      t->setup.texorg4 = ofs + t->offsets[4];
+
+      mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+   }
+
+   /* Let the world know we've used this memory recently.
+    */
+   mgaUpdateTexLRU( mmesa, t );
+
+
+   if (MGA_DEBUG&DEBUG_VERBOSE_LRU)
+      fprintf(stderr, "dispatch age: %d age freed memory: %d\n",
+             GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge);
+
+   if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa))
+      mgaWaitAgeLocked( mmesa, mmesa->dirtyAge );
+
+   if (t->dirty_images) {
+      if (MGA_DEBUG&DEBUG_VERBOSE_LRU)
+        fprintf(stderr, "*");
+
+      for (i = 0 ; i <= t->lastLevel ; i++)
+        if (t->dirty_images & (1<<i))
+           mgaUploadTexLevel( mmesa, t, i );
+   }
+
+
+   t->dirty_images = 0;
+   return 0;
+}
diff --git a/src/mesa/drivers/dri/mga/mgatris.c b/src/mesa/drivers/dri/mga/mgatris.c
new file mode 100644 (file)
index 0000000..e47cfc1
--- /dev/null
@@ -0,0 +1,915 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.10 2002/10/30 12:51:36 alanh Exp $ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "mtypes.h"
+#include "macros.h"
+#include "colormac.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "mm.h"
+#include "mgacontext.h"
+#include "mgaioctl.h"
+#include "mgatris.h"
+#include "mgavb.h"
+#include "mgastate.h"
+
+
+static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim );
+
+/***********************************************************************
+ *                 Functions to draw basic primitives                  *
+ ***********************************************************************/
+
+
+#if defined (USE_X86_ASM)
+#define EMIT_VERT( j, vb, vertex_size, v )             \
+do {   int __tmp;                                      \
+       __asm__ __volatile__( "rep ; movsl"             \
+                        : "=%c" (j), "=D" (vb), "=S" (__tmp)           \
+                        : "0" (vertex_size),           \
+                          "D" ((long)vb),              \
+                          "S" ((long)v));              \
+} while (0)
+#else
+#define EMIT_VERT( j, vb, vertex_size, v )     \
+do {                                           \
+   for ( j = 0 ; j < vertex_size ; j++ )       \
+      vb[j] = (v)->ui[j];                      \
+   vb += vertex_size;                          \
+} while (0)
+#endif
+
+static void __inline__ mga_draw_triangle( mgaContextPtr mmesa,
+                                          mgaVertexPtr v0,
+                                          mgaVertexPtr v1,
+                                          mgaVertexPtr v2 )
+{
+   GLuint vertex_size = mmesa->vertex_size;
+   GLuint *vb = mgaAllocDmaLow( mmesa, 3 * 4 * vertex_size );
+   int j;
+
+   EMIT_VERT( j, vb, vertex_size, v0 );
+   EMIT_VERT( j, vb, vertex_size, v1 );
+   EMIT_VERT( j, vb, vertex_size, v2 );
+}
+
+
+static void __inline__ mga_draw_quad( mgaContextPtr mmesa,
+                                      mgaVertexPtr v0,
+                                      mgaVertexPtr v1,
+                                      mgaVertexPtr v2,
+                                      mgaVertexPtr v3 )
+{
+   GLuint vertex_size = mmesa->vertex_size;
+   GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
+   int j;
+
+   EMIT_VERT( j, vb, vertex_size, v0 );
+   EMIT_VERT( j, vb, vertex_size, v1 );
+   EMIT_VERT( j, vb, vertex_size, v3 );
+   EMIT_VERT( j, vb, vertex_size, v1 );
+   EMIT_VERT( j, vb, vertex_size, v2 );
+   EMIT_VERT( j, vb, vertex_size, v3 );
+}
+
+
+static __inline__ void mga_draw_point( mgaContextPtr mmesa,
+                                       mgaVertexPtr tmp )
+{
+   GLfloat sz = mmesa->glCtx->Point._Size * .5;
+   int vertex_size = mmesa->vertex_size;
+   GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
+   int j;
+   
+#if 0
+   v0->v.x += PNT_X_OFFSET - TRI_X_OFFSET;
+   v0->v.y += PNT_Y_OFFSET - TRI_Y_OFFSET;
+#endif
+
+   /* Draw a point as two triangles.
+    */
+   *(float *)&vb[0] = tmp->v.x - sz;
+   *(float *)&vb[1] = tmp->v.y - sz;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x + sz;
+   *(float *)&vb[1] = tmp->v.y - sz;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x + sz;
+   *(float *)&vb[1] = tmp->v.y + sz;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x + sz;
+   *(float *)&vb[1] = tmp->v.y + sz;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x - sz;
+   *(float *)&vb[1] = tmp->v.y + sz;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x - sz;
+   *(float *)&vb[1] = tmp->v.y - sz;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = tmp->ui[j];
+
+#if 0
+   v0->v.x -= PNT_X_OFFSET - TRI_X_OFFSET;
+   v0->v.y -= PNT_Y_OFFSET - TRI_Y_OFFSET;
+#endif
+}
+
+
+static __inline__ void mga_draw_line( mgaContextPtr mmesa,
+                                     mgaVertexPtr v0,
+                                     mgaVertexPtr v1 )
+{
+   GLuint vertex_size = mmesa->vertex_size;
+   GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
+   GLfloat dx, dy, ix, iy;
+   GLfloat width = mmesa->glCtx->Line._Width;
+   GLint j;
+
+#if 0
+   v0->v.x += LINE_X_OFFSET - TRI_X_OFFSET;
+   v0->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET;
+   v1->v.x += LINE_X_OFFSET - TRI_X_OFFSET;
+   v1->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET;
+#endif
+
+   dx = v0->v.x - v1->v.x;
+   dy = v0->v.y - v1->v.y;
+   
+   ix = width * .5; iy = 0;
+   if (dx * dx > dy * dy) {
+      iy = ix; ix = 0;
+   }
+
+   *(float *)&vb[0] = v0->v.x - ix;
+   *(float *)&vb[1] = v0->v.y - iy;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = v0->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = v1->v.x + ix;
+   *(float *)&vb[1] = v1->v.y + iy;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = v1->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = v0->v.x + ix;
+   *(float *)&vb[1] = v0->v.y + iy;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = v0->ui[j];
+   vb += vertex_size;
+        
+   *(float *)&vb[0] = v0->v.x - ix;
+   *(float *)&vb[1] = v0->v.y - iy;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = v0->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = v1->v.x - ix;
+   *(float *)&vb[1] = v1->v.y - iy;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = v1->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = v1->v.x + ix;
+   *(float *)&vb[1] = v1->v.y + iy;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = v1->ui[j];
+   vb += vertex_size;
+
+#if 0
+   v0->v.x -= LINE_X_OFFSET - TRI_X_OFFSET;
+   v0->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET;
+   v1->v.x -= LINE_X_OFFSET - TRI_X_OFFSET;
+   v1->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET;
+#endif
+}
+
+/***********************************************************************
+ *          Macros for t_dd_tritmp.h to draw basic primitives          *
+ ***********************************************************************/
+
+#define TRI( a, b, c )                         \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      mmesa->draw_tri( mmesa, a, b, c );       \
+   else                                                \
+      mga_draw_triangle( mmesa, a, b, c );     \
+} while (0)
+
+#define QUAD( a, b, c, d )                     \
+do {                                           \
+   if (DO_FALLBACK) {                          \
+      mmesa->draw_tri( mmesa, a, b, d );       \
+      mmesa->draw_tri( mmesa, b, c, d );       \
+   } else {                                    \
+      mga_draw_quad( mmesa, a, b, c, d );      \
+   }                                           \
+} while (0)
+
+#define LINE( v0, v1 )                         \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      mmesa->draw_line( mmesa, v0, v1 );       \
+   else {                                      \
+      mga_draw_line( mmesa, v0, v1 );          \
+   }                                           \
+} while (0)
+
+#define POINT( v0 )                            \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      mmesa->draw_point( mmesa, v0 );          \
+   else {                                      \
+      mga_draw_point( mmesa, v0 );             \
+   }                                           \
+} while (0)
+
+
+/***********************************************************************
+ *              Fallback to swrast for basic primitives                *
+ ***********************************************************************/
+
+/* This code is hit only when a mix of accelerated and unaccelerated
+ * primitives are being drawn, and only for the unaccelerated
+ * primitives.  
+ */
+
+static void 
+mga_fallback_tri( mgaContextPtr mmesa, 
+                  mgaVertex *v0, 
+                  mgaVertex *v1, 
+                  mgaVertex *v2 )
+{
+   GLcontext *ctx = mmesa->glCtx;
+   SWvertex v[3];
+   mga_translate_vertex( ctx, v0, &v[0] );
+   mga_translate_vertex( ctx, v1, &v[1] );
+   mga_translate_vertex( ctx, v2, &v[2] );
+   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
+}
+
+
+static void 
+mga_fallback_line( mgaContextPtr mmesa,
+                   mgaVertex *v0,
+                   mgaVertex *v1 )
+{
+   GLcontext *ctx = mmesa->glCtx;
+   SWvertex v[2];
+   mga_translate_vertex( ctx, v0, &v[0] );
+   mga_translate_vertex( ctx, v1, &v[1] );
+   _swrast_Line( ctx, &v[0], &v[1] );
+}
+
+
+static void 
+mga_fallback_point( mgaContextPtr mmesa, 
+                    mgaVertex *v0 )
+{
+   GLcontext *ctx = mmesa->glCtx;
+   SWvertex v[1];
+   mga_translate_vertex( ctx, v0, &v[0] );
+   _swrast_Point( ctx, &v[0] );
+}
+
+/***********************************************************************
+ *              Build render functions from dd templates               *
+ ***********************************************************************/
+
+
+#define MGA_UNFILLED_BIT    0x1
+#define MGA_OFFSET_BIT     0x2
+#define MGA_TWOSIDE_BIT     0x4
+#define MGA_FLAT_BIT        0x8        /* mga can't flatshade? */
+#define MGA_FALLBACK_BIT    0x10
+#define MGA_MAX_TRIFUNC     0x20
+
+static struct {
+   points_func         points;
+   line_func           line;
+   triangle_func       triangle;
+   quad_func           quad;
+} rast_tab[MGA_MAX_TRIFUNC];
+
+#define DO_FALLBACK (IND & MGA_FALLBACK_BIT)
+#define DO_OFFSET   (IND & MGA_OFFSET_BIT)
+#define DO_UNFILLED (IND & MGA_UNFILLED_BIT)
+#define DO_TWOSIDE  (IND & MGA_TWOSIDE_BIT)
+#define DO_FLAT     (IND & MGA_FLAT_BIT)
+#define DO_TRI       1
+#define DO_QUAD      1
+#define DO_LINE      1
+#define DO_POINTS    1
+#define DO_FULL_QUAD 1
+
+#define HAVE_RGBA         1
+#define HAVE_BACK_COLORS  0
+#define HAVE_SPEC         1
+#define HAVE_HW_FLATSHADE 0
+#define VERTEX mgaVertex
+#define TAB rast_tab
+
+#define MGA_COLOR( dst, src )                  \
+do {                                           \
+   dst[0] = src[2];                            \
+   dst[1] = src[1];                            \
+   dst[2] = src[0];                            \
+   dst[3] = src[3];                            \
+} while (0)
+
+#define MGA_SPEC( dst, src )                   \
+do {                                           \
+   dst[0] = src[2];                            \
+   dst[1] = src[1];                            \
+   dst[2] = src[0];                            \
+} while (0)
+
+#define DEPTH_SCALE mmesa->depth_scale
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->v.x
+#define VERT_Y(_v) _v->v.y
+#define VERT_Z(_v) _v->v.z
+#define AREA_IS_CCW( a ) (a > 0)
+#define GET_VERTEX(e) (mmesa->verts + (e<<mmesa->vertex_stride_shift))
+
+#define VERT_SET_RGBA( v, c )  MGA_COLOR( v->ub4[4], c )
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
+#define VERT_SAVE_RGBA( idx )  color[idx] = v[idx]->ui[4]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]   
+
+#define VERT_SET_SPEC( v, c )  MGA_SPEC( v->ub4[5], c )
+#define VERT_COPY_SPEC( v0, v1 ) COPY_3V(v0->ub4[5], v1->ub4[5])
+#define VERT_SAVE_SPEC( idx )  spec[idx] = v[idx]->ui[5]
+#define VERT_RESTORE_SPEC( idx ) v[idx]->ui[5] = spec[idx]   
+
+#define LOCAL_VARS(n)                                  \
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);             \
+   GLuint color[n], spec[n];                           \
+   (void) color; (void) spec;
+
+
+
+/***********************************************************************
+ *            Functions to draw basic unfilled primitives              *
+ ***********************************************************************/
+
+#define RASTERIZE(x) if (mmesa->raster_primitive != x) \
+                        mgaRasterPrimitive( ctx, x, MGA_WA_TRIANGLES )
+#define RENDER_PRIMITIVE mmesa->render_primitive
+#define IND MGA_FALLBACK_BIT
+#define TAG(x) x
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+/***********************************************************************
+ *                 Functions to draw GL primitives                     *
+ ***********************************************************************/
+
+#define IND (0)
+#define TAG(x) x
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_OFFSET_BIT|MGA_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_UNFILLED_BIT|MGA_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT| \
+            MGA_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+
+/* Mga doesn't support provoking-vertex flat-shading?
+ */
+#define IND (MGA_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_OFFSET_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_offset_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_UNFILLED_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_unfilled_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_offset_unfilled_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_unfilled_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_FALLBACK_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_OFFSET_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_offset_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_unfilled_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_offset_unfilled_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT| \
+            MGA_FALLBACK_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
+
+
+static void init_rast_tab( void )
+{
+   init();
+   init_offset();
+   init_twoside();
+   init_twoside_offset();
+   init_unfilled();
+   init_offset_unfilled();
+   init_twoside_unfilled();
+   init_twoside_offset_unfilled();
+   init_fallback();
+   init_offset_fallback();
+   init_twoside_fallback();
+   init_twoside_offset_fallback();
+   init_unfilled_fallback();
+   init_offset_unfilled_fallback();
+   init_twoside_unfilled_fallback();
+   init_twoside_offset_unfilled_fallback();
+
+   init_flat();
+   init_offset_flat();
+   init_twoside_flat();
+   init_twoside_offset_flat();
+   init_unfilled_flat();
+   init_offset_unfilled_flat();
+   init_twoside_unfilled_flat();
+   init_twoside_offset_unfilled_flat();
+   init_fallback_flat();
+   init_offset_fallback_flat();
+   init_twoside_fallback_flat();
+   init_twoside_offset_fallback_flat();
+   init_unfilled_fallback_flat();
+   init_offset_unfilled_fallback_flat();
+   init_twoside_unfilled_fallback_flat();
+   init_twoside_offset_unfilled_fallback_flat();
+}
+
+/**********************************************************************/
+/*                 Render whole begin/end objects                     */
+/**********************************************************************/
+
+
+#define VERT(x) (mgaVertex *)(vertptr + ((x)<<vertshift))
+#define RENDER_POINTS( start, count )          \
+   for ( ; start < count ; start++)            \
+      mga_draw_point( mmesa, VERT(ELT(start)) );
+#define RENDER_LINE( v0, v1 ) \
+   mga_draw_line( mmesa, VERT(v0), VERT(v1) )
+#define RENDER_TRI( v0, v1, v2 )  \
+   mga_draw_triangle( mmesa, VERT(v0), VERT(v1), VERT(v2) )
+#define RENDER_QUAD( v0, v1, v2, v3 ) \
+   mga_draw_quad( mmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
+#define INIT(x) mgaRenderPrimitive( ctx, x )
+#undef LOCAL_VARS
+#define LOCAL_VARS                                             \
+    mgaContextPtr mmesa = MGA_CONTEXT(ctx);                    \
+    GLubyte *vertptr = (GLubyte *)mmesa->verts;                        \
+    const GLuint vertshift = mmesa->vertex_stride_shift;               \
+    const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;      \
+    (void) elt;
+#define RESET_STIPPLE 
+#define RESET_OCCLUSION 
+#define PRESERVE_VB_DEFS
+#define ELT(x) x
+#define TAG(x) mga_##x##_verts
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) mga_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl/t_vb_rendertmp.h"
+
+
+/**********************************************************************/
+/*                   Render clipped primitives                        */
+/**********************************************************************/
+
+
+
+static void mgaRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   GLuint prim = mmesa->render_primitive;
+
+   /* Render the new vertices as an unclipped polygon. 
+    */
+   {
+      GLuint *tmp = VB->Elts;
+      VB->Elts = (GLuint *)elts;
+      tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
+      VB->Elts = tmp;
+   }
+
+   /* Restore the render primitive
+    */
+   if (prim != GL_POLYGON)
+      tnl->Driver.Render.PrimitiveNotify( ctx, prim );
+}
+
+static void mgaRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   tnl->Driver.Render.Line( ctx, ii, jj );
+}
+
+static void mgaFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, 
+                                      GLuint n )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   GLuint vertex_size = mmesa->vertex_size;
+   GLuint *vb = mgaAllocDmaLow( mmesa, (n-2) * 3 * 4 * vertex_size );
+   GLubyte *vertptr = (GLubyte *)mmesa->verts;                 
+   const GLuint vertshift = mmesa->vertex_stride_shift;        
+   const GLuint *start = (const GLuint *)VERT(elts[0]);
+   int i,j;
+
+   for (i = 2 ; i < n ; i++) {
+      EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i-1]) );
+      EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i]) );
+      EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) start );
+   }
+}
+
+/**********************************************************************/
+/*                    Choose render functions                         */
+/**********************************************************************/
+
+
+
+#define _MGA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE |           \
+                              _DD_NEW_TRI_UNFILLED |           \
+                              _DD_NEW_TRI_LIGHT_TWOSIDE |      \
+                              _DD_NEW_TRI_OFFSET |             \
+                              _DD_NEW_TRI_STIPPLE |            \
+                              _NEW_POLYGONSTIPPLE)
+
+
+#define POINT_FALLBACK (DD_POINT_SMOOTH)
+#define LINE_FALLBACK (DD_LINE_SMOOTH | DD_LINE_STIPPLE)
+#define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_UNFILLED)
+#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK| \
+                            DD_TRI_STIPPLE)
+#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \
+                          DD_TRI_UNFILLED)
+
+static void mgaChooseRenderState(GLcontext *ctx)
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLuint flags = ctx->_TriangleCaps;
+   GLuint index = 0;
+
+   if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
+      if (flags & ANY_RASTER_FLAGS) {
+        if (flags & DD_TRI_LIGHT_TWOSIDE)    index |= MGA_TWOSIDE_BIT;
+        if (flags & DD_TRI_OFFSET)           index |= MGA_OFFSET_BIT;
+        if (flags & DD_TRI_UNFILLED)         index |= MGA_UNFILLED_BIT;
+        if (flags & DD_FLATSHADE)            index |= MGA_FLAT_BIT;
+      }
+
+      mmesa->draw_point = mga_draw_point;
+      mmesa->draw_line = mga_draw_line;
+      mmesa->draw_tri = mga_draw_triangle;
+
+      /* Hook in fallbacks for specific primitives.
+       */
+      if (flags & ANY_FALLBACK_FLAGS)
+      {
+        if (flags & POINT_FALLBACK) 
+           mmesa->draw_point = mga_fallback_point;
+        
+        if (flags & LINE_FALLBACK) 
+           mmesa->draw_line = mga_fallback_line;
+        
+        if (flags & TRI_FALLBACK) 
+           mmesa->draw_tri = mga_fallback_tri;
+        
+        if ((flags & DD_TRI_STIPPLE) && !mmesa->haveHwStipple)
+           mmesa->draw_tri = mga_fallback_tri;
+      
+        index |= MGA_FALLBACK_BIT;
+      }
+   }
+
+   if (mmesa->RenderIndex != index) {
+      mmesa->RenderIndex = index;
+
+      tnl->Driver.Render.Points = rast_tab[index].points;
+      tnl->Driver.Render.Line = rast_tab[index].line;
+      tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+      tnl->Driver.Render.Quad = rast_tab[index].quad;
+         
+      if (index == 0) {
+        tnl->Driver.Render.PrimTabVerts = mga_render_tab_verts;
+        tnl->Driver.Render.PrimTabElts = mga_render_tab_elts;
+        tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
+        tnl->Driver.Render.ClippedPolygon = mgaFastRenderClippedPoly;
+      } else {
+        tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+        tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+        tnl->Driver.Render.ClippedLine = mgaRenderClippedLine;
+        tnl->Driver.Render.ClippedPolygon = mgaRenderClippedPoly;
+      }
+   }
+}
+
+/**********************************************************************/
+/*                Runtime render state and callbacks                  */
+/**********************************************************************/
+
+
+static void mgaRunPipeline( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+   if (mmesa->new_state) {
+      mgaDDUpdateHwState( ctx );
+   }
+
+   if (!mmesa->Fallback && mmesa->new_gl_state) {
+      if (mmesa->new_gl_state & _MGA_NEW_RASTERSETUP)
+        mgaChooseVertexState( ctx );
+      
+      if (mmesa->new_gl_state & _MGA_NEW_RENDERSTATE)
+        mgaChooseRenderState( ctx );
+      
+      mmesa->new_gl_state = 0;
+
+      /* Circularity: mgaDDUpdateHwState can affect mmesa->Fallback,
+       * but mgaChooseVertexState can affect mmesa->new_state.  Hence
+       * the second check.  (Fix this...)
+       */
+      if (mmesa->new_state) {
+        mgaDDUpdateHwState( ctx );
+      }
+   }
+
+   _tnl_run_pipeline( ctx );
+}
+
+
+static GLenum reduced_prim[GL_POLYGON+1] = {
+   GL_POINTS,
+   GL_LINES,
+   GL_LINES,
+   GL_LINES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES
+};
+
+
+
+/* Always called between RenderStart and RenderFinish --> We already
+ * hold the lock.
+ */
+void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
+   FLUSH_BATCH( mmesa );
+   mmesa->raster_primitive = prim;
+/*     mmesa->hw_primitive = hwprim; */
+   mmesa->hw_primitive = MGA_WA_TRIANGLES; /* disable mgarender.c for now */
+   mgaUpdateCull(ctx);   
+
+   if (ctx->Polygon.StippleFlag && mmesa->haveHwStipple)
+   {
+      mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+      if (mmesa->raster_primitive == GL_TRIANGLES)
+        mmesa->setup.dwgctl |= mmesa->poly_stipple;
+      else
+        mmesa->setup.dwgctl &= ~(0xf<<20);
+   }
+}
+
+
+
+/* Determine the rasterized primitive when not drawing unfilled 
+ * polygons.
+ *
+ * Used only for the default render stage which always decomposes
+ * primitives to trianges/lines/points.  For the accelerated stage,
+ * which renders strips as strips, the equivalent calculations are
+ * performed in mgarender.c.
+ */
+static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLuint rprim = reduced_prim[prim];
+
+   mmesa->render_primitive = prim;
+
+   if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
+      return;
+       
+   if (mmesa->raster_primitive != rprim) {
+      mgaRasterPrimitive( ctx, rprim, MGA_WA_TRIANGLES );
+   }
+}
+
+static void mgaRenderFinish( GLcontext *ctx )
+{
+   if (MGA_CONTEXT(ctx)->RenderIndex & MGA_FALLBACK_BIT)
+      _swrast_flush( ctx );
+}
+
+
+
+/**********************************************************************/
+/*               Manage total rasterization fallbacks                 */
+/**********************************************************************/
+
+void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLuint oldfallback = mmesa->Fallback;
+
+   if (mode) {
+      mmesa->Fallback |= bit;
+      if (oldfallback == 0) {
+        FLUSH_BATCH(mmesa);
+        _swsetup_Wakeup( ctx );
+        mmesa->RenderIndex = ~0;
+      }
+   }
+   else {
+      mmesa->Fallback &= ~bit;
+      if (oldfallback == bit) {
+        _swrast_flush( ctx );
+        tnl->Driver.Render.Start = mgaCheckTexSizes;
+        tnl->Driver.Render.PrimitiveNotify = mgaRenderPrimitive;
+        tnl->Driver.Render.Finish = mgaRenderFinish;
+        tnl->Driver.Render.BuildVertices = mgaBuildVertices;
+        mmesa->new_gl_state |= (_MGA_NEW_RENDERSTATE |
+                                _MGA_NEW_RASTERSETUP);
+      }
+   }
+}
+
+
+void mgaDDInitTriFuncs( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   static int firsttime = 1;
+   if (firsttime) {
+      init_rast_tab();
+      firsttime = 0;
+   }
+
+   mmesa->RenderIndex = ~0;
+       
+   tnl->Driver.RunPipeline               = mgaRunPipeline;
+   tnl->Driver.Render.Start              = mgaCheckTexSizes;
+   tnl->Driver.Render.Finish             = mgaRenderFinish; 
+   tnl->Driver.Render.PrimitiveNotify    = mgaRenderPrimitive;
+   tnl->Driver.Render.ResetLineStipple   = _swrast_ResetLineStipple;
+   tnl->Driver.Render.BuildVertices      = mgaBuildVertices;
+   tnl->Driver.Render.Multipass                 = NULL;
+}
diff --git a/src/mesa/drivers/dri/mga/mgatris.h b/src/mesa/drivers/dri/mga/mgatris.h
new file mode 100644 (file)
index 0000000..88eda91
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.h,v 1.10 2002/10/30 12:51:36 alanh Exp $ */
+
+#ifndef MGATRIS_INC
+#define MGATRIS_INC
+
+#include "mtypes.h"
+
+extern void mgaDDInitTriFuncs( GLcontext *ctx );
+
+extern void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim );
+
+extern void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
+#define FALLBACK( ctx, bit, mode ) mgaFallback( ctx, bit, mode )
+
+
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/mgavb.c b/src/mesa/drivers/dri/mga/mgavb.c
new file mode 100644 (file)
index 0000000..d354fa4
--- /dev/null
@@ -0,0 +1,497 @@
+/*
+ * 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>
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.15 2003/03/26 20:43:49 tsi Exp $ */
+
+#include "mgacontext.h"
+#include "mgavb.h"
+#include "mgatris.h"
+#include "mgaioctl.h"
+#include "mga_xmesa.h"
+
+#include "glheader.h"
+#include "mtypes.h"
+/*#include "mem.h" */
+#include "macros.h"
+#include "colormac.h"
+/*#include "mmath.h"*/
+
+#include "tnl/t_context.h"
+#include "swrast_setup/swrast_setup.h"
+#include "swrast/swrast.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#define MGA_TEX1_BIT       0x1
+#define MGA_TEX0_BIT       0x2 
+#define MGA_RGBA_BIT       0x4
+#define MGA_SPEC_BIT       0x8
+#define MGA_FOG_BIT       0x10
+#define MGA_XYZW_BIT       0x20
+#define MGA_PTEX_BIT       0x40
+#define MGA_MAX_SETUP      0x80
+
+static struct {
+   void                (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
+   interp_func         interp;
+   copy_pv_func                copy_pv;
+   GLboolean           (*check_tex_sizes)( GLcontext *ctx );
+   GLuint               vertex_size;
+   GLuint               vertex_stride_shift;
+   GLuint               vertex_format;
+} setup_tab[MGA_MAX_SETUP];
+
+
+#define TINY_VERTEX_FORMAT      0
+#define NOTEX_VERTEX_FORMAT     0
+#define TEX0_VERTEX_FORMAT      (MGA_A|MGA_S|MGA_F)
+#define TEX1_VERTEX_FORMAT      (MGA_A|MGA_S|MGA_F|MGA_T2)
+#define PROJ_TEX1_VERTEX_FORMAT 0
+#define TEX2_VERTEX_FORMAT      0
+#define TEX3_VERTEX_FORMAT      0
+#define PROJ_TEX3_VERTEX_FORMAT 0
+
+#define DO_XYZW (IND & MGA_XYZW_BIT)
+#define DO_RGBA (IND & MGA_RGBA_BIT)
+#define DO_SPEC (IND & MGA_SPEC_BIT)
+#define DO_FOG  (IND & MGA_FOG_BIT)
+#define DO_TEX0 (IND & MGA_TEX0_BIT)
+#define DO_TEX1 (IND & MGA_TEX1_BIT)
+#define DO_TEX2 0
+#define DO_TEX3 0
+#define DO_PTEX (IND & MGA_PTEX_BIT)
+
+                              
+#define VERTEX mgaVertex
+#define VERTEX_COLOR mga_color_t
+#define LOCALVARS mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+#define GET_VIEWPORT_MAT() mmesa->hw_viewport
+#define GET_TEXSOURCE(n)  mmesa->tmu_source[n]
+#define GET_VERTEX_FORMAT() mmesa->vertex_format
+#define GET_VERTEX_STORE() ((GLubyte *)mmesa->verts)
+#define GET_VERTEX_STRIDE_SHIFT() mmesa->vertex_stride_shift
+#define GET_UBYTE_COLOR_STORE() &mmesa->UbyteColor
+#define GET_UBYTE_SPEC_COLOR_STORE() &mmesa->UbyteSecondaryColor
+
+#define HAVE_HW_VIEWPORT    0
+#define HAVE_HW_DIVIDE      0
+#define HAVE_RGBA_COLOR     0
+#define HAVE_TINY_VERTICES  0
+#define HAVE_NOTEX_VERTICES 0
+#define HAVE_TEX0_VERTICES  1
+#define HAVE_TEX1_VERTICES  1
+#define HAVE_TEX2_VERTICES  0
+#define HAVE_TEX3_VERTICES  0
+#define HAVE_PTEX_VERTICES  0
+
+#define UNVIEWPORT_VARS                                        \
+   const GLfloat dx = - mmesa->drawX - SUBPIXEL_X;     \
+   const GLfloat dy = (mmesa->driDrawable->h +                 \
+                      mmesa->drawY + SUBPIXEL_Y);      \
+   const GLfloat sz = 1.0 / mmesa->depth_scale
+
+#define UNVIEWPORT_X(x)    x      + dx;
+#define UNVIEWPORT_Y(y)  - y      + dy;
+#define UNVIEWPORT_Z(z)    z * sz;
+
+#define PTEX_FALLBACK() FALLBACK(ctx, MGA_FALLBACK_TEXTURE, 1)
+
+
+#define IMPORT_FLOAT_COLORS mga_import_float_colors
+#define IMPORT_FLOAT_SPEC_COLORS mga_import_float_spec_colors
+
+#define INTERP_VERTEX setup_tab[MGA_CONTEXT(ctx)->SetupIndex].interp
+#define COPY_PV_VERTEX setup_tab[MGA_CONTEXT(ctx)->SetupIndex].copy_pv
+
+
+/***********************************************************************
+ *         Generate  pv-copying and translation functions              *
+ ***********************************************************************/
+
+#define TAG(x) mga_##x
+#include "tnl_dd/t_dd_vb.c"
+
+/***********************************************************************
+ *             Generate vertex emit and interp functions               *
+ ***********************************************************************/
+
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT)
+#define TAG(x) x##_wg
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT)
+#define TAG(x) x##_wgs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_wgt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_wgt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT)
+#define TAG(x) x##_wgpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_wgst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_wgst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT)
+#define TAG(x) x##_wgspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT)
+#define TAG(x) x##_wgf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT)
+#define TAG(x) x##_wgfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_wgft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_wgft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT)
+#define TAG(x) x##_wgfpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_wgfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_wgfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_XYZW_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_PTEX_BIT)
+#define TAG(x) x##_wgfspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_TEX0_BIT)
+#define TAG(x) x##_t0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_t0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_FOG_BIT)
+#define TAG(x) x##_f
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_FOG_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_ft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_ft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT)
+#define TAG(x) x##_g
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_SPEC_BIT)
+#define TAG(x) x##_gs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_gt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_gt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_gst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_gst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_FOG_BIT)
+#define TAG(x) x##_gf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT)
+#define TAG(x) x##_gfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_gft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_gft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_gfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_gfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+
+static void init_setup_tab( void )
+{
+   init_wg();
+   init_wgs();
+   init_wgt0();
+   init_wgt0t1();
+   init_wgpt0();
+   init_wgst0();
+   init_wgst0t1();
+   init_wgspt0();
+   init_wgf();
+   init_wgfs();
+   init_wgft0();
+   init_wgft0t1();
+   init_wgfpt0();
+   init_wgfst0();
+   init_wgfst0t1();
+   init_wgfspt0();
+   init_t0();
+   init_t0t1();
+   init_f();
+   init_ft0();
+   init_ft0t1();
+   init_g();
+   init_gs();
+   init_gt0();
+   init_gt0t1();
+   init_gst0();
+   init_gst0t1();
+   init_gf();
+   init_gfs();
+   init_gft0();
+   init_gft0t1();
+   init_gfst0();
+   init_gfst0t1();
+}
+
+
+
+
+void mgaPrintSetupFlags(char *msg, GLuint flags )
+{
+   fprintf(stderr, "%s: %d %s%s%s%s%s%s\n",
+          msg,
+          (int)flags,
+          (flags & MGA_XYZW_BIT)      ? " xyzw," : "", 
+          (flags & MGA_RGBA_BIT)     ? " rgba," : "",
+          (flags & MGA_SPEC_BIT)     ? " spec," : "",
+          (flags & MGA_FOG_BIT)      ? " fog," : "",
+          (flags & MGA_TEX0_BIT)     ? " tex-0," : "",
+          (flags & MGA_TEX1_BIT)     ? " tex-1," : "");
+}
+
+
+void mgaCheckTexSizes( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+   /*fprintf(stderr, "%s\n", __FUNCTION__);*/
+
+   if (!setup_tab[mmesa->SetupIndex].check_tex_sizes(ctx)) {
+      mmesa->SetupIndex |= MGA_PTEX_BIT;
+      mmesa->SetupNewInputs = ~0;
+
+      if (!mmesa->Fallback &&
+         !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+        tnl->Driver.Render.Interp = setup_tab[mmesa->SetupIndex].interp;
+        tnl->Driver.Render.CopyPV = setup_tab[mmesa->SetupIndex].copy_pv;
+      }
+   }
+}
+
+
+void mgaBuildVertices( GLcontext *ctx, 
+                      GLuint start, 
+                      GLuint count,
+                      GLuint newinputs )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   GLubyte *v = ((GLubyte *)mmesa->verts + (start<<mmesa->vertex_stride_shift));
+   GLuint stride = 1<<mmesa->vertex_stride_shift;
+
+   newinputs |= mmesa->SetupNewInputs;
+   mmesa->SetupNewInputs = 0;
+
+   if (!newinputs)
+      return;
+
+   if (newinputs & VERT_BIT_CLIP) {
+      setup_tab[mmesa->SetupIndex].emit( ctx, start, count, v, stride );   
+   } else {
+      GLuint ind = 0;
+
+      if (newinputs & VERT_BIT_COLOR0)
+        ind |= MGA_RGBA_BIT;
+      
+      if (newinputs & VERT_BIT_COLOR1)
+        ind |= MGA_SPEC_BIT;
+
+      if (newinputs & VERT_BIT_TEX0) 
+        ind |= MGA_TEX0_BIT;
+
+      if (newinputs & VERT_BIT_TEX1)
+        ind |= MGA_TEX0_BIT|MGA_TEX1_BIT;
+
+      if (newinputs & VERT_BIT_FOG)
+        ind |= MGA_FOG_BIT;
+
+      if (mmesa->SetupIndex & MGA_PTEX_BIT)
+        ind = ~0;
+
+      ind &= mmesa->SetupIndex;
+
+      if (ind) {
+        setup_tab[ind].emit( ctx, start, count, v, stride );   
+      }
+   }
+}
+
+
+void mgaChooseVertexState( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint ind = MGA_XYZW_BIT|MGA_RGBA_BIT;
+
+   if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) 
+      ind |= MGA_SPEC_BIT;
+
+   if (ctx->Fog.Enabled) 
+      ind |= MGA_FOG_BIT;
+   
+   if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
+      if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
+        ind |= MGA_TEX1_BIT|MGA_TEX0_BIT;
+      }
+      else {
+        ind |= MGA_TEX0_BIT;
+      }
+   }
+   else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
+      ind |= MGA_TEX0_BIT;
+   }
+   
+   mmesa->SetupIndex = ind;
+
+   if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
+      tnl->Driver.Render.Interp = mga_interp_extras;
+      tnl->Driver.Render.CopyPV = mga_copy_pv_extras;
+   } else {
+      tnl->Driver.Render.Interp = setup_tab[ind].interp;
+      tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
+   }
+
+   if (setup_tab[ind].vertex_format != mmesa->vertex_format) {
+      FLUSH_BATCH(mmesa);      
+      mmesa->new_state |= MGA_NEW_WARP;
+      mmesa->dirty |= MGA_UPLOAD_PIPE;
+      mmesa->vertex_format = setup_tab[ind].vertex_format;
+      mmesa->vertex_size = setup_tab[ind].vertex_size;
+      mmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
+   }
+}
+
+
+
+void mga_emit_contiguous_verts( GLcontext *ctx,
+                                GLuint start,
+                                GLuint count )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLuint vertex_size = mmesa->vertex_size * 4;
+   GLuint *dest = mgaAllocDmaLow( mmesa, (count-start) * vertex_size);
+   setup_tab[mmesa->SetupIndex].emit( ctx, start, count, dest, vertex_size );
+}
+                                  
+
+
+void mgaInitVB( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   GLuint size = TNL_CONTEXT(ctx)->vb.Size;
+
+   mmesa->verts = (char *)ALIGN_MALLOC(size * sizeof(mgaVertex), 32);
+
+   {
+      static int firsttime = 1;
+      if (firsttime) {
+        init_setup_tab();
+        firsttime = 0;
+      }
+   }
+
+   mmesa->new_state |= MGA_NEW_WARP;
+   mmesa->dirty |= MGA_UPLOAD_PIPE;
+   mmesa->vertex_format = setup_tab[0].vertex_format;
+   mmesa->vertex_size = setup_tab[0].vertex_size;
+   mmesa->vertex_stride_shift = setup_tab[0].vertex_stride_shift;
+}
+
+
+void mgaFreeVB( GLcontext *ctx )
+{
+   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   if (mmesa->verts) {
+      ALIGN_FREE(mmesa->verts);
+      mmesa->verts = 0;
+   }
+
+   if (mmesa->UbyteSecondaryColor.Ptr) {
+      ALIGN_FREE(mmesa->UbyteSecondaryColor.Ptr);
+      mmesa->UbyteSecondaryColor.Ptr = 0;
+   }
+
+   if (mmesa->UbyteColor.Ptr) {
+      ALIGN_FREE(mmesa->UbyteColor.Ptr);
+      mmesa->UbyteColor.Ptr = 0;
+   }
+}
+
diff --git a/src/mesa/drivers/dri/mga/mgavb.h b/src/mesa/drivers/dri/mga/mgavb.h
new file mode 100644 (file)
index 0000000..88cc310
--- /dev/null
@@ -0,0 +1,65 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.h,v 1.8 2002/10/30 12:51:36 alanh Exp $ */
+/*
+ * 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>
+ */
+
+#ifndef MGAVB_INC
+#define MGAVB_INC
+
+#include "mtypes.h"
+#include "mgacontext.h"
+#include "swrast/swrast.h"
+
+#define _MGA_NEW_RASTERSETUP (_NEW_TEXTURE |                   \
+                             _DD_NEW_SEPARATE_SPECULAR |       \
+                             _DD_NEW_TRI_UNFILLED |            \
+                             _DD_NEW_TRI_LIGHT_TWOSIDE |       \
+                             _NEW_FOG)
+
+
+extern void mgaChooseVertexState( GLcontext *ctx );
+extern void mgaCheckTexSizes( GLcontext *ctx );
+extern void mgaBuildVertices( GLcontext *ctx, 
+                             GLuint start, 
+                             GLuint count,
+                             GLuint newinputs );
+
+extern void mgaPrintSetupFlags(char *msg, GLuint flags );
+
+extern void mgaInitVB( GLcontext *ctx );
+extern void mgaFreeVB( GLcontext *ctx );
+
+extern void mga_emit_contiguous_verts( GLcontext *ctx,
+                                       GLuint start,
+                                       GLuint count );
+
+extern void mga_translate_vertex(GLcontext *ctx, 
+                                const mgaVertex *src, 
+                                SWvertex *dst);
+
+extern void mga_print_vertex( GLcontext *ctx, const mgaVertex *v );
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/server/mga.h b/src/mesa/drivers/dri/mga/server/mga.h
new file mode 100644 (file)
index 0000000..830d48d
--- /dev/null
@@ -0,0 +1,115 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.85 2002/12/16 16:19:17 dawes Exp $ */
+/*
+ * MGA Millennium (MGA2064W) functions
+ *
+ * Copyright 1996 The XFree86 Project, Inc.
+ *
+ * Authors
+ *             Dirk Hohndel
+ *                     hohndel@XFree86.Org
+ *             David Dawes
+ *                     dawes@XFree86.Org
+ */
+
+#ifndef MGA_H
+#define MGA_H
+
+
+#include "xf86drm.h"
+#include "linux/types.h"
+
+
+#define PCI_CHIP_MGA2085               0x0518
+#define PCI_CHIP_MGA2064               0x0519
+#define PCI_CHIP_MGA1064               0x051A
+#define PCI_CHIP_MGA2164               0x051B
+#define PCI_CHIP_MGA2164_AGP           0x051F
+#define PCI_CHIP_MGAG200_PCI           0x0520
+#define PCI_CHIP_MGAG200               0x0521
+#define PCI_CHIP_MGAG400               0x0525
+#define PCI_CHIP_MGAG550               0x2527
+#define PCI_CHIP_MGAG100_PCI           0x1000
+#define PCI_CHIP_MGAG100               0x1001
+
+
+#  define MMIO_IN8(base, offset) \
+       *(volatile unsigned char *)(((unsigned char*)(base)) + (offset))
+#  define MMIO_IN16(base, offset) \
+       *(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset))
+#  define MMIO_IN32(base, offset) \
+       *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset))
+#  define MMIO_OUT8(base, offset, val) \
+       *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val)
+#  define MMIO_OUT16(base, offset, val) \
+       *(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset)) = (val)
+#  define MMIO_OUT32(base, offset, val) \
+       *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = (val)
+
+#define INREG8(addr) MMIO_IN8(pMga->IOBase, addr)
+#define INREG16(addr) MMIO_IN16(pMga->IOBase, addr)
+#define INREG(addr) MMIO_IN32(pMga->IOBase, addr)
+#define OUTREG8(addr, val) MMIO_OUT8(pMga->IOBase, addr, val)
+#define OUTREG16(addr, val) MMIO_OUT16(pMga->IOBase, addr, val)
+#define OUTREG(addr, val) MMIO_OUT32(pMga->IOBase, addr, val)
+
+#define MGAIOMAPSIZE           0x00004000
+
+
+typedef struct {
+  int               Chipset;          /**< \brief Chipset number */
+
+  int               irq;              /**< \brief IRQ number */
+
+
+  int               frontOffset;      /**< \brief Front color buffer offset */
+  int               frontPitch;       /**< \brief Front color buffer pitch */
+  int               backOffset;       /**< \brief Back color buffer offset */
+  int               backPitch;        /**< \brief Back color buffer pitch */
+  int               depthOffset;      /**< \brief Depth buffer offset */
+  int               depthPitch;       /**< \brief Depth buffer pitch */
+  int               textureOffset;    /**< \brief Texture area offset */
+  int               textureSize;      /**< \brief Texture area size */
+  int               logTextureGranularity;
+
+  /**
+   * \name AGP
+   */
+  /*@{*/
+  drmSize           agpSize;          /**< \brief AGP map size */
+  int               agpMode;          /**< \brief AGP mode */
+  /*@}*/
+
+  drmRegion         agp;
+
+  /* PCI mappings */
+  drmRegion         registers;
+  drmRegion         status;
+
+  /* AGP mappings */
+  drmRegion         warp;
+  drmRegion         primary;
+  drmRegion         buffers;
+  drmRegion         agpTextures;
+
+  drmBufMapPtr      drmBuffers;
+
+  unsigned long     IOAddress;
+  unsigned char    *IOBase;
+  int              HasSDRAM;
+
+  __u32             reg_ien;
+} MGARec, *MGAPtr;
+
+
+
+#define MGA_FRONT      0x1
+#define MGA_BACK       0x2
+#define MGA_DEPTH      0x4
+
+#define MGA_AGP_1X_MODE                0x01
+#define MGA_AGP_2X_MODE                0x02
+#define MGA_AGP_4X_MODE                0x04
+#define MGA_AGP_MODE_MASK      0x07
+
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/server/mga_bios.h b/src/mesa/drivers/dri/mga/server/mga_bios.h
new file mode 100644 (file)
index 0000000..8fbf619
--- /dev/null
@@ -0,0 +1,143 @@
+/* $XConsortium: mga_bios.h /main/2 1996/10/28 04:48:23 kaleb $ */
+#ifndef MGA_BIOS_H
+#define MGA_BIOS_H
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_bios.h,v 1.3 1998/07/25 16:55:51 dawes Exp $ */
+
+/*
+ * MGABiosInfo - This struct describes the video BIOS info block.
+ *
+ * DESCRIPTION
+ *   Do not mess with this, unless you know what you are doing.
+ *   The data lengths and types are critical.
+ *
+ * HISTORY
+ *   October 7, 1996 - [aem] Andrew E. Mileski
+ *   This struct was shamelessly stolen from the MGA DDK.
+ *   It has been reformatted, and the data types changed.
+ */
+typedef struct {
+       /* Length of this structure in bytes */
+       __u16 StructLen;
+
+       /*
+        * Unique number identifying the product type
+        * 0 : MGA-S1P20 (2MB base with 175MHz Ramdac)
+        * 1 : MGA-S1P21 (2MB base with 220MHz Ramdac)
+        * 2 : Reserved
+        * 3 : Reserved
+        * 4 : MGA-S1P40 (4MB base with 175MHz Ramdac)
+        * 5 : MGA-S1P41 (4MB base with 220MHz Ramdac)
+        */
+       __u16 ProductID;
+
+       /* Serial number of the board */
+       __u8 SerNo[ 10 ];
+
+       /*
+        * Manufacturing date of the board (at product test)
+        * Format: yyyy yyym mmmd dddd
+        */
+       __u16 ManufDate;
+
+       /* Identification of manufacturing site */
+       __u16 ManufId;
+
+       /*
+        * Number and revision level of the PCB
+        * Format: nnnn nnnn nnnr rrrr
+        *         n = PCB number ex:576 (from 0->2047)
+        *         r = PCB revision      (from 0->31)
+        */
+       __u16 PCBInfo;
+
+       /* Identification of any PMBs */
+       __u16 PMBInfo;
+
+       /*
+        * Bit  0-7  : Ramdac speed (0=175MHz, 1=220MHz)
+        * Bit  8-15 : Ramdac type  (0=TVP3026, 1=TVP3027)
+        */
+       __u16 RamdacType;
+
+       /* Maximum PCLK of the ramdac */
+       __u16 PclkMax;
+
+       /* Maximum LDCLK supported by the WRAM memory */
+       __u16 LclkMax;
+
+       /* Maximum MCLK of base board */
+       __u16 ClkBase;
+
+       /* Maximum MCLK of 4Mb board */
+       __u16 Clk4MB;
+
+       /* Maximum MCLK of 8Mb board */
+       __u16 Clk8MB;
+
+       /* Maximum MCLK of board with multimedia module */
+       __u16 ClkMod;
+
+       /* Diagnostic test pass frequency */
+       __u16 TestClk;
+
+       /* Default VGA mode1 pixel frequency */
+       __u16 VGAFreq1;
+
+       /* Default VGA mode2 pixel frequency */
+       __u16 VGAFreq2;
+
+       /* Date of last BIOS programming/update */
+       __u16 ProgramDate;
+
+       /* Number of times BIOS has been programmed */
+       __u16 ProgramCnt;
+
+       /* Support for up to 32 hardware/software options */
+       __u32 Options;
+
+       /* Support for up to 32 hardware/software features */
+       __u32 FeatFlag;
+
+       /* Definition of VGA mode MCLK */
+       __u16 VGAClk;
+
+       /* Indicate the revision level of this header struct */
+       __u16 StructRev;
+
+       __u16 Reserved[ 3 ];
+} MGABiosInfo;
+
+/* from the PINS structure, refer pins info from MGA */
+typedef struct tagParamMGA {
+       __u16   PinID;          /* 0 */
+       __u8    StructLen;      /* 2 */
+       __u8    Rsvd1;          /* 3 */
+       __u16   StructRev;      /* 4 */
+       __u16   ProgramDate;    /* 6 */
+       __u16   ProgramCnt;     /* 8 */
+       __u16   ProductID;      /* 10 */
+       __u8    SerNo[16];      /* 12 */
+       __u8    PLInfo[6];      /* 28 */
+       __u16   PCBInfo;        /* 34 */
+       __u32   FeatFlag;       /* 36 */
+       __u8    RamdacType;     /* 40 */
+       __u8    RamdacSpeed;    /* 41 */
+       __u8    PclkMax;        /* 42 */
+       __u8    ClkGE;          /* 43 */
+       __u8   ClkMem;          /* 44 */
+       __u8    Clk4MB;         /* 45 */
+       __u8    Clk8MB;         /* 46 */
+       __u8    ClkMod;         /* 47 */
+       __u8    TestClk;        /* 48 */
+       __u8    VGAFreq1;       /* 49 */
+       __u8    VGAFreq2;       /* 50 */
+       __u8    MCTLWTST;       /* 51 */
+       __u8    VidCtrl;        /* 52 */
+       __u8    Clk12MB;        /* 53 */
+       __u8    Clk16MB;        /* 54 */
+       __u8    Reserved[8];    /* 55-62 */
+       __u8    PinCheck;       /* 63 */
+}      MGABios2Info;
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/server/mga_common.h b/src/mesa/drivers/dri/mga/server/mga_common.h
new file mode 100644 (file)
index 0000000..90f6b37
--- /dev/null
@@ -0,0 +1,152 @@
+/* mga_common.h -- common header definitions for MGA 2D/3D/DRM suite
+ *
+ * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT 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.
+ *
+ * Converted to common header format:
+ *   Jens Owen <jens@tungstengraphics.com>
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_common.h,v 1.2 2002/12/16 16:19:18 dawes Exp $
+ *
+ */
+
+#ifndef _MGA_COMMON_H_
+#define _MGA_COMMON_H_
+
+/*
+ * WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (mga_drm.h)
+ */
+
+#define  DRM_MGA_IDLE_RETRY          2048
+#define  DRM_MGA_NR_TEX_HEAPS        2
+
+typedef struct {
+   int installed;
+   unsigned long phys_addr;
+   int size;
+} drmMGAWarpIndex;
+
+/* Driver specific DRM command indices
+ * NOTE: these are not OS specific, but they are driver specific
+ */
+#define DRM_MGA_INIT              0x00
+#define DRM_MGA_FLUSH             0x01
+#define DRM_MGA_RESET             0x02
+#define DRM_MGA_SWAP              0x03
+#define DRM_MGA_CLEAR             0x04
+#define DRM_MGA_VERTEX            0x05
+#define DRM_MGA_INDICES           0x06
+#define DRM_MGA_ILOAD             0x07
+#define DRM_MGA_BLIT              0x08
+#define DRM_MGA_GETPARAM          0x09
+
+typedef struct {
+   enum {
+      MGA_INIT_DMA    = 0x01,
+      MGA_CLEANUP_DMA = 0x02
+   } func;
+
+   unsigned long sarea_priv_offset;
+
+   int chipset;
+   int sgram;
+
+   unsigned int maccess;
+
+   unsigned int fb_cpp;
+   unsigned int front_offset, front_pitch;
+   unsigned int back_offset, back_pitch;
+
+   unsigned int depth_cpp;
+   unsigned int depth_offset, depth_pitch;
+
+   unsigned int texture_offset[DRM_MGA_NR_TEX_HEAPS];
+   unsigned int texture_size[DRM_MGA_NR_TEX_HEAPS];
+
+   unsigned long fb_offset;
+   unsigned long mmio_offset;
+   unsigned long status_offset;
+   unsigned long warp_offset;
+   unsigned long primary_offset;
+   unsigned long buffers_offset;
+} drmMGAInit;
+
+typedef enum {
+   DRM_MGA_LOCK_READY      = 0x01, /* Wait until hardware is ready for DMA */
+   DRM_MGA_LOCK_QUIESCENT  = 0x02, /* Wait until hardware quiescent        */
+   DRM_MGA_LOCK_FLUSH      = 0x04, /* Flush this context's DMA queue first */
+   DRM_MGA_LOCK_FLUSH_ALL  = 0x08, /* Flush all DMA queues first           */
+                                   /* These *HALT* flags aren't supported yet
+                                      -- they will be used to support the
+                                         full-screen DGA-like mode.        */
+   DRM_MGA_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues   */
+   DRM_MGA_HALT_CUR_QUEUES = 0x20  /* Halt all current queues              */
+} drmMGALockFlags;
+
+typedef struct {
+   int             context;
+   drmMGALockFlags flags;
+} drmMGALock;
+
+typedef struct {
+   int idx;
+   unsigned int dstorg;
+   unsigned int length;
+} drmMGAIload;
+
+typedef struct {
+   unsigned int flags;
+   unsigned int clear_color;
+   unsigned int clear_depth;
+   unsigned int color_mask;
+   unsigned int depth_mask;
+} drmMGAClearRec;
+
+typedef struct {
+   int idx;                        /* buffer to queue */
+   int used;                       /* bytes in use */
+   int discard;                    /* client finished with buffer?  */
+} drmMGAVertex;
+
+typedef struct {
+        unsigned int planemask;
+        unsigned int srcorg;
+        unsigned int dstorg;
+        int src_pitch, dst_pitch;
+        int delta_sx, delta_sy;
+        int delta_dx, delta_dy;
+        int height, ydir;               /* flip image vertically */
+        int source_pitch, dest_pitch;
+} drmMGABlit;
+
+/* 3.1: An ioctl to get parameters that aren't available to the 3d
+ * client any other way.  
+ */
+#define MGA_PARAM_IRQ_NR            1
+
+typedef struct {
+       int param;
+       int *value;
+} drmMGAGetParam;
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/server/mga_dri.c b/src/mesa/drivers/dri/mga/server/mga_dri.c
new file mode 100644 (file)
index 0000000..19ddb38
--- /dev/null
@@ -0,0 +1,1136 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.28 2003/02/08 21:26:58 dawes Exp $ */
+
+/*
+ * Copyright 2000 VA Linux Systems Inc., Fremont, California.
+ * 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * 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 NONINFRINGEMENT.  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>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "driver.h"
+#include "drm.h"
+
+#include "mga_reg.h"
+#include "mga.h"
+#include "mga_macros.h"
+#include "mga_dri.h"
+#include "mga_sarea.h"
+
+#include "sarea.h"
+
+
+
+/* Quiescence, locking
+ */
+#define MGA_TIMEOUT            2048
+
+static void MGAWaitForIdleDMA( struct DRIDriverContextRec *ctx, MGAPtr pMga )
+{
+   drmMGALock lock;
+   int ret;
+   int i = 0;
+
+   memset( &lock, 0, sizeof(drmMGALock) );
+
+   for (;;) {
+      do {
+         /* first ask for quiescent and flush */
+         lock.flags = DRM_MGA_LOCK_QUIESCENT | DRM_MGA_LOCK_FLUSH;
+         do {
+           ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH,
+                                   &lock, sizeof( drmMGALock ) );
+         } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );
+
+         /* if it's still busy just try quiescent */
+         if ( ret == -EBUSY ) { 
+            lock.flags = DRM_MGA_LOCK_QUIESCENT;
+            do {
+              ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH,
+                                      &lock, sizeof( drmMGALock ) );
+            } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );
+         }
+      } while ( ( ret == -EBUSY ) && ( i++ < MGA_TIMEOUT ) );
+
+      if ( ret == 0 )
+        return;
+
+      fprintf( stderr,
+               "[dri] Idle timed out, resetting engine...\n" );
+
+      drmCommandNone( ctx->drmFD, DRM_MGA_RESET );
+   }
+}
+
+static unsigned int mylog2( unsigned int n )
+{
+   unsigned int log2 = 1;
+   while ( n > 1 ) n >>= 1, log2++;
+   return log2;
+}
+
+static int MGADRIAgpInit(struct DRIDriverContextRec *ctx, MGAPtr pMga)
+{
+   unsigned long mode;
+   unsigned int vendor, device;
+   int ret, count, i;
+
+   if(pMga->agpSize < 12)pMga->agpSize = 12;
+   if(pMga->agpSize > 64)pMga->agpSize = 64; /* cap */
+
+   /* FIXME: Make these configurable...
+    */
+   pMga->agp.size = pMga->agpSize * 1024 * 1024;
+
+   pMga->warp.offset = 0;
+   pMga->warp.size = MGA_WARP_UCODE_SIZE;
+
+   pMga->primary.offset = (pMga->warp.offset +
+                                   pMga->warp.size);
+   pMga->primary.size = 1024 * 1024;
+
+   pMga->buffers.offset = (pMga->primary.offset +
+                                   pMga->primary.size);
+   pMga->buffers.size = MGA_NUM_BUFFERS * MGA_BUFFER_SIZE;
+
+
+   pMga->agpTextures.offset = (pMga->buffers.offset +
+                                    pMga->buffers.size);
+
+   pMga->agpTextures.size = pMga->agp.size -
+                                     pMga->agpTextures.offset;
+
+   if ( drmAgpAcquire( ctx->drmFD ) < 0 ) {
+     fprintf( stderr, "[agp] AGP not available\n" );
+      return 0;
+   }
+
+   mode   = drmAgpGetMode( ctx->drmFD );        /* Default mode */
+   vendor = drmAgpVendorId( ctx->drmFD );
+   device = drmAgpDeviceId( ctx->drmFD );
+
+   mode &= ~MGA_AGP_MODE_MASK;
+   switch ( pMga->agpMode ) {
+   case 4:
+      mode |= MGA_AGP_4X_MODE;
+   case 2:
+      mode |= MGA_AGP_2X_MODE;
+   case 1:
+   default:
+      mode |= MGA_AGP_1X_MODE;
+   }
+
+#if 0
+   fprintf( stderr,
+            "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
+            mode, vendor, device,
+            ctx->pciVendor,
+            ctx->pciChipType );
+#endif
+
+   if ( drmAgpEnable( ctx->drmFD, mode ) < 0 ) {
+     fprintf( stderr, "[agp] AGP not enabled\n" );
+      drmAgpRelease( ctx->drmFD );
+      return 0;
+   }
+
+   if ( pMga->Chipset == PCI_CHIP_MGAG200 ) {
+      switch ( pMga->agpMode ) {
+      case 2:
+        fprintf( stderr,
+                    "[drm] Enabling AGP 2x PLL encoding\n" );
+        OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_ENABLE );
+        break;
+
+      case 1:
+      default:
+        fprintf( stderr,
+                    "[drm] Disabling AGP 2x PLL encoding\n" );
+        OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_DISABLE );
+        pMga->agpMode = 1;
+        break;
+      }
+   }
+
+   ret = drmAgpAlloc( ctx->drmFD, pMga->agp.size,
+                     0, NULL, &pMga->agp.handle );
+   if ( ret < 0 ) {
+      fprintf( stderr, "[agp] Out of memory (%d)\n", ret );
+      drmAgpRelease( ctx->drmFD );
+      return 0;
+   }
+   fprintf( stderr,
+              "[agp] %d kB allocated with handle 0x%08x\n",
+              pMga->agp.size/1024, (unsigned int)pMga->agp.handle );
+
+   if ( drmAgpBind( ctx->drmFD, pMga->agp.handle, 0 ) < 0 ) {
+      fprintf( stderr, "[agp] Could not bind memory\n" );
+      drmAgpFree( ctx->drmFD, pMga->agp.handle );
+      drmAgpRelease( ctx->drmFD );
+      return 0;
+   }
+
+   /* WARP microcode space
+    */
+   if ( drmAddMap( ctx->drmFD,
+                  pMga->warp.offset,
+                  pMga->warp.size,
+                  DRM_AGP, DRM_READ_ONLY,
+                  &pMga->warp.handle ) < 0 ) {
+      fprintf( stderr,
+                 "[agp] Could not add WARP microcode mapping\n" );
+      return 0;
+   }
+   fprintf( stderr,
+              "[agp] WARP microcode handle = 0x%08lx\n",
+              pMga->warp.handle );
+
+   if ( drmMap( ctx->drmFD,
+               pMga->warp.handle,
+               pMga->warp.size,
+               &pMga->warp.map ) < 0 ) {
+      fprintf( stderr,
+                 "[agp] Could not map WARP microcode\n" );
+      return 0;
+   }
+   fprintf( stderr,
+              "[agp] WARP microcode mapped at 0x%08lx\n",
+              (unsigned long)pMga->warp.map );
+
+   /* Primary DMA space
+    */
+   if ( drmAddMap( ctx->drmFD,
+                  pMga->primary.offset,
+                  pMga->primary.size,
+                  DRM_AGP, DRM_READ_ONLY,
+                  &pMga->primary.handle ) < 0 ) {
+      fprintf( stderr,
+                 "[agp] Could not add primary DMA mapping\n" );
+      return 0;
+   }
+   fprintf( stderr,
+              "[agp] Primary DMA handle = 0x%08lx\n",
+              pMga->primary.handle );
+
+   if ( drmMap( ctx->drmFD,
+               pMga->primary.handle,
+               pMga->primary.size,
+               &pMga->primary.map ) < 0 ) {
+      fprintf( stderr,
+                 "[agp] Could not map primary DMA\n" );
+      return 0;
+   }
+   fprintf( stderr,
+              "[agp] Primary DMA mapped at 0x%08lx\n",
+              (unsigned long)pMga->primary.map );
+
+   /* DMA buffers
+    */
+   if ( drmAddMap( ctx->drmFD,
+                  pMga->buffers.offset,
+                  pMga->buffers.size,
+                  DRM_AGP, 0,
+                  &pMga->buffers.handle ) < 0 ) {
+      fprintf( stderr,
+                 "[agp] Could not add DMA buffers mapping\n" );
+      return 0;
+   }
+   fprintf( stderr,
+              "[agp] DMA buffers handle = 0x%08lx\n",
+              pMga->buffers.handle );
+
+   if ( drmMap( ctx->drmFD,
+               pMga->buffers.handle,
+               pMga->buffers.size,
+               &pMga->buffers.map ) < 0 ) {
+      fprintf( stderr,
+                 "[agp] Could not map DMA buffers\n" );
+      return 0;
+   }
+   fprintf( stderr,
+              "[agp] DMA buffers mapped at 0x%08lx\n",
+              (unsigned long)pMga->buffers.map );
+
+   count = drmAddBufs( ctx->drmFD,
+                      MGA_NUM_BUFFERS, MGA_BUFFER_SIZE,
+                      DRM_AGP_BUFFER, pMga->buffers.offset );
+   if ( count <= 0 ) {
+      fprintf( stderr,
+                 "[drm] failure adding %d %d byte DMA buffers\n",
+                 MGA_NUM_BUFFERS, MGA_BUFFER_SIZE );
+      return 0;
+   }
+   fprintf( stderr,
+              "[drm] Added %d %d byte DMA buffers\n",
+              count, MGA_BUFFER_SIZE );
+
+   i = mylog2(pMga->agpTextures.size / MGA_NR_TEX_REGIONS);
+   if(i < MGA_LOG_MIN_TEX_REGION_SIZE)
+      i = MGA_LOG_MIN_TEX_REGION_SIZE;
+   pMga->agpTextures.size = (pMga->agpTextures.size >> i) << i;
+
+   if ( drmAddMap( ctx->drmFD,
+                   pMga->agpTextures.offset,
+                   pMga->agpTextures.size,
+                   DRM_AGP, 0,
+                   &pMga->agpTextures.handle ) < 0 ) {
+      fprintf( stderr,
+                  "[agp] Could not add agpTexture mapping\n" );
+      return 0;
+   }
+/* should i map it ? */
+   fprintf( stderr,
+               "[agp] agpTexture handle = 0x%08lx\n",
+               pMga->agpTextures.handle );
+   fprintf( stderr,
+               "[agp] agpTexture size: %d kb\n", pMga->agpTextures.size/1024 );
+
+   return 1;
+}
+
+static int MGADRIMapInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
+{
+   pMga->registers.size = MGAIOMAPSIZE;
+
+   if ( drmAddMap( ctx->drmFD,
+                  (drmHandle)pMga->IOAddress,
+                  pMga->registers.size,
+                  DRM_REGISTERS, DRM_READ_ONLY,
+                  &pMga->registers.handle ) < 0 ) {
+      fprintf( stderr,
+                 "[drm] Could not add MMIO registers mapping\n" );
+      return 0;
+   }
+   fprintf( stderr,
+              "[drm] Registers handle = 0x%08lx\n",
+              pMga->registers.handle );
+
+   pMga->status.size = SAREA_MAX;
+
+   if ( drmAddMap( ctx->drmFD, 0, pMga->status.size,
+                  DRM_SHM, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL,
+                  &pMga->status.handle ) < 0 ) {
+      fprintf( stderr,
+                 "[drm] Could not add status page mapping\n" );
+      return 0;
+   }
+   fprintf( stderr,
+              "[drm] Status handle = 0x%08lx\n",
+              pMga->status.handle );
+
+   if ( drmMap( ctx->drmFD,
+               pMga->status.handle,
+               pMga->status.size,
+               &pMga->status.map ) < 0 ) {
+      fprintf( stderr,
+                 "[agp] Could not map status page\n" );
+      return 0;
+   }
+   fprintf( stderr,
+              "[agp] Status page mapped at 0x%08lx\n",
+              (unsigned long)pMga->status.map );
+
+   return 1;
+}
+
+static int MGADRIKernelInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
+{
+   drmMGAInit init;
+   int ret;
+
+   memset( &init, 0, sizeof(drmMGAInit) );
+
+   init.func = MGA_INIT_DMA;
+   init.sarea_priv_offset = sizeof(XF86DRISAREARec);
+
+   switch ( pMga->Chipset ) {
+   case PCI_CHIP_MGAG550:
+   case PCI_CHIP_MGAG400:
+      init.chipset = MGA_CARD_TYPE_G400;
+      break;
+   case PCI_CHIP_MGAG200:
+   case PCI_CHIP_MGAG200_PCI:
+      init.chipset = MGA_CARD_TYPE_G200;
+      break;
+   default:
+      return 0;
+   }
+
+   init.sgram = 0; /* FIXME !pMga->HasSDRAM; */
+
+
+   switch (ctx->bpp)
+     {
+     case 16:
+       init.maccess = MGA_MACCESS_PW16;
+       break;
+     case 32:
+       init.maccess = MGA_MACCESS_PW32;
+       break;
+     default:
+       fprintf( stderr, "[mga] invalid bpp (%d)\n", ctx->bpp );
+       return 0;
+     }
+
+
+   init.fb_cpp         = ctx->bpp / 8;
+   init.front_offset   = pMga->frontOffset;
+   init.front_pitch    = pMga->frontPitch / init.fb_cpp;
+   init.back_offset    = pMga->backOffset;
+   init.back_pitch     = pMga->backPitch / init.fb_cpp;
+
+   init.depth_cpp      = ctx->bpp / 8;
+   init.depth_offset   = pMga->depthOffset;
+   init.depth_pitch    = pMga->depthPitch / init.depth_cpp;
+
+   init.texture_offset[0] = pMga->textureOffset;
+   init.texture_size[0] = pMga->textureSize;
+
+   init.fb_offset = ctx->shared.hFrameBuffer;
+   init.mmio_offset = pMga->registers.handle;
+   init.status_offset = pMga->status.handle;
+
+   init.warp_offset = pMga->warp.handle;
+   init.primary_offset = pMga->primary.handle;
+   init.buffers_offset = pMga->buffers.handle;
+
+   init.texture_offset[1] = pMga->agpTextures.handle;
+   init.texture_size[1] = pMga->agpTextures.size;
+
+   ret = drmCommandWrite( ctx->drmFD, DRM_MGA_INIT, &init, sizeof(drmMGAInit));
+   if ( ret < 0 ) {
+      fprintf( stderr,
+                 "[drm] Failed to initialize DMA! (%d)\n", ret );
+      return 0;
+   }
+
+   return 1;
+}
+
+static void MGADRIIrqInit(struct DRIDriverContextRec *ctx, MGAPtr pMga)
+{
+  if (!pMga->irq)
+    {
+      pMga->irq = drmGetInterruptFromBusID(ctx->drmFD,
+                                           ctx->pciBus,
+                                           ctx->pciDevice,
+                                           ctx->pciFunc);
+
+      fprintf(stderr, "[drm] got IRQ %d\n", pMga->irq);
+
+    if((drmCtlInstHandler(ctx->drmFD, pMga->irq)) != 0)
+      {
+        fprintf(stderr,
+                "[drm] failure adding irq handler, "
+                "there is a device already using that irq\n"
+                "[drm] falling back to irq-free operation\n");
+        pMga->irq = 0;
+      }
+    else
+      {
+        pMga->reg_ien = INREG( MGAREG_IEN );
+      }
+    }
+
+  if (pMga->irq)
+    fprintf(stderr,
+            "[drm] dma control initialized, using IRQ %d\n",
+            pMga->irq);
+}
+
+static int MGADRIBuffersInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
+{
+   pMga->drmBuffers = drmMapBufs( ctx->drmFD );
+   if ( !pMga->drmBuffers )
+     {
+       fprintf( stderr,
+                "[drm] Failed to map DMA buffers list\n" );
+       return 0;
+     }
+   
+   fprintf( stderr,
+            "[drm] Mapped %d DMA buffers\n",
+            pMga->drmBuffers->count );
+
+   return 1;
+}
+
+static int MGAMemoryInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
+{
+   int        width_bytes = ctx->shared.virtualWidth * ctx->cpp;
+   int        bufferSize  = ((ctx->shared.virtualHeight * width_bytes
+                             + MGA_BUFFER_ALIGN)
+                            & ~MGA_BUFFER_ALIGN);
+   int        depthSize   = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes
+                             + MGA_BUFFER_ALIGN)
+                            & ~MGA_BUFFER_ALIGN);
+   int        l;
+
+   pMga->frontOffset = 0;
+   pMga->frontPitch = ctx->shared.virtualWidth * ctx->cpp;
+
+   fprintf(stderr, 
+          "Using %d MB AGP aperture\n", pMga->agpSize);
+   fprintf(stderr, 
+          "Using %d MB for vertex/indirect buffers\n", pMga->buffers.size>>20);
+   fprintf(stderr, 
+          "Using %d MB for AGP textures\n", pMga->agpTextures.size>>20);
+
+   /* Front, back and depth buffers - everything else texture??
+    */
+   pMga->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize;
+
+   if (pMga->textureSize < 0) 
+      return 0;
+
+   l = mylog2( pMga->textureSize / MGA_NR_TEX_REGIONS );
+   if ( l < MGA_LOG_MIN_TEX_REGION_SIZE )
+      l = MGA_LOG_MIN_TEX_REGION_SIZE;
+
+   /* Round the texture size up to the nearest whole number of
+    * texture regions.  Again, be greedy about this, don't
+    * round down.
+    */
+   pMga->logTextureGranularity = l;
+   pMga->textureSize = (pMga->textureSize >> l) << l;
+
+   /* Set a minimum usable local texture heap size.  This will fit
+    * two 256x256x32bpp textures.
+    */
+   if (pMga->textureSize < 512 * 1024) {
+      pMga->textureOffset = 0;
+      pMga->textureSize = 0;
+   }
+
+   /* Reserve space for textures */
+   pMga->textureOffset = ((ctx->shared.fbSize - pMga->textureSize +
+                          MGA_BUFFER_ALIGN) &
+                         ~MGA_BUFFER_ALIGN);
+
+   /* Reserve space for the shared depth
+    * buffer.
+    */
+   pMga->depthOffset = ((pMga->textureOffset - depthSize +
+                        MGA_BUFFER_ALIGN) &
+                       ~MGA_BUFFER_ALIGN);
+   pMga->depthPitch = ctx->shared.virtualWidth * ctx->cpp;
+
+   pMga->backOffset = ((pMga->depthOffset - bufferSize +
+                       MGA_BUFFER_ALIGN) &
+                        ~MGA_BUFFER_ALIGN);
+   pMga->backPitch = ctx->shared.virtualWidth * ctx->cpp;
+
+
+   fprintf(stderr, 
+          "Will use back buffer at offset 0x%x\n",
+          pMga->backOffset);
+   fprintf(stderr, 
+          "Will use depth buffer at offset 0x%x\n",
+          pMga->depthOffset);
+   fprintf(stderr, 
+          "Will use %d kb for textures at offset 0x%x\n",
+          pMga->textureSize/1024, pMga->textureOffset);
+
+   return 1;
+} 
+
+static int MGACheckDRMVersion( struct DRIDriverContextRec *ctx, MGAPtr pMga )
+{
+  drmVersionPtr version;
+
+  /* Check the MGA DRM version */
+  version = drmGetVersion(ctx->drmFD);
+  if ( version ) {
+    if ( version->version_major != 3 ||
+         version->version_minor < 0 ) {
+            /* incompatible drm version */
+      fprintf( stderr,
+               "[dri] MGADRIScreenInit failed because of a version mismatch.\n"
+               "[dri] mga.o kernel module version is %d.%d.%d but version 3.0.x is needed.\n"
+               "[dri] Disabling DRI.\n",
+               version->version_major,
+               version->version_minor,
+               version->version_patchlevel );
+      drmFreeVersion( version );
+      return 0;
+    }
+    drmFreeVersion( version );
+  }
+
+  return 1;
+}
+
+static void print_client_msg( MGADRIPtr pMGADRI )
+{
+  fprintf( stderr, "chipset:                  %d\n", pMGADRI->chipset );
+
+  fprintf( stderr, "width:                    %d\n", pMGADRI->width );
+  fprintf( stderr, "height:                   %d\n", pMGADRI->height );
+  fprintf( stderr, "mem:                      %d\n", pMGADRI->mem );
+  fprintf( stderr, "cpp:                      %d\n", pMGADRI->cpp );
+
+  fprintf( stderr, "agpMode:                  %d\n", pMGADRI->agpMode );
+
+  fprintf( stderr, "frontOffset:              %d\n", pMGADRI->frontOffset );
+  fprintf( stderr, "frontPitch:               %d\n", pMGADRI->frontPitch );
+
+  fprintf( stderr, "backOffset:               %d\n", pMGADRI->backOffset );
+  fprintf( stderr, "backPitch:                %d\n", pMGADRI->backPitch );
+
+  fprintf( stderr, "depthOffset:              %d\n", pMGADRI->depthOffset );
+  fprintf( stderr, "depthPitch:               %d\n", pMGADRI->depthPitch );
+
+  fprintf( stderr, "textureOffset:            %d\n", pMGADRI->textureOffset );
+  fprintf( stderr, "textureSize:              %d\n", pMGADRI->textureSize );
+
+  fprintf( stderr, "logTextureGranularity:    %d\n", pMGADRI->logTextureGranularity );
+  fprintf( stderr, "logAgpTextureGranularity: %d\n", pMGADRI->logAgpTextureGranularity );
+
+  fprintf( stderr, "agpTextureHandle:         %u\n", (unsigned int)pMGADRI->agpTextureOffset );
+  fprintf( stderr, "agpTextureSize:           %u\n", (unsigned int)pMGADRI->agpTextureSize );
+
+#if 0
+   pMGADRI->registers.handle   = pMga->registers.handle;
+   pMGADRI->registers.size     = pMga->registers.size;
+   pMGADRI->status.handle      = pMga->status.handle;
+   pMGADRI->status.size                = pMga->status.size;
+   pMGADRI->primary.handle     = pMga->primary.handle;
+   pMGADRI->primary.size       = pMga->primary.size;
+   pMGADRI->buffers.handle     = pMga->buffers.handle;
+   pMGADRI->buffers.size       = pMga->buffers.size;
+   pMGADRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+#endif
+}
+
+static int MGAScreenInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
+{
+  int       i;
+  int       err;
+  MGADRIPtr pMGADRI;
+
+  usleep(100);
+  /*assert(!ctx->IsClient);*/
+
+   {
+      int  width_bytes = (ctx->shared.virtualWidth * ctx->cpp);
+      int  maxy        = ctx->shared.fbSize / width_bytes;
+
+
+      if (maxy <= ctx->shared.virtualHeight * 3) {
+        fprintf(stderr, 
+                "Static buffer allocation failed -- "
+                "need at least %d kB video memory (have %d kB)\n",
+                (ctx->shared.virtualWidth * ctx->shared.virtualHeight *
+                 ctx->cpp * 3 + 1023) / 1024,
+                ctx->shared.fbSize / 1024);
+        return 0;
+      } 
+   }
+
+   switch(pMga->Chipset) {
+   case PCI_CHIP_MGAG550:
+   case PCI_CHIP_MGAG400:
+   case PCI_CHIP_MGAG200:
+#if 0
+   case PCI_CHIP_MGAG200_PCI:
+#endif
+      break;
+   default:
+      fprintf(stderr, "[drm] Direct rendering only supported with G200/G400/G550 AGP\n");
+      return 0;
+   }
+
+   fprintf( stderr,
+              "[drm] bpp: %d depth: %d\n",
+            ctx->bpp, ctx->bpp /* FIXME: depth */ );
+
+   if ( (ctx->bpp / 8) != 2 &&
+       (ctx->bpp / 8) != 4 ) {
+      fprintf( stderr,
+                 "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" );
+      return 0;
+   }
+
+   ctx->shared.SAREASize = SAREA_MAX;
+
+
+   /* Note that drmOpen will try to load the kernel module, if needed. */
+   ctx->drmFD = drmOpen("mga", NULL );
+   if (ctx->drmFD < 0) {
+      fprintf(stderr, "[drm] drmOpen failed\n");
+      return 0;
+   }
+
+   if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
+      fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
+             ctx->drmFD, ctx->pciBusID, strerror(-err));
+      return 0;
+   }
+
+     
+   if (drmAddMap( ctx->drmFD,
+                 0,
+                 ctx->shared.SAREASize,
+                 DRM_SHM,
+                 DRM_CONTAINS_LOCK,
+                 &ctx->shared.hSAREA) < 0)
+   {
+      fprintf(stderr, "[drm] drmAddMap failed\n");
+      return 0;
+   }
+   fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
+          ctx->shared.SAREASize, ctx->shared.hSAREA);
+
+   if (drmMap( ctx->drmFD,
+              ctx->shared.hSAREA,
+              ctx->shared.SAREASize,
+              (drmAddressPtr)(&ctx->pSAREA)) < 0)
+   {
+      fprintf(stderr, "[drm] drmMap failed\n");
+      return 0;
+   }
+   memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
+   fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
+          ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
+   
+   /* Need to AddMap the framebuffer and mmio regions here:
+    */
+   if (drmAddMap( ctx->drmFD,
+                 (drmHandle)ctx->FBStart,
+                 ctx->FBSize,
+                 DRM_FRAME_BUFFER,
+                 0,
+                 &ctx->shared.hFrameBuffer) < 0)
+   {
+      fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
+      return 0;
+   }
+   fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
+          ctx->shared.hFrameBuffer);
+
+
+#if 0 /* will be done in MGADRIMapInit */
+   if (drmAddMap(ctx->drmFD, 
+                ctx->FixedInfo.mmio_start,
+                ctx->FixedInfo.mmio_len,
+                DRM_REGISTERS, 
+                DRM_READ_ONLY, 
+                &pMga->registers.handle) < 0) {
+      fprintf(stderr, "[drm] drmAddMap mmio failed\n");        
+      return 0;
+   }
+   fprintf(stderr,
+          "[drm] register handle = 0x%08lx\n", pMga->registers.handle);
+#endif
+
+
+   /* Check the mga DRM version */
+   if (!MGACheckDRMVersion(ctx, pMga)) {
+      return 0;
+   }
+
+   if ( !MGADRIAgpInit( ctx, pMga ) ) {
+      return 0;
+   }
+
+   if ( !MGADRIMapInit( ctx, pMga ) ) {
+      return 0;
+   }
+
+   /* Memory manager setup */
+   if (!MGAMemoryInit(ctx, pMga)) {
+      return 0;
+   }
+
+
+   /* Create a 'server' context so we can grab the lock for
+    * initialization ioctls.
+    */
+   if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
+      fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
+      return 0;
+   }
+
+   DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); 
+
+   /* Initialize the kernel data structures */
+   if (!MGADRIKernelInit(ctx, pMga)) {
+      fprintf(stderr, "MGADRIKernelInit failed\n");
+      DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
+      return 0;
+   }
+
+   /* Initialize the vertex buffers list */
+   if (!MGADRIBuffersInit(ctx, pMga)) {
+      fprintf(stderr, "MGADRIBuffersInit failed\n");
+      DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
+      return 0;
+   }
+
+   /* Initialize IRQ */
+   MGADRIIrqInit(ctx, pMga);
+
+
+   /* Initialize the SAREA private data structure */
+   {
+      MGASAREAPrivPtr pSAREAPriv;
+      pSAREAPriv = (MGASAREAPrivPtr)(((char*)ctx->pSAREA) + 
+                                       sizeof(XF86DRISAREARec));
+      memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
+   }
+
+   /* Quick hack to clear the front & back buffers.  Could also use
+    * the clear ioctl to do this, but would need to setup hw state
+    * first.
+    */
+   memset((char *)ctx->FBAddress + pMga->frontOffset,
+         0,
+         pMga->frontPitch * ctx->shared.virtualHeight );
+
+   memset((char *)ctx->FBAddress + pMga->backOffset,
+         0,
+         pMga->backPitch * ctx->shared.virtualHeight );
+
+   /* Can release the lock now */
+/*   DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);*/
+
+   /* This is the struct passed to radeon_dri.so for its initialization */
+   ctx->driverClientMsg = malloc(sizeof(MGADRIRec));
+   ctx->driverClientMsgSize = sizeof(MGADRIRec);
+
+   pMGADRI                    = (MGADRIPtr)ctx->driverClientMsg;
+
+
+   switch(pMga->Chipset) {
+   case PCI_CHIP_MGAG550:
+   case PCI_CHIP_MGAG400:
+      pMGADRI->chipset = MGA_CARD_TYPE_G400;
+      break;
+   case PCI_CHIP_MGAG200:
+   case PCI_CHIP_MGAG200_PCI:
+      pMGADRI->chipset = MGA_CARD_TYPE_G200;
+      break;
+   default:
+      return 0;
+   }
+   pMGADRI->width              = ctx->shared.virtualWidth;
+   pMGADRI->height             = ctx->shared.virtualHeight;
+   pMGADRI->mem                        = ctx->shared.fbSize;
+   pMGADRI->cpp                        = ctx->bpp / 8;
+
+   pMGADRI->agpMode            = pMga->agpMode;
+
+   pMGADRI->frontOffset                = pMga->frontOffset;
+   pMGADRI->frontPitch         = pMga->frontPitch;
+   pMGADRI->backOffset         = pMga->backOffset;
+   pMGADRI->backPitch          = pMga->backPitch;
+   pMGADRI->depthOffset                = pMga->depthOffset;
+   pMGADRI->depthPitch         = pMga->depthPitch;
+   pMGADRI->textureOffset      = pMga->textureOffset;
+   pMGADRI->textureSize                = pMga->textureSize;
+   pMGADRI->logTextureGranularity = pMga->logTextureGranularity;
+
+   i = mylog2( pMga->agpTextures.size / MGA_NR_TEX_REGIONS );
+   if ( i < MGA_LOG_MIN_TEX_REGION_SIZE )
+      i = MGA_LOG_MIN_TEX_REGION_SIZE;
+
+   pMGADRI->logAgpTextureGranularity = i;
+   pMGADRI->agpTextureOffset = (unsigned int)pMga->agpTextures.handle;
+   pMGADRI->agpTextureSize = (unsigned int)pMga->agpTextures.size;
+
+   pMGADRI->registers.handle   = pMga->registers.handle;
+   pMGADRI->registers.size     = pMga->registers.size;
+   pMGADRI->status.handle      = pMga->status.handle;
+   pMGADRI->status.size                = pMga->status.size;
+   pMGADRI->primary.handle     = pMga->primary.handle;
+   pMGADRI->primary.size       = pMga->primary.size;
+   pMGADRI->buffers.handle     = pMga->buffers.handle;
+   pMGADRI->buffers.size       = pMga->buffers.size;
+   pMGADRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+
+   print_client_msg( pMGADRI );
+
+   return 1;
+}
+
+
+/**
+ * \brief Establish the set of modes available for the display.
+ *
+ * \param ctx display handle.
+ * \param numModes will receive the number of supported modes.
+ * \param modes will point to the list of supported modes.
+ *
+ * \return one on success, or zero on failure.
+ * 
+ * Allocates a single visual and fills it with information according to the
+ * display bit depth. Supports only 16 and 32 bpp bit depths, aborting
+ * otherwise.
+ */
+const __GLcontextModes __glModes[] = {
+    
+    /* 32 bit, RGBA Depth=24 Stencil=8 */
+    {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE,
+     .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_TRUE,
+     .redBits = 8, .greenBits = 8, .blueBits = 8, .alphaBits = 8,
+     .redMask = 0xff0000, .greenMask = 0xff00, .blueMask = 0xff, .alphaMask = 0xff000000,
+     .rgbBits = 32, .indexBits = 0,
+     .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0,
+     .depthBits = 24, .stencilBits = 8,
+     .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, },
+
+    /* 16 bit, RGB Depth=16 */
+    {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE,
+     .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_FALSE,
+     .redBits = 5, .greenBits = 6, .blueBits = 5, .alphaBits = 0,
+     .redMask = 0xf800, .greenMask = 0x07e0, .blueMask = 0x001f, .alphaMask = 0x0,
+     .rgbBits = 16, .indexBits = 0,
+     .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0,
+     .depthBits = 16, .stencilBits = 0,
+     .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, },
+};
+static int mgaInitContextModes( const DRIDriverContext *ctx,
+                                  int *numModes, const __GLcontextModes **modes)
+{
+   *numModes = sizeof(__glModes)/sizeof(__GLcontextModes *);
+   *modes = &__glModes[0];
+   return 1;
+}
+
+
+/**
+ * \brief Validate the fbdev mode.
+ * 
+ * \param ctx display handle.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Saves some registers and returns 1.
+ *
+ * \sa mgaValidateMode().
+ */
+static int mgaValidateMode( const DRIDriverContext *ctx )
+{
+   return 1;
+}
+
+
+/**
+ * \brief Examine mode returned by fbdev.
+ * 
+ * \param ctx display handle.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Restores registers that fbdev has clobbered and returns 1.
+ *
+ * \sa mgaValidateMode().
+ */
+static int mgaPostValidateMode( const DRIDriverContext *ctx )
+{
+   return 1;
+}
+
+
+/**
+ * \brief Initialize the framebuffer device mode
+ *
+ * \param ctx display handle.
+ *
+ * \return one on success, or zero on failure.
+ *
+ * Fills in \p info with some default values and some information from \p ctx
+ * and then calls MGAScreenInit() for the screen initialization.
+ * 
+ * Before exiting clears the framebuffer memomry accessing it directly.
+ */
+static int mgaInitFBDev( struct DRIDriverContextRec *ctx )
+{
+   MGAPtr pMga = calloc(1, sizeof(*pMga));
+
+   {
+      int  dummy = ctx->shared.virtualWidth;
+
+      switch (ctx->bpp / 8) {
+      case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break;
+      case 2: dummy = (ctx->shared.virtualWidth +  31) &  ~31; break;
+      case 3:
+      case 4: dummy = (ctx->shared.virtualWidth +  15) &  ~15; break;
+      }
+
+      ctx->shared.virtualWidth = dummy;
+   }
+
+   ctx->driverPrivate = (void *)pMga;
+   
+   pMga->agpMode       = MGA_DEFAULT_AGP_MODE;
+   pMga->agpSize       = MGA_DEFAULT_AGP_SIZE;
+  
+   pMga->Chipset = ctx->chipset;
+
+   pMga->IOAddress = ctx->MMIOStart;
+   pMga->IOBase    = ctx->MMIOAddress;
+
+   pMga->frontPitch = ctx->shared.virtualWidth * ctx->cpp;
+
+   if (!MGAScreenInit( ctx, pMga ))
+      return 0;
+
+   return 1;
+}
+
+
+/**
+ * \brief The screen is being closed, so clean up any state and free any
+ * resources used by the DRI.
+ *
+ * \param ctx display handle.
+ *
+ * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
+ * private data.
+ */
+static void mgaHaltFBDev( struct DRIDriverContextRec *ctx )
+{
+    drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
+    drmClose(ctx->drmFD);
+
+    if (ctx->driverPrivate) {
+       free(ctx->driverPrivate);
+       ctx->driverPrivate = NULL;
+    }
+}
+
+
+static int mgaEngineShutdown( const DRIDriverContext *ctx )
+{
+   fprintf(stderr, "%s() is not yet implemented!\n", __FUNCTION__);
+
+   return 1;
+}
+
+static int mgaEngineRestore( const DRIDriverContext *ctx )
+{
+   fprintf(stderr, "%s() is not yet implemented!\n", __FUNCTION__);
+
+   return 1;
+}
+
+/**
+ * \brief Exported driver interface for Mini GLX.
+ *
+ * \sa DRIDriverRec.
+ */
+struct DRIDriverRec __driDriver = {
+   mgaInitContextModes,
+   mgaValidateMode,
+   mgaPostValidateMode,
+   mgaInitFBDev,
+   mgaHaltFBDev,
+   mgaEngineShutdown,
+   mgaEngineRestore,
+   0
+};
+
+
+
+
+#if 0
+void MGADRICloseScreen( ScreenPtr pScreen )
+{
+   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+   MGAPtr pMga = MGAPTR(pScrn);
+   MGADRIServerPrivatePtr pMga = pMga->DRIServerInfo;
+   drmMGAInit init;
+
+   if ( pMga->drmBuffers ) {
+      drmUnmapBufs( pMga->drmBuffers );
+      pMga->drmBuffers = NULL;
+   }
+
+   if (pMga->irq) {
+      drmCtlUninstHandler(ctx->drmFD);
+      pMga->irq = 0;
+   }
+
+   /* Cleanup DMA */
+   memset( &init, 0, sizeof(drmMGAInit) );
+   init.func = MGA_CLEANUP_DMA;
+   drmCommandWrite( ctx->drmFD, DRM_MGA_INIT, &init, sizeof(drmMGAInit) );
+
+   if ( pMga->status.map ) {
+      drmUnmap( pMga->status.map, pMga->status.size );
+      pMga->status.map = NULL;
+   }
+   if ( pMga->buffers.map ) {
+      drmUnmap( pMga->buffers.map, pMga->buffers.size );
+      pMga->buffers.map = NULL;
+   }
+   if ( pMga->primary.map ) {
+      drmUnmap( pMga->primary.map, pMga->primary.size );
+      pMga->primary.map = NULL;
+   }
+   if ( pMga->warp.map ) {
+      drmUnmap( pMga->warp.map, pMga->warp.size );
+      pMga->warp.map = NULL;
+   }
+
+   if ( pMga->agpTextures.map ) {
+      drmUnmap( pMga->agpTextures.map, pMga->agpTextures.size );
+      pMga->agpTextures.map = NULL;
+   }
+
+   if ( pMga->agp.handle ) {
+      drmAgpUnbind( ctx->drmFD, pMga->agp.handle );
+      drmAgpFree( ctx->drmFD, pMga->agp.handle );
+      pMga->agp.handle = 0;
+      drmAgpRelease( ctx->drmFD );
+   }
+
+   DRICloseScreen( pScreen );
+
+   if ( pMga->pDRIInfo ) {
+      if ( pMga->pDRIpMga->devPrivate ) {
+        xfree( pMga->pDRIpMga->devPrivate );
+        pMga->pDRIpMga->devPrivate = 0;
+      }
+      DRIDestroyInfoRec( pMga->pDRIInfo );
+      pMga->pDRIInfo = 0;
+   }
+   if ( pMga->DRIServerInfo ) {
+      xfree( pMga->DRIServerInfo );
+      pMga->DRIServerInfo = 0;
+   }
+   if ( pMga->pVisualConfigs ) {
+      xfree( pMga->pVisualConfigs );
+   }
+   if ( pMga->pVisualConfigsPriv ) {
+      xfree( pMga->pVisualConfigsPriv );
+   }
+}
+#endif
diff --git a/src/mesa/drivers/dri/mga/server/mga_dri.h b/src/mesa/drivers/dri/mga/server/mga_dri.h
new file mode 100644 (file)
index 0000000..c6a3e23
--- /dev/null
@@ -0,0 +1,84 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h,v 1.8 2002/11/29 11:06:42 eich Exp $ */
+
+/*
+ * Copyright 2000 VA Linux Systems Inc., Fremont, California.
+ * 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * 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 NONINFRINGEMENT.  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>
+ *   Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __MGA_DRI_H__
+#define __MGA_DRI_H__
+
+#include "xf86drm.h"
+#include "mga_common.h"
+
+#define MGA_DEFAULT_AGP_SIZE     64
+#define MGA_DEFAULT_AGP_MODE     4
+#define MGA_MAX_AGP_MODE         4
+
+/* Buffer are aligned on 4096 byte boundaries.
+ */
+#define MGA_BUFFER_ALIGN       0x00000fff
+
+typedef struct {
+   int chipset;
+   int width;
+   int height;
+   int mem;
+   int cpp;
+
+   int agpMode;
+
+   int frontOffset;
+   int frontPitch;
+
+   int backOffset;
+   int backPitch;
+
+   int depthOffset;
+   int depthPitch;
+
+   int textureOffset;
+   int textureSize;
+   int logTextureGranularity;
+
+   /* Allow calculation of setup dma addresses.
+    */
+   unsigned int agpBufferOffset;
+
+   unsigned int agpTextureOffset;
+   unsigned int agpTextureSize;
+   int logAgpTextureGranularity;
+
+   unsigned int mAccess;
+
+   drmRegion registers;
+   drmRegion status;
+   drmRegion primary;
+   drmRegion buffers;
+   unsigned int sarea_priv_offset;
+} MGADRIRec, *MGADRIPtr;
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/server/mga_macros.h b/src/mesa/drivers/dri/mga/server/mga_macros.h
new file mode 100644 (file)
index 0000000..d985081
--- /dev/null
@@ -0,0 +1,118 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h,v 1.22 2002/02/20 17:17:50 dawes Exp $ */
+
+#ifndef _MGA_MACROS_H_
+#define _MGA_MACROS_H_
+
+#ifndef PSZ
+#define PSZ 8
+#endif
+
+#if PSZ == 8
+#define REPLICATE(r) r &= 0xFF; r |= r << 8; r |= r << 16
+#elif PSZ == 16
+#define REPLICATE(r) r &= 0xFFFF; r |= r << 16
+#elif PSZ == 24
+#define REPLICATE(r) r &= 0xFFFFFF; r |= r << 24
+#else
+#define REPLICATE(r) /* */
+#endif
+
+#define RGBEQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff))
+
+#ifdef XF86DRI
+#define MGA_SYNC_XTAG                 0x275f4200
+
+#define MGABUSYWAIT() do { \
+OUTREG(MGAREG_DWGSYNC, MGA_SYNC_XTAG); \
+while(INREG(MGAREG_DWGSYNC) != MGA_SYNC_XTAG) ; \
+}while(0);
+
+#endif
+
+#define MGAISBUSY() (INREG8(MGAREG_Status + 2) & 0x01)
+
+#define WAITFIFO(cnt) \
+   if(!pMga->UsePCIRetry) {\
+       register int n = cnt; \
+       if(n > pMga->FifoSize) n = pMga->FifoSize; \
+       while(pMga->fifoCount < (n))\
+           pMga->fifoCount = INREG8(MGAREG_FIFOSTATUS);\
+       pMga->fifoCount -= n;\
+   }
+
+#define XYADDRESS(x,y) \
+    ((y) * pMga->CurrentLayout.displayWidth + (x) + pMga->YDstOrg)
+
+#define MAKEDMAINDEX(index)  ((((index) >> 2) & 0x7f) | (((index) >> 6) & 0x80))
+
+#define DMAINDICES(one,two,three,four) \
+       ( MAKEDMAINDEX(one) | \
+        (MAKEDMAINDEX(two) << 8) | \
+        (MAKEDMAINDEX(three) << 16) | \
+        (MAKEDMAINDEX(four) << 24) )
+
+#if PSZ == 24
+#define SET_PLANEMASK(p) /**/
+#else
+#define SET_PLANEMASK(p) \
+       if(!(pMga->AccelFlags & MGA_NO_PLANEMASK) && ((p) != pMga->PlaneMask)) { \
+          pMga->PlaneMask = (p); \
+          REPLICATE((p)); \
+          OUTREG(MGAREG_PLNWT,(p)); \
+       }
+#endif
+
+#define SET_FOREGROUND(c) \
+       if((c) != pMga->FgColor) { \
+          pMga->FgColor = (c); \
+          REPLICATE((c)); \
+          OUTREG(MGAREG_FCOL,(c)); \
+       }
+
+#define SET_BACKGROUND(c) \
+       if((c) != pMga->BgColor) { \
+          pMga->BgColor = (c); \
+          REPLICATE((c)); \
+          OUTREG(MGAREG_BCOL,(c)); \
+       }
+
+#define DISABLE_CLIP() { \
+       pMga->AccelFlags &= ~CLIPPER_ON; \
+       WAITFIFO(1); \
+       OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); }
+
+#ifdef XF86DRI
+#define CHECK_DMA_QUIESCENT(pMGA, pScrn) {     \
+   if (!pMGA->haveQuiescense) {                        \
+      pMGA->GetQuiescence( pScrn );            \
+   }                                           \
+}
+#else
+#define CHECK_DMA_QUIESCENT(pMGA, pScrn)
+#endif
+
+#ifdef USEMGAHAL
+#define HAL_CHIPSETS ((pMga->Chipset == PCI_CHIP_MGAG200_PCI) || \
+                 (pMga->Chipset == PCI_CHIP_MGAG200) || \
+                 (pMga->Chipset == PCI_CHIP_MGAG400) || \
+                 (pMga->Chipset == PCI_CHIP_MGAG550))
+    
+#define MGA_HAL(x) { \
+       MGAPtr pMga = MGAPTR(pScrn); \
+       if (pMga->HALLoaded && HAL_CHIPSETS) { x; } \
+}
+#define MGA_NOT_HAL(x) { \
+       MGAPtr pMga = MGAPTR(pScrn); \
+       if (!pMga->HALLoaded || !HAL_CHIPSETS) { x; } \
+}
+#else
+#define MGA_NOT_HAL(x) { x; }
+#endif
+
+#define MGAISGx50(x) ( (((x)->Chipset == PCI_CHIP_MGAG400) && ((x)->ChipRev >= 0x80)) || \
+                      ((x)->Chipset == PCI_CHIP_MGAG550) )
+
+#define MGA_DH_NEEDS_HAL(x) (((x)->Chipset == PCI_CHIP_MGAG400) && \
+                            ((x)->ChipRev < 0x80))
+
+#endif /* _MGA_MACROS_H_ */
diff --git a/src/mesa/drivers/dri/mga/server/mga_reg.h b/src/mesa/drivers/dri/mga/server/mga_reg.h
new file mode 100644 (file)
index 0000000..b8e3499
--- /dev/null
@@ -0,0 +1,484 @@
+/* $XConsortium: mgareg.h /main/2 1996/10/25 10:33:21 kaleb $ */
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h,v 1.18 2001/09/26 12:59:18 alanh Exp $ */
+
+
+
+/*
+ * MGA Millennium (MGA2064W) functions
+ * MGA Mystique (MGA1064SG) functions
+ *
+ * Copyright 1996 The XFree86 Project, Inc.
+ *
+ * Authors
+ *             Dirk Hohndel
+ *                     hohndel@XFree86.Org
+ *             David Dawes
+ *                     dawes@XFree86.Org
+ * Contributors:
+ *             Guy DESBIEF, Aix-en-provence, France
+ *                     g.desbief@aix.pacwan.net
+ *             MGA1064SG Mystique register file
+ */
+
+
+#ifndef _MGA_REG_H_
+#define _MGA_REG_H_
+
+#define        MGAREG_DWGCTL           0x1c00
+#define        MGAREG_MACCESS          0x1c04
+#define        MGA_MACCESS_PW16        0x00000001
+#define        MGA_MACCESS_PW32        0x00000002
+/* the following is a mystique only register */
+#define MGAREG_MCTLWTST                0x1c08
+#define        MGAREG_ZORG             0x1c0c
+
+#define        MGAREG_PAT0             0x1c10
+#define        MGAREG_PAT1             0x1c14
+#define        MGAREG_PLNWT            0x1c1c
+
+#define        MGAREG_BCOL             0x1c20
+#define        MGAREG_FCOL             0x1c24
+
+#define        MGAREG_SRC0             0x1c30
+#define        MGAREG_SRC1             0x1c34
+#define        MGAREG_SRC2             0x1c38
+#define        MGAREG_SRC3             0x1c3c
+
+#define        MGAREG_XYSTRT           0x1c40
+#define        MGAREG_XYEND            0x1c44
+
+#define        MGAREG_SHIFT            0x1c50
+/* the following is a mystique only register */
+#define MGAREG_DMAPAD          0x1c54
+#define        MGAREG_SGN              0x1c58
+#define        MGAREG_LEN              0x1c5c
+
+#define        MGAREG_AR0              0x1c60
+#define        MGAREG_AR1              0x1c64
+#define        MGAREG_AR2              0x1c68
+#define        MGAREG_AR3              0x1c6c
+#define        MGAREG_AR4              0x1c70
+#define        MGAREG_AR5              0x1c74
+#define        MGAREG_AR6              0x1c78
+
+#define        MGAREG_CXBNDRY          0x1c80
+#define        MGAREG_FXBNDRY          0x1c84
+#define        MGAREG_YDSTLEN          0x1c88
+#define        MGAREG_PITCH            0x1c8c
+
+#define        MGAREG_YDST             0x1c90
+#define        MGAREG_YDSTORG          0x1c94
+#define        MGAREG_YTOP             0x1c98
+#define        MGAREG_YBOT             0x1c9c
+
+#define        MGAREG_CXLEFT           0x1ca0
+#define        MGAREG_CXRIGHT          0x1ca4
+#define        MGAREG_FXLEFT           0x1ca8
+#define        MGAREG_FXRIGHT          0x1cac
+
+#define        MGAREG_XDST             0x1cb0
+
+#define        MGAREG_DR0              0x1cc0
+#define        MGAREG_DR1              0x1cc4
+#define        MGAREG_DR2              0x1cc8
+#define        MGAREG_DR3              0x1ccc
+
+#define        MGAREG_DR4              0x1cd0
+#define        MGAREG_DR5              0x1cd4
+#define        MGAREG_DR6              0x1cd8
+#define        MGAREG_DR7              0x1cdc
+
+#define        MGAREG_DR8              0x1ce0
+#define        MGAREG_DR9              0x1ce4
+#define        MGAREG_DR10             0x1ce8
+#define        MGAREG_DR11             0x1cec
+
+#define        MGAREG_DR12             0x1cf0
+#define        MGAREG_DR13             0x1cf4
+#define        MGAREG_DR14             0x1cf8
+#define        MGAREG_DR15             0x1cfc
+
+#define MGAREG_SRCORG          0x2cb4
+#define MGAREG_DSTORG          0x2cb8
+
+/* add or or this to one of the previous "power registers" to start
+   the drawing engine */
+
+#define MGAREG_EXEC            0x0100
+
+#define        MGAREG_FIFOSTATUS       0x1e10
+#define        MGAREG_Status           0x1e14
+#define        MGAREG_ICLEAR           0x1e18
+#define        MGAREG_IEN              0x1e1c
+
+#define        MGAREG_VCOUNT           0x1e20
+
+#define        MGAREG_Reset            0x1e40
+
+#define        MGAREG_OPMODE           0x1e54
+
+/* Warp Registers */
+#define MGAREG_WIADDR           0x1dc0
+#define MGAREG_WIADDR2          0x1dd8
+#define MGAREG_WGETMSB          0x1dc8
+#define MGAREG_WVRTXSZ          0x1dcc
+#define MGAREG_WACCEPTSEQ       0x1dd4
+#define MGAREG_WMISC            0x1e70
+
+/* OPMODE register additives */
+
+#define MGAOPM_DMA_GENERAL     (0x00 << 2)
+#define MGAOPM_DMA_BLIT                (0x01 << 2)
+#define MGAOPM_DMA_VECTOR      (0x10 << 2)
+
+/* DWGCTL register additives */
+
+/* Lines */
+
+#define MGADWG_LINE_OPEN       0x00
+#define MGADWG_AUTOLINE_OPEN   0x01
+#define MGADWG_LINE_CLOSE      0x02
+#define MGADWG_AUTOLINE_CLOSE  0x03
+
+/* Trapezoids */
+#define MGADWG_TRAP            0x04
+#define MGADWG_TEXTURE_TRAP    0x05
+
+/* BitBlts */
+
+#define MGADWG_BITBLT          0x08
+#define MGADWG_FBITBLT         0x0c
+#define MGADWG_ILOAD           0x09
+#define MGADWG_ILOAD_SCALE     0x0d
+#define MGADWG_ILOAD_FILTER    0x0f
+#define MGADWG_ILOAD_HIQH      0x07
+#define MGADWG_ILOAD_HIQHV     0x0e
+#define MGADWG_IDUMP           0x0a
+
+/* atype access to WRAM */
+
+#define MGADWG_RPL             ( 0x00 << 4 )
+#define MGADWG_RSTR            ( 0x01 << 4 )
+#define MGADWG_ZI              ( 0x03 << 4 )
+#define MGADWG_BLK             ( 0x04 << 4 )
+#define MGADWG_I               ( 0x07 << 4 )
+
+/* specifies whether bit blits are linear or xy */
+#define MGADWG_LINEAR          ( 0x01 << 7 )
+
+/* z drawing mode. use MGADWG_NOZCMP for always */
+
+#define MGADWG_NOZCMP          ( 0x00 << 8 )
+#define MGADWG_ZE              ( 0x02 << 8 )
+#define MGADWG_ZNE             ( 0x03 << 8 )
+#define MGADWG_ZLT             ( 0x04 << 8 )
+#define MGADWG_ZLTE            ( 0x05 << 8 )
+#define MGADWG_GT              ( 0x06 << 8 )
+#define MGADWG_GTE             ( 0x07 << 8 )
+
+/* use this to force colour expansion circuitry to do its stuff */
+
+#define MGADWG_SOLID           ( 0x01 << 11 )
+
+/* ar register at zero */
+
+#define MGADWG_ARZERO          ( 0x01 << 12 )
+
+#define MGADWG_SGNZERO         ( 0x01 << 13 )
+
+#define MGADWG_SHIFTZERO       ( 0x01 << 14 )
+
+/* See table on 4-43 for bop ALU operations */
+
+/* See table on 4-44 for translucidity masks */
+
+#define MGADWG_BMONOLEF                ( 0x00 << 25 )
+#define MGADWG_BMONOWF         ( 0x04 << 25 )
+#define MGADWG_BPLAN           ( 0x01 << 25 )
+
+/* note that if bfcol is specified and you're doing a bitblt, it causes
+   a fbitblt to be performed, so check that you obey the fbitblt rules */
+
+#define MGADWG_BFCOL                   ( 0x02 << 25 )
+#define MGADWG_BUYUV           ( 0x0e << 25 )
+#define MGADWG_BU32BGR         ( 0x03 << 25 )
+#define MGADWG_BU32RGB         ( 0x07 << 25 )
+#define MGADWG_BU24BGR         ( 0x0b << 25 )
+#define MGADWG_BU24RGB         ( 0x0f << 25 )
+
+#define MGADWG_PATTERN         ( 0x01 << 29 )
+#define MGADWG_TRANSC          ( 0x01 << 30 )
+#define MGAREG_MISC_WRITE      0x3c2
+#define MGAREG_MISC_READ       0x3cc
+#define MGAREG_MISC_IOADSEL    (0x1 << 0)
+#define MGAREG_MISC_RAMMAPEN   (0x1 << 1)
+#define MGAREG_MISC_CLK_SEL_VGA25      (0x0 << 2)
+#define MGAREG_MISC_CLK_SEL_VGA28      (0x1 << 2)
+#define MGAREG_MISC_CLK_SEL_MGA_PIX    (0x2 << 2)
+#define MGAREG_MISC_CLK_SEL_MGA_MSK    (0x3 << 2)
+#define MGAREG_MISC_VIDEO_DIS  (0x1 << 4)
+#define MGAREG_MISC_HIGH_PG_SEL        (0x1 << 5)
+
+/* MMIO VGA registers */
+#define MGAREG_SEQ_INDEX       0x1fc4
+#define MGAREG_SEQ_DATA                0x1fc5
+#define MGAREG_CRTC_INDEX      0x1fd4
+#define MGAREG_CRTC_DATA       0x1fd5
+#define MGAREG_CRTCEXT_INDEX   0x1fde
+#define MGAREG_CRTCEXT_DATA    0x1fdf
+
+
+
+/* MGA bits for registers PCI_OPTION_REG */
+#define MGA1064_OPT_SYS_CLK_PCI                ( 0x00 << 0 )
+#define MGA1064_OPT_SYS_CLK_PLL                ( 0x01 << 0 )
+#define MGA1064_OPT_SYS_CLK_EXT                ( 0x02 << 0 )
+#define MGA1064_OPT_SYS_CLK_MSK                ( 0x03 << 0 )
+
+#define MGA1064_OPT_SYS_CLK_DIS                ( 0x01 << 2 )
+#define MGA1064_OPT_G_CLK_DIV_1                ( 0x01 << 3 )
+#define MGA1064_OPT_M_CLK_DIV_1                ( 0x01 << 4 )
+
+#define MGA1064_OPT_SYS_PLL_PDN                ( 0x01 << 5 )
+#define MGA1064_OPT_VGA_ION            ( 0x01 << 8 )
+
+/* MGA registers in PCI config space */
+#define PCI_MGA_INDEX          0x44
+#define PCI_MGA_DATA           0x48
+#define PCI_MGA_OPTION2                0x50
+#define PCI_MGA_OPTION3                0x54
+
+#define RAMDAC_OFFSET          0x3c00
+
+/* TVP3026 direct registers */
+
+#define TVP3026_INDEX          0x00
+#define TVP3026_WADR_PAL       0x00
+#define TVP3026_COL_PAL                0x01
+#define TVP3026_PIX_RD_MSK     0x02
+#define TVP3026_RADR_PAL       0x03
+#define TVP3026_CUR_COL_ADDR   0x04
+#define TVP3026_CUR_COL_DATA   0x05
+#define TVP3026_DATA           0x0a
+#define TVP3026_CUR_RAM                0x0b
+#define TVP3026_CUR_XLOW       0x0c
+#define TVP3026_CUR_XHI                0x0d
+#define TVP3026_CUR_YLOW       0x0e
+#define TVP3026_CUR_YHI                0x0f
+
+/* TVP3026 indirect registers */
+
+#define TVP3026_SILICON_REV    0x01
+#define TVP3026_CURSOR_CTL     0x06
+#define TVP3026_LATCH_CTL      0x0f
+#define TVP3026_TRUE_COLOR_CTL 0x18
+#define TVP3026_MUX_CTL                0x19
+#define TVP3026_CLK_SEL                0x1a
+#define TVP3026_PAL_PAGE       0x1c
+#define TVP3026_GEN_CTL                0x1d
+#define TVP3026_MISC_CTL       0x1e
+#define TVP3026_GEN_IO_CTL     0x2a
+#define TVP3026_GEN_IO_DATA    0x2b
+#define TVP3026_PLL_ADDR       0x2c
+#define TVP3026_PIX_CLK_DATA   0x2d
+#define TVP3026_MEM_CLK_DATA   0x2e
+#define TVP3026_LOAD_CLK_DATA  0x2f
+#define TVP3026_KEY_RED_LOW    0x32
+#define TVP3026_KEY_RED_HI     0x33
+#define TVP3026_KEY_GREEN_LOW  0x34
+#define TVP3026_KEY_GREEN_HI   0x35
+#define TVP3026_KEY_BLUE_LOW   0x36
+#define TVP3026_KEY_BLUE_HI    0x37
+#define TVP3026_KEY_CTL                0x38
+#define TVP3026_MCLK_CTL       0x39
+#define TVP3026_SENSE_TEST     0x3a
+#define TVP3026_TEST_DATA      0x3b
+#define TVP3026_CRC_LSB                0x3c
+#define TVP3026_CRC_MSB                0x3d
+#define TVP3026_CRC_CTL                0x3e
+#define TVP3026_ID             0x3f
+#define TVP3026_RESET          0xff
+
+
+/* MGA1064 DAC Register file */
+/* MGA1064 direct registers */
+
+#define MGA1064_INDEX          0x00
+#define MGA1064_WADR_PAL       0x00
+#define MGA1064_COL_PAL                0x01
+#define MGA1064_PIX_RD_MSK     0x02
+#define MGA1064_RADR_PAL       0x03
+#define MGA1064_DATA           0x0a
+
+#define MGA1064_CUR_XLOW       0x0c
+#define MGA1064_CUR_XHI                0x0d
+#define MGA1064_CUR_YLOW       0x0e
+#define MGA1064_CUR_YHI                0x0f
+
+/* MGA1064 indirect registers */
+#define MGA1064_DVI_PIPE_CTL    0x03
+#define MGA1064_CURSOR_BASE_ADR_LOW    0x04
+#define MGA1064_CURSOR_BASE_ADR_HI     0x05
+#define MGA1064_CURSOR_CTL     0x06
+#define MGA1064_CURSOR_COL0_RED        0x08
+#define MGA1064_CURSOR_COL0_GREEN      0x09
+#define MGA1064_CURSOR_COL0_BLUE       0x0a
+
+#define MGA1064_CURSOR_COL1_RED        0x0c
+#define MGA1064_CURSOR_COL1_GREEN      0x0d
+#define MGA1064_CURSOR_COL1_BLUE       0x0e
+
+#define MGA1064_CURSOR_COL2_RED        0x010
+#define MGA1064_CURSOR_COL2_GREEN      0x011
+#define MGA1064_CURSOR_COL2_BLUE       0x012
+
+#define MGA1064_VREF_CTL       0x018
+
+#define MGA1064_MUL_CTL                0x19
+#define MGA1064_MUL_CTL_8bits          0x0
+#define MGA1064_MUL_CTL_15bits         0x01
+#define MGA1064_MUL_CTL_16bits         0x02
+#define MGA1064_MUL_CTL_24bits         0x03
+#define MGA1064_MUL_CTL_32bits         0x04
+#define MGA1064_MUL_CTL_2G8V16bits             0x05
+#define MGA1064_MUL_CTL_G16V16bits             0x06
+#define MGA1064_MUL_CTL_32_24bits              0x07
+
+#define MGAGDAC_XVREFCTRL              0x18
+#define MGA1064_PIX_CLK_CTL            0x1a
+#define MGA1064_PIX_CLK_CTL_CLK_DIS            ( 0x01 << 2 )
+#define MGA1064_PIX_CLK_CTL_CLK_POW_DOWN       ( 0x01 << 3 )
+#define MGA1064_PIX_CLK_CTL_SEL_PCI            ( 0x00 << 0 )
+#define MGA1064_PIX_CLK_CTL_SEL_PLL            ( 0x01 << 0 )
+#define MGA1064_PIX_CLK_CTL_SEL_EXT            ( 0x02 << 0 )
+#define MGA1064_PIX_CLK_CTL_SEL_MSK            ( 0x03 << 0 )
+
+#define MGA1064_GEN_CTL                0x1d
+#define MGA1064_MISC_CTL       0x1e
+#define MGA1064_MISC_CTL_DAC_POW_DN            ( 0x01 << 0 )
+#define MGA1064_MISC_CTL_VGA                   ( 0x01 << 1 )
+#define MGA1064_MISC_CTL_DIS_CON               ( 0x03 << 1 )
+#define MGA1064_MISC_CTL_MAFC                  ( 0x02 << 1 )
+#define MGA1064_MISC_CTL_VGA8                  ( 0x01 << 3 )
+#define MGA1064_MISC_CTL_DAC_RAM_CS            ( 0x01 << 4 )
+
+#define MGA1064_GEN_IO_CTL     0x2a
+#define MGA1064_GEN_IO_DATA    0x2b
+#define MGA1064_SYS_PLL_M      0x2c
+#define MGA1064_SYS_PLL_N      0x2d
+#define MGA1064_SYS_PLL_P      0x2e
+#define MGA1064_SYS_PLL_STAT   0x2f
+#define MGA1064_ZOOM_CTL       0x38
+#define MGA1064_SENSE_TST      0x3a
+
+#define MGA1064_CRC_LSB                0x3c
+#define MGA1064_CRC_MSB                0x3d
+#define MGA1064_CRC_CTL                0x3e
+#define MGA1064_COL_KEY_MSK_LSB                0x40
+#define MGA1064_COL_KEY_MSK_MSB                0x41
+#define MGA1064_COL_KEY_LSB            0x42
+#define MGA1064_COL_KEY_MSB            0x43
+#define MGA1064_PIX_PLLA_M     0x44
+#define MGA1064_PIX_PLLA_N     0x45
+#define MGA1064_PIX_PLLA_P     0x46
+#define MGA1064_PIX_PLLB_M     0x48
+#define MGA1064_PIX_PLLB_N     0x49
+#define MGA1064_PIX_PLLB_P     0x4a
+#define MGA1064_PIX_PLLC_M     0x4c
+#define MGA1064_PIX_PLLC_N     0x4d
+#define MGA1064_PIX_PLLC_P     0x4e
+
+#define MGA1064_PIX_PLL_STAT   0x4f
+
+/*Added for G450 dual head*/
+/* Supported PLL*/
+#define __PIXEL_PLL                 1
+#define __SYSTEM_PLL                2
+#define __VIDEO_PLL                 3
+
+#define MGA1064_VID_PLL_P       0x8D
+#define MGA1064_VID_PLL_M       0x8E
+#define MGA1064_VID_PLL_N       0x8F
+
+#define MGA1064_DISP_CTL        0x8a
+#define MGA1064_SYNC_CTL        0x8b
+#define MGA1064_PWR_CTL         0xa0
+#define MGA1064_PAN_CTL         0xa2
+
+/* Using crtc2 */
+#define MGAREG2_C2CTL            0x10
+#define MGAREG2_C2HPARAM         0x14
+#define MGAREG2_C2HSYNC          0x18
+#define MGAREG2_C2VPARAM         0x1c
+#define MGAREG2_C2VSYNC          0x20
+#define MGAREG2_C2STARTADD0      0x28
+
+#define MGAREG2_C2OFFSET         0x40
+#define MGAREG2_C2DATACTL        0x4c
+
+#define MGAREG_C2CTL            0x3c10
+#define MGAREG_C2HPARAM         0x3c14
+#define MGAREG_C2HSYNC          0x3c18
+#define MGAREG_C2VPARAM         0x3c1c
+#define MGAREG_C2VSYNC          0x3c20
+#define MGAREG_C2STARTADD0      0x3c28
+
+#define MGAREG_C2OFFSET         0x3c40
+#define MGAREG_C2DATACTL        0x3c4c
+
+#define MGA1064_DISP_CTL        0x8a
+#define MGA1064_SYNC_CTL        0x8b
+#define MGA1064_PWR_CTL         0xa0
+
+/* video register */
+
+#define MGAREG_BESA1C3ORG      0x3d60
+#define MGAREG_BESA1CORG       0x3d10
+#define MGAREG_BESA1ORG                0x3d00
+#define MGAREG_BESCTL          0x3d20
+#define MGAREG_BESGLOBCTL      0x3dc0
+#define MGAREG_BESHCOORD       0x3d28
+#define MGAREG_BESHISCAL       0x3d30
+#define MGAREG_BESHSRCEND      0x3d3c
+#define MGAREG_BESHSRCLST      0x3d50
+#define MGAREG_BESHSRCST       0x3d38
+#define MGAREG_BESLUMACTL      0x3d40
+#define MGAREG_BESPITCH                0x3d24
+#define MGAREG_BESV1SRCLST     0x3d54
+#define MGAREG_BESV1WGHT       0x3d48
+#define MGAREG_BESVCOORD       0x3d2c
+#define MGAREG_BESVISCAL       0x3d34
+
+/* texture engine registers */
+
+#define MGAREG_TMR0            0x2c00
+#define MGAREG_TMR1            0x2c04
+#define MGAREG_TMR2            0x2c08
+#define MGAREG_TMR3            0x2c0c
+#define MGAREG_TMR4            0x2c10
+#define MGAREG_TMR5            0x2c14
+#define MGAREG_TMR6            0x2c18
+#define MGAREG_TMR7            0x2c1c
+#define MGAREG_TMR8            0x2c20
+#define MGAREG_TEXORG          0x2c24
+#define MGAREG_TEXWIDTH                0x2c28
+#define MGAREG_TEXHEIGHT       0x2c2c
+#define MGAREG_TEXCTL          0x2c30
+#define MGAREG_TEXCTL2         0x2c3c
+#define MGAREG_TEXTRANS                0x2c34
+#define MGAREG_TEXTRANSHIGH    0x2c38
+#define MGAREG_TEXFILTER       0x2c58
+#define MGAREG_ALPHASTART      0x2c70
+#define MGAREG_ALPHAXINC       0x2c74
+#define MGAREG_ALPHAYINC       0x2c78
+#define MGAREG_ALPHACTRL       0x2c7c
+#define MGAREG_DWGSYNC         0x2c4c
+
+#define MGAREG_AGP_PLL         0x1e4c
+#define MGA_AGP2XPLL_ENABLE            0x1
+#define MGA_AGP2XPLL_DISABLE           0x0
+
+#endif
diff --git a/src/mesa/drivers/dri/mga/server/mga_sarea.h b/src/mesa/drivers/dri/mga/server/mga_sarea.h
new file mode 100644 (file)
index 0000000..8bfa3f5
--- /dev/null
@@ -0,0 +1,222 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_sarea.h,v 1.1 2001/03/21 17:11:47 dawes Exp $ */
+
+/*
+ * Copyright 2000 Gareth Hughes
+ * 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * GARETH HUGHES 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:
+ *   Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __MGA_SAREA_H__
+#define __MGA_SAREA_H__
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (mga_drm.h)
+ */
+#ifndef __MGA_SAREA_DEFINES__
+#define __MGA_SAREA_DEFINES__
+
+/* WARP pipe flags
+ */
+#define MGA_F                  0x1             /* fog */
+#define MGA_A                  0x2             /* alpha */
+#define MGA_S                  0x4             /* specular */
+#define MGA_T2                 0x8             /* multitexture */
+
+#define MGA_WARP_TGZ           0
+#define MGA_WARP_TGZF          (MGA_F)
+#define MGA_WARP_TGZA          (MGA_A)
+#define MGA_WARP_TGZAF         (MGA_F|MGA_A)
+#define MGA_WARP_TGZS          (MGA_S)
+#define MGA_WARP_TGZSF         (MGA_S|MGA_F)
+#define MGA_WARP_TGZSA         (MGA_S|MGA_A)
+#define MGA_WARP_TGZSAF                (MGA_S|MGA_F|MGA_A)
+#define MGA_WARP_T2GZ          (MGA_T2)
+#define MGA_WARP_T2GZF         (MGA_T2|MGA_F)
+#define MGA_WARP_T2GZA         (MGA_T2|MGA_A)
+#define MGA_WARP_T2GZAF                (MGA_T2|MGA_A|MGA_F)
+#define MGA_WARP_T2GZS         (MGA_T2|MGA_S)
+#define MGA_WARP_T2GZSF                (MGA_T2|MGA_S|MGA_F)
+#define MGA_WARP_T2GZSA                (MGA_T2|MGA_S|MGA_A)
+#define MGA_WARP_T2GZSAF       (MGA_T2|MGA_S|MGA_F|MGA_A)
+
+#define MGA_MAX_G200_PIPES     8               /* no multitex */
+#define MGA_MAX_G400_PIPES     16
+#define MGA_MAX_WARP_PIPES     MGA_MAX_G400_PIPES
+#define MGA_WARP_UCODE_SIZE    32768           /* in bytes */
+
+#define MGA_CARD_TYPE_G200     1
+#define MGA_CARD_TYPE_G400     2
+
+
+#define MGA_FRONT              0x1
+#define MGA_BACK               0x2
+#define MGA_DEPTH              0x4
+
+/* What needs to be changed for the current vertex dma buffer?
+ */
+#define MGA_UPLOAD_CONTEXT     0x1
+#define MGA_UPLOAD_TEX0                0x2
+#define MGA_UPLOAD_TEX1                0x4
+#define MGA_UPLOAD_PIPE                0x8
+#define MGA_UPLOAD_TEX0IMAGE   0x10
+#define MGA_UPLOAD_TEX1IMAGE   0x20
+#define MGA_UPLOAD_2D          0x40
+#define MGA_WAIT_AGE           0x80 /* handled client-side */
+#define MGA_UPLOAD_CLIPRECTS   0x100 /* handled client-side */
+#if 0
+#define MGA_DMA_FLUSH          0x200 /* set when someone gets the lock
+                                        quiescent */
+#endif
+
+/* 32 buffers of 64k each, total 1 meg.
+ */
+#define MGA_BUFFER_SIZE                (1 << 16)
+#define MGA_NUM_BUFFERS                128
+
+/* Keep these small for testing.
+ */
+#define MGA_NR_SAREA_CLIPRECTS 8
+
+/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+ * regions, subject to a minimum region size of (1<<16) == 64k.
+ *
+ * Clients may subdivide regions internally, but when sharing between
+ * clients, the region size is the minimum granularity.
+ */
+
+#define MGA_CARD_HEAP                  0
+#define MGA_AGP_HEAP                   1
+#define MGA_NR_TEX_HEAPS               2
+#define MGA_NR_TEX_REGIONS             16
+#define MGA_LOG_MIN_TEX_REGION_SIZE    16
+
+#endif /* __MGA_SAREA_DEFINES__ */
+
+
+/* Setup registers for 3D context
+ */
+typedef struct {
+   unsigned int dstorg;
+   unsigned int maccess;
+   unsigned int plnwt;
+   unsigned int dwgctl;
+   unsigned int alphactrl;
+   unsigned int fogcolor;
+   unsigned int wflag;
+   unsigned int tdualstage0;
+   unsigned int tdualstage1;
+   unsigned int fcol;
+   unsigned int stencil;
+   unsigned int stencilctl;
+} mga_context_regs_t;
+
+/* Setup registers for 2D, X server
+ */
+typedef struct {
+   unsigned int pitch;
+} mga_server_regs_t;
+
+/* Setup registers for each texture unit
+ */
+typedef struct {
+   unsigned int texctl;
+   unsigned int texctl2;
+   unsigned int texfilter;
+   unsigned int texbordercol;
+   unsigned int texorg;
+   unsigned int texwidth;
+   unsigned int texheight;
+   unsigned int texorg1;
+   unsigned int texorg2;
+   unsigned int texorg3;
+   unsigned int texorg4;
+} mga_texture_regs_t;
+
+/* General ageing mechanism
+ */
+typedef struct {
+       unsigned int head;              /* Position of head pointer          */
+       unsigned int wrap;              /* Primary DMA wrap count            */
+} mga_age_t;
+
+
+/* WARNING: Do not change the SAREA structure without changing the kernel
+ * as well.
+ */
+typedef struct {
+   /* The channel for communication of state information to the kernel
+    * on firing a vertex dma buffer.
+    */
+   mga_context_regs_t ContextState;
+   mga_server_regs_t ServerState;
+   mga_texture_regs_t TexState[2];
+   unsigned int WarpPipe;
+   unsigned int dirty;
+   unsigned int vertsize;
+
+   /* The current cliprects, or a subset thereof.
+    */
+   XF86DRIClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS];
+   unsigned int nbox;
+
+   /* Information about the most recently used 3d drawable.  The
+    * client fills in the req_* fields, the server fills in the
+    * exported_ fields and puts the cliprects into boxes, above.
+    *
+    * The client clears the exported_drawable field before
+    * clobbering the boxes data.
+    */
+
+   unsigned int req_draw_buffer;    /* MGA_FRONT or MGA_BACK */
+
+   unsigned int exported_drawable;
+   unsigned int exported_index;
+   unsigned int exported_stamp;
+   unsigned int exported_buffers;
+   unsigned int exported_nfront;       /* FIXME: verify signedness... */
+   unsigned int exported_nback;
+   int exported_back_x, exported_front_x, exported_w;
+   int exported_back_y, exported_front_y, exported_h;
+   XF86DRIClipRectRec exported_boxes[MGA_NR_SAREA_CLIPRECTS];
+
+   /* Counters for aging textures and for client-side throttling.
+    */
+   unsigned int status[4];
+   unsigned int last_wrap;
+
+   mga_age_t last_frame;
+   unsigned int last_enqueue;       /* last time a buffer was enqueued */
+   unsigned int last_dispatch;      /* age of the most recently dispatched buffer */
+   unsigned int last_quiescent;     /*  */
+
+   /* LRU lists for texture memory in agp space and on the card.
+    */
+   drmTextureRegion texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
+   unsigned int texAge[MGA_NR_TEX_HEAPS];
+
+   /* Last context that uploaded statel
+    */
+   int ctxOwner;
+} MGASAREAPrivRec, *MGASAREAPrivPtr;
+
+#endif