summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'xc/lib/GL/mesa')
-rw-r--r--xc/lib/GL/mesa/dri/Imakefile42
-rw-r--r--xc/lib/GL/mesa/dri/dri_mesa.c746
-rw-r--r--xc/lib/GL/mesa/dri/dri_mesa.h48
-rw-r--r--xc/lib/GL/mesa/dri/dri_mesaint.h246
-rw-r--r--xc/lib/GL/mesa/dri/dri_xmesaapi.h77
-rw-r--r--xc/lib/GL/mesa/include/GL/Imakefile13
-rw-r--r--xc/lib/GL/mesa/src/Imakefile211
-rw-r--r--xc/lib/GL/mesa/src/X/Imakefile12
-rw-r--r--xc/lib/GL/mesa/src/X86/Imakefile103
-rw-r--r--xc/lib/GL/mesa/src/drv/Imakefile2
-rw-r--r--xc/lib/GL/mesa/src/drv/common/Imakefile56
-rw-r--r--xc/lib/GL/mesa/src/drv/common/hwlog.c107
-rw-r--r--xc/lib/GL/mesa/src/drv/common/hwlog.h115
-rw-r--r--xc/lib/GL/mesa/src/drv/common/mm.c262
-rw-r--r--xc/lib/GL/mesa/src/drv/common/mm.h101
-rw-r--r--xc/lib/GL/mesa/src/drv/common/mmx.h560
-rw-r--r--xc/lib/GL/mesa/src/drv/common/spantmp.h199
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/Imakefile31
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/Imakefile64
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h724
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_init.h135
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c611
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810clear.c193
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810clear.h7
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810context.h190
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dd.c146
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dd.h33
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810depth.c645
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810depth.h37
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dma.c105
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dma.h186
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810fastpath.c530
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810fasttmp.h143
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810lib.h130
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810log.h47
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810pipeline.c112
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810pipeline.h14
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810ring.c162
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810span.c133
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810span.h6
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810state.c933
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810state.h13
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810swap.c259
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810swap.h6
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tex.c1247
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tex.h108
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.c317
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.h158
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tritmp.h172
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810vb.c461
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810vb.h116
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/Imakefile68
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c514
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h121
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaclear.c10
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaclear.h7
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c250
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgacommon.h44
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadd.c146
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadd.h36
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadepth.c636
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadepth.h37
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadma.c59
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadma.h41
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgafastpath.c529
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h143
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaioctl.c321
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaioctl.h23
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgalib.h266
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgalog.h47
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgapipeline.c138
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgapipeline.h15
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaregs.h1377
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgarender.c334
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgarender.h10
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaspan.c153
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaspan.h6
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgastate.c723
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgastate.h15
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatex.c1051
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatex.h119
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatris.c226
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatris.h189
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatritmp.h150
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgavb.c493
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgavb.h132
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/Imakefile232
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c4
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.h28
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c2
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c79
91 files changed, 19714 insertions, 134 deletions
diff --git a/xc/lib/GL/mesa/dri/Imakefile b/xc/lib/GL/mesa/dri/Imakefile
new file mode 100644
index 000000000..f927089d2
--- /dev/null
+++ b/xc/lib/GL/mesa/dri/Imakefile
@@ -0,0 +1,42 @@
+XCOMM $XFree86: xc/lib/GL/mesa/dri/Imakefile,v 1.1 2000/02/08 17:18:35 dawes Exp $
+XCOMM $PI$
+
+#define DoNormalLib NormalLibGlx
+#define DoSharedLib SharedLibGlx
+#define DoExtraLib SharedLibGlx
+#define DoDebugLib DebugLibGlx
+#define DoProfileLib ProfileLibGlx
+
+#if Malloc0ReturnsNull
+ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
+#endif
+
+#if BuildXF86DRI
+ DRI_DEFINES = GlxDefines
+ DRI_INCLUDES = -I../../glx -I../../dri \
+ -I$(TOP)/include -I$(TOP)/include/GL \
+ -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri
+#endif
+
+MESA_INCLUDES = -I. -I.. -I../include
+
+ DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(DRI_INCLUDES) $(MESA_INCLUDES)
+ SRCS = dri_mesa.c
+ OBJS = dri_mesa.o
+
+#if !GlxUseBuiltInDRIDriver
+#undef DoNormalLib NormalLibGlx
+#undef DoExtraLib SharedLibGlx
+#undef DoDebugLib DebugLibGlx
+#undef DoProfileLib ProfileLibGlx
+#endif
+
+#include <Library.tmpl>
+
+LibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
diff --git a/xc/lib/GL/mesa/dri/dri_mesa.c b/xc/lib/GL/mesa/dri/dri_mesa.c
new file mode 100644
index 000000000..0e814b78c
--- /dev/null
+++ b/xc/lib/GL/mesa/dri/dri_mesa.c
@@ -0,0 +1,746 @@
+/* $XFree86: xc/lib/GL/mesa/dri/dri_mesa.c,v 1.4 2000/02/15 07:13:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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, 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 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $PI: xc/lib/GL/dri/dri_mesa.c,v 1.18 1999/08/04 18:13:27 faith Exp $
+ */
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <unistd.h>
+#include <Xlibint.h>
+#include <Xext.h>
+#include <extutil.h>
+#include "glxclient.h"
+#include "GL/xmesa.h"
+#include "xf86dri.h"
+#include "sarea.h"
+#include "dri_mesaint.h"
+#include "dri_xmesaapi.h"
+#ifdef BRIAN
+#include <dlfcn.h>
+#endif
+
+
+#if XMESA_MAJOR_VERSION != 3 || XMESA_MINOR_VERSION != 3
+#error using wrong version of Mesa (need 3.3)
+#endif
+
+
+/* Context binding */
+static Bool driMesaBindContext(Display *dpy, int scrn,
+ GLXDrawable draw, GLXContext gc);
+static Bool driMesaUnbindContext(Display *dpy, int scrn,
+ GLXDrawable draw, GLXContext gc);
+
+/* Drawable methods */
+static void *driMesaCreateDrawable(Display *dpy, int scrn, GLXDrawable draw,
+ VisualID vid, __DRIdrawable *pdraw);
+static __DRIdrawable *driMesaGetDrawable(Display *dpy, GLXDrawable draw);
+static void driMesaSwapBuffers(Display *dpy, void *private);
+static void driMesaDestroyDrawable(Display *dpy, void *private);
+
+/* Context methods */
+static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared,
+ __DRIcontext *pctx);
+static void driMesaDestroyContext(Display *dpy, int scrn, void *private);
+
+/* Screen methods */
+static void *driMesaCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
+ int numConfigs, __GLXvisualConfig *config);
+static void driMesaDestroyScreen(Display *dpy, int scrn, void *private);
+
+
+/*****************************************************************/
+
+/* Maintain a list of drawables */
+
+void *drawHash = NULL; /* Hash table to hold DRI drawables */
+
+static Bool __driMesaAddDrawable(__DRIdrawable *pdraw)
+{
+ __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
+
+ /* Create the hash table */
+ if (!drawHash) drawHash = drmHashCreate();
+
+ if (drmHashInsert(drawHash, pdp->draw, pdraw))
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+static __DRIdrawable *__driMesaFindDrawable(GLXDrawable draw)
+{
+ int retcode;
+ __DRIdrawable *pdraw;
+
+ /* Create the hash table */
+ if (!drawHash) drawHash = drmHashCreate();
+
+ retcode = drmHashLookup(drawHash, draw, (void **)&pdraw);
+ if (retcode)
+ return NULL;
+
+ return pdraw;
+}
+
+static void __driMesaRemoveDrawable(__DRIdrawable *pdraw)
+{
+ int retcode;
+ __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
+
+ /* Create the hash table */
+ if (!drawHash) drawHash = drmHashCreate();
+
+ retcode = drmHashLookup(drawHash, pdp->draw, (void **)&pdraw);
+ if (!retcode) { /* Found */
+ drmHashDelete(drawHash, pdp->draw);
+ }
+}
+
+/*****************************************************************/
+
+static void driMesaInitAPI(__XMESAapi *XMesaAPI)
+{
+ XMesaAPI->InitDriver = XMesaInitDriver;
+ XMesaAPI->ResetDriver = XMesaResetDriver;
+ XMesaAPI->CreateVisual = XMesaCreateVisual;
+ XMesaAPI->DestroyVisual = XMesaDestroyVisual;
+ XMesaAPI->CreateContext = XMesaCreateContext;
+ XMesaAPI->DestroyContext = XMesaDestroyContext;
+ XMesaAPI->CreateWindowBuffer = XMesaCreateWindowBuffer;
+ XMesaAPI->CreatePixmapBuffer = XMesaCreatePixmapBuffer;
+ XMesaAPI->DestroyBuffer = XMesaDestroyBuffer;
+ XMesaAPI->SwapBuffers = XMesaSwapBuffers;
+ XMesaAPI->MakeCurrent = XMesaMakeCurrent;
+ XMesaAPI->UnbindContext = XMesaUnbindContext;
+}
+
+/*****************************************************************/
+
+static Bool driMesaUnbindContext(Display *dpy, int scrn,
+ GLXDrawable draw, GLXContext gc)
+{
+ __DRIdrawable *pdraw;
+ __DRIcontextPrivate *pcp;
+ __DRIscreenPrivate *psp;
+ __DRIdrawablePrivate *pdp;
+
+ /*
+ ** Assume error checking is done properly in glXMakeCurrent before
+ ** calling driMesaUnbindContext.
+ */
+
+ if (gc == NULL || draw == None) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ pdraw = __driMesaFindDrawable(draw);
+ if (!pdraw) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ pcp = (__DRIcontextPrivate *)gc->driContext.private;
+ pdp = (__DRIdrawablePrivate *)pdraw->private;
+ psp = pdp->driScreenPriv;
+ if (!psp) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ /* Unbind Mesa's drawable from Mesa's context */
+ (*psp->XMesaAPI.UnbindContext)(pcp->xm_ctx);
+
+ if (pdp->refcount == 0) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ } else if (--pdp->refcount == 0) {
+#if 0
+ /*
+ ** NOT_DONE: When a drawable is unbound from one direct
+ ** rendering context and then bound to another, we do not want
+ ** to destroy the drawable data structure each time only to
+ ** recreate it immediatly afterwards when binding to the next
+ ** context. This also causes conflicts with caching of the
+ ** drawable stamp.
+ **
+ ** When GLX 1.3 is integrated, the create and destroy drawable
+ ** functions will have user level counterparts and the memory
+ ** will be able to be recovered.
+ */
+
+ /* Delete drawable if no longer referenced by any contexts */
+ (*pdraw->destroyDrawable)(dpy, pdraw->private);
+ __driMesaRemoveDrawable(pdraw);
+ Xfree(pdraw);
+#endif
+ }
+
+ /* Unbind the drawable */
+ pcp->driDrawablePriv = NULL;
+ pdp->driContextPriv = &psp->dummyContextPriv;
+
+ return GL_TRUE;
+}
+
+static Bool driMesaBindContext(Display *dpy, int scrn,
+ GLXDrawable draw, GLXContext gc)
+{
+ __DRIdrawable *pdraw;
+ __DRIdrawablePrivate *pdp;
+ __DRIscreenPrivate *psp;
+ __DRIcontextPrivate *pcp;
+
+ /*
+ ** Assume error checking is done properly in glXMakeCurrent before
+ ** calling driMesaBindContext.
+ */
+
+ if (gc == NULL || draw == None) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ pdraw = __driMesaFindDrawable(draw);
+ if (!pdraw) {
+ /* Allocate a new drawable */
+ pdraw = (__DRIdrawable *)Xmalloc(sizeof(__DRIdrawable));
+ if (!pdraw) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ /* Create a new drawable */
+ pdraw->private = driMesaCreateDrawable(dpy, scrn, draw, gc->vid,
+ pdraw);
+ if (!pdraw->private) {
+ /* ERROR!!! */
+ Xfree(pdraw);
+ return GL_FALSE;
+ }
+
+ /* Add pdraw to drawable list */
+ if (!__driMesaAddDrawable(pdraw)) {
+ /* ERROR!!! */
+ (*pdraw->destroyDrawable)(dpy, pdraw->private);
+ Xfree(pdraw);
+ return GL_FALSE;
+ }
+ }
+
+ pdp = (__DRIdrawablePrivate *)pdraw->private;
+ psp = pdp->driScreenPriv;
+ if (!psp) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ /* Bind the drawable to the context */
+ pcp = (__DRIcontextPrivate *)gc->driContext.private;
+ pcp->driDrawablePriv = pdp;
+ pdp->driContextPriv = pcp;
+ pdp->refcount++;
+
+ /*
+ ** Now that we have a context associated with this drawable, we can
+ ** initialize the drawable information if has not been done before.
+ */
+ if (!pdp->pStamp) {
+ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ driMesaUpdateDrawableInfo(dpy, scrn, pdp);
+ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ }
+
+ /* Bind Mesa's drawable to Mesa's context */
+ (*psp->XMesaAPI.MakeCurrent)(pcp->xm_ctx, pdp->xm_buf);
+
+ return GL_TRUE;
+}
+
+/*****************************************************************/
+
+void driMesaUpdateDrawableInfo(Display *dpy, int scrn,
+ __DRIdrawablePrivate *pdp)
+{
+ __DRIscreenPrivate *psp;
+ __DRIcontextPrivate *pcp = pdp->driContextPriv;
+
+ if (!pcp || (pdp != pcp->driDrawablePriv)) {
+ /* ERROR!!! */
+ return;
+ }
+
+ psp = pdp->driScreenPriv;
+ if (!psp) {
+ /* ERROR!!! */
+ return;
+ }
+
+ if (pdp->pClipRects) {
+ Xfree(pdp->pClipRects);
+ }
+
+ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+
+ if (!XF86DRIGetDrawableInfo(dpy, scrn, pdp->draw,
+ &pdp->index, &pdp->lastStamp,
+ &pdp->x, &pdp->y, &pdp->w, &pdp->h,
+ &pdp->numClipRects, &pdp->pClipRects)) {
+ pdp->numClipRects = 0;
+ pdp->pClipRects = NULL;
+ /* ERROR!!! */
+ }
+
+ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+
+ pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
+}
+
+/*****************************************************************/
+
+static void *driMesaCreateDrawable(Display *dpy, int scrn, GLXDrawable draw,
+ VisualID vid, __DRIdrawable *pdraw)
+{
+ __DRIscreen *pDRIScreen;
+ __DRIscreenPrivate *psp;
+ __DRIdrawablePrivate *pdp;
+ int i;
+ XMesaVisual xm_vis = NULL;
+
+ pdp = (__DRIdrawablePrivate *)Xmalloc(sizeof(__DRIdrawablePrivate));
+ if (!pdp) {
+ return NULL;
+ }
+
+ if (!XF86DRICreateDrawable(dpy, scrn, draw, &pdp->hHWDrawable)) {
+ Xfree(pdp);
+ return NULL;
+ }
+
+ pdp->draw = draw;
+ pdp->refcount = 0;
+ pdp->pStamp = NULL;
+ pdp->lastStamp = 0;
+ pdp->index = 0;
+ pdp->x = 0;
+ pdp->y = 0;
+ pdp->w = 0;
+ pdp->h = 0;
+ pdp->numClipRects = 0;
+ pdp->pClipRects = NULL;
+
+ pDRIScreen = __glXFindDRIScreen(dpy, scrn);
+ pdp->driScreenPriv = psp = (__DRIscreenPrivate *)pDRIScreen->private;
+
+ pdp->driContextPriv = &psp->dummyContextPriv;
+
+ for (i = 0; i < psp->numVisuals; i++) {
+ if (vid == psp->visuals[i].vid) {
+ xm_vis = psp->visuals[i].xm_vis;
+ break;
+ }
+ }
+
+ if (1 /* NOT_DONE: Determine if it is a pixmap or not */) {
+ pdp->xm_buf = (*psp->XMesaAPI.CreateWindowBuffer)(xm_vis, draw, pdp);
+ } else {
+ XMesaVisual xm_vis = NULL;
+ XMesaColormap cmap = 0;
+ pdp->xm_buf = (*psp->XMesaAPI.CreatePixmapBuffer)(xm_vis, draw, cmap,
+ pdp);
+ }
+ if (!pdp->xm_buf) {
+ (void)XF86DRIDestroyDrawable(dpy, scrn, pdp->draw);
+ Xfree(pdp);
+ return NULL;
+ }
+
+ pdraw->destroyDrawable = driMesaDestroyDrawable;
+ pdraw->swapBuffers = driMesaSwapBuffers;
+
+ return (void *)pdp;
+}
+
+static __DRIdrawable *driMesaGetDrawable(Display *dpy, GLXDrawable draw)
+{
+ /*
+ ** Make sure this routine returns NULL if the drawable is not bound
+ ** to a direct rendering context!
+ */
+ return __driMesaFindDrawable(draw);
+}
+
+static void driMesaSwapBuffers(Display *dpy, void *private)
+{
+ __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)private;
+ __DRIscreenPrivate *psp = pdp->driScreenPriv;
+
+ (*psp->XMesaAPI.SwapBuffers)(pdp->xm_buf);
+}
+
+static void driMesaDestroyDrawable(Display *dpy, void *private)
+{
+ __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)private;
+ __DRIscreenPrivate *psp = pdp->driScreenPriv;
+ int scrn = psp->myNum;
+
+ if (pdp) {
+ (*psp->XMesaAPI.DestroyBuffer)(pdp->xm_buf);
+ (void)XF86DRIDestroyDrawable(dpy, scrn, pdp->draw);
+ if (pdp->pClipRects)
+ Xfree(pdp->pClipRects);
+ Xfree(pdp);
+ }
+}
+
+/*****************************************************************/
+
+static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared,
+ __DRIcontext *pctx)
+{
+ __DRIcontextPrivate *pcp;
+ __DRIcontextPrivate *pshare = (__DRIcontextPrivate *)shared;
+ XMesaContext shared_xm_ctx = (pshare ?
+ pshare->xm_ctx : (XMesaContext)NULL);
+ __DRIscreenPrivate *psp;
+ __DRIscreen *pDRIScreen;
+ int i;
+
+ pDRIScreen = __glXFindDRIScreen(dpy, vis->screen);
+ psp = (__DRIscreenPrivate *)pDRIScreen->private;
+
+ if (!psp->dummyContextPriv.driScreenPriv) {
+ if (!XF86DRICreateContext(dpy, vis->screen, vis->visual,
+ &psp->dummyContextPriv.contextID,
+ &psp->dummyContextPriv.hHWContext)) {
+ return NULL;
+ }
+ psp->dummyContextPriv.driScreenPriv = psp;
+ psp->dummyContextPriv.xm_ctx = NULL;
+ psp->dummyContextPriv.driDrawablePriv = NULL;
+ /* No other fields should be used! */
+ }
+
+ pcp = (__DRIcontextPrivate *)Xmalloc(sizeof(__DRIcontextPrivate));
+ if (!pcp) {
+ return NULL;
+ }
+
+ pcp->driScreenPriv = psp;
+ pcp->xm_ctx = NULL;
+ pcp->driDrawablePriv = NULL;
+
+ if (!XF86DRICreateContext(dpy, vis->screen, vis->visual,
+ &pcp->contextID, &pcp->hHWContext)) {
+ Xfree(pcp);
+ return NULL;
+ }
+
+ for (i = 0; i < psp->numVisuals; i++)
+ if (psp->visuals[i].vid == vis->visualid)
+ pcp->xm_ctx = (*psp->XMesaAPI.CreateContext)
+ (psp->visuals[i].xm_vis, shared_xm_ctx, pcp);
+
+ if (!pcp->xm_ctx) {
+ (void)XF86DRIDestroyContext(dpy, vis->screen, pcp->contextID);
+ Xfree(pcp);
+ return NULL;
+ }
+
+ pctx->destroyContext = driMesaDestroyContext;
+ pctx->bindContext = driMesaBindContext;
+ pctx->unbindContext = driMesaUnbindContext;
+
+ return pcp;
+}
+
+static void driMesaDestroyContext(Display *dpy, int scrn, void *private)
+{
+ __DRIcontextPrivate *pcp = (__DRIcontextPrivate *)private;
+
+ if (pcp) {
+ (void)XF86DRIDestroyContext(dpy, scrn, pcp->contextID);
+ (*pcp->driScreenPriv->XMesaAPI.DestroyContext)(pcp->xm_ctx);
+ Xfree(pcp);
+ }
+}
+
+/*****************************************************************/
+
+static void *driMesaCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
+ int numConfigs, __GLXvisualConfig *config)
+{
+ int directCapable, i, n;
+ __DRIscreenPrivate *psp;
+ XVisualInfo visTmpl, *visinfo;
+ drmHandle hFB, hSAREA;
+ char *BusID, *driverName;
+ drmMagic magic;
+
+ if (!XF86DRIQueryDirectRenderingCapable(dpy, scrn, &directCapable)) {
+ return NULL;
+ }
+
+ if (!directCapable) {
+ return NULL;
+ }
+
+ psp = (__DRIscreenPrivate *)Xmalloc(sizeof(__DRIscreenPrivate));
+ if (!psp) {
+ return NULL;
+ }
+
+ psp->myNum = scrn;
+
+ if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
+ Xfree(psp);
+ return NULL;
+ }
+
+ /*
+ ** NOT_DONE: This is used by the X server to detect when the client
+ ** has died while holding the drawable lock. The client sets the
+ ** drawable lock to this value.
+ */
+ psp->drawLockID = 1;
+
+ psp->fd = drmOpen(NULL,BusID);
+ if (!psp->fd) {
+ Xfree(BusID);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+ Xfree(BusID); /* No longer needed */
+
+ if (drmGetMagic(psp->fd, &magic)) {
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+
+ if (!XF86DRIAuthConnection(dpy, scrn, magic)) {
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+
+ if (!XF86DRIGetClientDriverName(dpy, scrn,
+ &psp->major,
+ &psp->minor,
+ &psp->patch,
+ &driverName)) {
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+
+ driMesaInitAPI(&psp->XMesaAPI);
+
+ if (!XF86DRIGetDeviceInfo(dpy, scrn,
+ &hFB,
+ &psp->fbOrigin,
+ &psp->fbSize,
+ &psp->fbStride,
+ &psp->devPrivSize,
+ &psp->pDevPriv)) {
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+ psp->fbWidth = DisplayWidth(dpy, scrn);
+ psp->fbHeight = DisplayHeight(dpy, scrn);
+ psp->fbBPP = 32; /* NOT_DONE: Get this from X server */
+
+ if (drmMap(psp->fd, hFB, psp->fbSize, (drmAddressPtr)&psp->pFB)) {
+ Xfree(psp->pDevPriv);
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+
+ if (drmMap(psp->fd, hSAREA, SAREA_MAX, (drmAddressPtr)&psp->pSAREA)) {
+ (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
+ Xfree(psp->pDevPriv);
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+
+ psp->numVisuals = numConfigs;
+ psp->visuals = (__DRIvisualPrivate *)Xmalloc(numConfigs *
+ sizeof(__DRIvisualPrivate));
+ if (!psp->visuals) {
+ (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
+ (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
+ Xfree(psp->pDevPriv);
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+
+ visTmpl.screen = scrn;
+ visinfo = XGetVisualInfo(dpy, VisualScreenMask, &visTmpl, &n);
+ if (n != numConfigs) {
+ (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
+ (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
+ Xfree(psp->pDevPriv);
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+
+ for (i = 0; i < numConfigs; i++, config++) {
+ psp->visuals[i].vid = visinfo[i].visualid;
+ psp->visuals[i].xm_vis =
+ (*psp->XMesaAPI.CreateVisual)(dpy,
+ &visinfo[i],
+ config->rgba,
+ (config->alphaSize > 0),
+ config->doubleBuffer,
+ config->stereo,
+ GL_TRUE, /* ximage_flag */
+ config->depthSize,
+ config->stencilSize,
+ config->accumRedSize,
+ config->level);
+ if (!psp->visuals[i].xm_vis) {
+ /* Free the visuals so far created */
+ while (--i >= 0) {
+ (*psp->XMesaAPI.DestroyVisual)(psp->visuals[i].xm_vis);
+ }
+ Xfree(psp->visuals);
+ XFree(visinfo);
+ (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
+ (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
+ Xfree(psp->pDevPriv);
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+ }
+ XFree(visinfo);
+
+ /* Initialize the screen specific GLX driver */
+ if (psp->XMesaAPI.InitDriver) {
+ if (!(*psp->XMesaAPI.InitDriver)(psp)) {
+ while (--psp->numVisuals >= 0) {
+ (*psp->XMesaAPI.DestroyVisual)
+ (psp->visuals[psp->numVisuals].xm_vis);
+ }
+ Xfree(psp->visuals);
+ (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
+ (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
+ Xfree(psp->pDevPriv);
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+ (void)XF86DRICloseConnection(dpy, scrn);
+ return NULL;
+ }
+ }
+
+ /*
+ ** Do not init dummy context here; actual initialization will be
+ ** done when the first DRI context is created. Init screen priv ptr
+ ** to NULL to let CreateContext routine that it needs to be inited.
+ */
+ psp->dummyContextPriv.driScreenPriv = NULL;
+
+ psc->destroyScreen = driMesaDestroyScreen;
+ psc->createContext = driMesaCreateContext;
+ psc->createDrawable = driMesaCreateDrawable;
+ psc->getDrawable = driMesaGetDrawable;
+
+ return (void *)psp;
+}
+
+static void driMesaDestroyScreen(Display *dpy, int scrn, void *private)
+{
+ __DRIscreenPrivate *psp = (__DRIscreenPrivate *)private;
+
+ if (psp) {
+ if (psp->dummyContextPriv.driScreenPriv) {
+ (void)XF86DRIDestroyContext(dpy, scrn,
+ psp->dummyContextPriv.contextID);
+ }
+ if (psp->XMesaAPI.ResetDriver)
+ (*psp->XMesaAPI.ResetDriver)(psp);
+ while (--psp->numVisuals >= 0) {
+ (*psp->XMesaAPI.DestroyVisual)
+ (psp->visuals[psp->numVisuals].xm_vis);
+ }
+ Xfree(psp->visuals);
+ (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
+ (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
+ Xfree(psp->pDevPriv);
+ (void)drmClose(psp->fd);
+ Xfree(psp);
+
+#if 0
+ /*
+ ** NOT_DONE: Normally, we would call XF86DRICloseConnection()
+ ** here, but since this routine is called after the
+ ** XCloseDisplay() function has already shut down the connection
+ ** to the Display, there is no protocol stream open to the X
+ ** server anymore. Luckily, XF86DRICloseConnection() does not
+ ** really do anything (for now).
+ */
+ (void)XF86DRICloseConnection(dpy, scrn);
+#endif
+ }
+}
+
+
+/*
+ * This is the entrypoint into the driver.
+ * The driCreateScreen name is the symbol that libGL.so fetches.
+ */
+void *driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
+ int numConfigs, __GLXvisualConfig *config)
+{
+ return driMesaCreateScreen(dpy, scrn, psc, numConfigs, config);
+}
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/dri/dri_mesa.h b/xc/lib/GL/mesa/dri/dri_mesa.h
new file mode 100644
index 000000000..8b421eff0
--- /dev/null
+++ b/xc/lib/GL/mesa/dri/dri_mesa.h
@@ -0,0 +1,48 @@
+/* $XFree86: xc/lib/GL/mesa/dri/dri_mesa.h,v 1.1 2000/02/08 17:18:36 dawes Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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, 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 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $PI: xc/lib/GL/dri/dri_mesa.h,v 1.5 1999/04/05 05:24:31 martin Exp $
+ */
+
+#ifndef _DRI_MESA_H_
+#define _DRI_MESA_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate;
+typedef struct __DRIscreenPrivateRec __DRIscreenPrivate;
+typedef struct __DRIvisualPrivateRec __DRIvisualPrivate;
+typedef struct __DRIcontextPrivateRec __DRIcontextPrivate;
+typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate;
+
+#endif
+#endif /* _DRI_MESA_H_ */
diff --git a/xc/lib/GL/mesa/dri/dri_mesaint.h b/xc/lib/GL/mesa/dri/dri_mesaint.h
new file mode 100644
index 000000000..d77d7cd63
--- /dev/null
+++ b/xc/lib/GL/mesa/dri/dri_mesaint.h
@@ -0,0 +1,246 @@
+/* $XFree86: xc/lib/GL/mesa/dri/dri_mesaint.h,v 1.5 2000/02/15 07:13:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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, 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 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $PI: xc/lib/GL/dri/dri_mesaint.h,v 1.8 1999/06/14 21:10:35 faith Exp $
+ */
+
+#ifndef _DRI_MESAINT_H_
+#define _DRI_MESAINT_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <GL/glx.h>
+#include "xf86dri.h"
+#include "sarea.h"
+#include "GL/xmesa.h"
+#include "dri_mesa.h"
+#include "dri_xmesaapi.h"
+
+#define DRI_MESA_VALIDATE_DRAWABLE_INFO(dpy,scrn,pDrawPriv) \
+ do { \
+ if (*(pDrawPriv->pStamp) != pDrawPriv->lastStamp) { \
+ driMesaUpdateDrawableInfo(dpy,scrn,pDrawPriv); \
+ } \
+ } while (0)
+
+
+struct __DRIdrawablePrivateRec {
+ /*
+ ** Kernel drawable handle (not currently used).
+ */
+ drmDrawable hHWDrawable;
+
+ /*
+ ** Mesa's private context information. This structure is opaque.
+ */
+ XMesaBuffer xm_buf;
+
+ /*
+ ** X's drawable ID associated with this private drawable.
+ */
+ GLXDrawable draw;
+
+ /*
+ ** Reference count for number of context's currently bound to this
+ ** drawable. Once the refcount reaches 0, the drawable can be
+ ** destroyed. This behavior will change with GLX 1.3.
+ */
+ int refcount;
+
+ /*
+ ** Index of this drawable's information in the SAREA.
+ */
+ unsigned int index;
+
+ /*
+ ** Pointer to the "drawable has changed ID" stamp in the SAREA.
+ */
+ unsigned int *pStamp;
+
+ /*
+ ** Last value of the stamp. If this differs from the value stored
+ ** at *pStamp, then the drawable information has been modified by
+ ** the X server, and the drawable information (below) should be
+ ** retrieved from the X server.
+ */
+ unsigned int lastStamp;
+
+ /*
+ ** Drawable information used in software fallbacks.
+ */
+ int x;
+ int y;
+ int w;
+ int h;
+ int numClipRects;
+ XF86DRIClipRectPtr pClipRects;
+
+ /*
+ ** Pointer to context to which this drawable is currently bound.
+ */
+ __DRIcontextPrivate *driContextPriv;
+
+ /*
+ ** Pointer to screen on which this drawable was created.
+ */
+ __DRIscreenPrivate *driScreenPriv;
+};
+
+struct __DRIcontextPrivateRec {
+ /*
+ ** Kernel context handle used to access the device lock.
+ */
+ XID contextID;
+
+ /*
+ ** Kernel context handle used to access the device lock.
+ */
+ drmContext hHWContext;
+
+ /*
+ ** Mesa's private context information. This structure is opaque.
+ */
+ XMesaContext xm_ctx;
+
+ /*
+ ** Pointer to drawable currently bound to this context.
+ */
+ __DRIdrawablePrivate *driDrawablePriv;
+
+ /*
+ ** Pointer to screen on which this context was created.
+ */
+ __DRIscreenPrivate *driScreenPriv;
+};
+
+struct __DRIvisualPrivateRec {
+ /*
+ ** Mesa's private visual information. This structure is opaque.
+ */
+ XMesaVisual xm_vis;
+
+ /*
+ ** X's visual ID associated with this private visual.
+ */
+ VisualID vid;
+};
+
+struct __DRIscreenPrivateRec {
+ /*
+ ** Current screen's number
+ */
+ int myNum;
+
+ /*
+ ** Core rendering library's visuals associated with the current
+ ** screen.
+ */
+ __DRIvisualPrivate *visuals;
+ int numVisuals;
+
+ /*
+ ** Function pointers associated with Mesa's GLX functions.
+ */
+ __XMESAapi XMesaAPI;
+
+ /*
+ ** Core rendering library's driver version information.
+ */
+ int major;
+ int minor;
+ int patch;
+
+ /*
+ ** ID used when the client sets the drawable lock. The X server
+ ** uses this value to detect if the client has died while holding
+ ** the drawable lock.
+ */
+ int drawLockID;
+
+ /*
+ ** File descriptor returned when the kernel device driver is opened.
+ ** It is used to:
+ ** - authenticate client to kernel
+ ** - map the frame buffer, SAREA, etc.
+ ** - close the kernel device driver
+ */
+ int fd;
+
+ /*
+ ** SAREA pointer used to access:
+ ** - the device lock
+ ** - the device-independent per-drawable and per-context(?) information
+ */
+ XF86DRISAREAPtr pSAREA;
+
+ /*
+ ** Direct frame buffer access information used for software
+ ** fallbacks.
+ */
+ unsigned char *pFB;
+ int fbSize;
+ int fbOrigin;
+ int fbStride;
+ int fbWidth;
+ int fbHeight;
+ int fbBPP;
+
+ /*
+ ** Device-dependent private information (stored in the SAREA). This
+ ** data is accessed by the client driver only.
+ */
+ void *pDevPriv;
+ int devPrivSize;
+
+ /*
+ ** Dummy context to which drawables are bound when not bound to any
+ ** other context. A dummy hHWContext is created for this context,
+ ** and is used by the GL core when a HW lock is required but the
+ ** drawable is not currently bound (e.g., potentially during a
+ ** SwapBuffers request). The dummy context is created when the
+ ** first "real" context is created on this screen.
+ */
+ __DRIcontextPrivate dummyContextPriv;
+
+ /*
+ ** Device-dependent private information (not stored in the SAREA).
+ ** This pointer is never touched by the DRI layer.
+ */
+ void *private;
+};
+
+
+extern void driMesaUpdateDrawableInfo(Display *dpy, int scrn,
+ __DRIdrawablePrivate *pdp);
+
+#endif
+#endif /* _DRI_MESAINT_H_ */
diff --git a/xc/lib/GL/mesa/dri/dri_xmesaapi.h b/xc/lib/GL/mesa/dri/dri_xmesaapi.h
new file mode 100644
index 000000000..0db1d1296
--- /dev/null
+++ b/xc/lib/GL/mesa/dri/dri_xmesaapi.h
@@ -0,0 +1,77 @@
+/* $XFree86: xc/lib/GL/mesa/dri/dri_xmesaapi.h,v 1.2 2000/02/15 07:13:29 martin Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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, 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 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $PI: xc/lib/GL/dri/dri_xmesaapi.h,v 1.4 1999/04/05 05:24:31 martin Exp $
+ */
+
+#ifndef _DRI_XMESAAPI_H_
+#define _DRI_XMESAAPI_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "GL/xmesa.h"
+#include "dri_mesa.h"
+
+typedef struct __XMESAapiRec __XMESAapi;
+
+struct __XMESAapiRec {
+ /* XMESA Functions */
+ GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv);
+ void (*ResetDriver)(__DRIscreenPrivate *driScrnPriv);
+ XMesaVisual (*CreateVisual)(XMesaDisplay *display,
+ XMesaVisualInfo visinfo,
+ GLboolean rgb_flag,
+ GLboolean alpha_flag,
+ GLboolean db_flag,
+ GLboolean stereo_flag,
+ GLboolean ximage_flag,
+ GLint depth_size,
+ GLint stencil_size,
+ GLint accum_size,
+ GLint level);
+ void (*DestroyVisual)(XMesaVisual v);
+ XMesaContext (*CreateContext)(XMesaVisual v, XMesaContext share_list,
+ __DRIcontextPrivate *driContextPriv);
+ void (*DestroyContext)(XMesaContext c);
+ XMesaBuffer (*CreateWindowBuffer)(XMesaVisual v, XMesaWindow w,
+ __DRIdrawablePrivate *driDrawPriv);
+ XMesaBuffer (*CreatePixmapBuffer)(XMesaVisual v, XMesaPixmap p,
+ XMesaColormap c,
+ __DRIdrawablePrivate *driDrawPriv);
+ void (*DestroyBuffer)(XMesaBuffer b);
+ void (*SwapBuffers)(XMesaBuffer b);
+ GLboolean (*MakeCurrent)(XMesaContext c, XMesaBuffer b);
+ GLboolean (*UnbindContext)(XMesaContext c);
+};
+
+#endif
+#endif /* _DRI_XMESAAPI_H_ */
diff --git a/xc/lib/GL/mesa/include/GL/Imakefile b/xc/lib/GL/mesa/include/GL/Imakefile
new file mode 100644
index 000000000..fec9e3354
--- /dev/null
+++ b/xc/lib/GL/mesa/include/GL/Imakefile
@@ -0,0 +1,13 @@
+XCOMM $XFree86: xc/lib/GL/mesa/include/GL/Imakefile,v 1.1 2000/02/08 17:18:37 dawes Exp $
+XCOMM $PI: xc/programs/Xserver/GL/mesa/include/GL/Imakefile,v 1.6 1999/03/15 21:36:09 martin Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+ DEFINES = $(GLX_DEFINES)
+
+LinkSourceFile(gl.h, ../../../../../extras/Mesa/include/GL)
+LinkSourceFile(glx.h, ../../../../../extras/Mesa/include/GL)
+LinkSourceFile(xmesa.h, ../../../../../extras/Mesa/include/GL)
+LinkSourceFile(xmesa_x.h, ../../../../../extras/Mesa/include/GL)
+LinkSourceFile(xmesa_xf86.h, ../../../../../extras/Mesa/include/GL)
diff --git a/xc/lib/GL/mesa/src/Imakefile b/xc/lib/GL/mesa/src/Imakefile
index be1de5f3e..b3dade36c 100644
--- a/xc/lib/GL/mesa/src/Imakefile
+++ b/xc/lib/GL/mesa/src/Imakefile
@@ -1,5 +1,6 @@
-XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile,v 1.5 1999/12/14 01:32:25 robin Exp $
-XCOMM $PI: xc/lib/GL/mesa/src/Imakefile,v 1.5 1999/06/21 05:13:55 martin Exp $
+XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile,v 1.9 2000/02/15 07:13:29 martin Exp $
+
+#include <Threads.tmpl>
#define DoNormalLib NormalLibGlx
#define DoSharedLib SharedLibGlx
@@ -22,10 +23,6 @@ LinkSourceFile(alpha.c, ../../../../extras/Mesa/src)
LinkSourceFile(alpha.h, ../../../../extras/Mesa/src)
LinkSourceFile(alphabuf.c, ../../../../extras/Mesa/src)
LinkSourceFile(alphabuf.h, ../../../../extras/Mesa/src)
-LinkSourceFile(api.h, ../../../../extras/Mesa/src)
-LinkSourceFile(api1.c, ../../../../extras/Mesa/src)
-LinkSourceFile(api2.c, ../../../../extras/Mesa/src)
-LinkSourceFile(apiext.c, ../../../../extras/Mesa/src)
LinkSourceFile(attrib.c, ../../../../extras/Mesa/src)
LinkSourceFile(attrib.h, ../../../../extras/Mesa/src)
LinkSourceFile(bbox.c, ../../../../extras/Mesa/src)
@@ -34,6 +31,8 @@ LinkSourceFile(bitmap.c, ../../../../extras/Mesa/src)
LinkSourceFile(bitmap.h, ../../../../extras/Mesa/src)
LinkSourceFile(blend.c, ../../../../extras/Mesa/src)
LinkSourceFile(blend.h, ../../../../extras/Mesa/src)
+LinkSourceFile(buffers.c, ../../../../extras/Mesa/src)
+LinkSourceFile(buffers.h, ../../../../extras/Mesa/src)
LinkSourceFile(clip.c, ../../../../extras/Mesa/src)
LinkSourceFile(clip.h, ../../../../extras/Mesa/src)
LinkSourceFile(clip_funcs.h, ../../../../extras/Mesa/src)
@@ -77,12 +76,24 @@ LinkSourceFile(fog_tmp.h, ../../../../extras/Mesa/src)
LinkSourceFile(general_clip.h, ../../../../extras/Mesa/src)
LinkSourceFile(get.c, ../../../../extras/Mesa/src)
LinkSourceFile(get.h, ../../../../extras/Mesa/src)
-LinkSourceFile(glmisc.c, ../../../../extras/Mesa/src)
-LinkSourceFile(glmisc.h, ../../../../extras/Mesa/src)
+LinkSourceFile(glapi.c, ../../../../extras/Mesa/src)
+LinkSourceFile(glapi.h, ../../../../extras/Mesa/src)
+LinkSourceFile(glapinoop.c, ../../../../extras/Mesa/src)
+LinkSourceFile(glapinoop.h, ../../../../extras/Mesa/src)
+LinkSourceFile(glapioffsets.h, ../../../../extras/Mesa/src)
+LinkSourceFile(glapitable.h, ../../../../extras/Mesa/src)
+LinkSourceFile(glapitemp.h, ../../../../extras/Mesa/src)
+LinkSourceFile(glheader.h, ../../../../extras/Mesa/src)
+LinkSourceFile(glthread.c, ../../../../extras/Mesa/src)
+LinkSourceFile(glthread.h, ../../../../extras/Mesa/src)
LinkSourceFile(hash.c, ../../../../extras/Mesa/src)
LinkSourceFile(hash.h, ../../../../extras/Mesa/src)
+LinkSourceFile(hint.c, ../../../../extras/Mesa/src)
+LinkSourceFile(hint.h, ../../../../extras/Mesa/src)
LinkSourceFile(image.c, ../../../../extras/Mesa/src)
LinkSourceFile(image.h, ../../../../extras/Mesa/src)
+LinkSourceFile(imaging.c, ../../../../extras/Mesa/src)
+LinkSourceFile(imaging.h, ../../../../extras/Mesa/src)
LinkSourceFile(indirect_tmp.h, ../../../../extras/Mesa/src)
LinkSourceFile(interp_tmp.h, ../../../../extras/Mesa/src)
LinkSourceFile(light.c, ../../../../extras/Mesa/src)
@@ -98,10 +109,10 @@ LinkSourceFile(masking.c, ../../../../extras/Mesa/src)
LinkSourceFile(masking.h, ../../../../extras/Mesa/src)
LinkSourceFile(matrix.c, ../../../../extras/Mesa/src)
LinkSourceFile(matrix.h, ../../../../extras/Mesa/src)
+LinkSourceFile(mem.c, ../../../../extras/Mesa/src)
+LinkSourceFile(mem.h, ../../../../extras/Mesa/src)
LinkSourceFile(mmath.c, ../../../../extras/Mesa/src)
LinkSourceFile(mmath.h, ../../../../extras/Mesa/src)
-LinkSourceFile(mthreads.c, ../../../../extras/Mesa/src)
-LinkSourceFile(mthreads.h, ../../../../extras/Mesa/src)
LinkSourceFile(norm_tmp.h, ../../../../extras/Mesa/src)
LinkSourceFile(pb.c, ../../../../extras/Mesa/src)
LinkSourceFile(pb.h, ../../../../extras/Mesa/src)
@@ -109,8 +120,6 @@ LinkSourceFile(pipeline.c, ../../../../extras/Mesa/src)
LinkSourceFile(pipeline.h, ../../../../extras/Mesa/src)
LinkSourceFile(pixel.c, ../../../../extras/Mesa/src)
LinkSourceFile(pixel.h, ../../../../extras/Mesa/src)
-LinkSourceFile(pointers.c, ../../../../extras/Mesa/src)
-LinkSourceFile(pointers.h, ../../../../extras/Mesa/src)
LinkSourceFile(points.c, ../../../../extras/Mesa/src)
LinkSourceFile(points.h, ../../../../extras/Mesa/src)
LinkSourceFile(polygon.c, ../../../../extras/Mesa/src)
@@ -134,6 +143,8 @@ LinkSourceFile(span.c, ../../../../extras/Mesa/src)
LinkSourceFile(span.h, ../../../../extras/Mesa/src)
LinkSourceFile(stages.c, ../../../../extras/Mesa/src)
LinkSourceFile(stages.h, ../../../../extras/Mesa/src)
+LinkSourceFile(state.c, ../../../../extras/Mesa/src)
+LinkSourceFile(state.h, ../../../../extras/Mesa/src)
LinkSourceFile(stencil.c, ../../../../extras/Mesa/src)
LinkSourceFile(stencil.h, ../../../../extras/Mesa/src)
LinkSourceFile(texgen_tmp.h, ../../../../extras/Mesa/src)
@@ -178,41 +189,157 @@ LinkSourceFile(xform_tmp.h, ../../../../extras/Mesa/src)
LinkSourceFile(zoom.c, ../../../../extras/Mesa/src)
LinkSourceFile(zoom.h, ../../../../extras/Mesa/src)
- CORE_SRCS = accum.c alpha.c alphabuf.c api1.c api2.c apiext.c \
- attrib.c bitmap.c blend.c clip.c colortab.c context.c \
- copypix.c depth.c dlist.c drawpix.c enable.c eval.c \
- feedback.c fog.c get.c hash.c image.c light.c lines.c \
- logic.c masking.c matrix.c glmisc.c mmath.c mthreads.c \
- pb.c pixel.c points.c pointers.c polygon.c quads.c \
- rastpos.c readpix.c rect.c scissor.c shade.c span.c \
- stencil.c teximage.c texobj.c texstate.c texture.c \
- triangle.c varray.c winpos.c vb.c vbfill.c vbrender.c \
- vbxform.c xform.c zoom.c stages.c \
- bbox.c config.c cva.c enums.c extensions.c \
- pipeline.c translate.c vbcull.c vbindirect.c vector.c \
- vertices.c
+ CORE_SRCS = accum.c \
+ alpha.c \
+ alphabuf.c \
+ attrib.c \
+ bbox.c \
+ bitmap.c \
+ blend.c \
+ buffers.c \
+ clip.c \
+ colortab.c \
+ config.c \
+ context.c \
+ copypix.c \
+ cva.c \
+ debug_xform.c \
+ depth.c \
+ dlist.c \
+ drawpix.c \
+ enable.c \
+ enums.c \
+ eval.c \
+ extensions.c \
+ feedback.c \
+ fog.c \
+ get.c \
+ glapi.c \
+ glapinoop.c \
+ glthread.c \
+ hash.c \
+ hint.c \
+ image.c \
+ imaging.o \
+ light.c \
+ lines.c \
+ logic.c \
+ masking.c \
+ matrix.c \
+ mem.c \
+ mmath.c \
+ pb.c \
+ pipeline.c \
+ pixel.c \
+ points.c \
+ polygon.c \
+ quads.c \
+ rastpos.c \
+ readpix.c \
+ rect.c \
+ scissor.c \
+ shade.c \
+ span.c \
+ stages.c \
+ state.c \
+ stencil.c \
+ teximage.c \
+ texobj.c \
+ texstate.c \
+ texture.c \
+ translate.c \
+ triangle.c \
+ varray.c \
+ vb.c \
+ vbcull.c \
+ vbfill.c \
+ vbindirect.c \
+ vbrender.c \
+ vbxform.c \
+ vector.c \
+ vertices.c \
+ winpos.c \
+ xform.c \
+ zoom.c
- CORE_OBJS = accum.o alpha.o alphabuf.o api1.o api2.o apiext.o \
- attrib.o bitmap.o blend.o clip.o colortab.o context.o \
- copypix.o depth.o dlist.o drawpix.o enable.o eval.o \
- feedback.o fog.o get.o hash.o image.o light.o lines.o \
- logic.o masking.o matrix.o glmisc.o mmath.o mthreads.o \
- pb.o pixel.o points.o pointers.o polygon.o quads.o \
- rastpos.o readpix.o rect.o scissor.o shade.o span.o \
- stencil.o teximage.o texobj.o texstate.o texture.o \
- triangle.o varray.o winpos.o vb.o vbfill.o vbrender.o \
- vbxform.o xform.o zoom.o stages.o \
- bbox.o config.o cva.o enums.o extensions.o \
- pipeline.o translate.o vbcull.o vbindirect.o vector.o \
- vertices.o
+ CORE_OBJS = accum.o \
+ alpha.o \
+ alphabuf.o \
+ attrib.o \
+ bbox.o \
+ bitmap.o \
+ blend.o \
+ buffers.o \
+ clip.o \
+ colortab.o \
+ config.o \
+ context.o \
+ copypix.o \
+ cva.o \
+ debug_xform.o \
+ depth.o \
+ dlist.o \
+ drawpix.o \
+ enable.o \
+ enums.o \
+ eval.o \
+ extensions.o \
+ feedback.o \
+ fog.o \
+ get.o \
+ hash.o \
+ hint.o \
+ image.o \
+ imaging.o \
+ light.o \
+ lines.o \
+ logic.o \
+ masking.o \
+ matrix.o \
+ mem.o \
+ mmath.o \
+ pb.o \
+ pipeline.o \
+ pixel.o \
+ points.o \
+ polygon.o \
+ quads.o \
+ rastpos.o \
+ readpix.o \
+ rect.o \
+ scissor.o \
+ shade.o \
+ span.o \
+ stages.o \
+ state.o \
+ stencil.o \
+ teximage.o \
+ texobj.o \
+ texstate.o \
+ texture.o \
+ translate.o \
+ triangle.o \
+ varray.o \
+ vb.o \
+ vbcull.o \
+ vbfill.o \
+ vbindirect.o \
+ vbrender.o \
+ vbxform.o \
+ vector.o \
+ vertices.o \
+ winpos.o \
+ xform.o \
+ zoom.o
+#ifdef i386Architecture
ASM_SRCS =
ASM_OBJS =
- ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM
-# -DUSE_3DNOW_ASM
+ ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM -DUSE_3DNOW_ASM
+#endif
DEFINES = $(ALLOC_DEFINES) GlxDefines $(TDFX_DEFS) $(ASM_DEFS)
- INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) -I../include -I../../dri
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) -I../include -I../../dri -I. -I../../../../include
SRCS = $(CORE_SRCS) $(ASM_SRCS)
OBJS = $(CORE_OBJS) $(ASM_OBJS)
@@ -250,7 +377,7 @@ LIBNAME = mesa_dri.so
ALL_OBJS = $(CORE_OBJS) X/?*.o X86/?*.o
ALL_DEPS = $(SUBDIRS) DONE X/DONE X86/DONE
SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
-InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.)
#endif
DependTarget()
diff --git a/xc/lib/GL/mesa/src/X/Imakefile b/xc/lib/GL/mesa/src/X/Imakefile
index bf0671c0b..b01a469e9 100644
--- a/xc/lib/GL/mesa/src/X/Imakefile
+++ b/xc/lib/GL/mesa/src/X/Imakefile
@@ -1,4 +1,4 @@
-XCOMM $XFree86: xc/lib/GL/mesa/src/X/Imakefile,v 1.3 1999/12/14 01:33:34 robin Exp $
+XCOMM $XFree86: xc/lib/GL/mesa/src/X/Imakefile,v 1.4 2000/02/08 17:18:40 dawes Exp $
XCOMM $PI: xc/lib/GL/mesa/src/X/Imakefile,v 1.4 1999/06/21 05:13:55 martin Exp $
#define DoNormalLib NormalLibGlx
@@ -11,6 +11,8 @@ LinkSourceFile(xmesa1.c, ../../../../../extras/Mesa/src/X)
LinkSourceFile(xmesa2.c, ../../../../../extras/Mesa/src/X)
LinkSourceFile(xmesa3.c, ../../../../../extras/Mesa/src/X)
LinkSourceFile(xmesa4.c, ../../../../../extras/Mesa/src/X)
+LinkSourceFile(xmesaP.h, ../../../../../extras/Mesa/src/X)
+LinkSourceFile(glxheader.h, ../../../../../extras/Mesa/src/X)
#if Malloc0ReturnsNull
@@ -19,17 +21,11 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
#if BuildXF86DRI
DRI_DEFINES = GlxDefines
- DRI_INCLUDES = -I../../../dri -I../../../glx \
+ DRI_INCLUDES = -I../../../dri -I../../../glx -I../../dri \
-I$(TOP)/include -I$(TOP)/include/GL \
-I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri
#endif
-LinkSourceFile(xmesa1.c, ../../../../../extras/Mesa/src/X)
-LinkSourceFile(xmesa2.c, ../../../../../extras/Mesa/src/X)
-LinkSourceFile(xmesa3.c, ../../../../../extras/Mesa/src/X)
-LinkSourceFile(xmesa4.c, ../../../../../extras/Mesa/src/X)
-LinkSourceFile(xmesaP.h, ../../../../../extras/Mesa/src/X)
-
MESA_INCLUDES = -I. -I.. -I../../include
DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
diff --git a/xc/lib/GL/mesa/src/X86/Imakefile b/xc/lib/GL/mesa/src/X86/Imakefile
index 31df38154..99dfd8ea8 100644
--- a/xc/lib/GL/mesa/src/X86/Imakefile
+++ b/xc/lib/GL/mesa/src/X86/Imakefile
@@ -1,5 +1,4 @@
-XCOMM $XFree86: xc/lib/GL/mesa/src/X86/Imakefile,v 1.1 1999/12/14 01:49:19 robin Exp $
-XCOMM $PI: xc/lib/GL/mesa/src/Imakefile,v 1.5 1999/06/21 05:13:55 martin Exp $
+XCOMM $XFree86: xc/lib/GL/mesa/src/X86/Imakefile,v 1.4 2000/02/18 16:23:10 dawes Exp $
#define DoNormalLib NormalLibGlx
#define DoSharedLib SharedLibGlx
@@ -7,8 +6,20 @@ XCOMM $PI: xc/lib/GL/mesa/src/Imakefile,v 1.5 1999/06/21 05:13:55 martin Exp $
#define DoDebugLib DebugLibGlx
#define DoProfileLib ProfileLibGlx
-/* #define HAVE_3DNOW 1 */
-#define HAVE_MMX_ 1
+LinkSourceFile(assyntax.h, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(common_x86.c, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(common_x86asm.S, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(common_x86asm.h, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(glapi_x86.S, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(x86.c, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(x86.h, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(x86a.S, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(vertex.S, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(x86flatregs.m4, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(x86a.S.m4, ../../../../../extras/Mesa/src/X86)
+
+LinkSourceFile(mmx.h, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(mmx_blend.S, ../../../../../extras/Mesa/src/X86)
LinkSourceFile(3dnow.c, ../../../../../extras/Mesa/src/X86)
LinkSourceFile(3dnow.h, ../../../../../extras/Mesa/src/X86)
@@ -23,61 +34,51 @@ LinkSourceFile(3dnow_xform_raw3.S, ../../../../../extras/Mesa/src/X86)
LinkSourceFile(3dnow_xform_raw4.S, ../../../../../extras/Mesa/src/X86)
LinkSourceFile(vertex_3dnow.S, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(mmx.h, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(mmx_blend.S, ../../../../../extras/Mesa/src/X86)
-
-LinkSourceFile(x86a.S, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(assyntax.h, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(common_x86.c, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(common_x86asm.S, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(common_x86asm.h, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(x86.c, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(x86.h, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(vertex.S, ../../../../../extras/Mesa/src/X86)
-
-LinkSourceFile(x86flatregs.m4, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(x86a.S.m4, ../../../../../extras/Mesa/src/X86)
+LinkSourceFile(glapioffsets.h, ../../../../../extras/Mesa/src)
#if Malloc0ReturnsNull
ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
#endif
-#if HAVE_3DNOW
+#ifdef i386Architecture
+XCOMM We'll learn at runtime whether 3dNow, MMX, etc are really present.
+ X86_SRCS = x86a.S common_x86.c common_x86asm.S glapi_x86.S x86.c vertex.S
+
+ X86_OBJS = x86a.o common_x86.o common_x86asm.o x86.o vertex.o
+
+ X86_DEFS = -DUSE_X86_ASM
+
+
+ MMX_SRCS = mmx_blend.S
+
+ MMX_OBJS = mmx_blend.o
+
+ MMX_DEFS = -DUSE_MMX_ASM
+
+
+XCOMM Disabling 3DNow code for the time being
+#if 0
3DNOW_SRCS = 3dnow.c 3dnow_norm_raw.S 3dnow_xform_masked1.S \
3dnow_xform_masked2.S 3dnow_xform_masked3.S \
- 3dnow_xform_masked3.S 3dnow_xform_raw1.S \
+ 3dnow_xform_masked4.S 3dnow_xform_raw1.S \
3dnow_xform_raw2.S 3dnow_xform_raw3.S 3dnow_xform_raw4.S \
vertex_3dnow.S
3DNOW_OBJS = 3dnow.o 3dnow_norm_raw.o 3dnow_xform_masked1.o \
3dnow_xform_masked2.o 3dnow_xform_masked3.o \
- 3dnow_xform_masked3.o 3dnow_xform_raw1.o \
+ 3dnow_xform_masked4.o 3dnow_xform_raw1.o \
3dnow_xform_raw2.o 3dnow_xform_raw3.o 3dnow_xform_raw4.o \
vertex_3dnow.o
3DNOW_DEFS = -DUSE_3DNOW_ASM
#endif
-#if HAVE_MMX_
- MMX_SRCS = mmx_blend.S
-
- MMX_OBJS = mmx_blend.o
-
- MMX_DEFS = -DUSE_MMX_ASM
#endif
- X86_SRCS = x86a.S common_x86.c common_x86asm.S x86.c vertex.S \
- $(MMX_SRCS) $(3DNOW_SRCS)
-
- X86_OBJS = x86a.o common_x86.o common_x86asm.o x86.o vertex.o \
- $(MMX_OBJS) $(3DNOW_OBJS)
-
- X86_DEFS = -DUSE_X86_ASM $(MXX_DEFS) $(3DNOW_DEFS)
-
- DEFINES = $(ALLOC_DEFINES) GlxDefines -DFX $(X86_DEFS) $(3DNOW_DEFS) $(MMX_DEFS)
+ DEFINES = $(ALLOC_DEFINES) GlxDefines -DFX $(X86_DEFS) $(MMX_DEFS) $(3DNOW_DEFS)
INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) -I../include -I../../dri -I..
- SRCS = $(X86_SRCS) $(3DNOW_SRCS) $(MMX_SRCS)
- OBJS = $(X86_OBJS) $(3DNOW_OBJS) $(MMX_OBJS)
+ SRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
+ OBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
@@ -90,16 +91,34 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
LibraryObjectRule()
+STD_CPP_DEFINES = StandardDefines $(PROJECT_DEFINES)
+
SubdirLibraryRule($(OBJS))
NormalLintTarget($(SRCS))
-#if 1
+
+#ifdef HAVE_3DNOW
+ObjectFromAsmSource(3dnow_norm_raw, NullParameter)
+ObjectFromAsmSource(3dnow_xform_masked1, NullParameter)
+ObjectFromAsmSource(3dnow_xform_masked2, NullParameter)
+ObjectFromAsmSource(3dnow_xform_masked3, NullParameter)
+ObjectFromAsmSource(3dnow_xform_masked4, NullParameter)
+ObjectFromAsmSource(3dnow_xform_raw1, NullParameter)
+ObjectFromAsmSource(3dnow_xform_raw2, NullParameter)
+ObjectFromAsmSource(3dnow_xform_raw3, NullParameter)
+ObjectFromAsmSource(3dnow_xform_raw4, NullParameter)
+ObjectFromAsmSource(vertex_3dnow, NullParameter)
+#endif
+
+#ifdef HAVE_MMX
+ObjectFromAsmSource(mmx_blend, NullParameter)
#endif
+ObjectFromAsmSource(common_x86asm, NullParameter)
+ObjectFromAsmSource(vertex, NullParameter)
+ObjectFromAsmSource(x86a, NullParameter)
+
DependTarget()
x86a.S: x86flatregs.m4
x86a.S: x86a.S.m4
m4 $< >$@
-
-x86a.asm: x86a.S
- gcc -E -P -DNASM_ASSEMBLER $< >$@
diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile
index d22e1576c..471021749 100644
--- a/xc/lib/GL/mesa/src/drv/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/Imakefile
@@ -1,4 +1,4 @@
-XCOMM $XFree86: xc/lib/GL/mesa/src/drv/Imakefile,v 1.4 1999/12/29 00:44:13 robin Exp $
+XCOMM $XFree86: xc/lib/GL/mesa/src/drv/Imakefile,v 1.6 2000/02/14 06:27:12 martin Exp $
XCOMM $PI: xc/lib/GL/mesa/src/drv/Imakefile,v 1.3 1999/06/14 21:10:41 faith Exp $
#define DoNormalLib NormalLibGlx
diff --git a/xc/lib/GL/mesa/src/drv/common/Imakefile b/xc/lib/GL/mesa/src/drv/common/Imakefile
new file mode 100644
index 000000000..2bd674ffd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/Imakefile
@@ -0,0 +1,56 @@
+XCOMM $PI:$
+
+#define DoNormalLib NormalLibGlx
+#define DoSharedLib SharedLibGlx
+#define DoExtraLib SharedLibGlx
+#define DoDebugLib DebugLibGlx
+#define DoProfileLib ProfileLibGlx
+
+#if Malloc0ReturnsNull
+ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
+#endif
+
+#if BuildXF86DRI
+ DRI_DEFINES = GlxDefines -DDRIVERTS
+ DRI_INCLUDES = -I../../../../dri -I../../../../glx \
+ -I$(TOP)/include -I$(TOP)/include/GL \
+ -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
+ -I../../../include -I../.. -I../common -I../../X
+#endif
+
+MESA_INCLUDES = -I. -I.. -I../../include
+
+
+
+ DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
+ -I/usr/include/glide
+ DRISRCS = hwlog.c mm.c
+ DRIOBJS = hwlog.o mm.o
+
+ SRCS = $(DRISRCS)
+ OBJS = $(DRIOBJS)
+
+#if !GlxUseBuiltInDRIDriver
+#undef DoNormalLib NormalLibGlx
+#undef DoExtraLib SharedLibGlx
+#undef DoDebugLib DebugLibGlx
+#undef DoProfileLib ProfileLibGlx
+#endif
+
+#include <Library.tmpl>
+
+LibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+NormalLintTarget($(SRCS))
+
+#if !GlxUseBuiltInDRIDriver
+LIBNAME = i810_dri.so
+ALL_OBJS = $(OBJS)
+ALL_DEPS = DONE
+SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
+InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+#endif
+
+DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/common/hwlog.c b/xc/lib/GL/mesa/src/drv/common/hwlog.c
new file mode 100644
index 000000000..d8d69703a
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/hwlog.c
@@ -0,0 +1,107 @@
+/*
+ * GLX Hardware Device Driver common code
+ *
+ * Based on the original MGA G200 driver (c) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+#include "hwlog.h"
+hwlog_t hwlog = { 0,0,0, "[???] "};
+
+
+/* Should be shared, but is this a good place for it?
+ */
+#include <sys/time.h>
+
+
+int usec( void )
+{
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday( &tv, &tz );
+
+ return (tv.tv_sec & 2047) * 1000000 + tv.tv_usec;
+}
+
+
+#ifdef HW_LOG_ENABLED
+int hwOpenLog(const char *filename, char *prefix)
+{
+ hwCloseLog();
+ hwSetLogLevel(0);
+ hwlog.prefix=prefix;
+ if (!filename)
+ return -1;
+ if ((hwlog.file = fopen(filename,"w")) == NULL)
+ return -1;
+ return 0;
+}
+
+void hwCloseLog()
+{
+ if (hwlog.file) {
+ fclose(hwlog.file);
+ hwlog.file = NULL;
+ }
+}
+
+int hwIsLogReady()
+{
+ return (hwlog.file != NULL);
+}
+
+void hwSetLogLevel(int level)
+{
+ hwlog.level = level;
+}
+
+int hwGetLogLevel()
+{
+ return hwlog.level;
+}
+
+void hwLog(int level, const char *format, ...)
+{
+ va_list ap;
+ va_start(ap,format);
+ hwLogv(level,format,ap);
+ va_end(ap);
+}
+
+void hwLogv(int l, const char *format, va_list ap)
+{
+ if (hwlog.file && (l <= hwlog.level)) {
+ vfprintf(hwlog.file,format,ap);
+ fflush(hwlog.file);
+ }
+}
+
+#else /* ifdef HW_LOG_ENABLED */
+
+int hwlogdummy()
+{
+ return 0;
+}
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/common/hwlog.h b/xc/lib/GL/mesa/src/drv/common/hwlog.h
new file mode 100644
index 000000000..42e378afd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/hwlog.h
@@ -0,0 +1,115 @@
+/*
+ * GLX Hardware Device Driver common code
+ *
+ * Based on the original MGA G200 driver (c) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+/* Usage:
+ * - use mgaError for error messages. Always write to X error and log file.
+ * - use mgaMsg for debugging. Can be disabled by undefining MGA_LOG_ENABLED.
+ */
+
+#ifndef HWLOG_INC
+#define HWLOG_INC
+#include <stdio.h>
+
+#define DBG_LEVEL_BASE 1
+#define DBG_LEVEL_VERBOSE 10
+#define DBG_LEVEL_ENTEREXIT 20
+
+typedef struct
+{
+ FILE *file;
+ int level;
+ unsigned int timeTemp;
+ char *prefix;
+} hwlog_t;
+
+extern hwlog_t hwlog;
+
+
+#ifdef HW_LOG_ENABLED
+#include <stdarg.h>
+
+/* open and close log file. */
+int hwOpenLog(const char *filename, char *prefix);
+void hwCloseLog();
+
+/* return 1 if log file is succesfully opened */
+int hwIsLogReady();
+
+/* set current log level to 'level'. Messages with level less than or equal
+ the current log level will be written to the log file. */
+void hwSetLogLevel(int level);
+int hwGetLogLevel();
+
+/* hwLog and hwLogv write a message to the log file. */
+/* do not call these directly, use hwMsg() instead */
+void hwLog(int level, const char *format, ...);
+void hwLogv(int level, const char *format, va_list ap);
+
+
+int usec( void );
+
+
+/* hwMsg writes a message to the log file or to the standard X error file. */
+#define hwMsg(level_,format, args...) if ( level_ <= hwlog.level ) { \
+ if (hwIsLogReady()) { \
+ int __t=usec();hwLog(level_,"%6i:",__t-hwlog.timeTemp);hwlog.timeTemp=__t; \
+ hwLog(level_,format, ## args); \
+ } else { \
+ if (level_ <= hwGetLogLevel()) { \
+ fprintf(stderr,hwlog.prefix); \
+ fprintf(stderr,format, ## args); \
+ } \
+ } \
+}
+
+#define hwError(format, args...) do { \
+ fprintf(stderr, hwlog.prefix); \
+ fprintf(stderr, format, ## args); \
+ hwLog(0,format, ## args); \
+} while(0)
+
+#else
+
+static __inline__ int hwOpenLog(const char *f, char *prefix) { hwlog.prefix=prefix; return -1; }
+static __inline__ int hwIsLogReady( void ) { return 0; }
+static __inline__ int hwGetLogLevel( void ) { return -1; }
+static __inline__ int hwLogLevel(int level) { return 0; }
+
+#define hwCloseLog()
+#define hwSetLogLevel(x)
+#define hwLog(l,f,a...)
+#define hwLogv(l,f,a)
+#define hwMsg(l,f,a...)
+
+#define hwError(format, args...) do { \
+ fprintf(stderr, hwlog.prefix); \
+ fprintf(stderr, format, ## args); \
+} while(0)
+
+#endif
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/common/mm.c b/xc/lib/GL/mesa/src/drv/common/mm.c
new file mode 100644
index 000000000..c4ff8ae71
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/mm.c
@@ -0,0 +1,262 @@
+/*
+ * GLX Hardware Device Driver common code
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mm.h"
+#include "hwlog.h"
+
+#define ISFREE(bptr) ((bptr)->free)
+/* #define PRINTF(f,a...) hwMsg(1,f, ## a) */
+#define PRINTF(f,a...) fprintf(stderr, f, ## a)
+
+void mmDumpMemInfo( memHeap_t *heap )
+{
+ TMemBlock *p;
+
+ PRINTF("Memory heap %p:\n", heap);
+ if (heap == 0) {
+ PRINTF(" heap == 0\n");
+ } else {
+ p = (TMemBlock *)heap;
+ while (p) {
+ PRINTF(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
+ p->free ? '.':'U',
+ p->reserved ? 'R':'.');
+ p = p->next;
+ }
+ }
+ PRINTF("End of memory blocks\n");
+}
+
+memHeap_t *mmInit(int ofs,
+ int size)
+{
+ PMemBlock blocks;
+
+ if (size <= 0) {
+ return 0;
+ }
+ blocks = (TMemBlock *) calloc(1,sizeof(TMemBlock));
+ if (blocks) {
+ blocks->ofs = ofs;
+ blocks->size = size;
+ blocks->free = 1;
+ return (memHeap_t *)blocks;
+ } else
+ return 0;
+}
+
+/* Kludgey workaround for existing i810 server. Remove soon.
+ */
+memHeap_t *mmAddRange( memHeap_t *heap,
+ int ofs,
+ int size )
+{
+ PMemBlock blocks;
+ blocks = (TMemBlock *) calloc(2,sizeof(TMemBlock));
+ if (blocks) {
+ blocks[0].size = size;
+ blocks[0].free = 1;
+ blocks[0].ofs = ofs;
+ blocks[0].next = &blocks[1];
+
+ /* Discontinuity - stops JoinBlock from trying to join non-adjacent
+ * ranges.
+ */
+ blocks[1].size = 0;
+ blocks[1].free = 0;
+ blocks[1].ofs = ofs+size;
+ blocks[1].next = (PMemBlock) heap;
+ return (memHeap_t *)blocks;
+ }
+ else
+ return heap;
+}
+
+static TMemBlock* SliceBlock(TMemBlock *p,
+ int startofs, int size,
+ int reserved, int alignment)
+{
+ TMemBlock *newblock;
+
+ /* break left */
+ if (startofs > p->ofs) {
+ newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
+ newblock->ofs = startofs;
+ newblock->size = p->size - (startofs - p->ofs);
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size -= newblock->size;
+ p->next = newblock;
+ p = newblock;
+ }
+
+ /* break right */
+ if (size < p->size) {
+ newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
+ newblock->ofs = startofs + size;
+ newblock->size = p->size - size;
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size = size;
+ p->next = newblock;
+ }
+
+ /* p = middle block */
+ p->align = alignment;
+ p->free = 0;
+ p->reserved = reserved;
+ return p;
+}
+
+PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
+{
+ int mask,startofs,endofs;
+ TMemBlock *p;
+
+ if (!heap || align2 < 0 || size <= 0)
+ return NULL;
+ mask = (1 << align2)-1;
+ startofs = 0;
+ p = (TMemBlock *)heap;
+ while (p) {
+ if (ISFREE(p)) {
+ startofs = (p->ofs + mask) & ~mask;
+ if ( startofs < startSearch ) {
+ startofs = startSearch;
+ }
+ endofs = startofs+size;
+ if (endofs <= (p->ofs+p->size))
+ break;
+ }
+ p = p->next;
+ }
+ if (!p)
+ return NULL;
+ p = SliceBlock(p,startofs,size,0,mask+1);
+ p->heap = heap;
+ return p;
+}
+
+static __inline__ int Join2Blocks(TMemBlock *p)
+{
+ if (p->free && p->next && p->next->free) {
+ TMemBlock *q = p->next;
+ p->size += q->size;
+ p->next = q->next;
+ free(q);
+ return 1;
+ }
+ return 0;
+}
+
+int mmFreeMem(PMemBlock b)
+{
+ TMemBlock *p,*prev;
+
+ if (!b)
+ return 0;
+ if (!b->heap) {
+ fprintf(stderr, "no heap\n");
+ return -1;
+ }
+ p = b->heap;
+ prev = NULL;
+ while (p && p != b) {
+ prev = p;
+ p = p->next;
+ }
+ if (!p || p->free || p->reserved) {
+ if (!p)
+ fprintf(stderr, "block not found in heap\n");
+ else if (p->free)
+ fprintf(stderr, "block already free\n");
+ else
+ fprintf(stderr, "block is reserved\n");
+ return -1;
+ }
+ p->free = 1;
+ Join2Blocks(p);
+ if (prev)
+ Join2Blocks(prev);
+ return 0;
+}
+
+int mmReserveMem(memHeap_t *heap, int offset,int size)
+{
+ int endofs;
+ TMemBlock *p;
+
+ if (!heap || size <= 0)
+ return -1;
+ endofs = offset+size;
+ p = (TMemBlock *)heap;
+ while (p && p->ofs <= offset) {
+ if (ISFREE(p) && endofs <= (p->ofs+p->size)) {
+ SliceBlock(p,offset,size,1,1);
+ return 0;
+ }
+ p = p->next;
+ }
+ return -1;
+}
+
+int mmFreeReserved(memHeap_t *heap, int offset)
+{
+ TMemBlock *p,*prev;
+
+ if (!heap)
+ return -1;
+ p = (TMemBlock *)heap;
+ prev = NULL;
+ while (p && p->ofs != offset) {
+ prev = p;
+ p = p->next;
+ }
+ if (!p || !p->reserved)
+ return -1;
+ p->free = 1;
+ p->reserved = 0;
+ Join2Blocks(p);
+ if (prev)
+ Join2Blocks(prev);
+ return 0;
+}
+
+void mmDestroy(memHeap_t *heap)
+{
+ TMemBlock *p,*q;
+
+ if (!heap)
+ return;
+ p = (TMemBlock *)heap;
+ while (p) {
+ q = p->next;
+ free(p);
+ p = q;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/common/mm.h b/xc/lib/GL/mesa/src/drv/common/mm.h
new file mode 100644
index 000000000..6fa6e8b69
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/mm.h
@@ -0,0 +1,101 @@
+/*
+ * GLX Hardware Device Driver common code
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+#ifndef MM_INC
+#define MM_INC
+
+struct mem_block_t {
+ struct mem_block_t *next;
+ struct mem_block_t *heap;
+ int ofs,size;
+ int align;
+ int free:1;
+ int reserved:1;
+};
+typedef struct mem_block_t TMemBlock;
+typedef struct mem_block_t *PMemBlock;
+
+/* a heap is just the first block in a chain */
+typedef struct mem_block_t memHeap_t;
+
+static __inline__ int mmBlockSize(PMemBlock b)
+{ return b->size; }
+
+static __inline__ int mmOffset(PMemBlock b)
+{ return b->ofs; }
+
+static __inline__ void mmMarkReserved(PMemBlock b)
+{ b->reserved = 1; }
+
+/*
+ * input: total size in bytes
+ * return: a heap pointer if OK, NULL if error
+ */
+memHeap_t *mmInit( int ofs, int size );
+
+
+
+memHeap_t *mmAddRange( memHeap_t *heap,
+ int ofs,
+ int size );
+
+
+/*
+ * Allocate 'size' bytes with 2^align2 bytes alignment,
+ * restrict the search to free memory after 'startSearch'
+ * depth and back buffers should be in different 4mb banks
+ * to get better page hits if possible
+ * input: size = size of block
+ * align2 = 2^align2 bytes alignment
+ * startSearch = linear offset from start of heap to begin search
+ * return: pointer to the allocated block, 0 if error
+ */
+PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch );
+
+/*
+ * Free block starts at offset
+ * input: pointer to a block
+ * return: 0 if OK, -1 if error
+ */
+int mmFreeMem( PMemBlock b );
+
+/*
+ * Reserve 'size' bytes block start at offset
+ * This is used to prevent allocation of memory already used
+ * by the X server for the front buffer, pixmaps, and cursor
+ * input: size, offset
+ * output: 0 if OK, -1 if error
+ */
+int mmReserveMem( memHeap_t *heap, int offset,int size );
+int mmFreeReserved( memHeap_t *heap, int offset );
+
+/*
+ * destroy MM
+ */
+void mmDestroy( memHeap_t *mmInit );
+
+/* For debuging purpose. */
+void mmDumpMemInfo( memHeap_t *mmInit );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/common/mmx.h b/xc/lib/GL/mesa/src/drv/common/mmx.h
new file mode 100644
index 000000000..49ce7e3e3
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/mmx.h
@@ -0,0 +1,560 @@
+/* mmx.h
+
+ MultiMedia eXtensions GCC interface library for IA32.
+
+ To use this library, simply include this header file
+ and compile with GCC. You MUST have inlining enabled
+ in order for mmx_ok() to work; this can be done by
+ simply using -O on the GCC command line.
+
+ Compiling with -DMMX_TRACE will cause detailed trace
+ output to be sent to stderr for each mmx operation.
+ This adds lots of code, and obviously slows execution to
+ a crawl, but can be very useful for debugging.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ 1997-98 by H. Dietz and R. Fisher
+
+ History:
+ 97-98* R.Fisher Early versions
+ 980501 R.Fisher Original Release
+ 980611* H.Dietz Rewrite, correctly implementing inlines, and
+ R.Fisher including direct register accesses.
+ 980616 R.Fisher Release of 980611 as 980616.
+ 980714 R.Fisher Minor corrections to Makefile, etc.
+ 980715 R.Fisher mmx_ok() now prevents optimizer from using
+ clobbered values.
+ mmx_ok() now checks if cpuid instruction is
+ available before trying to use it.
+ 980726* R.Fisher mm_support() searches for AMD 3DNow, Cyrix
+ Extended MMX, and standard MMX. It returns a
+ value which is positive if any of these are
+ supported, and can be masked with constants to
+ see which. mmx_ok() is now a call to this
+ 980726* R.Fisher Added i2r support for shift functions
+ 980919 R.Fisher Fixed AMD extended feature recognition bug.
+ 980921 R.Fisher Added definition/check for _MMX_H.
+ Added "float s[2]" to mmx_t for use with
+ 3DNow and EMMX. So same mmx_t can be used.
+ 981013 R.Fisher Fixed cpuid function 1 bug (looked at wrong reg)
+ Fixed psllq_i2r error in mmxtest.c
+
+ * Unreleased (internal or interim) versions
+
+ Notes:
+ It appears that the latest gas has the pand problem fixed, therefore
+ I'll undefine BROKEN_PAND by default.
+ String compares may be quicker than the multiple test/jumps in vendor
+ test sequence in mmx_ok(), but I'm not concerned with that right now.
+
+ Acknowledgments:
+ Jussi Laako for pointing out the errors ultimately found to be
+ connected to the failure to notify the optimizer of clobbered values.
+ Roger Hardiman for reminding us that CPUID isn't everywhere, and that
+ someone may actually try to use this on a machine without CPUID.
+ Also for suggesting code for checking this.
+ Robert Dale for pointing out the AMD recognition bug.
+ Jimmy Mayfield and Carl Witty for pointing out the Intel recognition
+ bug.
+ Carl Witty for pointing out the psllq_i2r test bug.
+*/
+
+#ifndef _MMX_H
+#define _MMX_H
+
+//#define MMX_TRACE
+
+/* Warning: at this writing, the version of GAS packaged
+ with most Linux distributions does not handle the
+ parallel AND operation mnemonic correctly. If the
+ symbol BROKEN_PAND is defined, a slower alternative
+ coding will be used. If execution of mmxtest results
+ in an illegal instruction fault, define this symbol.
+*/
+#undef BROKEN_PAND
+
+
+/* The type of an value that fits in an MMX register
+ (note that long long constant values MUST be suffixed
+ by LL and unsigned long long values by ULL, lest
+ they be truncated by the compiler)
+*/
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} mmx_t;
+
+/* Helper functions for the instruction macros that follow...
+ (note that memory-to-register, m2r, instructions are nearly
+ as efficient as register-to-register, r2r, instructions;
+ however, memory-to-memory instructions are really simulated
+ as a convenience, and are only 1/3 as efficient)
+*/
+#ifdef MMX_TRACE
+
+/* Include the stuff for printing a trace to stderr...
+*/
+
+#include <stdio.h>
+
+#define mmx_i2r(op, imm, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (imm); \
+ fprintf(stderr, #op "_i2r(" #imm "=0x%016llx, ", mmx_trace.q); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%016llx) => ", mmx_trace.q); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%016llx\n", mmx_trace.q); \
+ }
+
+#define mmx_m2r(op, mem, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mem); \
+ fprintf(stderr, #op "_m2r(" #mem "=0x%016llx, ", mmx_trace.q); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%016llx) => ", mmx_trace.q); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%016llx\n", mmx_trace.q); \
+ }
+
+#define mmx_r2m(op, reg, mem) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #op "_r2m(" #reg "=0x%016llx, ", mmx_trace.q); \
+ mmx_trace = (mem); \
+ fprintf(stderr, #mem "=0x%016llx) => ", mmx_trace.q); \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ ); \
+ mmx_trace = (mem); \
+ fprintf(stderr, #mem "=0x%016llx\n", mmx_trace.q); \
+ }
+
+#define mmx_r2r(op, regs, regd) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #regs ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #op "_r2r(" #regs "=0x%016llx, ", mmx_trace.q); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #regd "=0x%016llx) => ", mmx_trace.q); \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #regd "=0x%016llx\n", mmx_trace.q); \
+ }
+
+#define mmx_m2m(op, mems, memd) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mems); \
+ fprintf(stderr, #op "_m2m(" #mems "=0x%016llx, ", mmx_trace.q); \
+ mmx_trace = (memd); \
+ fprintf(stderr, #memd "=0x%016llx) => ", mmx_trace.q); \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (memd) \
+ : "X" (mems)); \
+ mmx_trace = (memd); \
+ fprintf(stderr, #memd "=0x%016llx\n", mmx_trace.q); \
+ }
+
+#else
+
+/* These macros are a lot simpler without the tracing...
+*/
+
+#define mmx_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " $" #imm ", %%" #reg \
+ : /* nothing */ \
+ : /* nothing */);
+
+#define mmx_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define mmx_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define mmx_m2m(op, mems, memd) \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (memd) \
+ : "X" (mems))
+
+#endif
+
+
+/* 1x64 MOVe Quadword
+ (this is both a load and a store...
+ in fact, it is the only way to store)
+*/
+#define movq_m2r(var, reg) mmx_m2r(movq, var, reg)
+#define movq_r2m(reg, var) mmx_r2m(movq, reg, var)
+#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd)
+#define movq(vars, vard) \
+ __asm__ __volatile__ ("movq %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+/* 1x32 MOVe Doubleword
+ (like movq, this is both load and store...
+ but is most useful for moving things between
+ mmx registers and ordinary registers)
+*/
+#define movd_m2r(var, reg) mmx_m2r(movd, var, reg)
+#define movd_r2m(reg, var) mmx_r2m(movd, reg, var)
+#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd)
+#define movd(vars, vard) \
+ __asm__ __volatile__ ("movd %1, %%mm0\n\t" \
+ "movd %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+/* 2x32, 4x16, and 8x8 Parallel ADDs
+*/
+#define paddd_m2r(var, reg) mmx_m2r(paddd, var, reg)
+#define paddd_r2r(regs, regd) mmx_r2r(paddd, regs, regd)
+#define paddd(vars, vard) mmx_m2m(paddd, vars, vard)
+
+#define paddw_m2r(var, reg) mmx_m2r(paddw, var, reg)
+#define paddw_r2r(regs, regd) mmx_r2r(paddw, regs, regd)
+#define paddw(vars, vard) mmx_m2m(paddw, vars, vard)
+
+#define paddb_m2r(var, reg) mmx_m2r(paddb, var, reg)
+#define paddb_r2r(regs, regd) mmx_r2r(paddb, regs, regd)
+#define paddb(vars, vard) mmx_m2m(paddb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel ADDs using Saturation arithmetic
+*/
+#define paddsw_m2r(var, reg) mmx_m2r(paddsw, var, reg)
+#define paddsw_r2r(regs, regd) mmx_r2r(paddsw, regs, regd)
+#define paddsw(vars, vard) mmx_m2m(paddsw, vars, vard)
+
+#define paddsb_m2r(var, reg) mmx_m2r(paddsb, var, reg)
+#define paddsb_r2r(regs, regd) mmx_r2r(paddsb, regs, regd)
+#define paddsb(vars, vard) mmx_m2m(paddsb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel ADDs using Unsigned Saturation arithmetic
+*/
+#define paddusw_m2r(var, reg) mmx_m2r(paddusw, var, reg)
+#define paddusw_r2r(regs, regd) mmx_r2r(paddusw, regs, regd)
+#define paddusw(vars, vard) mmx_m2m(paddusw, vars, vard)
+
+#define paddusb_m2r(var, reg) mmx_m2r(paddusb, var, reg)
+#define paddusb_r2r(regs, regd) mmx_r2r(paddusb, regs, regd)
+#define paddusb(vars, vard) mmx_m2m(paddusb, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel SUBs
+*/
+#define psubd_m2r(var, reg) mmx_m2r(psubd, var, reg)
+#define psubd_r2r(regs, regd) mmx_r2r(psubd, regs, regd)
+#define psubd(vars, vard) mmx_m2m(psubd, vars, vard)
+
+#define psubw_m2r(var, reg) mmx_m2r(psubw, var, reg)
+#define psubw_r2r(regs, regd) mmx_r2r(psubw, regs, regd)
+#define psubw(vars, vard) mmx_m2m(psubw, vars, vard)
+
+#define psubb_m2r(var, reg) mmx_m2r(psubb, var, reg)
+#define psubb_r2r(regs, regd) mmx_r2r(psubb, regs, regd)
+#define psubb(vars, vard) mmx_m2m(psubb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel SUBs using Saturation arithmetic
+*/
+#define psubsw_m2r(var, reg) mmx_m2r(psubsw, var, reg)
+#define psubsw_r2r(regs, regd) mmx_r2r(psubsw, regs, regd)
+#define psubsw(vars, vard) mmx_m2m(psubsw, vars, vard)
+
+#define psubsb_m2r(var, reg) mmx_m2r(psubsb, var, reg)
+#define psubsb_r2r(regs, regd) mmx_r2r(psubsb, regs, regd)
+#define psubsb(vars, vard) mmx_m2m(psubsb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel SUBs using Unsigned Saturation arithmetic
+*/
+#define psubusw_m2r(var, reg) mmx_m2r(psubusw, var, reg)
+#define psubusw_r2r(regs, regd) mmx_r2r(psubusw, regs, regd)
+#define psubusw(vars, vard) mmx_m2m(psubusw, vars, vard)
+
+#define psubusb_m2r(var, reg) mmx_m2r(psubusb, var, reg)
+#define psubusb_r2r(regs, regd) mmx_r2r(psubusb, regs, regd)
+#define psubusb(vars, vard) mmx_m2m(psubusb, vars, vard)
+
+
+/* 4x16 Parallel MULs giving Low 4x16 portions of results
+*/
+#define pmullw_m2r(var, reg) mmx_m2r(pmullw, var, reg)
+#define pmullw_r2r(regs, regd) mmx_r2r(pmullw, regs, regd)
+#define pmullw(vars, vard) mmx_m2m(pmullw, vars, vard)
+
+
+/* 4x16 Parallel MULs giving High 4x16 portions of results
+*/
+#define pmulhw_m2r(var, reg) mmx_m2r(pmulhw, var, reg)
+#define pmulhw_r2r(regs, regd) mmx_r2r(pmulhw, regs, regd)
+#define pmulhw(vars, vard) mmx_m2m(pmulhw, vars, vard)
+
+
+/* 4x16->2x32 Parallel Mul-ADD
+ (muls like pmullw, then adds adjacent 16-bit fields
+ in the multiply result to make the final 2x32 result)
+*/
+#define pmaddwd_m2r(var, reg) mmx_m2r(pmaddwd, var, reg)
+#define pmaddwd_r2r(regs, regd) mmx_r2r(pmaddwd, regs, regd)
+#define pmaddwd(vars, vard) mmx_m2m(pmaddwd, vars, vard)
+
+
+/* 1x64 bitwise AND
+*/
+#ifdef BROKEN_PAND
+#define pand_m2r(var, reg) \
+ { \
+ mmx_m2r(pandn, (mmx_t) -1LL, reg); \
+ mmx_m2r(pandn, var, reg); \
+ }
+#define pand_r2r(regs, regd) \
+ { \
+ mmx_m2r(pandn, (mmx_t) -1LL, regd); \
+ mmx_r2r(pandn, regs, regd) \
+ }
+#define pand(vars, vard) \
+ { \
+ movq_m2r(vard, mm0); \
+ mmx_m2r(pandn, (mmx_t) -1LL, mm0); \
+ mmx_m2r(pandn, vars, mm0); \
+ movq_r2m(mm0, vard); \
+ }
+#else
+#define pand_m2r(var, reg) mmx_m2r(pand, var, reg)
+#define pand_r2r(regs, regd) mmx_r2r(pand, regs, regd)
+#define pand(vars, vard) mmx_m2m(pand, vars, vard)
+#endif
+
+
+/* 1x64 bitwise AND with Not the destination
+*/
+#define pandn_m2r(var, reg) mmx_m2r(pandn, var, reg)
+#define pandn_r2r(regs, regd) mmx_r2r(pandn, regs, regd)
+#define pandn(vars, vard) mmx_m2m(pandn, vars, vard)
+
+
+/* 1x64 bitwise OR
+*/
+#define por_m2r(var, reg) mmx_m2r(por, var, reg)
+#define por_r2r(regs, regd) mmx_r2r(por, regs, regd)
+#define por(vars, vard) mmx_m2m(por, vars, vard)
+
+
+/* 1x64 bitwise eXclusive OR
+*/
+#define pxor_m2r(var, reg) mmx_m2r(pxor, var, reg)
+#define pxor_r2r(regs, regd) mmx_r2r(pxor, regs, regd)
+#define pxor(vars, vard) mmx_m2m(pxor, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel CoMPare for EQuality
+ (resulting fields are either 0 or -1)
+*/
+#define pcmpeqd_m2r(var, reg) mmx_m2r(pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs, regd) mmx_r2r(pcmpeqd, regs, regd)
+#define pcmpeqd(vars, vard) mmx_m2m(pcmpeqd, vars, vard)
+
+#define pcmpeqw_m2r(var, reg) mmx_m2r(pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs, regd) mmx_r2r(pcmpeqw, regs, regd)
+#define pcmpeqw(vars, vard) mmx_m2m(pcmpeqw, vars, vard)
+
+#define pcmpeqb_m2r(var, reg) mmx_m2r(pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs, regd) mmx_r2r(pcmpeqb, regs, regd)
+#define pcmpeqb(vars, vard) mmx_m2m(pcmpeqb, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel CoMPare for Greater Than
+ (resulting fields are either 0 or -1)
+*/
+#define pcmpgtd_m2r(var, reg) mmx_m2r(pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs, regd) mmx_r2r(pcmpgtd, regs, regd)
+#define pcmpgtd(vars, vard) mmx_m2m(pcmpgtd, vars, vard)
+
+#define pcmpgtw_m2r(var, reg) mmx_m2r(pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs, regd) mmx_r2r(pcmpgtw, regs, regd)
+#define pcmpgtw(vars, vard) mmx_m2m(pcmpgtw, vars, vard)
+
+#define pcmpgtb_m2r(var, reg) mmx_m2r(pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs, regd) mmx_r2r(pcmpgtb, regs, regd)
+#define pcmpgtb(vars, vard) mmx_m2m(pcmpgtb, vars, vard)
+
+
+/* 1x64, 2x32, and 4x16 Parallel Shift Left Logical
+*/
+#define psllq_i2r(imm, reg) mmx_i2r(psllq, imm, reg)
+#define psllq_m2r(var, reg) mmx_m2r(psllq, var, reg)
+#define psllq_r2r(regs, regd) mmx_r2r(psllq, regs, regd)
+#define psllq(vars, vard) mmx_m2m(psllq, vars, vard)
+
+#define pslld_i2r(imm, reg) mmx_i2r(pslld, imm, reg)
+#define pslld_m2r(var, reg) mmx_m2r(pslld, var, reg)
+#define pslld_r2r(regs, regd) mmx_r2r(pslld, regs, regd)
+#define pslld(vars, vard) mmx_m2m(pslld, vars, vard)
+
+#define psllw_i2r(imm, reg) mmx_i2r(psllw, imm, reg)
+#define psllw_m2r(var, reg) mmx_m2r(psllw, var, reg)
+#define psllw_r2r(regs, regd) mmx_r2r(psllw, regs, regd)
+#define psllw(vars, vard) mmx_m2m(psllw, vars, vard)
+
+
+/* 1x64, 2x32, and 4x16 Parallel Shift Right Logical
+*/
+#define psrlq_i2r(imm, reg) mmx_i2r(psrlq, imm, reg)
+#define psrlq_m2r(var, reg) mmx_m2r(psrlq, var, reg)
+#define psrlq_r2r(regs, regd) mmx_r2r(psrlq, regs, regd)
+#define psrlq(vars, vard) mmx_m2m(psrlq, vars, vard)
+
+#define psrld_i2r(imm, reg) mmx_i2r(psrld, imm, reg)
+#define psrld_m2r(var, reg) mmx_m2r(psrld, var, reg)
+#define psrld_r2r(regs, regd) mmx_r2r(psrld, regs, regd)
+#define psrld(vars, vard) mmx_m2m(psrld, vars, vard)
+
+#define psrlw_i2r(imm, reg) mmx_i2r(psrlw, imm, reg)
+#define psrlw_m2r(var, reg) mmx_m2r(psrlw, var, reg)
+#define psrlw_r2r(regs, regd) mmx_r2r(psrlw, regs, regd)
+#define psrlw(vars, vard) mmx_m2m(psrlw, vars, vard)
+
+
+/* 2x32 and 4x16 Parallel Shift Right Arithmetic
+*/
+#define psrad_i2r(imm, reg) mmx_i2r(psrad, imm, reg)
+#define psrad_m2r(var, reg) mmx_m2r(psrad, var, reg)
+#define psrad_r2r(regs, regd) mmx_r2r(psrad, regs, regd)
+#define psrad(vars, vard) mmx_m2m(psrad, vars, vard)
+
+#define psraw_i2r(imm, reg) mmx_i2r(psraw, imm, reg)
+#define psraw_m2r(var, reg) mmx_m2r(psraw, var, reg)
+#define psraw_r2r(regs, regd) mmx_r2r(psraw, regs, regd)
+#define psraw(vars, vard) mmx_m2m(psraw, vars, vard)
+
+
+/* 2x32->4x16 and 4x16->8x8 PACK and Signed Saturate
+ (packs source and dest fields into dest in that order)
+*/
+#define packssdw_m2r(var, reg) mmx_m2r(packssdw, var, reg)
+#define packssdw_r2r(regs, regd) mmx_r2r(packssdw, regs, regd)
+#define packssdw(vars, vard) mmx_m2m(packssdw, vars, vard)
+
+#define packsswb_m2r(var, reg) mmx_m2r(packsswb, var, reg)
+#define packsswb_r2r(regs, regd) mmx_r2r(packsswb, regs, regd)
+#define packsswb(vars, vard) mmx_m2m(packsswb, vars, vard)
+
+
+/* 4x16->8x8 PACK and Unsigned Saturate
+ (packs source and dest fields into dest in that order)
+*/
+#define packuswb_m2r(var, reg) mmx_m2r(packuswb, var, reg)
+#define packuswb_r2r(regs, regd) mmx_r2r(packuswb, regs, regd)
+#define packuswb(vars, vard) mmx_m2m(packuswb, vars, vard)
+
+
+/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK Low
+ (interleaves low half of dest with low half of source
+ as padding in each result field)
+*/
+#define punpckldq_m2r(var, reg) mmx_m2r(punpckldq, var, reg)
+#define punpckldq_r2r(regs, regd) mmx_r2r(punpckldq, regs, regd)
+#define punpckldq(vars, vard) mmx_m2m(punpckldq, vars, vard)
+
+#define punpcklwd_m2r(var, reg) mmx_m2r(punpcklwd, var, reg)
+#define punpcklwd_r2r(regs, regd) mmx_r2r(punpcklwd, regs, regd)
+#define punpcklwd(vars, vard) mmx_m2m(punpcklwd, vars, vard)
+
+#define punpcklbw_m2r(var, reg) mmx_m2r(punpcklbw, var, reg)
+#define punpcklbw_r2r(regs, regd) mmx_r2r(punpcklbw, regs, regd)
+#define punpcklbw(vars, vard) mmx_m2m(punpcklbw, vars, vard)
+
+
+/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK High
+ (interleaves high half of dest with high half of source
+ as padding in each result field)
+*/
+#define punpckhdq_m2r(var, reg) mmx_m2r(punpckhdq, var, reg)
+#define punpckhdq_r2r(regs, regd) mmx_r2r(punpckhdq, regs, regd)
+#define punpckhdq(vars, vard) mmx_m2m(punpckhdq, vars, vard)
+
+#define punpckhwd_m2r(var, reg) mmx_m2r(punpckhwd, var, reg)
+#define punpckhwd_r2r(regs, regd) mmx_r2r(punpckhwd, regs, regd)
+#define punpckhwd(vars, vard) mmx_m2m(punpckhwd, vars, vard)
+
+#define punpckhbw_m2r(var, reg) mmx_m2r(punpckhbw, var, reg)
+#define punpckhbw_r2r(regs, regd) mmx_r2r(punpckhbw, regs, regd)
+#define punpckhbw(vars, vard) mmx_m2m(punpckhbw, vars, vard)
+
+
+/* Empty MMx State
+ (used to clean-up when going from mmx to float use
+ of the registers that are shared by both; note that
+ there is no float-to-mmx operation needed, because
+ only the float tag word info is corruptible)
+*/
+#ifdef MMX_TRACE
+
+#define emms() \
+ { \
+ fprintf(stderr, "emms()\n"); \
+ __asm__ __volatile__ ("emms"); \
+ }
+
+#else
+
+#define emms() __asm__ __volatile__ ("emms")
+
+#endif
+
+#endif
+
diff --git a/xc/lib/GL/mesa/src/drv/common/spantmp.h b/xc/lib/GL/mesa/src/drv/common/spantmp.h
new file mode 100644
index 000000000..e10dca1a2
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/spantmp.h
@@ -0,0 +1,199 @@
+
+static void TAG(WriteRGBASpan)( const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ const GLubyte rgba[][4],
+ const GLubyte mask[] )
+{
+ GLuint x1,n1;
+ LOCAL_VARS;
+
+ y = Y_FLIP(y);
+
+ if (DBG) fprintf(stderr, "WriteRGBASpan\n");
+
+ HW_CLIPLOOP()
+ {
+ GLuint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+ if (mask)
+ {
+ for (i=0;i<n1;i++,x1++)
+ if (mask[i])
+ WRITE_RGBA( x1, y,
+ rgba[i][0], rgba[i][1],
+ rgba[i][2], rgba[i][3] );
+ }
+ else
+ {
+ for (i=0;i<n1;i++,x1++)
+ WRITE_RGBA( x1, y,
+ rgba[i][0], rgba[i][1],
+ rgba[i][2], rgba[i][3] );
+ }
+ }
+ HW_ENDCLIPLOOP();
+}
+
+static void TAG(WriteRGBSpan)( const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ const GLubyte rgb[][3],
+ const GLubyte mask[] )
+{
+ GLuint x1,n1;
+ LOCAL_VARS;
+
+ y = Y_FLIP(y);
+
+
+ if (DBG) fprintf(stderr, "WriteRGBSpan\n");
+
+ HW_CLIPLOOP()
+ {
+ GLuint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+
+ if (mask)
+ {
+ for (;i<n1;i++,x1++)
+ if (mask[i])
+ WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 );
+ }
+ else
+ {
+ for (;i<n1;i++,x1++)
+ WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 );
+ }
+ }
+ HW_ENDCLIPLOOP();
+}
+
+static void TAG(WriteRGBAPixels)( const GLcontext *ctx,
+ GLuint n,
+ const GLint x[],
+ const GLint y[],
+ const GLubyte rgba[][4],
+ const GLubyte mask[] )
+{
+ GLuint i;
+ LOCAL_VARS;
+
+ if (DBG) fprintf(stderr, "WriteRGBAPixels\n");
+
+ HW_CLIPLOOP()
+ {
+ for (i=0;i<n;i++)
+ {
+ if (mask[i]) {
+ const int fy = Y_FLIP(y[i]);
+ if (CLIPPIXEL(x[i],fy))
+ WRITE_RGBA( x[i], fy,
+ rgba[i][0], rgba[i][1],
+ rgba[i][2], rgba[i][3] );
+ }
+ }
+ }
+ HW_ENDCLIPLOOP();
+}
+
+
+static void TAG(WriteMonoRGBASpan)( const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ const GLubyte mask[] )
+{
+ GLuint x1,n1;
+ LOCAL_VARS;
+ INIT_MONO_PIXEL(p);
+
+ y = Y_FLIP( y );
+
+ if (DBG) fprintf(stderr, "WriteMonoRGBASpan\n");
+
+ HW_CLIPLOOP()
+ {
+ GLuint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+ for (;i<n1;i++,x1++)
+ if (mask[i])
+ WRITE_PIXEL( x1, y, p );
+ }
+ HW_ENDCLIPLOOP();
+}
+
+
+static void TAG(WriteMonoRGBAPixels)( const GLcontext *ctx,
+ GLuint n,
+ const GLint x[], const GLint y[],
+ const GLubyte mask[] )
+{
+ GLuint i;
+ LOCAL_VARS;
+ INIT_MONO_PIXEL(p);
+
+ if (DBG) fprintf(stderr, "WriteMonoRGBAPixels\n");
+
+ HW_CLIPLOOP()
+ {
+ for (i=0;i<n;i++)
+ if (mask[i]) {
+ int fy = Y_FLIP(y[i]);
+ if (CLIPPIXEL( x[i], fy ))
+ WRITE_PIXEL( x[i], fy, p );
+ }
+ }
+ HW_ENDCLIPLOOP();
+}
+
+
+
+/*
+ * Read a horizontal span of color pixels.
+ */
+static void TAG(ReadRGBASpan)( const GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ GLubyte rgba[][4])
+{
+ GLuint x1,n1;
+ LOCAL_VARS;
+
+ y = Y_FLIP(y);
+
+ if (DBG) fprintf(stderr, "ReadRGBASpan\n");
+
+ HW_CLIPLOOP()
+ {
+ GLuint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+ for (;i<n1;i++)
+ READ_RGBA( rgba[i], x1+i, y );
+ }
+ HW_ENDCLIPLOOP();
+}
+
+static void TAG(ReadRGBAPixels)( const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ GLubyte rgba[][4], const GLubyte mask[] )
+{
+ GLuint i;
+ LOCAL_VARS;
+
+ if (DBG) fprintf(stderr, "ReadRGBAPixels\n");
+
+ HW_CLIPLOOP()
+ {
+ for (i=0;i<n;i++)
+ if (mask[i]) {
+ int fy = Y_FLIP( y[i] );
+ if (CLIPPIXEL( x[i], fy ))
+ READ_RGBA( rgba[i], x[i], fy );
+ }
+ }
+ HW_ENDCLIPLOOP();
+}
+
+
+
+
+#undef WRITE_PIXEL
+#undef WRITE_RGBA
+#undef READ_RGBA
+#undef TAG
diff --git a/xc/lib/GL/mesa/src/drv/gamma/Imakefile b/xc/lib/GL/mesa/src/drv/gamma/Imakefile
index 68313f826..98caebf5d 100644
--- a/xc/lib/GL/mesa/src/drv/gamma/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/gamma/Imakefile
@@ -1,4 +1,4 @@
-XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.4 1999/12/14 01:33:38 robin Exp $
+XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.6 2000/02/15 07:13:30 martin Exp $
XCOMM $PI: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.6 1999/06/21 05:13:55 martin Exp $
#define DoNormalLib NormalLibGlx
@@ -14,6 +14,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
#if BuildXF86DRI
DRI_DEFINES = GlxDefines
DRI_INCLUDES = -I../../../../dri -I../../../../glx \
+ -I../../../dri \
-I$(TOP)/include -I$(TOP)/include/GL \
-I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
-I$(XF86DRIVERSRC)/glint \
@@ -24,11 +25,33 @@ MESA_INCLUDES = -I. -I.. -I../../include
DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
- SRCS = gamma_gl.c gamma_xmesa.c gamma_init.c gamma_matrix.c \
+
+ DRISRCS = ../../../dri/dri_mesa.c \
+ ../../../../dri/dri_tmm.c
+
+ DRIOBJS = ../../../dri/dri_mesa.o \
+ ../../../../dri/dri_tmm.o
+
+ DRMSRCS = ../../../../dri/drm/xf86drm.c \
+ ../../../../dri/drm/xf86drmHash.c \
+ ../../../../dri/drm/xf86drmRandom.c \
+ ../../../../dri/drm/xf86drmSL.c
+
+ DRMOBJS = ../../../../dri/drm/xf86drm.o \
+ ../../../../dri/drm/xf86drmHash.o \
+ ../../../../dri/drm/xf86drmRandom.o \
+ ../../../../dri/drm/xf86drmSL.o
+
+ GAMMASRCS = gamma_gl.c gamma_xmesa.c gamma_init.c gamma_matrix.c \
gamma_inithw.c gamma_texture.c
- OBJS = gamma_gl.o gamma_xmesa.o gamma_init.o gamma_matrix.o \
+
+ GAMMAOBJS = gamma_gl.o gamma_xmesa.o gamma_init.o gamma_matrix.o \
gamma_inithw.o gamma_texture.o
+ SRCS = $(DRISRCS) $(DRMSRCS) $(GAMMASRCS)
+ OBJS = $(DRIOBJS) $(DRMOBJS) $(GAMMAOBJS)
+
+
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
#undef DoExtraLib SharedLibGlx
@@ -48,7 +71,7 @@ LIBNAME = gamma_dri.so
ALL_OBJS = $(OBJS)
ALL_DEPS = DONE
SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
-InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.)
#endif
DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/i810/Imakefile b/xc/lib/GL/mesa/src/drv/i810/Imakefile
new file mode 100644
index 000000000..4212adbd6
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/Imakefile
@@ -0,0 +1,64 @@
+XCOMM $PI:$
+
+#define DoNormalLib NormalLibGlx
+#define DoSharedLib SharedLibGlx
+#define DoExtraLib SharedLibGlx
+#define DoDebugLib DebugLibGlx
+#define DoProfileLib ProfileLibGlx
+
+#if Malloc0ReturnsNull
+ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
+#endif
+
+#if BuildXF86DRI
+ DRI_DEFINES = GlxDefines -DDRIVERTS
+ DRI_INCLUDES = -I../../../../dri -I../../../../glx \
+ -I$(TOP)/include -I$(TOP)/include/GL \
+ -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
+ -I$(XF86DRIVERSRC)/i810 \
+ -I../../../include -I../.. -I../common -I../../X
+#endif
+
+MESA_INCLUDES = -I. -I.. -I../../include
+
+
+
+ DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
+ -I/usr/include/glide
+ DRISRCS = i810_xmesa.c i810clear.c \
+ i810dd.c i810depth.c i810dma.c i810ring.c \
+ i810pipeline.c i810span.c i810state.c i810swap.c \
+ i810tex.c i810tris.c i810vb.c i810fastpath.c
+
+ DRIOBJS = i810_xmesa.o i810clear.o \
+ i810dd.o i810depth.o i810dma.o i810ring.o \
+ i810pipeline.o i810span.o i810state.o i810swap.o \
+ i810tex.o i810tris.o i810vb.o i810fastpath.o
+
+ SRCS = $(DRISRCS)
+ OBJS = $(DRIOBJS)
+
+#if !GlxUseBuiltInDRIDriver
+#undef DoNormalLib NormalLibGlx
+#undef DoExtraLib SharedLibGlx
+#undef DoDebugLib DebugLibGlx
+#undef DoProfileLib ProfileLibGlx
+#endif
+
+#include <Library.tmpl>
+
+LibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+NormalLintTarget($(SRCS))
+
+#if !GlxUseBuiltInDRIDriver
+LIBNAME = i810_dri.so
+ALL_OBJS = $(OBJS)
+ALL_DEPS = DONE
+SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
+InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+#endif
+
+DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
new file mode 100644
index 000000000..8e6942497
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
@@ -0,0 +1,724 @@
+
+
+#ifndef I810_3D_REG_H
+#define I810_3D_REG_H
+
+#include "i810_reg.h"
+
+/* Registers not used in the X server
+ */
+
+#define I810_NOP_ID 0x2094
+#define I810_NOP_ID_MASK ((1<<22)-1)
+
+
+/* 3D instructions
+ */
+
+
+/* GFXRENDERSTATE_PV_PIXELIZATION_RULE, p149
+ *
+ * Format:
+ * 0: GFX_OP_PV_RULE | PV_*
+ *
+ */
+#define GFX_OP_PV_RULE ((0x3<<29)|(0x7<<24))
+#define PV_SMALL_TRI_FILTER_ENABLE (0x1<<11)
+#define PV_UPDATE_PIXRULE (0x1<<10)
+#define PV_PIXRULE_ENABLE (0x1<<9)
+#define PV_UPDATE_LINELIST (0x1<<8)
+#define PV_LINELIST_MASK (0x3<<6)
+#define PV_LINELIST_PV0 (0x0<<6)
+#define PV_LINELIST_PV1 (0x1<<6)
+#define PV_UPDATE_TRIFAN (0x1<<5)
+#define PV_TRIFAN_MASK (0x3<<3)
+#define PV_TRIFAN_PV0 (0x0<<3)
+#define PV_TRIFAN_PV1 (0x1<<3)
+#define PV_TRIFAN_PV2 (0x2<<3)
+#define PV_UPDATE_TRISTRIP (0x1<<2)
+#define PV_TRISTRIP_MASK (0x3<<0)
+#define PV_TRISTRIP_PV0 (0x0<<0)
+#define PV_TRISTRIP_PV1 (0x1<<0)
+#define PV_TRISTRIP_PV2 (0x2<<0)
+
+
+/* GFXRENDERSTATE_SCISSOR_ENABLE, p146
+ *
+ * Format:
+ * 0: GFX_OP_SCISSOR | SC_*
+ */
+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define SC_UPDATE_SCISSOR (0x1<<1)
+#define SC_ENABLE_MASK (0x1<<0)
+#define SC_ENABLE (0x1<<0)
+
+/* GFXRENDERSTATE_SCISSOR_INFO, p147
+ *
+ * Format:
+ * 0: GFX_OP_SCISSOR_INFO
+ * 1: SCI_MIN_*
+ * 2: SCI_MAX_*
+ */
+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
+#define SCI_YMIN_MASK (0xffff<<16)
+#define SCI_XMIN_MASK (0xffff<<0)
+#define SCI_YMAX_MASK (0xffff<<16)
+#define SCI_XMAX_MASK (0xffff<<0)
+
+/* GFXRENDERSTATE_DRAWING_RECT_INFO, p144
+ *
+ * Format:
+ * 0: GFX_OP_DRAWRECT_INFO
+ * 1: DR1_*
+ * 2: DR2_*
+ * 3: DR3_*
+ * 4: DR4_*
+ */
+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define DR1_RECT_CLIP_ENABLE (0x0<<31)
+#define DR1_RECT_CLIP_DISABLE (0x1<<31)
+#define DR1_X_DITHER_BIAS_MASK (0x3<<26)
+#define DR1_X_DITHER_BIAS_SHIFT 26
+#define DR1_Y_DITHER_BIAS_MASK (0x3<<24)
+#define DR1_Y_DITHER_BIAS_SHIFT 24
+#define DR2_YMIN_MASK (0xffff<<16)
+#define DR2_XMIN_MASK (0xffff<<0)
+#define DR3_YMAX_MASK (0xffff<<16)
+#define DR3_XMAX_MASK (0xffff<<0)
+#define DR4_YORG_MASK (0x3ff<<16)
+#define DR4_XORG_MASK (0x7ff<<0)
+
+
+/* GFXRENDERSTATE_LINEWIDTH_CULL_SHADE_MODE, p140
+ *
+ * Format:
+ * 0: GFX_OP_LINEWIDTH_CULL_SHADE_MODE | LCS_*
+ */
+#define GFX_OP_LINEWIDTH_CULL_SHADE_MODE ((0x3<<29)|(0x2<<24))
+#define LCS_UPDATE_ZMODE (0x1<<20)
+#define LCS_Z_MASK (0xf<<16)
+#define LCS_Z_NEVER (0x1<<16)
+#define LCS_Z_LESS (0x2<<16)
+#define LCS_Z_EQUAL (0x3<<16)
+#define LCS_Z_LEQUAL (0x4<<16)
+#define LCS_Z_GREATER (0x5<<16)
+#define LCS_Z_NOTEQUAL (0x6<<16)
+#define LCS_Z_GEQUAL (0x7<<16)
+#define LCS_Z_ALWAYS (0x8<<16)
+#define LCS_UPDATE_LINEWIDTH (0x1<<15)
+#define LCS_LINEWIDTH_MASK (0x7<<12)
+#define LCS_LINEWIDTH_SHIFT 12
+#define LCS_UPDATE_ALPHA_INTERP (0x1<<11)
+#define LCS_ALPHA_FLAT (0x0<<10)
+#define LCS_ALPHA_INTERP (0x1<<10)
+#define LCS_UPDATE_FOG_INTERP (0x1<<9)
+#define LCS_FOG_INTERP (0x0<<8)
+#define LCS_FOG_FLAT (0x1<<8)
+#define LCS_UPDATE_SPEC_INTERP (0x1<<7)
+#define LCS_SPEC_INTERP (0x0<<6)
+#define LCS_SPEC_FLAT (0x1<<6)
+#define LCS_UPDATE_RGB_INTERP (0x1<<5)
+#define LCS_RGB_INTERP (0x0<<4)
+#define LCS_RGB_FLAT (0x1<<4)
+#define LCS_UPDATE_CULL_MODE (0x1<<3)
+#define LCS_CULL_MASK (0x7<<0)
+#define LCS_CULL_DISABLE (0x1<<0)
+#define LCS_CULL_CW (0x2<<0)
+#define LCS_CULL_CCW (0x3<<0)
+#define LCS_CULL_BOTH (0x4<<0)
+
+#define LCS_INTERP_FLAT (LCS_ALPHA_FLAT|LCS_RGB_FLAT|LCS_SPEC_FLAT)
+#define LCS_UPDATE_INTERP (LCS_UPDATE_ALPHA_INTERP| \
+ LCS_UPDATE_RGB_INTERP| \
+ LCS_UPDATE_SPEC_INTERP)
+
+
+/* GFXRENDERSTATE_BOOLEAN_ENA_1, p142
+ *
+ */
+#define GFX_OP_BOOL_1 ((0x3<<29)|(0x3<<24))
+#define B1_UPDATE_SPEC_SETUP_ENABLE (1<<19)
+#define B1_SPEC_SETUP_ENABLE (1<<18)
+#define B1_UPDATE_ALPHA_SETUP_ENABLE (1<<17)
+#define B1_ALPHA_SETUP_ENABLE (1<<16)
+#define B1_UPDATE_CI_KEY_ENABLE (1<<15)
+#define B1_CI_KEY_ENABLE (1<<14)
+#define B1_UPDATE_CHROMAKEY_ENABLE (1<<13)
+#define B1_CHROMAKEY_ENABLE (1<<12)
+#define B1_UPDATE_Z_BIAS_ENABLE (1<<11)
+#define B1_Z_BIAS_ENABLE (1<<10)
+#define B1_UPDATE_SPEC_ENABLE (1<<9)
+#define B1_SPEC_ENABLE (1<<8)
+#define B1_UPDATE_FOG_ENABLE (1<<7)
+#define B1_FOG_ENABLE (1<<6)
+#define B1_UPDATE_ALPHA_TEST_ENABLE (1<<5)
+#define B1_ALPHA_TEST_ENABLE (1<<4)
+#define B1_UPDATE_BLEND_ENABLE (1<<3)
+#define B1_BLEND_ENABLE (1<<2)
+#define B1_UPDATE_Z_TEST_ENABLE (1<<1)
+#define B1_Z_TEST_ENABLE (1<<0)
+
+/* GFXRENDERSTATE_BOOLEAN_ENA_2, p143
+ *
+ */
+#define GFX_OP_BOOL_2 ((0x3<<29)|(0x4<<24))
+#define B2_UPDATE_MAP_CACHE_ENABLE (1<<17)
+#define B2_MAP_CACHE_ENABLE (1<<16)
+#define B2_UPDATE_ALPHA_DITHER_ENABLE (1<<15)
+#define B2_ALPHA_DITHER_ENABLE (1<<14)
+#define B2_UPDATE_FOG_DITHER_ENABLE (1<<13)
+#define B2_FOG_DITHER_ENABLE (1<<12)
+#define B2_UPDATE_SPEC_DITHER_ENABLE (1<<11)
+#define B2_SPEC_DITHER_ENABLE (1<<10)
+#define B2_UPDATE_RGB_DITHER_ENABLE (1<<9)
+#define B2_RGB_DITHER_ENABLE (1<<8)
+#define B2_UPDATE_FB_WRITE_ENABLE (1<<3)
+#define B2_FB_WRITE_ENABLE (1<<2)
+#define B2_UPDATE_ZB_WRITE_ENABLE (1<<1)
+#define B2_ZB_WRITE_ENABLE (1<<0)
+
+
+/* GFXRENDERSTATE_FOG_COLOR, p144
+ */
+#define GFX_OP_FOG_COLOR ((0x3<<29)|(0x15<<24))
+#define FOG_RED_SHIFT 16
+#define FOG_GREEN_SHIFT 8
+#define FOG_BLUE_SHIFT 0
+#define FOG_RESERVED_MASK ((0x7<<16)|(0x3<<8)|(0x3))
+
+
+/* GFXRENDERSTATE_Z_BIAS_ALPHA_FUNC_REF, p139
+ */
+#define GFX_OP_ZBIAS_ALPHAFUNC ((0x3<<29)|(0x14<<24))
+#define ZA_UPDATE_ZBIAS (1<<22)
+#define ZA_ZBIAS_SHIFT 14
+#define ZA_ZBIAS_MASK (0xff<<14)
+#define ZA_UPDATE_ALPHAFUNC (1<<13)
+#define ZA_ALPHA_MASK (0xf<<9)
+#define ZA_ALPHA_NEVER (1<<9)
+#define ZA_ALPHA_LESS (2<<9)
+#define ZA_ALPHA_EQUAL (3<<9)
+#define ZA_ALPHA_LEQUAL (4<<9)
+#define ZA_ALPHA_GREATER (5<<9)
+#define ZA_ALPHA_NOTEQUAL (6<<9)
+#define ZA_ALPHA_GEQUAL (7<<9)
+#define ZA_ALPHA_ALWAYS (8<<9)
+#define ZA_UPDATE_ALPHAREF (1<<8)
+#define ZA_ALPHAREF_MASK (0xff<<0)
+#define ZA_ALPHAREF_SHIFT 0
+#define ZA_ALPHAREF_RESERVED (0x7<<0)
+
+
+/* GFXRENDERSTATE_SRC_DST_BLEND_MONO, p136
+ */
+#define GFX_OP_SRC_DEST_MONO ((0x3<<29)|(0x8<<24))
+#define SDM_UPDATE_MONO_ENABLE (1<<13)
+#define SDM_MONO_ENABLE (1<<12)
+#define SDM_UPDATE_SRC_BLEND (1<<11)
+#define SDM_SRC_MASK (0xf<<6)
+#define SDM_SRC_ZERO (0x1<<6)
+#define SDM_SRC_ONE (0x2<<6)
+#define SDM_SRC_SRC_COLOR (0x3<<6)
+#define SDM_SRC_INV_SRC_COLOR (0x4<<6)
+#define SDM_SRC_SRC_ALPHA (0x5<<6)
+#define SDM_SRC_INV_SRC_ALPHA (0x6<<6)
+#define SDM_SRC_DST_COLOR (0x9<<6)
+#define SDM_SRC_INV_DST_COLOR (0xa<<6)
+#define SDM_SRC_BOTH_SRC_ALPHA (0xc<<6)
+#define SDM_SRC_BOTH_INV_SRC_ALPHA (0xd<<6)
+#define SDM_UPDATE_DST_BLEND (1<<5)
+#define SDM_DST_MASK (0xf<<0)
+#define SDM_DST_ZERO (0x1<<0)
+#define SDM_DST_ONE (0x2<<0)
+#define SDM_DST_SRC_COLOR (0x3<<0)
+#define SDM_DST_INV_SRC_COLOR (0x4<<0)
+#define SDM_DST_SRC_ALPHA (0x5<<0)
+#define SDM_DST_INV_SRC_ALPHA (0x6<<0)
+#define SDM_DST_DST_COLOR (0x9<<0)
+#define SDM_DST_INV_DST_COLOR (0xa<<0)
+#define SDM_DST_BOTH_SRC_ALPHA (0xc<<0)
+#define SDM_DST_BOTH_INV_SRC_ALPHA (0xd<<0)
+
+
+/* GFXRENDERSTATE_COLOR_FACTOR, p134
+ *
+ * Format:
+ * 0: GFX_OP_COLOR_FACTOR
+ * 1: ARGB8888 color factor
+ */
+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
+
+/* GFXRENDERSTATE_MAP_ALPHA_BLEND_STAGES, p132
+ */
+#define GFX_OP_MAP_ALPHA_STAGES ((0x3<<29)|(0x1<<24))
+#define MA_STAGE_SHIFT 20
+#define MA_STAGE_0 (0<<20)
+#define MA_STAGE_1 (1<<20)
+#define MA_STAGE_2 (2<<20)
+#define MA_UPDATE_ARG1 (1<<18)
+#define MA_ARG1_MASK ((0x7<<15)|(0x1<<13))
+#define MA_ARG1_ALPHA_FACTOR (0x1<<15)
+#define MA_ARG1_ITERATED_ALPHA (0x3<<15)
+#define MA_ARG1_CURRENT_ALPHA (0x5<<15)
+#define MA_ARG1_TEX0_ALPHA (0x6<<15)
+#define MA_ARG1_TEX1_ALPHA (0x7<<15)
+#define MA_ARG1_INVERT (0x1<<13)
+#define MA_ARG1_DONT_INVERT (0x0<<13)
+#define MA_UPDATE_ARG2 (1<<12)
+#define MA_ARG2_MASK ((0x7<<8)|(0x1<<6))
+#define MA_ARG2_ALPHA_FACTOR (0x1<<8)
+#define MA_ARG2_ITERATED_ALPHA (0x3<<8)
+#define MA_ARG2_CURRENT_ALPHA (0x5<<8)
+#define MA_ARG2_TEX0_ALPHA (0x6<<8)
+#define MA_ARG2_TEX1_ALPHA (0x7<<8)
+#define MA_ARG2_INVERT (0x1<<6)
+#define MA_ARG2_DONT_INVERT (0x0<<6)
+#define MA_UPDATE_OP (1<<5)
+#define MA_OP_MASK (0xf)
+#define MA_OP_ARG1 (0x1)
+#define MA_OP_ARG2 (0x2)
+#define MA_OP_MODULATE (0x3)
+#define MA_OP_MODULATE_X2 (0x4)
+#define MA_OP_MODULATE_X4 (0x5)
+#define MA_OP_ADD (0x6)
+#define MA_OP_ADD_SIGNED (0x7)
+#define MA_OP_LIN_BLEND_ITER_ALPHA (0x8)
+#define MA_OP_LIN_BLEND_ALPHA_FACTOR (0xa)
+#define MA_OP_LIN_BLEND_TEX0_ALPHA (0x10)
+#define MA_OP_LIN_BLEND_TEX1_ALPHA (0x11)
+
+
+/* GFXRENDERSTATE_MAP_COLOR_BLEND_STAGES, p129
+ */
+#define GFX_OP_MAP_COLOR_STAGES ((0x3<<29)|(0x0<<24))
+#define MC_STAGE_SHIFT 20
+#define MC_STAGE_0 (0<<20)
+#define MC_STAGE_1 (1<<20)
+#define MC_STAGE_2 (2<<20)
+#define MC_UPDATE_DEST (1<<19)
+#define MC_DEST_MASK (1<<18)
+#define MC_DEST_CURRENT (0<<18)
+#define MC_DEST_ACCUMULATOR (1<<18)
+#define MC_UPDATE_ARG1 (1<<17)
+#define MC_ARG1_MASK ((0x7<<14)|(0x1<<13)|(0x1<<12))
+#define MC_ARG1_ONE (0x0<<14)
+#define MC_ARG1_COLOR_FACTOR (0x1<<14)
+#define MC_ARG1_ACCUMULATOR (0x2<<14)
+#define MC_ARG1_ITERATED_COLOR (0x3<<14)
+#define MC_ARG1_SPECULAR_COLOR (0x4<<14)
+#define MC_ARG1_CURRENT_COLOR (0x5<<14)
+#define MC_ARG1_TEX0_COLOR (0x6<<14)
+#define MC_ARG1_TEX1_COLOR (0x7<<14)
+#define MC_ARG1_DONT_REPLICATE_ALPHA (0x0<<13)
+#define MC_ARG1_REPLICATE_ALPHA (0x1<<13)
+#define MC_ARG1_DONT_INVERT (0x0<<12)
+#define MC_ARG1_INVERT (0x1<<12)
+#define MC_UPDATE_ARG2 (1<<11)
+#define MC_ARG2_MASK ((0x7<<8)|(0x1<<7)|(0x1<<6))
+#define MC_ARG2_ONE (0x0<<8)
+#define MC_ARG2_COLOR_FACTOR (0x1<<8)
+#define MC_ARG2_ACCUMULATOR (0x2<<8)
+#define MC_ARG2_ITERATED_COLOR (0x3<<8)
+#define MC_ARG2_SPECULAR_COLOR (0x4<<8)
+#define MC_ARG2_CURRENT_COLOR (0x5<<8)
+#define MC_ARG2_TEX0_COLOR (0x6<<8)
+#define MC_ARG2_TEX1_COLOR (0x7<<8)
+#define MC_ARG2_DONT_REPLICATE_ALPHA (0x0<<7)
+#define MC_ARG2_REPLICATE_ALPHA (0x1<<7)
+#define MC_ARG2_DONT_INVERT (0x0<<6)
+#define MC_ARG2_INVERT (0x1<<6)
+#define MC_UPDATE_OP (1<<5)
+#define MC_OP_MASK (0xf)
+#define MC_OP_DISABLE (0x0)
+#define MC_OP_ARG1 (0x1)
+#define MC_OP_ARG2 (0x2)
+#define MC_OP_MODULATE (0x3)
+#define MC_OP_MODULATE_X2 (0x4)
+#define MC_OP_MODULATE_X4 (0x5)
+#define MC_OP_ADD (0x6)
+#define MC_OP_ADD_SIGNED (0x7)
+#define MC_OP_LIN_BLEND_ITER_ALPHA (0x8)
+#define MC_OP_LIN_BLEND_ALPHA_FACTOR (0xa)
+#define MC_OP_LIN_BLEND_TEX0_ALPHA (0x10)
+#define MC_OP_LIN_BLEND_TEX1_ALPHA (0x11)
+#define MC_OP_LIN_BLEND_TEX0_COLOR (0x12)
+#define MC_OP_LIN_BLEND_TEX1_COLOR (0x13)
+#define MC_OP_SUBTRACT (0x14)
+
+/* GFXRENDERSTATE_MAP_PALETTE_LOAD, p128
+ *
+ * Format:
+ * 0: GFX_OP_MAP_PALETTE_LOAD
+ * 1: 16bpp color[0]
+ * ...
+ * 256: 16bpp color[255]
+ */
+#define GFX_OP_MAP_PALETTE_LOAD ((0x3<<29)|(0x1d<<24)|(0x82<<16)|0xff)
+
+/* GFXRENDERSTATE_MAP_LOD_CONTROL, p127
+ */
+#define GFX_OP_MAP_LOD_CTL ((0x3<<29)|(0x1c<<24)|(0x4<<19))
+#define MLC_MAP_ID_SHIFT 16
+#define MLC_MAP_0 (0<<16)
+#define MLC_MAP_1 (1<<16)
+#define MLC_UPDATE_DITHER_WEIGHT (1<<10)
+#define MLC_DITHER_WEIGHT_MASK (0x3<<8)
+#define MLC_DITHER_WEIGHT_FULL (0x0<<8)
+#define MLC_DITHER_WEIGHT_50 (0x1<<8)
+#define MLC_DITHER_WEIGHT_25 (0x2<<8)
+#define MLC_DITHER_WEIGHT_12 (0x3<<8)
+#define MLC_UPDATE_LOD_BIAS (1<<7)
+#define MLC_LOD_BIAS_MASK ((1<<7)-1)
+
+/* GFXRENDERSTATE_MAP_LOD_LIMITS, p126
+ */
+#define GFX_OP_MAP_LOD_LIMITS ((0x3<<29)|(0x1c<<24)|(0x3<<19))
+#define MLL_MAP_ID_SHIFT 16
+#define MLL_MAP_0 (0<<16)
+#define MLL_MAP_1 (1<<16)
+#define MLL_UPDATE_MAX_MIP (1<<13)
+#define MLL_MAX_MIP_SHIFT 5
+#define MLL_MAX_MIP_MASK (0xff<<5)
+#define MLL_MAX_MIP_ONE (0x10<<5)
+#define MLL_UPDATE_MIN_MIP (1<<4)
+#define MLL_MIN_MIP_SHIFT 0
+#define MLL_MIN_MIP_MASK (0xf<<0)
+
+/* GFXRENDERSTATE_MAP_FILTER, p124
+ */
+#define GFX_OP_MAP_FILTER ((0x3<<29)|(0x1c<<24)|(0x2<<19))
+#define MF_MAP_ID_SHIFT 16
+#define MF_MAP_0 (0<<16)
+#define MF_MAP_1 (1<<16)
+#define MF_UPDATE_ANISOTROPIC (1<<12)
+#define MF_ANISOTROPIC_MASK (1<<10)
+#define MF_ANISOTROPIC_ENABLE (1<<10)
+#define MF_UPDATE_MIP_FILTER (1<<9)
+#define MF_MIP_MASK (0x3<<6)
+#define MF_MIP_NONE (0x0<<6)
+#define MF_MIP_NEAREST (0x1<<6)
+#define MF_MIP_DITHER (0x2<<6)
+#define MF_UPDATE_MAG_FILTER (1<<5)
+#define MF_MAG_MASK (1<<3)
+#define MF_MAG_LINEAR (1<<3)
+#define MF_MAG_NEAREST (0<<3)
+#define MF_UPDATE_MIN_FILTER (1<<2)
+#define MF_MIN_MASK (1<<0)
+#define MF_MIN_LINEAR (1<<0)
+#define MF_MIN_NEAREST (0<<0)
+
+/* GFXRENDERSTATE_MAP_INFO, p118
+ */
+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2)
+#define MI1_MAP_ID_SHIFT 28
+#define MI1_MAP_0 (0<<28)
+#define MI1_MAP_1 (1<<28)
+#define MI1_FMT_MASK (0x7<<24)
+#define MI1_FMT_8CI (0x0<<24)
+#define MI1_FMT_8BPP (0x1<<24)
+#define MI1_FMT_16BPP (0x2<<24)
+#define MI1_FMT_422 (0x5<<24)
+#define MI1_PF_MASK (0x3<<21)
+#define MI1_PF_8CI_RGB565 (0x0<<21)
+#define MI1_PF_8CI_ARGB1555 (0x1<<21)
+#define MI1_PF_8CI_ARGB4444 (0x2<<21)
+#define MI1_PF_8CI_AY88 (0x3<<21)
+#define MI1_PF_16BPP_RGB565 (0x0<<21)
+#define MI1_PF_16BPP_ARGB1555 (0x1<<21)
+#define MI1_PF_16BPP_ARGB4444 (0x2<<21)
+#define MI1_PF_16BPP_AY88 (0x3<<21)
+#define MI1_PF_422_YCRCB_SWAP_Y (0x0<<21)
+#define MI1_PF_422_YCRCB (0x1<<21)
+#define MI1_PF_422_YCRCB_SWAP_UV (0x2<<21)
+#define MI1_PF_422_YCRCB_SWAP_YUV (0x3<<21)
+#define MI1_OUTPUT_CHANNEL_MASK (0x3<<19)
+#define MI1_COLOR_CONV_ENABLE (1<<18)
+#define MI1_VERT_STRIDE_MASK (1<<17)
+#define MI1_VERT_STRIDE_1 (1<<17)
+#define MI1_VERT_OFFSET_MASK (1<<16)
+#define MI1_VERT_OFFSET_1 (1<<16)
+#define MI1_ENABLE_FENCE_REGS (1<<10)
+#define MI1_TILED_SURFACE (1<<9)
+#define MI1_TILE_WALK_X (0<<8)
+#define MI1_TILE_WALK_Y (1<<8)
+#define MI1_PITCH_MASK (0xf<<0)
+#define MI2_DIMENSIONS_ARE_LOG2 (1<<31)
+#define MI2_DIMENSIONS_ARE_EXACT (0<<31)
+#define MI2_HEIGHT_SHIFT 16
+#define MI2_HEIGHT_MASK (0x1ff<<16)
+#define MI2_WIDTH_SHIFT 0
+#define MI2_WIDTH_MASK (0x1ff<<0)
+#define MI3_BASE_ADDR_MASK (~0xf)
+
+/* GFXRENDERSTATE_MAP_COORD_SETS, p116
+ */
+#define GFX_OP_MAP_COORD_SETS ((0x3<<29)|(0x1c<<24)|(0x1<<19))
+#define MCS_COORD_ID_SHIFT 16
+#define MCS_COORD_0 (0<<16)
+#define MCS_COORD_1 (1<<16)
+#define MCS_UPDATE_NORMALIZED (1<<15)
+#define MCS_NORMALIZED_COORDS_MASK (1<<14)
+#define MCS_NORMALIZED_COORDS (1<<14)
+#define MCS_UPDATE_V_STATE (1<<7)
+#define MCS_V_STATE_MASK (0x3<<4)
+#define MCS_V_WRAP (0x0<<4)
+#define MCS_V_MIRROR (0x1<<4)
+#define MCS_V_CLAMP (0x2<<4)
+#define MCS_V_WRAP_SHORTEST (0x3<<4)
+#define MCS_UPDATE_U_STATE (1<<3)
+#define MCS_U_STATE_MASK (0x3<<0)
+#define MCS_U_WRAP (0x0<<0)
+#define MCS_U_MIRROR (0x1<<0)
+#define MCS_U_CLAMP (0x2<<0)
+#define MCS_U_WRAP_SHORTEST (0x3<<0)
+
+/* GFXRENDERSTATE_MAP_TEXELS, p115
+ */
+#define GFX_OP_MAP_TEXELS ((0x3<<29)|(0x1c<<24)|(0x0<<19))
+#define MT_UPDATE_TEXEL1_STATE (1<<15)
+#define MT_TEXEL1_DISABLE (0<<14)
+#define MT_TEXEL1_ENABLE (1<<14)
+#define MT_TEXEL1_COORD0 (0<<11)
+#define MT_TEXEL1_COORD1 (1<<11)
+#define MT_TEXEL1_MAP0 (0<<8)
+#define MT_TEXEL1_MAP1 (1<<8)
+#define MT_UPDATE_TEXEL0_STATE (1<<7)
+#define MT_TEXEL0_DISABLE (0<<6)
+#define MT_TEXEL0_ENABLE (1<<6)
+#define MT_TEXEL0_COORD0 (0<<3)
+#define MT_TEXEL0_COORD1 (1<<3)
+#define MT_TEXEL0_MAP0 (0<<0)
+#define MT_TEXEL0_MAP1 (1<<0)
+
+/* GFXRENDERSTATE_VERTEX_FORMAT, p110
+ */
+#define GFX_OP_VERTEX_FMT ((0x3<<29)|(0x5<<24))
+#define VF_TEXCOORD_COUNT_SHIFT 8
+#define VF_TEXCOORD_COUNT_0 (0<<8)
+#define VF_TEXCOORD_COUNT_1 (1<<8)
+#define VF_TEXCOORD_COUNT_2 (2<<8)
+#define VF_SPEC_FOG_ENABLE (1<<7)
+#define VF_RGBA_ENABLE (1<<6)
+#define VF_Z_OFFSET_ENABLE (1<<5)
+#define VF_XYZ (0x1<<1)
+#define VF_XYZW (0x2<<1)
+#define VF_XY (0x3<<1)
+#define VF_XYW (0x4<<1)
+
+
+#define VERT_X_MASK (~0xf)
+#define VERT_X_EDGE_V2V0 (1<<2)
+#define VERT_X_EDGE_V1V2 (1<<1)
+#define VERT_X_EDGE_V0V1 (1<<0)
+
+/* Not enabled fields should not be sent to hardware:
+ */
+typedef struct {
+ union {
+ float x;
+ unsigned int edge_flags;
+ } x;
+ float y;
+ float z;
+ float z_bias;
+ float oow;
+ unsigned int argb;
+ unsigned int fog_spec_rgb; /* spec g and r ignored. */
+ float tu0;
+ float tv0;
+ float tu1;
+ float tv1;
+} i810_full_vertex;
+
+
+/* GFX_PRIMITIVE, p106
+ */
+#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24))
+#define PR_TRIANGLES (0x0<<18)
+#define PR_TRISTRIP_0 (0x1<<18)
+#define PR_TRISTRIP_1 (0x2<<18)
+#define PR_TRIFAN (0x3<<18)
+#define PR_POLYGON (0x4<<18)
+#define PR_LINES (0x5<<18)
+#define PR_LINESTRIP (0x6<<18)
+#define PR_RECTS (0x7<<18)
+#define PR_DWORD_COUNT_SHIFT 0
+
+/* GFXCMDPARSER_BATCH_BUFFER, p105
+ *
+ * Not clear whether start address must be shifted or not. Not clear
+ * whether address is physical system memory, or subject to GTT
+ * translation. Because the address appears to be 32 bits long,
+ * perhaps it refers to physical system memory...
+ */
+#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
+#define BB1_START_ADDR_MASK (~0x7)
+#define BB1_PROTECTED (1<<0)
+#define BB1_UNPROTECTED (0<<0)
+#define BB2_END_ADDR_MASK (~0x7)
+
+/* Hardware seems to barf on buffers larger than this (in strange ways)...
+ */
+#define MAX_BATCH (512*1024)
+
+
+/* GFXCMDPARSER_Z_BUFFER_INFO, p98
+ *
+ * Base address is in GTT space, and must be 4K aligned
+ */
+#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23))
+#define ZB_BASE_ADDR_SHIFT 0
+#define ZB_BASE_ADDR_MASK (~((1<<12)-1))
+#define ZB_PITCH_512B (0x0<<0)
+#define ZB_PITCH_1K (0x1<<0)
+#define ZB_PITCH_2K (0x2<<0)
+#define ZB_PITCH_4K (0x3<<0)
+
+/* GFXCMDPARSER_FRONT_BUFFER_INFO, p97
+ *
+ * Format:
+ * 0: CMD_OP_FRONT_BUFFER_INFO | (pitch<<FB0_PITCH_SHIFT) | FB0_*
+ * 1: FB1_*
+ */
+#define CMD_OP_FRONT_BUFFER_INFO ((0x0<<29)|(0x14<<23))
+#define FB0_PITCH_SHIFT 8
+#define FB0_FLIP_SYNC (0<<6)
+#define FB0_FLIP_ASYNC (1<<6)
+#define FB0_BASE_ADDR_SHIFT 0
+#define FB0_BASE_ADDR_MASK 0x03FFFFF8
+
+/* GFXCMDPARSER_DEST_BUFFER_INFO, p96
+ *
+ * Format:
+ */
+#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
+#define DB1_BASE_ADDR_SHIFT 0
+#define DB1_BASE_ADDR_MASK 0x03FFF000
+#define DB1_PITCH_512B (0x0<<0)
+#define DB1_PITCH_1K (0x1<<0)
+#define DB1_PITCH_2K (0x2<<0)
+#define DB1_PITCH_4K (0x4<<0)
+
+
+/* GFXRENDERSTATE_DEST_BUFFER_VARIABLES, p152
+ *
+ * Format:
+ * 0: GFX_OP_DESTBUFFER_VARS
+ * 1: DEST_*
+ */
+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define DV_HORG_BIAS_MASK (0xf<<20)
+#define DV_HORG_BIAS_OGL (0x0<<20)
+#define DV_VORG_BIAS_MASK (0xf<<16)
+#define DV_VORG_BIAS_OGL (0x0<<16)
+#define DV_PF_MASK (0x7<<8)
+#define DV_PF_INDEX (0x0<<8)
+#define DV_PF_555 (0x1<<8)
+#define DV_PF_565 (0x2<<8)
+
+
+
+
+#define GFX_OP_ANTIALIAS ((0x3<<29)|(0x6<<24))
+#define AA_UPDATE_EDGEFLAG (1<<13)
+#define AA_ENABLE_EDGEFLAG (1<<12)
+#define AA_UPDATE_POLYWIDTH (1<<11)
+#define AA_POLYWIDTH_05 (1<<9)
+#define AA_POLYWIDTH_10 (2<<9)
+#define AA_POLYWIDTH_20 (3<<9)
+#define AA_POLYWIDTH_40 (4<<9)
+#define AA_UPDATE_LINEWIDTH (1<<8)
+#define AA_LINEWIDTH_05 (1<<6)
+#define AA_LINEWIDTH_10 (2<<6)
+#define AA_LINEWIDTH_20 (3<<6)
+#define AA_LINEWIDTH_40 (4<<6)
+#define AA_UPDATE_BB_EXPANSION (1<<5)
+#define AA_BB_EXPANSION_SHIFT 2
+#define AA_UPDATE_AA_ENABLE (1<<1)
+#define AA_ENABLE (1<<0)
+
+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE (1<<16)
+#define ST1_MASK (0xffff)
+
+
+/* Indices into buf.Setup where various bits of state are mirrored per
+ * context and per buffer. These can be fired at the card as a unit,
+ * or in a piecewise fashion as required.
+ */
+
+/* Destbuffer state
+ * - backbuffer linear offset and pitch -- invarient in the current dri
+ * - zbuffer linear offset and pitch -- also invarient
+ * - drawing origin in back and depth buffers.
+ *
+ * Keep the depth/back buffer state here to acommodate private buffers
+ * in the future.
+ */
+#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */
+#define I810_DESTREG_DI1 1
+#define I810_DESTREG_ZB0 2 /* CMD_OP_Z_BUFFER_INFO */
+#define I810_DESTREG_ZB1 3 /* CMD_OP_Z_BUFFER_INFO */
+#define I810_DESTREG_DV0 4 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */
+#define I810_DESTREG_DV1 5
+#define I810_DESTREG_DR0 6 /* GFX_OP_DRAWRECT_INFO (4 dwords) */
+#define I810_DESTREG_DR1 7
+#define I810_DESTREG_DR2 8
+#define I810_DESTREG_DR3 9
+#define I810_DESTREG_DR4 10
+
+#define I810_DEST_SETUP_SIZE (11+1)
+
+/* Context state
+ */
+#define I810_CTXREG_VF 0 /* GFX_OP_VERTEX_FMT */
+#define I810_CTXREG_MT 1 /* GFX_OP_MAP_TEXELS */
+#define I810_CTXREG_MC0 2 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
+#define I810_CTXREG_MC1 3 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
+#define I810_CTXREG_MC2 4 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
+#define I810_CTXREG_MA0 5 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
+#define I810_CTXREG_MA1 6 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
+#define I810_CTXREG_MA2 7 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */
+#define I810_CTXREG_SDM 8 /* GFX_OP_SRC_DEST_MONO */
+#define I810_CTXREG_CF0 9 /* GFX_OP_COLOR_FACTOR */
+#define I810_CTXREG_CF1 10
+#define I810_CTXREG_FOG 11 /* GFX_OP_FOG_COLOR */
+#define I810_CTXREG_B1 12 /* GFX_OP_BOOL_1 */
+#define I810_CTXREG_B2 13 /* GFX_OP_BOOL_2 */
+#define I810_CTXREG_LCS 14 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */
+#define I810_CTXREG_PV 15 /* GFX_OP_PV_RULE -- Invarient! */
+#define I810_CTXREG_ZA 16 /* GFX_OP_ZBIAS_ALPHAFUNC */
+#define I810_CTXREG_ST0 17 /* GFX_OP_STIPPLE */
+#define I810_CTXREG_ST1 18
+#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */
+#define I810_CTX_SETUP_SIZE (20) /* pad to qword */
+
+
+/* Cliprect state - keep seperate from context as it is used for
+ * drawing triangles to the shared backbuffer, and
+ * changes more frequently than the 'normal' context.
+ */
+#define I810_CLIPREG_SCI0 0 /* GFX_OP_SCISSOR_INFO (3 dwords) */
+#define I810_CLIPREG_SCI1 1
+#define I810_CLIPREG_SCI2 2
+#define I810_CLIPREG_SC 3 /* GFX_OP_SCISSOR */
+
+#define I810_CLIP_SETUP_SIZE 4
+
+/* Texture state (per tex_buffer)
+ */
+#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */
+#define I810_TEXREG_MI1 1
+#define I810_TEXREG_MI2 2
+#define I810_TEXREG_MI3 3
+#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */
+#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */
+#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */
+#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
+
+#define I810_TEX_SETUP_SIZE 8
+
+
+#define I810_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_init.h b/xc/lib/GL/mesa/src/drv/i810/i810_init.h
new file mode 100644
index 000000000..f676a204f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810_init.h
@@ -0,0 +1,135 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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, 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 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keithw@precisioninsight.com>
+ * Daryll Strauss <daryll@precisioninsight.com> (Origninal tdfx driver).
+ *
+ * $PI: $
+ */
+
+#ifndef _I810_INIT_H_
+#define _I810_INIT_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <sys/time.h>
+#include "dri_tmm.h"
+#include "dri_mesaint.h"
+#include "dri_mesa.h"
+#include "types.h"
+#include "xmesaP.h"
+
+typedef struct {
+ drmHandle handle;
+ drmSize size;
+ drmAddress map;
+} i810Region, *i810RegionPtr;
+
+typedef struct {
+ i810Region regs;
+
+ int deviceID;
+ int width;
+ int height;
+ int mem;
+
+ int cpp; /* for front and back buffers */
+ int bitsPerPixel;
+
+ int fbFormat;
+ int fbOffset;
+ int fbStride;
+
+ int backOffset;
+ int depthOffset;
+
+ int auxPitch;
+ int auxPitchBits;
+
+ int textureOffset;
+ int textureSize;
+ int logTextureGranularity;
+
+ __DRIscreenPrivate *driScrnPriv;
+
+} i810ScreenPrivate;
+
+
+#include "i810context.h"
+
+extern void i810XMesaUpdateState( i810ContextPtr imesa );
+extern void i810EmitHwStateLocked( i810ContextPtr imesa );
+extern void i810EmitScissorValues( i810ContextPtr imesa, int box_nr, int emit );
+extern void i810EmitDrawingRectangle( i810ContextPtr imesa );
+extern void i810XMesaSetBackClipRects( i810ContextPtr imesa );
+extern void i810XMesaSetFrontClipRects( i810ContextPtr imesa );
+
+
+/* Lock the hardware and validate our state.
+ */
+#define LOCK_HARDWARE( imesa ) \
+ do { \
+ char __ret=0; \
+ DRM_CAS(imesa->driHwLock, imesa->hHWContext, \
+ (DRM_LOCK_HELD|imesa->hHWContext), __ret); \
+ if (__ret) { \
+ drmGetLock(imesa->driFd, imesa->hHWContext, 0); \
+ i810XMesaUpdateState( imesa ); \
+ } \
+ } while (0)
+
+
+/* Unlock the hardware using the global current context
+ */
+#define UNLOCK_HARDWARE(imesa) \
+ DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext);
+
+
+/*
+ This pair of macros makes a loop over the drawing operations
+ so it is not self contained and doesn't have the nice single
+ statement semantics of most macros
+*/
+#define BEGIN_CLIP_LOOP(imesa) \
+ do { \
+ int _nc; \
+ LOCK_HARDWARE( imesa ); \
+ for (_nc = imesa->numClipRects; _nc ; _nc--) { \
+ if (imesa->needClip) \
+ i810EmitScissorValues(imesa, _nc-1, 1);
+
+
+
+#define END_CLIP_LOOP(imesa) \
+ } \
+ UNLOCK_HARDWARE(imesa); \
+ } while (0)
+
+#endif
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c
new file mode 100644
index 000000000..cdac028b5
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c
@@ -0,0 +1,611 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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, 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 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keithw@precisioninsight.com>
+ *
+ * $PI: $
+ */
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <X11/Xlibint.h>
+#include <stdio.h>
+
+#include "i810_init.h"
+#include "context.h"
+#include "vbxform.h"
+#include "matrix.h"
+#include "simple_list.h"
+
+#include "i810dd.h"
+#include "i810state.h"
+#include "i810tex.h"
+#include "i810span.h"
+#include "i810depth.h"
+#include "i810tris.h"
+#include "i810swap.h"
+#include "i810pipeline.h"
+
+#include "i810_dri.h"
+
+
+
+#ifndef I810_DEBUG
+int I810_DEBUG = (0
+ | DEBUG_ALWAYS_SYNC
+ | DEBUG_VERBOSE_RING
+ | DEBUG_VERBOSE_OUTREG
+/* | DEBUG_VERBOSE_MSG */
+/* | DEBUG_NO_OUTRING */
+/* | DEBUG_NO_OUTREG */
+/* | DEBUG_VERBOSE_API */
+/* | DEBUG_VERBOSE_2D */
+/* | DEBUG_VERBOSE_DRI */
+ | DEBUG_VALIDATE_RING
+ );
+#endif
+
+
+static i810ContextPtr i810Ctx = 0;
+
+i810Glx_t i810glx;
+
+static int count_bits(unsigned int n)
+{
+ int bits = 0;
+
+ while (n > 0) {
+ if (n & 1) bits++;
+ n >>= 1;
+ }
+ return bits;
+}
+
+/* These functions are accessed by dlsym from dri_mesa_init.c:
+ *
+ * XMesaInitDriver
+ * XMesaResetDriver
+ * XMesaCreateVisual
+ * XMesaDestroyVisual
+ * XMesaCreateContext
+ * XMesaDestroyContext
+ * XMesaCreateWindowBuffer
+ * XMesaCreatePixmapBuffer
+ * XMesaDestroyBuffer
+ * XMesaSwapBuffers
+ * XMesaMakeCurrent
+ *
+ * So this is kind of the public interface to the driver. The driver
+ * uses the X11 mesa driver context as a kind of wrapper around its
+ * own driver context - but there isn't much justificiation for doing
+ * it that way - the DRI might as well use a (void *) to refer to the
+ * driver contexts. Nothing in the X context really gets used.
+ */
+
+
+GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
+{
+ i810ScreenPrivate *i810Screen;
+ I810DRIPtr gDRIPriv = (I810DRIPtr)sPriv->pDevPriv;
+
+ /* Allocate the private area */
+ i810Screen = (i810ScreenPrivate *)Xmalloc(sizeof(i810ScreenPrivate));
+ if (!i810Screen) return GL_FALSE;
+
+ i810Screen->driScrnPriv = sPriv;
+ sPriv->private = (void *)i810Screen;
+
+ i810Screen->regs.handle=gDRIPriv->regs;
+ i810Screen->regs.size=gDRIPriv->regsSize;
+ i810Screen->deviceID=gDRIPriv->deviceID;
+ i810Screen->width=gDRIPriv->width;
+ i810Screen->height=gDRIPriv->height;
+ i810Screen->mem=gDRIPriv->mem;
+ i810Screen->cpp=gDRIPriv->cpp;
+ i810Screen->fbStride=gDRIPriv->fbStride;
+ i810Screen->fbOffset=gDRIPriv->fbOffset;
+
+ if (gDRIPriv->bitsPerPixel == 15)
+ i810Screen->fbFormat = DV_PF_555;
+ else
+ i810Screen->fbFormat = DV_PF_565;
+
+ i810Screen->backOffset=gDRIPriv->backOffset;
+ i810Screen->depthOffset=gDRIPriv->depthOffset;
+ i810Screen->auxPitch = gDRIPriv->auxPitch;
+ i810Screen->auxPitchBits = gDRIPriv->auxPitchBits;
+ i810Screen->textureOffset=gDRIPriv->textureOffset;
+ i810Screen->textureSize=gDRIPriv->textureSize;
+ i810Screen->logTextureGranularity = gDRIPriv->logTextureGranularity;
+
+
+ if (0)
+ fprintf(stderr, "Tex heap size %x, granularity %x bytes\n",
+ i810Screen->textureSize, 1<<(i810Screen->logTextureGranularity));
+
+ if (drmMap(sPriv->fd,
+ i810Screen->regs.handle,
+ i810Screen->regs.size,
+ &i810Screen->regs.map) != 0)
+ {
+ Xfree(i810Screen);
+ return GL_FALSE;
+ }
+
+ /* Ditch i810glx in favor of i810Screen?
+ */
+ memset(&i810glx, 0, sizeof(i810glx));
+
+ i810glx.LpRing.mem.Start = gDRIPriv->ringOffset;
+ i810glx.LpRing.mem.Size = gDRIPriv->ringSize;
+ i810glx.LpRing.mem.End = gDRIPriv->ringOffset + gDRIPriv->ringSize;
+ i810glx.LpRing.virtual_start = sPriv->pFB + i810glx.LpRing.mem.Start;
+ i810glx.LpRing.tail_mask = i810glx.LpRing.mem.Size - 1;
+ i810glx.MMIOBase = i810Screen->regs.map;
+ i810glx.texVirtual = sPriv->pFB + i810Screen->textureOffset;
+
+
+ i810DDFastPathInit();
+ i810DDTrifuncInit();
+ i810DDSetupInit();
+
+ return GL_TRUE;
+}
+
+/* Accessed by dlsym from dri_mesa_init.c
+ */
+void XMesaResetDriver(__DRIscreenPrivate *sPriv)
+{
+ i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
+
+ drmUnmap(i810Screen->regs.map, i810Screen->regs.size);
+ Xfree(i810Screen);
+}
+
+/* Accessed by dlsym from dri_mesa_init.c
+ */
+XMesaVisual XMesaCreateVisual(XMesaDisplay *display,
+ XMesaVisualInfo visinfo,
+ GLboolean rgb_flag,
+ GLboolean alpha_flag,
+ GLboolean db_flag,
+ GLboolean stereo_flag,
+ GLboolean ximage_flag,
+ GLint depth_size,
+ GLint stencil_size,
+ GLint accum_size,
+ GLint level)
+{
+ XMesaVisual v;
+
+ /* Only RGB visuals are supported on the I810 boards */
+ if (!rgb_flag) return 0;
+
+ v = (XMesaVisual)Xmalloc(sizeof(struct xmesa_visual));
+ if (!v) return 0;
+
+ v->visinfo = (XVisualInfo *)Xmalloc(sizeof(*visinfo));
+ if(!v->visinfo) {
+ Xfree(v);
+ return 0;
+ }
+ memcpy(v->visinfo, visinfo, sizeof(*visinfo));
+
+ v->display = display;
+ v->level = level;
+
+ v->gl_visual = (GLvisual *)Xmalloc(sizeof(GLvisual));
+ if (!v->gl_visual) {
+ Xfree(v->visinfo);
+ XFree(v);
+ return 0;
+ }
+
+ v->gl_visual->RGBAflag = rgb_flag;
+ v->gl_visual->DBflag = db_flag;
+ v->gl_visual->StereoFlag = stereo_flag;
+
+ v->gl_visual->RedBits = count_bits(visinfo->red_mask);
+ v->gl_visual->GreenBits = count_bits(visinfo->green_mask);
+ v->gl_visual->BlueBits = count_bits(visinfo->blue_mask);
+ v->gl_visual->AlphaBits = 0; /* Not currently supported */
+
+ v->gl_visual->AccumBits = accum_size;
+ v->gl_visual->DepthBits = depth_size;
+ v->gl_visual->StencilBits = stencil_size;
+
+ return v;
+}
+
+void XMesaDestroyVisual(XMesaVisual v)
+{
+ Xfree(v->gl_visual);
+ Xfree(v->visinfo);
+ Xfree(v);
+}
+
+XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
+ __DRIcontextPrivate *driContextPriv)
+{
+ GLcontext *ctx;
+ XMesaContext c;
+ i810ContextPtr imesa;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
+ I810SAREAPriv *saPriv=(I810SAREAPriv*)(((char*)sPriv->pSAREA)+
+ sizeof(XF86DRISAREARec));
+
+ GLcontext *shareCtx = 0;
+
+ c = (XMesaContext)Xmalloc(sizeof(struct xmesa_context));
+ if (!c) {
+ return 0;
+ }
+
+ imesa = (i810ContextPtr)Xmalloc(sizeof(i810Context));
+ if (!imesa) {
+ Xfree(c);
+ return 0;
+ }
+
+ c->driContextPriv = driContextPriv;
+ c->xm_visual = v;
+ c->xm_buffer = 0; /* Set by MakeCurrent */
+ c->display = v->display;
+ c->private = (void *)imesa;
+
+ if (share_list)
+ shareCtx=((i810ContextPtr)(share_list->private))->glCtx;
+
+ ctx = imesa->glCtx = gl_create_context(v->gl_visual, shareCtx,
+ (void*)imesa, GL_TRUE);
+
+ /* Dri stuff
+ */
+ imesa->display = v->display;
+ imesa->hHWContext = driContextPriv->hHWContext;
+ imesa->driFd = sPriv->fd;
+ imesa->driHwLock = &sPriv->pSAREA->lock;
+
+ imesa->i810Screen = i810Screen;
+ imesa->driScreen = sPriv;
+ imesa->sarea = saPriv;
+
+ imesa->glBuffer = gl_create_framebuffer(v->gl_visual);
+
+ imesa->needClip=1;
+
+ imesa->texHeap = mmInit( 0, i810Screen->textureSize );
+
+
+ /* Utah stuff
+ */
+ imesa->renderindex = -1; /* impossible value */
+ imesa->new_state = ~0;
+ imesa->dirty = ~0;
+
+ make_empty_list(&imesa->TexObjList);
+ make_empty_list(&imesa->SwappedOut);
+
+ imesa->TextureMode = ctx->Texture.Unit[0].EnvMode;
+ imesa->CurrentTexObj[0] = 0;
+ imesa->CurrentTexObj[1] = 0;
+
+ i810DDExtensionsInit( ctx );
+
+ i810DDInitStateFuncs( ctx );
+ i810DDInitTextureFuncs( ctx );
+ i810DDInitSpanFuncs( ctx );
+ i810DDInitDepthFuncs( ctx );
+ i810DDInitDriverFuncs( ctx );
+
+ ctx->Driver.TriangleCaps = (DD_TRI_CULL|
+ DD_TRI_LIGHT_TWOSIDE|
+ DD_TRI_OFFSET);
+
+ /* Ask mesa to clip fog coordinates for us.
+ */
+ ctx->TriangleCaps |= DD_CLIP_FOG_COORD;
+
+ ctx->Shared->DefaultD[2][0].DriverData = 0;
+ ctx->Shared->DefaultD[2][1].DriverData = 0;
+
+ if (ctx->VB)
+ i810DDRegisterVB( ctx->VB );
+
+ if (ctx->NrPipelineStages)
+ ctx->NrPipelineStages =
+ i810DDRegisterPipelineStages(ctx->PipelineStage,
+ ctx->PipelineStage,
+ ctx->NrPipelineStages);
+
+ i810DDInitState( imesa );
+
+ return c;
+}
+
+void XMesaDestroyContext(XMesaContext c)
+{
+ i810ContextPtr imesa = (i810ContextPtr) c->private;
+
+ if (imesa) {
+ i810TextureObjectPtr next_t, t;
+
+ gl_destroy_context(imesa->glCtx);
+ gl_destroy_framebuffer(imesa->glBuffer);
+
+ foreach_s (t, next_t, &(imesa->TexObjList))
+ i810DestroyTexObj(imesa, t);
+
+ foreach_s (t, next_t, &(imesa->SwappedOut))
+ i810DestroyTexObj(imesa, t);
+
+ Xfree(imesa);
+
+ c->private = 0;
+ }
+}
+
+XMesaBuffer XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w,
+ __DRIdrawablePrivate *driDrawPriv)
+{
+ return (XMesaBuffer)1;
+}
+
+XMesaBuffer XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p,
+ XMesaColormap c,
+ __DRIdrawablePrivate *driDrawPriv)
+{
+ return (XMesaBuffer)1;
+}
+
+void XMesaDestroyBuffer(XMesaBuffer b)
+{
+}
+
+void XMesaSwapBuffers(XMesaBuffer bogus)
+{
+ i810ContextPtr imesa = i810Ctx;
+
+ FLUSH_VB( imesa->glCtx, "swap buffers" );
+ i810SwapBuffers(imesa);
+}
+
+static void i810InitClipRects( i810ContextPtr imesa )
+{
+ switch (imesa->numClipRects) {
+ case 0:
+ imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR |
+ SC_UPDATE_SCISSOR );
+ imesa->ClipSetup[I810_CLIPREG_SCI1] = 0;
+ imesa->ClipSetup[I810_CLIPREG_SCI2] = 0;
+ imesa->needClip = 0;
+ imesa->dirty |= I810_EMIT_CLIPRECT;
+ break;
+ case 1:
+ imesa->needClip = 0;
+ i810EmitScissorValues( imesa, 0, 0 );
+ imesa->dirty |= I810_EMIT_CLIPRECT;
+ break;
+ default:
+ imesa->needClip=1;
+ break;
+ }
+}
+
+
+
+void i810XMesaSetFrontClipRects( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+ imesa->numClipRects = dPriv->numClipRects;
+ imesa->pClipRects = dPriv->pClipRects;
+ imesa->drawX = dPriv->x;
+ imesa->drawY = dPriv->y;
+
+ imesa->drawOffset = imesa->i810Screen->fbOffset;
+ i810EmitDrawingRectangle( imesa );
+ i810InitClipRects( imesa );
+}
+
+
+void i810XMesaSetBackClipRects( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ int i;
+
+ if (dPriv->numAuxClipRects == 0)
+ {
+ if (I810_DEBUG & DEBUG_VERBOSE_DRI)
+ fprintf(stderr, "FRONT_CLIPRECTS, %d rects\n",
+ dPriv->numClipRects);
+
+ imesa->numClipRects = dPriv->numClipRects;
+ imesa->pClipRects = dPriv->pClipRects;
+ imesa->drawX = dPriv->x;
+ imesa->drawY = dPriv->y;
+ } else {
+ if (I810_DEBUG & DEBUG_VERBOSE_DRI)
+ fprintf(stderr, "AUX_RECTS, %d rects\n",
+ dPriv->numAuxClipRects);
+
+ imesa->numClipRects = dPriv->numAuxClipRects;
+ imesa->pClipRects = dPriv->pAuxClipRects;
+ imesa->drawX = dPriv->auxX;
+ imesa->drawY = dPriv->auxY;
+ }
+
+ imesa->drawOffset = imesa->i810Screen->backOffset;
+ i810EmitDrawingRectangle( imesa );
+ i810InitClipRects( imesa );
+
+ if (I810_DEBUG & DEBUG_VERBOSE_DRI)
+ for (i = 0 ; i < imesa->numClipRects ; i++)
+ fprintf(stderr, "cliprect %d: %d,%d - %d,%d\n",
+ i,
+ imesa->pClipRects[i].x1,
+ imesa->pClipRects[i].y1,
+ imesa->pClipRects[i].x2,
+ imesa->pClipRects[i].y2);
+}
+
+
+static void i810XMesaWindowMoved( i810ContextPtr imesa )
+{
+ switch (imesa->glCtx->Color.DriverDrawBuffer) {
+ case GL_FRONT_LEFT:
+ i810XMesaSetFrontClipRects( imesa );
+ break;
+ case GL_BACK_LEFT:
+ i810XMesaSetBackClipRects( imesa );
+ break;
+ default:
+ fprintf(stderr, "fallback buffer\n");
+ break;
+ }
+
+}
+
+
+/* This looks buggy to me - the 'b' variable isn't used anywhere...
+ * Hmm - It seems that the drawable is already hooked in to
+ * driDrawablePriv.
+ */
+GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b)
+{
+
+ if (c->private==(void *)i810Ctx) return GL_TRUE;
+
+ if (c) {
+ __DRIdrawablePrivate *dPriv = c->driContextPriv->driDrawablePriv;
+
+ i810Ctx = (i810ContextPtr)c->private;
+
+ gl_make_current(i810Ctx->glCtx, i810Ctx->glBuffer);
+
+ i810Ctx->driDrawable = dPriv;
+ i810Ctx->dirty = ~0;
+
+ i810XMesaWindowMoved( i810Ctx );
+
+ if (!i810Ctx->glCtx->Viewport.Width)
+ gl_Viewport(i810Ctx->glCtx, 0, 0, dPriv->w, dPriv->h);
+
+ } else {
+ gl_make_current(0,0);
+ i810Ctx = NULL;
+ }
+ return GL_TRUE;
+}
+
+
+void i810XMesaUpdateState( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ __DRIscreenPrivate *sPriv = imesa->driScreen;
+ I810SAREAPriv *sarea = imesa->sarea;
+ int me = imesa->hHWContext;
+ int stamp = dPriv->lastStamp;
+
+
+ /* If the window moved, may need to set a new cliprect now.
+ *
+ * NOTE: This releases and regains the hw lock, so all state
+ * checking must be done *after* this call:
+ */
+ XMESA_VALIDATE_DRAWABLE_INFO(imesa->display, sPriv, dPriv);
+
+ i810glx.LpRing.synced = 0;
+
+ /* If another client has touched the ringbuffer, need to update
+ * where we think the pointers are:
+ */
+ if (sarea->ringOwner != me) {
+ i810glx.c_ringlost++;
+ imesa->dirty |= I810_REFRESH_RING;
+ }
+
+ /* If we lost context, need to dump all registers to hardware.
+ * Note that we don't care about 2d contexts, even if they perform
+ * accelerated commands, so the DRI locking in the X server is even
+ * more broken than usual.
+ */
+ if (sarea->ctxOwner != me) {
+ i810glx.c_ctxlost++;
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->dirty |= I810_EMIT_CLIPRECT;
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+ }
+
+ /* Shared texture managment - if another client has played with
+ * texture space, figure out which if any of our textures have been
+ * ejected, and update our global LRU.
+ */
+ if (sarea->texAge != imesa->texAge) {
+ int sz = 1 << (imesa->i810Screen->logTextureGranularity);
+ int idx, nr = 0;
+
+ /* Have to go right round from the back to ensure stuff ends up
+ * LRU in our local list...
+ */
+ for (idx = sarea->texList[I810_NR_TEX_REGIONS].prev ;
+ idx != I810_NR_TEX_REGIONS && nr < I810_NR_TEX_REGIONS ;
+ idx = sarea->texList[idx].prev, nr++)
+ {
+ if (sarea->texList[idx].age > imesa->texAge)
+ i810TexturesGone(imesa, idx * sz, sz, sarea->texList[idx].in_use);
+ }
+
+ if (nr == I810_NR_TEX_REGIONS) {
+ i810TexturesGone(imesa, 0, imesa->i810Screen->textureSize, 0);
+ i810ResetGlobalLRU( imesa );
+ }
+
+ imesa->texAge = sarea->texAge;
+ imesa->dirty |= I810_UPLOAD_TEX0IMAGE | I810_UPLOAD_TEX1IMAGE;
+ }
+
+
+ if (dPriv->lastStamp != stamp)
+ i810XMesaWindowMoved( imesa );
+
+ sarea->ctxOwner=me;
+ sarea->ringOwner=me;
+
+
+ _I810RefreshLpRing(imesa, 0);
+
+ if (imesa->dirty)
+ i810EmitHwStateLocked( imesa );
+
+}
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.c b/xc/lib/GL/mesa/src/drv/i810/i810clear.c
new file mode 100644
index 000000000..5ba264059
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810clear.c
@@ -0,0 +1,193 @@
+
+
+#include "types.h"
+#include "vbrender.h"
+#include "i810log.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810dd.h"
+#include "i810clear.h"
+#include "i810state.h"
+#include "i810tris.h"
+
+
+
+/* Clear the depthbuffer. Always uses the auxillary cliprects and
+ * origin from 'dPriv'.
+ */
+static void i810_clear_depthbuffer( GLcontext *ctx,
+ GLboolean all,
+ GLint cx, GLint cy,
+ GLint cwidth, GLint cheight )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLuint zval = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE);
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+/* int _nc = dPriv->numAuxClipRects; */
+/* XF86DRIClipRectPtr box = dPriv->pAuxClipRects; */
+
+ int _nc = imesa->numClipRects;
+ XF86DRIClipRectPtr box = imesa->pClipRects;
+
+ cy = dPriv->h-cy-cheight;
+ cx += dPriv->auxX;
+ cy += dPriv->auxY;
+
+ while (_nc--) {
+ GLint x = box[_nc].x1;
+ GLint y = box[_nc].y1;
+ GLint width = box[_nc].x2 - x;
+ GLint height = box[_nc].y2 - y;
+
+ if (!all) {
+ if (x < cx) width -= cx - x, x = cx;
+ if (y < cy) height -= cy - y, y = cy;
+ if (x + width > cx + cwidth) width = cx + cwidth - x;
+ if (y + height > cy + cheight) height = cy + cheight - y;
+ if (width <= 0) continue;
+ if (height <= 0) continue;
+ }
+
+ if (I810_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "clear depth rect %d,%d %dx%d\n",
+ (int) x, (int) y, (int) width, (int) height);
+
+ {
+ int start = (i810Screen->depthOffset +
+ y * i810Screen->auxPitch +
+ x * 2);
+
+ BEGIN_BATCH(imesa, 6);
+
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
+ OUT_BATCH( BR13_SOLID_PATTERN |
+ (0xF0 << 16) |
+ i810Screen->auxPitch );
+ OUT_BATCH( (height << 16) | (width * 2));
+ OUT_BATCH( start );
+ OUT_BATCH( zval );
+ OUT_BATCH( 0 );
+
+ ADVANCE_BATCH();
+ }
+ }
+}
+
+
+/* Clear the current drawbuffer. Checks 'imesa' to determine which set of
+ * cliprects and origin to use.
+ */
+static void i810_clear_colorbuffer( GLcontext *ctx,
+ GLboolean all,
+ GLint cx, GLint cy,
+ GLint cwidth, GLint cheight )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLushort c = imesa->ClearColor;
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+ int _nc = imesa->numClipRects;
+ XF86DRIClipRectPtr box = imesa->pClipRects;
+
+ cy = dPriv->h-cy-cheight;
+ cx += imesa->drawX;
+ cy += imesa->drawY;
+
+ while (_nc--) {
+ GLint x = box[_nc].x1;
+ GLint y = box[_nc].y1;
+ GLint width = box[_nc].x2 - x;
+ GLint height = box[_nc].y2 - y;
+
+ if (!all) {
+ if (x < cx) width -= cx - x, x = cx;
+ if (y < cy) height -= cy - y, y = cy;
+ if (x + width > cx + cwidth) width = cx + cwidth - x;
+ if (y + height > cy + cheight) height = cy + cheight - y;
+ if (width <= 0) continue;
+ if (height <= 0) continue;
+ }
+
+ if (I810_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "clear color rect %d,%d %dx%d\n",
+ (int) x, (int) y, (int) width, (int) height);
+
+
+ {
+ int start = (imesa->drawOffset +
+ y * i810Screen->auxPitch +
+ x * i810Screen->cpp);
+
+ BEGIN_BATCH( imesa, 6 );
+
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
+ OUT_BATCH( BR13_SOLID_PATTERN |
+ (0xF0 << 16) |
+ i810Screen->auxPitch );
+ OUT_BATCH( (height << 16) | (width * i810Screen->cpp));
+ OUT_BATCH( start );
+ OUT_BATCH( c );
+ OUT_BATCH( 0 );
+
+ ADVANCE_BATCH();
+ }
+ }
+}
+
+
+
+
+/*
+ * i810Clear
+ *
+ * Clear the color and/or depth buffers. If 'all' is GL_TRUE, clear
+ * whole buffer, otherwise clear the region defined by the remaining
+ * parameters.
+ */
+GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint cx, GLint cy, GLint cwidth, GLint cheight )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+ if (I810_DEBUG&DEBUG_VERBOSE_API)
+ fprintf(stderr, "i810Clear( %d, %d, %d, %d, %d )\n",
+ (int)mask, (int)cx, (int)cy, (int)cwidth, (int)cheight );
+
+ LOCK_HARDWARE(imesa);
+
+ {
+ BEGIN_BATCH( imesa, 2 );
+ OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
+ OUT_BATCH( 0 );
+ ADVANCE_BATCH();
+ }
+
+ if (mask & GL_COLOR_BUFFER_BIT) {
+ i810_clear_colorbuffer( ctx, all, cx, cy, cwidth, cheight );
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ }
+
+ if ( (mask & GL_DEPTH_BUFFER_BIT) && ctx->Depth.Mask ) {
+ i810_clear_depthbuffer( ctx, all, cx, cy, cwidth, cheight );
+ mask &= ~GL_DEPTH_BUFFER_BIT;
+ }
+
+ {
+ BEGIN_BATCH( imesa, 2 );
+ OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
+ OUT_BATCH( 0 );
+ ADVANCE_BATCH();
+ }
+
+ UNLOCK_HARDWARE( imesa );
+ return mask;
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.h b/xc/lib/GL/mesa/src/drv/i810/i810clear.h
new file mode 100644
index 000000000..aedbf84d9
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810clear.h
@@ -0,0 +1,7 @@
+#ifndef _I810_CLEAR_H
+#define _I810_CLEAR_H
+
+extern GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.h b/xc/lib/GL/mesa/src/drv/i810/i810context.h
new file mode 100644
index 000000000..9f316f6fd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810context.h
@@ -0,0 +1,190 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+
+#ifndef I810CONTEXT_INC
+#define I810CONTEXT_INC
+
+typedef struct i810_context_t i810Context;
+typedef struct i810_context_t *i810ContextPtr;
+
+#include <X11/Xlibint.h>
+#include "dri_tmm.h"
+#include "dri_mesaint.h"
+#include "dri_mesa.h"
+#include "xmesaP.h"
+
+#include "types.h"
+#include "i810_init.h"
+#include "i810_sarea.h"
+
+#include "i810tex.h"
+#include "i810vb.h"
+
+
+
+#define I810_FALLBACK_TEXTURE 0x1
+#define I810_FALLBACK_BUFFER 0x2
+
+
+
+/* for i810ctx.new_state - manage GL->driver state changes
+ */
+#define I810_NEW_TEXTURE 0x1
+
+/* for i810ctx.dirty - manage driver->hw state changes, including
+ * lost contexts.
+ */
+#define I810_REQUIRE_QUIESCENT 0x1
+#define I810_UPLOAD_TEX0IMAGE 0x2
+#define I810_UPLOAD_TEX1IMAGE 0x4
+#define I810_UPLOAD_CTX 0x8
+#define I810_UPLOAD_BUFFERS 0x10
+#define I810_REFRESH_RING 0x20
+#define I810_EMIT_CLIPRECT 0x40
+
+
+typedef void (*i810_interp_func)( GLfloat t,
+ GLfloat *result,
+ const GLfloat *in,
+ const GLfloat *out );
+
+
+
+struct i810_context_t {
+ GLint refcount;
+
+ GLcontext *glCtx;
+
+ i810TextureObjectPtr CurrentTexObj[2];
+
+ struct i810_texture_object_t TexObjList;
+ struct i810_texture_object_t SwappedOut;
+
+ int TextureMode;
+
+ /* Hardware state
+ */
+ GLuint Setup[I810_CTX_SETUP_SIZE];
+ GLuint BufferSetup[I810_DEST_SETUP_SIZE];
+ GLuint ClipSetup[I810_CLIP_SETUP_SIZE];
+
+
+ /* Support for CVA and the fast paths.
+ */
+ GLuint setupdone;
+ GLuint setupindex;
+ GLuint renderindex;
+ GLuint using_fast_path;
+ i810_interp_func interp;
+
+ /* Shortcircuit some state changes.
+ */
+ points_func PointsFunc;
+ line_func LineFunc;
+ triangle_func TriangleFunc;
+ quad_func QuadFunc;
+
+ /* Manage our own state */
+ GLuint new_state;
+
+ /* Manage hardware state */
+ GLuint dirty;
+ memHeap_t *texHeap;
+
+ /* One of the few bits of hardware state that can't be calculated
+ * completely on the fly:
+ */
+ GLuint LcsCullMode;
+
+ /* Funny mesa mirrors
+ */
+ GLushort MonoColor;
+ GLushort ClearColor;
+
+ /* DRI stuff
+ */
+ GLframebuffer *glBuffer;
+
+ GLuint Fallback;
+ GLuint needClip;
+
+ /* These refer to the current draw (front vs. back) buffer:
+ */
+ int drawOffset; /* draw buffer address in agp space */
+ int drawX; /* origin of drawable in draw buffer */
+ int drawY;
+ GLuint numClipRects; /* cliprects for that buffer */
+ XF86DRIClipRectPtr pClipRects;
+
+
+ int lastSwap;
+ int texAge;
+
+ XF86DRIClipRectRec draw_rect;
+
+ drmContext hHWContext;
+ drmLock *driHwLock;
+ int driFd;
+ Display *display;
+
+ __DRIdrawablePrivate *driDrawable;
+ __DRIscreenPrivate *driScreen;
+ i810ScreenPrivate *i810Screen;
+ I810SAREAPriv *sarea;
+};
+
+
+/* To remove all debugging, make sure I810_DEBUG is defined as a
+ * preprocessor symbol, and equal to zero.
+ */
+#define I810_DEBUG 0
+#ifndef I810_DEBUG
+/* #warning "Debugging enabled - expect reduced performance" */
+extern int I810_DEBUG;
+#endif
+
+#define DEBUG_VERBOSE_2D 0x1
+#define DEBUG_VERBOSE_RING 0x8
+#define DEBUG_VERBOSE_OUTREG 0x10
+#define DEBUG_ALWAYS_SYNC 0x40
+#define DEBUG_VERBOSE_MSG 0x80
+#define DEBUG_NO_OUTRING 0x100
+#define DEBUG_NO_OUTREG 0x200
+#define DEBUG_VERBOSE_API 0x400
+#define DEBUG_VALIDATE_RING 0x800
+#define DEBUG_VERBOSE_LRU 0x1000
+#define DEBUG_VERBOSE_DRI 0x2000
+
+
+
+extern GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr );
+
+extern GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx );
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.c b/xc/lib/GL/mesa/src/drv/i810/i810dd.c
new file mode 100644
index 000000000..17436bf0d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.c
@@ -0,0 +1,146 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+
+#include "types.h"
+#include "vbrender.h"
+
+#include <stdio.h>
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810clear.h"
+#include "i810dd.h"
+#include "i810depth.h"
+#include "i810log.h"
+#include "i810state.h"
+#include "i810span.h"
+#include "i810tex.h"
+#include "i810tris.h"
+#include "i810vb.h"
+#include "i810pipeline.h"
+#include "extensions.h"
+#include "vb.h"
+#include "dd.h"
+
+
+extern int xf86VTSema;
+
+
+/***************************************
+ * Mesa's Driver Functions
+ ***************************************/
+
+
+static const GLubyte *i810DDGetString( GLcontext *ctx, GLenum name )
+{
+ switch (name) {
+ case GL_VENDOR:
+ return "Keith Whitwell, Precision Insight Inc.";
+ case GL_RENDERER:
+ return "DRI-I810";
+ default:
+ return 0;
+ }
+}
+
+static GLint i810GetParameteri(const GLcontext *ctx, GLint param)
+{
+ switch (param) {
+ case DD_HAVE_HARDWARE_FOG:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
+
+static void i810BufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ *width = imesa->driDrawable->w;
+ *height = imesa->driDrawable->h;
+}
+
+
+
+
+void i810DDExtensionsInit( GLcontext *ctx )
+{
+ /* paletted_textures currently doesn't work.
+ */
+ gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" );
+ gl_extensions_disable( ctx, "GL_EXT_paletted_texture" );
+
+ /* we don't support point parameters in hardware yet */
+ gl_extensions_disable( ctx, "GL_EXT_point_parameters" );
+
+ /* The imaging subset of 1.2 isn't supported by any mesa driver.
+ */
+ gl_extensions_disable( ctx, "ARB_imaging" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_minmax" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_subtract" );
+ gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" );
+
+
+ if (0) gl_extensions_disable( ctx, "GL_ARB_multitexture" );
+
+
+ /* We do support tex_env_add, however
+ */
+ gl_extensions_enable( ctx, "GL_EXT_texture_env_add" );
+}
+
+
+static void i810DDFlush( GLcontext *ctx )
+{
+ i810DmaFlush( I810_CONTEXT(ctx) );
+}
+
+static void i810DDFinish( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ LOCK_HARDWARE( imesa );
+ i810DmaFinish( imesa );
+ UNLOCK_HARDWARE( imesa );
+}
+
+
+void i810DDInitDriverFuncs( GLcontext *ctx )
+{
+ ctx->Driver.GetBufferSize = i810BufferSize;
+ ctx->Driver.GetString = i810DDGetString;
+ ctx->Driver.GetParameteri = i810GetParameteri;
+ ctx->Driver.RegisterVB = i810DDRegisterVB;
+ ctx->Driver.UnregisterVB = i810DDUnregisterVB;
+ ctx->Driver.Clear = i810Clear;
+
+
+ ctx->Driver.Flush = i810DDFlush;
+ ctx->Driver.Finish = i810DDFinish;
+
+ ctx->Driver.BuildPrecalcPipeline = i810DDBuildPrecalcPipeline;
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.h b/xc/lib/GL/mesa/src/drv/i810/i810dd.h
new file mode 100644
index 000000000..86a8618d0
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.h
@@ -0,0 +1,33 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+#ifndef I810DD_INC
+#define I810DD_INC
+
+#include "context.h"
+
+void i810DDExtensionsInit( GLcontext *ctx );
+void i810DDInitDriverFuncs( GLcontext *ctx );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810depth.c b/xc/lib/GL/mesa/src/drv/i810/i810depth.c
new file mode 100644
index 000000000..d1aa12711
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810depth.c
@@ -0,0 +1,645 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 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.
+ */
+
+/*
+ * This file has been modified by Wittawat Yamwong for GLX module.
+ */
+
+/*
+ * Depth buffer functions
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdlib.h>
+#include <string.h>
+#include "context.h"
+#include "i810depth.h"
+#include "types.h"
+#include "mm.h"
+#include "i810lib.h"
+#endif
+
+
+
+/*
+ * Return the address of the Z-buffer value for window coordinate (x,y):
+ */
+#define Z_SETUP \
+ i810ContextPtr imesa = I810_CONTEXT(ctx); \
+ __DRIscreenPrivate *sPriv = imesa->driScreen; \
+ i810ScreenPrivate *i810Screen = imesa->i810Screen; \
+ GLdepth *zbstart = (GLdepth *)(sPriv->pFB + i810Screen->depthOffset);\
+ GLint zbpitch = i810Screen->auxPitch
+
+#define Z_ADDRESS( X, Y ) \
+ (zbstart + zbpitch * (Y) + (X))
+
+
+/**********************************************************************/
+/***** Depth Testing Functions *****/
+/**********************************************************************/
+
+
+/*
+ * Depth test horizontal spans of fragments. These functions are called
+ * via ctx->Driver.depth_test_span only.
+ *
+ * Input: n - number of pixels in the span
+ * x, y - location of leftmost pixel in span in window coords
+ * z - array [n] of integer depth values
+ * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
+ * Return: number of pixels which passed depth test
+ */
+
+
+/*
+ * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ */
+static GLuint i810_depth_test_span_generic( GLcontext* ctx,
+ GLuint n, GLint x, GLint y,
+ const GLdepth z[],
+ GLubyte mask[] )
+{
+ Z_SETUP;
+ GLdepth *zptr = Z_ADDRESS( x, y );
+ GLubyte *m = mask;
+ GLuint i;
+ GLuint passed = 0;
+
+ LOCK_HARDWARE(imesa);
+
+ /* switch cases ordered from most frequent to less frequent */
+ switch (ctx->Depth.Func) {
+ case GL_LESS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] < *zptr) {
+ /* pass */
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ /* fail */
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] < *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_LEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] <= *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] <= *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] >= *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] >= *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GREATER:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] > *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] > *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_NOTEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] != *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] != *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_EQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] == *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m =0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] == *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m =0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_ALWAYS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ *zptr = z[i];
+ passed++;
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer or mask */
+ passed = n;
+ }
+ break;
+ case GL_NEVER:
+ for (i=0;i<n;i++) {
+ mask[i] = 0;
+ }
+ break;
+ default:
+ }
+
+ UNLOCK_HARDWARE(imesa);
+
+ return passed;
+}
+
+
+
+
+
+/*
+ * Depth test an array of randomly positioned fragments.
+ */
+
+/*
+ * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ */
+static void i810_depth_test_pixels_generic( GLcontext* ctx,
+ GLuint n,
+ const GLint x[],
+ const GLint y[],
+ const GLdepth z[],
+ GLubyte mask[] )
+{
+ Z_SETUP;
+ register GLdepth *zptr;
+ register GLuint i;
+
+ LOCK_HARDWARE(imesa);
+
+ /* switch cases ordered from most frequent to less frequent */
+ switch (ctx->Depth.Func) {
+ case GL_LESS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] < *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] < *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_LEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] <= *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] <= *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] >= *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] >= *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GREATER:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] > *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] > *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_NOTEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] != *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] != *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_EQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] == *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] == *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_ALWAYS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ *zptr = z[i];
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer or mask */
+ }
+ break;
+ case GL_NEVER:
+ /* depth test never passes */
+ for (i=0;i<n;i++) {
+ mask[i] = 0;
+ }
+ break;
+ default:
+ }
+
+ UNLOCK_HARDWARE(imesa);
+}
+
+
+
+
+
+
+/**********************************************************************/
+/***** Read Depth Buffer *****/
+/**********************************************************************/
+
+
+/*
+ * Return a span of depth values from the depth buffer as floats in [0,1].
+ * This function is only called through Driver.read_depth_span_float()
+ * Input: n - how many pixels
+ * x,y - location of first pixel
+ * Output: depth - the array of depth values
+ */
+static void i810_read_depth_span_float( GLcontext* ctx,
+ GLuint n, GLint x, GLint y,
+ GLfloat depth[] )
+{
+ Z_SETUP;
+ GLdepth *zptr;
+ GLfloat scale;
+ GLuint i;
+
+ LOCK_HARDWARE(imesa);
+
+ scale = 1.0F / DEPTH_SCALE;
+
+ if (ctx->Buffer->Depth) {
+ zptr = Z_ADDRESS( x, y );
+ for (i=0;i<n;i++) {
+ depth[i] = (GLfloat) zptr[i] * scale;
+ }
+ }
+ else {
+ for (i=0;i<n;i++) {
+ depth[i] = 0.0F;
+ }
+ }
+
+ UNLOCK_HARDWARE(imesa);
+}
+
+
+/*
+ * Return a span of depth values from the depth buffer as integers in
+ * [0,MAX_DEPTH].
+ * This function is only called through Driver.read_depth_span_int()
+ * Input: n - how many pixels
+ * x,y - location of first pixel
+ * Output: depth - the array of depth values
+ */
+static void i810_read_depth_span_int( GLcontext* ctx,
+ GLuint n, GLint x, GLint y,
+ GLdepth depth[] )
+{
+ Z_SETUP;
+
+ LOCK_HARDWARE(imesa);
+
+ if (ctx->Buffer->Depth) {
+ GLdepth *zptr = Z_ADDRESS( x, y );
+ MEMCPY( depth, zptr, n * sizeof(GLdepth) );
+ }
+ else {
+ GLuint i;
+ for (i=0;i<n;i++) {
+ depth[i] = 0;
+ }
+ }
+
+ UNLOCK_HARDWARE(imesa);
+}
+
+static void i810_alloc_depth_buffer( GLcontext *ctx )
+{
+}
+
+
+void i810DDInitDepthFuncs( GLcontext *ctx )
+{
+ ctx->Driver.AllocDepthBuffer = i810_alloc_depth_buffer;
+ ctx->Driver.ReadDepthSpanFloat = i810_read_depth_span_float;
+ ctx->Driver.ReadDepthSpanInt = i810_read_depth_span_int;
+ ctx->Driver.DepthTestSpan = i810_depth_test_span_generic;
+ ctx->Driver.DepthTestPixels = i810_depth_test_pixels_generic;
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810depth.h b/xc/lib/GL/mesa/src/drv/i810/i810depth.h
new file mode 100644
index 000000000..f5543b552
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810depth.h
@@ -0,0 +1,37 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 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.
+ */
+
+/*
+ * This file has been modified by Wittawat Yamwong for GLX module.
+ */
+
+
+#ifndef I810DEPTH_INC
+#define I810DEPTH_INC
+
+#include "types.h"
+
+extern void i810DDInitDepthFuncs( GLcontext *ctx );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.c b/xc/lib/GL/mesa/src/drv/i810/i810dma.c
new file mode 100644
index 000000000..a2f0bb3fd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dma.c
@@ -0,0 +1,105 @@
+/* -*- mode: C; c-basic-offset:8 -*- */
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mm.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810state.h"
+#include "i810dma.h"
+
+
+
+
+
+#if 0
+static void mga_vertex_dma_ioctl(mgaContextPtr mmesa)
+{
+ int retcode;
+ int size = MGA_DMA_BUF_SZ;
+ drmDMAReq dma;
+ drmBufPtr buf = mmesa->dma_buffer;
+
+ dma.context = mmesa->hHWContext;
+ dma.send_count = 1;
+ dma.send_list = &buf->idx;
+ dma.send_sizes = &size;
+ dma.flags = DRM_DMA_WAIT;
+ dma.request_count = 0;
+ dma.request_size = 0;
+ dma.request_list = 0;
+ dma.request_sizes = 0;
+
+ if ((retcode = drmDMA(mmesa->driFd, &dma))) {
+ printf("send iload retcode = %d\n", retcode);
+ exit(1);
+ }
+}
+
+
+
+void i810FlushVerticesLocked( i810ContextPtr imesa )
+{
+
+}
+
+
+void i810FlushVertices( i810ContextPtr imesa ) {
+ LOCK_HARDWARE( imesa );
+ i810FlushVerticesLocked( imesa );
+ UNLOCK_HARDWARE( imesa );
+}
+
+#endif
+
+
+/*
+ * i810DmaFinish
+ */
+void i810DmaFinish( i810ContextPtr imesa ) {
+#if I810_USE_BATCH
+#else
+ _I810Sync( imesa );
+#endif
+}
+
+
+
+void i810DmaFlush( i810ContextPtr imesa ) {
+#if I810_USE_BATCH
+#else
+#endif
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.h b/xc/lib/GL/mesa/src/drv/i810/i810dma.h
new file mode 100644
index 000000000..9d472719a
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dma.h
@@ -0,0 +1,186 @@
+/*
+ GLX Hardware Device Driver for Intel i810
+ Copyright (C) 1999 Keith Whitwell <keithw@precisioninsight.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ original by Jeff Hartmann <slicer@ionet.net>
+ 6/16/99: rewrite by John Carmack <johnc@idsoftware.com>
+ Oct 99: port to i180 by Keith Whitwell <keithw@precisioninsight.com>
+*/
+
+#ifndef I810DMA_H
+#define I810DMA_H
+
+#include "i810lib.h"
+#include "mm.h"
+
+/* a flush command will guarantee that all data added to the dma buffer
+is on its way to the card, and will eventually complete with no more
+intervention.
+*/
+void i810DmaFlush( i810ContextPtr imesa );
+
+/* the overflow function is called when a block can't be allocated
+in the current dma buffer. It flushes the current buffer and
+records some information */
+void i810DmaOverflow(int newDwords);
+
+/* a finish command will guarantee that all dma commands have actually
+been consumed by the card. Note that there may still be a couple primitives
+that have not yet been executed out of the internal FIFO, so this does not
+guarantee that the drawing engine is idle. */
+void i810DmaFinish( i810ContextPtr imesa );
+
+
+
+typedef struct {
+ unsigned long Start;
+ unsigned long End;
+ unsigned long Size;
+} I810MemRange;
+
+
+
+typedef struct i810_batch_buffer {
+ I810MemRange mem;
+ char *virtual_start;
+ int head;
+ int space;
+ int additional_space;
+ int texture_age;
+} i810BatchBuffer;
+
+
+
+#define I810_USE_BATCH 0
+#if I810_USE_BATCH
+
+#define BEGIN_BATCH( imesa, n ) \
+ unsigned int outbatch; \
+ volatile char *virt; \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, \
+ "BEGIN_BATCH(%d) in %s\n" \
+ "(spc left %d/%ld, head %x vstart %p start %lx)\n", \
+ n, __FUNCTION__, i810glx.dma_buffer->space, \
+ i810glx.dma_buffer->mem.Size - i810glx.dma_buffer->head, \
+ i810glx.dma_buffer->head, \
+ i810glx.dma_buffer->virtual_start, \
+ i810glx.dma_buffer->mem.Start ); \
+ if (i810glx.dma_buffer->space < n*4) \
+ i810DmaOverflow(n); \
+ outbatch = i810glx.dma_buffer->head; \
+ virt = i810glx.dma_buffer->virtual_start;
+
+
+#define OUT_BATCH(val) { \
+ *(volatile unsigned int *)(virt + outbatch) = val; \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, "OUT_BATCH %x: %x\n", (int)(outbatch/4), (int)(val)); \
+ outbatch += 4; \
+}
+
+
+#define ADVANCE_BATCH() { \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, "ADVANCE_BATCH(%f) in %s\n", \
+ (outbatch - i810glx.dma_buffer->head) / 4.0, \
+ __FUNCTION__); \
+ i810glx.dma_buffer->space -= outbatch - i810glx.dma_buffer->head; \
+ i810glx.dma_buffer->head = outbatch; \
+}
+
+#define FINISH_PRIM()
+
+#else
+
+
+/* As an alternate path to dma, we can export the registers (and hence
+ * ringbuffer) to the client. For security we should alloc these
+ * things in agp memory which isn't exported to the client. But then
+ * again, the client could blit over such things if it wanted to hang
+ * the system.
+ *
+ * Malicious clients aren't really delt with by the DRI.
+ */
+
+
+extern void _I810RefreshLpRing( i810ContextPtr imesa, int update );
+extern int _I810WaitLpRing( i810ContextPtr imesa, int n, int timeout_usec );
+extern int _I810Sync( i810ContextPtr imesa );
+
+
+#define OUT_RING(n) { \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, "OUT_RING %x: %x\n", outring, (int)(n)); \
+ if (!(I810_DEBUG & DEBUG_NO_OUTRING)) { \
+ *(volatile unsigned int *)(virt + outring) = n; \
+ outring += 4; \
+ outring &= ringmask; \
+ } \
+}
+
+#define ADVANCE_LP_RING() { \
+ i810glx.LpRing.tail = outring; \
+ OUTREG(LP_RING + RING_TAIL, outring); \
+}
+
+#define BEGIN_LP_RING(imesa, n) \
+ unsigned int outring, ringmask; \
+ volatile char *virt; \
+ if ((I810_DEBUG&DEBUG_ALWAYS_SYNC) && n>2) _I810Sync( imesa ); \
+ if (i810glx.LpRing.space < n*4) _I810WaitLpRing( imesa, n*4, 0); \
+ i810glx.LpRing.space -= n*4; \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, "BEGIN_LP_RING %d in %s\n", n, __FUNCTION__); \
+ if (I810_DEBUG & DEBUG_VALIDATE_RING) { \
+ CARD32 tail = INREG(LP_RING+RING_TAIL); \
+ if (tail != i810glx.LpRing.tail) { \
+ fprintf(stderr, "tail %x pI810->LpRing.tail %x\n", \
+ (int) tail, (int) i810glx.LpRing.tail); \
+ exit(1); \
+ } \
+ } \
+ i810glx.LpRing.synced = 0; \
+ outring = i810glx.LpRing.tail; \
+ ringmask = i810glx.LpRing.tail_mask; \
+ virt = i810glx.LpRing.virtual_start;
+
+
+#define EXTRAAA \
+
+#define INREG(addr) *(volatile CARD32 *)(i810glx.MMIOBase + (addr))
+#define INREG16(addr) *(volatile CARD16 *)(i810glx.MMIOBase + (addr))
+#define INREG8(addr) *(volatile CARD8 *)(i810glx.MMIOBase + (addr))
+
+#define OUTREG(addr, val) do { \
+ if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) \
+ fprintf(stderr, "OUTREG(%x, %x)\n", addr, val); \
+ if (!(I810_DEBUG&DEBUG_NO_OUTREG)) \
+ *(volatile CARD32 *)(i810glx.MMIOBase + (addr)) = (val); \
+} while (0)
+
+
+#define BEGIN_BATCH(imesa, n) BEGIN_LP_RING(imesa, n)
+#define ADVANCE_BATCH() ADVANCE_LP_RING()
+#define OUT_BATCH(val) OUT_RING(val)
+#define FINISH_PRIM() OUTREG(LP_RING + RING_TAIL, i810glx.LpRing.tail)
+
+#endif
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c b/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c
new file mode 100644
index 000000000..9223060e7
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c
@@ -0,0 +1,530 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+#include <stdio.h>
+
+#include "types.h"
+#include "enums.h"
+#include "cva.h"
+#include "vertices.h"
+
+/* #include "mmath.h" */
+
+#include "i810context.h"
+#include "i810pipeline.h"
+#include "i810tris.h"
+#include "i810state.h"
+#include "i810vb.h"
+
+
+extern void i810DDResizeVB( struct vertex_buffer *VB, GLuint size );
+
+extern void gl_fast_copy_vb( struct vertex_buffer *VB );
+
+struct i810_fast_tab {
+ void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest );
+ void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J );
+};
+
+
+
+
+#define POINT(x) i810_draw_point(imesa, &ivert[x].v, psize)
+#define LINE(x,y) i810_draw_line(imesa, &ivert[x].v, &ivert[y].v, lwidth)
+#define TRI(x,y,z) i810_draw_triangle(imesa, &ivert[x].v, &ivert[y].v, &ivert[z].v)
+
+
+
+
+/* Direct, and no clipping required. I haven't written the clip funcs
+ * yet, so this is only useful for the fast path.
+ */
+#define RENDER_POINTS( start, count ) \
+do { \
+ GLuint e; \
+ for(e=start;e<=count;e++) \
+ POINT(elt[e]); \
+} while (0)
+
+#define RENDER_LINE( i1, i ) \
+do { \
+ GLuint e1 = elt[i1], e = elt[i]; \
+ LINE( e1, e ); \
+} while (0)
+
+
+#define RENDER_TRI( i2, i1, i, pv, parity) \
+do { \
+{ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ if (parity) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \
+ TRI(e2, e1, e); \
+}} while (0)
+
+
+#define RENDER_QUAD( i3, i2, i1, i, pv) \
+do { \
+ GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ TRI(e3, e2, e); \
+ TRI(e2, e1, e); \
+} while (0)
+
+#define LOCAL_VARS \
+ i810VertexPtr ivert = I810_DRIVER_DATA(VB)->verts; \
+ const GLuint *elt = VB->EltPtr->data; \
+ GLcontext *ctx = VB->ctx; \
+ i810ContextPtr imesa = I810_CONTEXT(ctx); \
+ const GLfloat lwidth = ctx->Line.Width; \
+ const GLfloat psize = ctx->Point.Size; \
+ (void) lwidth; (void)psize; (void) ivert;
+
+
+#define TAG(x) x##_i810_smooth_indirect
+#include "render_tmp.h"
+
+
+
+static void i810_render_elements_direct( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLenum prim = ctx->CVA.elt_mode;
+ GLuint nr = VB->EltPtr->count;
+ render_func func = render_tab_i810_smooth_indirect[prim];
+ GLuint p = 0;
+
+ if (imesa->new_state)
+ i810DDUpdateHwState( ctx );
+
+ BEGIN_CLIP_LOOP(imesa)
+ {
+ do {
+ func( VB, 0, nr, 0 );
+ } while (ctx->Driver.MultipassFunc &&
+ ctx->Driver.MultipassFunc( VB, ++p ));
+ }
+ END_CLIP_LOOP(imesa);
+}
+
+
+
+#define NEGATIVE(f) (f < 0)
+#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
+#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) )
+
+
+#define INTERP_RGBA(t, out, a, b) { \
+ int i; \
+ for (i = 0; i < 4; i++) { \
+ GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \
+ GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \
+ GLfloat fo = LINTERP(t, fa, fb); \
+ FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \
+ } \
+}
+
+
+#define CLIP(SGN,V,PLANE) \
+if (mask & PLANE) { \
+ GLuint *indata = inlist[in]; \
+ GLuint *outdata = inlist[in ^= 1]; \
+ GLuint nr = n; \
+ GLfloat *J = verts[indata[nr-1]].f; \
+ GLfloat dpJ = (SGN J[V]) + J[3]; \
+ \
+ inlist[0] = vlist1; \
+ for (i = n = 0 ; i < nr ; i++) { \
+ GLuint elt_i = indata[i]; \
+ GLfloat *I = verts[elt_i].f; \
+ GLfloat dpI = (SGN I[V]) + I[3]; \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t, *in, *out; \
+ \
+ if (NEGATIVE(dpI)) { \
+ t = dpI / (dpI - dpJ); \
+ in = I; \
+ out = J; \
+ } \
+ else \
+ { \
+ t = dpJ / (dpJ - dpI); \
+ in = J; \
+ out = I; \
+ } \
+ \
+ interp(t, O, in, out); \
+ \
+ clipmask[next_vert] = 0; \
+ outdata[n++] = next_vert++; \
+ } \
+ \
+ clipmask[elt_i] |= PLANE; /* don't set up */ \
+ \
+ if (!NEGATIVE(dpI)) { \
+ outdata[n++] = elt_i; \
+ clipmask[elt_i] &= ~PLANE; /* set up after all */ \
+ } \
+ \
+ J = I; \
+ dpJ = dpI; \
+ } \
+ \
+ if (n < 3) return; \
+}
+
+#define LINE_CLIP(x,y,z,w,PLANE) \
+if (mask & PLANE) { \
+ GLfloat dpI = DOT4V(I,x,y,z,w); \
+ GLfloat dpJ = DOT4V(J,x,y,z,w); \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t = dpI / (dpI - dpJ); \
+ \
+ interp(t, O, I, J); \
+ \
+ clipmask[next_vert] = 0; \
+ \
+ if (NEGATIVE(dpI)) { \
+ clipmask[elts[0]] |= PLANE; \
+ I = O; elts[0] = next_vert++; \
+ } else { \
+ clipmask[elts[1]] |= PLANE; \
+ J = O; elts[1] = next_vert++; \
+ } \
+ } \
+ else if (NEGATIVE(dpI)) \
+ return; \
+}
+
+
+static __inline void i810_tri_clip( GLuint **p_elts,
+ i810Vertex *verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ i810_interp_func interp )
+{
+ GLuint *elts = *p_elts;
+ GLuint next_vert = *p_next_vert;
+ GLuint vlist1[VB_MAX_CLIPPED_VERTS];
+ GLuint vlist2[VB_MAX_CLIPPED_VERTS];
+ GLuint *inlist[2];
+ GLuint *out;
+ GLuint in = 0;
+ GLuint n = 3;
+ GLuint i;
+
+ inlist[0] = elts;
+ inlist[1] = vlist2;
+
+ CLIP(-,0,CLIP_RIGHT_BIT);
+ CLIP(+,0,CLIP_LEFT_BIT);
+ CLIP(-,1,CLIP_TOP_BIT);
+ CLIP(+,1,CLIP_BOTTOM_BIT);
+ CLIP(-,2,CLIP_FAR_BIT);
+ CLIP(+,2,CLIP_NEAR_BIT);
+
+ /* Convert the planar polygon to a list of triangles.
+ */
+ out = inlist[in];
+
+ for (i = 2 ; i < n ; i++) {
+ elts[0] = out[0];
+ elts[1] = out[i-1];
+ elts[2] = out[i];
+ elts += 3;
+ }
+
+ *p_next_vert = next_vert;
+ *p_elts = elts;
+}
+
+
+static __inline void i810_line_clip( GLuint **p_elts,
+ i810Vertex *verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ i810_interp_func interp )
+{
+ GLuint *elts = *p_elts;
+ GLfloat *I = verts[elts[0]].f;
+ GLfloat *J = verts[elts[1]].f;
+ GLuint next_vert = *p_next_vert;
+
+ LINE_CLIP(1,0,0,-1,CLIP_LEFT_BIT);
+ LINE_CLIP(-1,0,0,1,CLIP_RIGHT_BIT);
+ LINE_CLIP(0,1,0,-1,CLIP_TOP_BIT);
+ LINE_CLIP(0,-1,0,1,CLIP_BOTTOM_BIT);
+ LINE_CLIP(0,0,1,-1,CLIP_FAR_BIT);
+ LINE_CLIP(0,0,-1,1,CLIP_NEAR_BIT);
+
+ *p_next_vert = next_vert;
+ *p_elts += 2;
+}
+
+
+
+#define CLIP_POINT( e ) \
+ if (mask[e]) \
+ *out++ = e
+
+#define CLIP_LINE( e1, e0 ) \
+do { \
+ GLubyte ormask = mask[e0] | mask[e1]; \
+ out[0] = e1; \
+ out[1] = e0; \
+ out+=2; \
+ if (ormask) { \
+ out-=2; \
+ if (!(mask[e0] & mask[e1])) { \
+ i810_line_clip( &out, verts, mask, &next_vert, ormask, interp); \
+ } \
+ } \
+} while (0)
+
+#define CLIP_TRIANGLE( e2, e1, e0 ) \
+do { \
+ GLubyte ormask; \
+ out[0] = e2; \
+ out[1] = e1; \
+ out[2] = e0; \
+ out += 3; \
+ ormask = mask[e2] | mask[e1] | mask[e0]; \
+ if (ormask) { \
+ out -= 3; \
+ if ( !(mask[e2] & mask[e1] & mask[e0])) { \
+ i810_tri_clip( &out, verts, mask, &next_vert, ormask, interp ); \
+ } \
+ } \
+} while (0)
+
+
+
+
+
+
+/* Build a table of functions to clip each primitive type. These
+ * produce a list of elements in the appropriate 'reduced' primitive,
+ * ie (points, lines, triangles) containing all the clipped and
+ * unclipped primitives from the original list.
+ */
+#define LOCAL_VARS \
+ i810ContextPtr imesa = I810_CONTEXT( VB->ctx ); \
+ GLuint *elt = VB->EltPtr->data; \
+ i810Vertex *verts = I810_DRIVER_DATA(VB)->verts; \
+ GLuint next_vert = I810_DRIVER_DATA(VB)->last_vert; \
+ GLuint *out = I810_DRIVER_DATA(VB)->clipped_elements.data; \
+ GLubyte *mask = VB->ClipMask; \
+ i810_interp_func interp = imesa->interp; \
+ (void) interp; (void) verts;
+
+#define POSTFIX \
+ I810_DRIVER_DATA(VB)->clipped_elements.count = \
+ out - I810_DRIVER_DATA(VB)->clipped_elements.data; \
+ I810_DRIVER_DATA(VB)->last_vert = next_vert;
+
+
+#define INIT(x)
+
+#define RENDER_POINTS(start, count) \
+do { \
+ GLuint i; \
+ for (i = start ; i < count ; i++ ) \
+ CLIP_POINT( elt[i] ); \
+} while (0)
+
+#define RENDER_LINE(i1, i0) \
+ CLIP_LINE(elt[i1], elt[i0])
+
+#define RENDER_TRI(i2, i1, i0, pv, parity) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \
+ if (parity) e2 = elt[i1], e1 = elt[i2]; \
+ CLIP_TRIANGLE( e2, e1, e0 ); \
+} while (0)
+
+#define RENDER_QUAD(i3, i2, i1, i0, pv ) \
+ CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \
+ CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0])
+
+#define TAG(x) i810_clip_##x##_elt
+#include "render_tmp.h"
+
+
+
+static void i810_project_vertices( struct vertex_buffer *VB )
+{
+ i810VertexBufferPtr i810VB = I810_DRIVER_DATA(VB);
+ GLcontext *ctx = VB->ctx;
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ GLfloat m[16];
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX] - .5;
+ m[MAT_SY] = (- mat->m[MAT_SY]);
+ m[MAT_TY] = (- mat->m[MAT_TY]) + I810_CONTEXT(ctx)->driDrawable->h - .5;
+ m[MAT_SZ] = mat->m[MAT_SZ] * (1.0 / 0x10000);
+ m[MAT_TZ] = mat->m[MAT_TZ] * (1.0 / 0x10000);
+
+ gl_project_v16( i810VB->verts[VB->CopyStart].f,
+ i810VB->verts[i810VB->last_vert].f,
+ m,
+ 16 * 4 );
+}
+
+static void i810_project_clipped_vertices( struct vertex_buffer *VB )
+{
+ i810VertexBufferPtr i810VB = I810_DRIVER_DATA(VB);
+ GLcontext *ctx = VB->ctx;
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ GLfloat m[16];
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX] - .5;
+ m[MAT_SY] = (- mat->m[MAT_SY]);
+ m[MAT_TY] = (- mat->m[MAT_TY]) + I810_CONTEXT(ctx)->driDrawable->h - .5;
+ m[MAT_SZ] = mat->m[MAT_SZ] * (1.0 / 0x10000);
+ m[MAT_TZ] = mat->m[MAT_TZ] * (1.0 / 0x10000);
+
+ gl_project_clipped_v16( i810VB->verts[VB->CopyStart].f,
+ i810VB->verts[i810VB->last_vert].f,
+ m,
+ 16 * 4,
+ VB->ClipMask + VB->CopyStart );
+}
+
+
+/* Pack rgba and/or texture into the remaining half of a 32 byte vertex.
+ */
+#define CLIP_UBYTE_COLOR 4
+#define CLIP_UBYTE_B 0
+#define CLIP_UBYTE_G 1
+#define CLIP_UBYTE_R 2
+#define CLIP_UBYTE_A 3
+#define CLIP_S0 6
+#define CLIP_T0 7
+#define CLIP_S1 8
+#define CLIP_T1 9
+
+#define TYPE (0)
+#define TAG(x) x
+#include "i810fasttmp.h"
+
+#define TYPE (I810_RGBA_BIT)
+#define TAG(x) x##_RGBA
+#include "i810fasttmp.h"
+
+#define TYPE (I810_TEX0_BIT)
+#define TAG(x) x##_TEX0
+#include "i810fasttmp.h"
+
+#define TYPE (I810_RGBA_BIT|I810_TEX0_BIT)
+#define TAG(x) x##_RGBA_TEX0
+#include "i810fasttmp.h"
+
+#define TYPE (I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_RGBA_TEX0_TEX1
+#include "i810fasttmp.h"
+
+/* This one *could* get away with sneaking TEX1 into the color and
+ * specular slots, thus fitting inside a cache line. Would be even
+ * better to switch to a smaller vertex.
+ */
+#define TYPE (I810_TEX0_BIT|I810_TEX1_BIT)
+#define TAG(x) x##_TEX0_TEX1
+#include "i810fasttmp.h"
+
+
+/* Very sparsely popluated array - fix the indices.
+ */
+static struct i810_fast_tab i810FastTab[0x80];
+
+void i810DDFastPathInit( void )
+{
+ i810_clip_render_init_elt();
+ render_init_i810_smooth_indirect();
+
+ i810_init_fastpath( &i810FastTab[0] );
+ i810_init_fastpath_RGBA( &i810FastTab[I810_RGBA_BIT] );
+ i810_init_fastpath_TEX0( &i810FastTab[I810_TEX0_BIT] );
+ i810_init_fastpath_RGBA_TEX0( &i810FastTab[I810_RGBA_BIT|I810_TEX0_BIT] );
+ i810_init_fastpath_TEX0_TEX1( &i810FastTab[I810_TEX0_BIT|I810_TEX1_BIT] );
+ i810_init_fastpath_RGBA_TEX0_TEX1( &i810FastTab[I810_RGBA_BIT|I810_TEX0_BIT|
+ I810_TEX1_BIT] );
+}
+
+#define VALID_SETUP (I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
+
+
+void i810DDFastPath( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ GLenum prim = ctx->CVA.elt_mode;
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ struct i810_fast_tab *tab = &i810FastTab[imesa->setupindex & VALID_SETUP];
+ GLuint do_cliptest = 1;
+
+ gl_prepare_arrays_cva( VB ); /* still need this */
+
+ /* Reserve enough space for the pathological case.
+ */
+ if (VB->EltPtr->count * 12 > I810_DRIVER_DATA(VB)->size) {
+ i810DDResizeVB( VB, VB->EltPtr->count * 12 );
+ do_cliptest = 1;
+ }
+
+ tab->build_vertices( VB, do_cliptest ); /* object->clip space */
+
+ if (imesa->new_state)
+ i810DDUpdateHwState( ctx );
+
+ if (VB->ClipOrMask) {
+ if (!VB->ClipAndMask) {
+ render_func *clip = i810_clip_render_tab_elt;
+
+ imesa->interp = tab->interp;
+
+ clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */
+
+ ctx->CVA.elt_mode = gl_reduce_prim[prim];
+ VB->EltPtr = &(I810_DRIVER_DATA(VB)->clipped_elements);
+
+ i810_project_clipped_vertices( VB ); /* clip->device space */
+ i810_render_elements_direct( VB ); /* render using new list */
+ }
+ } else {
+ i810_project_vertices( VB ); /* clip->device space */
+ i810_render_elements_direct( VB ); /* render using orig list */
+ }
+
+ /* This indicates that there is no cached data to reuse.
+ */
+ VB->pipeline->data_valid = 0;
+ VB->pipeline->new_state = 0;
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810fasttmp.h b/xc/lib/GL/mesa/src/drv/i810/i810fasttmp.h
new file mode 100644
index 000000000..115fe7b24
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810fasttmp.h
@@ -0,0 +1,143 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+
+
+/* The first part of setup is applied to all vertices, clipped or
+ * unclipped. This data w!ill be used for clipping, and then all
+ * vertices with a zero clipmask will be projected to device space.
+ *
+ * This could be split into several loops, but - it seems that the
+ * large stride of the fxVertices makes cache issues the big
+ * performance factor, and that multiple loops mean multiple cache
+ * misses....
+ */
+static void TAG(i810_setup_full)( struct vertex_buffer *VB, GLuint do_cliptest )
+{
+ GLcontext *ctx = VB->ctx;
+ const GLfloat * const m = ctx->ModelProjectMatrix.m;
+ GLuint start = VB->CopyStart;
+ GLuint count = VB->Count;
+ GLuint i;
+
+ gl_xform_points3_v16_general(I810_DRIVER_DATA(VB)->verts[start].f,
+ m,
+ VB->ObjPtr->start,
+ VB->ObjPtr->stride,
+ count - start);
+
+ if (do_cliptest)
+ {
+ VB->ClipAndMask = ~0;
+ VB->ClipOrMask = 0;
+ gl_cliptest_points4_v16(I810_DRIVER_DATA(VB)->verts[start].f,
+ I810_DRIVER_DATA(VB)->verts[count].f,
+ &(VB->ClipOrMask),
+ &(VB->ClipAndMask),
+ VB->ClipMask + start);
+ }
+
+ /* These branches are all resolved at compile time. Hopefully all
+ * the pointers are valid addresses even when not enabled.
+ */
+ if (TYPE) {
+ GLubyte *color = VB->ColorPtr->start;
+ GLfloat *tex0_data = VB->TexCoordPtr[0]->start;
+ GLfloat *tex1_data = VB->TexCoordPtr[1]->start;
+
+ GLuint color_stride = VB->ColorPtr->stride;
+ GLuint tex0_stride = VB->TexCoordPtr[0]->stride;
+ GLuint tex1_stride = VB->TexCoordPtr[1]->stride;
+
+ GLfloat *f = I810_DRIVER_DATA(VB)->verts[start].f;
+
+ for (i = start ; i < count ; i++, f += 16) {
+ if (TYPE & I810_RGBA_BIT) {
+ GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR];
+ GLubyte *col = color; color += color_stride;
+ b[CLIP_UBYTE_R] = col[0];
+ b[CLIP_UBYTE_G] = col[1];
+ b[CLIP_UBYTE_B] = col[2];
+ b[CLIP_UBYTE_A] = col[3];
+ }
+ if (TYPE & I810_TEX0_BIT) {
+ f[CLIP_S0] = tex0_data[0];
+ f[CLIP_T0] = tex0_data[1];
+ STRIDE_F(tex0_data, tex0_stride);
+ }
+ if (TYPE & I810_TEX1_BIT) {
+ f[CLIP_S1] = tex1_data[0];
+ f[CLIP_T1] = tex1_data[1];
+ STRIDE_F(tex1_data, tex1_stride);
+ }
+ }
+ }
+
+ I810_DRIVER_DATA(VB)->clipped_elements.count = start;
+ I810_DRIVER_DATA(VB)->last_vert = count;
+}
+
+
+/* Changed to just put the interp func instead of the whole clip
+ * routine into the header. Less code and better chance of doing some
+ * of this stuff in assembly.
+ */
+static void TAG(i810_interp_vert)( GLfloat t,
+ GLfloat *O,
+ const GLfloat *I,
+ const GLfloat *J )
+{
+ O[0] = LINTERP(t, I[0], J[0]);
+ O[1] = LINTERP(t, I[1], J[1]);
+ O[2] = LINTERP(t, I[2], J[2]);
+ O[3] = LINTERP(t, I[3], J[3]);
+
+ if (TYPE & I810_RGBA_BIT) {
+ INTERP_RGBA(t,
+ ((GLubyte *)&(O[4])),
+ ((GLubyte *)&(I[4])),
+ ((GLubyte *)&(J[4])));
+ }
+
+ if (TYPE & I810_TEX0_BIT) {
+ O[6] = LINTERP(t, I[6], J[6]);
+ O[7] = LINTERP(t, I[7], J[7]);
+ }
+
+ if (TYPE & I810_TEX1_BIT) {
+ O[8] = LINTERP(t, I[8], J[8]);
+ O[9] = LINTERP(t, I[9], J[9]);
+ }
+}
+
+
+static void TAG(i810_init_fastpath)( struct i810_fast_tab *tab )
+{
+ tab->interp = TAG(i810_interp_vert);
+ tab->build_vertices = TAG(i810_setup_full);
+}
+
+#undef TYPE
+#undef TAG
+#undef SIZE
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810lib.h b/xc/lib/GL/mesa/src/drv/i810/i810lib.h
new file mode 100644
index 000000000..ad80674f0
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810lib.h
@@ -0,0 +1,130 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ *
+ */
+
+#ifndef I810LIB_INC
+#define I810LIB_INC
+
+#include <stdio.h>
+
+#include "i810context.h"
+#include "mm.h"
+#include "i810log.h"
+
+
+struct i810_mem_range {
+ unsigned long Start;
+ unsigned long End;
+ unsigned long Size;
+};
+
+struct i810_batch_buffer;
+
+struct i810_ring_buffer {
+ int tail_mask;
+ struct i810_mem_range mem;
+ char *virtual_start;
+ int head;
+ int tail;
+ int space;
+ int synced;
+};
+
+typedef struct {
+ /* logging stuff */
+ GLuint logLevel;
+ FILE *logFile;
+
+ /* bookkeeping for texture swaps */
+ GLuint dma_buffer_age;
+ GLuint current_texture_age;
+
+ /* options */
+ GLuint nullprims; /* skip all primitive generation */
+ GLuint boxes; /* draw performance boxes */
+ GLuint noFallback; /* don't fall back to software */
+ GLuint skipDma; /* don't send anything to hardware */
+
+ /* performance counters */
+ GLuint c_setupPointers;
+ GLuint c_triangles;
+ GLuint c_points;
+ GLuint c_lines;
+ GLuint c_drawWaits;
+ GLuint c_textureSwaps;
+ GLuint c_dmaFlush;
+ GLuint c_overflows;
+
+ GLuint c_ringlost;
+ GLuint c_texlost;
+ GLuint c_ctxlost;
+
+ GLuint hardwareWentIdle; /* cleared each swapbuffers, set if a
+ waitfordmacompletion ever exited
+ without having to wait */
+
+ unsigned char *texVirtual;
+
+
+ struct i810_batch_buffer *dma_buffer;
+ struct i810_ring_buffer LpRing;
+ unsigned char *MMIOBase;
+
+} i810Glx_t;
+
+extern i810Glx_t i810glx;
+
+
+#define I810PACKCOLOR1555(r,g,b,a) \
+ ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+
+#define I810PACKCOLOR565(r,g,b) \
+ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define I810PACKCOLOR4444(r,g,b,a) \
+ ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+
+#include "i810_3d_reg.h"
+
+static __inline__ GLuint i810PackColor(GLuint format,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a)
+{
+ switch (format) {
+ case DV_PF_555:
+ return I810PACKCOLOR1555(r,g,b,a);
+ case DV_PF_565:
+ return I810PACKCOLOR565(r,g,b);
+ default:
+ fprintf(stderr, "unknown format %d\n", (int)format);
+ return 0;
+ }
+}
+
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810log.h b/xc/lib/GL/mesa/src/drv/i810/i810log.h
new file mode 100644
index 000000000..707cd618f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810log.h
@@ -0,0 +1,47 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+/* Usage:
+ * - use i810Error for error messages. Always write to X error and log file.
+ * - use i810Msg for debugging. Can be disabled by undefining I810_LOG_ENABLED.
+ */
+
+#ifndef I810LOG_INC
+#define I810LOG_INC
+#include "hwlog.h"
+
+/* Mapping between old function names and new common code: */
+/* (Feel free to replace all i810Msg with hwMsg etc. in all *.c
+ * files, I was to lazy to do this...) */
+#define i810OpenLog(f) hwOpenLog(f,"[i810] ")
+#define i810CloseLog hwCloseLog
+#define i810IsLogReady hwIsLogReady
+#define i810SetLogLevel hwSetLogLevel
+#define i810GetLogLevel hwGetLogLevel
+#define i810Msg hwMsg
+#define i810Error hwError
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
new file mode 100644
index 000000000..fb2d368fe
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
@@ -0,0 +1,112 @@
+/* #include "i810pipeline.h" */
+
+#include <stdio.h>
+#include "i810vb.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810tris.h"
+#include "i810pipeline.h"
+
+#include "fog.h"
+
+static struct gl_pipeline_stage i810_fast_stage = {
+ "I810 fast path",
+ (PIPE_OP_VERT_XFORM|PIPE_OP_RAST_SETUP_0|
+ PIPE_OP_RAST_SETUP_1|PIPE_OP_RENDER),
+ PIPE_PRECALC,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ i810DDFastPath
+};
+
+
+#define ILLEGAL_ENABLES (TEXTURE0_3D| \
+ TEXTURE1_3D| \
+ ENABLE_TEXMAT0 | \
+ ENABLE_TEXMAT1 | \
+ ENABLE_TEXGEN0 | \
+ ENABLE_TEXGEN1 | \
+ ENABLE_USERCLIP | \
+ ENABLE_LIGHT | \
+ ENABLE_FOG)
+
+
+/* The driver gets first shot at building the pipeline - make some
+ * quick tests to see if we can use the fast path.
+ */
+GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ struct gl_pipeline *pipe = &ctx->CVA.pre;
+
+ if (imesa->renderindex == 0 &&
+ (ctx->Enabled & ILLEGAL_ENABLES) == 0 &&
+ (ctx->Array.Flags & (VERT_OBJ_234|
+ VERT_TEX0_4|
+ VERT_TEX1_4|
+ VERT_ELT)) == (VERT_OBJ_23|VERT_ELT))
+ {
+ pipe->stages[0] = &i810_fast_stage;
+ pipe->stages[1] = 0;
+ pipe->new_inputs = ctx->RenderFlags & VERT_DATA;
+ pipe->ops = pipe->stages[0]->ops;
+ imesa->using_fast_path = 1;
+ return 1;
+ }
+
+ if (imesa->using_fast_path)
+ {
+ imesa->using_fast_path = 0;
+ ctx->CVA.VB->ClipOrMask = 0;
+ ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS;
+ ctx->Array.NewArrayState |= ctx->Array.Summary;
+ return 0;
+ }
+
+ return 0;
+}
+
+
+
+GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr )
+{
+ GLuint i, o;
+
+ for (i = o = 0 ; i < nr ; i++) {
+ switch (in[i].ops) {
+
+ case PIPE_OP_RAST_SETUP_0:
+ out[o] = in[i];
+ out[o].cva_state_change = NEW_LIGHTING|NEW_TEXTURING|NEW_RASTER_OPS;
+ out[o].state_change = ~0;
+ out[o].check = i810DDCheckPartialRasterSetup;
+ out[o].run = i810DDPartialRasterSetup;
+ o++;
+ break;
+
+ case PIPE_OP_RAST_SETUP_0|PIPE_OP_RAST_SETUP_1:
+ out[o] = in[i];
+ out[o].run = i810DDDoRasterSetup;
+ o++;
+ break;
+
+ /* Completely replace Mesa's fog processing to generate fog
+ * coordinates instead of messing with colors.
+ */
+ case PIPE_OP_FOG:
+ out[o] = gl_fog_coord_stage;
+ o++;
+ break;
+
+
+ default:
+ out[o++] = in[i];
+ break;
+ }
+ }
+
+ return o;
+}
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h
new file mode 100644
index 000000000..87b95455d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h
@@ -0,0 +1,14 @@
+#ifndef _I810_PIPELINE_H
+#define _I810_PIPELINE_H
+
+extern GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr );
+
+extern GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx );
+
+extern void i810DDFastPath( struct vertex_buffer *VB );
+extern void i810DDFastPathInit( void );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ring.c b/xc/lib/GL/mesa/src/drv/i810/i810ring.c
new file mode 100644
index 000000000..2e5909e9f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810ring.c
@@ -0,0 +1,162 @@
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mm.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810state.h"
+
+
+#include "i810dma.h"
+
+static void
+I810PrintErrorState( void )
+{
+ fprintf(stderr, "pgetbl_ctl: 0x%x pgetbl_err: 0x%x\n",
+ INREG(PGETBL_CTL),
+ INREG(PGE_ERR));
+
+ fprintf(stderr, "ipeir: %x iphdr: %x\n",
+ INREG(IPEIR),
+ INREG(IPEHR));
+
+ fprintf(stderr, "LP ring tail: %x head: %x len: %x start %x\n",
+ INREG(LP_RING + RING_TAIL),
+ INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
+ INREG(LP_RING + RING_LEN),
+ INREG(LP_RING + RING_START));
+
+ fprintf(stderr, "eir: %x esr: %x emr: %x\n",
+ INREG16(EIR),
+ INREG16(ESR),
+ INREG16(EMR));
+
+ fprintf(stderr, "instdone: %x instpm: %x\n",
+ INREG16(INST_DONE),
+ INREG8(INST_PM));
+
+ fprintf(stderr, "memmode: %x instps: %x\n",
+ INREG(MEMMODE),
+ INREG(INST_PS));
+
+ fprintf(stderr, "hwstam: %x ier: %x imr: %x iir: %x\n",
+ INREG16(HWSTAM),
+ INREG16(IER),
+ INREG16(IMR),
+ INREG16(IIR));
+}
+
+
+
+
+static int
+I810USec( void )
+{
+ struct timeval tv;
+ struct timezone tz;
+ gettimeofday( &tv, &tz );
+ return (tv.tv_sec & 2047) * 1000000 + tv.tv_usec;
+}
+
+
+
+void
+_I810RefreshLpRing( i810ContextPtr imesa, int update )
+{
+ struct i810_ring_buffer *ring = &(i810glx.LpRing);
+
+ ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
+ ring->tail = INREG(LP_RING + RING_TAIL);
+ ring->space = ring->head - (ring->tail+8);
+
+ if (ring->space < 0) {
+ ring->space += ring->mem.Size;
+ if (update)
+ imesa->sarea->lastWrap = ++imesa->sarea->ringAge;
+ }
+}
+
+int
+_I810WaitLpRing( i810ContextPtr imesa, int n, int timeout_usec )
+{
+ struct i810_ring_buffer *ring = &(i810glx.LpRing);
+ int iters = 0;
+ int startTime = 0;
+ int curTime = 0;
+
+ if (timeout_usec == 0)
+ timeout_usec = 15000000;
+
+ if (I810_DEBUG & DEBUG_VERBOSE_API)
+ fprintf(stderr, "I810WaitLpRing %d\n", n);
+
+ while (ring->space < n)
+ {
+ int i;
+
+ ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
+ ring->space = ring->head - (ring->tail+8);
+
+ if (ring->space < 0) {
+ imesa->sarea->lastWrap = ++imesa->sarea->ringAge;
+ ring->space += ring->mem.Size;
+ }
+
+ iters++;
+ curTime = I810USec();
+ if ( startTime == 0 || curTime < startTime /*wrap case*/) {
+ startTime = curTime;
+ } else if ( curTime - startTime > timeout_usec ) {
+ I810PrintErrorState();
+ fprintf(stderr, "space: %d wanted %d\n",
+ ring->space, n );
+ UNLOCK_HARDWARE(imesa);
+ exit(1);
+ }
+
+ for (i = 0 ; i < 2000 ; i++)
+ ;
+ }
+
+ return iters;
+}
+
+int
+_I810Sync( i810ContextPtr imesa )
+{
+ int rv;
+
+ if (I810_DEBUG & DEBUG_VERBOSE_API)
+ fprintf(stderr, "I810Sync\n");
+
+ /* Send a flush instruction and then wait till the ring is empty.
+ * This is stronger than waiting for the blitter to finish as it also
+ * flushes the internal graphics caches.
+ */
+ {
+ BEGIN_LP_RING( imesa, 2 );
+ OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH );
+ OUT_RING( 0 ); /* pad to quadword */
+ ADVANCE_LP_RING();
+ }
+
+
+ i810glx.LpRing.synced = 1; /* ?? */
+
+ rv = _I810WaitLpRing( imesa, i810glx.LpRing.mem.Size - 8, 0 );
+ imesa->sarea->lastSync = ++imesa->sarea->ringAge;
+
+ return rv;
+}
+
+
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c
new file mode 100644
index 000000000..5ea27fd84
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810span.c
@@ -0,0 +1,133 @@
+#include "types.h"
+#include "i810dd.h"
+#include "i810lib.h"
+#include "i810dma.h"
+#include "i810log.h"
+#include "i810span.h"
+
+
+#define DBG 0
+
+
+#define LOCAL_VARS \
+ i810ContextPtr imesa = I810_CONTEXT(ctx); \
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
+ __DRIscreenPrivate *sPriv = imesa->driScreen; \
+ i810ScreenPrivate *i810Screen = imesa->i810Screen; \
+ GLuint pitch = i810Screen->auxPitch; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(sPriv->pFB + \
+ imesa->drawOffset + \
+ dPriv->x * 2 + \
+ dPriv->y * pitch)
+
+#define INIT_MONO_PIXEL(p) \
+ GLushort p = I810_CONTEXT( ctx )->MonoColor;
+
+#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), _x1 = minx; \
+ if (_x1 + _n1 > maxx) n1 -= (_x1 + n1 - maxx); \
+ }
+
+#define HW_CLIPLOOP() \
+ do { \
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
+ int _nc = dPriv->numClipRects; \
+ LOCK_HARDWARE(imesa); \
+ if (!i810glx.LpRing.synced) _I810Sync( imesa ); \
+ while (_nc--) { \
+ int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
+ int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
+ int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
+ int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
+
+
+#define HW_ENDCLIPLOOP() \
+ } \
+ UNLOCK_HARDWARE(imesa); \
+ } while (0)
+
+
+
+
+#define Y_FLIP(_y) (height - _y)
+#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 *)(buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 8) & 0xf8; \
+ rgba[1] = (p >> 3) & 0xfc; \
+ rgba[2] = (p << 3) & 0xf8; \
+ rgba[3] = 0; /* or 255? */ \
+} while(0)
+
+#define TAG(x) i810##x##_565
+#include "spantmp.h"
+
+
+
+
+
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
+ ((g & 0xf8) << 3) | \
+ ((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 *)(buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 7) & 0xf8; \
+ rgba[1] = (p >> 3) & 0xf8; \
+ rgba[2] = (p << 3) & 0xf8; \
+ rgba[3] = 0; /* or 255? */ \
+} while(0)
+
+#define TAG(x) i810##x##_555
+#include "spantmp.h"
+
+
+void i810DDInitSpanFuncs( GLcontext *ctx )
+{
+ if (1) {
+ ctx->Driver.WriteRGBASpan = i810WriteRGBASpan_565;
+ ctx->Driver.WriteRGBSpan = i810WriteRGBSpan_565;
+ ctx->Driver.WriteMonoRGBASpan = i810WriteMonoRGBASpan_565;
+ ctx->Driver.WriteRGBAPixels = i810WriteRGBAPixels_565;
+ ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_565;
+ ctx->Driver.ReadRGBASpan = i810ReadRGBASpan_565;
+ ctx->Driver.ReadRGBAPixels = i810ReadRGBAPixels_565;
+ } else {
+ ctx->Driver.WriteRGBASpan = i810WriteRGBASpan_555;
+ ctx->Driver.WriteRGBSpan = i810WriteRGBSpan_555;
+ ctx->Driver.WriteMonoRGBASpan = i810WriteMonoRGBASpan_555;
+ ctx->Driver.WriteRGBAPixels = i810WriteRGBAPixels_555;
+ ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_555;
+ ctx->Driver.ReadRGBASpan = i810ReadRGBASpan_555;
+ ctx->Driver.ReadRGBAPixels = i810ReadRGBAPixels_555;
+ }
+
+ ctx->Driver.WriteCI8Span =NULL;
+ ctx->Driver.WriteCI32Span =NULL;
+ ctx->Driver.WriteMonoCISpan =NULL;
+ ctx->Driver.WriteCI32Pixels =NULL;
+ ctx->Driver.WriteMonoCIPixels =NULL;
+ ctx->Driver.ReadCI32Span =NULL;
+ ctx->Driver.ReadCI32Pixels =NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.h b/xc/lib/GL/mesa/src/drv/i810/i810span.h
new file mode 100644
index 000000000..17a52085b
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810span.h
@@ -0,0 +1,6 @@
+#ifndef _I810_SPAN_H
+#define _I810_SPAN_H
+
+extern void i810DDInitSpanFuncs( GLcontext *ctx );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.c b/xc/lib/GL/mesa/src/drv/i810/i810state.c
new file mode 100644
index 000000000..bc3391e42
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810state.c
@@ -0,0 +1,933 @@
+
+#include <stdio.h>
+
+#include "types.h"
+#include "enums.h"
+#include "pb.h"
+#include "dd.h"
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810dd.h"
+#include "i810context.h"
+#include "i810state.h"
+#include "i810depth.h"
+#include "i810tex.h"
+#include "i810log.h"
+#include "i810vb.h"
+#include "i810tris.h"
+
+
+
+static void i810DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ CARD32 a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF);
+
+ switch (ctx->Color.AlphaFunc) {
+ case GL_NEVER: a |= ZA_ALPHA_NEVER; break;
+ case GL_LESS: a |= ZA_ALPHA_LESS; break;
+ case GL_GEQUAL: a |= ZA_ALPHA_GEQUAL; break;
+ case GL_LEQUAL: a |= ZA_ALPHA_LEQUAL; break;
+ case GL_GREATER: a |= ZA_ALPHA_GREATER; break;
+ case GL_NOTEQUAL: a |= ZA_ALPHA_NOTEQUAL; break;
+ case GL_EQUAL: a |= ZA_ALPHA_EQUAL; break;
+ case GL_ALWAYS: a |= ZA_ALPHA_ALWAYS; break;
+ default: return;
+ }
+
+ a |= ctx->Color.AlphaRef << ZA_ALPHAREF_SHIFT;
+
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK);
+ imesa->Setup[I810_CTXREG_ZA] |= a;
+}
+
+/* This shouldn't get called, as the extension is disabled. However,
+ * there are internal Mesa calls, and rogue use of the api which must be
+ * caught.
+ */
+static void i810DDBlendEquation(GLcontext *ctx, GLenum mode)
+{
+ if (mode != GL_FUNC_ADD_EXT) {
+ ctx->Color.BlendEquation = GL_FUNC_ADD_EXT;
+ i810Error("Unsupported blend equation");
+ exit(1);
+ }
+}
+
+static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint a;
+
+ a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND;
+
+ switch (ctx->Color.BlendSrcRGB) {
+ case GL_ZERO: a |= SDM_SRC_ZERO; break;
+ case GL_SRC_ALPHA: a |= SDM_SRC_SRC_ALPHA; break;
+ case GL_ONE: a |= SDM_SRC_ONE; break;
+ case GL_DST_COLOR: a |= SDM_SRC_DST_COLOR; break;
+ case GL_ONE_MINUS_DST_COLOR: a |= SDM_SRC_INV_DST_COLOR; break;
+ case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_SRC_INV_SRC_ALPHA; break;
+ case GL_DST_ALPHA: a |= SDM_SRC_ONE; break;
+ case GL_ONE_MINUS_DST_ALPHA: a |= SDM_SRC_ZERO; break;
+ case GL_SRC_ALPHA_SATURATE:
+ a |= SDM_SRC_SRC_ALPHA; /* use GFXRENDERSTATE_COLOR_FACTOR ??? */
+ break;
+ default:
+ i810Error("unknown blend source func");
+ exit(1);
+ return;
+ }
+
+ switch (ctx->Color.BlendDstRGB) {
+ case GL_SRC_ALPHA: a |= SDM_DST_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_DST_INV_SRC_ALPHA; break;
+ case GL_ZERO: a |= SDM_DST_ZERO; break;
+ case GL_ONE: a |= SDM_DST_ONE; break;
+ case GL_SRC_COLOR: a |= SDM_DST_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: a |= SDM_DST_INV_SRC_COLOR; break;
+ case GL_DST_ALPHA: a |= SDM_DST_ONE; break;
+ case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break;
+ default:
+ i810Error( "unknown blend dst func");
+ exit(1);
+ return;
+ }
+
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK);
+ imesa->Setup[I810_CTXREG_SDM] |= a;
+}
+
+
+/* Shouldn't be called as the extension is disabled.
+ */
+static void i810DDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
+ GLenum dfactorRGB, GLenum sfactorA,
+ GLenum dfactorA )
+{
+ if (dfactorRGB != dfactorA || sfactorRGB != sfactorA) {
+ gl_error( ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)");
+ }
+
+ i810DDBlendFunc( ctx, sfactorRGB, dfactorRGB );
+}
+
+
+
+static void i810DDDepthFunc(GLcontext *ctx, GLenum func)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ int zmode;
+
+ switch(func) {
+ case GL_NEVER: zmode = LCS_Z_NEVER; break;
+ case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break;
+ case GL_LESS: zmode = LCS_Z_LESS; break;
+ case GL_LEQUAL: zmode = LCS_Z_LEQUAL; break;
+ case GL_EQUAL: zmode = LCS_Z_EQUAL; break;
+ case GL_GREATER: zmode = LCS_Z_GREATER; break;
+ case GL_GEQUAL: zmode = LCS_Z_GEQUAL; break;
+ case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break;
+ default: return;
+ }
+
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_ZMODE | zmode;
+ imesa->dirty |= I810_UPLOAD_CTX;
+}
+
+static void i810DDDepthMask(GLcontext *ctx, GLboolean flag)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE;
+ imesa->Setup[I810_CTXREG_B2] |= B2_UPDATE_ZB_WRITE_ENABLE;
+
+ if (flag)
+ imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE;
+}
+
+
+
+
+
+
+
+
+
+
+/* =============================================================
+ * Hardware clipping
+ */
+
+
+static void i810DDScissor( GLcontext *ctx, GLint x, GLint y,
+ GLsizei w, GLsizei h )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ int x1,x2,y1,y2;
+
+ x1 = ctx->Scissor.X;
+ x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
+ y1 = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height;
+ y2 = dPriv->h - ctx->Scissor.Y - 1;
+
+ if (x1 < 0) x1 = 0;
+ if (y1 < 0) y1 = 0;
+ if (x2 >= dPriv->w) x2 = dPriv->w-1;
+ if (y2 >= dPriv->h) y2 = dPriv->h-1;
+
+ if (x1 > x2 || y1 > y2) {
+ x1 = 0; x2 = 0;
+ y2 = 0; y1 = 1;
+ }
+
+ /* Need to push this into drawing rectangle.
+ */
+#if 0
+ imesa->Setup[I810_CTXREG_SCI0] = GFX_OP_SCISSOR_INFO;
+ imesa->Setup[I810_CTXREG_SCI1] = (y1<<16)|x1;
+ imesa->Setup[I810_CTXREG_SCI2] = (y2<<16)|x2;
+
+
+ /* Need to intersect with cliprects???
+ */
+ imesa->dirty |= I810_UPLOAD_CTX;
+#endif
+
+}
+
+
+static void i810DDDither(GLcontext *ctx, GLboolean enable)
+{
+}
+
+
+static GLboolean i810DDSetBuffer(GLcontext *ctx, GLenum mode )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+
+ fprintf(stderr, "i810DDSetBuffer %s\n", gl_lookup_enum_by_nr( mode ));
+
+ imesa->Fallback &= ~I810_FALLBACK_BUFFER;
+
+ if (mode == GL_FRONT_LEFT)
+ {
+ imesa->drawOffset = imesa->i810Screen->fbOffset;
+ imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset |
+ imesa->i810Screen->auxPitchBits);
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+ i810XMesaSetFrontClipRects( imesa );
+ return GL_TRUE;
+ }
+ else if (mode == GL_BACK_LEFT)
+ {
+ imesa->drawOffset = imesa->i810Screen->backOffset;
+ imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset |
+ imesa->i810Screen->auxPitchBits);
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+ i810XMesaSetBackClipRects( imesa );
+ return GL_TRUE;
+ }
+
+ imesa->Fallback |= I810_FALLBACK_BUFFER;
+ return GL_FALSE;
+}
+
+
+
+static void i810DDSetColor(GLcontext *ctx,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ imesa->MonoColor = i810PackColor( imesa->i810Screen->fbFormat,
+ r, g, b, a );
+}
+
+
+static void i810DDClearColor(GLcontext *ctx,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat,
+ r, g, b, a );
+}
+
+
+/* =============================================================
+ * Culling - the i810 isn't quite as clean here as the rest of
+ * its interfaces, but it's not bad.
+ */
+static void i810DDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint mode = LCS_CULL_BOTH;
+
+ if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
+ mode = LCS_CULL_CW;
+ if (ctx->Polygon.CullFaceMode == GL_FRONT)
+ mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
+ if (ctx->Polygon.FrontFace != GL_CCW)
+ mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
+ }
+
+ imesa->LcsCullMode = mode;
+
+ if (ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON)
+ {
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode);
+ }
+}
+
+
+static void i810DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
+{
+ if (ctx->Polygon.CullFlag) {
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLuint mode = imesa->LcsCullMode;
+
+ if (ctx->PB->primitive != GL_POLYGON)
+ mode = LCS_CULL_DISABLE;
+
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode);
+
+ LOCK_HARDWARE(imesa);
+ i810EmitHwStateLocked( imesa );
+ UNLOCK_HARDWARE(imesa);
+ }
+}
+
+
+
+/* =============================================================
+ * Color masks
+ */
+
+/* Mesa calls this from the wrong place.
+ *
+ * Its a fallback...
+ */
+static GLboolean i810DDColorMask(GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a )
+{
+ return 1;
+}
+
+/* Seperate specular not fully implemented in hardware... Needs
+ * some interaction with material state? Just punt to software
+ * in all cases?
+ */
+static void i810DDLightModelfv(GLcontext *ctx, GLenum pname,
+ const GLfloat *param)
+{
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+ I810_CONTEXT(ctx)->new_state |= I810_NEW_TEXTURE;
+ }
+}
+
+
+
+/* =============================================================
+ * Fog
+ */
+
+static void i810DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ if (pname == GL_FOG_COLOR) {
+ GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
+ ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
+ ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
+
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_FOG] = ((GFX_OP_FOG_COLOR | color) &
+ ~FOG_RESERVED_MASK);
+ }
+}
+
+
+/* =============================================================
+ */
+
+static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ switch(cap) {
+ case GL_ALPHA_TEST:
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE;
+ imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_ALPHA_TEST_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE;
+ break;
+ case GL_BLEND:
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE;
+ imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_BLEND_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE;
+ break;
+ case GL_DEPTH_TEST:
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE;
+ imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_Z_TEST_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE;
+ break;
+ case GL_SCISSOR_TEST:
+#if 0
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_SC] &= ~SC_ENABLE_MASK;
+ imesa->Setup[I810_CTXREG_SC] |= SC_UPDATE_SCISSOR;
+ if (state)
+ imesa->Setup[I810_CTXREG_SC] |= SC_ENABLE;
+#endif
+ break;
+ case GL_FOG:
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE;
+ imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_FOG_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE;
+ break;
+ case GL_CULL_FACE:
+ if (ctx->PB->primitive == GL_POLYGON) {
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_CULL_MODE;
+ if (state)
+ imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode;
+ else
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ }
+ break;
+ case GL_TEXTURE_2D:
+ imesa->new_state |= I810_NEW_TEXTURE;
+ imesa->dirty |= I810_UPLOAD_CTX;
+ if (ctx->Texture.CurrentUnit == 0) {
+ imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE;
+ imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL0_STATE;
+ if (state)
+ imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE;
+ } else {
+ imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE;
+ imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL1_STATE;
+ if (state)
+ imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE;
+ }
+ break;
+ default:
+ ;
+ }
+}
+
+
+
+/* =============================================================
+ */
+
+/* Delightfully few possibilities:
+ */
+void i810DDPrintState( const char *msg, GLuint state )
+{
+ fprintf(stderr, "%s (0x%x): %s\n",
+ msg,
+ (unsigned int) state,
+ (state & I810_NEW_TEXTURE) ? "texture, " : "");
+}
+
+void i810DDUpdateHwState( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ if (imesa->new_state & I810_NEW_TEXTURE)
+ i810UpdateTextureState( ctx );
+
+ imesa->new_state = 0;
+
+ if (imesa->dirty) {
+ LOCK_HARDWARE(imesa);
+ i810EmitHwStateLocked( imesa );
+ UNLOCK_HARDWARE(imesa);
+ }
+}
+
+
+
+/*
+ * i810DmaExecute
+ * Add a block of data to the dma buffer
+ *
+ * -- In ring buffer mode, must be called with lock held, and translates to
+ * OUT_RING rather than outbatch
+ *
+ * -- In dma mode, probably won't be used because state updates will have
+ * to be done via the kernel for security...
+ */
+static void i810DmaExecute( i810ContextPtr imesa,
+ GLuint *code, int dwords, const char *where )
+{
+ if (I810_DEBUG & DEBUG_VERBOSE_RING)
+ fprintf(stderr, "i810DmaExecute (%s)\n", where);
+
+ if (dwords & 1) {
+ i810Error( "Misaligned buffer in i810DmaExecute\n" );
+ exit(1);
+ }
+
+ {
+ int i;
+ BEGIN_BATCH( imesa, dwords);
+
+ for ( i = 0 ; i < dwords ; i++ ) {
+ if (0) fprintf(stderr, "%d: %x\n", i, code[i]);
+ OUT_BATCH( code[i] );
+ }
+
+ ADVANCE_BATCH();
+ }
+}
+
+
+
+void i810EmitScissorValues( i810ContextPtr imesa, int nr, int emit )
+{
+ int x1 = imesa->pClipRects[nr].x1 - imesa->drawX;
+ int y1 = imesa->pClipRects[nr].y1 - imesa->drawY;
+ int x2 = imesa->pClipRects[nr].x2 - imesa->drawX;
+ int y2 = imesa->pClipRects[nr].y2 - imesa->drawY;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_DRI)
+ fprintf(stderr, "i810EmitScissorValues %d,%d - %d,%d\n",
+ x1,y1,x2,y2);
+
+ imesa->ClipSetup[I810_CLIPREG_SCI1] = (x1 | (y1 << 16));
+ imesa->ClipSetup[I810_CLIPREG_SCI2] = (x2 | (y2 << 16));
+ imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR |
+ SC_UPDATE_SCISSOR |
+ SC_ENABLE );
+
+ if (emit)
+ i810DmaExecute( imesa,
+ imesa->ClipSetup, I810_CLIP_SETUP_SIZE, "cliprect" );
+}
+
+void i810EmitDrawingRectangle( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+
+ int x0 = imesa->drawX;
+ int y0 = imesa->drawY;
+ int x1 = x0 + dPriv->w;
+ int y1 = y0 + dPriv->h;
+
+
+ /* Coordinate origin of the window - may be offscreen.
+ */
+ imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) |
+ (((unsigned)x0)&0xFFFF));
+
+
+ /* Clip to screen.
+ */
+ if (x0 < 0) x0 = 0;
+ if (y0 < 0) y0 = 0;
+ if (x1 > i810Screen->width-1) x1 = i810Screen->width-1;
+ if (y1 > i810Screen->height-1) y1 = i810Screen->height-1;
+
+
+ /* Onscreen drawing rectangle.
+ *
+ * TODO: clip again to GL scissor values.
+ */
+ imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0);
+ imesa->BufferSetup[I810_DESTREG_DR3] = ((y1<<16) | x1);
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+}
+
+
+static void i810DDPrintDirty( const char *msg, GLuint state )
+{
+ fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
+ msg,
+ (unsigned int) state,
+ (state & I810_REFRESH_RING) ? "read-lp-ring, " : "",
+ (state & I810_REQUIRE_QUIESCENT) ? "req-quiescent, " : "",
+ (state & I810_UPLOAD_TEX0IMAGE) ? "upload-tex0, " : "",
+ (state & I810_UPLOAD_TEX1IMAGE) ? "upload-tex1, " : "",
+ (state & I810_UPLOAD_CTX) ? "upload-ctx, " : "",
+ (state & I810_UPLOAD_BUFFERS) ? "upload-bufs, " : "",
+ (state & I810_EMIT_CLIPRECT) ? "emit-single-cliprect, " : ""
+ );
+}
+
+
+/* Spew the state onto the ringbuffer and/or texture memory.
+ */
+void i810EmitHwStateLocked( i810ContextPtr imesa )
+{
+ if (I810_DEBUG & DEBUG_VERBOSE_API)
+ i810DDPrintDirty( "i810EmitHwStateLocked", imesa->dirty );
+
+ if (imesa->dirty & I810_REQUIRE_QUIESCENT) {
+ i810glx.c_drawWaits += _I810Sync( imesa );
+ }
+
+ /* TODO: Refine mechanism to be equivalent to UploadSubImage
+ */
+ if ((imesa->dirty & I810_UPLOAD_TEX0IMAGE) && imesa->CurrentTexObj[0])
+ i810UploadTexImages(imesa, imesa->CurrentTexObj[0]);
+
+ if ((imesa->dirty & I810_UPLOAD_TEX1IMAGE) && imesa->CurrentTexObj[1])
+ i810UploadTexImages(imesa, imesa->CurrentTexObj[1]);
+
+ if ((imesa->dirty & I810_UPLOAD_CTX)) {
+ i810DmaExecute( imesa, imesa->Setup, I810_CTX_SETUP_SIZE, "context" );
+
+ if (imesa->CurrentTexObj[0])
+ i810DmaExecute( imesa, imesa->CurrentTexObj[0]->Setup,
+ I810_TEX_SETUP_SIZE, "tex-0");
+
+ if (imesa->CurrentTexObj[1])
+ i810DmaExecute( imesa, imesa->CurrentTexObj[1]->Setup,
+ I810_TEX_SETUP_SIZE, "tex-1");
+ }
+
+ if (imesa->dirty & I810_UPLOAD_BUFFERS)
+ i810DmaExecute( imesa, imesa->BufferSetup,
+ I810_DEST_SETUP_SIZE, "buffers" );
+
+ if (imesa->dirty & I810_EMIT_CLIPRECT)
+ i810DmaExecute( imesa, imesa->ClipSetup,
+ I810_CLIP_SETUP_SIZE, "cliprect" );
+
+ imesa->dirty = 0;
+}
+
+
+void i810DDInitState( i810ContextPtr imesa )
+{
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+
+ memset(imesa->Setup, 0, sizeof(imesa->Setup));
+
+ imesa->Setup[I810_CTXREG_VF] = (GFX_OP_VERTEX_FMT |
+ VF_TEXCOORD_COUNT_2 |
+ VF_SPEC_FOG_ENABLE |
+ VF_RGBA_ENABLE |
+ VF_XYZW);
+
+ imesa->Setup[I810_CTXREG_MT] = (GFX_OP_MAP_TEXELS |
+ MT_UPDATE_TEXEL1_STATE |
+ MT_TEXEL1_COORD1 |
+ MT_TEXEL1_MAP1 |
+ MT_TEXEL1_DISABLE |
+ MT_UPDATE_TEXEL0_STATE |
+ MT_TEXEL0_COORD0 |
+ MT_TEXEL0_MAP0 |
+ MT_TEXEL0_DISABLE);
+
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ITERATED_COLOR |
+ MC_ARG1_DONT_REPLICATE_ALPHA |
+ MC_ARG1_DONT_INVERT |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_ARG2_DONT_REPLICATE_ALPHA |
+ MC_ARG2_DONT_INVERT |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
+
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ONE |
+ MC_ARG1_DONT_REPLICATE_ALPHA |
+ MC_ARG1_DONT_INVERT |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_ARG2_DONT_REPLICATE_ALPHA |
+ MC_ARG2_DONT_INVERT |
+ MC_UPDATE_OP |
+ MC_OP_DISABLE );
+
+
+ imesa->Setup[I810_CTXREG_MC2] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_2 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_CURRENT_COLOR |
+ MC_ARG1_REPLICATE_ALPHA |
+ MC_ARG1_DONT_INVERT |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_ARG2_DONT_REPLICATE_ALPHA |
+ MC_ARG2_DONT_INVERT |
+ MC_UPDATE_OP |
+ MC_OP_DISABLE );
+
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_ARG1_DONT_INVERT |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_ARG2_DONT_INVERT |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_ARG1_DONT_INVERT |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_ARG2_DONT_INVERT |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ imesa->Setup[I810_CTXREG_MA2] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_2 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_ARG1_DONT_INVERT |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_ARG2_DONT_INVERT |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ imesa->Setup[I810_CTXREG_SDM] = ( GFX_OP_SRC_DEST_MONO |
+ SDM_UPDATE_MONO_ENABLE |
+ 0 |
+ SDM_UPDATE_SRC_BLEND |
+ SDM_SRC_ONE |
+ SDM_UPDATE_DST_BLEND |
+ SDM_DST_ZERO );
+
+ /* Use for colormask:
+ */
+ imesa->Setup[I810_CTXREG_CF0] = GFX_OP_COLOR_FACTOR;
+ imesa->Setup[I810_CTXREG_CF1] = 0xffffffff;
+
+ imesa->Setup[I810_CTXREG_ZA] = (GFX_OP_ZBIAS_ALPHAFUNC |
+ ZA_UPDATE_ALPHAFUNC |
+ ZA_ALPHA_ALWAYS |
+ ZA_UPDATE_ZBIAS |
+ 0 |
+ ZA_UPDATE_ALPHAREF |
+ 0x0);
+
+ imesa->Setup[I810_CTXREG_FOG] = (GFX_OP_FOG_COLOR |
+ (0xffffff & ~FOG_RESERVED_MASK));
+
+ /* Choose a pipe
+ */
+ imesa->Setup[I810_CTXREG_B1] = ( GFX_OP_BOOL_1 |
+ B1_UPDATE_SPEC_SETUP_ENABLE |
+ 0 |
+ B1_UPDATE_ALPHA_SETUP_ENABLE |
+ B1_ALPHA_SETUP_ENABLE |
+ B1_UPDATE_CI_KEY_ENABLE |
+ 0 |
+ B1_UPDATE_CHROMAKEY_ENABLE |
+ 0 |
+ B1_UPDATE_Z_BIAS_ENABLE |
+ 0 |
+ B1_UPDATE_SPEC_ENABLE |
+ 0 |
+ B1_UPDATE_FOG_ENABLE |
+ 0 |
+ B1_UPDATE_ALPHA_TEST_ENABLE |
+ 0 |
+ B1_UPDATE_BLEND_ENABLE |
+ 0 |
+ B1_UPDATE_Z_TEST_ENABLE |
+ 0 );
+
+ imesa->Setup[I810_CTXREG_B2] = ( GFX_OP_BOOL_2 |
+ B2_UPDATE_MAP_CACHE_ENABLE |
+ B2_MAP_CACHE_ENABLE |
+ B2_UPDATE_ALPHA_DITHER_ENABLE |
+ 0 |
+ B2_UPDATE_FOG_DITHER_ENABLE |
+ 0 |
+ B2_UPDATE_SPEC_DITHER_ENABLE |
+ 0 |
+ B2_UPDATE_RGB_DITHER_ENABLE |
+ B2_RGB_DITHER_ENABLE |
+ B2_UPDATE_FB_WRITE_ENABLE |
+ B2_FB_WRITE_ENABLE |
+ B2_UPDATE_ZB_WRITE_ENABLE |
+ B2_ZB_WRITE_ENABLE );
+
+ imesa->Setup[I810_CTXREG_LCS] = ( GFX_OP_LINEWIDTH_CULL_SHADE_MODE |
+ LCS_UPDATE_ZMODE |
+ LCS_Z_LESS |
+ LCS_UPDATE_LINEWIDTH |
+ (0x2<<LCS_LINEWIDTH_SHIFT) |
+ LCS_UPDATE_ALPHA_INTERP |
+ LCS_ALPHA_INTERP |
+ LCS_UPDATE_FOG_INTERP |
+ 0 |
+ LCS_UPDATE_SPEC_INTERP |
+ 0 |
+ LCS_UPDATE_RGB_INTERP |
+ LCS_RGB_INTERP |
+ LCS_UPDATE_CULL_MODE |
+ LCS_CULL_DISABLE);
+
+ imesa->LcsCullMode = LCS_CULL_CW;
+
+ imesa->Setup[I810_CTXREG_PV] = ( GFX_OP_PV_RULE |
+ PV_UPDATE_PIXRULE |
+ PV_PIXRULE_ENABLE |
+ PV_UPDATE_LINELIST |
+ PV_LINELIST_PV0 |
+ PV_UPDATE_TRIFAN |
+ PV_TRIFAN_PV0 |
+ PV_UPDATE_TRISTRIP |
+ PV_TRISTRIP_PV0 );
+
+
+ imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE;
+ imesa->Setup[I810_CTXREG_ST1] = 0;
+
+
+
+ imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS |
+ AA_UPDATE_EDGEFLAG |
+ 0 |
+ AA_UPDATE_POLYWIDTH |
+ AA_POLYWIDTH_05 |
+ AA_UPDATE_LINEWIDTH |
+ AA_LINEWIDTH_05 |
+ AA_UPDATE_BB_EXPANSION |
+ 0 |
+ AA_UPDATE_AA_ENABLE |
+ 0 );
+
+
+
+ memset(imesa->ClipSetup, 0, sizeof(imesa->ClipSetup));
+ imesa->ClipSetup[I810_CLIPREG_SCI0] = GFX_OP_SCISSOR_INFO;
+ imesa->ClipSetup[I810_CLIPREG_SCI1] = 0;
+ imesa->ClipSetup[I810_CLIPREG_SCI2] = 0;
+ imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR |
+ SC_UPDATE_SCISSOR |
+ 0 );
+
+ /* This stuff is all invarient as long as we are using
+ * shared back and depth buffers.
+ */
+ memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
+ imesa->drawOffset = i810Screen->backOffset;
+ imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO;
+
+ if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT)
+ imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset |
+ i810Screen->auxPitchBits);
+ else
+ imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset |
+ i810Screen->auxPitchBits);
+
+
+ imesa->BufferSetup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS;
+ imesa->BufferSetup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL |
+ DV_VORG_BIAS_OGL |
+ i810Screen->fbFormat);
+ imesa->BufferSetup[I810_DESTREG_ZB0] = CMD_OP_Z_BUFFER_INFO;
+ imesa->BufferSetup[I810_DESTREG_ZB1] = (i810Screen->depthOffset |
+ i810Screen->auxPitchBits);
+
+ imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO;
+ imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE;
+}
+
+
+#define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
+ NEW_TEXTURE_MATRIX|\
+ NEW_USER_CLIP|NEW_CLIENT_STATE|\
+ NEW_TEXTURE_ENABLE))
+
+void i810DDUpdateState( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+ if (ctx->NewState & INTERESTED) {
+ i810DDChooseRenderState(ctx);
+ i810ChooseRasterSetupFunc(ctx);
+ }
+
+ /* TODO: stop mesa from clobbering these.
+ */
+ ctx->Driver.PointsFunc=imesa->PointsFunc;
+ ctx->Driver.LineFunc=imesa->LineFunc;
+ ctx->Driver.TriangleFunc=imesa->TriangleFunc;
+ ctx->Driver.QuadFunc=imesa->QuadFunc;
+}
+
+
+void i810DDInitStateFuncs(GLcontext *ctx)
+{
+ ctx->Driver.UpdateState = i810DDUpdateState;
+ ctx->Driver.Enable = i810DDEnable;
+ ctx->Driver.LightModelfv = i810DDLightModelfv;
+ ctx->Driver.AlphaFunc = i810DDAlphaFunc;
+ ctx->Driver.BlendEquation = i810DDBlendEquation;
+ ctx->Driver.BlendFunc = i810DDBlendFunc;
+ ctx->Driver.BlendFuncSeparate = i810DDBlendFuncSeparate;
+ ctx->Driver.DepthFunc = i810DDDepthFunc;
+ ctx->Driver.DepthMask = i810DDDepthMask;
+ ctx->Driver.Fogfv = i810DDFogfv;
+ ctx->Driver.Scissor = i810DDScissor;
+ ctx->Driver.CullFace = i810DDCullFaceFrontFace;
+ ctx->Driver.FrontFace = i810DDCullFaceFrontFace;
+ ctx->Driver.ColorMask = i810DDColorMask;
+ ctx->Driver.ReducedPrimitiveChange = i810DDReducedPrimitiveChange;
+ ctx->Driver.RenderStart = i810DDUpdateHwState;
+ ctx->Driver.RenderFinish = 0;
+
+ ctx->Driver.SetBuffer = i810DDSetBuffer;
+ ctx->Driver.Color = i810DDSetColor;
+ ctx->Driver.ClearColor = i810DDClearColor;
+ ctx->Driver.Dither = i810DDDither;
+
+ ctx->Driver.Index = 0;
+ ctx->Driver.ClearIndex = 0;
+ ctx->Driver.IndexMask = 0;
+
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.h b/xc/lib/GL/mesa/src/drv/i810/i810state.h
new file mode 100644
index 000000000..d0551631e
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810state.h
@@ -0,0 +1,13 @@
+#ifndef _I810_STATE_H
+#define _I810_STATE_H
+
+
+extern void i810DDUpdateHwState( GLcontext *ctx );
+extern void i810DDUpdateState( GLcontext *ctx );
+extern void i810DDInitState( i810ContextPtr imesa );
+extern void i810DDInitStateFuncs( GLcontext *ctx );
+
+extern void i810DDPrintState( const char *msg, GLuint state );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810swap.c b/xc/lib/GL/mesa/src/drv/i810/i810swap.c
new file mode 100644
index 000000000..9220ef9f4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810swap.c
@@ -0,0 +1,259 @@
+
+
+#include "types.h"
+#include "vbrender.h"
+#include "i810log.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810dd.h"
+#include "i810dma.h"
+#include "i810state.h"
+#include "i810swap.h"
+#include "i810dma.h"
+
+/*
+ * i810BackToFront
+ *
+ * Blit the visible rectangles from the back buffer to the screen.
+ * Respects the frontbuffer cliprects, and applies the offset
+ * necessary if the backbuffer is positioned elsewhere in the screen.
+ */
+static int i810BackToFront( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+
+
+ /* Use the frontbuffer cliprects:
+ */
+ XF86DRIClipRectPtr pbox = dPriv->pClipRects;
+ int nbox = dPriv->numClipRects;
+
+ if( nbox )
+ {
+ int i;
+ int pitch = i810Screen->auxPitch;
+
+ int dx = dPriv->auxX - dPriv->x;
+ int dy = dPriv->auxY - dPriv->y;
+ int ofs = ( i810Screen->backOffset +
+ dy * i810Screen->auxPitch +
+ dx * i810Screen->cpp);
+
+ unsigned int BR13 = ((i810Screen->fbStride) |
+ (0xCC << 16));
+
+
+ for (i=0; i < nbox; i++, pbox++) {
+ int w = pbox->x2 - pbox->x1;
+ int h = pbox->y2 - pbox->y1;
+
+ int start = ofs + pbox->x1*i810Screen->cpp + pbox->y1*pitch;
+ int dst = pbox->x1*i810Screen->cpp + pbox->y1*i810Screen->fbStride;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "i810BackToFront %d,%d-%dx%d\n",
+ pbox->x1,pbox->y1,w,h);
+
+ {
+ BEGIN_BATCH( imesa, 6 );
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
+ OUT_BATCH( BR13 ); /* dest pitch, rop */
+
+ OUT_BATCH( (h << 16) | (w * i810Screen->cpp));
+ OUT_BATCH( dst );
+
+ OUT_BATCH( pitch ); /* src pitch */
+ OUT_BATCH( start );
+ ADVANCE_BATCH();
+ }
+ }
+ }
+
+ return Success;
+}
+
+
+/*
+ * ClearBox
+ *
+ * Add hardware commands to draw a filled box for the debugging
+ * display. These are drawn into the current drawbuffer, so should
+ * work with both front and backbuffer rendering. (However, it
+ * is only ever called on swapbuffer - ie backbuffer rendering).
+ */
+static void ClearBox( i810ContextPtr imesa,
+ int cx, int cy, int cw, int ch,
+ int r, int g, int b )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+
+ int _nc = imesa->numClipRects;
+
+ while (_nc--) {
+ int x1 = cx + dPriv->x;
+ int y1 = cy + dPriv->y;
+ int x2 = x1 + cw;
+ int y2 = y1 + ch;
+
+ if (imesa->needClip) {
+ int rx1 = imesa->pClipRects[_nc].x1;
+ int ry1 = imesa->pClipRects[_nc].y1;
+ int rx2 = imesa->pClipRects[_nc].x2;
+ int ry2 = imesa->pClipRects[_nc].y2;
+
+
+ if (x2 < rx1) continue;
+ if (y2 < ry1) continue;
+ if (x1 > rx2) continue;
+ if (y1 > ry2) continue;
+ if (x1 < rx1) x1 = rx1;
+ if (y1 < ry1) y1 = ry1;
+ if (x2 > rx2) x2 = rx2;
+ if (y2 > ry2) y2 = ry2;
+ }
+
+
+ {
+ int start = (imesa->drawOffset +
+ y1 * i810Screen->auxPitch +
+ x1 * i810Screen->cpp);
+
+ BEGIN_BATCH( imesa, 6 );
+
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
+ OUT_BATCH( BR13_SOLID_PATTERN |
+ (0xF0 << 16) |
+ i810Screen->auxPitch );
+ OUT_BATCH( ((y2-y1) << 16) | ((x2-x1) * i810Screen->cpp));
+ OUT_BATCH( start );
+ OUT_BATCH( i810PackColor( i810Screen->fbFormat, r, g, b, 0 ) );
+ OUT_BATCH( 0 );
+
+ if (I810_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "box %d,%x %d,%d col %x (%d,%d,%d)\n",
+ (int)x1,(int)y1, (int)x2,(int)y2,
+ (int)i810PackColor( i810Screen->fbFormat, r, g, b, 0 ),
+ (int)r, (int)g, (int)b);
+
+ ADVANCE_BATCH();
+ }
+ }
+}
+
+
+/*
+ * performanceBoxes
+ * Draw some small boxesin the corner of the buffer
+ * based on some performance information
+ */
+static void i810PerformanceBoxes( i810ContextPtr imesa ) {
+
+
+ /* draw a box to show we are active, so if it is't seen it means
+ that it is completely software based. Purple is traditional for
+ direct rendering */
+ ClearBox( imesa, 4, 4, 8, 8, 255, 0, 255 );
+
+ /* draw a red box if we had to wait for drawing to complete
+ (software render or texture swap) */
+ if ( i810glx.c_drawWaits ) {
+ ClearBox( imesa, 16, 4, 8, 8, 255, 0, 0 );
+ i810glx.c_drawWaits = 0;
+ }
+
+ /* draw a blue box if the 3d context was lost
+ */
+ if ( i810glx.c_ctxlost ) {
+ ClearBox( imesa, 28, 4, 8, 8, 0, 0, 255 );
+ i810glx.c_ctxlost = 0;
+ }
+
+ /* draw an orange box if texture state was stomped */
+ if ( i810glx.c_texlost ) {
+ ClearBox( imesa, 40, 4, 8, 8, 255, 128, 0 );
+ i810glx.c_texlost = 0;
+ }
+
+ /* draw a yellow box if textures were swapped */
+ if ( i810glx.c_textureSwaps ) {
+ ClearBox( imesa, 56, 4, 8, 8, 255, 255, 0 );
+ i810glx.c_textureSwaps = 0;
+ }
+
+ /* draw a green box if we had to wait for dma to complete (full utilization)
+ on the previous frame */
+ if ( !i810glx.hardwareWentIdle ) {
+ ClearBox( imesa, 72, 4, 8, 8, 0, 255, 0 );
+ }
+ i810glx.hardwareWentIdle = 0;
+
+#if 0
+ /* show buffer utilization */
+ if ( i810glx.c_dmaFlush > 1 ) {
+ /* draw a solid bar if we flushed more than one buffer */
+ ClearBox( imesa, 4, 16, 252, 4, 255, 32, 32 );
+ } else {
+ /* draw bars to represent the utilization of primary and
+ secondary buffers */
+ ClearBox( imesa, 4, 16, 252, 4, 32, 32, 32 );
+ t = i810glx.dma_buffer->mem.Size;
+ w = 252 * i810glx.dma_buffer->head / t;
+ if ( w < 1 ) {
+ w = 1;
+ }
+ ClearBox( imesa, 4, 16, w, 4, 196, 128, 128 );
+ }
+#endif
+
+ i810glx.c_dmaFlush = 0;
+}
+
+
+static void i810SendDmaFlush( i810ContextPtr imesa )
+{
+ BEGIN_BATCH( imesa, 2 );
+ OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
+ OUT_BATCH( 0 );
+ ADVANCE_BATCH();
+}
+
+void i810SwapBuffers( i810ContextPtr imesa )
+{
+ if (I810_DEBUG & DEBUG_VERBOSE_API)
+ fprintf(stderr, "i810SwapBuffers()\n");
+
+ LOCK_HARDWARE( imesa );
+ i810SendDmaFlush( imesa );
+ if ( i810glx.boxes )
+ i810PerformanceBoxes( imesa );
+ i810BackToFront( imesa );
+
+ /* Check if we are emitting thousands of tiny frames, and if so
+ * throttle them. Would be better to simply go to sleep until
+ * our stuff had cleared, rather than polling. A dma solution
+ * should provide for this.
+ */
+ if (imesa->lastSwap >= imesa->sarea->lastWrap &&
+ imesa->lastSwap >= imesa->sarea->lastSync) {
+
+ if (I810_DEBUG & DEBUG_VERBOSE_API)
+ fprintf(stderr, ".");
+
+ _I810Sync( imesa );
+ }
+
+ imesa->lastSwap = imesa->sarea->lastSync;
+ if (imesa->sarea->lastWrap > imesa->lastSwap)
+ imesa->lastSwap = imesa->sarea->lastWrap;
+
+
+ UNLOCK_HARDWARE( imesa );
+
+/* XSync(imesa->display, 0); */
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810swap.h b/xc/lib/GL/mesa/src/drv/i810/i810swap.h
new file mode 100644
index 000000000..1657a717d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810swap.h
@@ -0,0 +1,6 @@
+#ifndef I810_SWAP_H
+#define I810_SWAP_H
+
+extern void i810SwapBuffers( i810ContextPtr imesa );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c
new file mode 100644
index 000000000..039c0af59
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c
@@ -0,0 +1,1247 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <GL/gl.h>
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810tex.h"
+#include "i810log.h"
+#include "simple_list.h"
+#include "enums.h"
+
+static void i810SetTexWrapping(i810TextureObjectPtr tex, GLenum s, GLenum t)
+{
+ unsigned int val = tex->Setup[I810_TEXREG_MCS];
+
+ val &= ~(MCS_U_STATE_MASK|MCS_V_STATE_MASK);
+ val |= (MCS_U_WRAP|MCS_V_WRAP);
+
+ if (s != GL_REPEAT)
+ val ^= (MCS_U_WRAP^MCS_U_CLAMP);
+
+ if (t != GL_REPEAT)
+ val ^= (MCS_V_WRAP^MCS_V_CLAMP);
+
+ tex->Setup[I810_TEXREG_MCS] = val;
+}
+
+static void i810SetTexFilter(i810TextureObjectPtr t, GLenum minf, GLenum magf)
+{
+ GLuint LastLevel;
+
+ switch (minf) {
+ case GL_NEAREST:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_NEAREST | MF_MIP_NONE);
+ break;
+ case GL_LINEAR:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_LINEAR | MF_MIP_NONE);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_NEAREST | MF_MIP_NEAREST);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_LINEAR | MF_MIP_NEAREST);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_NEAREST | MF_MIP_DITHER );
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MIN_MASK | MF_MIP_MASK,
+ MF_MIN_LINEAR | MF_MIP_DITHER );
+ break;
+ default:
+ i810Error("i810SetTexFilter(): not supported min. filter %d\n",(int)minf);
+ break;
+ }
+
+ switch (magf) {
+ case GL_NEAREST:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MAG_MASK,MF_MAG_NEAREST);
+ break;
+ case GL_LINEAR:
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MF],
+ MF_MAG_MASK,MF_MAG_LINEAR);
+ break;
+ default:
+ i810Error("i810SetTexFilter(): not supported mag. filter %d\n",(int)magf);
+ break;
+ }
+
+
+ if (t->globj->MinFilter != GL_NEAREST &&
+ t->globj->MinFilter != GL_LINEAR) {
+ LastLevel = t->max_level;
+ } else {
+ LastLevel = t->min_level;
+ }
+
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MLL],
+ MLL_MAX_MIP_MASK,
+ (t->min_level << (MLL_MAX_MIP_SHIFT+4)));
+
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MLL],
+ MLL_MIN_MIP_MASK,
+ (LastLevel << MLL_MIN_MIP_SHIFT));
+
+ /* See OpenGL 1.2 specification */
+ if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST ||
+ minf == GL_NEAREST_MIPMAP_LINEAR))
+ {
+ /* c = 0.5 */
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MLC],
+ MLC_LOD_BIAS_MASK,
+ 0x10);
+ } else {
+ /* c = 0 */
+ I810_SET_FIELD(t->Setup[I810_TEXREG_MLC],
+ MLC_LOD_BIAS_MASK,
+ 0x0);
+ }
+}
+
+
+/* Need a fallback ?
+ */
+static void i810SetTexBorderColor(i810TextureObjectPtr t, GLubyte color[4])
+{
+/* t->Setup[I810_TEXREG_TEXBORDERCOL] = */
+/* I810PACKCOLOR8888(color[0],color[1],color[2],color[3]); */
+}
+
+
+
+static void ReplicateMesaTexState(i810TextureObjectPtr t,
+ struct gl_texture_object *mesatex)
+{
+ i810SetTexWrapping(t,mesatex->WrapS,mesatex->WrapT);
+ i810SetTexFilter(t,mesatex->MinFilter,mesatex->MagFilter);
+ i810SetTexBorderColor(t,mesatex->BorderColor);
+}
+
+static i810TextureObjectPtr i810CreateTexObj(i810ContextPtr imesa,
+ struct gl_texture_object *tObj)
+{
+ i810TextureObjectPtr t;
+ GLuint height, width, pitch, i, textureFormat, log_pitch;
+ struct gl_texture_image *image;
+
+ image = tObj->Image[ 0 ];
+ if ( !image ) {
+ fprintf(stderr, "no image at level zero - not creating texobj\n");
+ return 0;
+ }
+
+ t = (i810TextureObjectPtr) calloc(1,sizeof(*t));
+ if (!t)
+ return 0;
+
+ switch( image->Format ) {
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ t->texelBytes = 2;
+ textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_RGBA:
+ t->texelBytes = 2;
+ textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB4444;
+ break;
+ case GL_COLOR_INDEX:
+ textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444;
+ t->texelBytes = 1;
+ break;
+ default:
+ i810Error( "i810CreateTexObj: bad image->Format\n" );
+ free( t );
+ return 0;
+ }
+
+
+ /* Figure out the size now (and count the levels). Upload won't be done
+ * until later.
+ */
+ width = image->Width * t->texelBytes;
+ for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
+ log_pitch++;
+
+ t->dirty_images = 0;
+
+ for ( height = i = 0 ; i < I810_TEX_MAXLEVELS && tObj->Image[i] ; i++ ) {
+ t->image[i].image = tObj->Image[i];
+ t->image[i].offset = height * pitch;
+ t->image[i].internalFormat = image->Format;
+ t->dirty_images |= (1<<i);
+ height += t->image[i].image->Height;
+ }
+
+ t->Pitch = pitch;
+ t->totalSize = height*pitch;
+ t->max_level = i-1;
+ t->min_level = 0;
+ t->globj = tObj;
+ t->age = 0;
+
+ t->Setup[I810_TEXREG_MI0] = GFX_OP_MAP_INFO;
+
+ t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 |
+ textureFormat |
+ log_pitch);
+
+ t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_LOG2 |
+ (image->HeightLog2 << 16) |
+ (image->WidthLog2));
+
+ t->Setup[I810_TEXREG_MI3] = 0;
+
+ t->Setup[I810_TEXREG_MLC] = (GFX_OP_MAP_LOD_CTL |
+ MLC_MAP_0 |
+ MLC_DITHER_WEIGHT_FULL |
+ MLC_UPDATE_LOD_BIAS |
+ 0x0);
+
+ t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS |
+ MLL_MAP_0 |
+ MLL_UPDATE_MAX_MIP |
+ (t->min_level << MLL_MAX_MIP_SHIFT) |
+ MLL_UPDATE_MIN_MIP |
+ t->max_level);
+
+ /* I think this is context state, really.
+ */
+ t->Setup[I810_TEXREG_MCS] = (GFX_OP_MAP_COORD_SETS |
+ MCS_COORD_0 |
+ MCS_UPDATE_NORMALIZED |
+ MCS_NORMALIZED_COORDS |
+ MCS_UPDATE_V_STATE |
+ MCS_V_WRAP |
+ MCS_UPDATE_U_STATE |
+ MCS_U_WRAP);
+
+ t->Setup[I810_TEXREG_MF] = (GFX_OP_MAP_FILTER |
+ MF_MAP_0 |
+ MF_UPDATE_ANISOTROPIC |
+ 0 |
+ MF_UPDATE_MIP_FILTER |
+ MF_MIP_NEAREST |
+ MF_UPDATE_MAG_FILTER |
+ MF_MAG_NEAREST |
+ MF_UPDATE_MIN_FILTER |
+ MF_MIN_NEAREST);
+
+ t->current_unit = 0;
+
+ ReplicateMesaTexState(t,tObj);
+ tObj->DriverData = t;
+ imesa->dirty |= I810_UPLOAD_CTX;
+ make_empty_list( t );
+ return t;
+}
+
+void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t)
+{
+ int i;
+ if (!t) return;
+
+ /* This is sad - need to sync *in case* we upload a texture
+ * to this newly free memory...
+ */
+ if (t->MemBlock) {
+ imesa->dirty |= I810_REQUIRE_QUIESCENT;
+ mmFreeMem(t->MemBlock);
+ t->MemBlock = 0;
+ }
+
+ if (t->globj)
+ t->globj->DriverData = 0;
+
+ for ( i = 0 ; i < 2 ; i++ )
+ if ( imesa->CurrentTexObj[i] == t )
+ imesa->CurrentTexObj[i] = 0;
+
+ remove_from_list(t);
+ free(t);
+}
+
+
+static void i810SwapOutTexObj(i810ContextPtr imesa, i810TextureObjectPtr t)
+{
+ if (t->MemBlock) {
+ imesa->dirty |= I810_REQUIRE_QUIESCENT;
+ mmFreeMem(t->MemBlock);
+ t->MemBlock = 0;
+ }
+
+ t->dirty_images = ~0;
+ move_to_tail(&(imesa->SwappedOut), t);
+}
+
+
+
+/* Upload an image from mesa's internal copy.
+ */
+static void i810UploadTexLevel( i810TextureObjectPtr t, int level )
+{
+ const struct gl_texture_image *image = t->image[level].image;
+ int i,j;
+
+ if (I810_DEBUG & DEBUG_VERBOSE_LRU)
+ fprintf(stderr, "i810UploadTexLevel %d, BufAddr %p offset %x\n",
+ level, t->BufAddr, t->image[level].offset);
+
+ /* Need triangle (rather than pixel) fallbacks to simulate this using
+ * normal textured triangles.
+ *
+ * DO THIS IN DRIVER STATE MANAGMENT, not hardware state.
+ *
+ if (image->Border != 0)
+ i810Error("Not supported texture border %d.\n", (int) image->Border);
+ */
+
+ switch (t->image[level].internalFormat) {
+ case GL_RGB:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyRGB: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR565(src[0],src[1],src[2]);
+ src += 3;
+ }
+ }
+ }
+ break;
+
+ case GL_RGBA:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyRGBA: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR4444(src[0],src[1],src[2],src[3]);
+ src += 4;
+ }
+ }
+ }
+ break;
+
+ case GL_LUMINANCE:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyL: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR565(src[0],src[0],src[0]);
+ src ++;
+ }
+ }
+ }
+ break;
+
+ case GL_INTENSITY:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ int i;
+ i810Msg(10," CopyI: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR4444(src[0],src[0],src[0],src[0]);
+ src ++;
+ }
+ }
+ }
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyLA: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR4444(src[0],src[0],src[0],src[1]);
+ src += 2;
+ }
+ }
+ }
+ break;
+
+ /* TODO: Translate color indices *now*:
+ */
+ case GL_COLOR_INDEX:
+ {
+ GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyIndex %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = src[0];
+ src += 1;
+ }
+ }
+ }
+ break;
+
+ default:
+ i810Error("Not supported texture format %d\n",(int)image->Format);
+ exit(1);
+ }
+}
+
+
+
+void i810PrintLocalLRU( i810ContextPtr imesa )
+{
+ i810TextureObjectPtr t;
+ int sz = 1 << (imesa->i810Screen->logTextureGranularity);
+
+ foreach( t, &imesa->TexObjList ) {
+ if (!t->globj)
+ fprintf(stderr, "Placeholder %d at %x sz %x\n",
+ t->MemBlock->ofs / sz,
+ t->MemBlock->ofs,
+ t->MemBlock->size);
+ }
+}
+
+void i810PrintGlobalLRU( i810ContextPtr imesa )
+{
+ int i, j;
+ i810TexRegion *list = imesa->sarea->texList;
+
+ for (i = 0, j = I810_NR_TEX_REGIONS ; i < I810_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 == I810_NR_TEX_REGIONS) break;
+ }
+
+ if (j != I810_NR_TEX_REGIONS)
+ fprintf(stderr, "Loop detected in global LRU\n");
+}
+
+
+void i810ResetGlobalLRU( i810ContextPtr imesa )
+{
+ i810TexRegion *list = imesa->sarea->texList;
+ int sz = 1 << imesa->i810Screen->logTextureGranularity;
+ int i;
+
+ /* (Re)initialize the global circular LRU list. The last element
+ * in the array (I810_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 < imesa->i810Screen->textureSize ; i++) {
+ list[i].prev = i-1;
+ list[i].next = i+1;
+ list[i].age = 0;
+ }
+
+ i--;
+ list[0].prev = I810_NR_TEX_REGIONS;
+ list[i].prev = i-1;
+ list[i].next = I810_NR_TEX_REGIONS;
+ list[I810_NR_TEX_REGIONS].prev = i;
+ list[I810_NR_TEX_REGIONS].next = 0;
+ imesa->sarea->texAge = 0;
+}
+
+
+static void i810UpdateTexLRU( i810ContextPtr imesa, i810TextureObjectPtr t )
+{
+ int i;
+ int logsz = imesa->i810Screen->logTextureGranularity;
+ int start = t->MemBlock->ofs >> logsz;
+ int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
+ i810TexRegion *list = imesa->sarea->texList;
+
+ imesa->texAge = ++imesa->sarea->texAge;
+
+ /* Update our local LRU
+ */
+ move_to_head( &(imesa->TexObjList), t );
+
+ /* Update the global LRU
+ */
+ for (i = start ; i <= end ; i++) {
+
+ list[i].in_use = 1;
+ list[i].age = imesa->texAge;
+
+ /* 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 = I810_NR_TEX_REGIONS;
+ list[i].next = list[I810_NR_TEX_REGIONS].next;
+ list[(unsigned)list[I810_NR_TEX_REGIONS].next].prev = i;
+ list[I810_NR_TEX_REGIONS].next = i;
+ }
+}
+
+
+/* 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.
+ */
+void i810TexturesGone( i810ContextPtr imesa,
+ GLuint offset,
+ GLuint size,
+ GLuint in_use )
+{
+ i810TextureObjectPtr t, tmp;
+
+ foreach_s ( t, tmp, &imesa->TexObjList ) {
+
+ 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 == imesa->CurrentTexObj[0] || t == imesa->CurrentTexObj[1])
+ i810SwapOutTexObj( imesa, t );
+ else
+ i810DestroyTexObj( imesa, t );
+ }
+
+
+ if (in_use) {
+ t = (i810TextureObjectPtr) calloc(1,sizeof(*t));
+ if (!t) return;
+
+ t->MemBlock = mmAllocMem( imesa->texHeap, size, 0, offset);
+ insert_at_head( &imesa->TexObjList, t );
+ }
+}
+
+
+
+
+
+/* This is called with the lock held. May have to eject our own and/or
+ * other client's texture objects to make room for the upload.
+ */
+int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t )
+{
+ int i;
+ int ofs;
+ i810glx.c_textureSwaps++;
+
+ /* Do we need to eject LRU texture objects?
+ */
+ if (!t->MemBlock) {
+ while (1)
+ {
+ t->MemBlock = mmAllocMem( imesa->texHeap, t->totalSize, 12, 0 );
+ if (t->MemBlock)
+ break;
+
+ if (imesa->TexObjList.prev == &(imesa->TexObjList)) {
+ fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
+ mmDumpMemInfo( imesa->texHeap );
+ return -1;
+ }
+
+ i810DestroyTexObj( imesa, imesa->TexObjList.prev );
+ }
+
+ ofs = t->MemBlock->ofs;
+ t->Setup[I810_TEXREG_MI3] = imesa->i810Screen->textureOffset + ofs;
+ t->BufAddr = i810glx.texVirtual + ofs;
+ imesa->dirty |= I810_UPLOAD_CTX;
+ }
+
+ /* Let the world know we've used this memory recently.
+ */
+ i810UpdateTexLRU( imesa, t );
+
+ if (t->dirty_images) {
+ if (I810_DEBUG & DEBUG_VERBOSE_LRU)
+ fprintf(stderr, "*");
+
+ for (i = t->min_level ; i <= t->max_level ; i++)
+ if (t->dirty_images & (1<<i))
+ i810UploadTexLevel( t, i );
+ }
+
+
+ t->dirty_images = 0;
+ return 0;
+}
+
+static void i810TexSetUnit( i810TextureObjectPtr t, GLuint unit )
+{
+ if (t->current_unit == unit) return;
+
+ t->Setup[I810_TEXREG_MI1] ^= (MI1_MAP_0 ^ MI1_MAP_1);
+ t->Setup[I810_TEXREG_MLC] ^= (MLC_MAP_0 ^ MLC_MAP_1);
+ t->Setup[I810_TEXREG_MLL] ^= (MLL_MAP_0 ^ MLL_MAP_1);
+ t->Setup[I810_TEXREG_MCS] ^= (MCS_COORD_0 ^ MCS_COORD_1);
+ t->Setup[I810_TEXREG_MF] ^= (MF_MAP_0 ^ MF_MAP_1);
+
+ t->current_unit = unit;
+}
+
+
+
+
+static void i810UpdateTex0State( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_object *tObj;
+ i810TextureObjectPtr t;
+ int ma_modulate_op;
+
+
+ tObj = ctx->Texture.Unit[0].Current;
+
+ if ( tObj != ctx->Texture.Unit[0].CurrentD[2] )
+ tObj = 0;
+
+
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ITERATED_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ITERATED_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX0_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+
+ if (!(ctx->Texture.Enabled & 0xf) || !tObj || !tObj->Complete) {
+ return;
+ }
+
+ t = tObj->DriverData;
+
+ if (!t) {
+ t = i810CreateTexObj( imesa, tObj );
+ if (!t) return;
+ }
+
+ if (t->current_unit != 0)
+ i810TexSetUnit( t, 0 );
+
+ if (t->dirty_images)
+ imesa->dirty |= I810_UPLOAD_TEX0IMAGE;
+
+ imesa->CurrentTexObj[0] = t;
+
+ switch (ctx->Texture.Unit[0].EnvMode) {
+ case GL_REPLACE:
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX0_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ ma_modulate_op = MA_OP_ARG1;
+ } else {
+ ma_modulate_op = MA_OP_ARG2;
+ }
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ITERATED_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX0_ALPHA |
+ MA_UPDATE_OP |
+ ma_modulate_op );
+ break;
+ case GL_MODULATE:
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX0_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ITERATED_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_MODULATE );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ ma_modulate_op = MA_OP_ARG1;
+ } else {
+ ma_modulate_op = MA_OP_MODULATE;
+ }
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ITERATED_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX0_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_MODULATE );
+ break;
+
+ case GL_ADD:
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX0_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ITERATED_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_ADD );
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ITERATED_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX0_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_ADD );
+ break;
+
+ case GL_DECAL:
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_TEX0_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_ARG2 );
+
+ } else {
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_TEX0_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_LIN_BLEND_TEX0_ALPHA );
+ }
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ALPHA_FACTOR |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+ break;
+ case GL_BLEND:
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ITERATED_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_LIN_BLEND_TEX0_COLOR );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ITERATED_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+ } else {
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ITERATED_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_LIN_BLEND_TEX0_ALPHA );
+ }
+ break;
+
+ default:
+ fprintf(stderr, "unknown tex env mode");
+ exit(1);
+ break;
+ }
+}
+
+
+
+static void i810UpdateTex1State( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct gl_texture_object *tObj;
+ i810TextureObjectPtr t;
+ int ma_modulate_op;
+
+
+ tObj = ctx->Texture.Unit[1].Current;
+
+ if ( tObj != ctx->Texture.Unit[1].CurrentD[2] )
+ tObj = 0;
+
+
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ONE |
+ MC_ARG1_DONT_REPLICATE_ALPHA |
+ MC_ARG1_DONT_INVERT |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_ARG2_DONT_REPLICATE_ALPHA |
+ MC_ARG2_DONT_INVERT |
+ MC_UPDATE_OP |
+ MC_OP_DISABLE );
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_ARG1_DONT_INVERT |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_ARG2_DONT_INVERT |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+
+ if (!(ctx->Texture.Enabled & 0xf0) || !tObj || !tObj->Complete) {
+ return;
+ }
+
+ t = tObj->DriverData;
+
+ if (!t) {
+ t = i810CreateTexObj( imesa, tObj );
+ if (!t) return;
+ }
+
+ if (t->current_unit != 1)
+ i810TexSetUnit( t, 1 );
+
+ if (t->dirty_images)
+ imesa->dirty |= I810_UPLOAD_TEX1IMAGE;
+
+ imesa->CurrentTexObj[1] = t;
+
+
+ switch (ctx->Texture.Unit[1].EnvMode) {
+ case GL_REPLACE:
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX1_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ ma_modulate_op = MA_OP_ARG1;
+ } else {
+ ma_modulate_op = MA_OP_ARG2;
+ }
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX1_ALPHA |
+ MA_UPDATE_OP |
+ ma_modulate_op );
+ break;
+ case GL_MODULATE:
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX1_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_CURRENT_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_MODULATE );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ ma_modulate_op = MA_OP_ARG1;
+ } else {
+ ma_modulate_op = MA_OP_MODULATE;
+ }
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX1_ALPHA |
+ MA_UPDATE_OP |
+ ma_modulate_op );
+ break;
+
+ case GL_ADD:
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX1_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_CURRENT_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_ADD );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ ma_modulate_op = MA_OP_ARG1;
+ } else {
+ ma_modulate_op = MA_OP_ADD;
+ }
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX1_ALPHA |
+ MA_UPDATE_OP |
+ ma_modulate_op );
+ break;
+
+
+ case GL_DECAL:
+ if (t->image[0].internalFormat == GL_RGB) {
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_TEX1_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_ARG2 );
+
+ } else {
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_TEX1_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_LIN_BLEND_TEX1_ALPHA );
+ }
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ALPHA_FACTOR |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+ break;
+
+ case GL_BLEND:
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_CURRENT_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_LIN_BLEND_TEX1_COLOR );
+
+ if (t->image[0].internalFormat == GL_RGB) {
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
+ } else {
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ALPHA_FACTOR |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_ITERATED_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_LIN_BLEND_TEX1_ALPHA );
+ }
+ break;
+
+ default:
+ fprintf(stderr, "unkown tex 1 env mode\n");
+ exit(1);
+ break;
+ }
+}
+
+
+void i810UpdateTextureState( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ imesa->CurrentTexObj[0] = 0;
+ imesa->CurrentTexObj[1] = 0;
+ i810UpdateTex0State( ctx );
+ i810UpdateTex1State( ctx );
+ I810_CONTEXT( ctx )->dirty |= I810_UPLOAD_CTX;
+}
+
+
+
+/*****************************************
+ * DRIVER functions
+ *****************************************/
+
+static void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+ if (pname == GL_TEXTURE_ENV_MODE) {
+
+ imesa->new_state |= I810_NEW_TEXTURE;
+
+ } else if (pname == GL_TEXTURE_ENV_COLOR) {
+
+ struct gl_texture_unit *texUnit =
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ GLubyte c[4];
+ GLuint col;
+
+ FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c);
+ col = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]);
+
+ if (imesa->Setup[I810_CTXREG_CF1] != col) {
+ imesa->Setup[I810_CTXREG_CF1] = col;
+ imesa->dirty |= I810_UPLOAD_CTX;
+ }
+ }
+}
+
+static void i810TexImage( GLcontext *ctx,
+ GLenum target,
+ struct gl_texture_object *tObj,
+ GLint level,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ i810TextureObjectPtr t;
+
+ i810Msg(10,"i810TexImage(%d): level %d internalFormat %x\n",
+ tObj->Name, level, internalFormat);
+
+ if (target != GL_TEXTURE_2D)
+ return;
+
+ if (level >= I810_TEX_MAXLEVELS)
+ return;
+
+ t = (i810TextureObjectPtr) tObj->DriverData;
+ if (t) {
+ /* if this is the current object, it will force an update */
+ i810DestroyTexObj( imesa, t );
+ tObj->DriverData = 0;
+ imesa->new_state |= I810_NEW_TEXTURE;
+ }
+}
+
+static void i810TexSubImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ i810TextureObjectPtr t;
+ i810Msg(10,"i810TexSubImage():\n");
+ i810Msg(10," Size: %d,%d of %d,%d; Level %d\n",
+ width, height, image->Width,image->Height,
+ level);
+
+ if ( target != GL_TEXTURE_2D )
+ return;
+
+ t = (i810TextureObjectPtr) tObj->DriverData;
+ if (t) {
+ i810DestroyTexObj( imesa, t );
+ tObj->DriverData = 0;
+ imesa->new_state |= I810_NEW_TEXTURE;
+ i810glx.c_textureSwaps++;
+ }
+}
+
+static void i810TexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params )
+{
+ i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+ if (!t || target != GL_TEXTURE_2D)
+ return;
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ i810SetTexFilter(t,tObj->MinFilter,tObj->MagFilter);
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ i810SetTexWrapping(t,tObj->WrapS,tObj->WrapT);
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ i810SetTexBorderColor(t,tObj->BorderColor);
+ break;
+
+ default:
+ return;
+ }
+
+ imesa->new_state |= I810_NEW_TEXTURE;
+}
+
+static void i810BindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ imesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0;
+ imesa->new_state |= I810_NEW_TEXTURE;
+}
+
+static void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+ i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+ if (t) {
+ i810DestroyTexObj(imesa,t);
+ tObj->DriverData=0;
+ }
+}
+
+
+static GLboolean i810IsTextureResident( GLcontext *ctx,
+ struct gl_texture_object *t )
+{
+ i810TextureObjectPtr mt;
+
+/* LOCK_HARDWARE; */
+ mt = (i810TextureObjectPtr)t->DriverData;
+/* UNLOCK_HARDWARE; */
+
+ return mt && mt->MemBlock;
+}
+
+void i810DDInitTextureFuncs( GLcontext *ctx )
+{
+ ctx->Driver.TexEnv = i810TexEnv;
+ ctx->Driver.TexImage = i810TexImage;
+ ctx->Driver.TexSubImage = i810TexSubImage;
+ ctx->Driver.BindTexture = i810BindTexture;
+ ctx->Driver.DeleteTexture = i810DeleteTexture;
+ ctx->Driver.TexParameter = i810TexParameter;
+ ctx->Driver.UpdateTexturePalette = 0;
+ ctx->Driver.IsTextureResident = i810IsTextureResident;
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.h b/xc/lib/GL/mesa/src/drv/i810/i810tex.h
new file mode 100644
index 000000000..d2b153ad8
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.h
@@ -0,0 +1,108 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ *
+ */
+
+#ifndef I810TEX_INC
+#define I810TEX_INC
+
+#include "types.h"
+#include "mmath.h"
+#include "mm.h"
+
+#include "i810context.h"
+#include "i810_3d_reg.h"
+
+#define VALID_I810_TEXTURE_OBJECT(tobj) (tobj)
+
+#define I810_TEX_MAXLEVELS 10
+
+
+
+/* For shared texture space managment, these texture objects may also
+ * be used as proxies for regions of texture memory containing other
+ * client's textures. Such proxy textures (not to be confused with GL
+ * proxy textures) are subject to the same LRU aging we use for our
+ * own private textures, and thus we have a mechanism where we can
+ * fairly decide between kicking out our own textures and those of
+ * other clients.
+ *
+ * Non-local texture objects have a valid MemBlock to describe the
+ * region managed by the other client, and can be identified by
+ * 't->globj == 0'
+ */
+struct i810_texture_object_t {
+ struct i810_texture_object_t *next, *prev;
+
+ GLuint age;
+ struct gl_texture_object *globj;
+
+ int Pitch;
+ int Height;
+ int texelBytes;
+ int totalSize;
+
+ PMemBlock MemBlock;
+ char *BufAddr;
+
+ GLuint min_level;
+ GLuint max_level;
+ GLuint dirty_images;
+
+ struct {
+ const struct gl_texture_image *image;
+ int offset; /* into BufAddr */
+ int height;
+ int internalFormat;
+ } image[I810_TEX_MAXLEVELS];
+
+ /* Support for multitexture.
+ */
+ GLuint current_unit;
+ GLuint Setup[I810_TEX_SETUP_SIZE];
+};
+
+#define I810_NO_PALETTE 0x0
+#define I810_USE_PALETTE 0x1
+#define I810_UPDATE_PALETTE 0x2
+#define I810_FALLBACK_PALETTE 0x4
+
+typedef struct i810_texture_object_t *i810TextureObjectPtr;
+
+void i810UpdateTextureState( GLcontext *ctx );
+void i810DDInitTextureFuncs( GLcontext *ctx );
+
+void i810DestroyTexObj( i810ContextPtr imesa, i810TextureObjectPtr t);
+int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t );
+
+void i810ResetGlobalLRU( i810ContextPtr imesa );
+void i810TexturesGone( i810ContextPtr imesa,
+ GLuint start, GLuint end,
+ GLuint in_use );
+
+void i810PrintLocalLRU( i810ContextPtr imesa );
+void i810PrintGlobalLRU( i810ContextPtr imesa );
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.c b/xc/lib/GL/mesa/src/drv/i810/i810tris.c
new file mode 100644
index 000000000..08e012c66
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.c
@@ -0,0 +1,317 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "vb.h"
+#include "pipeline.h"
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810tris.h"
+#include "i810vb.h"
+#include "i810log.h"
+
+
+static void i810_null_quad( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint v3, GLuint pv )
+{
+}
+
+static void i810_null_triangle( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint pv )
+{
+}
+
+static void i810_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
+{
+}
+
+static void i810_null_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+}
+
+
+#define I810_COLOR(to, from) { \
+ (to)[0] = (from)[2]; \
+ (to)[1] = (from)[1]; \
+ (to)[2] = (from)[0]; \
+ (to)[3] = (from)[3]; \
+}
+
+
+
+static triangle_func tri_tab[0x20];
+static quad_func quad_tab[0x20];
+static line_func line_tab[0x20];
+static points_func points_tab[0x20];
+
+void i810PrintRenderState( const char *msg, GLuint state )
+{
+ fprintf(stderr, "%s: (%x) %s%s%s%s%s%s\n",
+ msg, (int) state,
+ (state & I810_FLAT_BIT) ? "flat, " : "",
+ (state & I810_OFFSET_BIT) ? "offset, " : "",
+ (state & I810_TWOSIDE_BIT) ? "twoside, " : "",
+ (state & I810_ANTIALIAS_BIT) ? "antialias, " : "",
+ (state & I810_NODRAW_BIT) ? "no-draw, " : "",
+ (state & I810_FALLBACK_BIT) ? "fallback" : "");
+}
+
+#define IND (0)
+#define TAG(x) x
+#include "i810tritmp.h"
+
+#define IND (I810_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "i810tritmp.h"
+
+#define IND (I810_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "i810tritmp.h"
+
+#define IND (I810_OFFSET_BIT|I810_FLAT_BIT)
+#define TAG(x) x##_offset_flat
+#include "i810tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "i810tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_FLAT_BIT)
+#define TAG(x) x##_twoside_flat
+#include "i810tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "i810tritmp.h"
+
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_flat
+#include "i810tritmp.h"
+
+void i810DDTrifuncInit()
+{
+ int i;
+ init();
+ init_flat();
+ init_offset();
+ init_offset_flat();
+ init_twoside();
+ init_twoside_flat();
+ init_twoside_offset();
+ init_twoside_offset_flat();
+
+ /* Hmmm...
+ */
+ for (i = 0 ; i < 0x20 ; i++) {
+ if (i & ~I810_FLAT_BIT) {
+ points_tab[i] = points_tab[i&I810_FLAT_BIT];
+ line_tab[i] = line_tab[i&I810_FLAT_BIT];
+ }
+ }
+
+ for (i = 0 ; i < 0x20 ; i++)
+ if ((i & (I810_NODRAW_BIT|I810_FALLBACK_BIT)) == I810_NODRAW_BIT ||
+ i810glx.nullprims)
+ {
+ quad_tab[i] = i810_null_quad;
+ tri_tab[i] = i810_null_triangle;
+ line_tab[i] = i810_null_line;
+ points_tab[i] = i810_null_points;
+ }
+
+ if (i810glx.noFallback) {
+ for (i = 0 ; i < 0x10 ; i++) {
+ points_tab[i|I810_FALLBACK_BIT] = points_tab[i];
+ line_tab[i|I810_FALLBACK_BIT] = line_tab[i];
+ tri_tab[i|I810_FALLBACK_BIT] = tri_tab[i];
+ quad_tab[i|I810_FALLBACK_BIT] = quad_tab[i];
+ }
+ }
+
+}
+
+
+/* Everything is done via single triangle instructiopns at the moment;
+ * this can change fairly easily.
+ */
+#if I810_USE_BATCH
+
+GLuint *i810AllocPrimitiveVerts( i810ContextPtr imesa, int dwords )
+{
+ GLuint orig_dwords = dwords;
+
+ dwords+=2;
+ dwords&=~1;
+
+ while (1) {
+ if (i810glx.dma_buffer->space < dwords * 4)
+ {
+ if (I810_DEBUG & DEBUG_VERBOSE_RING)
+ fprintf(stderr, "i810AllocPrimitiveVerts: dma buffer overflow\n");
+ i810DmaOverflow( dwords );
+ }
+ else
+ {
+ GLuint start = i810glx.dma_buffer->head;
+ i810glx.dma_buffer->head += dwords * 4;
+ i810glx.dma_buffer->space -= dwords * 4;
+
+ if ((orig_dwords & 1) == 0) {
+ *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) = 0;
+ start += 4;
+ }
+
+ *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) =
+ GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1);
+
+ return (GLuint *)(i810glx.dma_buffer->virtual_start + start + 4);
+ }
+ }
+}
+
+#else
+
+/* Hardware lock is held.
+ */
+GLuint *i810AllocPrimitiveVerts( i810ContextPtr imesa, int dwords )
+{
+ GLuint orig_dwords = dwords;
+
+ dwords+=2;
+ dwords&=~1;
+
+ while (1)
+ {
+ BEGIN_LP_RING( imesa, dwords );
+
+ if (outring + dwords * 4 != ((outring + dwords * 4) & ringmask))
+ {
+ int i;
+
+ if (I810_DEBUG & DEBUG_VERBOSE_RING)
+ fprintf(stderr, "\n\nwrap case in i810AllocPrimitiveVerts\n\n");
+
+ for (i = 0 ; i < dwords ; i++)
+ OUT_RING( 0 );
+ ADVANCE_LP_RING();
+ }
+ else
+ {
+ i810glx.LpRing.tail = outring + dwords * 4;
+
+ if ((orig_dwords & 1) == 0)
+ OUT_RING(0);
+
+ OUT_RING( GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1) );
+ return (GLuint *)(virt + outring);
+ }
+ }
+}
+
+#if 0
+void i810FinishPrim( void )
+{
+ char *virt = i810glx.LpRing.virtual_start;
+
+ for (i = i810glx.LpRing.head ; i != i810glx.LpRing.tail ; i += 4)
+ fprintf(stderr, "prim %x (%f)", *(virt + i), *(float *)(virt + i));
+
+ OUTREG(LP_RING + RING_TAIL, i810glx.LpRing.tail);
+}
+#endif
+#endif
+
+
+
+void i810DDChooseRenderState( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLuint flags = ctx->TriangleCaps;
+
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+
+ if (flags) {
+ GLuint ind = 0;
+ GLuint shared = 0;
+ GLuint setup = imesa->setupindex;
+ GLuint fallback = I810_FALLBACK_BIT;
+
+ if (i810glx.noFallback) fallback = 0;
+
+ if ((flags & DD_FLATSHADE) && (setup & I810_RGBA_BIT)) shared |= I810_FLAT_BIT;
+ if (flags & DD_MULTIDRAW) shared |= fallback;
+ if (flags & DD_SELECT) shared |= I810_FALLBACK_BIT;
+ if (flags & DD_FEEDBACK) shared |= I810_FALLBACK_BIT;
+
+ ind = shared;
+ if (flags & DD_POINT_SMOOTH) ind |= I810_ANTIALIAS_BIT;
+ if (flags & DD_POINT_ATTEN) ind |= fallback;
+
+ imesa->renderindex = ind;
+ imesa->PointsFunc = points_tab[ind];
+ if (ind & I810_FALLBACK_BIT)
+ ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+
+ ind = shared;
+ if (flags & DD_LINE_SMOOTH) ind |= I810_ANTIALIAS_BIT;
+ if (flags & DD_LINE_STIPPLE) ind |= fallback;
+
+ imesa->renderindex |= ind;
+ imesa->LineFunc = line_tab[ind];
+ if (ind & I810_FALLBACK_BIT)
+ ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+
+ ind = shared;
+ if (flags & DD_TRI_SMOOTH) ind |= I810_ANTIALIAS_BIT;
+ if (flags & DD_TRI_OFFSET) ind |= I810_OFFSET_BIT;
+ if (flags & DD_TRI_LIGHT_TWOSIDE) ind |= I810_TWOSIDE_BIT;
+ if (flags & (DD_TRI_UNFILLED|DD_TRI_STIPPLE)) ind |= fallback;
+
+ imesa->renderindex |= ind;
+ imesa->TriangleFunc = tri_tab[ind];
+ imesa->QuadFunc = quad_tab[ind];
+ if (ind & I810_FALLBACK_BIT)
+ ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE);
+ }
+ else if (imesa->renderindex)
+ {
+ imesa->renderindex = 0;
+ imesa->PointsFunc = points_tab[0];
+ imesa->LineFunc = line_tab[0];
+ imesa->TriangleFunc = tri_tab[0];
+ imesa->QuadFunc = quad_tab[0];
+ }
+
+ if (I810_DEBUG&DEBUG_VERBOSE_API) {
+ gl_print_tri_caps("tricaps", ctx->TriangleCaps);
+ i810PrintRenderState("i810: Render state", imesa->renderindex);
+ }
+}
+
+
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h
new file mode 100644
index 000000000..81cdb5159
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h
@@ -0,0 +1,158 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ *
+ */
+
+#ifndef I810TRIS_INC
+#define I810TRIS_INC
+
+#include "types.h"
+#include "i810dma.h"
+
+extern void i810PrintRenderState( const char *msg, GLuint state );
+extern void i810DDChooseRenderState(GLcontext *ctx);
+extern void i810DDTrifuncInit( void );
+
+extern GLuint *i810AllocPrimitiveVerts( i810ContextPtr imesa, int dwords );
+
+
+
+/* Todo:
+ * - multidraw, ...
+ * - Antialiasing (?)
+ * - line and polygon stipple
+ * - select and feedback
+ * - stencil
+ * - point parameters
+ * -
+ */
+#define I810_ANTIALIAS_BIT 0 /* ignored for now, no fallback */
+#define I810_FLAT_BIT 0x1
+#define I810_OFFSET_BIT 0x2
+#define I810_TWOSIDE_BIT 0x4
+#define I810_NODRAW_BIT 0x8
+#define I810_FALLBACK_BIT 0x10
+
+/* Not in use:
+ */
+#define I810_FEEDBACK_BIT 0x20
+#define I810_SELECT_BIT 0x40
+#define I810_POINT_PARAM_BIT 0x80 /* not needed? */
+
+
+
+static void __inline__ i810_draw_triangle( i810ContextPtr imesa,
+ i810_vertex *v0,
+ i810_vertex *v1,
+ i810_vertex *v2 )
+{
+ i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 30 );
+ wv[0] = *v0;
+ wv[1] = *v1;
+ wv[2] = *v2;
+ FINISH_PRIM();
+}
+
+
+
+
+/* These can go soon, but for the meantime we're using triangles for
+ * everything.
+ */
+static __inline__ void i810_draw_point( i810ContextPtr imesa,
+ i810_vertex *tmp, float sz )
+{
+ i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 6*10 );
+
+ wv[0] = *tmp;
+ wv[0].x = tmp->x - sz;
+ wv[0].y = tmp->y - sz;
+
+ wv[1] = *tmp;
+ wv[1].x = tmp->x + sz;
+ wv[1].y = tmp->y - sz;
+
+ wv[2] = *tmp;
+ wv[2].x = tmp->x + sz;
+ wv[2].y = tmp->y + sz;
+
+ wv[3] = *tmp;
+ wv[3].x = tmp->x + sz;
+ wv[3].y = tmp->y + sz;
+
+ wv[4] = *tmp;
+ wv[4].x = tmp->x - sz;
+ wv[4].y = tmp->y + sz;
+
+ wv[5] = *tmp;
+ wv[5].x = tmp->x - sz;
+ wv[5].y = tmp->y - sz;
+
+ FINISH_PRIM();
+}
+
+
+static __inline__ void i810_draw_line( i810ContextPtr imesa,
+ i810_vertex *tmp0,
+ i810_vertex *tmp1,
+ float width )
+{
+ i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 6 * 10 );
+ float dx, dy, ix, iy;
+
+ dx = tmp0->x - tmp1->x;
+ dy = tmp0->y - tmp1->y;
+
+ ix = width * .5; iy = 0;
+ if (dx * dx > dy * dy) {
+ iy = ix; ix = 0;
+ }
+
+ wv[0] = *tmp0;
+ wv[0].x = tmp0->x - ix;
+ wv[0].y = tmp0->y - iy;
+
+ wv[1] = *tmp1;
+ wv[1].x = tmp1->x + ix;
+ wv[1].y = tmp1->y + iy;
+
+ wv[2] = *tmp0;
+ wv[2].x = tmp0->x + ix;
+ wv[2].y = tmp0->y + iy;
+
+ wv[3] = *tmp0;
+ wv[3].x = tmp0->x - ix;
+ wv[3].y = tmp0->y - iy;
+
+ wv[4] = *tmp1;
+ wv[4].x = tmp1->x - ix;
+ wv[4].y = tmp1->y - iy;
+
+ wv[5] = *tmp1;
+ wv[5].x = tmp1->x + ix;
+ wv[5].y = tmp1->y + iy;
+
+ FINISH_PRIM();
+}
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
new file mode 100644
index 000000000..97c101c17
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
@@ -0,0 +1,172 @@
+
+static __inline__ void TAG(triangle)( GLcontext *ctx, GLuint e0,
+ GLuint e1, GLuint e2, GLuint pv )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ struct vertex_buffer *VB = ctx->VB;
+ i810VertexPtr i810VB = I810_DRIVER_DATA(VB)->verts;
+ const i810_vertex *v0 = &i810VB[e0].v;
+ const i810_vertex *v1 = &i810VB[e1].v;
+ const i810_vertex *v2 = &i810VB[e2].v;
+
+#if (IND & I810_OFFSET_BIT)
+ GLfloat offset = ctx->Polygon.OffsetUnits * 1.0/0x10000;
+#endif
+
+#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
+ int c0 = *(int *)&i810VB[pv].v.color;
+ int c1 = c0;
+ int c2 = c0;
+#endif
+
+
+#if (IND & (I810_TWOSIDE_BIT|I810_OFFSET_BIT))
+ {
+ GLfloat ex = v0->x - v2->x;
+ GLfloat ey = v0->y - v2->y;
+ GLfloat fx = v1->x - v2->x;
+ GLfloat fy = v1->y - v2->y;
+ GLfloat c = ex*fy-ey*fx;
+
+#if (IND & I810_TWOSIDE_BIT)
+ {
+ GLuint facing = (c>0.0) ^ ctx->Polygon.FrontBit;
+ GLubyte (*vbcolor)[4] = VB->Color[facing]->data;
+ if (IND & I810_FLAT_BIT) {
+ I810_COLOR((char *)&c0,vbcolor[pv]);
+ c2 = c1 = c0;
+ } else {
+ I810_COLOR((char *)&c0,vbcolor[e0]);
+ I810_COLOR((char *)&c1,vbcolor[e1]);
+ I810_COLOR((char *)&c2,vbcolor[e2]);
+ }
+ }
+#endif
+
+#if (IND & I810_OFFSET_BIT)
+ {
+ if (c * c > 1e-16) {
+ GLfloat factor = ctx->Polygon.OffsetFactor;
+ GLfloat ez = v0->z - v2->z;
+ GLfloat fz = v1->z - v2->z;
+ GLfloat a = ey*fz-ez*fy;
+ GLfloat b = ez*fx-ex*fz;
+ GLfloat ic = 1.0 / c;
+ GLfloat ac = a * ic;
+ GLfloat bc = b * ic;
+ if (ac<0.0F) ac = -ac;
+ if (bc<0.0F) bc = -bc;
+ offset += MAX2( ac, bc ) * factor;
+ }
+ }
+#endif
+ }
+#endif
+
+ i810glx.c_triangles++;
+
+
+ BEGIN_CLIP_LOOP(imesa)
+ {
+ i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 30 );
+ wv[0] = *v0;
+#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
+ *((int *)(&wv[0].color)) = c0;
+#endif
+#if (IND & I810_OFFSET_BIT)
+ wv[0].z = v0->z + offset;
+#endif
+
+
+ wv[1] = *v1;
+#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
+ *((int *)(&wv[1].color)) = c1;
+#endif
+#if (IND & I810_OFFSET_BIT)
+ wv[1].z = v1->z + offset;
+#endif
+
+ wv[2] = *v2;
+#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
+ *((int *)(&wv[2].color)) = c2;
+#endif
+#if (IND & I810_OFFSET_BIT)
+ wv[2].z = v2->z + offset;
+#endif
+
+ FINISH_PRIM();
+ }
+ END_CLIP_LOOP(imesa);
+}
+
+
+
+static void TAG(quad)( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint v3,
+ GLuint pv )
+{
+ TAG(triangle)( ctx, v0, v1, v3, pv );
+ TAG(triangle)( ctx, v1, v2, v3, pv );
+}
+
+
+#if ((IND & ~I810_FLAT_BIT) == 0)
+
+static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ i810VertexPtr i810VB = I810_DRIVER_DATA(ctx->VB)->verts;
+ i810_vertex tmp0 = i810VB[v0].v;
+ i810_vertex tmp1 = i810VB[v1].v;
+ float width = ctx->Line.Width;
+
+ if (IND & I810_FLAT_BIT) {
+ *(int *)&tmp1.color = *(int *)&tmp0.color =
+ *(int *)&i810VB[pv].v.color;
+ }
+
+ BEGIN_CLIP_LOOP(imesa)
+ i810_draw_line( imesa, &tmp0, &tmp1, width );
+ END_CLIP_LOOP(imesa);
+}
+
+
+static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ struct vertex_buffer *VB = ctx->VB;
+ i810VertexPtr i810VB = I810_DRIVER_DATA(VB)->verts;
+ GLfloat sz = ctx->Point.Size * .5;
+ int i;
+
+ /* Culling is disabled automatically via. the
+ * ctx->Driver.ReducedPrimitiveChange() callback.
+ */
+
+ BEGIN_CLIP_LOOP(imesa)
+ for(i=first;i<=last;i++) {
+ if(VB->ClipMask[i]==0) {
+ i810_vertex *tmp = &i810VB[i].v;
+ i810_draw_point( imesa, tmp, sz );
+ }
+ }
+ END_CLIP_LOOP(imesa);
+}
+
+#endif
+
+
+static void TAG(init)( void )
+{
+ tri_tab[IND] = TAG(triangle);
+ quad_tab[IND] = TAG(quad);
+
+#if ((IND & ~I810_FLAT_BIT) == 0)
+ line_tab[IND] = TAG(line);
+ points_tab[IND] = TAG(points);
+#endif
+}
+
+
+#undef IND
+#undef TAG
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c
new file mode 100644
index 000000000..6ba7eb9a5
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c
@@ -0,0 +1,461 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ *
+ */
+
+#include "i810lib.h"
+#include "i810context.h"
+#include "i810vb.h"
+#include "i810log.h"
+#include "i810dma.h"
+
+#include "stages.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#define TEX0 { \
+ v->v.tu0 = tc0[i][0]; \
+ v->v.tv0 = tc0[i][1]; \
+}
+
+#define TEX1 { \
+ v->v.tu1 = tc1[i][0]; \
+ v->v.tv1 = tc1[i][1]; \
+}
+
+/* Doesn't seem to work very well (golly).
+ */
+#define SPC { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.specular.red = spec[0]; \
+ v->v.specular.green = spec[1]; \
+ v->v.specular.blue = spec[2]; \
+}
+
+#define FOG { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.specular.alpha = spec[3]; \
+}
+
+#define COL { \
+ GLubyte *col = &(VB->Color[0]->data[i][0]); \
+ v->v.color.blue = col[2]; \
+ v->v.color.green = col[1]; \
+ v->v.color.red = col[0]; \
+ v->v.color.alpha = col[3]; \
+}
+
+/* The vertex formats we have don't seem to support projective texturing
+ * in the multitexture case. (Would require another 1/w value for the
+ * second set of texcoords).
+ */
+#define TEX0_4 \
+ if (VB->TexCoordPtr[0]->size == 4) \
+ { \
+ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \
+ v = &(I810_DRIVER_DATA(VB)->verts[start]); \
+ imesa->setupdone &= ~I810_WIN_BIT; \
+ for (i=start; i < end; i++, v++) { \
+ float oow = 1.0 / tc[i][3]; \
+ v->v.oow *= tc[i][3]; \
+ v->v.tu0 *= oow; \
+ v->v.tv0 *= oow; \
+ } \
+ }
+
+
+#define COORD \
+ GLfloat *win = VB->Win.data[i]; \
+ v->v.x = win[0]; \
+ v->v.y = i810height - win[1]; \
+ v->v.z = (1.0/0x10000) * win[2]; \
+ v->v.oow = win[3];
+
+
+
+#define NOP
+
+
+#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,spec,fog) \
+static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
+{ \
+ i810ContextPtr imesa = I810_CONTEXT( VB->ctx ); \
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
+ i810VertexPtr v; \
+ GLfloat (*tc0)[4]; \
+ GLfloat (*tc1)[4]; \
+ GLfloat i810height = dPriv->h; \
+ int i; \
+ (void) i810height; (void) imesa; \
+ \
+ \
+ gl_import_client_data( VB, VB->ctx->RenderFlags, \
+ (VB->ClipOrMask \
+ ? VEC_WRITABLE|VEC_GOOD_STRIDE \
+ : VEC_GOOD_STRIDE)); \
+ \
+ tc0 = VB->TexCoordPtr[0]->data; \
+ tc1 = VB->TexCoordPtr[1]->data; \
+ \
+ v = &(I810_DRIVER_DATA(VB)->verts[start]); \
+ \
+ if (VB->ClipOrMask == 0) \
+ for (i=start; i < end; i++, v++) { \
+ win; \
+ col; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ else \
+ for (i=start; i < end; i++, v++) { \
+ if (VB->ClipMask[i] == 0) { \
+ win; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ col; \
+ } \
+ tex0_4; \
+}
+
+
+
+
+SETUPFUNC(rs_wt0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wt0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wft0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wft0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wg, COORD,COL,NOP,NOP,NOP,NOP,NOP)
+SETUPFUNC(rs_wgs, COORD,COL,NOP,NOP,NOP,SPC,NOP)
+SETUPFUNC(rs_wgt0, COORD,COL,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wgt0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wgst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_wgst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_wgf, COORD,COL,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_wgfs, COORD,COL,NOP,NOP,NOP,SPC,FOG)
+SETUPFUNC(rs_wgft0, COORD,COL,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wgft0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wgfst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,FOG)
+SETUPFUNC(rs_wgfst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,FOG)
+
+SETUPFUNC(rs_t0, NOP,NOP,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_t0t1, NOP,NOP,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_f, NOP,NOP,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_ft0, NOP,NOP,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_ft0t1, NOP,NOP,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_g, NOP,COL,NOP,NOP,NOP,NOP,NOP)
+SETUPFUNC(rs_gs, NOP,COL,NOP,NOP,NOP,SPC,NOP)
+SETUPFUNC(rs_gt0, NOP,COL,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_gt0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_gst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_gst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_gf, NOP,COL,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_gfs, NOP,COL,NOP,NOP,NOP,SPC,FOG)
+SETUPFUNC(rs_gft0, NOP,COL,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_gft0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_gfst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,FOG)
+SETUPFUNC(rs_gfst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,FOG)
+
+
+
+static void rs_invalid(struct vertex_buffer *VB, GLuint start, GLuint end)
+{
+
+ fprintf(stderr, "i810RasterSetup(): invalid setup function\n");
+}
+
+typedef void (*setupFunc)(struct vertex_buffer *,GLuint,GLuint);
+
+static setupFunc setup_func[0x80];
+
+void i810DDSetupInit( void )
+{
+ int i;
+
+ for (i = 0 ; i < 0x80 ; i++)
+ setup_func[i] = rs_invalid;
+
+ /* Functions to build vert's from scratch */
+ setup_func[I810_WIN_BIT|I810_TEX0_BIT] = rs_wt0;
+ setup_func[I810_WIN_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wt0t1;
+ setup_func[I810_WIN_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_wft0;
+ setup_func[I810_WIN_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wft0t1;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT] = rs_wg;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT] = rs_wgs;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_TEX0_BIT] = rs_wgt0;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgt0t1;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_wgst0;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgst0t1;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT] = rs_wgf;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT] = rs_wgfs;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_wgft0;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgft0t1;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_wgfst0;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgfst0t1;
+
+ /* Repair functions */
+ setup_func[I810_TEX0_BIT] = rs_t0;
+ setup_func[I810_TEX0_BIT|I810_TEX1_BIT] = rs_t0t1;
+ setup_func[I810_FOG_BIT] = rs_f;
+ setup_func[I810_FOG_BIT|I810_TEX0_BIT] = rs_ft0;
+ setup_func[I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_ft0t1;
+ setup_func[I810_RGBA_BIT] = rs_g;
+ setup_func[I810_RGBA_BIT|I810_SPEC_BIT] = rs_gs;
+ setup_func[I810_RGBA_BIT|I810_TEX0_BIT] = rs_gt0;
+ setup_func[I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gt0t1;
+ setup_func[I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_gst0;
+ setup_func[I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gst0t1;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT] = rs_gf;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT] = rs_gfs;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_gft0;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gft0t1;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_gfst0;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gfst0t1;
+
+}
+
+
+void i810PrintSetupFlags(char *msg, GLuint flags )
+{
+ fprintf(stderr, "%s: %d %s%s%s%s%s%s%s\n",
+ msg,
+ (int)flags,
+ (flags & I810_WIN_BIT) ? " xyzw," : "",
+ (flags & I810_RGBA_BIT) ? " rgba," : "",
+ (flags & I810_SPEC_BIT) ? " spec," : "",
+ (flags & I810_FOG_BIT) ? " fog," : "",
+ (flags & I810_TEX0_BIT) ? " tex-0," : "",
+ (flags & I810_TEX1_BIT) ? " tex-1," : "",
+ (flags & I810_ALPHA_BIT) ? " alpha," : "");
+}
+
+
+
+
+void i810ChooseRasterSetupFunc(GLcontext *ctx)
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ int funcindex = (I810_WIN_BIT | I810_RGBA_BIT);
+
+ if (ctx->Texture.Enabled & 0xf) {
+ if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE)
+ funcindex &= ~I810_RGBA_BIT;
+
+ funcindex |= I810_TEX0_BIT;
+ }
+
+ if (ctx->Texture.Enabled & 0xf0)
+ funcindex |= I810_TEX1_BIT;
+
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ funcindex |= I810_SPEC_BIT;
+
+ if (ctx->FogMode == FOG_FRAGMENT)
+ funcindex |= I810_FOG_BIT;
+
+ if (MESA_VERBOSE)
+ i810PrintSetupFlags("xsmesa: full setup function", funcindex);
+
+ imesa->setupindex = funcindex;
+ ctx->Driver.RasterSetup = setup_func[funcindex];
+}
+
+
+
+
+void i810DDCheckPartialRasterSetup( GLcontext *ctx,
+ struct gl_pipeline_stage *d )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLuint tmp = imesa->setupdone;
+
+ d->type = 0;
+ imesa->setupdone = 0; /* cleared if we return */
+
+ if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0)
+ return;
+
+ if (ctx->IndirectTriangles)
+ return;
+
+ imesa->setupdone = tmp;
+
+ /* disabled until we have a merge&render op */
+ /* d->inputs = available; */
+ /* d->outputs = VERT_RAST_SETUP_PART; */
+ /* d->type = PIPE_PRECALC; */
+}
+
+
+/* Repair existing precalculated vertices with new data.
+ */
+void i810DDPartialRasterSetup( struct vertex_buffer *VB )
+{
+ i810ContextPtr imesa = I810_CONTEXT( VB->ctx );
+ GLuint new = VB->pipeline->new_outputs;
+ GLuint available = VB->pipeline->outputs;
+ GLuint ind = 0;
+
+ if (new & VERT_WIN) {
+ new = available;
+ ind |= I810_WIN_BIT | I810_FOG_BIT;
+ }
+
+ if (new & VERT_RGBA)
+ ind |= I810_RGBA_BIT | I810_SPEC_BIT;
+
+ if (new & VERT_TEX0_ANY)
+ ind |= I810_TEX0_BIT;
+
+ if (new & VERT_TEX1_ANY)
+ ind |= I810_TEX1_BIT;
+
+ if (new & VERT_FOG_COORD)
+ ind |= I810_FOG_BIT;
+
+ imesa->setupdone &= ~ind;
+ ind &= imesa->setupindex;
+ imesa->setupdone |= ind;
+
+ if (0) i810PrintSetupFlags("xsmesa: partial setup function", ind);
+
+ if (ind)
+ setup_func[ind&~I810_ALPHA_BIT]( VB, VB->Start, VB->Count );
+}
+
+
+void i810DDDoRasterSetup( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+
+ if (VB->Type == VB_CVA_PRECALC)
+ i810DDPartialRasterSetup( VB );
+ else if (ctx->Driver.RasterSetup)
+ ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count );
+}
+
+
+
+
+void i810DDResizeVB( struct vertex_buffer *VB, GLuint size )
+{
+ i810VertexBufferPtr mvb = I810_DRIVER_DATA(VB);
+
+ while (mvb->size < size)
+ mvb->size *= 2;
+
+ free( mvb->vert_store );
+ mvb->vert_store = malloc( sizeof(i810Vertex) * mvb->size + 31);
+ if (!mvb->vert_store) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
+ mvb->verts = (i810VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31);
+
+ gl_vector1ui_free( &mvb->clipped_elements );
+ gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 );
+ if (!mvb->clipped_elements.start) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
+ free( VB->ClipMask );
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size);
+ if (!VB->ClipMask) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
+
+ if (VB->Type == VB_IMMEDIATE) {
+ free( mvb->primitive );
+ free( mvb->next_primitive );
+ mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ if (!mvb->primitive || !mvb->next_primitive) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+ }
+}
+
+
+void i810DDRegisterVB( struct vertex_buffer *VB )
+{
+ i810VertexBufferPtr mvb;
+
+ mvb = (i810VertexBufferPtr)calloc( 1, sizeof(*mvb) );
+
+ mvb->size = VB->Size * 2;
+ mvb->vert_store = malloc( sizeof(i810Vertex) * mvb->size + 31);
+ if (!mvb->vert_store) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
+ mvb->verts = (i810VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31);
+
+ gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 );
+ if (!mvb->clipped_elements.start) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
+ free( VB->ClipMask );
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size);
+ if (!VB->ClipMask) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
+ mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ if (!mvb->primitive || !mvb->next_primitive) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
+ VB->driver_data = mvb;
+}
+
+
+void i810DDUnregisterVB( struct vertex_buffer *VB )
+{
+ i810VertexBufferPtr mvb = I810_DRIVER_DATA(VB);
+
+ if (mvb) {
+ if (mvb->vert_store) free(mvb->vert_store);
+ if (mvb->primitive) free(mvb->primitive);
+ if (mvb->next_primitive) free(mvb->next_primitive);
+ gl_vector1ui_free( &mvb->clipped_elements );
+ free(mvb);
+ VB->driver_data = 0;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.h b/xc/lib/GL/mesa/src/drv/i810/i810vb.h
new file mode 100644
index 000000000..23685f106
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.h
@@ -0,0 +1,116 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ *
+ */
+
+#ifndef I810VB_INC
+#define I810VB_INC
+
+#include "vb.h"
+#include "types.h"
+
+/*
+ * color type for the vertex data
+ * we probably want to use an internal datatype here?
+ */
+typedef struct {
+ GLubyte blue;
+ GLubyte green;
+ GLubyte red;
+ GLubyte alpha;
+} i810_color;
+
+
+/* A basic fixed format vertex to kick things off. Move to dynamic
+ * layouts later on. (see also the i810_full_vertex struct in
+ * i810_3d_reg.h)
+ */
+typedef struct {
+ GLfloat x,y,z; /* coordinates in screen space*/
+ GLfloat oow; /* reciprocal homogeneous w */
+ i810_color color; /* vertex color */
+ i810_color specular; /* specular color, alpha is fog */
+ GLfloat tu0,tv0; /* texture 0 */
+ GLfloat tu1,tv1; /* texture 1 */
+} i810_vertex;
+
+
+/* Unfortunately only have assembly for 16-stride vertices.
+ */
+union i810_vertex_t {
+ i810_vertex v;
+ float f[16];
+};
+
+typedef union i810_vertex_t i810Vertex;
+typedef union i810_vertex_t *i810VertexPtr;
+
+struct i810_vertex_buffer_t {
+ GLvector1ui clipped_elements;
+ i810VertexPtr verts;
+ int last_vert;
+ GLuint *primitive;
+ GLuint *next_primitive;
+ void *vert_store;
+ GLuint size;
+};
+
+typedef struct i810_vertex_buffer_t *i810VertexBufferPtr;
+
+
+#define I810_CONTEXT(ctx) ((i810ContextPtr)(ctx->DriverCtx))
+#define I810_DRIVER_DATA(vb) ((i810VertexBufferPtr)((vb)->driver_data))
+
+
+#define I810_SPEC_BIT 0x1
+#define I810_FOG_BIT 0x2
+#define I810_ALPHA_BIT 0x4 /* GL_BLEND, not used */
+#define I810_TEX1_BIT 0x8
+#define I810_TEX0_BIT 0x10
+#define I810_RGBA_BIT 0x20
+#define I810_WIN_BIT 0x40
+
+
+extern void i810ChooseRasterSetupFunc(GLcontext *ctx);
+extern void i810PrintSetupFlags(char *msg, GLuint flags );
+extern void i810DDDoRasterSetup( struct vertex_buffer *VB );
+extern void i810DDPartialRasterSetup( struct vertex_buffer *VB );
+extern void i810DDCheckPartialRasterSetup( GLcontext *ctx,
+ struct gl_pipeline_stage *d );
+
+extern void i810DDViewport( GLcontext *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height );
+
+extern void i810DDDepthRange( GLcontext *ctx,
+ GLclampd nearval, GLclampd farval );
+
+
+extern void i810DDUnregisterVB( struct vertex_buffer *VB );
+extern void i810DDRegisterVB( struct vertex_buffer *VB );
+extern void i810DDResizeVB( struct vertex_buffer *VB, GLuint size );
+
+extern void i810DDSetupInit( void );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile
new file mode 100644
index 000000000..9ff1203ee
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile
@@ -0,0 +1,68 @@
+XCOMM $PI:$
+
+#define DoNormalLib NormalLibGlx
+#define DoSharedLib SharedLibGlx
+#define DoExtraLib SharedLibGlx
+#define DoDebugLib DebugLibGlx
+#define DoProfileLib ProfileLibGlx
+
+#if Malloc0ReturnsNull
+ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
+#endif
+
+#if BuildXF86DRI
+ DRI_DEFINES = GlxDefines -DDRIVERTS
+ DRI_INCLUDES = -I../../../../dri -I../../../../glx \
+ -I$(TOP)/include -I$(TOP)/include/GL \
+ -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
+ -I$(XF86DRIVERSRC)/mga \
+ -I../../../include -I../.. -I../../X -I../common \
+ -I$(XF86OSSRC)/linux/drm/kernel
+#endif
+
+MESA_INCLUDES = -I. -I.. -I../../include
+
+
+
+ DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
+ -I/usr/include/glide
+ DRISRCS = mgaclear.c mgacnvtex.c mgadd.c mgadepth.c \
+ mgafastpath.c \
+ mgapipeline.c \
+ mgaspan.c mgastate.c mgatex.c \
+ mgatris.c mgavb.c mgaioctl.c mga_xmesa.c
+
+ DRIOBJS = mgaclear.o mgacnvtex.o mgadd.o mgadepth.o \
+ mgafastpath.o \
+ mgapipeline.o \
+ mgaspan.o mgastate.o mgatex.o \
+ mgatris.o mgavb.o mgaioctl.o mga_xmesa.o
+
+
+ SRCS = $(DRISRCS)
+ OBJS = $(DRIOBJS)
+
+#if !GlxUseBuiltInDRIDriver
+#undef DoNormalLib NormalLibGlx
+#undef DoExtraLib SharedLibGlx
+#undef DoDebugLib DebugLibGlx
+#undef DoProfileLib ProfileLibGlx
+#endif
+
+#include <Library.tmpl>
+
+LibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+NormalLintTarget($(SRCS))
+
+#if !GlxUseBuiltInDRIDriver
+LIBNAME = mga_dri.so
+ALL_OBJS = $(OBJS)
+ALL_DEPS = DONE
+SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
+InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+#endif
+
+DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
new file mode 100644
index 000000000..8c42d0842
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
@@ -0,0 +1,514 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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, 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 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Daryll Strauss <daryll@precisioninsight.com>
+ *
+ * $PI: $
+ */
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <X11/Xlibint.h>
+#include <stdio.h>
+
+#include "mga_xmesa.h"
+#include "context.h"
+#include "vbxform.h"
+#include "matrix.h"
+#include "simple_list.h"
+
+#include "mgadd.h"
+#include "mgastate.h"
+#include "mgatex.h"
+#include "mgaspan.h"
+#include "mgadepth.h"
+#include "mgatris.h"
+#include "mgapipeline.h"
+
+#include "xf86dri.h"
+#include "mga_dri.h"
+#include "mga_drm_public.h"
+#include "mga_xmesa.h"
+
+
+
+
+
+#ifndef MGA_DEBUG
+int MGA_DEBUG = (0
+/* | MGA_DEBUG_ALWAYS_SYNC */
+/* | MGA_DEBUG_VERBOSE_MSG */
+ );
+#endif
+
+
+static mgaContextPtr mgaCtx = 0;
+
+mgaGlx_t mgaglx;
+
+static int count_bits(unsigned int n)
+{
+ int bits = 0;
+
+ while (n > 0) {
+ if (n & 1) bits++;
+ n >>= 1;
+ }
+ return bits;
+}
+
+/* These functions are accessed by dlsym from dri_mesa_init.c:
+ *
+ * XMesaInitDriver
+ * XMesaResetDriver
+ * XMesaCreateVisual
+ * XMesaDestroyVisual
+ * XMesaCreateContext
+ * XMesaDestroyContext
+ * XMesaCreateWindowBuffer
+ * XMesaCreatePixmapBuffer
+ * XMesaDestroyBuffer
+ * XMesaSwapBuffers
+ * XMesaMakeCurrent
+ *
+ * So this is kind of the public interface to the driver. The driver
+ * uses the X11 mesa driver context as a kind of wrapper around its
+ * own driver context - but there isn't much justificiation for doing
+ * it that way - the DRI might as well use a (void *) to refer to the
+ * driver contexts. Nothing in the X context really gets used.
+ */
+
+
+GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
+{
+ mgaScreenPrivate *mgaScreen;
+ MGADRIPtr gDRIPriv = (MGADRIPtr)sPriv->pDevPriv;
+
+ /* Allocate the private area */
+ mgaScreen = (mgaScreenPrivate *)Xmalloc(sizeof(mgaScreenPrivate));
+ if (!mgaScreen) return GL_FALSE;
+
+ mgaScreen->sPriv = sPriv;
+ sPriv->private = (void *)mgaScreen;
+
+ mgaScreen->chipset=gDRIPriv->chipset;
+ mgaScreen->width=gDRIPriv->width;
+ mgaScreen->height=gDRIPriv->height;
+ mgaScreen->mem=gDRIPriv->mem;
+ mgaScreen->cpp=gDRIPriv->cpp;
+ mgaScreen->frontPitch=gDRIPriv->frontPitch;
+ mgaScreen->frontOffset=gDRIPriv->frontOffset;
+ mgaScreen->backOffset=gDRIPriv->backOffset;
+ mgaScreen->backPitch = gDRIPriv->backPitch;
+ mgaScreen->depthOffset=gDRIPriv->depthOffset;
+ mgaScreen->depthPitch = gDRIPriv->depthPitch;
+ mgaScreen->textureOffset=gDRIPriv->textureOffset;
+ mgaScreen->textureSize=gDRIPriv->textureSize;
+ mgaScreen->logTextureGranularity = gDRIPriv->logTextureGranularity;
+
+
+ mgaScreen->bufs = drmMapBufs(sPriv->fd);
+
+
+ /* Other mgaglx stuff, too??
+ */
+ memset(&mgaglx, 0, sizeof(mgaglx));
+
+ mgaDDFastPathInit();
+ mgaDDTrifuncInit();
+ mgaDDSetupInit();
+
+ return GL_TRUE;
+}
+
+/* Accessed by dlsym from dri_mesa_init.c
+ */
+void XMesaResetDriver(__DRIscreenPrivate *sPriv)
+{
+ Xfree(sPriv->private);
+}
+
+/* Accessed by dlsym from dri_mesa_init.c
+ */
+XMesaVisual XMesaCreateVisual(XMesaDisplay *display,
+ XMesaVisualInfo visinfo,
+ GLboolean rgb_flag,
+ GLboolean alpha_flag,
+ GLboolean db_flag,
+ GLboolean stereo_flag,
+ GLboolean ximage_flag,
+ GLint depth_size,
+ GLint stencil_size,
+ GLint accum_size,
+ GLint level)
+{
+ XMesaVisual v;
+
+ /* Only RGB visuals are supported on the MGA boards */
+ if (!rgb_flag) return 0;
+
+ v = (XMesaVisual)Xmalloc(sizeof(struct xmesa_visual));
+ if (!v) return 0;
+
+ v->visinfo = (XVisualInfo *)Xmalloc(sizeof(*visinfo));
+ if(!v->visinfo) {
+ Xfree(v);
+ return 0;
+ }
+ memcpy(v->visinfo, visinfo, sizeof(*visinfo));
+
+ v->display = display;
+ v->level = level;
+
+ v->gl_visual = (GLvisual *)Xmalloc(sizeof(GLvisual));
+ if (!v->gl_visual) {
+ Xfree(v->visinfo);
+ XFree(v);
+ return 0;
+ }
+
+ v->gl_visual->RGBAflag = rgb_flag;
+ v->gl_visual->DBflag = db_flag;
+ v->gl_visual->StereoFlag = stereo_flag;
+
+ v->gl_visual->RedBits = count_bits(visinfo->red_mask);
+ v->gl_visual->GreenBits = count_bits(visinfo->green_mask);
+ v->gl_visual->BlueBits = count_bits(visinfo->blue_mask);
+ v->gl_visual->AlphaBits = 0; /* Not currently supported */
+
+ v->gl_visual->AccumBits = accum_size;
+ v->gl_visual->DepthBits = depth_size;
+ v->gl_visual->StencilBits = stencil_size;
+
+ return v;
+}
+
+void XMesaDestroyVisual(XMesaVisual v)
+{
+ Xfree(v->gl_visual);
+ Xfree(v->visinfo);
+ Xfree(v);
+}
+
+XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
+ __DRIcontextPrivate *driContextPriv)
+{
+ GLcontext *ctx;
+ XMesaContext c;
+ mgaContextPtr mmesa;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private;
+ drm_mga_sarea_t *saPriv=(drm_mga_sarea_t*)(((char*)sPriv->pSAREA)+
+ sizeof(XF86DRISAREARec));
+ GLcontext *shareCtx = 0;
+
+ c = (XMesaContext)Xmalloc(sizeof(struct xmesa_context));
+ if (!c) {
+ return 0;
+ }
+
+ mmesa = (mgaContextPtr)Xmalloc(sizeof(mgaContext));
+ if (!mmesa) {
+ Xfree(c);
+ return 0;
+ }
+
+ c->driContextPriv = driContextPriv;
+ c->xm_visual = v;
+ c->xm_buffer = 0; /* Set by MakeCurrent */
+ c->display = v->display;
+ c->private = (void *)mmesa;
+
+ if (share_list)
+ shareCtx=((mgaContextPtr)(share_list->private))->glCtx;
+
+ ctx = mmesa->glCtx = gl_create_context(v->gl_visual, shareCtx,
+ (void*)mmesa, GL_TRUE);
+
+ /* Dri stuff
+ */
+ mmesa->display = v->display;
+ mmesa->hHWContext = driContextPriv->hHWContext;
+ mmesa->driFd = sPriv->fd;
+ mmesa->driHwLock = &sPriv->pSAREA->lock;
+
+ mmesa->mgaScreen = mgaScreen;
+ mmesa->driScreen = sPriv;
+ mmesa->sarea = saPriv;
+
+ mmesa->glBuffer=gl_create_framebuffer(v->gl_visual);
+
+
+ mmesa->needClip=1;
+
+ mmesa->texHeap = mmInit( 0, mgaScreen->textureSize );
+
+ /* Utah stuff
+ */
+ mmesa->renderindex = -1; /* impossible value */
+ mmesa->new_state = ~0;
+ mmesa->dirty = ~0;
+
+ mmesa->warp_pipe = 0;
+
+
+ make_empty_list(&mmesa->SwappedOut);
+ make_empty_list(&mmesa->TexObjList);
+
+ mmesa->CurrentTexObj[0] = 0;
+ mmesa->CurrentTexObj[1] = 0;
+
+ mgaDDExtensionsInit( ctx );
+
+ mgaDDInitStateFuncs( ctx );
+ mgaDDInitTextureFuncs( ctx );
+ mgaDDInitSpanFuncs( ctx );
+ mgaDDInitDepthFuncs( ctx );
+ mgaDDInitDriverFuncs( ctx );
+ mgaDDInitIoctlFuncs( ctx );
+
+
+ ctx->Driver.TriangleCaps = (DD_TRI_CULL|
+ DD_TRI_LIGHT_TWOSIDE|
+ DD_TRI_OFFSET);
+
+ /* Ask mesa to clip fog coordinates for us.
+ */
+ ctx->TriangleCaps |= DD_CLIP_FOG_COORD;
+
+ ctx->Shared->DefaultD[2][0].DriverData = 0;
+ ctx->Shared->DefaultD[2][1].DriverData = 0;
+
+ if (ctx->VB)
+ mgaDDRegisterVB( ctx->VB );
+
+ if (ctx->NrPipelineStages)
+ ctx->NrPipelineStages =
+ mgaDDRegisterPipelineStages(ctx->PipelineStage,
+ ctx->PipelineStage,
+ ctx->NrPipelineStages);
+ return c;
+}
+
+void XMesaDestroyContext(XMesaContext c)
+{
+ mgaContextPtr mmesa = (mgaContextPtr) c->private;
+
+ if (mmesa) {
+/* mgaTextureObjectPtr next_t, t; */
+
+ gl_destroy_context(mmesa->glCtx);
+ gl_destroy_framebuffer(mmesa->glBuffer);
+
+/* foreach_s (t, next_t, &(mmesa->TexObjList)) */
+/* mgaDestroyTexObj(mmesa, t); */
+
+/* foreach_s (t, next_t, &(mmesa->SwappedOut)) */
+/* mgaDestroyTexObj(mmesa, t); */
+
+ Xfree(mmesa);
+
+ c->private = 0;
+ }
+}
+
+XMesaBuffer XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w,
+ __DRIdrawablePrivate *driDrawPriv)
+{
+ return (XMesaBuffer)1;
+}
+
+XMesaBuffer XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p,
+ XMesaColormap c,
+ __DRIdrawablePrivate *driDrawPriv)
+{
+ return (XMesaBuffer)1;
+}
+
+void XMesaDestroyBuffer(XMesaBuffer b)
+{
+}
+
+void XMesaSwapBuffers(XMesaBuffer bogus_value_do_not_use)
+{
+ mgaContextPtr mmesa = mgaCtx;
+ FLUSH_VB( mmesa->glCtx, "swap buffers" );
+ mgaSwapBuffers(mmesa);
+}
+
+
+
+
+
+void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa )
+{
+ __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+
+ mmesa->numClipRects = dPriv->numClipRects;
+ mmesa->pClipRects = dPriv->pClipRects;
+ mmesa->drawX = dPriv->x;
+ mmesa->drawY = dPriv->y;
+
+ mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
+}
+
+
+void mgaXMesaSetBackClipRects( mgaContextPtr mmesa )
+{
+ __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+
+ if (dPriv->numAuxClipRects == 0)
+ {
+ mmesa->numClipRects = dPriv->numClipRects;
+ mmesa->pClipRects = dPriv->pClipRects;
+ mmesa->drawX = dPriv->x;
+ mmesa->drawY = dPriv->y;
+ } else {
+ mmesa->numClipRects = dPriv->numAuxClipRects;
+ mmesa->pClipRects = dPriv->pAuxClipRects;
+ mmesa->drawX = dPriv->auxX;
+ mmesa->drawY = dPriv->auxY;
+ }
+
+ mmesa->drawOffset = mmesa->mgaScreen->backOffset;
+}
+
+
+static void mgaXMesaWindowMoved( mgaContextPtr mmesa )
+{
+ /* Clear any contaminated CVA data.
+ */
+ mmesa->setupdone = 0;
+
+ switch (mmesa->glCtx->Color.DriverDrawBuffer) {
+ case GL_FRONT_LEFT:
+ mgaXMesaSetFrontClipRects( mmesa );
+ break;
+ case GL_BACK_LEFT:
+ mgaXMesaSetBackClipRects( mmesa );
+ break;
+ default:
+ fprintf(stderr, "fallback buffer\n");
+ break;
+ }
+
+}
+
+
+/* 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???
+ */
+GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b)
+{
+
+ if (c->private==(void *)mgaCtx) return GL_TRUE;
+
+ if (c) {
+ __DRIdrawablePrivate *dPriv = c->driContextPriv->driDrawablePriv;
+
+ mgaCtx = (mgaContextPtr)c->private;
+
+
+ gl_make_current(mgaCtx->glCtx, mgaCtx->glBuffer);
+
+ mgaXMesaWindowMoved( mgaCtx );
+ mgaCtx->driDrawable = dPriv;
+ mgaCtx->dirty = ~0;
+
+ if (!mgaCtx->glCtx->Viewport.Width)
+ gl_Viewport(mgaCtx->glCtx, 0, 0, dPriv->w, dPriv->h);
+
+ } else {
+ gl_make_current(0,0);
+ mgaCtx = NULL;
+ }
+
+ return GL_TRUE;
+}
+
+
+void mgaXMesaUpdateState( mgaContextPtr mmesa )
+{
+ __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+ __DRIscreenPrivate *sPriv = mmesa->driScreen;
+ drm_mga_sarea_t *sarea = mmesa->sarea;
+
+ int me = mmesa->hHWContext;
+ int stamp = dPriv->lastStamp;
+
+ /* If the window moved, may need to set a new cliprect now.
+ *
+ * NOTE: This releases and regains the hw lock, so all state
+ * checking must be done *after* this call:
+ */
+ XMESA_VALIDATE_DRAWABLE_INFO(mmesa->display, sPriv, dPriv);
+
+ if (sarea->ctxOwner != me) {
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ }
+
+ if (sarea->texAge != mmesa->texAge) {
+ int sz = 1 << (mmesa->mgaScreen->logTextureGranularity);
+ int idx, nr = 0;
+
+ /* Have to go right round from the back to ensure stuff ends up
+ * LRU in our local list...
+ */
+ for (idx = sarea->texList[MGA_NR_TEX_REGIONS].prev ;
+ idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ;
+ idx = sarea->texList[idx].prev, nr++)
+ {
+ if (sarea->texList[idx].age > mmesa->texAge)
+ mgaTexturesGone(mmesa, idx * sz, sz, 1);
+ }
+
+ if (nr == MGA_NR_TEX_REGIONS) {
+ mgaTexturesGone(mmesa, 0, mmesa->mgaScreen->textureSize, 0);
+ mgaResetGlobalLRU( mmesa );
+ }
+
+ mmesa->texAge = sarea->texAge;
+ mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE;
+ }
+
+ if (dPriv->lastStamp != stamp)
+ mgaXMesaWindowMoved( mmesa );
+
+ sarea->ctxOwner=me;
+}
+
+
+
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h
new file mode 100644
index 000000000..c24e982d0
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h
@@ -0,0 +1,121 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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, 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 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keithw@precisioninsight.com>
+ * Daryll Strauss <daryll@precisioninsight.com> (Origninal tdfx driver).
+ *
+ * $PI: $
+ */
+
+#ifndef _MGA_INIT_H_
+#define _MGA_INIT_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <sys/time.h>
+#include "dri_tmm.h"
+#include "dri_mesaint.h"
+#include "dri_mesa.h"
+#include "types.h"
+#include "xmesaP.h"
+
+typedef struct {
+
+ int chipset;
+ int width;
+ int height;
+ int mem;
+
+ int cpp; /* for front and back buffers */
+
+ int Attrib;
+
+ int frontOffset;
+ int frontPitch;
+ int backOffset;
+ int backPitch;
+
+ int depthOffset;
+ int depthPitch;
+ int depthCpp;
+
+ int textureOffset;
+ int textureSize;
+ int logTextureGranularity;
+
+ __DRIscreenPrivate *sPriv;
+ drmBufMapPtr bufs;
+
+} mgaScreenPrivate;
+
+
+#include "mgalib.h"
+
+extern void mgaXMesaUpdateState( mgaContextPtr mmesa );
+extern void mgaEmitHwStateLocked( mgaContextPtr mmesa );
+extern void mgaEmitScissorValues( mgaContextPtr mmesa, int box_nr, int emit );
+extern void mgaXMesaSetBackClipRects( mgaContextPtr mmesa );
+extern void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa );
+
+
+
+/* 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) { \
+ drmGetLock(mmesa->driFd, mmesa->hHWContext, 0); \
+ mgaXMesaUpdateState( mmesa ); \
+ } \
+ } 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 ); \
+ UNLOCK_HARDWARE( mmesa ); \
+} while (0)
+
+
+#define GET_DRAWABLE_LOCK( mmesa ) while(0)
+#define RELEASE_DRAWABLE_LOCK( mmesa ) while(0)
+
+#endif
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaclear.c b/xc/lib/GL/mesa/src/drv/mga/mgaclear.c
new file mode 100644
index 000000000..48b9b30a7
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaclear.c
@@ -0,0 +1,10 @@
+#include "types.h"
+#include "vbrender.h"
+
+#include <stdio.h>
+
+#include "mm.h"
+#include "mgalib.h"
+#include "mgadd.h"
+#include "mgaclear.h"
+#include "mgastate.h"
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaclear.h b/xc/lib/GL/mesa/src/drv/mga/mgaclear.h
new file mode 100644
index 000000000..15a723d65
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaclear.h
@@ -0,0 +1,7 @@
+#ifndef _MGA_CLEAR_H
+#define _MGA_CLEAR_H
+
+extern GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c b/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c
new file mode 100644
index 000000000..ae8d95037
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c
@@ -0,0 +1,250 @@
+/* -*- mode: C; c-basic-offset:8 -*- */
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * original by Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ * 9/20/99 rewrite by John Carmack <johnc@idsoftware.com>
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <GL/gl.h>
+
+#include "mm.h"
+#include "mgalib.h"
+#include "mgatex.h"
+
+
+/*
+ * mgaConvertTexture
+ * Converts a mesa format texture to the apropriate 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( mgaUI32 *destPtr, int texelBytes,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height ) {
+ register int i, j;
+ mgaUI8 *src;
+ int stride;
+
+ /* 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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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 = (mgaUI8 *)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:
+
+ mgaError( "Unsupported texelBytes %i, image->Format %i\n",
+ texelBytes, image->Format );
+}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacommon.h b/xc/lib/GL/mesa/src/drv/mga/mgacommon.h
new file mode 100644
index 000000000..fd7c7987f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgacommon.h
@@ -0,0 +1,44 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+
+#ifndef MGACOMMON_INC
+#define MGACOMMON_INC
+
+typedef unsigned int mgaUI32;
+typedef unsigned short mgaUI16;
+typedef unsigned char mgaUI8;
+typedef int mgaI32;
+typedef short mgaI16;
+typedef char mgaI8;
+
+typedef mgaUI8 mgaColor[4];
+
+struct mga_context_t;
+typedef struct mga_context_t mgaContext;
+typedef struct mga_context_t *mgaContextPtr;
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.c b/xc/lib/GL/mesa/src/drv/mga/mgadd.c
new file mode 100644
index 000000000..ad56cbbc3
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.c
@@ -0,0 +1,146 @@
+/*
+ * GLX Hardware Device Driver for Matrox G200/G400
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+
+
+#include "types.h"
+#include "vbrender.h"
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mm.h"
+#include "mgalib.h"
+#include "mgaclear.h"
+#include "mgadd.h"
+#include "mgadepth.h"
+#include "mgalog.h"
+#include "mgastate.h"
+#include "mgaspan.h"
+#include "mgatex.h"
+#include "mgatris.h"
+#include "mgavb.h"
+#include "mgapipeline.h"
+#include "extensions.h"
+#include "vb.h"
+#include "dd.h"
+
+
+
+/***************************************
+ * Mesa's Driver Functions
+ ***************************************/
+
+
+static const GLubyte *mgaDDGetString( GLcontext *ctx, GLenum name )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ switch (name) {
+ case GL_VENDOR:
+ return "Utah GLX";
+ case GL_RENDERER:
+ if (MGA_IS_G200(mmesa)) return "GLX-MGA-G200";
+ if (MGA_IS_G400(mmesa)) return "GLX-MGA-G400";
+ return "GLX-MGA";
+ default:
+ return 0;
+ }
+}
+
+
+static GLint mgaGetParameteri(const GLcontext *ctx, GLint param)
+{
+ switch (param) {
+ case DD_HAVE_HARDWARE_FOG:
+ return 1;
+ default:
+ mgaError("mgaGetParameteri(): unknown parameter!\n");
+ return 0;
+ }
+}
+
+
+static void mgaBufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+/* 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 */
+ gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" );
+ gl_extensions_disable( ctx, "GL_EXT_paletted_texture" );
+
+ /* Support multitexture only on the g400.
+ */
+ if (!MGA_IS_G400(MGA_CONTEXT(ctx)))
+ {
+ gl_extensions_disable( ctx, "GL_EXT_multitexture" );
+ gl_extensions_disable( ctx, "GL_SGIS_multitexture" );
+ gl_extensions_disable( ctx, "GL_ARB_multitexture" );
+ }
+
+ /* Turn on texenv_add for the G400.
+ */
+ if (MGA_IS_G400(MGA_CONTEXT(ctx)))
+ {
+ gl_extensions_enable( ctx, "GL_EXT_texture_env_add" );
+ }
+
+ /* we don't support point parameters in hardware yet */
+ gl_extensions_disable( ctx, "GL_EXT_point_parameters" );
+
+ /* No support for fancy imaging stuff. This should kill off
+ * a few rogue fallbacks.
+ */
+ gl_extensions_disable( ctx, "ARB_imaging" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_minmax" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_subtract" );
+ gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" );
+}
+
+
+
+
+
+
+
+void mgaDDInitDriverFuncs( GLcontext *ctx )
+{
+ ctx->Driver.GetBufferSize = mgaBufferSize;
+ ctx->Driver.GetString = mgaDDGetString;
+ ctx->Driver.GetParameteri = mgaGetParameteri;
+ ctx->Driver.RegisterVB = mgaDDRegisterVB;
+ ctx->Driver.UnregisterVB = mgaDDUnregisterVB;
+ ctx->Driver.BuildPrecalcPipeline = mgaDDBuildPrecalcPipeline;
+}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.h b/xc/lib/GL/mesa/src/drv/mga/mgadd.h
new file mode 100644
index 000000000..0bd4c712e
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.h
@@ -0,0 +1,36 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+
+#ifndef MGADD_INC
+#define MGADD_INC
+
+#include "context.h"
+
+void mgaDDInitDriverFuncs( GLcontext *ctx );
+void mgaDDExtensionsInit( GLcontext *ctx );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadepth.c b/xc/lib/GL/mesa/src/drv/mga/mgadepth.c
new file mode 100644
index 000000000..0d55137d1
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgadepth.c
@@ -0,0 +1,636 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 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.
+ */
+
+/*
+ * This file has been modified by Wittawat Yamwong for GLX module.
+ */
+
+/*
+ * Depth buffer functions
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdlib.h>
+#include <string.h>
+#include "context.h"
+#include "mgadepth.h"
+#include "types.h"
+#include "mm.h"
+#include "mgalib.h"
+#endif
+
+
+
+/*
+ * Return the address of the Z-buffer value for window coordinate (x,y):
+ */
+#define Z_SETUP \
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
+ __DRIscreenPrivate *sPriv = mmesa->driScreen; \
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
+ GLdepth *zbstart = (GLdepth *)(sPriv->pFB + mgaScreen->depthOffset);\
+ GLint zbpitch = mgaScreen->depthPitch
+
+#define Z_ADDRESS( X, Y ) \
+ (zbstart + zbpitch * (Y) + (X))
+
+
+/**********************************************************************/
+/***** Depth Testing Functions *****/
+/**********************************************************************/
+
+
+/*
+ * Depth test horizontal spans of fragments. These functions are called
+ * via ctx->Driver.depth_test_span only.
+ *
+ * Input: n - number of pixels in the span
+ * x, y - location of leftmost pixel in span in window coords
+ * z - array [n] of integer depth values
+ * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
+ * Return: number of pixels which passed depth test
+ */
+
+
+/*
+ * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ */
+static GLuint mga_depth_test_span_generic( GLcontext* ctx,
+ GLuint n, GLint x, GLint y,
+ const GLdepth z[],
+ GLubyte mask[] )
+{
+ Z_SETUP;
+ GLdepth *zptr = Z_ADDRESS( x, y );
+ GLubyte *m = mask;
+ GLuint i;
+ GLuint passed = 0;
+
+ LOCK_HARDWARE(mmesa);
+
+ /* switch cases ordered from most frequent to less frequent */
+ switch (ctx->Depth.Func) {
+ case GL_LESS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] < *zptr) {
+ /* pass */
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ /* fail */
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] < *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_LEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] <= *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] <= *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] >= *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] >= *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GREATER:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] > *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] > *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_NOTEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] != *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] != *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_EQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] == *zptr) {
+ *zptr = z[i];
+ passed++;
+ }
+ else {
+ *m =0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ if (z[i] == *zptr) {
+ /* pass */
+ passed++;
+ }
+ else {
+ *m =0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_ALWAYS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0;i<n;i++,zptr++,m++) {
+ if (*m) {
+ *zptr = z[i];
+ passed++;
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer or mask */
+ passed = n;
+ }
+ break;
+ case GL_NEVER:
+ for (i=0;i<n;i++) {
+ mask[i] = 0;
+ }
+ break;
+ default:
+ }
+
+ UNLOCK_HARDWARE(mmesa);
+
+ return passed;
+}
+
+
+
+
+
+/*
+ * Depth test an array of randomly positioned fragments.
+ */
+
+/*
+ * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ */
+static void mga_depth_test_pixels_generic( GLcontext* ctx,
+ GLuint n,
+ const GLint x[], const GLint y[],
+ const GLdepth z[], GLubyte mask[] )
+{
+ Z_SETUP;
+ register GLdepth *zptr;
+ register GLuint i;
+
+ LOCK_HARDWARE(mmesa);
+
+ /* switch cases ordered from most frequent to less frequent */
+ switch (ctx->Depth.Func) {
+ case GL_LESS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] < *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] < *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_LEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] <= *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] <= *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] >= *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] >= *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_GREATER:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] > *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] > *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_NOTEQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] != *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] != *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_EQUAL:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] == *zptr) {
+ /* pass */
+ *zptr = z[i];
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ if (z[i] == *zptr) {
+ /* pass */
+ }
+ else {
+ /* fail */
+ mask[i] = 0;
+ }
+ }
+ }
+ }
+ break;
+ case GL_ALWAYS:
+ if (ctx->Depth.Mask) {
+ /* Update Z buffer */
+ for (i=0; i<n; i++) {
+ if (mask[i]) {
+ zptr = Z_ADDRESS(x[i],y[i]);
+ *zptr = z[i];
+ }
+ }
+ }
+ else {
+ /* Don't update Z buffer or mask */
+ }
+ break;
+ case GL_NEVER:
+ /* depth test never passes */
+ for (i=0;i<n;i++) {
+ mask[i] = 0;
+ }
+ break;
+ default:
+ }
+
+ UNLOCK_HARDWARE(mmesa);
+}
+
+
+
+/**********************************************************************/
+/***** Read Depth Buffer *****/
+/**********************************************************************/
+
+
+/*
+ * Return a span of depth values from the depth buffer as floats in [0,1].
+ * This function is only called through Driver.read_depth_span_float()
+ * Input: n - how many pixels
+ * x,y - location of first pixel
+ * Output: depth - the array of depth values
+ */
+static void mga_read_depth_span_float( GLcontext* ctx,
+ GLuint n, GLint x, GLint y,
+ GLfloat depth[] )
+{
+ Z_SETUP;
+ GLdepth *zptr;
+ GLfloat scale;
+ GLuint i;
+
+ LOCK_HARDWARE(mmesa);
+
+ scale = 1.0F / DEPTH_SCALE;
+
+ if (ctx->Buffer->Depth) {
+ zptr = Z_ADDRESS( x, y );
+ for (i=0;i<n;i++) {
+ depth[i] = (GLfloat) zptr[i] * scale;
+ }
+ }
+ else {
+ for (i=0;i<n;i++) {
+ depth[i] = 0.0F;
+ }
+ }
+
+ UNLOCK_HARDWARE(mmesa);
+}
+
+
+/*
+ * Return a span of depth values from the depth buffer as integers in
+ * [0,MAX_DEPTH].
+ * This function is only called through Driver.read_depth_span_int()
+ * Input: n - how many pixels
+ * x,y - location of first pixel
+ * Output: depth - the array of depth values
+ */
+static void mga_read_depth_span_int( GLcontext* ctx,
+ GLuint n, GLint x, GLint y,
+ GLdepth depth[] )
+{
+ Z_SETUP;
+
+ LOCK_HARDWARE(mmesa);
+
+ if (ctx->Buffer->Depth) {
+ GLdepth *zptr = Z_ADDRESS( x, y );
+ MEMCPY( depth, zptr, n * sizeof(GLdepth) );
+ }
+ else {
+ GLuint i;
+ for (i=0;i<n;i++) {
+ depth[i] = 0;
+ }
+ }
+
+ UNLOCK_HARDWARE(mmesa);
+}
+
+
+void mgaDDInitDepthFuncs( GLcontext *ctx )
+{
+ ctx->Driver.ReadDepthSpanFloat = mga_read_depth_span_float;
+ ctx->Driver.ReadDepthSpanInt = mga_read_depth_span_int;
+ ctx->Driver.DepthTestSpan = mga_depth_test_span_generic;
+ ctx->Driver.DepthTestPixels = mga_depth_test_pixels_generic;
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadepth.h b/xc/lib/GL/mesa/src/drv/mga/mgadepth.h
new file mode 100644
index 000000000..e47a114ee
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgadepth.h
@@ -0,0 +1,37 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 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.
+ */
+
+/*
+ * This file has been modified by Wittawat Yamwong for GLX module.
+ */
+
+
+#ifndef MGADEPTH_INC
+#define MGADEPTH_INC
+
+
+#include "types.h"
+void mgaDDInitDepthFuncs( GLcontext *ctx );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadma.c b/xc/lib/GL/mesa/src/drv/mga/mgadma.c
new file mode 100644
index 000000000..becfb32f5
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgadma.c
@@ -0,0 +1,59 @@
+/* -*- mode: C; c-basic-offset:8 -*- */
+/*
+ * GLX Hardware Device Driver for Matrox G200/G400
+ * Copyright (C) 1999 Jeff Hartmann
+ *
+ * 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
+ * JEFF HARTMANN, 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.
+ *
+ *
+ * original by Jeff Hartmann <slicer@ionet.net>
+ * 6/16/99: rewrite by John Carmack <johnc@idsoftware.com>
+ * 1/13/00: rewrite for DRI by Keith Whitwell <keithw@precisioninsight.com>
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "mm.h"
+#include "mgabuf.h"
+#include "mgadd.h"
+#include "mgalib.h"
+#include "mgalog.h"
+#include "mgastate.h"
+#include "mgaglx.h"
+
+#include "pb.h"
+
+
+
+
+
+
+
+
+
+
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadma.h b/xc/lib/GL/mesa/src/drv/mga/mgadma.h
new file mode 100644
index 000000000..9a02d1f36
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgadma.h
@@ -0,0 +1,41 @@
+/*
+ GLX Hardware Device Driver for Matrox Millenium G200
+ Copyright (C) 1999 Stephen Crowley (crow@debian.org)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ original by Jeff Hartmann <slicer@ionet.net>
+ 6/16/99: rewrite by John Carmack <johnc@idsoftware.com>
+*/
+
+#ifndef MGADMA_H
+#define MGADMA_H
+
+#include "mgacommon.h"
+#include "mm.h"
+#include <stdio.h>
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c
new file mode 100644
index 000000000..8017e7f02
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c
@@ -0,0 +1,529 @@
+/*
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+#include <stdio.h>
+
+#include "types.h"
+#include "enums.h"
+#include "cva.h"
+#include "vertices.h"
+#include "mmath.h"
+
+#include "mgalib.h"
+#include "mgapipeline.h"
+#include "mgatris.h"
+#include "mgastate.h"
+#include "mgavb.h"
+
+
+extern void mgaDDResizeVB( struct vertex_buffer *VB, GLuint size );
+
+extern void gl_fast_copy_vb( struct vertex_buffer *VB );
+
+struct mga_fast_tab {
+ void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest );
+ void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J );
+};
+
+
+
+
+#define POINT(x) mga_draw_point(mmesa, &ivert[x], psize)
+#define LINE(x,y) mga_draw_line(mmesa, &ivert[x], &ivert[y], lwidth)
+#define TRI(x,y,z) mga_draw_triangle(mmesa, &ivert[x], &ivert[y], &ivert[z])
+
+
+
+
+/* Direct, and no clipping required. I haven't written the clip funcs
+ * yet, so this is only useful for the fast path.
+ */
+#define RENDER_POINTS( start, count ) \
+do { \
+ GLuint e; \
+ for(e=start;e<=count;e++) \
+ POINT(elt[e]); \
+} while (0)
+
+#define RENDER_LINE( i1, i ) \
+do { \
+ GLuint e1 = elt[i1], e = elt[i]; \
+ LINE( e1, e ); \
+} while (0)
+
+
+#define RENDER_TRI( i2, i1, i, pv, parity) \
+do { \
+{ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ if (parity) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \
+ TRI(e2, e1, e); \
+}} while (0)
+
+
+#define RENDER_QUAD( i3, i2, i1, i, pv) \
+do { \
+ GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ TRI(e3, e2, e); \
+ TRI(e2, e1, e); \
+} while (0)
+
+#define LOCAL_VARS \
+ mgaVertexPtr ivert = MGA_DRIVER_DATA(VB)->verts; \
+ const GLuint *elt = VB->EltPtr->data; \
+ GLcontext *ctx = VB->ctx; \
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
+ const GLfloat lwidth = ctx->Line.Width; \
+ const GLfloat psize = ctx->Point.Size; \
+ (void) lwidth; (void)psize; (void) ivert;
+
+
+#define TAG(x) x##_mga_smooth_indirect
+#include "render_tmp.h"
+
+
+
+static void mga_render_elements_direct( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ GLenum prim = ctx->CVA.elt_mode;
+ GLuint nr = VB->EltPtr->count;
+ render_func func = render_tab_mga_smooth_indirect[prim];
+ GLuint p = 0;
+
+ if (mmesa->new_state)
+ mgaDDUpdateHwState( ctx );
+
+ do {
+ func( VB, 0, nr, 0 );
+ } while (ctx->Driver.MultipassFunc &&
+ ctx->Driver.MultipassFunc( VB, ++p ));
+}
+
+
+
+#define NEGATIVE(f) (f < 0)
+#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
+#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) )
+
+
+#define INTERP_RGBA(t, out, a, b) { \
+ int i; \
+ for (i = 0; i < 4; i++) { \
+ GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \
+ GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \
+ GLfloat fo = LINTERP(t, fa, fb); \
+ FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \
+ } \
+}
+
+
+#define CLIP(SGN,V,PLANE) \
+if (mask & PLANE) { \
+ GLuint *indata = inlist[in]; \
+ GLuint *outdata = inlist[in ^= 1]; \
+ GLuint nr = n; \
+ GLfloat *J = verts[indata[nr-1]].f; \
+ GLfloat dpJ = (SGN J[V]) + J[3]; \
+ \
+ inlist[0] = vlist1; \
+ for (i = n = 0 ; i < nr ; i++) { \
+ GLuint elt_i = indata[i]; \
+ GLfloat *I = verts[elt_i].f; \
+ GLfloat dpI = (SGN I[V]) + I[3]; \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t, *in, *out; \
+ \
+ if (NEGATIVE(dpI)) { \
+ t = dpI / (dpI - dpJ); \
+ in = I; \
+ out = J; \
+ } \
+ else \
+ { \
+ t = dpJ / (dpJ - dpI); \
+ in = J; \
+ out = I; \
+ } \
+ \
+ interp(t, O, in, out); \
+ \
+ clipmask[next_vert] = 0; \
+ outdata[n++] = next_vert++; \
+ } \
+ \
+ clipmask[elt_i] |= PLANE; /* don't set up */ \
+ \
+ if (!NEGATIVE(dpI)) { \
+ outdata[n++] = elt_i; \
+ clipmask[elt_i] &= ~PLANE; /* set up after all */ \
+ } \
+ \
+ J = I; \
+ dpJ = dpI; \
+ } \
+ \
+ if (n < 3) return; \
+}
+
+#define LINE_CLIP(x,y,z,w,PLANE) \
+if (mask & PLANE) { \
+ GLfloat dpI = DOT4V(I,x,y,z,w); \
+ GLfloat dpJ = DOT4V(J,x,y,z,w); \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t = dpI / (dpI - dpJ); \
+ \
+ interp(t, O, I, J); \
+ \
+ clipmask[next_vert] = 0; \
+ \
+ if (NEGATIVE(dpI)) { \
+ clipmask[elts[0]] |= PLANE; \
+ I = O; elts[0] = next_vert++; \
+ } else { \
+ clipmask[elts[1]] |= PLANE; \
+ J = O; elts[1] = next_vert++; \
+ } \
+ } \
+ else if (NEGATIVE(dpI)) \
+ return; \
+}
+
+
+static __inline void mga_tri_clip( GLuint **p_elts,
+ mgaVertex *verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ mga_interp_func interp )
+{
+ GLuint *elts = *p_elts;
+ GLuint next_vert = *p_next_vert;
+ GLuint vlist1[VB_MAX_CLIPPED_VERTS];
+ GLuint vlist2[VB_MAX_CLIPPED_VERTS];
+ GLuint *inlist[2];
+ GLuint *out;
+ GLuint in = 0;
+ GLuint n = 3;
+ GLuint i;
+
+ inlist[0] = elts;
+ inlist[1] = vlist2;
+
+ CLIP(-,0,CLIP_RIGHT_BIT);
+ CLIP(+,0,CLIP_LEFT_BIT);
+ CLIP(-,1,CLIP_TOP_BIT);
+ CLIP(+,1,CLIP_BOTTOM_BIT);
+ CLIP(-,2,CLIP_FAR_BIT);
+ CLIP(+,2,CLIP_NEAR_BIT);
+
+ /* Convert the planar polygon to a list of triangles.
+ */
+ out = inlist[in];
+
+ for (i = 2 ; i < n ; i++) {
+ elts[0] = out[0];
+ elts[1] = out[i-1];
+ elts[2] = out[i];
+ elts += 3;
+ }
+
+ *p_next_vert = next_vert;
+ *p_elts = elts;
+}
+
+
+static __inline void mga_line_clip( GLuint **p_elts,
+ mgaVertex *verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ mga_interp_func interp )
+{
+ GLuint *elts = *p_elts;
+ GLfloat *I = verts[elts[0]].f;
+ GLfloat *J = verts[elts[1]].f;
+ GLuint next_vert = *p_next_vert;
+
+ LINE_CLIP(1,0,0,-1,CLIP_LEFT_BIT);
+ LINE_CLIP(-1,0,0,1,CLIP_RIGHT_BIT);
+ LINE_CLIP(0,1,0,-1,CLIP_TOP_BIT);
+ LINE_CLIP(0,-1,0,1,CLIP_BOTTOM_BIT);
+ LINE_CLIP(0,0,1,-1,CLIP_FAR_BIT);
+ LINE_CLIP(0,0,-1,1,CLIP_NEAR_BIT);
+
+ *p_next_vert = next_vert;
+ *p_elts += 2;
+}
+
+
+
+#define CLIP_POINT( e ) \
+ if (mask[e]) \
+ *out++ = e
+
+#define CLIP_LINE( e1, e0 ) \
+do { \
+ GLubyte ormask = mask[e0] | mask[e1]; \
+ out[0] = e1; \
+ out[1] = e0; \
+ out+=2; \
+ if (ormask) { \
+ out-=2; \
+ if (!(mask[e0] & mask[e1])) { \
+ mga_line_clip( &out, verts, mask, &next_vert, ormask, interp); \
+ } \
+ } \
+} while (0)
+
+#define CLIP_TRIANGLE( e2, e1, e0 ) \
+do { \
+ GLubyte ormask; \
+ out[0] = e2; \
+ out[1] = e1; \
+ out[2] = e0; \
+ out += 3; \
+ ormask = mask[e2] | mask[e1] | mask[e0]; \
+ if (ormask) { \
+ out -= 3; \
+ if ( !(mask[e2] & mask[e1] & mask[e0])) { \
+ mga_tri_clip( &out, verts, mask, &next_vert, ormask, interp ); \
+ } \
+ } \
+} while (0)
+
+
+
+
+
+
+/* Build a table of functions to clip each primitive type. These
+ * produce a list of elements in the appropriate 'reduced' primitive,
+ * ie (points, lines, triangles) containing all the clipped and
+ * unclipped primitives from the original list.
+ */
+#define LOCAL_VARS \
+ mgaContextPtr mmesa = MGA_CONTEXT( VB->ctx ); \
+ GLuint *elt = VB->EltPtr->data; \
+ mgaVertex *verts = MGA_DRIVER_DATA(VB)->verts; \
+ GLuint next_vert = MGA_DRIVER_DATA(VB)->last_vert; \
+ GLuint *out = MGA_DRIVER_DATA(VB)->clipped_elements.data; \
+ GLubyte *mask = VB->ClipMask; \
+ mga_interp_func interp = mmesa->interp; \
+ (void) interp; (void) verts;
+
+#define POSTFIX \
+ MGA_DRIVER_DATA(VB)->clipped_elements.count = \
+ out - MGA_DRIVER_DATA(VB)->clipped_elements.data; \
+ MGA_DRIVER_DATA(VB)->last_vert = next_vert;
+
+
+#define INIT(x)
+
+#define RENDER_POINTS(start, count) \
+do { \
+ GLuint i; \
+ for (i = start ; i < count ; i++ ) \
+ CLIP_POINT( elt[i] ); \
+} while (0)
+
+#define RENDER_LINE(i1, i0) \
+ CLIP_LINE(elt[i1], elt[i0])
+
+#define RENDER_TRI(i2, i1, i0, pv, parity) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \
+ if (parity) e2 = elt[i1], e1 = elt[i2]; \
+ CLIP_TRIANGLE( e2, e1, e0 ); \
+} while (0)
+
+#define RENDER_QUAD(i3, i2, i1, i0, pv ) \
+ CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \
+ CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0])
+
+#define TAG(x) mga_clip_##x##_elt
+#include "render_tmp.h"
+
+
+
+static void mga_project_vertices( struct vertex_buffer *VB )
+{
+ mgaVertexBufferPtr mgaVB = MGA_DRIVER_DATA(VB);
+ GLcontext *ctx = VB->ctx;
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ GLfloat m[16];
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX] + mmesa->drawX - .5;
+ m[MAT_SY] = (- mat->m[MAT_SY]);
+ m[MAT_TY] = (- mat->m[MAT_TY]) + mmesa->driDrawable->h + mmesa->drawY - .5;
+ m[MAT_SZ] = mat->m[MAT_SZ] * (1.0 / 0x10000);
+ m[MAT_TZ] = mat->m[MAT_TZ] * (1.0 / 0x10000);
+
+ gl_project_v16( mgaVB->verts[VB->CopyStart].f,
+ mgaVB->verts[mgaVB->last_vert].f,
+ m,
+ 16 * 4 );
+}
+
+static void mga_project_clipped_vertices( struct vertex_buffer *VB )
+{
+ mgaVertexBufferPtr mgaVB = MGA_DRIVER_DATA(VB);
+ GLcontext *ctx = VB->ctx;
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ GLfloat m[16];
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX] + mmesa->drawX - .5;
+ m[MAT_SY] = (- mat->m[MAT_SY]);
+ m[MAT_TY] = (- mat->m[MAT_TY]) + mmesa->driDrawable->h + mmesa->drawY - .5;
+ m[MAT_SZ] = mat->m[MAT_SZ] * (1.0 / 0x10000);
+ m[MAT_TZ] = mat->m[MAT_TZ] * (1.0 / 0x10000);
+
+ gl_project_clipped_v16( mgaVB->verts[VB->CopyStart].f,
+ mgaVB->verts[mgaVB->last_vert].f,
+ m,
+ 16 * 4,
+ VB->ClipMask + VB->CopyStart );
+}
+
+
+/* Pack rgba and/or texture into the remaining half of a 32 byte vertex.
+ */
+#define CLIP_UBYTE_COLOR 4
+#define CLIP_UBYTE_B 0
+#define CLIP_UBYTE_G 1
+#define CLIP_UBYTE_R 2
+#define CLIP_UBYTE_A 3
+#define CLIP_S0 6
+#define CLIP_T0 7
+#define CLIP_S1 8
+#define CLIP_T1 9
+
+#define TYPE (0)
+#define TAG(x) x
+#include "mgafasttmp.h"
+
+#define TYPE (MGA_RGBA_BIT)
+#define TAG(x) x##_RGBA
+#include "mgafasttmp.h"
+
+#define TYPE (MGA_TEX0_BIT)
+#define TAG(x) x##_TEX0
+#include "mgafasttmp.h"
+
+#define TYPE (MGA_RGBA_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_RGBA_TEX0
+#include "mgafasttmp.h"
+
+#define TYPE (MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_RGBA_TEX0_TEX1
+#include "mgafasttmp.h"
+
+#define TYPE (MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_TEX0_TEX1
+#include "mgafasttmp.h"
+
+
+/* Very sparsely popluated array - fix the indices.
+ */
+static struct mga_fast_tab mgaFastTab[0x80];
+
+void mgaDDFastPathInit( void )
+{
+ mga_clip_render_init_elt();
+ render_init_mga_smooth_indirect();
+
+ mga_init_fastpath( &mgaFastTab[0] );
+ mga_init_fastpath_RGBA( &mgaFastTab[MGA_RGBA_BIT] );
+ mga_init_fastpath_TEX0( &mgaFastTab[MGA_TEX0_BIT] );
+ mga_init_fastpath_RGBA_TEX0( &mgaFastTab[MGA_RGBA_BIT|MGA_TEX0_BIT] );
+ mga_init_fastpath_TEX0_TEX1( &mgaFastTab[MGA_TEX0_BIT|MGA_TEX1_BIT] );
+ mga_init_fastpath_RGBA_TEX0_TEX1( &mgaFastTab[MGA_RGBA_BIT|MGA_TEX0_BIT|
+ MGA_TEX1_BIT] );
+}
+
+#define VALID_SETUP (MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+
+
+void mgaDDFastPath( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ GLenum prim = ctx->CVA.elt_mode;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ struct mga_fast_tab *tab = &mgaFastTab[mmesa->setupindex & VALID_SETUP];
+ GLuint do_cliptest = 1;
+
+ gl_prepare_arrays_cva( VB ); /* still need this */
+
+ /* Reserve enough space for the pathological case.
+ */
+ if (VB->EltPtr->count * 12 > MGA_DRIVER_DATA(VB)->size) {
+ mgaDDResizeVB( VB, VB->EltPtr->count * 12 );
+ do_cliptest = 1;
+ }
+
+ tab->build_vertices( VB, do_cliptest ); /* object->clip space */
+
+ if (mmesa->new_state)
+ mgaDDUpdateHwState( ctx );
+
+ if (VB->ClipOrMask) {
+ if (!VB->ClipAndMask) {
+ render_func *clip = mga_clip_render_tab_elt;
+
+ mmesa->interp = tab->interp;
+
+ clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */
+
+ ctx->CVA.elt_mode = gl_reduce_prim[prim];
+ VB->EltPtr = &(MGA_DRIVER_DATA(VB)->clipped_elements);
+
+ LOCK_HARDWARE( mmesa );
+ mga_project_clipped_vertices( VB ); /* clip->device space */
+ mga_render_elements_direct( VB ); /* render using new list */
+ mgaFlushVerticesLocked( mmesa );
+ UNLOCK_HARDWARE( mmesa );
+ }
+ } else {
+ LOCK_HARDWARE( mmesa );
+ mga_project_vertices( VB ); /* clip->device space */
+ mga_render_elements_direct( VB ); /* render using orig list */
+ mgaFlushVerticesLocked( mmesa );
+ UNLOCK_HARDWARE( mmesa );
+ }
+
+ /* This indicates that there is no cached data to reuse.
+ */
+ VB->pipeline->data_valid = 0;
+ VB->pipeline->new_state = 0;
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h b/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h
new file mode 100644
index 000000000..43caddcac
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h
@@ -0,0 +1,143 @@
+/*
+ * DRI Hardware Device Driver for G200/G400
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * 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
+ * KEITH WHITWELL, 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.
+ *
+ */
+
+
+
+/* The first part of setup is applied to all vertices, clipped or
+ * unclipped. This data will be used for clipping, and then all
+ * vertices with a zero clipmask will be projected to device space.
+ *
+ * This could be split into several loops, but - it seems that the
+ * large stride of the fxVertices makes cache issues the big
+ * performance factor, and that multiple loops mean multiple cache
+ * misses....
+ */
+static void TAG(mga_setup_full)( struct vertex_buffer *VB, GLuint do_cliptest )
+{
+ GLcontext *ctx = VB->ctx;
+ const GLfloat * const m = ctx->ModelProjectMatrix.m;
+ GLuint start = VB->CopyStart;
+ GLuint count = VB->Count;
+ GLuint i;
+
+ gl_xform_points3_v16_general(MGA_DRIVER_DATA(VB)->verts[start].f,
+ m,
+ VB->ObjPtr->start,
+ VB->ObjPtr->stride,
+ count - start);
+
+ if (do_cliptest)
+ {
+ VB->ClipAndMask = ~0;
+ VB->ClipOrMask = 0;
+ gl_cliptest_points4_v16(MGA_DRIVER_DATA(VB)->verts[start].f,
+ MGA_DRIVER_DATA(VB)->verts[count].f,
+ &(VB->ClipOrMask),
+ &(VB->ClipAndMask),
+ VB->ClipMask + start);
+ }
+
+ /* These branches are all resolved at compile time. Hopefully all
+ * the pointers are valid addresses even when not enabled.
+ */
+ if (TYPE) {
+ GLubyte *color = VB->ColorPtr->start;
+ GLfloat *tex0_data = VB->TexCoordPtr[0]->start;
+ GLfloat *tex1_data = VB->TexCoordPtr[1]->start;
+
+ GLuint color_stride = VB->ColorPtr->stride;
+ GLuint tex0_stride = VB->TexCoordPtr[0]->stride;
+ GLuint tex1_stride = VB->TexCoordPtr[1]->stride;
+
+ GLfloat *f = MGA_DRIVER_DATA(VB)->verts[start].f;
+
+ for (i = start ; i < count ; i++, f += 16) {
+ if (TYPE & MGA_RGBA_BIT) {
+ GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR];
+ GLubyte *col = color; color += color_stride;
+ b[CLIP_UBYTE_R] = col[0];
+ b[CLIP_UBYTE_G] = col[1];
+ b[CLIP_UBYTE_B] = col[2];
+ b[CLIP_UBYTE_A] = col[3];
+ }
+ if (TYPE & MGA_TEX0_BIT) {
+ f[CLIP_S0] = tex0_data[0];
+ f[CLIP_T0] = tex0_data[1];
+ STRIDE_F(tex0_data, tex0_stride);
+ }
+ if (TYPE & MGA_TEX1_BIT) {
+ f[CLIP_S1] = tex1_data[0];
+ f[CLIP_T1] = tex1_data[1];
+ STRIDE_F(tex1_data, tex1_stride);
+ }
+ }
+ }
+
+ MGA_DRIVER_DATA(VB)->clipped_elements.count = start;
+ MGA_DRIVER_DATA(VB)->last_vert = count;
+}
+
+
+/* Changed to just put the interp func instead of the whole clip
+ * routine into the header. Less code and better chance of doing some
+ * of this stuff in assembly.
+ */
+static void TAG(mga_interp_vert)( GLfloat t,
+ GLfloat *O,
+ const GLfloat *I,
+ const GLfloat *J )
+{
+ O[0] = LINTERP(t, I[0], J[0]);
+ O[1] = LINTERP(t, I[1], J[1]);
+ O[2] = LINTERP(t, I[2], J[2]);
+ O[3] = LINTERP(t, I[3], J[3]);
+
+ if (TYPE & MGA_RGBA_BIT) {
+ INTERP_RGBA(t,
+ ((GLubyte *)&(O[4])),
+ ((GLubyte *)&(I[4])),
+ ((GLubyte *)&(J[4])));
+ }
+
+ if (TYPE & MGA_TEX0_BIT) {
+ O[6] = LINTERP(t, I[6], J[6]);
+ O[7] = LINTERP(t, I[7], J[7]);
+ }
+
+ if (TYPE & MGA_TEX1_BIT) {
+ O[8] = LINTERP(t, I[8], J[8]);
+ O[9] = LINTERP(t, I[9], J[9]);
+ }
+}
+
+
+static void TAG(mga_init_fastpath)( struct mga_fast_tab *tab )
+{
+ tab->interp = TAG(mga_interp_vert);
+ tab->build_vertices = TAG(mga_setup_full);
+}
+
+#undef TYPE
+#undef TAG
+#undef SIZE
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c
new file mode 100644
index 000000000..c1819924d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c
@@ -0,0 +1,321 @@
+#include <stdio.h>
+
+
+#include "types.h"
+#include "pb.h"
+#include "dd.h"
+
+#include "mm.h"
+#include "mgalib.h"
+#include "mgadd.h"
+#include "mgastate.h"
+#include "mgadepth.h"
+#include "mgatex.h"
+#include "mgalog.h"
+#include "mgavb.h"
+#include "mgatris.h"
+
+#include "drm.h"
+#include <sys/ioctl.h>
+
+static void mga_iload_dma_ioctl(mgaContextPtr mmesa,
+ int x1, int y1, int x2, int y2,
+ unsigned long dest, unsigned int maccess)
+{
+ int retcode;
+ drm_mga_iload_t iload;
+ drmBufPtr buf = mmesa->dma_buffer;
+
+ iload.idx = buf->idx;
+ iload.destOrg = dest;
+ iload.mAccess = maccess;
+ iload.texture.x1 = x1;
+ iload.texture.y1 = y1;
+ iload.texture.y2 = x2;
+ iload.texture.x2 = y2;
+
+ if ((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_ILOAD, &iload))) {
+ printf("send iload retcode = %d\n", retcode);
+ exit(1);
+ }
+}
+
+
+static void mga_vertex_dma_ioctl(mgaContextPtr mmesa)
+{
+ int retcode;
+ int size = MGA_DMA_BUF_SZ;
+ drmDMAReq dma;
+ drmBufPtr buf = mmesa->dma_buffer;
+
+ dma.context = mmesa->hHWContext;
+ dma.send_count = 1;
+ dma.send_list = &buf->idx;
+ dma.send_sizes = &size;
+ dma.flags = DRM_DMA_WAIT;
+ dma.request_count = 0;
+ dma.request_size = 0;
+ dma.request_list = 0;
+ dma.request_sizes = 0;
+
+ if ((retcode = drmDMA(mmesa->driFd, &dma))) {
+ printf("send iload retcode = %d\n", retcode);
+ exit(1);
+ }
+}
+
+
+static void mga_get_buffer_ioctl( mgaContextPtr mmesa )
+{
+ int idx = 0;
+ int size = 0;
+ drmDMAReq dma;
+ int retcode;
+
+ fprintf(stderr, "Getting dma buffer\n");
+
+ dma.context = mmesa->hHWContext;
+ dma.send_count = 0;
+ dma.send_list = NULL;
+ dma.send_sizes = NULL;
+ dma.flags = DRM_DMA_WAIT;
+ dma.request_count = 1;
+ dma.request_size = MGA_DMA_BUF_SZ;
+ dma.request_list = &idx;
+ dma.request_sizes = &size;
+
+ if ((retcode = drmDMA(mmesa->driFd, &dma))) {
+ fprintf(stderr, "request drmDMA retcode = %d\n", retcode);
+ exit(1);
+ }
+
+ mmesa->dma_buffer = &mmesa->mgaScreen->bufs->list[idx];
+}
+
+static void mga_swap_ioctl( mgaContextPtr mmesa )
+{
+ int retcode;
+ drm_mga_swap_t swap;
+
+ if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) {
+ printf("send swap retcode = %d\n", retcode);
+ exit(1);
+ }
+}
+
+
+
+static void mga_clear_ioctl( mgaContextPtr mmesa, int flags, int col, int zval )
+{
+ int retcode;
+ drm_mga_clear_t clear;
+
+ clear.flags = flags;
+ clear.clear_color = col;
+ clear.clear_depth = zval;
+
+ if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_CLEAR, &clear))) {
+ printf("send clear retcode = %d\n", retcode);
+ exit(1);
+ }
+}
+
+
+
+
+
+
+
+GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ GLuint c = mmesa->ClearColor;
+ mgaUI32 zval = (mgaUI32) (ctx->Depth.Clear * DEPTH_SCALE);
+ __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+ int flags = 0;
+ int i;
+
+ mgaMsg( 10, "mgaClear( %i, %i, %i, %i, %i )\n",
+ mask, x, y, width, height );
+
+
+ mgaFlushVertices( mmesa );
+
+
+ if (mask & GL_COLOR_BUFFER_BIT) {
+ if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT) {
+ flags |= MGA_CLEAR_FRONT;
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ } else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT) {
+ flags |= MGA_CLEAR_BACK;
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ }
+ }
+
+ if ((flags & GL_DEPTH_BUFFER_BIT) && ctx->Depth.Mask) {
+ flags |= MGA_CLEAR_DEPTH;
+ mask &= ~GL_DEPTH_BUFFER_BIT;
+ }
+
+ if (!flags)
+ return mask;
+
+ LOCK_HARDWARE( mmesa );
+
+ /* flip top to bottom */
+ cy = dPriv->h-cy-ch;
+ cx += mmesa->drawX;
+ cy += mmesa->drawY;
+
+ for (i = 0 ; i < dPriv->numClipRects ; ) {
+
+ /* Use the cliprects for the current draw buffer
+ */
+ int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects);
+ XF86DRIClipRectRec *box = mmesa->pClipRects;
+ xf86drmClipRectRec *b = mmesa->sarea->boxes;
+ mmesa->sarea->nbox = nr - i;
+
+ 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++;
+ }
+ } else {
+ for ( ; i < nr ; i++)
+ *b++ = *(xf86drmClipRectRec *)&box[i];
+ }
+
+ mga_clear_ioctl( mmesa, mask, c, zval );
+ }
+
+ UNLOCK_HARDWARE( mmesa );
+ return mask;
+}
+
+
+
+
+/*
+ * Copy the back buffer to the front buffer.
+ */
+void mgaSwapBuffers( mgaContextPtr mmesa )
+{
+ __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+ int i;
+
+ mgaFlushVertices( mmesa );
+
+ LOCK_HARDWARE( mmesa );
+ {
+ /* Use the frontbuffer cliprects
+ */
+ XF86DRIClipRectPtr pbox = dPriv->pClipRects;
+ int nbox = dPriv->numClipRects;
+
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+ XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes;
+ mmesa->sarea->nbox = nr - i;
+
+ for ( ; i < nr ; i++)
+ *b++ = pbox[i];
+
+ mga_swap_ioctl( mmesa );
+ }
+ }
+
+
+#if 1
+ UNLOCK_HARDWARE(mmesa);
+#else
+ {
+ last_enqueue = mmesa->sarea->lastEnqueue;
+ last_dispatch = mmesa->sarea->lastDispatch;
+ UNLOCK_HARDWARE;
+
+ /* Throttle runaway apps - there should be an easier way to sleep
+ * on dma without locking out the rest of the system!
+ */
+ if (mmesa->lastSwap > last_dispatch) {
+ drmGetLock(mmesa->driFd, mmesa->hHWContext, DRM_LOCK_QUIESCENT);
+ DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
+ }
+
+ mmesa->lastSwap = last_enqueue;
+ }
+#endif
+}
+
+
+/* This is overkill
+ */
+void mgaDDFinish( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ drmGetLock(mmesa->driFd, mmesa->hHWContext, DRM_LOCK_QUIESCENT);
+ DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
+}
+
+
+
+
+void mgaFlushVertices( mgaContextPtr mmesa )
+{
+ LOCK_HARDWARE( mmesa );
+ mgaFlushVerticesLocked( mmesa );
+ UNLOCK_HARDWARE( mmesa );
+}
+
+
+void mgaFlushVerticesLocked( mgaContextPtr mmesa )
+{
+ XF86DRIClipRectPtr pbox = mmesa->pClipRects;
+ int nbox = mmesa->numClipRects;
+ int i;
+
+ if (mmesa->dirty)
+ mgaEmitHwStateLocked( mmesa );
+
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
+ XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes;
+ mmesa->sarea->nbox = nr - i;
+
+ for ( ; i < nr ; i++)
+ *b++ = pbox[i];
+
+ mga_vertex_dma_ioctl( mmesa );
+
+ break; /* fix dma multiple dispatch */
+ }
+
+ mga_get_buffer_ioctl( mmesa );
+}
+
+
+
+void mgaDDInitIoctlFuncs( GLcontext *ctx )
+{
+ ctx->Driver.Clear = mgaClear;
+ ctx->Driver.Flush = 0;
+ ctx->Driver.Finish = mgaDDFinish;
+}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h
new file mode 100644
index 000000000..22ca26e17
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h
@@ -0,0 +1,23 @@
+#ifndef MGA_IOCTL_H
+#define MGA_IOCTL_H
+
+#include "mgalib.h"
+
+GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch );
+
+
+void mgaSwapBuffers( mgaContextPtr mmesa );
+
+void mgaFlushVertices( mgaContextPtr mmesa );
+void mgaFlushVerticesLocked( mgaContextPtr mmesa );
+
+/* upload texture
+ */
+
+void mgaDDFinish( GLcontext *ctx );
+
+void mgaDDInitIoctlFuncs( GLcontext *ctx );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgalib.h b/xc/lib/GL/mesa/src/drv/mga/mgalib.h
new file mode 100644
index 000000000..4600a69a0
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgalib.h
@@ -0,0 +1,266 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+
+#ifndef MGALIB_INC
+#define MGALIB_INC
+
+#include <X11/Xlibint.h>
+#include "dri_tmm.h"
+#include "dri_mesaint.h"
+#include "dri_mesa.h"
+#include "xmesaP.h"
+
+#include "types.h"
+
+#include "mgacommon.h"
+#include "mm.h"
+#include "mgalog.h"
+#include "mgaioctl.h"
+#include "mgatex.h"
+#include "mgavb.h"
+
+#include "mga_drm_public.h"
+#include "mga_xmesa.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_CHIP_MGAG200 0
+#define MGA_CHIP_MGAG400 1
+
+#define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CHIP_MGAG200)
+#define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CHIP_MGAG400)
+
+
+/* SoftwareFallback
+ * - texture env GL_BLEND -- can be fixed
+ * - 1D and 3D textures
+ * - incomplete textures
+ */
+#define MGA_FALLBACK_TEXTURE 0x1
+#define MGA_FALLBACK_BUFFER 0x2
+
+
+/* For mgaCtx->new_state.
+ */
+#define MGA_NEW_DEPTH 0x1
+#define MGA_NEW_ALPHA 0x2
+#define MGA_NEW_FOG 0x4
+#define MGA_NEW_CLIP 0x8
+#define MGA_NEW_MASK 0x10
+#define MGA_NEW_TEXTURE 0x20
+#define MGA_NEW_CULL 0x40
+#define MGA_NEW_WARP 0x80
+#define MGA_NEW_CONTEXT 0x100
+
+
+typedef void (*mga_interp_func)( GLfloat t,
+ GLfloat *result,
+ const GLfloat *in,
+ const GLfloat *out );
+
+
+
+
+/* if type == MGA_COLORBUFFER */
+#define MGA_PF_MASK 0xf0
+#define MGA_PF_INDEX 0
+#define MGA_PF_565 (1 << 4)
+#define MGA_PF_555 (9 << 4)
+#define MGA_PF_888 (3 << 4)
+#define MGA_PF_8888 (10 << 4)
+#define MGA_PF_HASALPHA (8 << 4)
+
+struct mga_context_t {
+
+ GLcontext *glCtx;
+
+ /* Hardware state - moved from mgabuf.h
+ */
+ mgaUI32 Setup[MGA_CTX_SETUP_SIZE];
+
+ /* Variable sized vertices
+ */
+ mgaUI32 vertsize;
+
+ /* Map GL texture units onto hardware.
+ */
+ mgaUI32 multitex;
+ mgaUI32 tmu_source[2];
+ mgaUI32 tex_dest[2];
+
+
+
+ /* bookkeeping for textureing */
+ struct mga_texture_object_s TexObjList;
+ struct mga_texture_object_s SwappedOut;
+ struct mga_texture_object_s *CurrentTexObj[2];
+
+
+ /* shared texture palette */
+ mgaUI16 GlobalPalette[256];
+
+ int Fallback; /* or'ed values of FALLBACK_* */
+
+ /* Support for CVA and the fast paths */
+ unsigned int setupdone;
+ unsigned int setupindex;
+ unsigned int renderindex;
+ unsigned int using_fast_path;
+ unsigned int using_immediate_fast_path;
+ mga_interp_func interp;
+
+ /* Shortcircuit some state changes */
+ points_func PointsFunc;
+ line_func LineFunc;
+ triangle_func TriangleFunc;
+ quad_func QuadFunc;
+
+ /* Manage our own state */
+ GLuint new_state;
+ GLuint dirty;
+
+ GLubyte clearcolor[4];
+ GLushort MonoColor;
+ GLushort ClearColor;
+
+
+ /* DRI stuff
+ */
+ drmBufPtr dma_buffer;
+
+ GLframebuffer *glBuffer;
+ memHeap_t *texHeap;
+
+ GLuint needClip;
+ GLuint warp_pipe;
+
+ /* These refer to the current draw (front vs. back) buffer:
+ */
+ int drawOffset; /* draw buffer address in agp space */
+ int drawX; /* origin of drawable in draw buffer */
+ int drawY;
+ GLuint numClipRects; /* cliprects for that buffer */
+ XF86DRIClipRectPtr pClipRects;
+
+ int texAge;
+
+ XF86DRIClipRectRec draw_rect;
+
+ drmContext hHWContext;
+ drmLock *driHwLock;
+ int driFd;
+ Display *display;
+
+ __DRIdrawablePrivate *driDrawable;
+ __DRIscreenPrivate *driScreen;
+ mgaScreenPrivate *mgaScreen;
+ drm_mga_sarea_t *sarea;
+};
+
+
+
+
+typedef struct {
+
+ /* dma stuff */
+ mgaUI32 systemTexture;
+ mgaUI32 noSetupDma;
+
+ mgaUI32 default32BitTextures;
+ mgaUI32 swapBuffersCount;
+
+ /* options */
+ mgaUI32 nullprims; /* skip all primitive generation */
+ mgaUI32 noFallback; /* don't fall back to software, do
+ best-effort rendering */
+ mgaUI32 skipDma; /* don't send anything to the hardware */
+
+ /* performance counters */
+ mgaUI32 c_textureUtilization;
+ mgaUI32 c_textureSwaps;
+ mgaUI32 c_setupPointers;
+ mgaUI32 c_triangles;
+ mgaUI32 c_points;
+ mgaUI32 c_lines;
+ mgaUI32 c_drawWaits;
+ mgaUI32 c_dmaFlush;
+ mgaUI32 c_overflows;
+
+} mgaGlx_t;
+
+extern mgaGlx_t mgaglx;
+
+
+#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 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 MGA_DEBUG_ALWAYS_SYNC 0x1
+#define MGA_DEBUG_VERBOSE_MSG 0x2
+#define MGA_DEBUG_VERBOSE_LRU 0x4
+#define MGA_DEBUG_VERBOSE_DRI 0x8
+
+static __inline__ mgaUI32 mgaPackColor(mgaUI32 format,
+ mgaUI8 r, mgaUI8 g,
+ mgaUI8 b, mgaUI8 a)
+{
+ switch (format & MGA_PF_MASK) {
+ case MGA_PF_555:
+ return MGAPACKCOLOR555(r,g,b,a);
+ case MGA_PF_565:
+ return MGAPACKCOLOR565(r,g,b);
+ case MGA_PF_888:
+ return MGAPACKCOLOR888(r,g,b);
+ case MGA_PF_8888:
+ return MGAPACKCOLOR8888(r,g,b,a);
+ default:
+ return 0;
+ }
+}
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgalog.h b/xc/lib/GL/mesa/src/drv/mga/mgalog.h
new file mode 100644
index 000000000..74f52f8d6
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgalog.h
@@ -0,0 +1,47 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+/* Usage:
+ * - use mgaError for error messages. Always write to X error and log file.
+ * - use mgaMsg for debugging. Can be disabled by undefining MGA_LOG_ENABLED.
+ */
+
+#ifndef MGALOG_INC
+#define MGALOG_INC
+#include "hwlog.h"
+
+/* Mapping between old function names and new common code: */
+/* (Feel free to replace all mgaMsg with hwMsg etc. in all *.c
+ * files, I was to lazy to do this...) */
+#define mgaOpenLog(f) hwOpenLog(f,"[mga] ")
+#define mgaCloseLog hwCloseLog
+#define mgaIsLogReady hwIsLogReady
+#define mgaSetLogLevel hwSetLogLevel
+#define mgaGetLogLevel hwGetLogLevel
+#define mgaMsg hwMsg
+#define mgaError hwError
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapipeline.c b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.c
new file mode 100644
index 000000000..8f8fea669
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.c
@@ -0,0 +1,138 @@
+/* #include "mgapipeline.h" */
+
+#include <stdio.h>
+#include "mgavb.h"
+#include "mgadd.h"
+#include "mgalib.h"
+#include "mgatris.h"
+#include "mgapipeline.h"
+#include "fog.h"
+
+static struct gl_pipeline_stage mga_fast_stage = {
+ "MGA fast path",
+ (PIPE_OP_VERT_XFORM|PIPE_OP_RAST_SETUP_0|
+ PIPE_OP_RAST_SETUP_1|PIPE_OP_RENDER),
+ PIPE_PRECALC,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ mgaDDFastPath
+};
+
+
+#define ILLEGAL_ENABLES (TEXTURE0_3D| \
+ TEXTURE1_3D| \
+ ENABLE_TEXMAT0 | \
+ ENABLE_TEXMAT1 | \
+ ENABLE_TEXGEN0 | \
+ ENABLE_TEXGEN1 | \
+ ENABLE_USERCLIP | \
+ ENABLE_LIGHT | \
+ ENABLE_FOG)
+
+
+/* The driver gets first shot at building the pipeline - make some
+ * quick tests to see if we can use the fast path.
+ */
+GLboolean mgaDDBuildPrecalcPipeline( GLcontext *ctx )
+{
+ struct gl_pipeline *pipe = &ctx->CVA.pre;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
+ if (mmesa->renderindex == 0 &&
+ (ctx->Enabled & ILLEGAL_ENABLES) == 0 &&
+ (ctx->Array.Flags & (VERT_OBJ_234|
+ VERT_TEX0_4|
+ VERT_TEX1_4|
+ VERT_ELT)) == (VERT_OBJ_23|VERT_ELT))
+ {
+ pipe->stages[0] = &mga_fast_stage;
+ pipe->stages[1] = 0;
+ pipe->new_inputs = ctx->RenderFlags & VERT_DATA;
+ pipe->ops = pipe->stages[0]->ops;
+ mmesa->using_fast_path = 1;
+ return 1;
+ }
+
+ if (mmesa->using_fast_path)
+ {
+ mmesa->using_fast_path = 0;
+ ctx->CVA.VB->ClipOrMask = 0;
+ ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS;
+ ctx->Array.NewArrayState |= ctx->Array.Summary;
+ return 0;
+ }
+
+ return 0;
+}
+
+
+
+
+/* Still do the normal fixup and copy-to-current, so this isn't so
+ * bad.
+ */
+#define ILLEGAL_INPUTS_IMM (VERT_OBJ_4| \
+ VERT_TEX0_4| \
+ VERT_TEX1_4| \
+ VERT_MATERIAL)
+
+
+static void mgaDDCheckRasterSetup( GLcontext *ctx, struct gl_pipeline_stage *d )
+{
+ d->type = PIPE_IMMEDIATE|PIPE_PRECALC;
+ d->inputs = ctx->RenderFlags;
+
+ /* MGA requires an extra input:
+ */
+ if (ctx->FogMode == FOG_FRAGMENT)
+ d->inputs |= VERT_FOG_COORD;
+
+ d->outputs = VERT_SETUP_FULL;
+
+ if (ctx->IndirectTriangles & DD_SW_SETUP)
+ d->type = PIPE_IMMEDIATE;
+}
+
+
+GLuint mgaDDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr )
+{
+ GLuint i, o;
+
+ for (i = o = 0 ; i < nr ; i++) {
+ switch (in[i].ops) {
+
+ /* Completely replace Mesa's fog processing to generate fog
+ * coordinates instead of messing with colors.
+ */
+ case PIPE_OP_FOG:
+ out[o] = gl_fog_coord_stage;
+ o++;
+ break;
+
+ case PIPE_OP_RAST_SETUP_0:
+ out[o] = in[i];
+ out[o].cva_state_change = NEW_LIGHTING|NEW_TEXTURING|NEW_RASTER_OPS;
+ out[o].state_change = ~0;
+ out[o].check = mgaDDCheckPartialRasterSetup;
+ out[o].run = mgaDDPartialRasterSetup;
+ o++;
+ break;
+
+ case PIPE_OP_RAST_SETUP_0|PIPE_OP_RAST_SETUP_1:
+ out[o] = in[i];
+ out[o].check = mgaDDCheckRasterSetup;
+ out[o].run = mgaDDDoRasterSetup;
+ o++;
+ break;
+
+ default:
+ out[o++] = in[i];
+ break;
+ }
+ }
+
+ return o;
+}
+
+
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h
new file mode 100644
index 000000000..d42abddfe
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h
@@ -0,0 +1,15 @@
+#ifndef _MGA_PIPELINE_H
+#define _MGA_PIPELINE_H
+
+
+extern GLuint mgaDDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr );
+
+extern GLboolean mgaDDBuildImmediatePipeline( GLcontext *ctx );
+extern GLboolean mgaDDBuildPrecalcPipeline( GLcontext *ctx );
+
+extern void mgaDDFastPath( struct vertex_buffer *VB );
+extern void mgaDDFastPathInit( void );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaregs.h b/xc/lib/GL/mesa/src/drv/mga/mgaregs.h
new file mode 100644
index 000000000..3842ee258
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaregs.h
@@ -0,0 +1,1377 @@
+/* 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.
+ */
+
+#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_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_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/xc/lib/GL/mesa/src/drv/mga/mgarender.c b/xc/lib/GL/mesa/src/drv/mga/mgarender.c
new file mode 100644
index 000000000..6f406db2d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgarender.c
@@ -0,0 +1,334 @@
+#include <stdio.h>
+#include "mgadd.h"
+#include "mgavb.h"
+#include "mgadma.h"
+#include "mgalib.h"
+#include "mgatris.h"
+#include "mgastate.h"
+#include "xsmesaP.h"
+#include "enums.h"
+
+#define POINT(x) mga_draw_point(&gWin[x], psize)
+#define LINE(x,y) mga_draw_line(&gWin[x], &gWin[y], lwidth)
+#define TRI(x,y,z) mga_draw_triangle(&gWin[x], &gWin[y], &gWin[z])
+
+
+/* Direct, and no clipping required. I haven't written the clip funcs
+ * yet, so this is only useful for the fast path, which does its own
+ * clipping.
+ */
+#define RENDER_POINTS( start, count ) \
+do { \
+ GLuint e; \
+ for(e=start;e<=count;e++) \
+ POINT(elt[e]); \
+} while (0)
+
+#define RENDER_LINE( i1, i ) \
+do { \
+ GLuint e1 = elt[i1], e = elt[i]; \
+ LINE( e1, e ); \
+} while (0)
+
+
+#define RENDER_TRI( i2, i1, i, pv, parity) \
+do { \
+{ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ if (parity) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \
+ TRI(e2, e1, e); \
+}} while (0)
+
+
+#define RENDER_QUAD( i3, i2, i1, i, pv) \
+do { \
+ GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ TRI(e3, e2, e); \
+ TRI(e2, e1, e); \
+} while (0)
+
+#define LOCAL_VARS \
+ mgaVertexPtr gWin = MGA_DRIVER_DATA(VB)->verts; \
+ const GLuint *elt = VB->EltPtr->data; \
+ const GLfloat lwidth = VB->ctx->Line.Width; \
+ const GLfloat psize = VB->ctx->Point.Size; \
+ GLcontext *ctx = VB->ctx; \
+ (void) lwidth; (void)psize; (void)ctx; (void) gWin;
+
+
+#define TAG(x) x##_mga_smooth_indirect
+#include "render_tmp.h"
+
+
+
+
+#define RENDER_POINTS( start, count ) \
+do { \
+ GLuint e; \
+ for(e=start;e<=count;e++) \
+ POINT(e); \
+} while (0)
+
+#define RENDER_LINE( i1, i ) \
+do { \
+ LINE( i1, i ); \
+} while (0)
+
+
+#define RENDER_TRI( i2, i1, i, pv, parity) \
+do { \
+ GLuint e2 = i2, e1 = i1; \
+ if (parity) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \
+ TRI(e2, e1, i); \
+} while (0)
+
+
+#define RENDER_QUAD( i3, i2, i1, i, pv) \
+do { \
+ TRI(i3, i2, i); \
+ TRI(i2, i1, i); \
+} while (0)
+
+#define LOCAL_VARS \
+ mgaVertexPtr gWin = MGA_DRIVER_DATA(VB)->verts; \
+ const GLfloat lwidth = VB->ctx->Line.Width; \
+ const GLfloat psize = VB->ctx->Point.Size; \
+ GLcontext *ctx = VB->ctx; \
+ (void) lwidth; (void)psize; (void)ctx; (void) gWin;
+
+#define TAG(x) x##_mga_smooth_direct
+#include "render_tmp.h"
+
+
+
+
+
+/* Vertex array rendering via. the SetupDma function - no clipping required.
+ */
+#define RENDER_POINTS( start, count ) \
+do { \
+ FatalError("Dead code in mgarender.c\n"); \
+} while (0)
+
+#define RENDER_LINE( i1, i ) \
+do { \
+ FatalError("Dead code in mgarender.c\n"); \
+} while (0)
+
+
+#define RENDER_TRI( i2, i1, i, pv, parity) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ if (/*parity*/0) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \
+ TRI(e2, e1, e); \
+} while (0)
+
+#define RENDER_QUAD( i3, i2, i1, i, pv) \
+do { \
+ GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ TRI(e3, e2, e); \
+ TRI(e2, e1, e); \
+} while (0)
+
+#define LOCAL_VARS \
+ mgaVertexBufferPtr mgaVB = MGA_DRIVER_DATA(VB); \
+ mgaUI32 phys = mgaVB->vert_phys_start; \
+ const GLuint *elt = VB->EltPtr->data; \
+ (void) phys; (void) elt;
+
+#define PRESERVE_VB_DEFS
+#undef TRI
+#define VERT_ADDR_10( phys, elt ) ( phys + elt * 48 )
+#define TRI( ee0, ee1, ee2 ) \
+{ \
+ mgaVB->elt_buf[0] = VERT_ADDR_10(phys, ee0); \
+ mgaVB->elt_buf[1] = VERT_ADDR_10(phys, ee1); \
+ mgaVB->elt_buf[2] = VERT_ADDR_10(phys, ee2); \
+ mgaVB->elt_buf += 3; \
+}
+#define TAG(x) x##_mga_elt_10
+#include "render_tmp.h"
+
+
+#define TAG(x) x##_mga_elt_8
+#undef TRI
+#define VERT_ADDR_8( phys, elt ) ( phys + elt * 32 )
+#define TRI( ee0, ee1, ee2 ) \
+{ \
+ mgaVB->elt_buf[0] = VERT_ADDR_8(phys, ee0); \
+ mgaVB->elt_buf[1] = VERT_ADDR_8(phys, ee1); \
+ mgaVB->elt_buf[2] = VERT_ADDR_8(phys, ee2); \
+ mgaVB->elt_buf += 3; \
+}
+#include "render_tmp.h"
+
+
+
+
+/* Currently only used on the fast path - need a set of render funcs
+ * for clipped primitives.
+ */
+void mgaDDRenderElementsDirect( struct vertex_buffer *VB )
+{
+ mgaVertexBufferPtr mgaVB = MGA_DRIVER_DATA(VB);
+ GLcontext *ctx = VB->ctx;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ GLenum prim = ctx->CVA.elt_mode;
+ GLuint nr = VB->EltPtr->count;
+ render_func func = render_tab_mga_smooth_indirect[prim];
+ GLuint p = 0;
+ mgaUI32 *start = mgaVB->elt_buf;
+
+ struct vertex_buffer *saved_vb = ctx->VB;
+
+ if (mmesa->new_state)
+ mgaDDUpdateHwState( ctx );
+
+ /* Are we using Setup DMA?
+ */
+ if (start) {
+ switch (MGA_CONTEXT(ctx)->vertsize) {
+ case 10:
+ func = render_tab_mga_elt_10[prim];
+ break;
+ case 8:
+ func = render_tab_mga_elt_8[prim];
+ break;
+ default:
+ }
+ }
+
+ ctx->VB = VB;
+
+ do {
+ func( VB, 0, nr, 0 );
+ } while (ctx->Driver.MultipassFunc &&
+ ctx->Driver.MultipassFunc( VB, ++p ));
+
+ ctx->VB = saved_vb;
+
+
+ if (start && nr) {
+ if (0)
+ fprintf(stderr, "%d/%d elts\n", nr, mgaVB->elt_buf-start);
+ mgaSetupDma( start, mgaVB->elt_buf - start );
+ mgaVB->elt_buf = mgaVB->vert_buf = 0;
+ }
+}
+
+
+void mgaDDRenderElementsImmediate( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ GLuint nr = VB->EltPtr->count;
+ render_func *tab = render_tab_mga_smooth_indirect;
+ GLuint parity = VB->Parity;
+ GLuint p = 0;
+ GLuint i, next;
+
+ if (mmesa->new_state)
+ mgaDDUpdateHwState( ctx );
+
+ do {
+ for ( i= VB->CopyStart ; i < nr ; parity = 0, i = next )
+ {
+ GLenum prim = VB->Primitive[i];
+ next = VB->NextPrimitive[i];
+ tab[prim]( VB, i, next, parity );
+ }
+ } while (ctx->Driver.MultipassFunc &&
+ ctx->Driver.MultipassFunc( VB, ++p ));
+}
+
+
+void mgaDDRenderDirect( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ GLuint nr = VB->Count;
+ render_func *tab = render_tab_mga_smooth_direct;
+ GLuint parity = VB->Parity;
+ GLuint p = 0;
+ GLuint i, next;
+
+ if (mmesa->new_state)
+ mgaDDUpdateHwState( ctx );
+
+ do {
+ for ( i= VB->CopyStart ; i < nr ; parity = 0, i = next )
+ {
+ GLenum prim = VB->Primitive[i];
+ next = VB->NextPrimitive[i];
+ tab[prim]( VB, i, next, parity );
+ }
+ } while (ctx->Driver.MultipassFunc &&
+ ctx->Driver.MultipassFunc( VB, ++p ));
+}
+
+
+static void optimized_render_vb_triangle_mga_smooth_indirect(struct vertex_buffer *VB,
+ GLuint start,
+ GLuint count,
+ GLuint parity)
+{
+ mgaVertexPtr gWin = MGA_DRIVER_DATA(VB)->verts;
+ const GLuint *elt = VB->EltPtr->data;
+ GLcontext *ctx = VB->ctx;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
+ mgaUI32 vertsize = mmesa->vertsize;
+
+ /* We know how many dwords we need so we can allocate all of it
+ * in one call */
+ mgaUI32 *wv = mgaAllocSecondaryBuffer( count * vertsize );
+
+ int vertex;
+
+ (void)ctx; (void) gWin; (void) parity;
+
+
+ for(vertex=start+2;vertex<count;vertex+=3){
+ GLuint e2=elt[vertex-2],e1=elt[vertex-1],e=elt[vertex];
+ mgaUI32 *src;
+
+ int j;
+
+ if(parity){
+ GLuint tmp=e2;
+ e2=e1;
+ e1=tmp;
+ }
+
+ src=&gWin[e2].ui[0];
+
+ for(j=vertsize;j;j--){
+ *wv++=*src++;
+ }
+
+ src=&gWin[e1].ui[0];
+ for(j=vertsize;j;j--){
+ *wv++=*src++;
+ }
+
+ src=&gWin[e].ui[0];
+ for(j=vertsize;j;j--){
+ *wv++=*src++;
+ }
+ }
+
+}
+
+
+void mgaDDRenderInit()
+{
+
+ render_init_mga_smooth_indirect();
+ render_init_mga_smooth_direct();
+ render_init_mga_elt_10();
+ render_init_mga_elt_8();
+
+ render_tab_mga_smooth_indirect[GL_TRIANGLES] =
+ optimized_render_vb_triangle_mga_smooth_indirect;
+}
+
+
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgarender.h b/xc/lib/GL/mesa/src/drv/mga/mgarender.h
new file mode 100644
index 000000000..c772ac459
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgarender.h
@@ -0,0 +1,10 @@
+
+#ifndef _MGA_RENDER_H
+#define _MGA_RENDER_H
+
+extern void mgaDDRenderElementsDirect( struct vertex_buffer *VB );
+extern void mgaDDRenderElementsImmediate( struct vertex_buffer *VB );
+extern void mgaDDRenderDirect( struct vertex_buffer *VB );
+extern void mgaDDRenderInit();
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c
new file mode 100644
index 000000000..38e3cdde8
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c
@@ -0,0 +1,153 @@
+#include "types.h"
+#include "mgadd.h"
+#include "mgalib.h"
+#include "mgadma.h"
+#include "mgalog.h"
+#include "mgaspan.h"
+
+
+#define LOCAL_VARS \
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx ); \
+ __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
+ __DRIscreenPrivate *sPriv = mmesa->driScreen; \
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
+ GLuint pitch = mgaScreen->backPitch; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(sPriv->pFB + \
+ mmesa->drawOffset + \
+ dPriv->x * 2 + \
+ dPriv->y * pitch)
+
+#define INIT_MONO_PIXEL(p) \
+ GLushort p = MGA_CONTEXT( ctx )->MonoColor;
+
+#define CLIPPIXEL(_x,_y) (_x >= minx && _x <= maxx && \
+ _y >= miny && _y <= maxy)
+
+
+#define CLIPSPAN(_x,_y,_n,_x1,_n1) \
+ if (_y < miny || _y >= maxy) _n1 = 0, _x1 = x; \
+ else { \
+ _n1 = _n; \
+ _x1 = _x; \
+ if (_x1 < minx) _n1 -= (minx - _x1), _x1 = minx; \
+ if (_x1 + _n1 > maxx) n1 -= (_x1 + n1 - maxx); \
+ }
+
+
+
+
+
+#define HW_CLIPLOOP() \
+ do { \
+ int _nc = mmesa->numClipRects; \
+ LOCK_HARDWARE_QUIESCENT(mmesa); \
+ 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() \
+ } \
+ UNLOCK_HARDWARE(mmesa); \
+ } while (0)
+
+
+#define Y_FLIP(_y) (height - _y)
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = ( ((r & 0x1f) << 11) | \
+ ((g & 0x3f) << 5) | \
+ ((b & 0x1f)))
+#define WRITE_PIXEL( _x, _y, p ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+do { \
+ GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 11) & 0x1f; \
+ rgba[1] = (p >> 5) & 0x3f; \
+ rgba[2] = (p >> 0) & 0x1f; \
+ rgba[3] = 0; /* or 255? */ \
+} while(0)
+
+#define TAG(x) mga##x##_565
+#include "spantmp.h"
+
+
+
+
+
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = ( ((r & 0x1f) << 10) | \
+ ((g & 0x1f) << 5) | \
+ ((b & 0x1f)))
+
+#define WRITE_PIXEL( _x, _y, p ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+do { \
+ GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 10) & 0x1f; \
+ rgba[1] = (p >> 5) & 0x1f; \
+ rgba[2] = (p >> 0) & 0x1f; \
+ rgba[3] = 0; /* or 255? */ \
+} while(0)
+
+#define TAG(x) mga##x##_555
+#include "spantmp.h"
+
+
+
+#if 0
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLuint *)(buf + _x*4 + _y*pitch) = ( ((r) << 16) | \
+ ((g) << 8) | \
+ ((b)))
+
+#define WRITE_PIXEL( _x, _y, p ) \
+ *(GLuint *)(buf + _x*4 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+do { \
+ GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \
+ rgba[0] = (p >> 16) & 0xff; \
+ rgba[1] = (p >> 8) & 0xff; \
+ rgba[2] = (p >> 0) & 0xff; \
+ rgba[3] = 0; /* or 255? */ \
+} while(0)
+
+#define TAG(x) mga##x##_888
+#include "spantmp.h"
+#endif
+
+void mgaDDInitSpanFuncs( GLcontext *ctx )
+{
+ if (1) {
+ ctx->Driver.WriteRGBASpan = mgaWriteRGBASpan_565;
+ ctx->Driver.WriteRGBSpan = mgaWriteRGBSpan_565;
+ ctx->Driver.WriteMonoRGBASpan = mgaWriteMonoRGBASpan_565;
+ ctx->Driver.WriteRGBAPixels = mgaWriteRGBAPixels_565;
+ ctx->Driver.WriteMonoRGBAPixels = mgaWriteMonoRGBAPixels_565;
+ ctx->Driver.ReadRGBASpan = mgaReadRGBASpan_565;
+ ctx->Driver.ReadRGBAPixels = mgaReadRGBAPixels_565;
+ } else {
+ ctx->Driver.WriteRGBASpan = mgaWriteRGBASpan_555;
+ ctx->Driver.WriteRGBSpan = mgaWriteRGBSpan_555;
+ ctx->Driver.WriteMonoRGBASpan = mgaWriteMonoRGBASpan_555;
+ ctx->Driver.WriteRGBAPixels = mgaWriteRGBAPixels_555;
+ ctx->Driver.WriteMonoRGBAPixels = mgaWriteMonoRGBAPixels_555;
+ ctx->Driver.ReadRGBASpan = mgaReadRGBASpan_555;
+ ctx->Driver.ReadRGBAPixels = mgaReadRGBAPixels_555;
+ }
+
+ ctx->Driver.WriteCI8Span =NULL;
+ ctx->Driver.WriteCI32Span =NULL;
+ ctx->Driver.WriteMonoCISpan =NULL;
+ ctx->Driver.WriteCI32Pixels =NULL;
+ ctx->Driver.WriteMonoCIPixels =NULL;
+ ctx->Driver.ReadCI32Span =NULL;
+ ctx->Driver.ReadCI32Pixels =NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.h b/xc/lib/GL/mesa/src/drv/mga/mgaspan.h
new file mode 100644
index 000000000..5db0fb976
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.h
@@ -0,0 +1,6 @@
+#ifndef _MGA_SPAN_H
+#define _MGA_SPAN_H
+
+extern void mgaDDInitSpanFuncs( GLcontext *ctx );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c
new file mode 100644
index 000000000..ff9063e0b
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c
@@ -0,0 +1,723 @@
+
+#include <stdio.h>
+
+
+#include "types.h"
+#include "pb.h"
+#include "dd.h"
+
+#include "mm.h"
+#include "mgalib.h"
+#include "mgadd.h"
+#include "mgastate.h"
+#include "mgadepth.h"
+#include "mgatex.h"
+#include "mgalog.h"
+#include "mgavb.h"
+#include "mgatris.h"
+#include "mgaregs.h"
+#include "mga_drm_public.h"
+
+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:
+ 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 | DC_atype_i;
+ }
+
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_zmode_MASK & DC_atype_MASK;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= zmode;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+}
+
+
+static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
+{
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+}
+
+
+static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode)
+{
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+}
+
+static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+}
+
+static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
+ GLenum dfactorRGB, GLenum sfactorA,
+ GLenum dfactorA )
+{
+ 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) {
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+ }
+}
+
+
+static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
+{
+ if (1) {
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+ mgaMsg(8, "mgaDDShadeModel: %x\n", mode);
+ }
+}
+
+
+static void mgaDDDepthFunc(GLcontext *ctx, GLenum func)
+{
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
+}
+
+static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag)
+{
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
+}
+
+
+
+
+static void mgaUpdateFogAttrib( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ mgaUI32 color = MGAPACKCOLOR888((mgaUI8)(ctx->Fog.Color[0]*255.0F),
+ (mgaUI8)(ctx->Fog.Color[1]*255.0F),
+ (mgaUI8)(ctx->Fog.Color[2]*255.0F));
+
+ if (color != mmesa->Setup[MGA_CTXREG_FOGCOLOR])
+ mmesa->Setup[MGA_CTXREG_FOGCOLOR] = color;
+
+ mmesa->Setup[MGA_CTXREG_MACCESS] &= ~MA_fogen_enable;
+ if (ctx->FogMode == FOG_FRAGMENT)
+ mmesa->Setup[MGA_CTXREG_MACCESS] |= MA_fogen_enable;
+
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+}
+
+static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_FOG;
+}
+
+
+
+
+/* =============================================================
+ * Alpha blending
+ */
+
+
+static void mgaUpdateAlphaMode(GLcontext *ctx)
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ int a = 0;
+
+ /* determine source of alpha for blending and testing */
+ if ( !ctx->Texture.Enabled || (mmesa->Fallback & MGA_FALLBACK_TEXTURE))
+ a |= AC_alphasel_diffused;
+ else {
+ switch (ctx->Texture.Unit[0].EnvMode) {
+ case GL_DECAL:
+ case GL_REPLACE:
+ a |= AC_alphasel_fromtex;
+ break;
+ case GL_BLEND:
+ case GL_MODULATE:
+ a |= AC_alphasel_modulated;
+ break;
+ default:
+ }
+ }
+
+
+ /* alpha test control - disabled by default.
+ */
+ 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:
+ }
+ 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 (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/
+ a |= AC_src_dst_alpha;
+ else
+ a |= AC_src_one;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/
+ a |= AC_src_om_dst_alpha;
+ else
+ a |= AC_src_zero;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ a |= AC_src_src_alpha_sat;
+ break;
+ default: /* never happens */
+ }
+
+ 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 (0) /*(mgaDB->Attrib & MGA_PF_HASALPHA)*/
+ a |= AC_dst_dst_alpha;
+ else
+ a |= AC_dst_one;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/
+ a |= AC_dst_om_dst_alpha;
+ else
+ a |= AC_dst_zero;
+ break;
+ default: /* never happens */
+ }
+ } else {
+ a |= AC_src_one|AC_dst_zero;
+ }
+
+ mmesa->Setup[MGA_CTXREG_ALPHACTRL] = (AC_amode_alpha_channel |
+ AC_astipple_disable |
+ AC_aten_disable |
+ AC_atmode_noacmp |
+ a);
+
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+}
+
+
+
+/* =============================================================
+ * Hardware clipping
+ */
+
+static void mgaUpdateClipping(const GLcontext *ctx)
+{
+#if 0
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+ int x1,x2,y1,y2;
+
+ if ( ctx->Scissor.Enabled) {
+ x1 = ctx->Scissor.X;
+ x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
+ y1 = dPriv->Height - ctx->Scissor.Y - ctx->Scissor.Height;
+ y2 = dPriv->Height - ctx->Scissor.Y - 1;
+ } else {
+ x1 = 0;
+ y1 = 0;
+ x2 = mgaDB->Width-1;
+ y2 = mgaDB->Height-1;
+ }
+
+ if (x1 < 0) x1 = 0;
+ if (y1 < 0) y1 = 0;
+ if (x2 >= mgaDB->Width) x2 = mgaDB->Width-1;
+ if (y2 >= mgaDB->Height) y2 = mgaDB->Height-1;
+
+ if (x1 > x2 || y1 > y2) {
+ x1 = 0; x2 = 0;
+ y2 = 0; y1 = 1;
+ }
+
+
+ mmesa->Setup[MGA_CTXREG_CXBNDRY] = (MGA_FIELD(CXB_cxright,x2) |
+ MGA_FIELD(CXB_cxleft,x1));
+ mmesa->Setup[MGA_CTXREG_YTOP] = y1*mgaDB->Pitch;
+ mmesa->Setup[MGA_CTXREG_YBOT] = y2*mgaDB->Pitch;
+
+
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+#endif
+}
+
+
+static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y,
+ GLsizei w, GLsizei h )
+{
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP;
+}
+
+
+/* ======================================================================
+ * New stuff for DRI state.
+ */
+
+static void mgaDDDither(GLcontext *ctx, GLboolean enable)
+{
+}
+
+
+static GLboolean mgaDDSetBuffer(GLcontext *ctx, GLenum mode )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ mmesa->Fallback &= ~MGA_FALLBACK_BUFFER;
+
+ if (mode == GL_FRONT_LEFT)
+ {
+ mmesa->drawOffset = mmesa->mgaScreen->fbOffset;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->fbOffset;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mgaXMesaSetFrontClipRects( mmesa );
+ return GL_TRUE;
+ }
+ else if (mode == GL_BACK_LEFT)
+ {
+ mmesa->drawOffset = mmesa->mgaScreen->backOffset;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->backOffset;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mgaXMesaSetBackClipRects( mmesa );
+ return GL_TRUE;
+ }
+ else
+ {
+ mmesa->Fallback |= MGA_FALLBACK_BUFFER;
+ return GL_FALSE;
+ }
+}
+
+
+
+static void mgaDDSetColor(GLcontext *ctx,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ mmesa->MonoColor = mgaPackColor( mmesa->mgaScreen->fbFormat,
+ r, g, b, a );
+}
+
+
+static void mgaDDClearColor(GLcontext *ctx,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->fbFormat,
+ r, g, b, a );
+}
+
+
+/* =============================================================
+ * Culling
+ */
+
+#define _CULL_DISABLE 0
+#define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16))
+#define _CULL_POSITIVE (1<<11)
+
+
+static void mgaUpdateCull( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ GLuint mode = _CULL_DISABLE;
+
+ if (ctx->Polygon.CullFlag &&
+ ctx->PB->primitive == GL_POLYGON &&
+ 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 (mmesa->multitex)
+ mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* why??? */
+ }
+
+ mmesa->Setup[MGA_CTXREG_WFLAG] = mode;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+}
+
+
+static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum mode)
+{
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL;
+}
+
+
+
+
+/* =============================================================
+ * Color masks
+ */
+
+/* Mesa calls this from the wrong place:
+ */
+static GLboolean mgaDDColorMask(GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
+
+
+ GLuint mask = mgaPackColor(mgaScreen->Attrib,
+ ctx->Color.ColorMask[RCOMP],
+ ctx->Color.ColorMask[GCOMP],
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP]);
+
+ switch (mgaScreen->Attrib & MGA_PF_MASK)
+ {
+ case MGA_PF_555:
+ case MGA_PF_565:
+ mask = mask | (mask << 16);
+ break;
+ }
+
+ if (mmesa->Setup[MGA_CTXREG_PLNWT] != mask) {
+ mmesa->Setup[MGA_CTXREG_PLNWT] = mask;
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_MASK;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ }
+
+ return 1;
+}
+
+/* =============================================================
+ */
+
+
+
+
+static void mgaDDPrintDirty( const char *msg, GLuint state )
+{
+ fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n",
+ msg,
+ (unsigned int) state,
+ (state & MGA_REQUIRE_QUIESCENT) ? "req-quiescent, " : "",
+ (state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img, " : "",
+ (state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img, " : "",
+ (state & MGA_UPLOAD_CTX) ? "upload-ctx, " : "",
+ (state & MGA_UPLOAD_TEX0) ? "upload-tex0, " : "",
+ (state & MGA_UPLOAD_TEX1) ? "upload-tex1, " : ""
+ );
+}
+
+
+/* Push the state into the sarea and/or texture memory.
+ */
+void mgaEmitHwStateLocked( mgaContextPtr mmesa )
+{
+ if (MGA_DEBUG & MGA_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_CTX) {
+ memcpy( mmesa->sarea->ContextState,
+ mmesa->Setup,
+ sizeof(mmesa->Setup));
+
+ if (mmesa->CurrentTexObj[0])
+ memcpy(mmesa->sarea->TexState[0],
+ mmesa->CurrentTexObj[0]->Setup,
+ sizeof(mmesa->sarea->TexState[0]));
+
+ if (mmesa->CurrentTexObj[1])
+ memcpy(mmesa->sarea->TexState[1],
+ mmesa->CurrentTexObj[1]->Setup,
+ sizeof(mmesa->sarea->TexState[1]));
+ }
+
+ if (mmesa->dirty & MGA_UPLOAD_PIPE)
+ mmesa->sarea->WarpPipe = mmesa->setupindex & MGA_WARP_T2GZSAF;
+
+ mmesa->sarea->dirty |= mmesa->dirty;
+ mmesa->dirty = 0;
+}
+
+
+
+/* =============================================================
+ */
+
+static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ switch(cap) {
+ case GL_ALPHA_TEST:
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+ break;
+ case GL_BLEND:
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+ break;
+ case GL_DEPTH_TEST:
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
+ break;
+ case GL_SCISSOR_TEST:
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP;
+ break;
+ case GL_FOG:
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_FOG;
+ break;
+ case GL_CULL_FACE:
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL;
+ break;
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+ break;
+ default:
+ ;
+ }
+}
+
+
+/* =============================================================
+ */
+
+/* Just need to note that it has changed - the kernel will do the
+ * upload the next time we fire a dma buffer.
+ */
+static void mgaWarpUpdateState( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ int index = mmesa->setupindex;
+
+ index &= ~(MGA_WIN_BIT|MGA_TEX0_BIT|MGA_RGBA_BIT);
+ index |= MGA_ALPHA_BIT;
+
+ if (index != mmesa->warp_pipe)
+ {
+ mmesa->warp_pipe = index;
+ mmesa->new_state |= MGA_NEW_WARP;
+ }
+}
+
+
+
+/* =============================================================
+ */
+
+static void mgaDDPrintState( const char *msg, GLuint state )
+{
+ mgaMsg(1, "%s (0x%x): %s%s%s%s%s%s%s%s\n",
+ msg,
+ state,
+ (state & MGA_NEW_DEPTH) ? "depth, " : "",
+ (state & MGA_NEW_ALPHA) ? "alpha, " : "",
+ (state & MGA_NEW_FOG) ? "fog, " : "",
+ (state & MGA_NEW_CLIP) ? "clip, " : "",
+ (state & MGA_NEW_MASK) ? "colormask, " : "",
+ (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)
+ {
+ mmesa->new_state = 0;
+
+ /* Emit any vertices for the current state. This will also
+ * push the current state into the sarea.
+ */
+/* mgaFlushVertices( mmesa ); */
+
+ if (MESA_VERBOSE&VERBOSE_DRIVER)
+ mgaDDPrintState("UpdateHwState", new_state);
+
+ if (new_state & MGA_NEW_DEPTH)
+ {
+ mgaUpdateZMode(ctx);
+ mgaDDInitDepthFuncs(ctx);
+ }
+
+ if (new_state & MGA_NEW_ALPHA)
+ mgaUpdateAlphaMode(ctx);
+
+ if (new_state & MGA_NEW_FOG)
+ mgaUpdateFogAttrib(ctx);
+
+ if (new_state & MGA_NEW_CLIP)
+ mgaUpdateClipping(ctx);
+
+ if (new_state & (MGA_NEW_WARP|MGA_NEW_CULL))
+ mgaUpdateCull(ctx);
+
+ if (new_state & (MGA_NEW_WARP|MGA_NEW_TEXTURE))
+ mgaUpdateTextureState(ctx);
+
+ mmesa->new_state = 0; /* tex uploads scribble newstate */
+ }
+}
+
+
+
+
+
+
+
+void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
+{
+ mgaFlushVertices( MGA_CONTEXT(ctx) );
+ mgaUpdateCull(ctx);
+}
+
+
+#define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
+ NEW_TEXTURE_MATRIX|\
+ NEW_USER_CLIP|NEW_CLIENT_STATE|\
+ NEW_TEXTURE_ENABLE))
+
+void mgaDDUpdateState( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaglx.c_setupPointers++;
+
+ if (ctx->NewState & INTERESTED) {
+ mgaDDChooseRenderState(ctx);
+ mgaChooseRasterSetupFunc(ctx);
+ mgaWarpUpdateState(ctx);
+ }
+
+ /* Have to do this here to detect texture fallbacks in time:
+ */
+ if (MGA_CONTEXT(ctx)->new_state & MGA_NEW_TEXTURE)
+ mgaDDUpdateHwState( ctx );
+
+ if (!mmesa->Fallback || mgaglx.noFallback) {
+ ctx->Driver.PointsFunc=mmesa->PointsFunc;
+ ctx->Driver.LineFunc=mmesa->LineFunc;
+ ctx->Driver.TriangleFunc=mmesa->TriangleFunc;
+ ctx->Driver.QuadFunc=mmesa->QuadFunc;
+ }
+}
+
+
+void mgaDDInitStateFuncs( GLcontext *ctx )
+{
+ ctx->Driver.UpdateState = mgaDDUpdateState;
+ 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.ReducedPrimitiveChange = mgaDDReducedPrimitiveChange;
+ ctx->Driver.RenderStart = mgaDDUpdateHwState;
+ ctx->Driver.RenderFinish = 0;
+
+ ctx->Driver.SetBuffer = mgaDDSetBuffer;
+ ctx->Driver.Color = mgaDDSetColor;
+ ctx->Driver.ClearColor = mgaDDClearColor;
+ ctx->Driver.Dither = mgaDDDither;
+
+ ctx->Driver.Index = 0;
+ ctx->Driver.ClearIndex = 0;
+ ctx->Driver.IndexMask = 0;
+
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.h b/xc/lib/GL/mesa/src/drv/mga/mgastate.h
new file mode 100644
index 000000000..5ada1b23c
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.h
@@ -0,0 +1,15 @@
+#ifndef _MGA_STATE_H
+#define _MGA_STATE_H
+
+
+extern void mgaDDInitStateFuncs(GLcontext *ctx);
+extern void mgaDDUpdateHwState( GLcontext *ctx );
+extern void mgaDDUpdateState( GLcontext *ctx );
+extern void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim );
+
+/* reprograms the current registers without updating them, used to
+reset state after a dma buffer overflow */
+void mgaUpdateRegs( GLuint regs );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c
new file mode 100644
index 000000000..be7ad6018
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c
@@ -0,0 +1,1051 @@
+/* -*- mode: C; c-basic-offset:8 -*- */
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * original by Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ * 9/20/99 rewrite by John Carmack <johnc@idsoftware.com>
+ * 13/1/00 port to DRI by Keith Whitwell <keithw@precisioninsight.com>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/gl.h>
+
+#include "mm.h"
+#include "mgalib.h"
+#include "mgadma.h"
+#include "mgatex.h"
+#include "mgalog.h"
+#include "mgaregs.h"
+
+#include "simple_list.h"
+
+
+/*
+ * mgaDestroyTexObj
+ * Free all memory associated with a texture and NULL any pointers
+ * to it.
+ */
+static void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) {
+ int i;
+
+ if ( !t ) return;
+
+ /* free the texture memory */
+ mmFreeMem( t->MemBlock );
+
+ /* free mesa's link */
+ t->tObj->DriverData = NULL;
+
+ /* see if it was the driver's current object */
+ for ( i = 0 ; i < 2 ; i++ ) {
+ if ( mmesa->CurrentTexObj[i] == t ) {
+ mmesa->CurrentTexObj[i] = NULL;
+ }
+ }
+
+ remove_from_list(t);
+ free( t );
+}
+
+static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t)
+{
+ if (t->MemBlock) {
+ mmFreeMem(t->MemBlock);
+ t->MemBlock = 0;
+ }
+
+ t->dirty_images = ~0;
+ move_to_tail(&(mmesa->SwappedOut), t);
+}
+
+
+void mgaResetGlobalLRU( mgaContextPtr mmesa )
+{
+ mgaTexRegion *list = mmesa->sarea->texList;
+ int sz = 1 << mmesa->mgaScreen->logTextureGranularity;
+ int i;
+
+ /* (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 ; i++) {
+ list[i].prev = i-1;
+ list[i].next = i+1;
+ list[i].age = 0;
+ }
+
+ 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;
+ mmesa->sarea->texAge = 0;
+}
+
+
+static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+ int i;
+ int logsz = mmesa->mgaScreen->logTextureGranularity;
+ int start = t->MemBlock->ofs >> logsz;
+ int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
+ mgaTexRegion *list = mmesa->sarea->texList;
+
+ mmesa->texAge = ++mmesa->sarea->texAge;
+
+ /* Update our local LRU
+ */
+ move_to_head( &(mmesa->TexObjList), t );
+
+ /* Update the global LRU
+ */
+ for (i = start ; i <= end ; i++) {
+
+ list[i].in_use = 1;
+ list[i].age = mmesa->texAge;
+
+ /* 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;
+ }
+}
+
+
+/* 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.
+ */
+void mgaTexturesGone( mgaContextPtr mmesa,
+ GLuint offset,
+ GLuint size,
+ GLuint in_use )
+{
+ mgaTextureObjectPtr t, tmp;
+
+ foreach_s ( t, tmp, &mmesa->TexObjList ) {
+
+ 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 == mmesa->CurrentTexObj[0] || t == mmesa->CurrentTexObj[1])
+ mgaSwapOutTexObj( mmesa, t );
+ else
+ mgaDestroyTexObj( mmesa, t );
+ }
+
+
+ if (in_use) {
+ t = (mgaTextureObjectPtr) calloc(1,sizeof(*t));
+ if (!t) return;
+
+ t->MemBlock = mmAllocMem( mmesa->texHeap, size, 0, offset);
+ insert_at_head( &mmesa->TexObjList, t );
+ }
+}
+
+
+/*
+ * mgaSetTexWrappings
+ */
+static void mgaSetTexWrapping( mgaTextureObjectPtr t,
+ GLenum sWrap, GLenum tWrap ) {
+ if (sWrap == GL_REPEAT) {
+ t->Setup[MGA_TEXREG_CTL] &= ~TMC_clampu_enable;
+ } else {
+ t->Setup[MGA_TEXREG_CTL] |= TMC_clampu_enable;
+ }
+ if (tWrap == GL_REPEAT) {
+ t->Setup[MGA_TEXREG_CTL] &= ~TMC_clampv_enable;
+ } else {
+ t->Setup[MGA_TEXREG_CTL] |= TMC_clampv_enable;
+ }
+}
+
+/*
+ * mgaSetTexFilter
+ */
+static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf) {
+ switch (minf) {
+ case GL_NEAREST:
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],
+ TF_minfilter_MASK, TF_minfilter_nrst);
+ break;
+ case GL_LINEAR:
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],
+ TF_minfilter_MASK, TF_minfilter_bilin);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],
+ TF_minfilter_MASK, TF_minfilter_mm1s);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],
+ TF_minfilter_MASK, TF_minfilter_mm4s);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],
+ TF_minfilter_MASK, TF_minfilter_mm2s);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],
+ TF_minfilter_MASK, TF_minfilter_mm8s);
+ break;
+ default:
+ mgaError("mgaSetTexFilter(): not supported min. filter %d\n",
+ (int)minf);
+ break;
+ }
+
+ switch (magf) {
+ case GL_NEAREST:
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],
+ TF_magfilter_MASK,TF_magfilter_nrst);
+ break;
+ case GL_LINEAR:
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],
+ TF_magfilter_MASK,TF_magfilter_bilin);
+ break;
+ default:
+ mgaError("mgaSetTexFilter(): not supported mag. filter %d\n",
+ (int)magf);
+ break;
+ }
+
+ /* See OpenGL 1.2 specification */
+ if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST ||
+ minf == GL_NEAREST_MIPMAP_LINEAR)) {
+ /* c = 0.5 */
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],TF_fthres_MASK,
+ 0x20 << TF_fthres_SHIFT);
+ } else {
+ /* c = 0 */
+ MGA_SET_FIELD(t->Setup[MGA_TEXREG_FILTER],TF_fthres_MASK,
+ 0x10 << TF_fthres_SHIFT);
+ }
+
+}
+
+/*
+ * mgaSetTexBorderColor
+ */
+static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) {
+ t->Setup[MGA_TEXREG_BORDERCOL] =
+ MGAPACKCOLOR8888(color[0],color[1],color[2],color[3]);
+
+}
+
+
+
+
+
+
+
+/*
+ * mgaUploadSubImage
+ *
+ * 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.
+ */
+static void mgaUploadSubImage( mgaContextPtr mmesa,
+ mgaTextureObjectPtr t,
+ int level,
+ int x, int y, int width, int height ) {
+ int x2;
+ int dwords;
+ int dstorg;
+ struct gl_texture_image *image;
+ int texelBytes, texelsPerDword, texelMaccess;
+
+ if ( level < 0 || level >= MGA_TEX_MAXLEVELS ) {
+ mgaMsg( 1, "mgaUploadSubImage: bad level: %i\n", level );
+ return;
+ }
+
+ image = t->tObj->Image[level];
+ if ( !image ) {
+ mgaError( "mgaUploadSubImage: NULL image\n" );
+ return;
+ }
+
+ /* find the proper destination offset for this level */
+ dstorg = (mmesa->mgaScreen->textureOffset + t->MemBlock->ofs +
+ t->offsets[level]);
+
+ /* turn on PCI/AGP if needed
+ if ( textureHeapPhysical ) {
+ dstorg |= 1 | mgaglx.use_agp;
+ }
+ */
+
+ 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_DMA_BUF_SZ ) {
+ break;
+ }
+ mgaMsg(10, "mgaUploadSubImage: recursively subdividing\n" );
+
+ mgaUploadSubImage( mmesa, t, level, x, y, width, height >> 1 );
+ y += ( height >> 1 );
+ height -= ( height >> 1 );
+ }
+
+ mgaMsg(10, "mgaUploadSubImage: %i,%i of %i,%i at %i,%i\n",
+ width, height, image->Width, image->Height, x, y );
+
+ /* bump the performance counter */
+ mgaglx.c_textureSwaps += ( dwords << 2 );
+
+
+#if 0
+
+ /* fill in the secondary buffer with properly converted texels
+ from the mesa buffer */
+ mgaConvertTexture( dest, texelBytes, image, x, y, width, height );
+
+ /* send the secondary data */
+ mgaSecondaryDma( TT_BLIT, dest, dwords );
+#endif
+
+}
+
+
+
+static void mgaUploadTexLevel( mgaContextPtr mmesa,
+ mgaTextureObjectPtr t,
+ int l )
+{
+ mgaUploadSubImage( mmesa,
+ t,
+ l,
+ 0, 0,
+ t->tObj->Image[l]->Width,
+ t->tObj->Image[l]->Height);
+}
+
+
+
+/*
+ * 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)
+{
+ mgaTextureObjectPtr t;
+ int i, ofs, size;
+ struct gl_texture_image *image;
+ int LastLevel;
+ int s, s2;
+ int textureFormat;
+
+ mgaMsg( 10,"mgaCreateTexObj( %p )\n", tObj );
+
+ t = malloc( sizeof( *t ) );
+ if ( !t ) {
+ mgaError( "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" );
+ return;
+ }
+ memset( t, 0, sizeof( *t ) );
+
+ image = tObj->Image[ 0 ];
+ if ( !image ) {
+ return;
+ }
+
+ if ( 0 ) {
+ /* G400 texture format options */
+
+ } else {
+ /* G200 texture format options */
+
+ switch( image->Format ) {
+ case GL_RGB:
+ case GL_LUMINANCE:
+ if ( image->IntFormat != GL_RGB5 &&
+ ( image->IntFormat == GL_RGB8 ||
+ mgaglx.default32BitTextures ) ) {
+ t->texelBytes = 4;
+ textureFormat = TMC_tformat_tw32;
+ } else {
+ t->texelBytes = 2;
+ textureFormat = TMC_tformat_tw16;
+ }
+ break;
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_RGBA:
+ if ( image->IntFormat != GL_RGBA4 &&
+ ( image->IntFormat == GL_RGBA8 ||
+ mgaglx.default32BitTextures ) ) {
+ t->texelBytes = 4;
+ textureFormat = TMC_tformat_tw32;
+ } else {
+ t->texelBytes = 2;
+ textureFormat = TMC_tformat_tw12;
+ }
+ break;
+ case GL_COLOR_INDEX:
+ textureFormat = TMC_tformat_tw8;
+ t->texelBytes = 1;
+ break;
+ default:
+ mgaError( "mgaCreateTexObj: bad image->Format\n" );
+ free( t );
+ return;
+ }
+ }
+
+ /* 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++ ) {
+ int levelWidth, levelHeight;
+
+ t->offsets[i] = ofs;
+ image = tObj->Image[ i ];
+ if ( !image ) {
+ LastLevel = i - 1;
+ mgaMsg( 10, " missing images after LastLevel: %i\n",
+ LastLevel );
+ break;
+ }
+ /* the G400 doesn't work with textures less than 8
+ units in size */
+ levelWidth = image->Width;
+ levelHeight = image->Height;
+ if ( levelWidth < 8 ) {
+ levelWidth = 8;
+ }
+ if ( levelHeight < 8 ) {
+ levelHeight = 8;
+ }
+ size = levelWidth * levelHeight * t->texelBytes;
+ size = ( size + 31 ) & ~31; /* 32 byte aligned */
+ ofs += size;
+ t->dirty_images |= (1<<i);
+ }
+ t->totalSize = ofs;
+ t->lastLevel = LastLevel;
+
+
+ /* fill in our mga texture object */
+ t->tObj = tObj;
+ t->ctx = mmesa;
+
+
+ insert_at_tail(&(mmesa->TexObjList), t);
+
+ t->MemBlock = 0;
+
+ /* base image */
+ image = tObj->Image[ 0 ];
+
+ /* setup hardware register values */
+ t->Setup[MGA_TEXREG_CTL] = (TMC_takey_1 |
+ TMC_tamask_0 |
+ textureFormat );
+
+ if (image->WidthLog2 >= 3) {
+ t->Setup[MGA_TEXREG_CTL] |= ((image->WidthLog2 - 3) <<
+ TMC_tpitch_SHIFT);
+ } else {
+ t->Setup[MGA_TEXREG_CTL] |= (TMC_tpitchlin_enable |
+ (image->Width <<
+ TMC_tpitchext_SHIFT));
+ }
+
+
+ t->Setup[MGA_TEXREG_CTL2] = TMC_ckstransdis_enable;
+
+ if ( mmesa->glCtx->Light.Model.ColorControl ==
+ GL_SEPARATE_SPECULAR_COLOR )
+ {
+ t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable;
+ }
+
+ t->Setup[MGA_TEXREG_FILTER] = (TF_minfilter_nrst |
+ TF_magfilter_nrst |
+ TF_filteralpha_enable |
+ (0x10 << TF_fthres_SHIFT) |
+ (LastLevel << TF_mapnb_SHIFT));
+
+ /* warp texture registers */
+ if (MGA_IS_G200(mmesa)) {
+ ofs = 28;
+ } else {
+ ofs = 11;
+ }
+
+ s = image->Width;
+ s2 = image->WidthLog2;
+ t->Setup[MGA_TEXREG_WIDTH] =
+ 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[MGA_TEXREG_HEIGHT] =
+ 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->BorderColor );
+
+ tObj->DriverData = t;
+}
+
+
+
+int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+
+ int i;
+ int ofs;
+ mgaglx.c_textureSwaps++;
+
+ /* Do we need to eject LRU texture objects?
+ */
+ if (!t->MemBlock) {
+ while (1)
+ {
+ t->MemBlock = mmAllocMem( mmesa->texHeap, t->totalSize, 12, 0 );
+ if (t->MemBlock)
+ break;
+
+ if (mmesa->TexObjList.prev == &(mmesa->TexObjList)) {
+ fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
+ mmDumpMemInfo( mmesa->texHeap );
+ return -1;
+ }
+
+ mgaDestroyTexObj( mmesa, mmesa->TexObjList.prev );
+ }
+
+ ofs = t->MemBlock->ofs;
+
+ t->Setup[MGA_TEXREG_ORG] = ofs;
+ t->Setup[MGA_TEXREG_ORG1] = ofs + t->offsets[1];
+ t->Setup[MGA_TEXREG_ORG2] = ofs + t->offsets[2];
+ t->Setup[MGA_TEXREG_ORG3] = ofs + t->offsets[3];
+ t->Setup[MGA_TEXREG_ORG4] = ofs + t->offsets[4];
+
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ }
+
+ /* Let the world know we've used this memory recently.
+ */
+ mgaUpdateTexLRU( mmesa, t );
+
+ if (t->dirty_images) {
+ if (MGA_DEBUG & MGA_DEBUG_VERBOSE_MSG)
+ 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;
+}
+
+/*
+============================================================================
+
+PUBLIC MGA FUNCTIONS
+
+============================================================================
+*/
+
+
+
+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;
+
+ switch (ctx->Texture.Unit[0].EnvMode) {
+ case GL_REPLACE:
+ t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable;
+ t->Setup[MGA_TEXREG_CTL2] &= ~TMC_decaldis_enable;
+ break;
+ case GL_MODULATE:
+ t->Setup[MGA_TEXREG_CTL] |= TMC_tmodulate_enable;
+ t->Setup[MGA_TEXREG_CTL2] &= ~TMC_decaldis_enable;
+ break;
+ case GL_DECAL:
+ t->Setup[MGA_TEXREG_CTL] &= ~TMC_tmodulate_enable;
+ t->Setup[MGA_TEXREG_CTL2] &= ~TMC_decaldis_enable;
+ break;
+ case GL_BLEND:
+ t->ctx->Fallback |= MGA_FALLBACK_TEXTURE;
+ break;
+ default:
+ }
+}
+
+/* I don't have the alpha values correct yet:
+ */
+static void mgaUpdateTextureStage( GLcontext *ctx, int unit )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaUI32 *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit];
+ GLuint source = mmesa->tmu_source[unit];
+ struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current;
+
+ *reg = 0;
+ if (unit == 1)
+ *reg = mmesa->Setup[MGA_CTXREG_TDUAL0];
+
+ if ( tObj != ctx->Texture.Unit[source].CurrentD[2] )
+ return;
+
+ if ( ((ctx->Enabled>>(source*4))&TEXTURE0_ANY) != TEXTURE0_2D )
+ return;
+
+ if (!tObj || !tObj->Complete)
+ return;
+
+ switch (ctx->Texture.Unit[source].EnvMode) {
+ case GL_REPLACE:
+ *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_arg1);
+ else
+ *reg = ( TD0_color_arg2_prevstage |
+ TD0_color_alpha_prevstage |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg1);
+ break;
+ case GL_DECAL:
+ *reg = (TD0_color_arg2_fcol |
+ 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_fcol |
+ TD0_alpha_sel_arg2 );
+ break;
+
+ case GL_ADD:
+ if (unit == 0)
+ *reg = ( TD0_color_arg2_diffuse |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_arg1);
+ 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_arg1);
+ break;
+
+ case GL_BLEND:
+ /* Use a multipass mechanism to do this:
+ */
+ mmesa->Fallback |= MGA_FALLBACK_TEXTURE;
+ break;
+ default:
+ }
+}
+
+
+
+static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
+ mgaTextureObjectPtr t;
+ struct gl_texture_object *tObj;
+ GLuint enabled;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ GLuint source = mmesa->tmu_source[unit];
+
+ mgaMsg(15,"mgaUpdateTextureState %d\n", unit);
+
+ /* disable texturing until it is known to be good */
+ mmesa->Setup[MGA_CTXREG_DWGCTL] =
+ (( mmesa->Setup[MGA_CTXREG_DWGCTL] & DC_opcod_MASK ) |
+ DC_opcod_trap);
+
+ enabled = (ctx->Texture.Enabled>>(source*4))&TEXTURE0_ANY;
+ if (enabled != TEXTURE0_2D) {
+ if (enabled)
+ mmesa->Fallback |= MGA_FALLBACK_TEXTURE;
+ return;
+ }
+
+ tObj = ctx->Texture.Unit[source].Current;
+
+ if ( !tObj || tObj != ctx->Texture.Unit[source].CurrentD[2] )
+ return;
+
+ /* if the texture object doesn't exist at all (never used or
+ swapped out), create it now, uploading all texture images */
+
+ if ( !tObj->DriverData ) {
+ /* clear the current pointer so that texture object can be
+ swapped out if necessary to make room */
+ mmesa->CurrentTexObj[source] = NULL;
+ mgaCreateTexObj( mmesa, tObj );
+
+ if ( !tObj->DriverData ) {
+ mgaMsg( 5, "mgaUpdateTextureState: create failed\n" );
+ mmesa->Fallback |= MGA_FALLBACK_TEXTURE;
+ return; /* can't create a texture object */
+ }
+ }
+
+ /* we definately have a valid texture now */
+ mmesa->Setup[MGA_CTXREG_DWGCTL] =
+ (( mmesa->Setup[MGA_CTXREG_DWGCTL] & DC_opcod_MASK ) |
+ DC_opcod_texture_trap);
+
+ t = (mgaTextureObjectPtr)tObj->DriverData;
+
+ if (t->dirty_images)
+ mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << unit);
+
+ mmesa->CurrentTexObj[unit] = t;
+
+ t->Setup[MGA_TEXREG_CTL2] &= ~TMC_dualtex_enable;
+ if (ctx->Texture.Enabled == (TEXTURE0_2D|TEXTURE1_2D))
+ t->Setup[MGA_TEXREG_CTL2] |= TMC_dualtex_enable;
+
+ t->Setup[MGA_TEXREG_CTL2] &= ~TMC_specen_enable;
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ t->Setup[MGA_TEXREG_CTL2] |= TMC_specen_enable;
+
+}
+
+
+
+
+
+
+/* The G400 is now programmed quite differently wrt texture environment.
+ */
+void mgaUpdateTextureState( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mmesa->Fallback &= ~MGA_FALLBACK_TEXTURE;
+
+ if (MGA_IS_G400(mmesa)) {
+ mgaUpdateTextureObject( ctx, 0 );
+ mgaUpdateTextureStage( ctx, 0 );
+
+ mmesa->Setup[MGA_CTXREG_TDUAL1] = mmesa->Setup[MGA_CTXREG_TDUAL0];
+
+ if (mmesa->multitex) {
+ mgaUpdateTextureObject( ctx, 1 );
+ mgaUpdateTextureStage( ctx, 1 );
+ }
+ } else {
+ mgaUpdateTextureObject( ctx, 0 );
+ mgaUpdateTextureEnvG200( ctx );
+ }
+
+ /* schedule the register writes */
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+}
+
+
+
+/*
+============================================================================
+
+Driver functions called directly from mesa
+
+============================================================================
+*/
+
+/*
+ * mgaTexEnv
+ */
+void mgaTexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param ) {
+ mgaMsg( 10, "mgaTexEnv( %i )\n", pname );
+
+ if (pname == GL_TEXTURE_ENV_MODE) {
+ /* force the texture state to be updated */
+ MGA_CONTEXT(ctx)->CurrentTexObj[0] = 0;
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+ }
+}
+
+/*
+ * mgaTexImage
+ */
+void mgaTexImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaTextureObjectPtr t;
+
+ mgaMsg( 10,"mgaTexImage( %p, level %i )\n", tObj, level );
+
+ /* just free the mga texture if it exists, it will be recreated at
+ mgaUpdateTextureState time. */
+ t = (mgaTextureObjectPtr) tObj->DriverData;
+ if ( t ) {
+ /* if this is the current object, it will force an update */
+ mgaDestroyTexObj( mmesa, t );
+ mmesa->new_state |= MGA_NEW_TEXTURE;
+ }
+}
+
+/*
+ * mgaTexSubImage
+ */
+void mgaTexSubImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaTextureObjectPtr t;
+
+ mgaMsg(10,"mgaTexSubImage() Size: %d,%d of %d,%d; Level %d\n",
+ width, height, image->Width,image->Height, level);
+
+ t = (mgaTextureObjectPtr) tObj->DriverData;
+
+
+ /* just free the mga texture if it exists, it will be recreated at
+ mgaUpdateTextureState time. */
+ t = (mgaTextureObjectPtr) tObj->DriverData;
+ if ( t ) {
+ /* if this is the current object, it will force an update */
+ mgaDestroyTexObj( mmesa, t );
+ mmesa->new_state |= MGA_NEW_TEXTURE;
+ }
+
+
+
+#if 0
+ /* the texture currently exists, so directly update it */
+ mgaUploadSubImage( t, level, xoffset, yoffset, width, height );
+#endif
+}
+
+/*
+ * mgaTexParameter
+ * This just changes variables and flags for a state update, which
+ * will happen at the next mgaUpdateTextureState
+ */
+void mgaTexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params ) {
+ mgaTextureObjectPtr t;
+
+ mgaMsg( 10, "mgaTexParameter( %p, %i )\n", tObj, pname );
+
+ 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 || target != GL_TEXTURE_2D ) {
+ return;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT);
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ mgaSetTexBorderColor(t,tObj->BorderColor);
+ break;
+
+ default:
+ return;
+ }
+ /* force the texture state to be updated */
+ MGA_CONTEXT(ctx)->CurrentTexObj[0] = NULL;
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+}
+
+/*
+ * mgaBindTexture
+ */
+void mgaBindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj ) {
+
+ mgaMsg( 10, "mgaBindTexture( %p )\n", tObj );
+
+ /* force the texture state to be updated
+ */
+ MGA_CONTEXT(ctx)->CurrentTexObj[0] = NULL;
+ MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+}
+
+/*
+ * mgaDeleteTexture
+ */
+void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) {
+
+ mgaMsg( 10, "mgaDeleteTexture( %p )\n", tObj );
+
+ /* delete our driver data */
+ if ( tObj->DriverData ) {
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaDestroyTexObj( mmesa,
+ (mgaTextureObjectPtr)(tObj->DriverData) );
+ mmesa->new_state |= MGA_NEW_TEXTURE;
+ }
+}
+
+
+/* Have to grab the lock to find out if anyone has kicked out our
+ * textures.
+ */
+GLboolean mgaIsTextureResident( GLcontext *ctx, struct gl_texture_object *t )
+{
+ mgaTextureObjectPtr mt;
+
+/* LOCK_HARDWARE; */
+ mt = (mgaTextureObjectPtr)t->DriverData;
+/* UNLOCK_HARDWARE; */
+
+ return mt && mt->MemBlock;
+}
+
+void mgaDDInitTextureFuncs( GLcontext *ctx )
+{
+ ctx->Driver.TexEnv = mgaTexEnv;
+ ctx->Driver.TexImage = mgaTexImage;
+ ctx->Driver.TexSubImage = mgaTexSubImage;
+ ctx->Driver.BindTexture = mgaBindTexture;
+ ctx->Driver.DeleteTexture = mgaDeleteTexture;
+ ctx->Driver.TexParameter = mgaTexParameter;
+ ctx->Driver.UpdateTexturePalette = 0;
+ ctx->Driver.IsTextureResident = mgaIsTextureResident;
+}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.h b/xc/lib/GL/mesa/src/drv/mga/mgatex.h
new file mode 100644
index 000000000..1e8e7e86f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.h
@@ -0,0 +1,119 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * John Carmack <johnc@idsoftware.com>
+ * Keith Whitwell <keithw@precisioninsight.com>
+ */
+
+#ifndef MGATEX_INC
+#define MGATEX_INC
+
+#include "mga_drm_public.h"
+#include "types.h"
+#include "mgacommon.h"
+#include "mm.h"
+
+
+#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;
+ mgaContextPtr ctx;
+ PMemBlock MemBlock;
+ mgaUI32 offsets[MGA_TEX_MAXLEVELS];
+ int lastLevel;
+ mgaUI32 dirty_images;
+ mgaUI32 totalSize;
+ int texelBytes;
+ mgaUI32 age;
+ mgaUI32 Setup[MGA_TEX_SETUP_SIZE];
+} mgaTextureObject_t;
+
+typedef mgaTextureObject_t *mgaTextureObjectPtr;
+
+/* called to check for environment variable options */
+void mgaInitTextureSystem( void );
+
+/* called when a context is being destroyed */
+void mgaDestroyContextTextures( mgaContextPtr ctx );
+
+/* 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 );
+
+
+/* Driver functions which are called directly from mesa */
+
+void mgaTexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param );
+
+void mgaTexImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint internalFormat,
+ const struct gl_texture_image *image );
+
+void mgaTexSubImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLint internalFormat,
+ const struct gl_texture_image *image );
+
+void mgaTexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params );
+
+void mgaBindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj );
+
+void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj );
+
+void mgaUpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj );
+
+GLboolean mgaIsTextureResident( GLcontext *ctx, struct gl_texture_object *t );
+
+void mgaConvertTexture( mgaUI32 *destPtr, int texelBytes,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height );
+
+
+
+int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t );
+
+
+
+
+void mgaResetGlobalLRU( mgaContextPtr mmesa );
+void mgaTexturesGone( mgaContextPtr mmesa, GLuint offset,
+ GLuint size, GLuint in_use );
+
+void mgaDDInitTextureFuncs( GLcontext *ctx );
+
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c
new file mode 100644
index 000000000..bd8ef083f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c
@@ -0,0 +1,226 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "vb.h"
+#include "pipeline.h"
+
+#include "mm.h"
+#include "mgalib.h"
+#include "mgatris.h"
+#include "mgavb.h"
+#include "mgalog.h"
+
+
+static void mga_null_quad( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint v3, GLuint pv ) {
+}
+static void mga_null_triangle( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint pv ) {
+}
+static void mga_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) {
+}
+
+static void mga_null_points( GLcontext *ctx, GLuint first, GLuint last ) {
+}
+
+
+#define MGA_COLOR(to, from) { \
+ (to)[0] = (from)[2]; \
+ (to)[1] = (from)[1]; \
+ (to)[2] = (from)[0]; \
+ (to)[3] = (from)[3]; \
+}
+
+
+
+static triangle_func tri_tab[0x20];
+static quad_func quad_tab[0x20];
+static line_func line_tab[0x20];
+static points_func points_tab[0x20];
+
+static void mgaPrintRenderState( const char *msg, GLuint state )
+{
+ mgaMsg(1, "%s: (%x) %s%s%s%s%s%s\n",
+ msg, state,
+ (state & MGA_FLAT_BIT) ? "flat, " : "",
+ (state & MGA_OFFSET_BIT) ? "offset, " : "",
+ (state & MGA_TWOSIDE_BIT) ? "twoside, " : "",
+ (state & MGA_ANTIALIAS_BIT) ? "antialias, " : "",
+ (state & MGA_NODRAW_BIT) ? "no-draw, " : "",
+ (state & MGA_FALLBACK_BIT) ? "fallback" : "");
+}
+
+#define IND (0)
+#define TAG(x) x
+#include "mgatritmp.h"
+
+#define IND (MGA_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "mgatritmp.h"
+
+#define IND (MGA_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "mgatritmp.h"
+
+#define IND (MGA_OFFSET_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_offset_flat
+#include "mgatritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "mgatritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_flat
+#include "mgatritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "mgatritmp.h"
+
+#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_flat
+#include "mgatritmp.h"
+
+void mgaDDTrifuncInit()
+{
+ int i;
+
+
+ init();
+ init_flat();
+ init_offset();
+ init_offset_flat();
+ init_twoside();
+ init_twoside_flat();
+ init_twoside_offset();
+ init_twoside_offset_flat();
+
+ /* Hmmm...
+ */
+ for (i = 0 ; i < 0x20 ; i++) {
+ if (i & ~MGA_FLAT_BIT) {
+ points_tab[i] = points_tab[i&MGA_FLAT_BIT];
+ line_tab[i] = line_tab[i&MGA_FLAT_BIT];
+ }
+ }
+
+ for (i = 0 ; i < 0x20 ; i++)
+ if ((i & (MGA_NODRAW_BIT|MGA_FALLBACK_BIT)) == MGA_NODRAW_BIT ||
+ mgaglx.nullprims)
+ {
+ quad_tab[i] = mga_null_quad;
+ tri_tab[i] = mga_null_triangle;
+ line_tab[i] = mga_null_line;
+ points_tab[i] = mga_null_points;
+ }
+
+ if (mgaglx.noFallback) {
+ for (i = 0 ; i < 0x10 ; i++) {
+ points_tab[i|MGA_FALLBACK_BIT] = points_tab[i];
+ line_tab[i|MGA_FALLBACK_BIT] = line_tab[i];
+ tri_tab[i|MGA_FALLBACK_BIT] = tri_tab[i];
+ quad_tab[i|MGA_FALLBACK_BIT] = quad_tab[i];
+ }
+ }
+
+}
+
+
+
+
+
+
+void mgaDDChooseRenderState( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ GLuint flags = ctx->TriangleCaps;
+
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+
+ if (flags) {
+ GLuint ind = 0;
+ GLuint shared = 0;
+ GLuint fallback = MGA_FALLBACK_BIT;
+
+ if (mgaglx.noFallback) fallback = 0;
+
+ if (flags & DD_Z_NEVER) shared |= MGA_NODRAW_BIT;
+ if (flags & DD_FLATSHADE) shared |= MGA_FLAT_BIT;
+ if (flags & DD_MULTIDRAW) shared |= fallback;
+ if (flags & (DD_SELECT|DD_FEEDBACK)) shared |= MGA_FALLBACK_BIT;
+ if (flags & DD_STENCIL) shared |= MGA_FALLBACK_BIT;
+
+ ind = shared;
+ if (flags & DD_POINT_SMOOTH) ind |= MGA_ANTIALIAS_BIT;
+ if (flags & DD_POINT_ATTEN) ind |= fallback;
+
+ mmesa->renderindex = ind;
+ mmesa->PointsFunc = points_tab[ind];
+ if (ind & MGA_FALLBACK_BIT)
+ ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+
+ ind = shared;
+ if (flags & DD_LINE_SMOOTH) ind |= MGA_ANTIALIAS_BIT;
+ if (flags & DD_LINE_STIPPLE) ind |= fallback;
+
+ mmesa->renderindex |= ind;
+ mmesa->LineFunc = line_tab[ind];
+ if (ind & MGA_FALLBACK_BIT)
+ ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+
+ ind = shared;
+ if (flags & DD_TRI_SMOOTH) ind |= MGA_ANTIALIAS_BIT;
+ if (flags & DD_TRI_OFFSET) ind |= MGA_OFFSET_BIT;
+ if (flags & DD_TRI_LIGHT_TWOSIDE) ind |= MGA_TWOSIDE_BIT;
+ if (flags & (DD_TRI_UNFILLED|DD_TRI_STIPPLE)) ind |= fallback;
+
+ mmesa->renderindex |= ind;
+ mmesa->TriangleFunc = tri_tab[ind];
+ mmesa->QuadFunc = quad_tab[ind];
+ if (ind & MGA_FALLBACK_BIT)
+ ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | DD_QUAD_SW_RASTERIZE);
+ }
+ else if (mmesa->renderindex)
+ {
+ mmesa->renderindex = 0;
+ mmesa->PointsFunc = points_tab[0];
+ mmesa->LineFunc = line_tab[0];
+ mmesa->TriangleFunc = tri_tab[0];
+ mmesa->QuadFunc = quad_tab[0];
+ }
+
+ if (0) {
+ gl_print_tri_caps("tricaps", ctx->TriangleCaps);
+ mgaPrintRenderState("mga: Render state", mmesa->renderindex);
+ }
+}
+
+
+
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.h b/xc/lib/GL/mesa/src/drv/mga/mgatris.h
new file mode 100644
index 000000000..3b41900f1
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.h
@@ -0,0 +1,189 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+#ifndef MGATIS_INC
+#define MGATIS_INC
+
+#include "types.h"
+
+extern void mgaDDChooseRenderState(GLcontext *ctx);
+extern void mgaDDTrifuncInit( void );
+
+
+/* Todo:
+ * - multidraw, ...
+ * - Antialiasing (?)
+ * - line and polygon stipple
+ * - select and feedback
+ * - stencil
+ * - point parameters
+ * -
+ */
+#define MGA_ANTIALIAS_BIT 0 /* ignored for now, no fallback */
+#define MGA_FLAT_BIT 0x1
+#define MGA_OFFSET_BIT 0x2 /* 3.1 only */
+#define MGA_TWOSIDE_BIT 0x4 /* 3.1 only */
+#define MGA_NODRAW_BIT 0x8
+#define MGA_FALLBACK_BIT 0x10
+
+/* Not in use:
+ */
+#define MGA_FEEDBACK_BIT 0x20
+#define MGA_SELECT_BIT 0x40
+#define MGA_POINT_PARAM_BIT 0x80 /* not needed? */
+
+
+
+
+static __inline void mga_draw_triangle( mgaContextPtr mmesa,
+ mgaVertex *v0,
+ mgaVertex *v1,
+ mgaVertex *v2 )
+{
+ mgaUI32 vertsize = mmesa->vertsize;
+ mgaUI32 *wv = mgaAllocVertexDwords( mmesa, 3 * vertsize );
+ int j;
+
+ for (j = 0 ; j < vertsize ; j++)
+ wv[j] = v0->ui[j];
+
+ wv += vertsize;
+ for (j = 0 ; j < vertsize ; j++)
+ wv[j] = v1->ui[j];
+
+ wv += vertsize;
+ for (j = 0 ; j < vertsize ; j++)
+ wv[j] = v2->ui[j];
+}
+
+
+static __inline void mga_draw_point( mgaContextPtr mmesa,
+ mgaVertex *tmp, float sz )
+{
+ mgaUI32 vertsize = mmesa->vertsize;
+ mgaUI32 *wv = mgaAllocVertexDwords( mmesa, 6*vertsize);
+ int j;
+
+ *(float *)&wv[0] = tmp->warp1.x - sz;
+ *(float *)&wv[1] = tmp->warp1.y - sz;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp->warp1.x + sz;
+ *(float *)&wv[1] = tmp->warp1.y - sz;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp->warp1.x + sz;
+ *(float *)&wv[1] = tmp->warp1.y + sz;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp->warp1.x + sz;
+ *(float *)&wv[1] = tmp->warp1.y + sz;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp->warp1.x - sz;
+ *(float *)&wv[1] = tmp->warp1.y + sz;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp->warp1.x - sz;
+ *(float *)&wv[1] = tmp->warp1.y - sz;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp->ui[j];
+}
+
+
+static __inline void mga_draw_line( mgaContextPtr mmesa,
+ const mgaVertex *tmp0,
+ const mgaVertex *tmp1,
+ float width )
+{
+ mgaUI32 vertsize = mmesa->vertsize;
+ mgaUI32 *wv = mgaAllocVertexDwords( mmesa, 6 * vertsize );
+ float dx, dy, ix, iy;
+ int j;
+
+ dx = tmp0->warp1.x - tmp1->warp1.x;
+ dy = tmp0->warp1.y - tmp1->warp1.y;
+
+ ix = width * .5; iy = 0;
+
+ if ((ix<.5) && (ix>0.1)) ix = .5; /* I want to see lines with width
+ 0.5 also */
+
+ if (dx * dx > dy * dy) {
+ iy = ix; ix = 0;
+ }
+
+ *(float *)&wv[0] = tmp0->warp1.x - ix;
+ *(float *)&wv[1] = tmp0->warp1.y - iy;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp0->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp1->warp1.x + ix;
+ *(float *)&wv[1] = tmp1->warp1.y + iy;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp1->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp0->warp1.x + ix;
+ *(float *)&wv[1] = tmp0->warp1.y + iy;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp0->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp0->warp1.x - ix;
+ *(float *)&wv[1] = tmp0->warp1.y - iy;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp0->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp1->warp1.x - ix;
+ *(float *)&wv[1] = tmp1->warp1.y - iy;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp1->ui[j];
+ wv += vertsize;
+
+ *(float *)&wv[0] = tmp1->warp1.x + ix;
+ *(float *)&wv[1] = tmp1->warp1.y + iy;
+ for (j = 2 ; j < vertsize ; j++)
+ wv[j] = tmp1->ui[j];
+ wv += vertsize;
+}
+
+
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h
new file mode 100644
index 000000000..ac5a545d2
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h
@@ -0,0 +1,150 @@
+
+static __inline void TAG(triangle)( GLcontext *ctx, GLuint e0,
+ GLuint e1, GLuint e2, GLuint pv )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ GLuint vertsize = mmesa->vertsize;
+ mgaUI32 *wv = mgaAllocVertexDwords( mmesa, 3 * vertsize);
+
+ struct vertex_buffer *VB = ctx->VB;
+ mgaVertexPtr mgaVB = MGA_DRIVER_DATA(VB)->verts;
+ const mgaVertex *v[3];
+ int i, j;
+
+#if (IND & MGA_OFFSET_BIT)
+ GLfloat offset = ctx->Polygon.OffsetUnits * 1.0/0x10000;
+#endif
+
+#if (IND & (MGA_FLAT_BIT|MGA_TWOSIDE_BIT))
+ mgaUI32 c[3];
+
+ c[2] = c[1] = c[0] = *(mgaUI32 *)&mgaVB[pv].warp2.color;
+#endif
+
+ (void) VB;
+
+ v[0] = &mgaVB[e0];
+ v[1] = &mgaVB[e1];
+ v[2] = &mgaVB[e2];
+
+
+#if (IND & (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT))
+ {
+ GLfloat ex = v[0]->warp1.x - v[2]->warp1.x;
+ GLfloat ey = v[0]->warp1.y - v[2]->warp1.y;
+ GLfloat fx = v[1]->warp1.x - v[2]->warp1.x;
+ GLfloat fy = v[1]->warp1.y - v[2]->warp1.y;
+ GLfloat cc = ex*fy-ey*fx;
+
+#if (IND & MGA_TWOSIDE_BIT)
+ {
+ GLuint facing = (cc>0.0) ^ ctx->Polygon.FrontBit;
+ GLubyte (*vbcolor)[4] = VB->Color[facing]->data;
+ if (IND & MGA_FLAT_BIT) {
+ MGA_COLOR((char *)&c[0],vbcolor[pv]);
+ c[2] = c[1] = c[0];
+ } else {
+ MGA_COLOR((char *)&c[0],vbcolor[e0]);
+ MGA_COLOR((char *)&c[1],vbcolor[e1]);
+ MGA_COLOR((char *)&c[2],vbcolor[e2]);
+ }
+ }
+#endif
+
+#if (IND & MGA_OFFSET_BIT)
+ {
+ if (cc * cc > 1e-16) {
+ GLfloat factor = ctx->Polygon.OffsetFactor;
+ GLfloat ez = v[0]->warp1.z - v[2]->warp1.z;
+ GLfloat fz = v[1]->warp1.z - v[2]->warp1.z;
+ GLfloat a = ey*fz-ez*fy;
+ GLfloat b = ez*fx-ex*fz;
+ GLfloat ic = 1.0 / cc;
+ GLfloat ac = a * ic;
+ GLfloat bc = b * ic;
+ if (ac<0.0F) ac = -ac;
+ if (bc<0.0F) bc = -bc;
+ offset += MAX2( ac, bc ) * factor;
+ }
+ }
+#endif
+ }
+#endif
+
+ mgaglx.c_triangles++;
+
+ for (j = 0 ; j < 3 ; j++, wv += vertsize) {
+
+ for (i = 0 ; i < vertsize ; i++)
+ wv[i] = v[j]->ui[i];
+
+#if (IND & (MGA_FLAT_BIT|MGA_TWOSIDE_BIT))
+ wv[4] = c[j]; /* color is the fifth element... */
+#endif
+#if (IND & MGA_OFFSET_BIT)
+ *(float *)&wv[2] = v[j]->warp1.z + offset;
+#endif
+ }
+}
+
+
+
+static void TAG(quad)( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint v3,
+ GLuint pv )
+{
+ TAG(triangle)( ctx, v0, v1, v3, pv );
+ TAG(triangle)( ctx, v1, v2, v3, pv );
+}
+
+
+#if ((IND & ~MGA_FLAT_BIT) == 0)
+
+static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaVertexPtr mgaVB = MGA_DRIVER_DATA(ctx->VB)->verts;
+ float width = ctx->Line.Width;
+
+ if (IND & MGA_FLAT_BIT) {
+ mgaVertex tmp0 = mgaVB[v0];
+ mgaVertex tmp1 = mgaVB[v1];
+ *(int *)&tmp0.warp1.color = *(int *)&mgaVB[pv].warp1.color;
+ *(int *)&tmp1.warp1.color = *(int *)&mgaVB[pv].warp1.color;
+ mga_draw_line( mmesa, &tmp0, &tmp1, width );
+ }
+ else
+ mga_draw_line( mmesa, &mgaVB[v0], &mgaVB[v1], width );
+}
+
+
+static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ struct vertex_buffer *VB = ctx->VB;
+ mgaVertexPtr mgaVB = MGA_DRIVER_DATA(VB)->verts;
+ GLfloat sz = ctx->Point.Size * .5;
+ int i;
+
+ for(i=first;i<=last;i++)
+ if(VB->ClipMask[i]==0)
+ mga_draw_point( mmesa, &mgaVB[i], sz );
+}
+
+#endif
+
+
+static void TAG(init)( void )
+{
+ tri_tab[IND] = TAG(triangle);
+ quad_tab[IND] = TAG(quad);
+
+#if ((IND & ~MGA_FLAT_BIT) == 0)
+ line_tab[IND] = TAG(line);
+ points_tab[IND] = TAG(points);
+#endif
+}
+
+
+#undef IND
+#undef TAG
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c
new file mode 100644
index 000000000..f78c542c8
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c
@@ -0,0 +1,493 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+#include "mgalib.h"
+#include "mgavb.h"
+#include "mgalog.h"
+#include "stages.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TEX0 { \
+ v->warp2.tu0 = tc0[i][0]; \
+ v->warp2.tv0 = tc0[i][1]; \
+}
+
+#define TEX1 { \
+ v->warp2.tu1 = tc1[i][0]; \
+ v->warp2.tv1 = tc1[i][1]; \
+}
+
+#define SPC { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->warp2.specular.red = spec[0]; \
+ v->warp2.specular.green = spec[1]; \
+ v->warp2.specular.blue = spec[2]; \
+}
+
+#define FOG { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->warp2.specular.alpha = spec[3]; \
+}
+
+#define COL { \
+ GLubyte *col = &(VB->Color[0]->data[i][0]); \
+ v->warp2.color.blue = col[2]; \
+ v->warp2.color.green = col[1]; \
+ v->warp2.color.red = col[0]; \
+ v->warp2.color.alpha = col[3]; \
+}
+
+/* The warp2 code we have doesn't seem to support projective texturing
+ * in the multitexture case. (Would require another 1/w value for the
+ * second set of texcoords). This may be a problem for the g400.
+ */
+#define TEX0_4 \
+ if (VB->TexCoordPtr[0]->size == 4) \
+ { \
+ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \
+ v = &(MGA_DRIVER_DATA(VB)->verts[start]); \
+ mmesa->setupdone &= ~MGA_WIN_BIT; \
+ for (i=start; i < end; i++, v++) { \
+ float oow = 1.0 / tc[i][3]; \
+ v->warp2.rhw *= tc[i][3]; \
+ v->warp2.tu0 *= oow; \
+ v->warp2.tv0 *= oow; \
+ } \
+ }
+
+
+#define COORD \
+ GLfloat *win = VB->Win.data[i]; \
+ v->warp2.rhw = win[3]; \
+ v->warp2.z = (1.0/0x10000) * win[2]; \
+ v->warp2.x = win[0] + xoffset; \
+ v->warp2.y = - win[1] + yoffset;
+
+#define NOP
+
+
+
+
+#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,spec,fog) \
+static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
+{ \
+ mgaContextPtr mmesa = MGA_CONTEXT( VB->ctx ); \
+ mgaVertexPtr v; \
+ GLfloat (*tc0)[4]; \
+ GLfloat (*tc1)[4]; \
+ GLfloat xoffset = 0.5 + mmesa->drawX; \
+ GLfloat yoffset = mmesa->driDrawable->h - 0.5 + mmesa->drawY; \
+ int i; \
+ (void) xoffset; (void) yoffset; \
+ \
+ gl_import_client_data( VB, VB->ctx->RenderFlags, \
+ (VB->ClipOrMask \
+ ? VEC_WRITABLE|VEC_GOOD_STRIDE \
+ : VEC_GOOD_STRIDE)); \
+ \
+ tc0 = VB->TexCoordPtr[mmesa->tmu_source[0]]->data; \
+ tc1 = VB->TexCoordPtr[mmesa->tmu_source[1]]->data; \
+ \
+ v = &(MGA_DRIVER_DATA(VB)->verts[start]); \
+ \
+ if (VB->ClipOrMask == 0) \
+ for (i=start; i < end; i++, v++) { \
+ win; \
+ col; \
+ tex0; \
+ tex1; \
+ spec; \
+ fog; \
+ } \
+ else \
+ for (i=start; i < end; i++, v++) { \
+ if (VB->ClipMask[i] == 0) { \
+ win; \
+ tex0; \
+ tex1; \
+ spec; \
+ fog; \
+ } \
+ col; \
+ } \
+ tex0_4; \
+}
+
+
+
+SETUPFUNC(rs_wt0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wt0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wft0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wft0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wg, COORD,COL,NOP,NOP,NOP,NOP,NOP)
+SETUPFUNC(rs_wgs, COORD,COL,NOP,NOP,NOP,SPC,NOP)
+SETUPFUNC(rs_wgt0, COORD,COL,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wgt0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_wgst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_wgst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_wgf, COORD,COL,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_wgfs, COORD,COL,NOP,NOP,NOP,SPC,FOG)
+SETUPFUNC(rs_wgft0, COORD,COL,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wgft0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_wgfst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,FOG)
+SETUPFUNC(rs_wgfst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,FOG)
+
+SETUPFUNC(rs_t0, NOP,NOP,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_t0t1, NOP,NOP,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_f, NOP,NOP,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_ft0, NOP,NOP,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_ft0t1, NOP,NOP,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_g, NOP,COL,NOP,NOP,NOP,NOP,NOP)
+SETUPFUNC(rs_gs, NOP,COL,NOP,NOP,NOP,SPC,NOP)
+SETUPFUNC(rs_gt0, NOP,COL,TEX0,NOP,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_gt0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,NOP)
+SETUPFUNC(rs_gst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_gst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,NOP)
+SETUPFUNC(rs_gf, NOP,COL,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_gfs, NOP,COL,NOP,NOP,NOP,SPC,FOG)
+SETUPFUNC(rs_gft0, NOP,COL,TEX0,NOP,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_gft0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,FOG)
+SETUPFUNC(rs_gfst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,FOG)
+SETUPFUNC(rs_gfst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,FOG)
+
+
+static void rs_invalid(struct vertex_buffer *VB, GLuint start, GLuint end)
+{
+ mgaError("mgaRasterSetup(): invalid combination\n");
+}
+
+typedef void (*setupFunc)(struct vertex_buffer *,GLuint,GLuint);
+
+static setupFunc setup_func[0x80];
+
+void mgaDDSetupInit( void )
+{
+ int i;
+
+ for (i = 0 ; i < 0x80 ; i++)
+ setup_func[i] = rs_invalid;
+
+ /* Functions to build vert's from scratch */
+ setup_func[MGA_WIN_BIT|MGA_TEX0_BIT] = rs_wt0;
+ setup_func[MGA_WIN_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_wt0t1;
+ setup_func[MGA_WIN_BIT|MGA_FOG_BIT|MGA_TEX0_BIT] = rs_wft0;
+ setup_func[MGA_WIN_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_wft0t1;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT] = rs_wg;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT] = rs_wgs;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT] = rs_wgt0;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_wgt0t1;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT] = rs_wgst0;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_wgst0t1;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_FOG_BIT] = rs_wgf;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT] = rs_wgfs;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT] = rs_wgft0;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_wgft0t1;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT] = rs_wgfst0;
+ setup_func[MGA_WIN_BIT|MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_wgfst0t1;
+
+ /* Repair functions */
+ setup_func[MGA_TEX0_BIT] = rs_t0;
+ setup_func[MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_t0t1;
+ setup_func[MGA_FOG_BIT] = rs_f;
+ setup_func[MGA_FOG_BIT|MGA_TEX0_BIT] = rs_ft0;
+ setup_func[MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_ft0t1;
+ setup_func[MGA_RGBA_BIT] = rs_g;
+ setup_func[MGA_RGBA_BIT|MGA_SPEC_BIT] = rs_gs;
+ setup_func[MGA_RGBA_BIT|MGA_TEX0_BIT] = rs_gt0;
+ setup_func[MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_gt0t1;
+ setup_func[MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT] = rs_gst0;
+ setup_func[MGA_RGBA_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_gst0t1;
+ setup_func[MGA_RGBA_BIT|MGA_FOG_BIT] = rs_gf;
+ setup_func[MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT] = rs_gfs;
+ setup_func[MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT] = rs_gft0;
+ setup_func[MGA_RGBA_BIT|MGA_FOG_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_gft0t1;
+ setup_func[MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT] = rs_gfst0;
+ setup_func[MGA_RGBA_BIT|MGA_FOG_BIT|MGA_SPEC_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT] = rs_gfst0t1;
+
+}
+
+
+void mgaPrintSetupFlags(char *msg, GLuint flags )
+{
+ fprintf(stderr, "%s: %d %s%s%s%s%s%s%s\n",
+ msg,
+ (int)flags,
+ (flags & MGA_WIN_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," : "",
+ (flags & MGA_ALPHA_BIT) ? " alpha," : "");
+}
+
+
+
+
+void mgaChooseRasterSetupFunc(GLcontext *ctx)
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ int funcindex = (MGA_WIN_BIT | MGA_RGBA_BIT);
+
+ mmesa->vertsize = 8;
+ mmesa->tmu_source[0] = 0;
+ mmesa->tmu_source[1] = 1;
+ mmesa->tex_dest[0] = MGA_TEX0_BIT;
+ mmesa->tex_dest[1] = MGA_TEX1_BIT;
+ mmesa->multitex = 0;
+
+ if (ctx->Texture.Enabled & 0xf) {
+ if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE)
+ funcindex &= ~MGA_RGBA_BIT;
+
+ funcindex |= MGA_TEX0_BIT;
+ }
+
+ if (ctx->Texture.Enabled & 0xf0) {
+ if (ctx->Texture.Enabled & 0xf) {
+ mmesa->multitex = 1;
+ mmesa->vertsize = 10;
+ funcindex |= MGA_TEX1_BIT;
+ } else {
+ /* Just a funny way of doing single texturing
+ */
+ mmesa->tmu_source[0] = 1;
+ mmesa->tex_dest[1] = MGA_TEX0_BIT;
+
+ if (ctx->Texture.Unit[1].EnvMode == GL_REPLACE)
+ funcindex &= ~MGA_RGBA_BIT;
+
+ funcindex |= MGA_TEX0_BIT;
+ }
+ }
+
+ if (ctx->Color.BlendEnabled)
+ funcindex |= MGA_ALPHA_BIT;
+
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ funcindex |= MGA_SPEC_BIT;
+
+ if (ctx->Fog.Enabled)
+ funcindex |= MGA_FOG_BIT;
+
+ if (0)
+ mgaPrintSetupFlags("xsmesa: full setup function", funcindex);
+
+ mmesa->setupindex = funcindex;
+
+ /* Called by mesa's clip functons:
+ */
+ ctx->Driver.RasterSetup = setup_func[funcindex & ~MGA_ALPHA_BIT];
+}
+
+
+
+
+void mgaDDCheckPartialRasterSetup( GLcontext *ctx, struct gl_pipeline_stage *d )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ GLuint tmp = mmesa->setupdone;
+
+ d->type = 0;
+ mmesa->setupdone = 0; /* cleared if we return */
+
+ if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0)
+ return;
+
+ if (ctx->IndirectTriangles)
+ return;
+
+ mmesa->setupdone = tmp;
+
+ /* disabled until we have a merge&render op */
+ /* d->inputs = available; */
+ /* d->outputs = VERT_RAST_SETUP_PART; */
+ /* d->type = PIPE_PRECALC; */
+}
+
+
+/* Repair existing precalculated vertices with new data.
+ */
+void mgaDDPartialRasterSetup( struct vertex_buffer *VB )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( VB->ctx );
+ GLuint new = VB->pipeline->new_outputs;
+ GLuint available = VB->pipeline->outputs;
+ GLuint ind = 0;
+
+ if (new & VERT_WIN) {
+ new = available;
+ ind |= MGA_WIN_BIT | MGA_FOG_BIT;
+ }
+
+ if (new & VERT_RGBA)
+ ind |= MGA_RGBA_BIT | MGA_SPEC_BIT;
+
+ if (new & VERT_TEX0_ANY)
+ ind |= MGA_TEX0_BIT;
+
+ if (new & VERT_TEX1_ANY)
+ ind |= mmesa->tex_dest[1];
+
+ if (new & VERT_FOG_COORD)
+ ind |= MGA_FOG_BIT;
+
+ mmesa->setupdone &= ~ind;
+ ind &= mmesa->setupindex;
+ mmesa->setupdone |= ind;
+
+ if (0)
+ mgaPrintSetupFlags("xsmesa: partial setup function", ind);
+
+ if (ind)
+ setup_func[ind&~MGA_ALPHA_BIT]( VB, VB->Start, VB->Count );
+}
+
+
+void mgaDDDoRasterSetup( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
+ /* Can't lock, won't lock
+ */
+ REFRESH_DRAWABLE_INFO( mmesa );
+
+ if (VB->Type == VB_CVA_PRECALC)
+ mgaDDPartialRasterSetup( VB );
+ else if (ctx->Driver.RasterSetup)
+ ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count );
+}
+
+static void FatalError( char *s )
+{
+ fprintf(stderr, s);
+ exit(1);
+}
+
+
+
+void mgaDDResizeVB( struct vertex_buffer *VB, GLuint size )
+{
+ mgaVertexBufferPtr mvb = MGA_DRIVER_DATA(VB);
+
+ while (mvb->size < size)
+ mvb->size *= 2;
+
+ free( mvb->vert_store );
+ mvb->vert_store = malloc( sizeof(mgaVertex) * mvb->size + 31);
+ if (!mvb->vert_store)
+ FatalError("mga-glx: out of memory !\n");
+
+ mvb->verts = (mgaVertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31);
+
+ gl_vector1ui_free( &mvb->clipped_elements );
+ gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 );
+ if (!mvb->clipped_elements.start)
+ FatalError("mga-glx: out of memory !\n");
+
+ free( VB->ClipMask );
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size);
+ if (!VB->ClipMask)
+ FatalError("mga-glx: out of memory !\n");
+
+ if (VB->Type == VB_IMMEDIATE) {
+ free( mvb->primitive );
+ free( mvb->next_primitive );
+ mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ if (!mvb->primitive || !mvb->next_primitive)
+ FatalError("mga-glx: out of memory!");
+ }
+}
+
+
+void mgaDDRegisterVB( struct vertex_buffer *VB )
+{
+ mgaVertexBufferPtr mvb;
+
+ mvb = (mgaVertexBufferPtr)calloc( 1, sizeof(*mvb) );
+
+ /* This looks like it allocates a lot of memory, but it basically
+ * just sets an upper limit on how much can be used - nothing like
+ * this amount will ever be turned into 'real' memory.
+ */
+ mvb->size = VB->Size * 5;
+ mvb->vert_store = malloc( sizeof(mgaVertex) * mvb->size + 31);
+ if (!mvb->vert_store)
+ FatalError("mga-glx: out of memory !\n");
+
+ mvb->verts = (mgaVertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31);
+
+ gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 );
+ if (!mvb->clipped_elements.start)
+ FatalError("mga-glx: out of memory !\n");
+
+ free( VB->ClipMask );
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size);
+ if (!VB->ClipMask)
+ FatalError("mga-glx: out of memory !\n");
+
+ mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
+ if (!mvb->primitive || !mvb->next_primitive)
+ FatalError("mga-glx: out of memory!");
+
+ VB->driver_data = mvb;
+}
+
+
+void mgaDDUnregisterVB( struct vertex_buffer *VB )
+{
+ mgaVertexBufferPtr mvb = MGA_DRIVER_DATA(VB);
+
+ if (mvb) {
+ if (mvb->vert_store) free(mvb->vert_store);
+ if (mvb->primitive) free(mvb->primitive);
+ if (mvb->next_primitive) free(mvb->next_primitive);
+ gl_vector1ui_free( &mvb->clipped_elements );
+ free(mvb);
+ VB->driver_data = 0;
+ }
+}
+
+
+mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords )
+{
+ int bytes = dwords * 4;
+ mgaUI32 *head;
+
+ if (mmesa->dma_buffer->used + bytes > mmesa->dma_buffer->total)
+ mgaFlushVertices( mmesa );
+
+ head = (mgaUI32 *)((char *)mmesa->dma_buffer->address +
+ mmesa->dma_buffer->used);
+
+ mmesa->dma_buffer->used += bytes;
+ return head;
+}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.h b/xc/lib/GL/mesa/src/drv/mga/mgavb.h
new file mode 100644
index 000000000..8d7c65207
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.h
@@ -0,0 +1,132 @@
+/*
+ * GLX Hardware Device Driver for Matrox Millenium G200
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * 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
+ * WITTAWAT YAMWONG, 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.
+ *
+ *
+ * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
+ */
+
+#ifndef MGAVB_INC
+#define MGAVB_INC
+
+#include "vb.h"
+#include "mgacommon.h"
+
+
+/* common datatypes for the mga warp engines */
+
+/*
+ * color type for the vertex data
+ * we probably want to use an internal datatype here?
+ */
+typedef struct mga_warp_color_t {
+ GLubyte blue;
+ GLubyte green;
+ GLubyte red;
+ GLubyte alpha;
+} mga_warp_color;
+
+
+/*
+ * vertex type used for the single-warp g200
+ */
+typedef struct mga_warp_vertex_t {
+ GLfloat x,y,z; /* coordinates in screen space*/
+ GLfloat rhw; /* reciprocal homogeneous w */
+ mga_warp_color color; /* vertex color */
+ mga_warp_color specular; /* specular color, alpha is fog */
+ GLfloat tu0,tv0; /* texture coordinates */
+} mga_warp_vertex1;
+
+/*
+ * vertex type used for the dual-warp g400
+ */
+typedef struct mga_warp_vertex2_t {
+ GLfloat x,y,z; /* coordinates in screen space*/
+ GLfloat rhw; /* reciprocal homogeneous w */
+ mga_warp_color color; /* vertex color */
+ mga_warp_color specular; /* specular color, alpha is fog */
+ GLfloat tu0,tv0; /* texture coordinates */
+ GLfloat tu1,tv1; /* same for second stage */
+} mga_warp_vertex2;
+
+
+/* The fastpath code still expects a 16-float stride vertex.
+ */
+union mga_vertex_t {
+ mga_warp_vertex1 warp1;
+ mga_warp_vertex2 warp2;
+ float f[16];
+ mgaUI32 ui[16];
+};
+
+typedef union mga_vertex_t mgaVertex;
+typedef union mga_vertex_t *mgaVertexPtr;
+
+struct mga_vertex_buffer_t {
+ GLvector1ui clipped_elements;
+ mgaVertexPtr verts;
+ int last_vert;
+ GLuint *primitive;
+ GLuint *next_primitive;
+ void *vert_store;
+ GLuint size;
+
+ mgaUI32 *vert_buf;
+ mgaUI32 *elt_buf;
+ mgaUI32 vert_phys_start;
+};
+
+typedef struct mga_vertex_buffer_t *mgaVertexBufferPtr;
+
+#define MGA_CONTEXT(ctx) ((mgaContextPtr)((ctx)->DriverCtx))
+#define MGA_DRIVER_DATA(vb) ((mgaVertexBufferPtr)((vb)->driver_data))
+
+
+#define MGA_FOG_BIT MGA_F
+#define MGA_ALPHA_BIT MGA_A
+#define MGA_SPEC_BIT MGA_S
+#define MGA_TEX1_BIT MGA_T2
+#define MGA_TEX0_BIT 0x10 /* non-warp parameters */
+#define MGA_RGBA_BIT 0x20
+#define MGA_WIN_BIT 0x40
+
+struct gl_pipeline_stage;
+
+extern void mgaChooseRasterSetupFunc(GLcontext *ctx);
+extern void mgaPrintSetupFlags(char *msg, GLuint flags );
+extern void mgaDDDoRasterSetup( struct vertex_buffer *VB );
+extern void mgaDDPartialRasterSetup( struct vertex_buffer *VB );
+extern void mgaDDCheckPartialRasterSetup( GLcontext *ctx,
+ struct gl_pipeline_stage *d );
+
+
+extern void mgaDDUnregisterVB( struct vertex_buffer *VB );
+extern void mgaDDRegisterVB( struct vertex_buffer *VB );
+extern void mgaDDResizeVB( struct vertex_buffer *VB, GLuint size );
+
+extern void mgaDDSetupInit( void );
+
+
+extern mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords );
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
index dc940bab3..d221dc5cd 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
@@ -1,4 +1,5 @@
-XCOMM $PI:$
+
+#include <Threads.tmpl>
#define DoNormalLib NormalLibGlx
#define DoSharedLib SharedLibGlx
@@ -13,6 +14,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
#if BuildXF86DRI
DRI_DEFINES = GlxDefines -DFX -DFX_GLIDE3 -DGLIDE3 -DDRIVERTS
DRI_INCLUDES = -I../../../../dri -I../../../../glx \
+ -I../../../dri \
-I$(TOP)/include -I$(TOP)/include/GL \
-I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
-I$(XF86DRIVERSRC)/tdfx \
@@ -49,18 +51,230 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX)
DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
- -I/usr/include/glide
- DRISRCS = tdfx_xmesa.c tdfx_init.c tdfx_inithw.c
- DRIOBJS = tdfx_xmesa.o tdfx_init.o tdfx_inithw.o
- MESASRCS = fxclip.c fxcva.c fxdd.c fxddspan.c fxddtex.c fxfastpath.c \
+ -I/usr/include/glide3
+
+ DRISRCS = ../../../dri/dri_mesa.c \
+ ../../../../dri/dri_tmm.c
+
+ DRIOBJS = ../../../dri/dri_mesa.o \
+ ../../../../dri/dri_tmm.o
+
+ DRMSRCS = ../../../../dri/drm/xf86drm.c \
+ ../../../../dri/drm/xf86drmHash.c \
+ ../../../../dri/drm/xf86drmRandom.c \
+ ../../../../dri/drm/xf86drmSL.c
+
+ DRMOBJS = ../../../../dri/drm/xf86drm.o \
+ ../../../../dri/drm/xf86drmHash.o \
+ ../../../../dri/drm/xf86drmRandom.o \
+ ../../../../dri/drm/xf86drmSL.o
+
+ TDFXSRCS = tdfx_xmesa.c tdfx_init.c tdfx_inithw.c \
+ fxclip.c fxcva.c fxdd.c fxddspan.c fxddtex.c fxfastpath.c \
fxglidew.c fxpipeline.c fxrender.c fxsanity.c fxsetup.c \
fxtexman.c fxtrifuncs.c fxvsetup.c
- MESAOBJS = fxclip.o fxcva.o fxdd.o fxddspan.o fxddtex.o fxfastpath.o \
+
+ TDFXOBJS = tdfx_xmesa.o tdfx_init.o tdfx_inithw.o \
+ fxclip.o fxcva.o fxdd.o fxddspan.o fxddtex.o fxfastpath.o \
fxglidew.o fxpipeline.o fxrender.o fxsanity.o fxsetup.o \
fxtexman.o fxtrifuncs.o fxvsetup.o
- SRCS = $(DRISRCS) $(MESASRCS)
- OBJS = $(DRIOBJS) $(MESAOBJS)
+ MESASRCS = ../../accum.c \
+ ../../alpha.c \
+ ../../alphabuf.c \
+ ../../attrib.c \
+ ../../bbox.c \
+ ../../bitmap.c \
+ ../../blend.c \
+ ../../buffers.c \
+ ../../clip.c \
+ ../../colortab.c \
+ ../../config.c \
+ ../../context.c \
+ ../../copypix.c \
+ ../../cva.c \
+ ../../debug_xform.c \
+ ../../depth.c \
+ ../../dlist.c \
+ ../../drawpix.c \
+ ../../enable.c \
+ ../../enums.c \
+ ../../eval.c \
+ ../../extensions.c \
+ ../../feedback.c \
+ ../../fog.c \
+ ../../get.c \
+ ../../glapi.c \
+ ../../glapinoop.c \
+ ../../glthread.c \
+ ../../hash.c \
+ ../../image.c \
+ ../../imaging.o \
+ ../../light.c \
+ ../../lines.c \
+ ../../logic.c \
+ ../../masking.c \
+ ../../matrix.c \
+ ../../mem.c \
+ ../../mmath.c \
+ ../../pb.c \
+ ../../pipeline.c \
+ ../../pixel.c \
+ ../../points.c \
+ ../../polygon.c \
+ ../../quads.c \
+ ../../rastpos.c \
+ ../../readpix.c \
+ ../../rect.c \
+ ../../scissor.c \
+ ../../shade.c \
+ ../../span.c \
+ ../../stages.c \
+ ../../state.c \
+ ../../stencil.c \
+ ../../teximage.c \
+ ../../texobj.c \
+ ../../texstate.c \
+ ../../texture.c \
+ ../../translate.c \
+ ../../triangle.c \
+ ../../varray.c \
+ ../../vb.c \
+ ../../vbcull.c \
+ ../../vbfill.c \
+ ../../vbindirect.c \
+ ../../vbrender.c \
+ ../../vbxform.c \
+ ../../vector.c \
+ ../../vertices.c \
+ ../../winpos.c \
+ ../../xform.c \
+ ../../zoom.c \
+ ../../X86/common_x86.c
+
+ MESAOBJS = ../../accum.o \
+ ../../alpha.o \
+ ../../alphabuf.o \
+ ../../attrib.o \
+ ../../bbox.o \
+ ../../bitmap.o \
+ ../../blend.o \
+ ../../buffers.o \
+ ../../clip.o \
+ ../../colortab.o \
+ ../../config.o \
+ ../../context.o \
+ ../../copypix.o \
+ ../../cva.o \
+ ../../debug_xform.o \
+ ../../depth.o \
+ ../../dlist.o \
+ ../../drawpix.o \
+ ../../enable.o \
+ ../../enums.o \
+ ../../eval.o \
+ ../../extensions.o \
+ ../../feedback.o \
+ ../../fog.o \
+ ../../get.o \
+ ../../hash.o \
+ ../../hint.o \
+ ../../image.o \
+ ../../imaging.o \
+ ../../light.o \
+ ../../lines.o \
+ ../../logic.o \
+ ../../masking.o \
+ ../../matrix.o \
+ ../../mem.o \
+ ../../mmath.o \
+ ../../pb.o \
+ ../../pipeline.o \
+ ../../pixel.o \
+ ../../points.o \
+ ../../polygon.o \
+ ../../quads.o \
+ ../../rastpos.o \
+ ../../readpix.o \
+ ../../rect.o \
+ ../../scissor.o \
+ ../../shade.o \
+ ../../span.o \
+ ../../stages.o \
+ ../../state.o \
+ ../../stencil.o \
+ ../../teximage.o \
+ ../../texobj.o \
+ ../../texstate.o \
+ ../../texture.o \
+ ../../translate.o \
+ ../../triangle.o \
+ ../../varray.o \
+ ../../vb.o \
+ ../../vbcull.o \
+ ../../vbfill.o \
+ ../../vbindirect.o \
+ ../../vbrender.o \
+ ../../vbxform.o \
+ ../../vector.o \
+ ../../vertices.o \
+ ../../winpos.o \
+ ../../xform.o \
+ ../../zoom.o
+
+#ifdef i386Architecture
+ X86_SRCS = ../../X86/x86.c \
+ ../../X86/x86a.S \
+ ../../X86/common_x86.c \
+ ../../X86/common_x86asm.S \
+ ../../X86/vertex.S
+
+ X86_OBJS = ../../X86/x86.o \
+ ../../X86/x86a.o \
+ ../../X86/common_x86.o \
+ ../../X86/common_x86asm.o \
+ ../../X86/vertex.o
+
+ MMX_SRCS = ../../X86/mmx_blend.S
+
+ MMX_OBJS = ../../X86/mmx_blend.o
+
+XCOMM Disabling 3Dnow code for the time being.
+#if 0
+ 3DNOW_SRCS = ../../X86/3dnow.c \
+ ../../X86/3dnow_norm_raw.S \
+ ../../X86/3dnow_xform_masked1.S \
+ ../../X86/3dnow_xform_masked2.S \
+ ../../X86/3dnow_xform_masked3.S \
+ ../../X86/3dnow_xform_masked4.S \
+ ../../X86/3dnow_xform_raw1.S \
+ ../../X86/3dnow_xform_raw2.S \
+ ../../X86/3dnow_xform_raw3.S \
+ ../../X86/3dnow_xform_raw4.S \
+ ../../X86/vertex_3dnow.S
+
+ 3DNOW_OBJS = ../../X86/3dnow.o \
+ ../../X86/3dnow_norm_raw.o \
+ ../../X86/3dnow_xform_masked1.o \
+ ../../X86/3dnow_xform_masked2.o \
+ ../../X86/3dnow_xform_masked3.o \
+ ../../X86/3dnow_xform_masked4.o \
+ ../../X86/3dnow_xform_raw1.o \
+ ../../X86/3dnow_xform_raw2.o \
+ ../../X86/3dnow_xform_raw3.o \
+ ../../X86/3dnow_xform_raw4.o \
+ ../../X86/vertex_3dnow.o
+#endif
+
+#endif
+
+ ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
+ ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
+
+ SRCS = $(DRISRCS) $(DRMSRCS) $(TDFXSRCS) $(MESASRCS) $(ASMSRCS)
+ OBJS = $(DRIOBJS) $(DRMOBJS) $(TDFXOBJS) $(MESAOBJS) $(ASMOBJS)
+
+REQUIREDLIBS += -lglide3x
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
@@ -81,7 +295,7 @@ LIBNAME = tdfx_dri.so
ALL_OBJS = $(OBJS)
ALL_DEPS = DONE
SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
-InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.)
#endif
DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c
index eb505b8a3..3fc44b59d 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.c
@@ -57,8 +57,8 @@ static void performMagic(__DRIscreenPrivate *driScrnPriv)
gPriv->mem=gDRIPriv->mem;
gPriv->cpp=gDRIPriv->cpp;
gPriv->stride=gDRIPriv->stride;
- gPriv->fifoOffset=gDRIPriv->priv1;
- gPriv->fifoSize=gDRIPriv->priv2;
+ gPriv->fifoOffset=gDRIPriv->fifoOffset;
+ gPriv->fifoSize=gDRIPriv->fifoSize;
gPriv->fbOffset=gDRIPriv->fbOffset;
gPriv->backOffset=gDRIPriv->backOffset;
gPriv->depthOffset=gDRIPriv->depthOffset;
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.h
index f0b3f4131..ead84e61a 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.h
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.h
@@ -71,8 +71,8 @@ typedef struct {
} tdfxScreenPrivate;
typedef struct {
- volatile int *fifoPtr;
- volatile int *fifoRead;
+ volatile int fifoPtr;
+ volatile int fifoRead;
volatile int fifoOwner;
volatile int ctxOwner;
volatile int texOwner;
@@ -123,8 +123,7 @@ extern void grDRIResetSAREA(void);
extern XMesaContext gCC;
extern tdfxContextPrivate *gCCPriv;
-/*
-You can turn this on to find locking conflicts.
+/* You can turn this on to find locking conflicts.
#define DEBUG_LOCKING
*/
@@ -168,18 +167,20 @@ extern int prevLockLine;
/* Lock the hardware using the global current context */
#define LOCK_HARDWARE() \
do { \
- int stamp; \
char __ret=0; \
__DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \
__DRIscreenPrivate *sPriv = dPriv->driScreenPriv; \
DEBUG_CHECK_LOCK(); \
- DRM_LIGHT_LOCK_RETURN(sPriv->fd, &sPriv->pSAREA->lock, \
- dPriv->driContextPriv->hHWContext, __ret); \
- if (__ret) __ret=1; \
- stamp=dPriv->lastStamp; \
- XMESA_VALIDATE_DRAWABLE_INFO(gCC->display, sPriv, dPriv); \
- if (*(dPriv->pStamp)!=stamp) __ret=2; \
- if (__ret) XMesaUpdateState(__ret==2); \
+ DRM_CAS(&sPriv->pSAREA->lock, dPriv->driContextPriv->hHWContext, \
+ DRM_LOCK_HELD|dPriv->driContextPriv->hHWContext, __ret); \
+ if (__ret) { \
+ int stamp; \
+ drmGetLock(sPriv->fd, dPriv->driContextPriv->hHWContext, 0); \
+ stamp=dPriv->lastStamp; \
+ XMESA_VALIDATE_DRAWABLE_INFO(gCC->display, sPriv, dPriv); \
+ if (*(dPriv->pStamp)!=stamp) XMesaUpdateState(GL_TRUE); \
+ else XMesaUpdateState(GL_FALSE); \
+ } \
DEBUG_LOCK(); \
} while (0)
@@ -205,8 +206,9 @@ extern int prevLockLine;
#define BEGIN_CLIP_LOOP() \
do { \
__DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \
- int _nc = dPriv->numClipRects; \
+ int _nc; \
LOCK_HARDWARE(); \
+ _nc = dPriv->numClipRects; \
while (_nc--) { \
if (gCCPriv->needClip) { \
gCCPriv->clipMinX=dPriv->pClipRects[_nc].x1; \
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c
index 065d33338..7b08f9766 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c
@@ -94,6 +94,8 @@ GLboolean tdfxInitHW(XMesaContext c)
if (!fxMesa->glideContext || !fxDDInitFxMesaContext( fxMesa ))
return GL_FALSE;
+ fxInitPixelTables(fxMesa, GL_FALSE); /* Load tables of pixel colors */
+
cPriv->initDone=GL_TRUE;
return GL_TRUE;
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c
index dca2d806d..38772c95d 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c
@@ -172,7 +172,13 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
c->private = (void *)cPriv;
cPriv->glVis=v->gl_visual;
- cPriv->glBuffer=gl_create_framebuffer(v->gl_visual);
+ cPriv->glBuffer=gl_create_framebuffer(v->gl_visual,
+ GL_FALSE, /* software depth buffer? */
+ v->gl_visual->StencilBits > 0,
+ v->gl_visual->AccumBits > 0,
+ v->gl_visual->AlphaBits > 0
+ );
+
cPriv->screen_width=sPriv->width;
cPriv->screen_height=sPriv->height;
@@ -204,6 +210,10 @@ void XMesaDestroyContext(XMesaContext c)
gl_destroy_context(cPriv->glCtx);
gl_destroy_framebuffer(cPriv->glBuffer);
}
+ if (c==gCC) {
+ gCC=0;
+ gCCPriv=0;
+ }
}
XMesaBuffer XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w,
@@ -225,6 +235,11 @@ void XMesaDestroyBuffer(XMesaBuffer b)
void XMesaSwapBuffers(XMesaBuffer b)
{
FxI32 result;
+#ifdef STATS
+ int stalls;
+ extern int texSwaps;
+ static int prevStalls=0;
+#endif
/*
** NOT_DONE: This assumes buffer is currently bound to a context.
** This needs to be able to swap buffers when not currently bound.
@@ -234,6 +249,17 @@ void XMesaSwapBuffers(XMesaBuffer b)
FLUSH_VB( gCCPriv->glCtx, "swap buffers" );
if (gCCPriv->haveDoubleBuffer) {
+#ifdef STATS
+ stalls=grFifoGetStalls();
+ if (stalls!=prevStalls) {
+ fprintf(stderr, "%d stalls occurred\n", stalls-prevStalls);
+ prevStalls=stalls;
+ }
+ if (texSwaps) {
+ fprintf(stderr, "%d texture swaps occurred\n", texSwaps);
+ texSwaps=0;
+ }
+#endif
FX_grDRIBufferSwap(gCCPriv->swapInterval);
do {
result=FX_grGetInteger(FX_PENDING_BUFFERSWAPS);
@@ -244,29 +270,33 @@ void XMesaSwapBuffers(XMesaBuffer b)
}
}
+GLboolean XMesaUnbindContext(XMesaContext c)
+{
+ if (c && c==gCC && gCCPriv) FX_grGlideGetState((GrState*)gCCPriv->state);
+ return GL_TRUE;
+}
+
GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b)
{
__DRIdrawablePrivate *driDrawPriv;
if (c) {
if (c==gCC) return GL_TRUE;
- if (gCCPriv) FX_grGlideGetState((GrState*)gCCPriv->state);
gCC = c;
gCCPriv = (tdfxContextPrivate *)c->private;
- fprintf(stderr, "Make current\n");
driDrawPriv = gCC->driContextPriv->driDrawablePriv;
if (!gCCPriv->initDone) {
- gCCPriv->width=driDrawPriv->w;
- gCCPriv->height=driDrawPriv->h;
if (!tdfxInitHW(c)) return GL_FALSE;
- /* Zap the width to force XMesaWindowMoved to execute */
gCCPriv->width=0;
+ XMesaWindowMoved();
+ FX_grGlideGetState((GrState*)gCCPriv->state);
+ } else {
+ FX_grSstSelect(gCCPriv->board);
+ FX_grGlideSetState((GrState*)gCCPriv->state);
+ XMesaWindowMoved();
}
- FX_grSstSelect(gCCPriv->board);
- XMesaWindowMoved();
- FX_grGlideSetState((GrState*)gCCPriv->state);
gl_make_current(gCCPriv->glCtx, gCCPriv->glBuffer);
fxSetupDDPointers(gCCPriv->glCtx);
if (!gCCPriv->glCtx->Viewport.Width)
@@ -319,6 +349,7 @@ XMesaWindowMoved() {
}
}
+/* This is called from within the LOCK_HARDWARE routine */
void XMesaUpdateState(int windowMoved) {
__DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv;
__DRIscreenPrivate *sPriv = dPriv->driScreenPriv;
@@ -329,12 +360,18 @@ void XMesaUpdateState(int windowMoved) {
grDRIImportFifo(saPriv->fifoPtr, saPriv->fifoRead);
}
if (saPriv->ctxOwner!=dPriv->driContextPriv->hHWContext) {
- grDRIInvalidateAll();
- /* This shouldn't be needed if the state is reset by Glide */
- /* FX_grConstantColorValue_NoLock(FXCOLOR4(&gCCPriv->constColor)); */
+ /* This sequence looks a little odd. Glide mirrors the state, and
+ when you get the state you are forcing the mirror to be up to
+ date, and then getting a copy from the mirror. You can then force
+ that state onto the hardware when you set the state. */
+ void *state;
+ state=malloc(FX_grGetInteger_NoLock(FX_GLIDE_STATE_SIZE));
+ FX_grGlideGetState_NoLock(state);
+ FX_grGlideSetState_NoLock(state);
+ free(state);
}
if (saPriv->texOwner!=dPriv->driContextPriv->hHWContext) {
- fxTMRestoreTextures(gCCPriv);
+ fxTMRestoreTextures_NoLock(gCCPriv);
}
if (windowMoved)
XMesaWindowMoved();
@@ -352,4 +389,20 @@ void XMesaSetSAREA() {
/* fprintf(stderr, "Out FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */
}
+
+extern void _register_gl_extensions(void); /* silence compiler warning */
+
+void _register_gl_extensions(void)
+{
+ /* Here is where the 3Dfx driver would register new extensions
+ * with libGL.so.
+ * This function is called as soon as the driver object is dlopened.
+ */
+#if 0
+ /* really, the return code should be checked */
+ _glapi_add_entrypoint("glFooBarEXT", _gloffset_FooBarEXT);
+#endif
+}
+
+
#endif