mesa: Branch 'master' - 6 commits

George Sapountzis gsap7 at kemper.freedesktop.org
Fri Apr 20 18:09:58 UTC 2007


 src/mesa/drivers/x11/fakeglx.c  |   17 ++
 src/mesa/drivers/x11/xm_api.c   |   82 ++++++-----
 src/mesa/drivers/x11/xm_glide.c |  276 ++++++++++++++++++++++++++++++++++++++++
 src/mesa/drivers/x11/xm_glide.h |   40 +++++
 src/mesa/drivers/x11/xmesaP.h   |   13 +
 5 files changed, 392 insertions(+), 36 deletions(-)

New commits:
diff-tree 5491c8194c03761a1a45a17539db6bc241bacf9c (from e4e2068ac9d21ce50e863ccf3171462ab61c3ec8)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Fri Apr 20 18:51:20 2007 +0300

    xmesa: call _glapi_set_dispatch() for all xserver DDXes.
    
    This is to unify the xmesa code across xserver DDX'es. The call is intented for
    XGL, but it does not hurt to call for other DDX'es. In fact it was not guarded
    against XGL when it was first added in xserver.

diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index 212f7b5..a07d0a9 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -1869,9 +1869,7 @@ PUBLIC
 GLboolean XMesaForceCurrent(XMesaContext c)
 {
    if (c) {
-#ifdef XGLServer
       _glapi_set_dispatch(c->mesa.CurrentDispatch);
-#endif
 
       if (&(c->mesa) != _mesa_get_current_context()) {
 	 _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer);
diff-tree e4e2068ac9d21ce50e863ccf3171462ab61c3ec8 (from 6346a753c6e77373cffcec6dd0df253efd159dd4)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Wed Apr 18 23:44:01 2007 +0300

    xmesa: minor cosmetic
    
    mainly drop 'client' argument from initialize_visual_and_buffer().

diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index 5e2327a..212f7b5 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -1036,10 +1036,16 @@ setup_monochrome( XMesaVisual v, XMesaBu
  * \return GL_TRUE=success, GL_FALSE=failure
  */
 static GLboolean
-initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b,
+initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
                              GLboolean rgb_flag, XMesaDrawable window,
                              XMesaColormap cmap)
 {
+   int client = 0;
+
+#ifdef XFree86Server
+   client = (window) ? CLIENT_ID(window->id) : 0;
+#endif
+
    ASSERT(!b || b->xm_visual == v);
 
    /* Save true bits/pixel */
@@ -1103,6 +1109,8 @@ initialize_visual_and_buffer(int client,
    }
 
    if (b && window) {
+      char *data;
+
       /* Do window-specific initializations */
 
       /* these should have been set in create_xmesa_buffer */
@@ -1170,15 +1178,15 @@ initialize_visual_and_buffer(int client,
       }
 
       /* Initialize the row buffer XImage for use in write_color_span() */
+      data = (char*) MALLOC(MAX_WIDTH*4);
 #ifdef XFree86Server
-      b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1,
-				     (char *)MALLOC(MAX_WIDTH*4));
+      b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1, data);
 #else
       b->rowimage = XCreateImage( v->display,
                                   v->visinfo->visual,
                                   v->visinfo->depth,
                                   ZPixmap, 0,           /*format, offset*/
-                                  (char*) MALLOC(MAX_WIDTH*4),  /*data*/
+                                  data,                 /*data*/
                                   MAX_WIDTH, 1,         /*width, height*/
                                   32,                   /*bitmap_pad*/
                                   0                     /*bytes_per_line*/ );
@@ -1410,7 +1418,7 @@ XMesaVisual XMesaCreateVisual( XMesaDisp
    if (alpha_flag)
       v->mesa_visual.alphaBits = 8;
 
-   (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 );
+   (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 );
 
    {
       const int xclass = v->mesa_visual.visualType;
@@ -1585,31 +1593,25 @@ XMesaCreateWindowBuffer(XMesaVisual v, X
 #ifndef XFree86Server
    XWindowAttributes attr;
 #endif
-   int client = 0;
    XMesaBuffer b;
    XMesaColormap cmap;
+   int depth;
 
    assert(v);
    assert(w);
 
    /* Check that window depth matches visual depth */
 #ifdef XFree86Server
-   client = CLIENT_ID(((XMesaDrawable)w)->id);
-
-   if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) {
-      _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
-                    GET_VISUAL_DEPTH(v), ((XMesaDrawable) w)->depth);
-      return NULL;
-   }
+   depth = ((XMesaDrawable)w)->depth;
 #else
    XGetWindowAttributes( v->display, w, &attr );
-
-   if (GET_VISUAL_DEPTH(v) != attr.depth) {
+   depth = attr.depth;
+#endif
+   if (GET_VISUAL_DEPTH(v) != depth) {
       _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
-                    GET_VISUAL_DEPTH(v), attr.depth);
+                    GET_VISUAL_DEPTH(v), depth);
       return NULL;
    }
-#endif
 
    /* Find colormap */
 #ifdef XFree86Server
@@ -1630,7 +1632,7 @@ XMesaCreateWindowBuffer(XMesaVisual v, X
    if (!b)
       return NULL;
 
-   if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
+   if (!initialize_visual_and_buffer( v, b, v->mesa_visual.rgbMode,
                                       (XMesaDrawable) w, cmap )) {
       xmesa_free_buffer(b);
       return NULL;
@@ -1653,7 +1655,6 @@ XMesaCreateWindowBuffer(XMesaVisual v, X
 PUBLIC XMesaBuffer
 XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
 {
-   int client = 0;
    XMesaBuffer b;
 
    assert(v);
@@ -1662,11 +1663,7 @@ XMesaCreatePixmapBuffer(XMesaVisual v, X
    if (!b)
       return NULL;
 
-#ifdef XFree86Server
-   client = CLIENT_ID(((XMesaDrawable)p)->id);
-#endif
-
-   if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
+   if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
 				     (XMesaDrawable) p, cmap)) {
       xmesa_free_buffer(b);
       return NULL;
@@ -1681,10 +1678,7 @@ XMesaBuffer
 XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
                    unsigned int width, unsigned int height)
 {
-#ifdef XFree86Server
-   return 0;
-#else
-   int client = 0;
+#ifndef XFree86Server
    XMesaWindow root;
    XMesaDrawable drawable;  /* X Pixmap Drawable */
    XMesaBuffer b;
@@ -1700,13 +1694,15 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaC
    if (!b)
       return NULL;
 
-   if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
+   if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
 				     drawable, cmap)) {
       xmesa_free_buffer(b);
       return NULL;
    }
 
    return b;
+#else
+   return 0;
 #endif
 }
 
diff-tree 6346a753c6e77373cffcec6dd0df253efd159dd4 (from 4d944b502f8a1ae372d9248e888612bffb5eb6a5)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Fri Apr 20 18:25:42 2007 +0300

    xmesa: split FX functions to separate file, part 2.

diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index 692eb5f..5e2327a 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -1557,12 +1557,11 @@ PUBLIC
 void XMesaDestroyContext( XMesaContext c )
 {
    GLcontext *mesaCtx = &c->mesa;
-#ifdef FX
-   XMesaBuffer xmbuf = XMESA_BUFFER(mesaCtx->DrawBuffer);
 
-   if (xmbuf && xmbuf->FXctx)
-      fxMesaDestroyContext(xmbuf->FXctx);
+#ifdef FX
+   FXdestroyContext( XMESA_BUFFER(mesaCtx->DrawBuffer) );
 #endif
+
    _swsetup_DestroyContext( mesaCtx );
    _swrast_DestroyContext( mesaCtx );
    _tnl_DestroyContext( mesaCtx );
@@ -1767,15 +1766,6 @@ GLboolean XMesaMakeCurrent2( XMesaContex
       if (!drawBuffer || !readBuffer)
          return GL_FALSE;  /* must specify buffers! */
 
-#ifdef FX
-      if (drawBuffer->FXctx) {
-         fxMesaMakeCurrent(drawBuffer->FXctx);
-
-         c->xm_buffer = drawBuffer;
-
-         return GL_TRUE;
-      }
-#endif
       if (&(c->mesa) == _mesa_get_current_context()
           && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
           && c->mesa.ReadBuffer == &readBuffer->mesa_buffer
@@ -1786,6 +1776,11 @@ GLboolean XMesaMakeCurrent2( XMesaContex
 
       c->xm_buffer = drawBuffer;
 
+#ifdef FX
+      if (FXmakeCurrent( drawBuffer ))
+         return GL_TRUE;
+#endif
+
       /* Call this periodically to detect when the user has begun using
        * GL rendering from multiple threads.
        */
diff --git a/src/mesa/drivers/x11/xm_glide.c b/src/mesa/drivers/x11/xm_glide.c
index 37787a7..ae4f428 100644
--- a/src/mesa/drivers/x11/xm_glide.c
+++ b/src/mesa/drivers/x11/xm_glide.c
@@ -27,6 +27,8 @@
 #include "xmesaP.h"
 
 #ifdef FX
+#include "../glide/fxdrv.h"
+
 void
 FXcreateContext(XMesaVisual v, XMesaWindow w, XMesaContext c, XMesaBuffer b)
 {
@@ -109,6 +111,24 @@ FXcreateContext(XMesaVisual v, XMesaWind
 }
 
 
+void FXdestroyContext( XMesaBuffer b )
+{
+   if (b && b->FXctx)
+      fxMesaDestroyContext(b->FXctx);
+}
+
+
+GLboolean FXmakeCurrent( XMesaBuffer b )
+{
+   if (b->FXctx) {
+      fxMesaMakeCurrent(b->FXctx);
+
+      return GL_TRUE;
+   }
+   return GL_FALSE;
+}
+
+
 /*
  * Read image from VooDoo frame buffer into X/Mesa's back XImage.
  */
@@ -118,7 +138,6 @@ static void FXgetImage( XMesaBuffer b )
    static unsigned short pixbuf[MAX_WIDTH];
    GLuint x, y;
    GLuint width, height;
-   XMesaContext xmesa = XMESA_CONTEXT(ctx);
 
 #ifdef XFree86Server
    x = b->frontxrb->pixmap->x;
diff --git a/src/mesa/drivers/x11/xm_glide.h b/src/mesa/drivers/x11/xm_glide.h
index 7458c57..f7d0316 100644
--- a/src/mesa/drivers/x11/xm_glide.h
+++ b/src/mesa/drivers/x11/xm_glide.h
@@ -31,6 +31,10 @@ extern void FXcreateContext( XMesaVisual
                              XMesaContext c,
                              XMesaBuffer b );
 
+extern void FXdestroyContext( XMesaBuffer b );
+
+extern GLboolean FXmakeCurrent( XMesaBuffer b );
+
 extern GLboolean FXswapBuffers( XMesaBuffer b );
 
 #endif /* _XM_GLIDE_H_ */
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
index cae5c0d..0198886 100644
--- a/src/mesa/drivers/x11/xmesaP.h
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -31,7 +31,6 @@
 #include "mtypes.h"
 #if defined(FX)
 #include "GL/fxmesa.h"
-#include "../glide/fxdrv.h"
 #include "xm_glide.h"
 #endif
 #ifdef XFree86Server
diff-tree 4d944b502f8a1ae372d9248e888612bffb5eb6a5 (from 6aa5668871e7f366b33e85fabc72885fc269a7d4)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Fri Apr 20 18:12:38 2007 +0300

    xmesa: split FX functions to separate file, part 1.

diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index 3e65ebd..692eb5f 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -1640,88 +1640,6 @@ XMesaCreateWindowBuffer(XMesaVisual v, X
    return b;
 }
 
-#ifdef FX
-void
-FXcreateContext(XMesaVisual v, XMesaWindow w, XMesaContext c, XMesaBuffer b)
-{
-   char *fxEnvVar = _mesa_getenv("MESA_GLX_FX");
-   if (fxEnvVar) {
-     if (fxEnvVar[0]!='d') {
-       int attribs[100];
-       int numAttribs = 0;
-       int hw;
-       if (v->mesa_visual.depthBits > 0) {
-	 attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
-	 attribs[numAttribs++] = v->mesa_visual.depthBits;
-       }
-       if (v->mesa_visual.doubleBufferMode) {
-	 attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
-       }
-       if (v->mesa_visual.accumRedBits > 0) {
-	 attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
-	 attribs[numAttribs++] = v->mesa_visual.accumRedBits;
-       }
-       if (v->mesa_visual.stencilBits > 0) {
-         attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
-         attribs[numAttribs++] = v->mesa_visual.stencilBits;
-       }
-       if (v->mesa_visual.alphaBits > 0) {
-         attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
-         attribs[numAttribs++] = v->mesa_visual.alphaBits;
-       }
-       if (1) {
-         attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
-         attribs[numAttribs++] = (int) &(c->mesa);
-       }
-       attribs[numAttribs++] = FXMESA_NONE;
-
-       /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */
-       hw = fxMesaSelectCurrentBoard(0);
-
-       /* if these fail, there's a new bug somewhere */
-       ASSERT(b->mesa_buffer.Width > 0);
-       ASSERT(b->mesa_buffer.Height > 0);
-
-       if ((hw == GR_SSTTYPE_VOODOO) || (hw == GR_SSTTYPE_Voodoo2)) {
-         b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
-                                            b->mesa_buffer.Height, attribs);
-         if ((v->undithered_pf!=PF_Index) && (b->backxrb->ximage)) {
-	   b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
-	   if (b->FXctx && (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')) {
-	     b->FXwindowHack = GL_TRUE;
-	     FX_grSstControl(GR_CONTROL_DEACTIVATE);
-	   }
-           else {
-	     b->FXwindowHack = GL_FALSE;
-	   }
-         }
-       }
-       else {
-         if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
-	   b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
-					  GR_REFRESH_75Hz, attribs);
-         else
-	   b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
-                                              b->mesa_buffer.Height, attribs);
-         b->FXisHackUsable = GL_FALSE;
-         b->FXwindowHack = GL_FALSE;
-       }
-       /*
-       fprintf(stderr,
-               "voodoo %d, wid %d height %d hack: usable %d active %d\n",
-               hw, b->mesa_buffer.Width, b->mesa_buffer.Height,
-	       b->FXisHackUsable, b->FXwindowHack);
-       */
-     }
-   }
-   else {
-      _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n");
-      _mesa_warning(NULL, "         you have not defined the MESA_GLX_FX env. var.\n");
-      _mesa_warning(NULL, "         (check the README.3DFX file for more information).\n\n");
-      _mesa_warning(NULL, "         you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
-   }
-}
-#endif
 
 
 /**
@@ -1993,51 +1911,7 @@ GLboolean XMesaCopyContext( XMesaContext
 #endif /* XFree86Server */
 
 
-/*
- * Switch 3Dfx support hack between window and full-screen mode.
- */
-#ifdef FX
-GLboolean XMesaSetFXmode( GLint mode )
-{
-   const char *fx = _mesa_getenv("MESA_GLX_FX");
-   if (fx && fx[0] != 'd') {
-      GET_CURRENT_CONTEXT(ctx);
-      GrHwConfiguration hw;
-      if (!FX_grSstQueryHardware(&hw)) {
-         /*fprintf(stderr, "!grSstQueryHardware\n");*/
-         return GL_FALSE;
-      }
-      if (hw.num_sst < 1) {
-         /*fprintf(stderr, "hw.num_sst < 1\n");*/
-         return GL_FALSE;
-      }
-      if (ctx) {
-         /* [dBorca] Hack alert: 
-	  * oh, this is sooo wrong: ctx above is
-	  * really an fxMesaContext, not an XMesaContext
-	  */
-         XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
-         if (mode == XMESA_FX_WINDOW) {
-	    if (xmbuf->FXisHackUsable) {
-	       FX_grSstControl(GR_CONTROL_DEACTIVATE);
-	       xmbuf->FXwindowHack = GL_TRUE;
-	       return GL_TRUE;
-	    }
-	 }
-	 else if (mode == XMESA_FX_FULLSCREEN) {
-	    FX_grSstControl(GR_CONTROL_ACTIVATE);
-	    xmbuf->FXwindowHack = GL_FALSE;
-	    return GL_TRUE;
-	 }
-	 else {
-	    /* Error: Bad mode value */
-	 }
-      }
-   }
-   /*fprintf(stderr, "fallthrough\n");*/
-   return GL_FALSE;
-}
-#else
+#ifndef FX
 GLboolean XMesaSetFXmode( GLint mode )
 {
    (void) mode;
@@ -2047,96 +1921,6 @@ GLboolean XMesaSetFXmode( GLint mode )
 
 
 
-#ifdef FX
-/*
- * Read image from VooDoo frame buffer into X/Mesa's back XImage.
- */
-static void FXgetImage( XMesaBuffer b )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   static unsigned short pixbuf[MAX_WIDTH];
-   GLuint x, y;
-   GLuint width, height;
-   XMesaContext xmesa = XMESA_CONTEXT(ctx);
-
-#ifdef XFree86Server
-   x = b->frontxrb->pixmap->x;
-   y = b->frontxrb->pixmap->y;
-   width = b->frontxrb->pixmap->width;
-   height = b->frontxrb->pixmap->height;
-   depth = b->frontxrb->pixmap->depth;
-#else
-   xmesa_get_window_size(b->display, b, &width, &height);
-   x = y = 0;
-#endif
-   if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
-      b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
-      b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
-      if (b->mesa_buffer.Width & 1)
-         b->mesa_buffer.Width--;  /* prevent odd width */
-   }
-
-   /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
-   /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */
-   if (b->xm_visual->undithered_pf==PF_5R6G5B) {
-      /* Special case: 16bpp RGB */
-      grLfbReadRegion( GR_BUFFER_FRONTBUFFER,       /* src buffer */
-                       0, b->FXctx->height - b->mesa_buffer.Height,  /*pos*/
-                       b->mesa_buffer.Width, b->mesa_buffer.Height,  /* size */
-                       b->mesa_buffer.Width * sizeof(GLushort), /* stride */
-                       b->backxrb->ximage->data);         /* dest buffer */
-   }
-   else if (b->xm_visual->dithered_pf==PF_Dither
-	    && GET_VISUAL_DEPTH(b->xm_visual)==8) {
-      /* Special case: 8bpp RGB */
-      for (y=0;y<b->mesa_buffer.Height;y++) {
-         GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data
-                        + b->backxrb->ximage->bytes_per_line * y;
-         XDITHER_SETUP(y);
-
-         /* read row from 3Dfx frame buffer */
-         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
-                          0, b->FXctx->height-(b->mesa_buffer.Height-y),
-                          b->mesa_buffer.Width, 1,
-                          0,
-                          pixbuf );
-
-         /* write to XImage back buffer */
-         for (x=0;x<b->mesa_buffer.Width;x++) {
-            GLubyte r = (pixbuf[x] & 0xf800) >> 8;
-            GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
-            GLubyte b = (pixbuf[x] & 0x001f) << 3;
-            *ptr++ = XDITHER( x, r, g, b);
-         }
-      }
-   }
-   else {
-      /* General case: slow! */
-      for (y=0;y<b->mesa_buffer.Height;y++) {
-         /* read row from 3Dfx frame buffer */
-         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
-                          0, b->FXctx->height-(b->mesa_buffer.Height-y),
-                          b->mesa_buffer.Width, 1,
-                          0,
-                          pixbuf );
-
-         /* write to XImage back buffer */
-         for (x=0;x<b->mesa_buffer.Width;x++) {
-            XMesaPutPixel(b->backxrb->ximage,x,y,
-			  xmesa_color_to_pixel(ctx,
-					       (pixbuf[x] & 0xf800) >> 8,
-					       (pixbuf[x] & 0x07e0) >> 3,
-					       (pixbuf[x] & 0x001f) << 3,
-					       0xff,
-                                               b->xm_visual->undithered_pf));
-         }
-      }
-   }
-   /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */
-}
-#endif
-
-
 /*
  * Copy the back buffer to the front buffer.  If there's no back buffer
  * this is a no-op.
@@ -2159,16 +1943,10 @@ void XMesaSwapBuffers( XMesaBuffer b )
 
    if (b->db_mode) {
 #ifdef FX
-      if (b->FXctx) {
-         fxMesaSwapBuffers();
-
-         if (b->FXwindowHack)
-            FXgetImage(b);
-         else
-            return;
-      }
+      if (FXswapBuffers(b))
+         return;
 #endif
-     if (b->backxrb->ximage) {
+      if (b->backxrb->ximage) {
 	 /* Copy Ximage (back buf) from client memory to server window */
 #if defined(USE_XSHM) && !defined(XFree86Server)
 	 if (b->shm) {
@@ -2235,13 +2013,8 @@ void XMesaCopySubBuffer( XMesaBuffer b, 
    if (b->db_mode) {
       int yTop = b->mesa_buffer.Height - y - height;
 #ifdef FX
-      if (b->FXctx) {
-         fxMesaSwapBuffers();
-         if (b->FXwindowHack)
-            FXgetImage(b);
-         else
-            return;
-      }
+      if (FXswapBuffers(b))
+         return;
 #endif
       if (b->backxrb->ximage) {
          /* Copy Ximage from host's memory to server's window */
diff --git a/src/mesa/drivers/x11/xm_glide.c b/src/mesa/drivers/x11/xm_glide.c
new file mode 100644
index 0000000..37787a7
--- /dev/null
+++ b/src/mesa/drivers/x11/xm_glide.c
@@ -0,0 +1,257 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 1999-2006  Brian Paul   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 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
+ * BRIAN PAUL 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.
+ */
+
+
+#include "glxheader.h"
+#include "xmesaP.h"
+
+#ifdef FX
+void
+FXcreateContext(XMesaVisual v, XMesaWindow w, XMesaContext c, XMesaBuffer b)
+{
+   char *fxEnvVar = _mesa_getenv("MESA_GLX_FX");
+   if (fxEnvVar) {
+     if (fxEnvVar[0]!='d') {
+       int attribs[100];
+       int numAttribs = 0;
+       int hw;
+       if (v->mesa_visual.depthBits > 0) {
+	 attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
+	 attribs[numAttribs++] = v->mesa_visual.depthBits;
+       }
+       if (v->mesa_visual.doubleBufferMode) {
+	 attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
+       }
+       if (v->mesa_visual.accumRedBits > 0) {
+	 attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
+	 attribs[numAttribs++] = v->mesa_visual.accumRedBits;
+       }
+       if (v->mesa_visual.stencilBits > 0) {
+         attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
+         attribs[numAttribs++] = v->mesa_visual.stencilBits;
+       }
+       if (v->mesa_visual.alphaBits > 0) {
+         attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
+         attribs[numAttribs++] = v->mesa_visual.alphaBits;
+       }
+       if (1) {
+         attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
+         attribs[numAttribs++] = (int) &(c->mesa);
+       }
+       attribs[numAttribs++] = FXMESA_NONE;
+
+       /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */
+       hw = fxMesaSelectCurrentBoard(0);
+
+       /* if these fail, there's a new bug somewhere */
+       ASSERT(b->mesa_buffer.Width > 0);
+       ASSERT(b->mesa_buffer.Height > 0);
+
+       if ((hw == GR_SSTTYPE_VOODOO) || (hw == GR_SSTTYPE_Voodoo2)) {
+         b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
+                                            b->mesa_buffer.Height, attribs);
+         if ((v->undithered_pf!=PF_Index) && (b->backxrb->ximage)) {
+	   b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
+	   if (b->FXctx && (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')) {
+	     b->FXwindowHack = GL_TRUE;
+	     FX_grSstControl(GR_CONTROL_DEACTIVATE);
+	   }
+           else {
+	     b->FXwindowHack = GL_FALSE;
+	   }
+         }
+       }
+       else {
+         if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
+	   b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
+					  GR_REFRESH_75Hz, attribs);
+         else
+	   b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
+                                              b->mesa_buffer.Height, attribs);
+         b->FXisHackUsable = GL_FALSE;
+         b->FXwindowHack = GL_FALSE;
+       }
+       /*
+       fprintf(stderr,
+               "voodoo %d, wid %d height %d hack: usable %d active %d\n",
+               hw, b->mesa_buffer.Width, b->mesa_buffer.Height,
+	       b->FXisHackUsable, b->FXwindowHack);
+       */
+     }
+   }
+   else {
+      _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n");
+      _mesa_warning(NULL, "         you have not defined the MESA_GLX_FX env. var.\n");
+      _mesa_warning(NULL, "         (check the README.3DFX file for more information).\n\n");
+      _mesa_warning(NULL, "         you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
+   }
+}
+
+
+/*
+ * Read image from VooDoo frame buffer into X/Mesa's back XImage.
+ */
+static void FXgetImage( XMesaBuffer b )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   static unsigned short pixbuf[MAX_WIDTH];
+   GLuint x, y;
+   GLuint width, height;
+   XMesaContext xmesa = XMESA_CONTEXT(ctx);
+
+#ifdef XFree86Server
+   x = b->frontxrb->pixmap->x;
+   y = b->frontxrb->pixmap->y;
+   width = b->frontxrb->pixmap->width;
+   height = b->frontxrb->pixmap->height;
+   depth = b->frontxrb->pixmap->depth;
+#else
+   xmesa_get_window_size(b->display, b, &width, &height);
+   x = y = 0;
+#endif
+   if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
+      b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
+      b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
+      if (b->mesa_buffer.Width & 1)
+         b->mesa_buffer.Width--;  /* prevent odd width */
+   }
+
+   /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
+   /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */
+   if (b->xm_visual->undithered_pf==PF_5R6G5B) {
+      /* Special case: 16bpp RGB */
+      grLfbReadRegion( GR_BUFFER_FRONTBUFFER,       /* src buffer */
+                       0, b->FXctx->height - b->mesa_buffer.Height,  /*pos*/
+                       b->mesa_buffer.Width, b->mesa_buffer.Height,  /* size */
+                       b->mesa_buffer.Width * sizeof(GLushort), /* stride */
+                       b->backxrb->ximage->data);         /* dest buffer */
+   }
+   else if (b->xm_visual->dithered_pf==PF_Dither
+	    && GET_VISUAL_DEPTH(b->xm_visual)==8) {
+      /* Special case: 8bpp RGB */
+      for (y=0;y<b->mesa_buffer.Height;y++) {
+         GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data
+                        + b->backxrb->ximage->bytes_per_line * y;
+         XDITHER_SETUP(y);
+
+         /* read row from 3Dfx frame buffer */
+         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
+                          0, b->FXctx->height-(b->mesa_buffer.Height-y),
+                          b->mesa_buffer.Width, 1,
+                          0,
+                          pixbuf );
+
+         /* write to XImage back buffer */
+         for (x=0;x<b->mesa_buffer.Width;x++) {
+            GLubyte r = (pixbuf[x] & 0xf800) >> 8;
+            GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
+            GLubyte b = (pixbuf[x] & 0x001f) << 3;
+            *ptr++ = XDITHER( x, r, g, b);
+         }
+      }
+   }
+   else {
+      /* General case: slow! */
+      for (y=0;y<b->mesa_buffer.Height;y++) {
+         /* read row from 3Dfx frame buffer */
+         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
+                          0, b->FXctx->height-(b->mesa_buffer.Height-y),
+                          b->mesa_buffer.Width, 1,
+                          0,
+                          pixbuf );
+
+         /* write to XImage back buffer */
+         for (x=0;x<b->mesa_buffer.Width;x++) {
+            XMesaPutPixel(b->backxrb->ximage,x,y,
+			  xmesa_color_to_pixel(ctx,
+					       (pixbuf[x] & 0xf800) >> 8,
+					       (pixbuf[x] & 0x07e0) >> 3,
+					       (pixbuf[x] & 0x001f) << 3,
+					       0xff,
+                                               b->xm_visual->undithered_pf));
+         }
+      }
+   }
+   /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */
+}
+
+
+GLboolean FXswapBuffers( XMesaBuffer b )
+{
+   if (b->FXctx) {
+      fxMesaSwapBuffers();
+
+      if (!b->FXwindowHack)
+         return GL_TRUE;
+
+      FXgetImage(b);
+   }
+   return GL_FALSE;
+}
+
+
+/*
+ * Switch 3Dfx support hack between window and full-screen mode.
+ */
+GLboolean XMesaSetFXmode( GLint mode )
+{
+   const char *fx = _mesa_getenv("MESA_GLX_FX");
+   if (fx && fx[0] != 'd') {
+      GET_CURRENT_CONTEXT(ctx);
+      GrHwConfiguration hw;
+      if (!FX_grSstQueryHardware(&hw)) {
+         /*fprintf(stderr, "!grSstQueryHardware\n");*/
+         return GL_FALSE;
+      }
+      if (hw.num_sst < 1) {
+         /*fprintf(stderr, "hw.num_sst < 1\n");*/
+         return GL_FALSE;
+      }
+      if (ctx) {
+         /* [dBorca] Hack alert: 
+	  * oh, this is sooo wrong: ctx above is
+	  * really an fxMesaContext, not an XMesaContext
+	  */
+         XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+         if (mode == XMESA_FX_WINDOW) {
+	    if (xmbuf->FXisHackUsable) {
+	       FX_grSstControl(GR_CONTROL_DEACTIVATE);
+	       xmbuf->FXwindowHack = GL_TRUE;
+	       return GL_TRUE;
+	    }
+	 }
+	 else if (mode == XMESA_FX_FULLSCREEN) {
+	    FX_grSstControl(GR_CONTROL_ACTIVATE);
+	    xmbuf->FXwindowHack = GL_FALSE;
+	    return GL_TRUE;
+	 }
+	 else {
+	    /* Error: Bad mode value */
+	 }
+      }
+   }
+   /*fprintf(stderr, "fallthrough\n");*/
+   return GL_FALSE;
+}
+#endif
diff --git a/src/mesa/drivers/x11/xm_glide.h b/src/mesa/drivers/x11/xm_glide.h
new file mode 100644
index 0000000..7458c57
--- /dev/null
+++ b/src/mesa/drivers/x11/xm_glide.h
@@ -0,0 +1,36 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 1999-2006  Brian Paul   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 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
+ * BRIAN PAUL 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.
+ */
+
+
+#ifndef _XM_GLIDE_H_
+#define _XM_GLIDE_H_
+
+extern void FXcreateContext( XMesaVisual v,
+                             XMesaWindow w,
+                             XMesaContext c,
+                             XMesaBuffer b );
+
+extern GLboolean FXswapBuffers( XMesaBuffer b );
+
+#endif /* _XM_GLIDE_H_ */
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
index 170fc67..cae5c0d 100644
--- a/src/mesa/drivers/x11/xmesaP.h
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -32,6 +32,7 @@
 #if defined(FX)
 #include "GL/fxmesa.h"
 #include "../glide/fxdrv.h"
+#include "xm_glide.h"
 #endif
 #ifdef XFree86Server
 #include "xm_image.h"
@@ -568,13 +569,6 @@ extern void xmesa_register_swrast_functi
 
 
 
-/* XXX this is a hack to implement shared display lists with 3Dfx */
-extern void FXcreateContext( XMesaVisual v,
-                             XMesaWindow w,
-                             XMesaContext c,
-                             XMesaBuffer b );
-
-
 #define ENABLE_EXT_texure_compression_s3tc 0 /* SW texture compression */
 
 #ifdef XFree86Server
diff-tree 6aa5668871e7f366b33e85fabc72885fc269a7d4 (from d60009bd6dba15d094b0d0bcb8180b7a2e1c1708)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Fri Apr 20 17:51:55 2007 +0300

    xmesa: spilt FX code to separate functions.

diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
index eecd52a..86a4dea 100644
--- a/src/mesa/drivers/x11/fakeglx.c
+++ b/src/mesa/drivers/x11/fakeglx.c
@@ -1440,11 +1440,14 @@ Fake_glXMakeContextCurrent( Display *dpy
       }
       if (!drawBuffer) {
          /* drawable must be a new window! */
-         drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, xmctx);
+         drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
          if (!drawBuffer) {
             /* Out of memory, or context/drawable depth mismatch */
             return False;
          }
+#ifdef FX
+         FXcreateContext( xmctx->xm_visual, draw, xmctx, drawBuffer );
+#endif
       }
 
       /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
@@ -1457,12 +1460,14 @@ Fake_glXMakeContextCurrent( Display *dpy
       }
       if (!readBuffer) {
          /* drawable must be a new window! */
-         readBuffer = XMesaCreateWindowBuffer2(glxCtx->xmesaContext->xm_visual,
-                                               read, xmctx);
+         readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
          if (!readBuffer) {
             /* Out of memory, or context/drawable depth mismatch */
             return False;
          }
+#ifdef FX
+         FXcreateContext( xmctx->xm_visual, read, xmctx, readBuffer );
+#endif
       }
 
       MakeCurrent_PrevContext = ctx;
@@ -2107,10 +2112,15 @@ Fake_glXCreateWindow( Display *dpy, GLXF
    if (!xmvis)
       return 0;
 
-   xmbuf = XMesaCreateWindowBuffer2(xmvis, win, NULL);
+   xmbuf = XMesaCreateWindowBuffer(xmvis, win);
    if (!xmbuf)
       return 0;
 
+#ifdef FX
+   /* XXX this will segfault if actually called */
+   FXcreateContext(xmvis, win, NULL, xmbuf);
+#endif
+
    (void) dpy;
    (void) attribList;  /* Ignored in GLX 1.3 */
 
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index 6439d13..3e65ebd 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -1578,25 +1578,20 @@ void XMesaDestroyContext( XMesaContext c
  * X window or pixmap.
  * \param v  the window's XMesaVisual
  * \param w  the window we're wrapping
- * \param c  context used to initialize the buffer if 3Dfx mode in use.
  * \return  new XMesaBuffer or NULL if error
  */
-XMesaBuffer
-XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
+PUBLIC XMesaBuffer
+XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
 {
 #ifndef XFree86Server
    XWindowAttributes attr;
 #endif
-#ifdef FX
-   char *fxEnvVar;
-#endif
    int client = 0;
    XMesaBuffer b;
    XMesaColormap cmap;
 
    assert(v);
    assert(w);
-   (void) c;
 
    /* Check that window depth matches visual depth */
 #ifdef XFree86Server
@@ -1642,8 +1637,14 @@ XMesaCreateWindowBuffer2(XMesaVisual v, 
       return NULL;
    }
 
+   return b;
+}
+
 #ifdef FX
-   fxEnvVar = _mesa_getenv("MESA_GLX_FX");
+void
+FXcreateContext(XMesaVisual v, XMesaWindow w, XMesaContext c, XMesaBuffer b)
+{
+   char *fxEnvVar = _mesa_getenv("MESA_GLX_FX");
    if (fxEnvVar) {
      if (fxEnvVar[0]!='d') {
        int attribs[100];
@@ -1719,17 +1720,8 @@ XMesaCreateWindowBuffer2(XMesaVisual v, 
       _mesa_warning(NULL, "         (check the README.3DFX file for more information).\n\n");
       _mesa_warning(NULL, "         you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
    }
-#endif
-
-   return b;
-}
-
-
-PUBLIC XMesaBuffer
-XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
-{
-   return XMesaCreateWindowBuffer2( v, w, NULL );
 }
+#endif
 
 
 /**
@@ -2004,9 +1996,9 @@ GLboolean XMesaCopyContext( XMesaContext
 /*
  * Switch 3Dfx support hack between window and full-screen mode.
  */
+#ifdef FX
 GLboolean XMesaSetFXmode( GLint mode )
 {
-#ifdef FX
    const char *fx = _mesa_getenv("MESA_GLX_FX");
    if (fx && fx[0] != 'd') {
       GET_CURRENT_CONTEXT(ctx);
@@ -2043,11 +2035,15 @@ GLboolean XMesaSetFXmode( GLint mode )
       }
    }
    /*fprintf(stderr, "fallthrough\n");*/
+   return GL_FALSE;
+}
 #else
+GLboolean XMesaSetFXmode( GLint mode )
+{
    (void) mode;
-#endif
    return GL_FALSE;
 }
+#endif
 
 
 
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
index 98d03cc..170fc67 100644
--- a/src/mesa/drivers/x11/xmesaP.h
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -569,9 +569,10 @@ extern void xmesa_register_swrast_functi
 
 
 /* XXX this is a hack to implement shared display lists with 3Dfx */
-extern XMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v,
-					     XMesaWindow w,
-					     XMesaContext c );
+extern void FXcreateContext( XMesaVisual v,
+                             XMesaWindow w,
+                             XMesaContext c,
+                             XMesaBuffer b );
 
 
 #define ENABLE_EXT_texure_compression_s3tc 0 /* SW texture compression */
diff-tree d60009bd6dba15d094b0d0bcb8180b7a2e1c1708 (from 535c37e85d9283f177825e7534e5d0abb4d93886)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Fri Apr 20 17:35:01 2007 +0300

    Revert "xmesa: drop glide (FX) backend."
    
    This reverts commit 2a2f8d806f74619f0a7cf97fdc7f7b3ad1cad81b.

diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
index b6569b1..eecd52a 100644
--- a/src/mesa/drivers/x11/fakeglx.c
+++ b/src/mesa/drivers/x11/fakeglx.c
@@ -1440,7 +1440,7 @@ Fake_glXMakeContextCurrent( Display *dpy
       }
       if (!drawBuffer) {
          /* drawable must be a new window! */
-         drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
+         drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, xmctx);
          if (!drawBuffer) {
             /* Out of memory, or context/drawable depth mismatch */
             return False;
@@ -1457,7 +1457,8 @@ Fake_glXMakeContextCurrent( Display *dpy
       }
       if (!readBuffer) {
          /* drawable must be a new window! */
-         readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
+         readBuffer = XMesaCreateWindowBuffer2(glxCtx->xmesaContext->xm_visual,
+                                               read, xmctx);
          if (!readBuffer) {
             /* Out of memory, or context/drawable depth mismatch */
             return False;
@@ -1929,6 +1930,12 @@ Fake_glXWaitX( void )
 static const char *
 get_extensions( void )
 {
+#ifdef FX
+   const char *fx = _mesa_getenv("MESA_GLX_FX");
+   if (fx && fx[0] != 'd') {
+      return EXTENSIONS;
+   }
+#endif
    return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */
 }
 
@@ -2100,7 +2107,7 @@ Fake_glXCreateWindow( Display *dpy, GLXF
    if (!xmvis)
       return 0;
 
-   xmbuf = XMesaCreateWindowBuffer(xmvis, win);
+   xmbuf = XMesaCreateWindowBuffer2(xmvis, win, NULL);
    if (!xmbuf)
       return 0;
 
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index 6f67196..6439d13 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -1557,6 +1557,12 @@ PUBLIC
 void XMesaDestroyContext( XMesaContext c )
 {
    GLcontext *mesaCtx = &c->mesa;
+#ifdef FX
+   XMesaBuffer xmbuf = XMESA_BUFFER(mesaCtx->DrawBuffer);
+
+   if (xmbuf && xmbuf->FXctx)
+      fxMesaDestroyContext(xmbuf->FXctx);
+#endif
    _swsetup_DestroyContext( mesaCtx );
    _swrast_DestroyContext( mesaCtx );
    _tnl_DestroyContext( mesaCtx );
@@ -1572,20 +1578,25 @@ void XMesaDestroyContext( XMesaContext c
  * X window or pixmap.
  * \param v  the window's XMesaVisual
  * \param w  the window we're wrapping
+ * \param c  context used to initialize the buffer if 3Dfx mode in use.
  * \return  new XMesaBuffer or NULL if error
  */
-PUBLIC XMesaBuffer
-XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
+XMesaBuffer
+XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
 {
 #ifndef XFree86Server
    XWindowAttributes attr;
 #endif
+#ifdef FX
+   char *fxEnvVar;
+#endif
    int client = 0;
    XMesaBuffer b;
    XMesaColormap cmap;
 
    assert(v);
    assert(w);
+   (void) c;
 
    /* Check that window depth matches visual depth */
 #ifdef XFree86Server
@@ -1631,10 +1642,96 @@ XMesaCreateWindowBuffer(XMesaVisual v, X
       return NULL;
    }
 
+#ifdef FX
+   fxEnvVar = _mesa_getenv("MESA_GLX_FX");
+   if (fxEnvVar) {
+     if (fxEnvVar[0]!='d') {
+       int attribs[100];
+       int numAttribs = 0;
+       int hw;
+       if (v->mesa_visual.depthBits > 0) {
+	 attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
+	 attribs[numAttribs++] = v->mesa_visual.depthBits;
+       }
+       if (v->mesa_visual.doubleBufferMode) {
+	 attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
+       }
+       if (v->mesa_visual.accumRedBits > 0) {
+	 attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
+	 attribs[numAttribs++] = v->mesa_visual.accumRedBits;
+       }
+       if (v->mesa_visual.stencilBits > 0) {
+         attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
+         attribs[numAttribs++] = v->mesa_visual.stencilBits;
+       }
+       if (v->mesa_visual.alphaBits > 0) {
+         attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
+         attribs[numAttribs++] = v->mesa_visual.alphaBits;
+       }
+       if (1) {
+         attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
+         attribs[numAttribs++] = (int) &(c->mesa);
+       }
+       attribs[numAttribs++] = FXMESA_NONE;
+
+       /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */
+       hw = fxMesaSelectCurrentBoard(0);
+
+       /* if these fail, there's a new bug somewhere */
+       ASSERT(b->mesa_buffer.Width > 0);
+       ASSERT(b->mesa_buffer.Height > 0);
+
+       if ((hw == GR_SSTTYPE_VOODOO) || (hw == GR_SSTTYPE_Voodoo2)) {
+         b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
+                                            b->mesa_buffer.Height, attribs);
+         if ((v->undithered_pf!=PF_Index) && (b->backxrb->ximage)) {
+	   b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
+	   if (b->FXctx && (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')) {
+	     b->FXwindowHack = GL_TRUE;
+	     FX_grSstControl(GR_CONTROL_DEACTIVATE);
+	   }
+           else {
+	     b->FXwindowHack = GL_FALSE;
+	   }
+         }
+       }
+       else {
+         if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
+	   b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
+					  GR_REFRESH_75Hz, attribs);
+         else
+	   b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
+                                              b->mesa_buffer.Height, attribs);
+         b->FXisHackUsable = GL_FALSE;
+         b->FXwindowHack = GL_FALSE;
+       }
+       /*
+       fprintf(stderr,
+               "voodoo %d, wid %d height %d hack: usable %d active %d\n",
+               hw, b->mesa_buffer.Width, b->mesa_buffer.Height,
+	       b->FXisHackUsable, b->FXwindowHack);
+       */
+     }
+   }
+   else {
+      _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n");
+      _mesa_warning(NULL, "         you have not defined the MESA_GLX_FX env. var.\n");
+      _mesa_warning(NULL, "         (check the README.3DFX file for more information).\n\n");
+      _mesa_warning(NULL, "         you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
+   }
+#endif
+
    return b;
 }
 
 
+PUBLIC XMesaBuffer
+XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
+{
+   return XMesaCreateWindowBuffer2( v, w, NULL );
+}
+
+
 /**
  * Create a new XMesaBuffer from an X pixmap.
  *
@@ -1760,6 +1857,15 @@ GLboolean XMesaMakeCurrent2( XMesaContex
       if (!drawBuffer || !readBuffer)
          return GL_FALSE;  /* must specify buffers! */
 
+#ifdef FX
+      if (drawBuffer->FXctx) {
+         fxMesaMakeCurrent(drawBuffer->FXctx);
+
+         c->xm_buffer = drawBuffer;
+
+         return GL_TRUE;
+      }
+#endif
       if (&(c->mesa) == _mesa_get_current_context()
           && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
           && c->mesa.ReadBuffer == &readBuffer->mesa_buffer
@@ -1900,12 +2006,141 @@ GLboolean XMesaCopyContext( XMesaContext
  */
 GLboolean XMesaSetFXmode( GLint mode )
 {
+#ifdef FX
+   const char *fx = _mesa_getenv("MESA_GLX_FX");
+   if (fx && fx[0] != 'd') {
+      GET_CURRENT_CONTEXT(ctx);
+      GrHwConfiguration hw;
+      if (!FX_grSstQueryHardware(&hw)) {
+         /*fprintf(stderr, "!grSstQueryHardware\n");*/
+         return GL_FALSE;
+      }
+      if (hw.num_sst < 1) {
+         /*fprintf(stderr, "hw.num_sst < 1\n");*/
+         return GL_FALSE;
+      }
+      if (ctx) {
+         /* [dBorca] Hack alert: 
+	  * oh, this is sooo wrong: ctx above is
+	  * really an fxMesaContext, not an XMesaContext
+	  */
+         XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+         if (mode == XMESA_FX_WINDOW) {
+	    if (xmbuf->FXisHackUsable) {
+	       FX_grSstControl(GR_CONTROL_DEACTIVATE);
+	       xmbuf->FXwindowHack = GL_TRUE;
+	       return GL_TRUE;
+	    }
+	 }
+	 else if (mode == XMESA_FX_FULLSCREEN) {
+	    FX_grSstControl(GR_CONTROL_ACTIVATE);
+	    xmbuf->FXwindowHack = GL_FALSE;
+	    return GL_TRUE;
+	 }
+	 else {
+	    /* Error: Bad mode value */
+	 }
+      }
+   }
+   /*fprintf(stderr, "fallthrough\n");*/
+#else
    (void) mode;
+#endif
    return GL_FALSE;
 }
 
 
 
+#ifdef FX
+/*
+ * Read image from VooDoo frame buffer into X/Mesa's back XImage.
+ */
+static void FXgetImage( XMesaBuffer b )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   static unsigned short pixbuf[MAX_WIDTH];
+   GLuint x, y;
+   GLuint width, height;
+   XMesaContext xmesa = XMESA_CONTEXT(ctx);
+
+#ifdef XFree86Server
+   x = b->frontxrb->pixmap->x;
+   y = b->frontxrb->pixmap->y;
+   width = b->frontxrb->pixmap->width;
+   height = b->frontxrb->pixmap->height;
+   depth = b->frontxrb->pixmap->depth;
+#else
+   xmesa_get_window_size(b->display, b, &width, &height);
+   x = y = 0;
+#endif
+   if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
+      b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
+      b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
+      if (b->mesa_buffer.Width & 1)
+         b->mesa_buffer.Width--;  /* prevent odd width */
+   }
+
+   /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
+   /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */
+   if (b->xm_visual->undithered_pf==PF_5R6G5B) {
+      /* Special case: 16bpp RGB */
+      grLfbReadRegion( GR_BUFFER_FRONTBUFFER,       /* src buffer */
+                       0, b->FXctx->height - b->mesa_buffer.Height,  /*pos*/
+                       b->mesa_buffer.Width, b->mesa_buffer.Height,  /* size */
+                       b->mesa_buffer.Width * sizeof(GLushort), /* stride */
+                       b->backxrb->ximage->data);         /* dest buffer */
+   }
+   else if (b->xm_visual->dithered_pf==PF_Dither
+	    && GET_VISUAL_DEPTH(b->xm_visual)==8) {
+      /* Special case: 8bpp RGB */
+      for (y=0;y<b->mesa_buffer.Height;y++) {
+         GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data
+                        + b->backxrb->ximage->bytes_per_line * y;
+         XDITHER_SETUP(y);
+
+         /* read row from 3Dfx frame buffer */
+         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
+                          0, b->FXctx->height-(b->mesa_buffer.Height-y),
+                          b->mesa_buffer.Width, 1,
+                          0,
+                          pixbuf );
+
+         /* write to XImage back buffer */
+         for (x=0;x<b->mesa_buffer.Width;x++) {
+            GLubyte r = (pixbuf[x] & 0xf800) >> 8;
+            GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
+            GLubyte b = (pixbuf[x] & 0x001f) << 3;
+            *ptr++ = XDITHER( x, r, g, b);
+         }
+      }
+   }
+   else {
+      /* General case: slow! */
+      for (y=0;y<b->mesa_buffer.Height;y++) {
+         /* read row from 3Dfx frame buffer */
+         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
+                          0, b->FXctx->height-(b->mesa_buffer.Height-y),
+                          b->mesa_buffer.Width, 1,
+                          0,
+                          pixbuf );
+
+         /* write to XImage back buffer */
+         for (x=0;x<b->mesa_buffer.Width;x++) {
+            XMesaPutPixel(b->backxrb->ximage,x,y,
+			  xmesa_color_to_pixel(ctx,
+					       (pixbuf[x] & 0xf800) >> 8,
+					       (pixbuf[x] & 0x07e0) >> 3,
+					       (pixbuf[x] & 0x001f) << 3,
+					       0xff,
+                                               b->xm_visual->undithered_pf));
+         }
+      }
+   }
+   /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */
+}
+#endif
+
+
 /*
  * Copy the back buffer to the front buffer.  If there's no back buffer
  * this is a no-op.
@@ -1927,6 +2162,16 @@ void XMesaSwapBuffers( XMesaBuffer b )
       _mesa_notifySwapBuffers(ctx);
 
    if (b->db_mode) {
+#ifdef FX
+      if (b->FXctx) {
+         fxMesaSwapBuffers();
+
+         if (b->FXwindowHack)
+            FXgetImage(b);
+         else
+            return;
+      }
+#endif
      if (b->backxrb->ximage) {
 	 /* Copy Ximage (back buf) from client memory to server window */
 #if defined(USE_XSHM) && !defined(XFree86Server)
@@ -1993,6 +2238,15 @@ void XMesaCopySubBuffer( XMesaBuffer b, 
 
    if (b->db_mode) {
       int yTop = b->mesa_buffer.Height - y - height;
+#ifdef FX
+      if (b->FXctx) {
+         fxMesaSwapBuffers();
+         if (b->FXwindowHack)
+            FXgetImage(b);
+         else
+            return;
+      }
+#endif
       if (b->backxrb->ximage) {
          /* Copy Ximage from host's memory to server's window */
 #if defined(USE_XSHM) && !defined(XFree86Server)
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
index 7b72e6b..98d03cc 100644
--- a/src/mesa/drivers/x11/xmesaP.h
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -29,7 +29,10 @@
 
 #include "GL/xmesa.h"
 #include "mtypes.h"
-
+#if defined(FX)
+#include "GL/fxmesa.h"
+#include "../glide/fxdrv.h"
+#endif
 #ifdef XFree86Server
 #include "xm_image.h"
 #endif
@@ -257,6 +260,13 @@ struct xmesa_buffer {
    unsigned long alloced_colors[256];
 #endif
 
+#if defined( FX )
+   /* For 3Dfx Glide only */
+   GLboolean FXisHackUsable;	/* Can we render into window? */
+   GLboolean FXwindowHack;	/* Are we rendering into a window? */
+   fxMesaContext FXctx;
+#endif
+
    struct xmesa_buffer *Next;	/* Linked list pointer: */
 };
 
@@ -557,6 +567,13 @@ extern void xmesa_choose_triangle( GLcon
 extern void xmesa_register_swrast_functions( GLcontext *ctx );
 
 
+
+/* XXX this is a hack to implement shared display lists with 3Dfx */
+extern XMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v,
+					     XMesaWindow w,
+					     XMesaContext c );
+
+
 #define ENABLE_EXT_texure_compression_s3tc 0 /* SW texture compression */
 
 #ifdef XFree86Server



More information about the mesa-commit mailing list