fixup draw/depth region handling in i830 along lines of i915
[mesa.git] / src / mesa / drivers / glide / fxapi.c
index 89b4a38a620a884e7c1f249f5687601e6e523a3e..e535e739b31229857dea7cb7eb54464dabfc2abb 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id: fxapi.c,v 1.38 2003/10/02 17:36:44 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
  * Version:  4.0
 #if defined(FX)
 #include "fxdrv.h"
 
+#include "drivers/common/driverfuncs.h"
+#include "framebuffer.h"
+
 #ifndef TDFX_DEBUG
-int TDFX_DEBUG = (0 
+int TDFX_DEBUG = (0
 /*               | VERBOSE_VARRAY */
 /*               | VERBOSE_TEXTURE */
 /*               | VERBOSE_IMMEDIATE */
@@ -103,27 +104,53 @@ cleangraphics_handler(int s)
 #endif
 
 
+/*
+ * Query 3Dfx hardware presence/kind
+ */
+static GLboolean GLAPIENTRY fxQueryHardware (void)
+{
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+    fprintf(stderr, "fxQueryHardware()\n");
+ }
+
+ if (!glbGlideInitialized) {
+    grGlideInit();
+    glb3DfxPresent = FX_grSstQueryHardware(&glbHWConfig);
+
+    glbGlideInitialized = 1;
+
+#if defined(__WIN32__)
+    _onexit((_onexit_t) cleangraphics);
+#elif defined(__linux__)
+    /* Only register handler if environment variable is not defined. */
+    if (!getenv("MESA_FX_NO_SIGNALS")) {
+       atexit(cleangraphics);
+    }
+#endif
+ }
+
+ return glb3DfxPresent;
+}
+
+
 /*
  * Select the Voodoo board to use when creating
  * a new context.
  */
-GLboolean GLAPIENTRY fxMesaSelectCurrentBoard (int n)
+GLint GLAPIENTRY fxMesaSelectCurrentBoard (int n)
 {
    fxQueryHardware();
 
    if ((n < 0) || (n >= glbHWConfig.num_sst))
-      return GL_FALSE;
-
-   glbCurrentBoard = n;
+      return -1;
 
-   return GL_TRUE;
+   return glbHWConfig.SSTs[glbCurrentBoard = n].type;
 }
 
 
-void * GLAPIENTRY fxMesaGetCurrentContext (void)
+fxMesaContext GLAPIENTRY fxMesaGetCurrentContext (void)
 {
- GET_CURRENT_CONTEXT(ctx);
- return ctx;
+ return fxMesaCurrentCtx;
 }
 
 
@@ -160,7 +187,7 @@ gl3DfxSetPaletteEXT(GLuint * pal)
    if (TDFX_DEBUG & VERBOSE_DRIVER) {
       int i;
 
-      fprintf(stderr, "%s(...)\n", __FUNCTION__);
+      fprintf(stderr, "gl3DfxSetPaletteEXT(...)\n");
 
       for (i = 0; i < 256; i++) {
         fprintf(stderr, "\t%x\n", pal[i]);
@@ -177,32 +204,65 @@ gl3DfxSetPaletteEXT(GLuint * pal)
 
 static GrScreenResolution_t fxBestResolution (int width, int height)
 {
- static int resolutions[][5] = {
-        { 320,  200, GR_RESOLUTION_320x200  },
-        { 320,  240, GR_RESOLUTION_320x240  },
-        { 512,  384, GR_RESOLUTION_512x384  },
-        { 640,  400, GR_RESOLUTION_640x400  },
-        { 640,  480, GR_RESOLUTION_640x480  },
-        { 800,  600, GR_RESOLUTION_800x600  },
-        {1024,  768, GR_RESOLUTION_1024x768 },
-        {1280, 1024, GR_RESOLUTION_1280x1024},
-        {1600, 1200, GR_RESOLUTION_1600x1200},
+ static int resolutions[][3] = {
+        { GR_RESOLUTION_320x200,    320,  200 },
+        { GR_RESOLUTION_320x240,    320,  240 },
+        { GR_RESOLUTION_400x256,    400,  256 },
+        { GR_RESOLUTION_512x384,    512,  384 },
+        { GR_RESOLUTION_640x200,    640,  200 },
+        { GR_RESOLUTION_640x350,    640,  350 },
+        { GR_RESOLUTION_640x400,    640,  400 },
+        { GR_RESOLUTION_640x480,    640,  480 },
+        { GR_RESOLUTION_800x600,    800,  600 },
+        { GR_RESOLUTION_960x720,    960,  720 },
+        { GR_RESOLUTION_856x480,    856,  480 },
+        { GR_RESOLUTION_512x256,    512,  256 },
+        { GR_RESOLUTION_1024x768,  1024,  768 },
+        { GR_RESOLUTION_1280x1024, 1280, 1024 },
+        { GR_RESOLUTION_1600x1200, 1600, 1200 },
+        { GR_RESOLUTION_400x300,    400,  300 },
+        { GR_RESOLUTION_1152x864,  1152,  864 },
+        { GR_RESOLUTION_1280x960,  1280,  960 },
+        { GR_RESOLUTION_1600x1024, 1600, 1024 },
+        { GR_RESOLUTION_1792x1344, 1792, 1344 },
+        { GR_RESOLUTION_1856x1392, 1856, 1392 },
+        { GR_RESOLUTION_1920x1440, 1920, 1440 },
+        { GR_RESOLUTION_2048x1536, 2048, 1536 },
+        { GR_RESOLUTION_2048x2048, 2048, 2048 }
  };
 
- int i, NUM_RESOLUTIONS = sizeof(resolutions) / sizeof(resolutions[0]);
- int lastvalidres = 4;  /* set default to GR_RESOLUTION_640x480 */
+ int i, size;
+ int lastvalidres = GR_RESOLUTION_640x480;
  int min = 2048 * 2048; /* max is GR_RESOLUTION_2048x2048 */
-
- for (i = 0; i < NUM_RESOLUTIONS; i++) {
-     if ((width <= resolutions[i][0]) && (height <= resolutions[i][1])) {
-        if (min > (resolutions[i][0] * resolutions[i][1])) {
-           min = resolutions[i][0] * resolutions[i][1];
-           lastvalidres = i;
+ GrResolution resTemplate = {
+              GR_QUERY_ANY,
+              GR_QUERY_ANY,
+              2 /*GR_QUERY_ANY */,
+              GR_QUERY_ANY
+ };
+ GrResolution *presSupported;
+
+ fxQueryHardware();
+
+ size = grQueryResolutions(&resTemplate, NULL);
+ presSupported = malloc(size);
+        
+ size /= sizeof(GrResolution);
+ grQueryResolutions(&resTemplate, presSupported);
+
+ for (i = 0; i < size; i++) {
+     int r = presSupported[i].resolution;
+     if ((width <= resolutions[r][1]) && (height <= resolutions[r][2])) {
+        if (min > (resolutions[r][1] * resolutions[r][2])) {
+           min = resolutions[r][1] * resolutions[r][2];
+           lastvalidres = r;
         }
      }
  }
 
- return resolutions[lastvalidres][2];
+ free(presSupported);
+
+ return resolutions[lastvalidres][0];
 }
 
 
@@ -216,7 +276,7 @@ fxMesaCreateBestContext(GLuint win, GLint width, GLint height,
     return NULL;
  }
 
- return fxMesaCreateContext(win, res, GR_REFRESH_60Hz/*ZZZ: GR_REFRESH_75Hz*/, attribList);
+ return fxMesaCreateContext(win, res, GR_REFRESH_60Hz, attribList);
 }
 
 
@@ -230,10 +290,11 @@ fxMesaCreateContext(GLuint win,
 {
  fxMesaContext fxMesa = NULL;
  GLcontext *ctx = NULL, *shareCtx = NULL;
+ struct dd_function_table functions;
 
  int i;
  const char *str;
- int numChips, sliaa, fsaa;
+ int sliaa, numSLI, samplesPerChip;
  struct SstCard_St *voodoo;
  struct tdfx_glide *Glide;
 
@@ -244,15 +305,8 @@ fxMesaCreateContext(GLuint win,
  GLuint redBits, greenBits, blueBits, alphaBits;
  GrPixelFormat_t pixFmt;
    
- GLboolean useBGR;
- GLboolean verbose = GL_FALSE;
-
  if (TDFX_DEBUG & VERBOSE_DRIVER) {
-    fprintf(stderr, "%s(...)\n", __FUNCTION__);
- }
-
- if (getenv("MESA_FX_INFO")) {
-    verbose = GL_TRUE;
+    fprintf(stderr, "fxMesaCreateContext(...)\n");
  }
 
  /* Okay, first process the user flags */
@@ -288,32 +342,23 @@ fxMesaCreateContext(GLuint win,
                   break;
               /* XXX ugly hack here for sharing display lists */
               case FXMESA_SHARE_CONTEXT:
-                  {
-                   const void *vPtr = &attribList[++i];
-                   GLcontext **ctx = (GLcontext **)vPtr;
-                   shareCtx = *ctx;
-                   }
+                   shareCtx = (GLcontext *)attribList[++i];
                   break;
               default:
-                   fprintf(stderr, "%s: ERROR: wrong parameter (%d) passed\n", __FUNCTION__, attribList[i]);
+                   fprintf(stderr, "fxMesaCreateContext: ERROR: wrong parameter (%d) passed\n", attribList[i]);
                   return NULL;
        }
        i++;
  }
 
  if (!fxQueryHardware()) {
-    fprintf(stderr, "%s: ERROR: no Voodoo hardware!\n", __FUNCTION__);
-    return NULL;
+    str = "no Voodoo hardware!";
+    goto errorhandler;
  }
 
  grSstSelect(glbCurrentBoard);
- /*grEnable(GR_OPENGL_MODE_EXT);*/ /* ZZZ: trick to make GL happy.
-                                  Glide3 will unmap memory for card when grSstWinClose is called.
-                                  This also forces the SLI band height to be 32 (above 1024x768) or 16
-                                  and disables the splash screen due to y-origin swapping.
-                                  Note: We only want the former. */
+ /*grEnable(GR_OPENGL_MODE_EXT);*/ /* [koolsmoky] */
  voodoo = &glbHWConfig.SSTs[glbCurrentBoard];
- numChips = voodoo->numChips;
 
  fxMesa = (fxMesaContext)CALLOC_STRUCT(tfxMesaContext);
  if (!fxMesa) {
@@ -321,47 +366,161 @@ fxMesaCreateContext(GLuint win,
     goto errorhandler;
  }
 
+ if (getenv("MESA_FX_INFO")) {
+    fxMesa->verbose = GL_TRUE;
+ }
+
  fxMesa->type = voodoo->type;
- fxMesa->HavePixExt = voodoo->HavePixExt;
- fxMesa->HaveTexFmt = voodoo->HaveTexFmt;
- fxMesa->HaveCmbExt = voodoo->HaveCmbExt;
- fxMesa->HaveMirExt = voodoo->HaveMirExt;
- fxMesa->HaveTexus2 = voodoo->HaveTexus2;
+ fxMesa->HavePalExt = voodoo->HavePalExt && !getenv("MESA_FX_IGNORE_PALEXT");
+ fxMesa->HavePixExt = voodoo->HavePixExt && !getenv("MESA_FX_IGNORE_PIXEXT");
+ fxMesa->HaveTexFmt = voodoo->HaveTexFmt && !getenv("MESA_FX_IGNORE_TEXFMT");
+ fxMesa->HaveCmbExt = voodoo->HaveCmbExt && !getenv("MESA_FX_IGNORE_CMBEXT");
+ fxMesa->HaveMirExt = voodoo->HaveMirExt && !getenv("MESA_FX_IGNORE_MIREXT");
+ fxMesa->HaveTexUma = voodoo->HaveTexUma && !getenv("MESA_FX_IGNORE_TEXUMA");
  fxMesa->Glide = glbHWConfig.Glide;
  Glide = &fxMesa->Glide;
- sprintf(fxMesa->rendererString, "Mesa %s v0.51 %s %dMB FB, %dMB TM, %d TMU, %s",
-                           grGetString(GR_RENDERER),
-                           grGetString(GR_HARDWARE),
-                           voodoo->fbRam,
-                           (voodoo->tmuConfig[GR_TMU0].tmuRam + ((voodoo->nTexelfx > 1) ? voodoo->tmuConfig[GR_TMU1].tmuRam : 0)),
-                           voodoo->nTexelfx,
-                           (numChips > 1) ? "SLI" : "NOSLI");
-
- switch (fxMesa->colDepth = colDepth) {
-        case 15:
-             redBits = 5;
-             greenBits = 5;
-             blueBits = 5;
-             alphaBits = 1;
-             pixFmt = GR_PIXFMT_ARGB_1555;
-             break;
-        case 16:
-             redBits = 5;
-             greenBits = 6;
-             blueBits = 5;
-             alphaBits = depthSize ? 0 : 8;
-             pixFmt = GR_PIXFMT_RGB_565;
+ fxMesa->HaveTexus2 = Glide->txImgQuantize &&
+                      Glide->txMipQuantize &&
+                      Glide->txPalToNcc && !getenv("MESA_FX_IGNORE_TEXUS2");
+
+ /* Determine if we need vertex swapping, RGB order and SLI/AA */
+ sliaa = 0;
+ switch (fxMesa->type) {
+        case GR_SSTTYPE_VOODOO:
+        case GR_SSTTYPE_SST96:
+        case GR_SSTTYPE_Banshee:
+             fxMesa->bgrOrder = GL_TRUE;
+             fxMesa->snapVertices = (getenv("MESA_FX_NOSNAP") == NULL);
              break;
-        case 32:
-             redBits = 8;
-             greenBits = 8;
-             blueBits = 8;
-             alphaBits = 8;
-             pixFmt = GR_PIXFMT_ARGB_8888;
+        case GR_SSTTYPE_Voodoo2:
+             fxMesa->bgrOrder = GL_TRUE;
+             fxMesa->snapVertices = GL_FALSE;
              break;
+        case GR_SSTTYPE_Voodoo4:
+        case GR_SSTTYPE_Voodoo5:
+             /* number of SLI units and AA Samples per chip */
+             if ((str = Glide->grGetRegistryOrEnvironmentStringExt("SSTH3_SLI_AA_CONFIGURATION")) != NULL) {
+                sliaa = atoi(str);
+             }
+        case GR_SSTTYPE_Voodoo3:
         default:
-             str = "pixelFormat";
-             goto errorhandler;
+             fxMesa->bgrOrder = GL_FALSE;
+             fxMesa->snapVertices = GL_FALSE;
+             break;
+ }
+ /* XXX todo - Add the old SLI/AA settings for Napalm. */
+ switch(voodoo->numChips) {
+ case 4: /* 4 chips */
+   switch(sliaa) {
+   case 8: /* 8 Sample AA */
+     numSLI         = 1;
+     samplesPerChip = 2;
+     break;
+   case 7: /* 4 Sample AA */
+     numSLI         = 1;
+     samplesPerChip = 1;
+     break;
+   case 6: /* 2 Sample AA */
+     numSLI         = 2;
+     samplesPerChip = 1;
+     break;
+   default:
+     numSLI         = 4;
+     samplesPerChip = 1;
+   }
+   break;
+ case 2: /* 2 chips */
+   switch(sliaa) {
+   case 4: /* 4 Sample AA */
+     numSLI         = 1;
+     samplesPerChip = 2;
+     break;
+   case 3: /* 2 Sample AA */
+     numSLI         = 1;
+     samplesPerChip = 1;
+     break;
+   default:
+     numSLI         = 2;
+     samplesPerChip = 1;
+   }
+   break;
+ default: /* 1 chip */
+   switch(sliaa) {
+   case 1: /* 2 Sample AA */
+     numSLI         = 1;
+     samplesPerChip = 2;
+     break;
+   default:
+     numSLI         = 1;
+     samplesPerChip = 1;
+   }
+ }
+
+ fxMesa->fsaa = samplesPerChip * voodoo->numChips / numSLI; /* 1:noFSAA, 2:2xFSAA, 4:4xFSAA, 8:8xFSAA */
+
+ switch (fxMesa->colDepth = colDepth) {
+   case 15:
+     redBits   = 5;
+     greenBits = 5;
+     blueBits  = 5;
+     alphaBits = depthSize ? 1 : 8;
+     switch(fxMesa->fsaa) {
+       case 8:
+         pixFmt = GR_PIXFMT_AA_8_ARGB_1555;
+         break;
+       case 4:
+         pixFmt = GR_PIXFMT_AA_4_ARGB_1555;
+         break;
+       case 2:
+         pixFmt = GR_PIXFMT_AA_2_ARGB_1555;
+         break;
+       default:
+         pixFmt = GR_PIXFMT_ARGB_1555;
+     }
+     break;
+   case 16:
+     redBits   = 5;
+     greenBits = 6;
+     blueBits  = 5;
+     alphaBits = depthSize ? 0 : 8;
+     switch(fxMesa->fsaa) {
+       case 8:
+         pixFmt = GR_PIXFMT_AA_8_RGB_565;
+         break;
+       case 4:
+         pixFmt = GR_PIXFMT_AA_4_RGB_565;
+         break;
+       case 2:
+         pixFmt = GR_PIXFMT_AA_2_RGB_565;
+         break;
+       default:
+         pixFmt = GR_PIXFMT_RGB_565;
+     }
+     break;
+   case 24:
+     fxMesa->colDepth = 32;
+   case 32:
+     redBits   = 8;
+     greenBits = 8;
+     blueBits  = 8;
+     alphaBits = 8;
+     switch(fxMesa->fsaa) {
+       case 8:
+         pixFmt = GR_PIXFMT_AA_8_ARGB_8888;
+         break;
+       case 4:
+         pixFmt = GR_PIXFMT_AA_4_ARGB_8888;
+         break;
+       case 2:
+         pixFmt = GR_PIXFMT_AA_2_ARGB_8888;
+         break;
+       default:
+         pixFmt = GR_PIXFMT_ARGB_8888;
+     }
+     break;
+   default:
+     str = "pixelFormat";
+     goto errorhandler;
  }
 
  /* Tips:
@@ -391,7 +550,6 @@ fxMesaCreateContext(GLuint win,
  fxMesa->haveZBuffer = depthSize > 0;
  fxMesa->haveDoubleBuffer = doubleBuffer;
  fxMesa->haveGlobalPaletteTexture = GL_FALSE;
- fxMesa->verbose = verbose;
  fxMesa->board = glbCurrentBoard;
 
  fxMesa->haveTwoTMUs = (voodoo->nTexelfx > 1);
@@ -404,8 +562,8 @@ fxMesaCreateContext(GLuint win,
 
  if ((str = Glide->grGetRegistryOrEnvironmentStringExt("FX_GLIDE_SWAPPENDINGCOUNT"))) {
     fxMesa->maxPendingSwapBuffers = atoi(str);
-    if (fxMesa->maxPendingSwapBuffers > 3) {
-       fxMesa->maxPendingSwapBuffers = 3;
+    if (fxMesa->maxPendingSwapBuffers > 6) {
+       fxMesa->maxPendingSwapBuffers = 6;
     } else if (fxMesa->maxPendingSwapBuffers < 0) {
        fxMesa->maxPendingSwapBuffers = 0;
     }
@@ -419,60 +577,6 @@ fxMesaCreateContext(GLuint win,
     fxMesa->swapInterval = 0;
  }
 
- if ((str = Glide->grGetRegistryOrEnvironmentStringExt("SSTH3_SLI_AA_CONFIGURATION"))) {
-    sliaa = atoi(str);
- } else {
-    sliaa = 0;
- }
- switch (colDepth) {
-        case 15:
-             if ((numChips == 4) && (sliaa == 8)) {
-                pixFmt = GR_PIXFMT_AA_8_ARGB_1555;
-                fsaa = 8;
-             } else if (((numChips == 4) && (sliaa == 7)) || ((numChips == 2) && (sliaa == 4))) {
-                pixFmt = GR_PIXFMT_AA_4_ARGB_1555;
-                fsaa = 4;
-             } else if (((numChips == 4) && (sliaa == 6)) || ((numChips == 2) && (sliaa == 3)) || ((numChips == 1) && (sliaa == 1))) {
-                pixFmt = GR_PIXFMT_AA_2_ARGB_1555;
-                fsaa = 2;
-             } else {
-                fsaa = 0;
-             }
-             break;
-        case 16:
-             if ((numChips == 4) && (sliaa == 8)) {
-                pixFmt = GR_PIXFMT_AA_8_RGB_565;
-                fsaa = 8;
-             } else if (((numChips == 4) && (sliaa == 7)) || ((numChips == 2) && (sliaa == 4))) {
-                pixFmt = GR_PIXFMT_AA_4_RGB_565;
-                fsaa = 4;
-             } else if (((numChips == 4) && (sliaa == 6)) || ((numChips == 2) && (sliaa == 3)) || ((numChips == 1) && (sliaa == 1))) {
-                pixFmt = GR_PIXFMT_AA_2_RGB_565;
-                fsaa = 2;
-             } else {
-                fsaa = 0;
-             }
-             break;
-        case 32:
-             if ((numChips == 4) && (sliaa == 8)) {
-                pixFmt = GR_PIXFMT_AA_8_ARGB_8888;
-                fsaa = 8;
-             } else if (((numChips == 4) && (sliaa == 7)) || ((numChips == 2) && (sliaa == 4))) {
-                pixFmt = GR_PIXFMT_AA_4_ARGB_8888;
-                fsaa = 4;
-             } else if (((numChips == 4) && (sliaa == 6)) || ((numChips == 2) && (sliaa == 3)) || ((numChips == 1) && (sliaa == 1))) {
-                pixFmt = GR_PIXFMT_AA_2_ARGB_8888;
-                fsaa = 2;
-             } else {
-                fsaa = 0;
-             }
-             break;
-        default: /* NOTREACHED */
-             str = "pixelFormat";
-             goto errorhandler;
- }
- fxMesa->fsaa = fsaa;
-
  BEGIN_BOARD_LOCK();
  if (fxMesa->HavePixExt) {
     fxMesa->glideContext = Glide->grSstWinOpenExt((FxU32)win, res, ref,
@@ -492,62 +596,54 @@ fxMesaCreateContext(GLuint win,
     goto errorhandler;
  }
 
-   /*
-    * Pixel tables are used during pixel read-back
-    * Either initialize them for RGB or BGR order;
-    * However, 32bit capable cards have the right order.
-    * As a consequence, 32bit read-back is not swizzled!
-    * Also determine if we need vertex snapping.
-    */
-   switch (voodoo->type) {
-          case GR_SSTTYPE_VOODOO:
-          case GR_SSTTYPE_Banshee:
-               useBGR = GL_TRUE;
-               fxMesa->snapVertices = GL_TRUE;
-               break;
-          case GR_SSTTYPE_Voodoo2:
-               useBGR = GL_TRUE;
-               fxMesa->snapVertices = GL_FALSE;
-               break;
-          case GR_SSTTYPE_Voodoo3:
-          case GR_SSTTYPE_Voodoo4:
-          case GR_SSTTYPE_Voodoo5:
-          default:
-               useBGR = GL_FALSE;
-               fxMesa->snapVertices = GL_FALSE;
-               break;
-   }
+   /* screen */
+   fxMesa->screen_width = FX_grSstScreenWidth();
+   fxMesa->screen_height = FX_grSstScreenHeight();
 
-   fxInitPixelTables(fxMesa, useBGR);
-
-   fxMesa->width = FX_grSstScreenWidth();
-   fxMesa->height = FX_grSstScreenHeight();
+   /* window inside screen */
+   fxMesa->width = fxMesa->screen_width;
+   fxMesa->height = fxMesa->screen_height;
 
+   /* scissor inside window */
    fxMesa->clipMinX = 0;
    fxMesa->clipMaxX = fxMesa->width;
    fxMesa->clipMinY = 0;
    fxMesa->clipMaxY = fxMesa->height;
 
-   fxMesa->screen_width = fxMesa->width;
-   fxMesa->screen_height = fxMesa->height;
-
-   if (verbose) {
-      char buf[80];
-
-      strcpy(buf, grGetString(GR_VERSION));
-      fprintf(stderr, "Voodoo Using Glide %s\n", buf);
-      fprintf(stderr, "Voodoo Number of boards: %d\n", glbHWConfig.num_sst);
-      fprintf(stderr, "Voodoo Number of TMUs: %d\n", voodoo->nTexelfx);
-      fprintf(stderr, "Voodoo fbRam: %d\n", voodoo->fbRam);
-      fprintf(stderr, "Voodoo fbiRev: %d\n", voodoo->fbiRev);
-      fprintf(stderr, "Voodoo chips detected: %d\n", voodoo->numChips);
-      fprintf(stderr, "Voodoo pixel order = %s, vertex snapping = %d\n",
-                      useBGR ? "BGR" : "RGB",
-                      fxMesa->snapVertices);
-      fprintf(stderr, "Voodoo screen: %dx%d.%d\n",
-                     fxMesa->screen_width, fxMesa->screen_height, colDepth);
+   if (fxMesa->verbose) {
+      FxI32 tmuRam, fbRam;
+
+      /* Not that it matters, but tmuRam and fbRam change after grSstWinOpen. */
+      tmuRam = voodoo->tmuConfig[GR_TMU0].tmuRam;
+      fbRam  = voodoo->fbRam;
+      BEGIN_BOARD_LOCK();
+      grGet(GR_MEMORY_TMU, 4, &tmuRam);
+      grGet(GR_MEMORY_FB, 4, &fbRam);
+      END_BOARD_LOCK();
+
+      fprintf(stderr, "Voodoo Using Glide %s\n", grGetString(GR_VERSION));
+      fprintf(stderr, "Voodoo Board: %d/%d, %s, %d GPU\n",
+                      fxMesa->board + 1,
+                      glbHWConfig.num_sst,
+                      grGetString(GR_HARDWARE),
+                      voodoo->numChips);
+      fprintf(stderr, "Voodoo Memory: FB = %ld, TM = %d x %ld\n",
+                      fbRam,
+                      voodoo->nTexelfx,
+                      tmuRam);
+      fprintf(stderr, "Voodoo Screen: %dx%d:%d %s, %svertex snapping\n",
+                     fxMesa->screen_width,
+                      fxMesa->screen_height,
+                      colDepth,
+                      fxMesa->bgrOrder ? "BGR" : "RGB",
+                      fxMesa->snapVertices ? "" : "no ");
    }
 
+  sprintf(fxMesa->rendererString, "Mesa %s v0.63 %s%s",
+          grGetString(GR_RENDERER),
+          grGetString(GR_HARDWARE),
+          ((fxMesa->type < GR_SSTTYPE_Voodoo4) && (voodoo->numChips > 1)) ? " SLI" : "");
+
    fxMesa->glVis = _mesa_create_visual(GL_TRUE,                /* RGB mode */
                                       doubleBuffer,
                                       GL_FALSE,        /* stereo */
@@ -568,9 +664,9 @@ fxMesaCreateContext(GLuint win,
       goto errorhandler;
    }
 
-   ctx = fxMesa->glCtx = _mesa_create_context(fxMesa->glVis,
-                                              shareCtx,
-                                             (void *) fxMesa, GL_TRUE);
+   _mesa_init_driver_functions(&functions);
+   ctx = fxMesa->glCtx = _mesa_create_context(fxMesa->glVis, shareCtx,
+                                             &functions, (void *) fxMesa);
    if (!ctx) {
       str = "_mesa_create_context";
       goto errorhandler;
@@ -583,11 +679,17 @@ fxMesaCreateContext(GLuint win,
    }
 
 
-   fxMesa->glBuffer = _mesa_create_framebuffer(fxMesa->glVis,
+   fxMesa->glBuffer = _mesa_create_framebuffer(fxMesa->glVis);
+#if 0
+/* XXX this is a complete mess :(
+ *     _mesa_add_soft_renderbuffers
+ *     driNewRenderbuffer
+ */
                                               GL_FALSE,        /* no software depth */
                                               stencilSize && !fxMesa->haveHwStencil,
                                               fxMesa->glVis->accumRedBits > 0,
                                               alphaSize && !fxMesa->haveHwAlpha);
+#endif
    if (!fxMesa->glBuffer) {
       str = "_mesa_create_framebuffer";
       goto errorhandler;
@@ -598,7 +700,7 @@ fxMesaCreateContext(GLuint win,
    /* install signal handlers */
 #if defined(__linux__)
    /* Only install if environment var. is not set. */
-   if (fxMesa->glCtx->CatchSignals && !getenv("MESA_FX_NO_SIGNALS")) {
+   if (!getenv("MESA_FX_NO_SIGNALS")) {
       signal(SIGINT, cleangraphics_handler);
       signal(SIGHUP, cleangraphics_handler);
       signal(SIGPIPE, cleangraphics_handler);
@@ -637,7 +739,7 @@ errorhandler:
     FREE(fxMesa);
  }
 
- fprintf(stderr, "%s: ERROR: %s\n", __FUNCTION__, str);
+ fprintf(stderr, "fxMesaCreateContext: ERROR: %s\n", str);
  return NULL;
 }
 
@@ -660,7 +762,7 @@ void GLAPIENTRY
 fxMesaDestroyContext(fxMesaContext fxMesa)
 {
    if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s(...)\n", __FUNCTION__);
+      fprintf(stderr, "fxMesaDestroyContext(...)\n");
    }
 
    if (!fxMesa)
@@ -674,10 +776,10 @@ fxMesaDestroyContext(fxMesaContext fxMesa)
         fxMesa->stats.swapBuffer = 1;
 
       fprintf(stderr, "Textures Stats:\n");
-      fprintf(stderr, "  Free texture memory on TMU0: %d:\n",
+      fprintf(stderr, "  Free texture memory on TMU0: %d\n",
              fxMesa->freeTexMem[FX_TMU0]);
       if (fxMesa->haveTwoTMUs)
-        fprintf(stderr, "  Free texture memory on TMU1: %d:\n",
+        fprintf(stderr, "  Free texture memory on TMU1: %d\n",
                 fxMesa->freeTexMem[FX_TMU1]);
       fprintf(stderr, "  # request to TMM to upload a texture objects: %u\n",
              fxMesa->stats.reqTexUpload);
@@ -698,14 +800,37 @@ fxMesaDestroyContext(fxMesaContext fxMesa)
 
    glbTotNumCtx--;
 
-   fxDDDestroyFxMesaContext(fxMesa);
-   _mesa_destroy_visual(fxMesa->glVis);
-   _mesa_destroy_context(fxMesa->glCtx);
-   _mesa_destroy_framebuffer(fxMesa->glBuffer);
+   if (!glbTotNumCtx && getenv("MESA_FX_INFO")) {
+      GrSstPerfStats_t st;
+
+      FX_grSstPerfStats(&st);
 
+      fprintf(stderr, "Pixels Stats:\n");
+      fprintf(stderr, "  # pixels processed (minus buffer clears): %u\n",
+              (unsigned) st.pixelsIn);
+      fprintf(stderr, "  # pixels not drawn due to chroma key test failure: %u\n",
+              (unsigned) st.chromaFail);
+      fprintf(stderr, "  # pixels not drawn due to depth test failure: %u\n",
+              (unsigned) st.zFuncFail);
+      fprintf(stderr,
+              "  # pixels not drawn due to alpha test failure: %u\n",
+              (unsigned) st.aFuncFail);
+      fprintf(stderr, "  # pixels drawn (including buffer clears and LFB writes): %u\n",
+              (unsigned) st.pixelsOut);
+   }
+
+   /* close the hardware first,
+    * so we can debug atexit problems (memory leaks, etc).
+    */
    grSstWinClose(fxMesa->glideContext);
    fxCloseHardware();
 
+   fxDDDestroyFxMesaContext(fxMesa); /* must be before _mesa_destroy_context */
+   _mesa_destroy_visual(fxMesa->glVis);
+   _mesa_destroy_context(fxMesa->glCtx);
+   _mesa_destroy_framebuffer(fxMesa->glBuffer);
+   fxTMClose(fxMesa); /* must be after _mesa_destroy_context */
+
    FREE(fxMesa);
 
    if (fxMesa == fxMesaCurrentCtx)
@@ -720,11 +845,11 @@ void GLAPIENTRY
 fxMesaMakeCurrent(fxMesaContext fxMesa)
 {
    if (!fxMesa) {
-      _mesa_make_current(NULL, NULL);
+      _mesa_make_current(NULL, NULL, NULL);
       fxMesaCurrentCtx = NULL;
 
       if (TDFX_DEBUG & VERBOSE_DRIVER) {
-        fprintf(stderr, "%s(NULL)\n", __FUNCTION__);
+        fprintf(stderr, "fxMesaMakeCurrent(NULL)\n");
       }
 
       return;
@@ -734,14 +859,14 @@ fxMesaMakeCurrent(fxMesaContext fxMesa)
    if (fxMesaCurrentCtx == fxMesa
        && fxMesaCurrentCtx->glCtx == _mesa_get_current_context()) {
       if (TDFX_DEBUG & VERBOSE_DRIVER) {
-        fprintf(stderr, "%s(fxMesaCurrentCtx==fxMesa)\n", __FUNCTION__);
+        fprintf(stderr, "fxMesaMakeCurrent(NOP)\n");
       }
 
       return;
    }
 
    if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s(...)\n", __FUNCTION__);
+      fprintf(stderr, "fxMesaMakeCurrent(...)\n");
    }
 
    if (fxMesaCurrentCtx)
@@ -752,13 +877,9 @@ fxMesaMakeCurrent(fxMesaContext fxMesa)
    grSstSelect(fxMesa->board);
    grGlideSetState((GrState *) fxMesa->state);
 
-   _mesa_make_current(fxMesa->glCtx, fxMesa->glBuffer);
+   _mesa_make_current(fxMesa->glCtx, fxMesa->glBuffer, fxMesa->glBuffer);
 
    fxSetupDDPointers(fxMesa->glCtx);
-
-   /* The first time we call MakeCurrent we set the initial viewport size */
-   if (fxMesa->glCtx->Viewport.Width == 0)
-      _mesa_set_viewport(fxMesa->glCtx, 0, 0, fxMesa->width, fxMesa->height);
 }
 
 
@@ -769,7 +890,7 @@ void GLAPIENTRY
 fxMesaSwapBuffers(void)
 {
    if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s()\n", __FUNCTION__);
+      fprintf(stderr, "fxMesaSwapBuffers()\n");
    }
 
    if (fxMesaCurrentCtx) {
@@ -779,6 +900,7 @@ fxMesaSwapBuffers(void)
 
         grBufferSwap(fxMesaCurrentCtx->swapInterval);
 
+#if 0
         /*
          * Don't allow swap buffer commands to build up!
          */
@@ -790,6 +912,7 @@ fxMesaSwapBuffers(void)
               in order to enable this option) */
            /* usleep(10000); */
            ;
+#endif
 
         fxMesaCurrentCtx->stats.swapBuffer++;
       }
@@ -797,35 +920,6 @@ fxMesaSwapBuffers(void)
 }
 
 
-/*
- * Query 3Dfx hardware presence/kind
- */
-GLboolean GLAPIENTRY fxQueryHardware (void)
-{
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
-    fprintf(stderr, "%s()\n", __FUNCTION__);
- }
-
- if (!glbGlideInitialized) {
-    grGlideInit();
-    glb3DfxPresent = FX_grSstQueryHardware(&glbHWConfig);
-
-    glbGlideInitialized = 1;
-
-#if defined(__WIN32__)
-    _onexit((_onexit_t) cleangraphics);
-#elif defined(__linux__)
-    /* Only register handler if environment variable is not defined. */
-    if (!getenv("MESA_FX_NO_SIGNALS")) {
-       atexit(cleangraphics);
-    }
-#endif
- }
-
- return glb3DfxPresent;
-}
-
-
 /*
  * Shutdown Glide library
  */
@@ -833,27 +927,6 @@ void GLAPIENTRY
 fxCloseHardware(void)
 {
    if (glbGlideInitialized) {
-      if (fxMesaCurrentCtx && fxMesaCurrentCtx->verbose) {
-        GrSstPerfStats_t st;
-
-        FX_grSstPerfStats(&st);
-        fprintf(stderr, "Pixels Stats:\n");
-        fprintf(stderr, "  # pixels processed (minus buffer clears): %u\n",
-                (unsigned) st.pixelsIn);
-        fprintf(stderr,
-                "  # pixels not drawn due to chroma key test failure: %u\n",
-                (unsigned) st.chromaFail);
-        fprintf(stderr,
-                "  # pixels not drawn due to depth test failure: %u\n",
-                (unsigned) st.zFuncFail);
-        fprintf(stderr,
-                "  # pixels not drawn due to alpha test failure: %u\n",
-                (unsigned) st.aFuncFail);
-        fprintf(stderr,
-                "  # pixels drawn (including buffer clears and LFB writes): %u\n",
-                (unsigned) st.pixelsOut);
-      }
-
       if (glbTotNumCtx == 0) {
         grGlideShutdown();
         glbGlideInitialized = 0;