diff options
author | kem <kem> | 2000-02-22 15:37:57 +0000 |
---|---|---|
committer | kem <kem> | 2000-02-22 15:37:57 +0000 |
commit | 3033c9bfc1f7d29d3c87214d33cb9c5a5bbd22f9 (patch) | |
tree | a0726451c24e98fda169a2528118b7b2315d3ca7 /xc/lib/GL/mesa | |
parent | aaf0250c05ea51b0b850b2b4675d611faccb0fe7 (diff) |
Import of XFree86 3.9.18X_3_9_18
Diffstat (limited to 'xc/lib/GL/mesa')
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 |