diff options
author | alanh <alanh> | 2003-03-24 23:54:15 +0000 |
---|---|---|
committer | alanh <alanh> | 2003-03-24 23:54:15 +0000 |
commit | d5935687c69a0c1c3455dc34e5027637fc745fac (patch) | |
tree | 5a0cfacd60fc5128a3b8a5ed08c4aba2bf36c94b /xc/lib/GL | |
parent | 2ff36509093f39110af8b57f08e9d6e6a57321c5 (diff) |
XFree86 4.3.0 mergeX_4_3_0-20030324-merge
Diffstat (limited to 'xc/lib/GL')
223 files changed, 35225 insertions, 4960 deletions
diff --git a/xc/lib/GL/GL/Imakefile b/xc/lib/GL/GL/Imakefile index acdab5640..8980e573e 100644 --- a/xc/lib/GL/GL/Imakefile +++ b/xc/lib/GL/GL/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/GL/Imakefile,v 1.13 2002/02/27 21:09:32 tsi Exp $ +XCOMM $XFree86: xc/lib/GL/GL/Imakefile,v 1.16 2002/12/04 21:38:34 tsi Exp $ #include <Threads.tmpl> @@ -8,6 +8,12 @@ XCOMM $XFree86: xc/lib/GL/GL/Imakefile,v 1.13 2002/02/27 21:09:32 tsi Exp $ #define DoDebugLib DebugLibGlx #define DoProfileLib ProfileLibGlx +#ifndef ShLibBindGlobals +#if !HasGcc2 || (GccMajorVersion > 2) || (GccMinorVersion > 7) +#define ShlibBindGlobals YES +#endif +#endif + LIBNAME = GL SOREV = $(SOGLREV) diff --git a/xc/lib/GL/Imakefile b/xc/lib/GL/Imakefile index b7b2409bd..ac2b8f1e3 100644 --- a/xc/lib/GL/Imakefile +++ b/xc/lib/GL/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/Imakefile,v 1.40 2002/02/27 00:51:14 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/Imakefile,v 1.41 2002/11/22 22:55:57 tsi Exp $ XCOMM XCOMM Imake tokens which are significant to building libGL: @@ -14,11 +14,13 @@ XCOMM GlxBuiltInMga - if defined, build mga_dri.so driver into libGL XCOMM GlxBuiltInI810 - if defined, build i810_dri.so driver into libGL XCOMM GlxBuiltInR128 - if defined, build r128_dri.so driver into libGL XCOMM GlxBuiltInRadeon - if defined, build radeon_dri.so driver into libGL +XCOMM GlxBuiltInR200 - if defined, build r200_dri.so driver into libGL XCOMM GlxBuiltInFfb - if defined, build ffb_dri.so driver into libGL XCOMM GlxBuiltInSIS - if defined, build sis_dri.so driver into libGL XCOMM XCOMM GlxUseBuiltInDRIDriver - automatically defined if any of the -XCOMM GlxBuiltIn[Gamma,Tdfx,Mga,I810,R128,Radeon,Ffb,SIS] tokens is defined +XCOMM GlxBuiltIn[Gamma,Tdfx,Mga,I810,R128,Radeon,R200,Ffb,SIS] tokens is +XCOMM defined XCOMM XCOMM GlxBuiltInXMesa - if defined, build XMesa (Xlib Mesa driver) into libGL XCOMM to enable rendering to displays that lack the GLX extension. @@ -66,8 +68,9 @@ LIBGLBUILDDIR = GL * GlxBuiltInXMesa * BuildOSMesaLib */ -#if (BuildXF86DRI && defined(DriDrivers)) || \ - GlxDriverUsesMesa || GlxBuiltInXMesa || BuildOSMesaLib +#if BuildOSMesaLib || \ + (BuildXF86DRI && \ + (defined(DriDrivers) || GlxDriverUsesMesa || GlxBuiltInXMesa)) MESADIRS = mesa/src #endif @@ -100,7 +103,7 @@ LIBGLBUILDDIR = GL * built-in to libGL. In the former case, libGL needs to be built before * the drivers, and in the latter case, it needs to be built after the driver. */ -#if GlxUseBuiltInDRIDriver +#if BuildXF86DRI && GlxUseBuiltInDRIDriver SUBDIRS = $(MESADIRS) $(DRIDIRS) $(DRIVERDIRS) $(GLXDIRS) $(LIBGLBUILDDIR) $(OSMESADIRS) #else SUBDIRS = $(MESADIRS) $(GLXDIRS) $(DRIDIRS) $(LIBGLBUILDDIR) $(OSMESADIRS) $(DRIVERDIRS) diff --git a/xc/lib/GL/dri/XF86dri.c b/xc/lib/GL/dri/XF86dri.c index c4c1565d3..24eeaf7ff 100644 --- a/xc/lib/GL/dri/XF86dri.c +++ b/xc/lib/GL/dri/XF86dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.12 2001/08/27 17:40:57 dawes Exp $ */ +/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -30,7 +30,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Kevin E. Martin <martin@valinux.com> - * Jens Owen <jens@valinux.com> + * Jens Owen <jens@tungstengraphics.com> * Rickard E. (Rik) Faith <faith@valinux.com> * */ @@ -86,7 +86,8 @@ static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info) *****************************************************************************/ #if 0 -#define TRACE(msg) printf("XF86DRI%s\n", msg); +#include <stdio.h> +#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg); #else #define TRACE(msg) #endif diff --git a/xc/lib/GL/dri/dri_glx.c b/xc/lib/GL/dri/dri_glx.c index d962e8585..ea5a30823 100644 --- a/xc/lib/GL/dri/dri_glx.c +++ b/xc/lib/GL/dri/dri_glx.c @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/dri/dri_glx.c,v 1.10 2001/08/27 17:40:57 dawes Exp $ */ +/* $XFree86: xc/lib/GL/dri/dri_glx.c,v 1.12 2003/02/06 12:42:10 alanh Exp $ */ /* * Authors: @@ -52,6 +52,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. typedef void *(*CreateScreenFunc)(Display *dpy, int scrn, __DRIscreen *psc, int numConfigs, __GLXvisualConfig *config); +typedef void *(*RegisterExtensionsFunc)(void); #ifdef BUILT_IN_DRI_DRIVER @@ -68,6 +69,23 @@ extern void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, #define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri" #endif +/* + * We keep a linked list of these structures, one per DRI device driver. + */ +typedef struct __DRIdriverRec { + const char *name; + void *handle; + CreateScreenFunc createScreenFunc; + RegisterExtensionsFunc registerExtensionsFunc; + struct __DRIdriverRec *next; +} __DRIdriver; + +static __DRIdriver *Drivers = NULL; + + +/* + * printf wrappers + */ static void InfoMessageF(const char *f, ...) { @@ -94,36 +112,6 @@ static void ErrorMessageF(const char *f, ...) } } -#if 0 -static void PrintF(const char *f, ...) -{ - va_list args; - const char *env; - - if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) { - va_start(args, f); - vfprintf(stderr, f, args); - va_end(args); - } -} -#endif - -static void ErrorMessage(const char *msg) -{ - if (getenv("LIBGL_DEBUG")) { - fprintf(stderr, "libGL error: %s\n", msg); - } -} - - -static void InfoMessage(const char *msg) -{ - const char *env = getenv("LIBGL_DEBUG"); - if (env && strstr(env, "verbose")) { - fprintf(stderr, "libGL: %s\n", msg); - } -} - /* * We'll save a pointer to this function when we couldn't find a @@ -194,7 +182,6 @@ static void ExtractDir(int index, const char *paths, int dirLen, char *dir) } - /* * Try to dlopen() the named driver. This function adds the * "_dri.so" suffix to the driver name and searches the @@ -205,10 +192,19 @@ static void ExtractDir(int index, const char *paths, int dirLen, char *dir) * Return: * handle from dlopen, or NULL if driver file not found. */ -static void *OpenDriver(const char *driverName) +static __DRIdriver *OpenDriver(const char *driverName) { char *libPaths = NULL; int i; + __DRIdriver *driver; + + /* First, search Drivers list to see if we've already opened this driver */ + for (driver = Drivers; driver; driver = driver->next) { + if (strcmp(driver->name, driverName) == 0) { + /* found it */ + return driver; + } + } if (geteuid() == getuid()) { /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ @@ -224,95 +220,112 @@ static void *OpenDriver(const char *driverName) void *handle; ExtractDir(i, libPaths, 1000, libDir); if (!libDir[0]) - return NULL; + break; /* ran out of paths to search */ snprintf(realDriverName, 200, "%s/%s_dri.so", libDir, driverName); InfoMessageF("OpenDriver: trying %s\n", realDriverName); handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); if (handle) { - return handle; + /* allocate __DRIdriver struct */ + driver = (__DRIdriver *) Xmalloc(sizeof(__DRIdriver)); + if (!driver) + return NULL; /* out of memory! */ + /* init the struct */ + driver->name = __glXstrdup(driverName); + if (!driver->name) { + Xfree(driver); + return NULL; /* out of memory! */ + } + driver->createScreenFunc = (CreateScreenFunc) + dlsym(handle, "__driCreateScreen"); + if (!driver->createScreenFunc) { + /* If the driver doesn't have this symbol then something's + * really, really wrong. + */ + ErrorMessageF("__driCreateScreen() not defined in %s_dri.so!\n", + driverName); + Xfree(driver); + dlclose(handle); + continue; + } + driver->registerExtensionsFunc = (RegisterExtensionsFunc) + dlsym(handle, "__driRegisterExtensions"); + driver->handle = handle; + /* put at head of linked list */ + driver->next = Drivers; + Drivers = driver; + return driver; } else { - ErrorMessageF("dlopen failed: %s\n", dlerror()); + ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); } } + ErrorMessageF("unable to find driver: %s_dri.so\n", driverName); return NULL; } - /* - * Initialize two arrays: an array of createScreen function pointers - * and an array of dlopen library handles. Arrays are indexed by - * screen number. - * We use the DRI in order to find the __driCreateScreen function - * exported by each screen on a display. + * Given a display pointer and screen number, determine the name of + * the DRI driver for the screen. (I.e. "r128", "tdfx", etc). + * Return True for success, False for failure. */ -static void Find_CreateScreenFuncs(Display *dpy, - CreateScreenFunc *createFuncs, - void **libraryHandles) +static Bool GetDriverName(Display *dpy, int scrNum, char **driverName) { - const int numScreens = ScreenCount(dpy); - int scrn; + int directCapable; + Bool b; + int driverMajor, driverMinor, driverPatch; - __glXRegisterExtensions(); + *driverName = NULL; - for (scrn = 0; scrn < numScreens; scrn++) { - int directCapable; - Bool b; - int driverMajor, driverMinor, driverPatch; - char *driverName = NULL; - void *handle; - - /* defaults */ - createFuncs[scrn] = DummyCreateScreen; - libraryHandles[scrn] = NULL; - - if (!XF86DRIQueryDirectRenderingCapable(dpy, scrn, &directCapable)) { - ErrorMessage("XF86DRIQueryDirectRenderingCapable failed"); - continue; - } - if (!directCapable) { - ErrorMessage("XF86DRIQueryDirectRenderingCapable returned false"); - continue; - } + if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) { + ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed"); + return False; + } + if (!directCapable) { + ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false"); + return False; + } - /* - * Use DRI to find the device driver for use on screen number 'scrn'. - */ - b = XF86DRIGetClientDriverName(dpy, scrn, &driverMajor, &driverMinor, - &driverPatch, &driverName); - if (!b) { - ErrorMessageF("Cannot determine driver name for screen %d\n", scrn); - continue; - } + b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor, + &driverPatch, driverName); + if (!b) { + ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum); + return False; + } + InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", + driverMajor, driverMinor, driverPatch, *driverName, scrNum); - /* - * Open the driver module and save the pointer to its - * __driCreateScreen function. - */ - handle = OpenDriver(driverName); - if (handle) { - CreateScreenFunc createScreenFunc; - createScreenFunc = (CreateScreenFunc) dlsym(handle, "__driCreateScreen"); - if (createScreenFunc) { - /* success! */ - createFuncs[scrn] = createScreenFunc; - libraryHandles[scrn] = handle; - continue; /* onto the next screen */ - } - else { - ErrorMessage("driCreateScreen() not defined in driver!"); - dlclose(handle); - } - } - } /* for scrn */ + return True; } + +/* + * Given a display pointer and screen number, return a __DRIdriver handle. + * Return NULL if anything goes wrong. + */ +static __DRIdriver *GetDriver(Display *dpy, int scrNum) +{ + char *driverName; + __DRIdriver *ret; + + if (GetDriverName(dpy, scrNum, &driverName)) { + ret = OpenDriver(driverName); + if (driverName) + Xfree(driverName); + return ret; + } + + return NULL; +} + + #endif /* BUILT_IN_DRI_DRIVER */ +/* This function isn't currently used. + */ static void driDestroyDisplay(Display *dpy, void *private) { __DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private; @@ -330,12 +343,18 @@ static void driDestroyDisplay(Display *dpy, void *private) } +/* + * Allocate, initialize and return a __DRIdisplayPrivate object. + * This is called from __glXInitialize() when we are given a new + * display pointer. + */ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) { const int numScreens = ScreenCount(dpy); __DRIdisplayPrivate *pdpyp; int eventBase, errorBase; int major, minor, patch; + int scrn; /* Initialize these fields to NULL in case we fail. * If we don't do this we may later get segfaults trying to free random @@ -366,100 +385,49 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) /* allocate array of pointers to createScreen funcs */ pdisp->createScreen = (CreateScreenFunc *) Xmalloc(numScreens * sizeof(void *)); - if (!pdisp->createScreen) + if (!pdisp->createScreen) { + XFree(pdpyp); return NULL; + } /* allocate array of library handles */ pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*)); if (!pdpyp->libraryHandles) { Xfree(pdisp->createScreen); + XFree(pdpyp); return NULL; } #ifdef BUILT_IN_DRI_DRIVER - /* we'll statically bind to the __driCreateScreen function */ - { - int i; - for (i = 0; i < numScreens; i++) { - pdisp->createScreen[i] = __driCreateScreen; - pdpyp->libraryHandles[i] = NULL; - } + /* we'll statically bind to the built-in __driCreateScreen function */ + for (scrn = 0; scrn < numScreens; scrn++) { + pdisp->createScreen[scrn] = __driCreateScreen; + pdpyp->libraryHandles[scrn] = NULL; } + #else - Find_CreateScreenFuncs(dpy, pdisp->createScreen, pdpyp->libraryHandles); + /* dynamically discover DRI drivers for all screens, saving each + * driver's "__driCreateScreen" function pointer. That's the bootstrap + * entrypoint for all DRI drivers. + */ + __glXRegisterExtensions(); + for (scrn = 0; scrn < numScreens; scrn++) { + __DRIdriver *driver = GetDriver(dpy, scrn); + if (driver) { + pdisp->createScreen[scrn] = driver->createScreenFunc; + pdpyp->libraryHandles[scrn] = driver->handle; + } + else { + pdisp->createScreen[scrn] = DummyCreateScreen; + pdpyp->libraryHandles[scrn] = NULL; + } + } #endif return (void *)pdpyp; } -#ifndef BUILT_IN_DRI_DRIVER -/* - * Use the DRI and dlopen/dlsym facilities to find the GL extensions - * possible on the given display and screen. - */ -static void -register_extensions_on_screen(Display *dpy, int scrNum) -{ - int eventBase, errorBase; - Bool b, b2; - int driMajor, driMinor, driPatch; - int driverMajor, driverMinor, driverPatch; - char *driverName = NULL; - void *handle; - - /* - * Check if the DRI extension is available, check the DRI version, - * determine the 3D driver for the screen. - */ - b = XF86DRIQueryExtension(dpy, &eventBase, &errorBase); - if (!b) { - InfoMessage("XF86DRIQueryExtension failed"); - return; - } - - b = XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &b2); - if (!b || !b2) { - InfoMessage("XF86DRIQueryDirectRenderingCapable failed"); - return; - } - - b = XF86DRIQueryVersion(dpy, &driMajor, &driMinor, &driPatch); - if (!b) { - InfoMessage("XF86DRIQueryVersion failed"); - } - - b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor, - &driverPatch, &driverName); - if (!b) { - InfoMessage("XF86DRIGetClientDriverName failed"); - return; - } - else { - InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", - driverMajor, driverMinor, driverPatch, driverName, scrNum); - } - - /* - * OK, now we know the name of the relevant driver for this screen. - * dlopen() the driver library file, get a pointer to the driver's - * __driRegisterExtensions() function, and call it if it exists. - */ - handle = OpenDriver(driverName); - if (handle) { - typedef void *(*RegisterExtFunc)(void); - RegisterExtFunc registerExtFunc = (RegisterExtFunc) dlsym(handle, - "__driRegisterExtensions"); - if (registerExtFunc) { - (*registerExtFunc)(); - } - dlclose(handle); - return; - } -} -#endif /* !BUILT_IN_DRI_DRIVER */ - - /* ** Here we'll query the DRI driver for each screen and let each @@ -474,39 +442,45 @@ register_extensions_on_screen(Display *dpy, int scrNum) void __glXRegisterExtensions(void) { +#ifndef BUILT_IN_DRI_DRIVER static GLboolean alreadyCalled = GL_FALSE; + int displayNum, maxDisplays; - if (alreadyCalled) { + if (alreadyCalled) return; + alreadyCalled = GL_TRUE; + + if (getenv("LIBGL_MULTIHEAD")) { + /* we'd like to always take this path but doing so causes a second + * or more of delay while the XOpenDisplay() function times out. + */ + maxDisplays = 10; /* infinity, really */ + } + else { + /* just open the :0 display */ + maxDisplays = 1; } -#ifndef BUILT_IN_DRI_DRIVER - { - int displayNum, maxDisplays; - if (getenv("LIBGL_MULTIHEAD")) - maxDisplays = 10; /* infinity, really */ - else - maxDisplays = 1; - for (displayNum = 0; displayNum < maxDisplays; displayNum++) { - char displayName[200]; - Display *dpy; - snprintf(displayName, 199, ":%d.0", displayNum); - dpy = XOpenDisplay(displayName); - if (dpy) { - const int numScreens = ScreenCount(dpy); - int screenNum; - for (screenNum = 0; screenNum < numScreens; screenNum++) { - register_extensions_on_screen(dpy, screenNum); + for (displayNum = 0; displayNum < maxDisplays; displayNum++) { + char displayName[200]; + Display *dpy; + snprintf(displayName, 199, ":%d.0", displayNum); + dpy = XOpenDisplay(displayName); + if (dpy) { + const int numScreens = ScreenCount(dpy); + int screenNum; + for (screenNum = 0; screenNum < numScreens; screenNum++) { + __DRIdriver *driver = GetDriver(dpy, screenNum); + if (driver && driver->registerExtensionsFunc) { + (*driver->registerExtensionsFunc)(); } - XCloseDisplay(dpy); - } - else { - break; } + XCloseDisplay(dpy); + } + else { + break; } } - - alreadyCalled = GL_TRUE; #endif } diff --git a/xc/lib/GL/dri/dri_util.c b/xc/lib/GL/dri/dri_util.c index a9a39215c..3afca5487 100644 --- a/xc/lib/GL/dri/dri_util.c +++ b/xc/lib/GL/dri/dri_util.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/dri/dri_util.c,v 1.1 2002/02/22 21:32:52 dawes Exp $ */ +/* $XFree86: xc/lib/GL/dri/dri_util.c,v 1.6 2003/02/15 22:12:29 dawes Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -612,7 +612,8 @@ __driUtilUpdateDrawableInfo(Display *dpy, int scrn, DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - if (!XF86DRIGetDrawableInfo(dpy, scrn, pdp->draw, + if (!__driFindDrawable(psp->drawHash, pdp->draw) || + !XF86DRIGetDrawableInfo(dpy, scrn, pdp->draw, &pdp->index, &pdp->lastStamp, &pdp->x, &pdp->y, &pdp->w, &pdp->h, &pdp->numClipRects, &pdp->pClipRects, @@ -621,16 +622,20 @@ __driUtilUpdateDrawableInfo(Display *dpy, int scrn, &pdp->numBackClipRects, &pdp->pBackClipRects )) { + /* Error -- eg the window may have been destroyed. Keep going + * with no cliprects. + */ + pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */ pdp->numClipRects = 0; pdp->pClipRects = NULL; pdp->numBackClipRects = 0; - pdp->pBackClipRects = 0; - /* ERROR!!! */ + pdp->pBackClipRects = NULL; } + else + pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp); DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp); } /*****************************************************************/ @@ -735,8 +740,14 @@ static void driDestroyDrawable(Display *dpy, void *drawablePrivate) (*psp->DriverAPI.DestroyBuffer)(pdp); if (__driWindowExists(dpy, pdp->draw)) (void)XF86DRIDestroyDrawable(dpy, scrn, pdp->draw); - if (pdp->pClipRects) + if (pdp->pClipRects) { Xfree(pdp->pClipRects); + pdp->pClipRects = NULL; + } + if (pdp->pBackClipRects) { + Xfree(pdp->pBackClipRects); + pdp->pBackClipRects = NULL; + } Xfree(pdp); } } @@ -758,8 +769,8 @@ static void driDestroyContext(Display *dpy, int scrn, void *contextPrivate) psp->fullscreen = NULL; } } - __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); + __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); (void)XF86DRIDestroyContext(dpy, scrn, pcp->contextID); Xfree(pcp); } @@ -925,7 +936,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, if (!psp) { return NULL; } - + psp->fullscreen = NULL; psp->display = dpy; psp->myNum = scrn; @@ -953,6 +964,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, Xfree(BusID); /* No longer needed */ if (drmGetMagic(psp->fd, &magic)) { + fprintf(stderr, "libGL error: drmGetMagic failed\n"); (void)drmClose(psp->fd); Xfree(psp); (void)XF86DRICloseConnection(dpy, scrn); @@ -975,6 +987,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, } if (!XF86DRIAuthConnection(dpy, scrn, magic)) { + fprintf(stderr, "libGL error: XF86DRIAuthConnection failed\n"); (void)drmClose(psp->fd); Xfree(psp); (void)XF86DRICloseConnection(dpy, scrn); @@ -991,6 +1004,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, &psp->ddxMinor, &psp->ddxPatch, &driverName)) { + fprintf(stderr, "libGL error: XF86DRIGetClientDriverName failed\n"); (void)drmClose(psp->fd); Xfree(psp); (void)XF86DRICloseConnection(dpy, scrn); @@ -1013,6 +1027,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, &psp->fbStride, &psp->devPrivSize, &psp->pDevPriv)) { + fprintf(stderr, "libGL error: XF86DRIGetDeviceInfo failed\n"); (void)drmClose(psp->fd); Xfree(psp); (void)XF86DRICloseConnection(dpy, scrn); @@ -1026,6 +1041,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, * Map the framebuffer region. */ if (drmMap(psp->fd, hFB, psp->fbSize, (drmAddressPtr)&psp->pFB)) { + fprintf(stderr, "libGL error: drmMap of framebuffer failed\n"); Xfree(psp->pDevPriv); (void)drmClose(psp->fd); Xfree(psp); @@ -1038,6 +1054,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, * each DRI driver's "createScreen" function. */ if (drmMap(psp->fd, hSAREA, SAREA_MAX, (drmAddressPtr)&psp->pSAREA)) { + fprintf(stderr, "libGL error: drmMap of sarea failed\n"); (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); Xfree(psp->pDevPriv); (void)drmClose(psp->fd); @@ -1049,6 +1066,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, /* Initialize the screen specific GLX driver */ if (psp->DriverAPI.InitDriver) { if (!(*psp->DriverAPI.InitDriver)(psp)) { + fprintf(stderr, "libGL error: InitDriver failed\n"); (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); Xfree(psp->pDevPriv); diff --git a/xc/lib/GL/dri/drm/Imakefile b/xc/lib/GL/dri/drm/Imakefile index 5c2be7f92..ba80d275d 100644 --- a/xc/lib/GL/dri/drm/Imakefile +++ b/xc/lib/GL/dri/drm/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/dri/drm/Imakefile,v 1.19 2002/02/22 21:32:52 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/dri/drm/Imakefile,v 1.20 2002/10/30 12:51:25 alanh Exp $ #if GlxUseBuiltInDRIDriver #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) @@ -24,10 +24,8 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL -I$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel \ -I$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel \ -I$(XF86OSSRC) - SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \ - xf86drmMga.c xf86drmR128.c xf86drmRadeon.c xf86drmGamma.c - OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o \ - xf86drmMga.o xf86drmR128.o xf86drmRadeon.o xf86drmGamma.o + SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c + OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o #if defined(LinuxArchitecture) OS_SUBDIR = linux @@ -43,19 +41,8 @@ LinkSourceFile(xf86drm.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) LinkSourceFile(xf86drmHash.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) LinkSourceFile(xf86drmRandom.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) LinkSourceFile(xf86drmSL.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) -LinkSourceFile(xf86drmMga.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) -LinkSourceFile(xf86drmR128.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) -LinkSourceFile(xf86drmRadeon.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) -LinkSourceFile(xf86drmGamma.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) LinkSourceFile(drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) -LinkSourceFile(gamma_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) -LinkSourceFile(i810_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) -LinkSourceFile(i830_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) -LinkSourceFile(mga_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) -LinkSourceFile(r128_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) -LinkSourceFile(radeon_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) -LinkSourceFile(sis_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) #include <Library.tmpl> diff --git a/xc/lib/GL/dri/xf86dri.h b/xc/lib/GL/dri/xf86dri.h index a16db686f..a3aee8805 100644 --- a/xc/lib/GL/dri/xf86dri.h +++ b/xc/lib/GL/dri/xf86dri.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.7 2000/12/07 20:26:02 dawes Exp $ */ +/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -30,7 +30,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Kevin E. Martin <martin@valinux.com> - * Jens Owen <jens@valinux.com> + * Jens Owen <jens@tungstengraphics.com> * Rickard E. (Rik) Faith <faith@valinux.com> * */ diff --git a/xc/lib/GL/dri/xf86dristr.h b/xc/lib/GL/dri/xf86dristr.h index 44f58d5d8..ac05b183b 100644 --- a/xc/lib/GL/dri/xf86dristr.h +++ b/xc/lib/GL/dri/xf86dristr.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.9 2001/03/21 16:01:08 dawes Exp $ */ +/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.10 2002/10/30 12:51:25 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -30,7 +30,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Kevin E. Martin <martin@valinux.com> - * Jens Owen <jens@valinux.com> + * Jens Owen <jens@tungstengraphics.com> * Rickard E. (Rik) Fiath <faith@valinux.com> * */ @@ -42,8 +42,17 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define XF86DRINAME "XFree86-DRI" -#define XF86DRI_MAJOR_VERSION 4 /* current version numbers */ -#define XF86DRI_MINOR_VERSION 0 +/* The DRI version number. This was originally set to be the same of the + * XFree86 version number. However, this version is really indepedent of + * the XFree86 version. + * + * Version History: + * 4.0.0: Original + * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 + * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + */ +#define XF86DRI_MAJOR_VERSION 4 +#define XF86DRI_MINOR_VERSION 1 #define XF86DRI_PATCH_VERSION 0 typedef struct _XF86DRIQueryVersion { diff --git a/xc/lib/GL/glx/Imakefile b/xc/lib/GL/glx/Imakefile index a99be350f..f93e8c4dc 100644 --- a/xc/lib/GL/glx/Imakefile +++ b/xc/lib/GL/glx/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/glx/Imakefile,v 1.16 2002/02/27 21:09:32 tsi Exp $ +XCOMM $XFree86: xc/lib/GL/glx/Imakefile,v 1.18 2002/11/25 14:04:49 eich Exp $ XCOMM The contents of this file are subject to the GLX Public License Version 1.0 XCOMM (the "License"). You may not use this file except in compliance with the XCOMM License. You may obtain a copy of the License at Silicon Graphics, Inc., @@ -101,7 +101,7 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/SPARC) #if BuildXF86DRI DRI_INCS = -I$(GLXLIBSRC)/dri -#if defined(i386Architecture) +#if defined(i386Architecture) && MesaUseX86Asm ASM_SRCS = glapi_x86.S ASM_OBJS = glapi_x86.o ASM_DEFS = -DUSE_X86_ASM @@ -111,11 +111,11 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/SPARC) ASM_OBJS = glapi_sparc.o ASM_DEFS = -DUSE_SPARC_ASM #endif -#endif #if GlxBuiltInXMesa XMESA_DEFINES = -DGLX_BUILT_IN_XMESA #endif +#endif SRCS = $(GLX_SRCS) $(ASM_SRCS) OBJS = $(GLX_OBJS) $(ASM_OBJS) diff --git a/xc/lib/GL/glx/glxclient.h b/xc/lib/GL/glx/glxclient.h index ee19a19e4..c43cc1c3f 100644 --- a/xc/lib/GL/glx/glxclient.h +++ b/xc/lib/GL/glx/glxclient.h @@ -31,7 +31,7 @@ ** published by SGI, but has not been independently verified as being ** compliant with the OpenGL(R) version 1.2.1 Specification. */ -/* $XFree86: xc/lib/GL/glx/glxclient.h,v 1.14 2002/02/22 21:32:53 dawes Exp $ */ +/* $XFree86: xc/lib/GL/glx/glxclient.h,v 1.15 2002/10/30 12:51:26 alanh Exp $ */ /* * Direct rendering support added by Precision Insight, Inc. @@ -404,7 +404,6 @@ struct __GLXcontextRec { ** context is not current to any drawable. */ GLXDrawable currentDrawable; - GLXDrawable currentReadable; /* ** Constant strings that describe the server implementation @@ -548,6 +547,10 @@ extern __GLXdisplayPrivate *__glXInitialize(Display*); /* Query drivers for dynamically registered extensions */ extern void __glXRegisterExtensions(void); +/* Functions for extending the GLX API: */ +extern void *__glXRegisterGLXFunction(const char *funcName, void *funcAddr); +extern void __glXRegisterGLXExtensionString(const char *extName); + /************************************************************************/ @@ -697,4 +700,6 @@ extern void _XSend(Display*, const void*, long); #endif +extern char *__glXstrdup(const char *str); + #endif /* !__GLX_client_h__ */ diff --git a/xc/lib/GL/glx/glxcmds.c b/xc/lib/GL/glx/glxcmds.c index c12064234..226b50573 100644 --- a/xc/lib/GL/glx/glxcmds.c +++ b/xc/lib/GL/glx/glxcmds.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/glx/glxcmds.c,v 1.17 2002/02/27 21:09:32 tsi Exp $ */ +/* $XFree86: xc/lib/GL/glx/glxcmds.c,v 1.19 2003/01/20 21:37:18 tsi Exp $ */ /* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free @@ -65,12 +65,15 @@ static const char __glXGLClientExtensions[] = static const char __glXGLXClientVendorName[] = "SGI"; static const char __glXGLXClientVersion[] = "1.2"; -static const char __glXGLXClientExtensions[] = +static const char __glXGLXDefaultClientExtensions[] = "GLX_EXT_visual_info " "GLX_EXT_visual_rating " "GLX_EXT_import_context " ; +static const char *__glXGLXClientExtensions = __glXGLXDefaultClientExtensions; + + /* ** Create a new context. */ @@ -87,6 +90,9 @@ GLXContext CreateContext(Display *dpy, XVisualInfo *vis, __GLXdisplayPrivate *priv; #endif + if (!dpy || !vis) + return NULL; + opcode = __glXSetupForCommand(dpy); if (!opcode) { return NULL; @@ -1012,6 +1018,7 @@ XVisualInfo *GLX_PREFIX(glXChooseVisual)(Display *dpy, int screen, int *attribLi else score += AuxScore(auxBuffers, val); if (transparentPixel) { + __GLX_GCONF(GLX_TRANSPARENT_TYPE_EXT); if (transparentPixelValue != val) continue; if (transparentPixelValue == GLX_TRANSPARENT_TYPE_EXT) { @@ -1210,7 +1217,7 @@ static char *combine_strings( const char *cext_string, const char *sext_string ) */ if ( (clen = strlen( cext_string)) > (slen = strlen( sext_string)) ) { combo_string = (char *) Xmalloc( slen + 2 ); - s1 = (char *) malloc( slen + 2 ); strcpy( s1, sext_string ); + s1 = (char *) Xmalloc( slen + 2 ); strcpy( s1, sext_string ); s2 = cext_string; } else { combo_string = (char *) Xmalloc( clen + 2 ); @@ -1407,6 +1414,7 @@ static int __glXQueryContextInfo(Display *dpy, GLXContext ctx) xGLXQueryContextInfoEXTReply reply; CARD8 opcode; GLuint numValues; + int retval; if (ctx == NULL) { return GLX_BAD_CONTEXT; @@ -1426,12 +1434,13 @@ static int __glXQueryContextInfo(Display *dpy, GLXContext ctx) req->vendorCode = X_GLXvop_QueryContextInfoEXT; req->context = (unsigned int)(ctx->xid); _XReply(dpy, (xReply*) &reply, 0, False); - UnlockDisplay(dpy); numValues = reply.n; - if (numValues == 0) return Success; - if (numValues > __GLX_MAX_CONTEXT_PROPS) return 0; - + if (numValues == 0) + retval = Success; + else if (numValues > __GLX_MAX_CONTEXT_PROPS) + retval = 0; + else { int *propList, *pProp; int nPropListBytes; @@ -1440,30 +1449,33 @@ static int __glXQueryContextInfo(Display *dpy, GLXContext ctx) nPropListBytes = numValues << 3; propList = (int *) Xmalloc(nPropListBytes); if (NULL == propList) { - return 0; - } - _XRead(dpy, (char *)propList, nPropListBytes); - pProp = propList; - for (i=0; i < numValues; i++) { - switch (*pProp++) { - case GLX_SHARE_CONTEXT_EXT: - ctx->share_xid = *pProp++; - break; - case GLX_VISUAL_ID_EXT: - ctx->vid = *pProp++; - break; - case GLX_SCREEN_EXT: - ctx->screen = *pProp++; - break; - default: - pProp++; - continue; + retval = 0; + } else { + _XRead(dpy, (char *)propList, nPropListBytes); + pProp = propList; + for (i=0; i < numValues; i++) { + switch (*pProp++) { + case GLX_SHARE_CONTEXT_EXT: + ctx->share_xid = *pProp++; + break; + case GLX_VISUAL_ID_EXT: + ctx->vid = *pProp++; + break; + case GLX_SCREEN_EXT: + ctx->screen = *pProp++; + break; + default: + pProp++; + continue; + } } + Xfree((char *)propList); + retval = Success; } - Xfree((char *)propList); } + UnlockDisplay(dpy); SyncHandle(); - return Success; + return retval; } int GLX_PREFIX(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx, @@ -1602,7 +1614,7 @@ void GLX_PREFIX(glXDestroyWindow)(Display *dpy, GLXWindow window) GLXDrawable glXGetCurrentReadDrawable(void) { GLXContext gc = __glXGetCurrentContext(); - return gc->currentReadable; + return gc->currentDrawable; } @@ -2016,6 +2028,21 @@ Bool GLX_PREFIX(glXSet3DfxModeMESA)( int mode ) } + +/* strdup() is actually not a standard ANSI C or POSIX routine. + * Irix will not define it if ANSI mode is in effect. + */ +char * +__glXstrdup(const char *str) +{ + char *copy; + copy = (char *) Xmalloc(strlen(str) + 1); + if (!copy) + return NULL; + strcpy(copy, str); + return copy; +} + /* ** glXGetProcAddress support */ @@ -2023,142 +2050,233 @@ Bool GLX_PREFIX(glXSet3DfxModeMESA)( int mode ) struct name_address_pair { const char *Name; GLvoid *Address; + struct name_address_pair *Next; }; static struct name_address_pair GLX_functions[] = { /*** GLX_VERSION_1_0 ***/ - { "glXChooseVisual", (GLvoid *) glXChooseVisual }, - { "glXCopyContext", (GLvoid *) glXCopyContext }, - { "glXCreateContext", (GLvoid *) glXCreateContext }, - { "glXCreateGLXPixmap", (GLvoid *) glXCreateGLXPixmap }, - { "glXDestroyContext", (GLvoid *) glXDestroyContext }, - { "glXDestroyGLXPixmap", (GLvoid *) glXDestroyGLXPixmap }, - { "glXGetConfig", (GLvoid *) glXGetConfig }, - { "glXGetCurrentContext", (GLvoid *) glXGetCurrentContext }, - { "glXGetCurrentDrawable", (GLvoid *) glXGetCurrentDrawable }, - { "glXIsDirect", (GLvoid *) glXIsDirect }, - { "glXMakeCurrent", (GLvoid *) glXMakeCurrent }, - { "glXQueryExtension", (GLvoid *) glXQueryExtension }, - { "glXQueryVersion", (GLvoid *) glXQueryVersion }, - { "glXSwapBuffers", (GLvoid *) glXSwapBuffers }, - { "glXUseXFont", (GLvoid *) glXUseXFont }, - { "glXWaitGL", (GLvoid *) glXWaitGL }, - { "glXWaitX", (GLvoid *) glXWaitX }, + { "glXChooseVisual", (GLvoid *) glXChooseVisual, NULL }, + { "glXCopyContext", (GLvoid *) glXCopyContext, NULL }, + { "glXCreateContext", (GLvoid *) glXCreateContext, NULL }, + { "glXCreateGLXPixmap", (GLvoid *) glXCreateGLXPixmap, NULL }, + { "glXDestroyContext", (GLvoid *) glXDestroyContext, NULL }, + { "glXDestroyGLXPixmap", (GLvoid *) glXDestroyGLXPixmap, NULL }, + { "glXGetConfig", (GLvoid *) glXGetConfig, NULL }, + { "glXGetCurrentContext", (GLvoid *) glXGetCurrentContext, NULL }, + { "glXGetCurrentDrawable", (GLvoid *) glXGetCurrentDrawable, NULL }, + { "glXIsDirect", (GLvoid *) glXIsDirect, NULL }, + { "glXMakeCurrent", (GLvoid *) glXMakeCurrent, NULL }, + { "glXQueryExtension", (GLvoid *) glXQueryExtension, NULL }, + { "glXQueryVersion", (GLvoid *) glXQueryVersion, NULL }, + { "glXSwapBuffers", (GLvoid *) glXSwapBuffers, NULL }, + { "glXUseXFont", (GLvoid *) glXUseXFont, NULL }, + { "glXWaitGL", (GLvoid *) glXWaitGL, NULL }, + { "glXWaitX", (GLvoid *) glXWaitX, NULL }, /*** GLX_VERSION_1_1 ***/ - { "glXGetClientString", (GLvoid *) glXGetClientString }, - { "glXQueryExtensionsString", (GLvoid *) glXQueryExtensionsString }, - { "glXQueryServerString", (GLvoid *) glXQueryServerString }, + { "glXGetClientString", (GLvoid *) glXGetClientString, NULL }, + { "glXQueryExtensionsString", (GLvoid *) glXQueryExtensionsString, NULL }, + { "glXQueryServerString", (GLvoid *) glXQueryServerString, NULL }, /*** GLX_VERSION_1_2 ***/ - { "glXGetCurrentDisplay", (GLvoid *) glXGetCurrentDisplay }, + { "glXGetCurrentDisplay", (GLvoid *) glXGetCurrentDisplay, NULL }, /*** GLX_VERSION_1_3 ***/ - { "glXChooseFBConfig", (GLvoid *) glXChooseFBConfig }, - { "glXCreateNewContext", (GLvoid *) glXCreateNewContext }, - { "glXCreatePbuffer", (GLvoid *) glXCreatePbuffer }, - { "glXCreatePixmap", (GLvoid *) glXCreatePixmap }, - { "glXCreateWindow", (GLvoid *) glXCreateWindow }, - { "glXDestroyPbuffer", (GLvoid *) glXDestroyPbuffer }, - { "glXDestroyPixmap", (GLvoid *) glXDestroyPixmap }, - { "glXDestroyWindow", (GLvoid *) glXDestroyWindow }, - { "glXGetCurrentReadDrawable", (GLvoid *) glXGetCurrentReadDrawable }, - { "glXGetFBConfigAttrib", (GLvoid *) glXGetFBConfigAttrib }, - { "glXGetFBConfigs", (GLvoid *) glXGetFBConfigs }, - { "glXGetSelectedEvent", (GLvoid *) glXGetSelectedEvent }, - { "glXGetVisualFromFBConfig", (GLvoid *) glXGetVisualFromFBConfig }, - { "glXMakeContextCurrent", (GLvoid *) glXMakeContextCurrent }, - { "glXQueryContext", (GLvoid *) glXQueryContext }, - { "glXQueryDrawable", (GLvoid *) glXQueryDrawable }, - { "glXSelectEvent", (GLvoid *) glXSelectEvent }, + { "glXChooseFBConfig", (GLvoid *) glXChooseFBConfig, NULL }, + { "glXCreateNewContext", (GLvoid *) glXCreateNewContext, NULL }, + { "glXCreatePbuffer", (GLvoid *) glXCreatePbuffer, NULL }, + { "glXCreatePixmap", (GLvoid *) glXCreatePixmap, NULL }, + { "glXCreateWindow", (GLvoid *) glXCreateWindow, NULL }, + { "glXDestroyPbuffer", (GLvoid *) glXDestroyPbuffer, NULL }, + { "glXDestroyPixmap", (GLvoid *) glXDestroyPixmap, NULL }, + { "glXDestroyWindow", (GLvoid *) glXDestroyWindow, NULL }, + { "glXGetCurrentReadDrawable", (GLvoid *) glXGetCurrentReadDrawable, NULL }, + { "glXGetFBConfigAttrib", (GLvoid *) glXGetFBConfigAttrib, NULL }, + { "glXGetFBConfigs", (GLvoid *) glXGetFBConfigs, NULL }, + { "glXGetSelectedEvent", (GLvoid *) glXGetSelectedEvent, NULL }, + { "glXGetVisualFromFBConfig", (GLvoid *) glXGetVisualFromFBConfig, NULL }, + { "glXMakeContextCurrent", (GLvoid *) glXMakeContextCurrent, NULL }, + { "glXQueryContext", (GLvoid *) glXQueryContext, NULL }, + { "glXQueryDrawable", (GLvoid *) glXQueryDrawable, NULL }, + { "glXSelectEvent", (GLvoid *) glXSelectEvent, NULL }, /*** GLX_SGI_swap_control ***/ - { "glXSwapIntervalSGI", (GLvoid *) glXSwapIntervalSGI }, + { "glXSwapIntervalSGI", (GLvoid *) glXSwapIntervalSGI, NULL }, /*** GLX_SGI_video_sync ***/ - { "glXGetVideoSyncSGI", (GLvoid *) glXGetVideoSyncSGI }, - { "glXWaitVideoSyncSGI", (GLvoid *) glXWaitVideoSyncSGI }, + { "glXGetVideoSyncSGI", (GLvoid *) glXGetVideoSyncSGI, NULL }, + { "glXWaitVideoSyncSGI", (GLvoid *) glXWaitVideoSyncSGI, NULL }, /*** GLX_SGI_make_current_read ***/ - { "glXMakeCurrentReadSGI", (GLvoid *) glXMakeCurrentReadSGI }, - { "glXGetCurrentReadDrawableSGI", (GLvoid *) glXGetCurrentReadDrawableSGI }, + { "glXMakeCurrentReadSGI", (GLvoid *) glXMakeCurrentReadSGI, NULL }, + { "glXGetCurrentReadDrawableSGI", (GLvoid *) glXGetCurrentReadDrawableSGI, NULL }, /*** GLX_SGIX_video_source ***/ #if defined(_VL_H) - { "glXCreateGLXVideoSourceSGIX", (GLvoid *) glXCreateGLXVideoSourceSGIX }, - { "glXDestroyGLXVideoSourceSGIX", (GLvoid *) glXDestroyGLXVideoSourceSGIX }, + { "glXCreateGLXVideoSourceSGIX", (GLvoid *) glXCreateGLXVideoSourceSGIX, NULL }, + { "glXDestroyGLXVideoSourceSGIX", (GLvoid *) glXDestroyGLXVideoSourceSGIX, NULL }, #endif /*** GLX_EXT_import_context ***/ - { "glXFreeContextEXT", (GLvoid *) glXFreeContextEXT }, - { "glXGetContextIDEXT", (GLvoid *) glXGetContextIDEXT }, - { "glXGetCurrentDisplayEXT", (GLvoid *) glXGetCurrentDisplayEXT }, - { "glXImportContextEXT", (GLvoid *) glXImportContextEXT }, - { "glXQueryContextInfoEXT", (GLvoid *) glXQueryContextInfoEXT }, + { "glXFreeContextEXT", (GLvoid *) glXFreeContextEXT, NULL }, + { "glXGetContextIDEXT", (GLvoid *) glXGetContextIDEXT, NULL }, + { "glXGetCurrentDisplayEXT", (GLvoid *) glXGetCurrentDisplayEXT, NULL }, + { "glXImportContextEXT", (GLvoid *) glXImportContextEXT, NULL }, + { "glXQueryContextInfoEXT", (GLvoid *) glXQueryContextInfoEXT, NULL }, /*** GLX_SGIX_fbconfig ***/ - { "glXGetFBConfigAttribSGIX", (GLvoid *) glXGetFBConfigAttribSGIX }, - { "glXChooseFBConfigSGIX", (GLvoid *) glXChooseFBConfigSGIX }, - { "glXCreateGLXPixmapWithConfigSGIX", (GLvoid *) glXCreateGLXPixmapWithConfigSGIX }, - { "glXCreateContextWithConfigSGIX", (GLvoid *) glXCreateContextWithConfigSGIX }, - { "glXGetVisualFromFBConfigSGIX", (GLvoid *) glXGetVisualFromFBConfigSGIX }, - { "glXGetFBConfigFromVisualSGIX", (GLvoid *) glXGetFBConfigFromVisualSGIX }, + { "glXGetFBConfigAttribSGIX", (GLvoid *) glXGetFBConfigAttribSGIX, NULL }, + { "glXChooseFBConfigSGIX", (GLvoid *) glXChooseFBConfigSGIX, NULL }, + { "glXCreateGLXPixmapWithConfigSGIX", (GLvoid *) glXCreateGLXPixmapWithConfigSGIX, NULL }, + { "glXCreateContextWithConfigSGIX", (GLvoid *) glXCreateContextWithConfigSGIX, NULL }, + { "glXGetVisualFromFBConfigSGIX", (GLvoid *) glXGetVisualFromFBConfigSGIX, NULL }, + { "glXGetFBConfigFromVisualSGIX", (GLvoid *) glXGetFBConfigFromVisualSGIX, NULL }, /*** GLX_SGIX_pbuffer ***/ - { "glXCreateGLXPbufferSGIX", (GLvoid *) glXCreateGLXPbufferSGIX }, - { "glXDestroyGLXPbufferSGIX", (GLvoid *) glXDestroyGLXPbufferSGIX }, - { "glXQueryGLXPbufferSGIX", (GLvoid *) glXQueryGLXPbufferSGIX }, - { "glXSelectEventSGIX", (GLvoid *) glXSelectEventSGIX }, - { "glXGetSelectedEventSGIX", (GLvoid *) glXGetSelectedEventSGIX }, + { "glXCreateGLXPbufferSGIX", (GLvoid *) glXCreateGLXPbufferSGIX, NULL }, + { "glXDestroyGLXPbufferSGIX", (GLvoid *) glXDestroyGLXPbufferSGIX, NULL }, + { "glXQueryGLXPbufferSGIX", (GLvoid *) glXQueryGLXPbufferSGIX, NULL }, + { "glXSelectEventSGIX", (GLvoid *) glXSelectEventSGIX, NULL }, + { "glXGetSelectedEventSGIX", (GLvoid *) glXGetSelectedEventSGIX, NULL }, /*** GLX_SGI_cushion ***/ - { "glXCushionSGI", (GLvoid *) glXCushionSGI }, + { "glXCushionSGI", (GLvoid *) glXCushionSGI, NULL }, /*** GLX_SGIX_video_resize ***/ - { "glXBindChannelToWindowSGIX", (GLvoid *) glXBindChannelToWindowSGIX }, - { "glXChannelRectSGIX", (GLvoid *) glXChannelRectSGIX }, - { "glXQueryChannelRectSGIX", (GLvoid *) glXQueryChannelRectSGIX }, - { "glXQueryChannelDeltasSGIX", (GLvoid *) glXQueryChannelDeltasSGIX }, - { "glXChannelRectSyncSGIX", (GLvoid *) glXChannelRectSyncSGIX }, + { "glXBindChannelToWindowSGIX", (GLvoid *) glXBindChannelToWindowSGIX, NULL }, + { "glXChannelRectSGIX", (GLvoid *) glXChannelRectSGIX, NULL }, + { "glXQueryChannelRectSGIX", (GLvoid *) glXQueryChannelRectSGIX, NULL }, + { "glXQueryChannelDeltasSGIX", (GLvoid *) glXQueryChannelDeltasSGIX, NULL }, + { "glXChannelRectSyncSGIX", (GLvoid *) glXChannelRectSyncSGIX, NULL }, /*** GLX_SGIX_dmbuffer **/ #if defined(_DM_BUFFER_H_) - { "glXAssociateDMPbufferSGIX", (GLvoid *) glXAssociateDMPbufferSGIX }, + { "glXAssociateDMPbufferSGIX", (GLvoid *) glXAssociateDMPbufferSGIX, NULL }, #endif /*** GLX_SGIX_swap_group ***/ - { "glXJoinSwapGroupSGIX", (GLvoid *) glXJoinSwapGroupSGIX }, + { "glXJoinSwapGroupSGIX", (GLvoid *) glXJoinSwapGroupSGIX, NULL }, /*** GLX_SGIX_swap_barrier ***/ - { "glXBindSwapBarrierSGIX", (GLvoid *) glXBindSwapBarrierSGIX }, - { "glXQueryMaxSwapBarriersSGIX", (GLvoid *) glXQueryMaxSwapBarriersSGIX }, + { "glXBindSwapBarrierSGIX", (GLvoid *) glXBindSwapBarrierSGIX, NULL }, + { "glXQueryMaxSwapBarriersSGIX", (GLvoid *) glXQueryMaxSwapBarriersSGIX, NULL }, /*** GLX_SUN_get_transparent_index ***/ - { "glXGetTransparentIndexSUN", (GLvoid *) glXGetTransparentIndexSUN }, + { "glXGetTransparentIndexSUN", (GLvoid *) glXGetTransparentIndexSUN, NULL }, /*** GLX_MESA_copy_sub_buffer ***/ - { "glXCopySubBufferMESA", (GLvoid *) glXCopySubBufferMESA }, + { "glXCopySubBufferMESA", (GLvoid *) glXCopySubBufferMESA, NULL }, /*** GLX_MESA_pixmap_colormap ***/ - { "glXCreateGLXPixmapMESA", (GLvoid *) glXCreateGLXPixmapMESA }, + { "glXCreateGLXPixmapMESA", (GLvoid *) glXCreateGLXPixmapMESA, NULL }, /*** GLX_MESA_release_buffers ***/ - { "glXReleaseBuffersMESA", (GLvoid *) glXReleaseBuffersMESA }, + { "glXReleaseBuffersMESA", (GLvoid *) glXReleaseBuffersMESA, NULL }, /*** GLX_MESA_set_3dfx_mode ***/ - { "glXSet3DfxModeMESA", (GLvoid *) glXSet3DfxModeMESA }, + { "glXSet3DfxModeMESA", (GLvoid *) glXSet3DfxModeMESA, NULL }, /*** GLX_ARB_get_proc_address ***/ - { "glXGetProcAddressARB", (GLvoid *) glXGetProcAddressARB }, + { "glXGetProcAddressARB", (GLvoid *) glXGetProcAddressARB, NULL }, - { NULL, NULL } /* end of list */ + /*** GLX 1.4 ***/ + { "glXGetProcAddress", (GLvoid *) glXGetProcAddress, NULL }, + + /*** GLX_???_allocate_memory ***/ + { "glXAllocateMemoryNV", (GLvoid *) glXAllocateMemoryNV, NULL }, + { "glXFreeMemoryNV", (GLvoid *) glXFreeMemoryNV, NULL }, + + /*** GLX_MESA_agp_pointer ***/ + { "glXGetAGPOffsetMESA", (GLvoid *) glXGetAGPOffsetMESA, NULL }, + + { NULL, NULL, NULL } /* end of list */ }; +static struct name_address_pair *Dynamic_GLX_functions = NULL; + + +/* + * Drivers can call this function to append the name of a new GLX + * extension string to __glXGLXClientExtensions. Then, when the user + * calls glXGetClientString() they'll see it listed. + * This is a companion to __glXRegisterGLXFunction(). + */ +void +__glXRegisterGLXExtensionString(const char *extName) +{ + char *newList; + if (!extName) + return; + newList = Xmalloc(strlen(__glXGLXClientExtensions) + + strlen(extName) + 2); /* 2 for ' ' and '\0' */ + if (!newList) + return; + strcpy(newList, __glXGLXClientExtensions); + strcat(newList, " "); + strcat(newList, extName); + if (__glXGLXClientExtensions != __glXGLXDefaultClientExtensions) + Xfree((void *) __glXGLXClientExtensions); + __glXGLXClientExtensions = newList; +} + + +/* + * DRI drivers should call this function if they want to extend + * the GLX API. After registering a new GLX function, the user + * can query and use it by calling glXGetProcAddress(). + * Input: funcName - name of new GLX function + * funcAddr - pointer to the function. + * Return: address of previously registered function with this + * name, or NULL. + */ +void * +__glXRegisterGLXFunction(const char *funcName, void *funcAddr) +{ + struct name_address_pair *ext; + + /* look if the function is already registered */ + for (ext = Dynamic_GLX_functions; ext; ext = ext->Next) { + if (strcmp(ext->Name, funcName) == 0) { + /* It's up the caller to use this return value if he wants + * to chain-call or wrap the previously registered function. + */ + void *prevAddr = ext->Address; + ext->Address = funcAddr; + return prevAddr; + } + } + + /* add new function */ + ext = Xmalloc(sizeof(struct name_address_pair)); + if (!ext) + return NULL; + ext->Name = __glXstrdup(funcName); + if (!ext->Name) { + Xfree(ext); + return NULL; + } + ext->Address = funcAddr; + ext->Next = Dynamic_GLX_functions; + Dynamic_GLX_functions = ext; + return NULL; +} + + static const GLvoid * get_glx_proc_address(const char *funcName) { + const struct name_address_pair *ext; GLuint i; + + /* try dynamic functions */ + for (ext = Dynamic_GLX_functions; ext; ext = ext->Next) { + if (strcmp(ext->Name, funcName) == 0) { + return ext->Address; + } + } + + /* try static functions */ for (i = 0; GLX_functions[i].Name; i++) { if (strcmp(GLX_functions[i].Name, funcName) == 0) return GLX_functions[i].Address; @@ -2168,9 +2286,9 @@ get_glx_proc_address(const char *funcName) #ifndef GLX_BUILT_IN_XMESA -void (*glXGetProcAddressARB(const GLubyte *procName))() +void (*glXGetProcAddressARB(const GLubyte *procName))( void ) { - typedef void (*gl_function)(); + typedef void (*gl_function)( void ); gl_function f; #if defined(GLX_DIRECT_RENDERING) @@ -2185,4 +2303,94 @@ void (*glXGetProcAddressARB(const GLubyte *procName))() f = (gl_function) _glapi_get_proc_address((const char *) procName); return f; } + +/* GLX 1.4 */ +void (*glXGetProcAddress(const GLubyte *procName))( void ) +{ + return glXGetProcAddressARB(procName); +} #endif + + +/* + * AGP memory allocation + */ +void *GLX_PREFIX(glXAllocateMemoryNV)(GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority) +{ + /* This is special - search the list of dynamically-added functions + * and call the allocator if present. + * More typically, the user will have gotten a pointer to + * glXAllocateMemoryNV() via glXGetProcAddress() so we won't be + * doing this. + */ + typedef void * (*allocFunc)(GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); + const struct name_address_pair *ext; + static allocFunc f = (allocFunc) NULL; + + if (!f) { + for (ext = Dynamic_GLX_functions; ext; ext = ext->Next) { + if (strcmp(ext->Name, "glXAllocateMemoryNV") == 0) { + f = (allocFunc) ext->Address; + break; + } + } + } + if (f) + return (*f)(size, readFrequency, writeFrequency, priority); + return NULL; +} + + +void GLX_PREFIX(glXFreeMemoryNV)(GLvoid *pointer) +{ + /* This is special - search the list of dynamically-added functions + * and call the free func if present. + * More typically, the user will have gotten a pointer to + * glXFreeMemoryNV() via glXGetProcAddress() so we won't be + * doing this. + */ + typedef void * (*freeFunc)(GLvoid *pointer); + const struct name_address_pair *ext; + static freeFunc f = (freeFunc) NULL; + + if (!f) { + for (ext = Dynamic_GLX_functions; ext; ext = ext->Next) { + if (strcmp(ext->Name, "glXFreeMemoryNV") == 0) { + f = (freeFunc) ext->Address; + break; + } + } + } + if (f) + (*f)(pointer); +} + + +GLuint GLX_PREFIX(glXGetAGPOffsetMESA)( const GLvoid *pointer ) +{ + /* This is special - search the list of dynamically-added functions + * and call the free func if present. + * More typically, the user will have gotten a pointer to + * glXGetAGPOffsetMESA() via glXGetProcAddress() so we won't be + * doing this. + */ + typedef GLuint (*getAGPOffsetFunc)(const GLvoid *pointer); + const struct name_address_pair *ext; + static getAGPOffsetFunc f = (getAGPOffsetFunc) NULL; + + if (!f) { + for (ext = Dynamic_GLX_functions; ext; ext = ext->Next) { + if (strcmp(ext->Name, "glXGetAGPOffsetMESA") == 0) { + f = (getAGPOffsetFunc) ext->Address; + break; + } + } + } + if (f) + return (*f)(pointer); + else + return ~0; +} diff --git a/xc/lib/GL/glx/glxext.c b/xc/lib/GL/glx/glxext.c index 110ee0c48..4ff2350ad 100644 --- a/xc/lib/GL/glx/glxext.c +++ b/xc/lib/GL/glx/glxext.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/glx/glxext.c,v 1.14 2002/02/22 21:32:53 dawes Exp $ */ +/* $XFree86: xc/lib/GL/glx/glxext.c,v 1.16 2003/01/20 21:37:19 tsi Exp $ */ /* ** License Applicability. Except to the extent portions of this file are @@ -344,12 +344,13 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) if (!_XReply(dpy, (xReply*) &reply, 0, False)) { /* Something is busted. Punt. */ UnlockDisplay(dpy); + SyncHandle(); FreeScreenConfigs(priv); return GL_FALSE; } - UnlockDisplay(dpy); if (!reply.numVisuals) { /* This screen does not support GL rendering */ + UnlockDisplay(dpy); continue; } @@ -358,6 +359,8 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) if ((nprops < __GLX_MIN_CONFIG_PROPS) || (nprops > __GLX_MAX_CONFIG_PROPS)) { /* Huh? Not in protocol defined limits. Punt */ + UnlockDisplay(dpy); + SyncHandle(); FreeScreenConfigs(priv); return GL_FALSE; } @@ -367,6 +370,8 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) Xmalloc(reply.numVisuals * sizeof(__GLXvisualConfig)); psc->numConfigs = reply.numVisuals; if (!psc->configs) { + UnlockDisplay(dpy); + SyncHandle(); FreeScreenConfigs(priv); return GL_FALSE; } @@ -444,6 +449,7 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) if (props != buf) { Xfree((char *)props); } + UnlockDisplay(dpy); #ifdef GLX_DIRECT_RENDERING /* Initialize the direct rendering per screen data and functions */ @@ -868,7 +874,7 @@ Bool GLX_PREFIX(glXMakeCurrent)(Display *dpy, GLXDrawable draw, GLXContext gc) if (!bindReturnValue) { /* The make current failed. */ - if (!gc->isDirect) { + if (gc && !gc->isDirect) { SyncHandle(); } diff --git a/xc/lib/GL/glx/packrender.h b/xc/lib/GL/glx/packrender.h index 0dc695742..305838054 100644 --- a/xc/lib/GL/glx/packrender.h +++ b/xc/lib/GL/glx/packrender.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/glx/packrender.h,v 1.6 2001/03/21 16:04:39 dawes Exp $ */ +/* $XFree86: xc/lib/GL/glx/packrender.h,v 1.7 2002/10/30 12:51:26 alanh Exp $ */ #ifndef __GLX_packrender_h__ #define __GLX_packrender_h__ @@ -156,7 +156,8 @@ /* Array copy macros */ #define __GLX_MEM_COPY(dest,src,bytes) \ - memcpy(dest, src, bytes) + if (src && dest) \ + memcpy(dest, src, bytes) /* Single item copy macros */ #define __GLX_PUT_CHAR(offset,a) \ diff --git a/xc/lib/GL/glx/pixel.c b/xc/lib/GL/glx/pixel.c index c957b304c..7236165c2 100644 --- a/xc/lib/GL/glx/pixel.c +++ b/xc/lib/GL/glx/pixel.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/glx/pixel.c,v 1.6 2002/02/22 21:32:54 dawes Exp $ */ +/* $XFree86: xc/lib/GL/glx/pixel.c,v 1.7 2002/10/30 12:51:26 alanh Exp $ */ /* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free @@ -183,7 +183,11 @@ GLint __glImageSize(GLsizei width, GLsizei height, GLsizei depth, */ components = ElementsPerGroup(format,type); if (type == GL_BITMAP) { - bytes_per_row = (width + 7) >> 3; + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { + bytes_per_row = (width + 7) >> 3; + } else { + return 0; + } } else { bytes_per_row = BytesPerElement(type) * width; } diff --git a/xc/lib/GL/mesa/src/Imakefile b/xc/lib/GL/mesa/src/Imakefile index a73cb5b4a..57330df6a 100644 --- a/xc/lib/GL/mesa/src/Imakefile +++ b/xc/lib/GL/mesa/src/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile,v 1.30 2002/02/27 00:51:14 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile,v 1.32 2002/11/25 14:04:50 eich Exp $ #include <Threads.tmpl> @@ -12,7 +12,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile,v 1.30 2002/02/27 00:51:14 dawes Ex * driver modules. */ -#if GlxDriverUsesMesa || GlxBuiltInXMesa || BuildOSMesaLib +#if BuildOSMesaLib || (BuildXF86DRI && (GlxDriverUsesMesa || GlxBuiltInXMesa)) #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) #define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) #define DoExtraLib SharedLibGlx @@ -30,7 +30,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile,v 1.30 2002/02/27 00:51:14 dawes Ex ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #define MesaX86BuildDir /**/ #include "X86/Imakefile.inc" ASM_SUBDIRS = X86 diff --git a/xc/lib/GL/mesa/src/Imakefile.inc b/xc/lib/GL/mesa/src/Imakefile.inc index e435bef36..e9965fd0b 100644 --- a/xc/lib/GL/mesa/src/Imakefile.inc +++ b/xc/lib/GL/mesa/src/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile.inc,v 1.7 2002/02/23 00:45:46 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/Imakefile.inc,v 1.8 2002/11/14 21:01:16 tsi Exp $ #ifndef MesaBuildDir #define MesaBuildDir $(GLXLIBSRC)/mesa/src/ @@ -275,7 +275,7 @@ GLAPINOOPUOBJS = $(MESABUILDDIR)unshared/glapinoop.o GLTHREADUOBJS = $(MESABUILDDIR)unshared/glthread.o #endif -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib COREMESABASEUOBJS = $(MESABUILDDIR)unshared/accum.o \ $(MESABUILDDIR)unshared/api_arrayelt.o \ $(MESABUILDDIR)unshared/api_eval.o \ diff --git a/xc/lib/GL/mesa/src/OSmesa/Imakefile b/xc/lib/GL/mesa/src/OSmesa/Imakefile index 173586068..8cce29b1f 100644 --- a/xc/lib/GL/mesa/src/OSmesa/Imakefile +++ b/xc/lib/GL/mesa/src/OSmesa/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/OSmesa/Imakefile,v 1.14 2002/06/06 13:56:15 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/OSmesa/Imakefile,v 1.17 2002/11/27 18:28:02 tsi Exp $ #include <Threads.tmpl> @@ -15,7 +15,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/OSmesa/Imakefile,v 1.14 2002/06/06 13:56:15 d #include "../tnl/Imakefile.inc" #include "../tnl_dd/Imakefile.inc" #include "../Imakefile.inc" -#if defined(i386Architecture) && !SystemV4 +#if defined(i386Architecture) && !SystemV4 && MesaUseX86Asm #include "../X86/Imakefile.inc" #endif #ifdef SparcArchitecture diff --git a/xc/lib/GL/mesa/src/SPARC/Imakefile b/xc/lib/GL/mesa/src/SPARC/Imakefile index 7c958924b..32176f3fd 100644 --- a/xc/lib/GL/mesa/src/SPARC/Imakefile +++ b/xc/lib/GL/mesa/src/SPARC/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/SPARC/Imakefile,v 1.2 2002/02/27 00:51:14 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/SPARC/Imakefile,v 1.3 2002/11/22 22:55:58 tsi Exp $ /* * Need both shared and unshared Mesa objects in the following cases: @@ -10,7 +10,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/SPARC/Imakefile,v 1.2 2002/02/27 00:51:14 daw * driver modules. */ -#if GlxDriverUsesMesa || GlxBuiltInXMesa || BuildOSMesaLib +#if BuildOSMesaLib || (BuildXF86DRI && (GlxDriverUsesMesa || GlxBuiltInXMesa)) #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) #define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) #define DoExtraLib SharedLibGlx diff --git a/xc/lib/GL/mesa/src/SPARC/Imakefile.inc b/xc/lib/GL/mesa/src/SPARC/Imakefile.inc index 43965660e..444c2c551 100644 --- a/xc/lib/GL/mesa/src/SPARC/Imakefile.inc +++ b/xc/lib/GL/mesa/src/SPARC/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/SPARC/Imakefile.inc,v 1.1 2002/02/22 21:32:56 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/SPARC/Imakefile.inc,v 1.2 2002/11/14 21:01:16 tsi Exp $ #ifndef MesaSPARCBuildDir #define MesaSPARCBuildDir $(GLXLIBSRC)/mesa/src/SPARC/ @@ -23,7 +23,7 @@ MESA_SPARC_OBJS = $(MESASPARCBUILDDIR)sparc.o \ $(MESASPARCBUILDDIR)clip.o \ $(MESASPARCBUILDDIR)norm.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_SPARC_UOBJS = $(MESASPARCBUILDDIR)unshared/sparc.o \ $(MESASPARCBUILDDIR)xform.o \ $(MESASPARCBUILDDIR)clip.o \ diff --git a/xc/lib/GL/mesa/src/X/Imakefile b/xc/lib/GL/mesa/src/X/Imakefile index 2fc8bfd22..cfdc45f8c 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.12 2002/02/28 17:52:15 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/X/Imakefile,v 1.13 2002/11/22 22:55:59 tsi Exp $ #include <Threads.tmpl> @@ -12,7 +12,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/X/Imakefile,v 1.12 2002/02/28 17:52:15 dawes * driver modules. */ -#if GlxDriverUsesMesa || GlxBuiltInXMesa || BuildOSMesaLib +#if BuildOSMesaLib || (BuildXF86DRI && (GlxDriverUsesMesa || GlxBuiltInXMesa)) #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) #define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) #define DoExtraLib SharedLibGlx @@ -52,7 +52,7 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src \ MATHDEF = -DCCPML #endif -#if GlxBuiltInXMesa +#if BuildXF86DRI && GlxBuiltInXMesa XMESA_DEFINES = -DGLX_BUILT_IN_XMESA #endif diff --git a/xc/lib/GL/mesa/src/X/Imakefile.inc b/xc/lib/GL/mesa/src/X/Imakefile.inc index 4c18af1b0..7c3575290 100644 --- a/xc/lib/GL/mesa/src/X/Imakefile.inc +++ b/xc/lib/GL/mesa/src/X/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/X/Imakefile.inc,v 1.3 2002/02/25 00:45:40 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/X/Imakefile.inc,v 1.4 2002/11/14 21:01:16 tsi Exp $ #ifndef MesaXBuildDir #define MesaXBuildDir $(GLXLIBSRC)/mesa/src/X/ @@ -49,7 +49,7 @@ XMESA_GLX_OBJS = $(MESAXBUILDDIR)fakeglx.o \ $(MESAXBUILDDIR)xm_span.o \ $(MESAXBUILDDIR)xm_tri.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib #ifndef MesaInXServer XMESA_GLX_UOBJS = $(MESAXBUILDDIR)unshared/fakeglx.o \ $(MESAXBUILDDIR)unshared/glxapi.o \ diff --git a/xc/lib/GL/mesa/src/X86/Imakefile b/xc/lib/GL/mesa/src/X86/Imakefile index 7e1f86661..cf4b3efee 100644 --- a/xc/lib/GL/mesa/src/X86/Imakefile +++ b/xc/lib/GL/mesa/src/X86/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/X86/Imakefile,v 1.23 2002/07/14 17:08:16 alanh Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/X86/Imakefile,v 1.24 2002/11/25 12:58:55 tsi Exp $ /* * Need both shared and unshared Mesa objects in the following cases: @@ -71,7 +71,7 @@ ObjectFromAsmSource(3dnow_xform3, NullParameter) ObjectFromAsmSource(3dnow_xform4, NullParameter) #endif -#if MesaUseKatmai +#if MesaUseSSE ObjectFromAsmSource(sse_normal, NullParameter) ObjectFromAsmSource(sse_vertex, NullParameter) ObjectFromAsmSource(sse_xform1, NullParameter) diff --git a/xc/lib/GL/mesa/src/X86/Imakefile.inc b/xc/lib/GL/mesa/src/X86/Imakefile.inc index 143073c74..8e56bef74 100644 --- a/xc/lib/GL/mesa/src/X86/Imakefile.inc +++ b/xc/lib/GL/mesa/src/X86/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/X86/Imakefile.inc,v 1.4 2002/02/27 21:09:33 tsi Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/X86/Imakefile.inc,v 1.6 2002/11/25 12:58:55 tsi Exp $ #ifndef MesaX86BuildDir #define MesaX86BuildDir $(GLXLIBSRC)/mesa/src/X86/ @@ -37,7 +37,7 @@ MESA_X86_OBJS = $(MESAX86BUILDDIR)common_x86.o \ $(MESAX86BUILDDIR)x86_xform3.o \ $(MESAX86BUILDDIR)x86_xform4.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_X86_UOBJS = $(MESAX86BUILDDIR)unshared/common_x86.o \ $(MESAX86BUILDDIR)common_x86_asm.o \ $(MESAX86BUILDDIR)unshared/x86.o \ @@ -113,7 +113,7 @@ MESA_3DNOW_OBJS = $(MESAX86BUILDDIR)3dnow.o \ $(MESAX86BUILDDIR)3dnow_xform3.o \ $(MESAX86BUILDDIR)3dnow_xform4.o -#ifdef DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_3DNOW_UOBJS = $(MESAX86BUILDDIR)unshared/3dnow.o \ $(MESAX86BUILDDIR)3dnow_normal.o \ $(MESAX86BUILDDIR)3dnow_vertex.o \ @@ -144,7 +144,7 @@ MESA_3DNOW_POBJS = $(MESAX86BUILDDIR)profiled/3dnow.o \ MESA_3DNOW_DEFS = -DUSE_3DNOW_ASM #endif -#if MesaUseKatmai +#if MesaUseSSE MESA_SSE_SRCS = $(MESAX86BUILDDIR)sse.c \ $(MESAX86BUILDDIR)sse_normal.S \ $(MESAX86BUILDDIR)sse_vertex.S \ @@ -171,7 +171,7 @@ MESA_SSE_OBJS = $(MESAX86BUILDDIR)sse.o \ $(MESAX86BUILDDIR)sse_xform3.o \ $(MESAX86BUILDDIR)sse_xform4.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_SSE_UOBJS = $(MESAX86BUILDDIR)unshared/sse.o \ $(MESAX86BUILDDIR)sse_normal.o \ $(MESAX86BUILDDIR)sse_vertex.o \ diff --git a/xc/lib/GL/mesa/src/array_cache/Imakefile b/xc/lib/GL/mesa/src/array_cache/Imakefile index 1007a0497..cffb06cba 100644 --- a/xc/lib/GL/mesa/src/array_cache/Imakefile +++ b/xc/lib/GL/mesa/src/array_cache/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/array_cache/Imakefile,v 1.5 2002/02/28 17:52:16 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/array_cache/Imakefile,v 1.9 2002/11/25 14:04:50 eich Exp $ #include <Threads.tmpl> @@ -12,7 +12,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/array_cache/Imakefile,v 1.5 2002/02/28 17:52: * driver modules. */ -#if GlxDriverUsesMesa || GlxBuiltInXMesa || BuildOSMesaLib +#if BuildOSMesaLib || (BuildXF86DRI && (GlxDriverUsesMesa || GlxBuiltInXMesa)) #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) #define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) #define DoExtraLib SharedLibGlx @@ -52,7 +52,7 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src \ OBJS = $(MESA_AC_OBJS) -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm ASM_SRCS = ASM_OBJS = #if MesaUseMMX diff --git a/xc/lib/GL/mesa/src/array_cache/Imakefile.inc b/xc/lib/GL/mesa/src/array_cache/Imakefile.inc index c3fea9947..d3ee37046 100644 --- a/xc/lib/GL/mesa/src/array_cache/Imakefile.inc +++ b/xc/lib/GL/mesa/src/array_cache/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/array_cache/Imakefile.inc,v 1.1 2002/02/23 00:45:48 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/array_cache/Imakefile.inc,v 1.2 2002/11/14 21:01:16 tsi Exp $ #ifndef MesaACBuildDir #define MesaACBuildDir $(GLXLIBSRC)/mesa/src/array_cache/ @@ -17,7 +17,7 @@ LinkSourceFile(ac_import.c, $(MESASRCDIR)/src/array_cache) MESA_AC_OBJS = $(MESAACBUILDDIR)ac_context.o \ $(MESAACBUILDDIR)ac_import.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_AC_UOBJS = $(MESAACBUILDDIR)unshared/ac_context.o \ $(MESAACBUILDDIR)unshared/ac_import.o #else diff --git a/xc/lib/GL/mesa/src/drv/common/mm.c b/xc/lib/GL/mesa/src/drv/common/mm.c index 89a204952..d8250331e 100644 --- a/xc/lib/GL/mesa/src/drv/common/mm.c +++ b/xc/lib/GL/mesa/src/drv/common/mm.c @@ -21,7 +21,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/common/mm.c,v 1.3 2001/08/18 02:51:03 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/common/mm.c,v 1.4 2002/10/30 12:51:27 alanh Exp $ */ #include <stdlib.h> #include <stdio.h> @@ -29,27 +29,27 @@ #include "mm.h" #include "hwlog.h" -#define ISFREE(bptr) ((bptr)->free) -/* #define PRINTF hwMsg(1, */ -#define PRINTF fprintf(stderr, +/* KW: I don't know who the author of this code is, but it wasn't me + * despite what the copyright says... + */ 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"); + TMemBlock *p; + + fprintf(stderr, "Memory heap %p:\n", heap); + if (heap == 0) { + fprintf(stderr, " heap == 0\n"); + } else { + p = (TMemBlock *)heap; + while (p) { + fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? '.':'U', + p->reserved ? 'R':'.'); + p = p->next; + } + } + fprintf(stderr, "End of memory blocks\n"); } memHeap_t *mmInit(int ofs, @@ -70,197 +70,131 @@ memHeap_t *mmInit(int ofs, 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)); - if (!newblock) - return NULL; - 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; - } + TMemBlock *newblock; + + /* break left */ + if (startofs > p->ofs) { + newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock)); + if (!newblock) + return NULL; + 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)); - if (!newblock) - return NULL; - newblock->ofs = startofs + size; - newblock->size = p->size - size; - newblock->free = 1; - newblock->next = p->next; - p->size = size; - p->next = newblock; - } + /* break right */ + if (size < p->size) { + newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock)); + if (!newblock) + return NULL; + 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; + /* 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; + 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 ((p)->free) { + startofs = (p->ofs + mask) & ~mask; + if ( startofs < startSearch ) { + startofs = startSearch; + } + endofs = startofs+size; + if (endofs <= (p->ofs+p->size)) + break; } - 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; + 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; + 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; + TMemBlock *p,*prev; - 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); + if (!b) return 0; - } - p = p->next; - } - return -1; + 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 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; - } + 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 index 6fa6e8b69..d52871d39 100644 --- a/xc/lib/GL/mesa/src/drv/common/mm.h +++ b/xc/lib/GL/mesa/src/drv/common/mm.h @@ -45,22 +45,12 @@ static __inline__ int mmBlockSize(PMemBlock b) 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' @@ -71,7 +61,8 @@ memHeap_t *mmAddRange( memHeap_t *heap, * 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 ); +PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, + int startSearch ); /* * Free block starts at offset @@ -81,16 +72,6 @@ PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch ); 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 ); diff --git a/xc/lib/GL/mesa/src/drv/ffb/Imakefile b/xc/lib/GL/mesa/src/drv/ffb/Imakefile index b373c463b..f0f8e9d76 100644 --- a/xc/lib/GL/mesa/src/drv/ffb/Imakefile +++ b/xc/lib/GL/mesa/src/drv/ffb/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/ffb/Imakefile,v 1.15 2002/02/23 00:45:48 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/ffb/Imakefile,v 1.17 2002/11/25 14:04:50 eich Exp $ #include <Threads.tmpl> @@ -25,7 +25,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/ffb/Imakefile,v 1.15 2002/02/23 00:45:48 #include "../../tnl/Imakefile.inc" #include "../../tnl_dd/Imakefile.inc" #include "../../Imakefile.inc" -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #include "../../X86/Imakefile.inc" #endif #ifdef SparcArchitecture @@ -55,7 +55,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/ffb/Imakefile,v 1.15 2002/02/23 00:45:48 OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(COREMESAOBJS) \ $(MESA_ASM_OBJS) $(COMMONOBJS) $(FFBOBJS) $(HIOBJS) -REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) +REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) $(XONLYLIB) #include <Library.tmpl> diff --git a/xc/lib/GL/mesa/src/drv/ffb/ffb_rendertmp.h b/xc/lib/GL/mesa/src/drv/ffb/ffb_rendertmp.h index de5185909..9d18db5fd 100644 --- a/xc/lib/GL/mesa/src/drv/ffb/ffb_rendertmp.h +++ b/xc/lib/GL/mesa/src/drv/ffb/ffb_rendertmp.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_rendertmp.h,v 1.1 2002/02/22 21:32:59 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_rendertmp.h,v 1.2 2003/01/29 23:00:40 dawes Exp $ */ #define IMPL_LOCAL_VARS \ ffbContextPtr fmesa = FFB_CONTEXT(ctx); \ @@ -56,8 +56,8 @@ static void TAG(ffb_vb_points)(GLcontext *ctx, GLuint start, GLuint count, GLuin IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_POINTS); if (ctx->_TriangleCaps & DD_POINT_SMOOTH) { @@ -90,8 +90,8 @@ static void TAG(ffb_vb_lines)(GLcontext *ctx, GLuint start, GLuint count, GLuint IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_LINES); for (i = start + 1; i < count; i += 2) { @@ -123,8 +123,8 @@ static void TAG(ffb_vb_line_loop)(GLcontext *ctx, GLuint start, GLuint count, GL IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_LINE_LOOP); if ((flags & PRIM_BEGIN) != 0) { @@ -185,8 +185,8 @@ static void TAG(ffb_vb_line_strip)(GLcontext *ctx, GLuint start, GLuint count, G IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_LINE_STRIP); FFBFifo(fmesa, (1 + FFB_PRIM_COLOR_COST + @@ -278,8 +278,8 @@ static void TAG(ffb_vb_triangles)(GLcontext *ctx, GLuint start, GLuint count, GL IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_TRIANGLES); for (i = start + 2; i < count; i += 3) { @@ -321,8 +321,8 @@ static void TAG(ffb_vb_tri_strip)(GLcontext *ctx, GLuint start, GLuint count, GL IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_TRIANGLE_STRIP); if ((flags & PRIM_PARITY) != 0) @@ -394,8 +394,8 @@ static void TAG(ffb_vb_tri_fan)(GLcontext *ctx, GLuint start, GLuint count, GLui IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_TRIANGLE_FAN); @@ -464,8 +464,8 @@ static void TAG(ffb_vb_poly)(GLcontext *ctx, GLuint start, GLuint count, GLuint IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_POLYGON); @@ -508,8 +508,8 @@ static void TAG(ffb_vb_quads)(GLcontext *ctx, GLuint start, GLuint count, GLuint IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_QUADS); @@ -557,8 +557,8 @@ static void TAG(ffb_vb_quad_strip)(GLcontext *ctx, GLuint start, GLuint count, G IMPL_LOCAL_VARS; #ifdef FFB_RENDER_TRACE - fprintf(stderr, __FUNCTION__ ": start(%d) count(%d) flags(%x)\n", - start, count, flags); + fprintf(stderr, "%s: start(%d) count(%d) flags(%x)\n", + __FUNCTION__, start, count, flags); #endif ffbRenderPrimitive(ctx, GL_QUAD_STRIP); diff --git a/xc/lib/GL/mesa/src/drv/ffb/ffb_state.c b/xc/lib/GL/mesa/src/drv/ffb/ffb_state.c index 3853fd3a0..838d851d3 100644 --- a/xc/lib/GL/mesa/src/drv/ffb/ffb_state.c +++ b/xc/lib/GL/mesa/src/drv/ffb/ffb_state.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_state.c,v 1.4 2002/09/10 00:39:37 dawes Exp $ +/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_state.c,v 1.5 2002/10/30 12:51:27 alanh Exp $ * * GLX Hardware Device Driver for Sun Creator/Creator3D * Copyright (C) 2000, 2001 David S. Miller @@ -477,20 +477,20 @@ static void ffbDDSetDrawBuffer(GLcontext *ctx, GLenum buffer) fprintf(stderr, "ffbDDSetDrawBuffer: mode(%s)\n", _mesa_lookup_enum_by_nr(buffer)); #endif - fbc &= ~(FFB_FBC_WB_AB); + fbc &= ~(FFB_FBC_WB_AB | FFB_FBC_RB_MASK); switch (buffer) { case GL_FRONT_LEFT: if (fmesa->back_buffer == 0) - fbc |= FFB_FBC_WB_B; + fbc |= FFB_FBC_WB_B | FFB_FBC_RB_B; else - fbc |= FFB_FBC_WB_A; + fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A; break; case GL_BACK_LEFT: if (fmesa->back_buffer == 0) - fbc |= FFB_FBC_WB_A; + fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A; else - fbc |= FFB_FBC_WB_B; + fbc |= FFB_FBC_WB_B | FFB_FBC_RB_B; break; case GL_FRONT_AND_BACK: diff --git a/xc/lib/GL/mesa/src/drv/ffb/ffb_tris.c b/xc/lib/GL/mesa/src/drv/ffb/ffb_tris.c index 792198652..b58886218 100644 --- a/xc/lib/GL/mesa/src/drv/ffb/ffb_tris.c +++ b/xc/lib/GL/mesa/src/drv/ffb/ffb_tris.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_tris.c,v 1.2 2002/02/22 21:32:59 dawes Exp $ +/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_tris.c,v 1.3 2002/10/30 12:51:28 alanh Exp $ * * GLX Hardware Device Driver for Sun Creator/Creator3D * Copyright (C) 2000, 2001 David S. Miller @@ -34,7 +34,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "swrast_setup/ss_context.h" +#include "swrast/s_context.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -926,7 +926,7 @@ void ffbFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) void ffbDDInitRenderFuncs( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - SScontext *swsetup = SWSETUP_CONTEXT(ctx); + SWcontext *swrast = SWRAST_CONTEXT(ctx); static int firsttime = 1; if (firsttime) { @@ -944,6 +944,6 @@ void ffbDDInitRenderFuncs( GLcontext *ctx ) tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; - swsetup->Driver.Start = ffbSWRenderStart; - swsetup->Driver.Finish = ffbSWRenderFinish; + swrast->Driver.SpanRenderStart = ffbSWRenderStart; + swrast->Driver.SpanRenderFinish = ffbSWRenderFinish; } diff --git a/xc/lib/GL/mesa/src/drv/gamma/Imakefile b/xc/lib/GL/mesa/src/drv/gamma/Imakefile index aa9021bb5..01a349b37 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.25 2002/02/23 00:45:49 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.27 2002/11/25 14:04:50 eich Exp $ #include <Threads.tmpl> @@ -25,7 +25,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.25 2002/02/23 00:45:4 #include "../../tnl/Imakefile.inc" #include "../../tnl_dd/Imakefile.inc" #include "../../Imakefile.inc" -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #include "../../X86/Imakefile.inc" #endif #ifdef SparcArchitecture @@ -55,7 +55,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.25 2002/02/23 00:45:4 OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(COREMESAOBJS) \ $(MESA_ASM_OBJS) $(COMMONOBJS) $(GAMMAOBJS) $(HIOBJS) -REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) +REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) $(XONLYLIB) #include <Library.tmpl> diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_context.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_context.c index 4365505b1..4f666f6d8 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_context.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_context.c @@ -19,7 +19,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> * * 3DLabs Gamma driver. * @@ -74,7 +74,7 @@ GLboolean gammaCreateContext( Display *dpy, const __GLcontextModes *glVisual, __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; gammaContextPtr gmesa; gammaScreenPtr gammascrn; - drm_gamma_sarea_t *saPriv=(drm_gamma_sarea_t *)(((char*)sPriv->pSAREA)+ + GLINTSAREADRIPtr saPriv=(GLINTSAREADRIPtr)(((char*)sPriv->pSAREA)+ sizeof(XF86DRISAREARec)); gmesa = (gammaContextPtr) CALLOC( sizeof(*gmesa) ); diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_context.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_context.h index e37c4c3e4..b81490ae1 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_context.h +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_context.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_context.h,v 1.3 2002/09/18 17:11:40 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_context.h,v 1.6 2002/12/16 16:18:50 dawes Exp $ */ /* * Copyright 2001 by Alan Hourihane. * @@ -20,7 +20,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> * */ @@ -34,7 +34,7 @@ #include "gamma_screen.h" #include "macros.h" #include "mtypes.h" -#include "drm.h" +#include "glint_dri.h" #include "mm.h" typedef union { @@ -144,7 +144,7 @@ struct gamma_texture_object_t { int bound; PMemBlock MemBlock; - char *BufAddr; + char * BufAddr; GLuint min_level; GLuint max_level; @@ -238,7 +238,7 @@ struct gamma_context { GLuint new_state; GLuint dirty; - drm_gamma_sarea_t *sarea; + GLINTSAREADRIPtr sarea; /* Temporaries for translating away float colors: */ @@ -299,11 +299,11 @@ struct gamma_context { memHeap_t *texHeap; - int lastSwap; + unsigned int lastSwap; int texAge; int ctxAge; int dirtyAge; - int lastStamp; + unsigned int lastStamp; CARD32 ClearColor; diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_dd.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_dd.c index c65a3e8fb..98ef6cc52 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_dd.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_dd.c @@ -19,7 +19,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> * */ @@ -30,15 +30,15 @@ #include "X86/common_x86_asm.h" #endif -#include "swrast/swrast.h" #include "context.h" +#include "swrast/swrast.h" #define GAMMA_DATE "20010624" /* Return the width and height of the current color buffer. */ -static void gammaDDGetBufferSize(GLframebuffer *buffer, +static void gammaDDGetBufferSize( GLframebuffer *buffer, GLuint *width, GLuint *height ) { GET_CURRENT_CONTEXT(ctx); @@ -105,6 +105,7 @@ void gammaDDInitExtensions( GLcontext *ctx ) void gammaDDInitDriverFuncs( GLcontext *ctx ) { ctx->Driver.GetBufferSize = gammaDDGetBufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; ctx->Driver.GetString = gammaDDGetString; ctx->Driver.Error = NULL; diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c index b012360e0..47eb802b4 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c @@ -19,11 +19,11 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> * Kevin E. Martin <martin@valinux.com> * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c,v 1.8 2002/02/22 21:33:02 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c,v 1.9 2002/10/30 12:51:29 alanh Exp $ */ #include "gamma_context.h" #include "glint_dri.h" @@ -196,28 +196,6 @@ void gammaInitHW( gammaContextPtr gmesa ) gmesa->ColorDDAMode = (ColorDDAEnable | ColorDDAGouraud); -#ifdef CULL_ALL_PRIMS - gmesa->GeometryMode = (GM_TextureDisable | - GM_FogDisable | - GM_FogExp | - GM_FrontPolyFill | - GM_BackPolyFill | - GM_FrontFaceCCW | - GM_PolyCullDisable | - GM_PolyCullBoth | - GM_ClipShortLinesDisable | - GM_ClipSmallTrisDisable | - GM_RenderMode | - GM_Feedback2D | - GM_CullFaceNormDisable | - GM_AutoFaceNormDisable | - GM_GouraudShading | - GM_UserClipNone | - GM_PolyOffsetPointDisable | - GM_PolyOffsetLineDisable | - GM_PolyOffsetFillDisable | - GM_InvertFaceNormCullDisable); -#else gmesa->GeometryMode = (GM_TextureDisable | GM_FogDisable | GM_FogExp | @@ -238,7 +216,6 @@ void gammaInitHW( gammaContextPtr gmesa ) GM_PolyOffsetLineDisable | GM_PolyOffsetFillDisable | GM_InvertFaceNormCullDisable); -#endif gmesa->AlphaTestMode = (AlphaTestModeDisable | AT_Always); @@ -293,46 +270,25 @@ void gammaInitHW( gammaContextPtr gmesa ) XM_TexGenModeR_None | XM_TexGenModeQ_None; - /* Set MXs to known state */ - CHECK_DMA_BUFFER(gmesa, 24); - WRITE(gmesa->buf, RasterizerMode, 0); - WRITE(gmesa->buf, AreaStippleMode, 0); + CHECK_DMA_BUFFER(gmesa, 20); WRITE(gmesa->buf, LineStippleMode, 0); - WRITE(gmesa->buf, ScissorMode, 0); WRITE(gmesa->buf, RouterMode, 0); WRITE(gmesa->buf, TextureAddressMode, 0); WRITE(gmesa->buf, TextureReadMode, 0); WRITE(gmesa->buf, TextureFilterMode, 0); - WRITE(gmesa->buf, ColorDDAMode, 0); WRITE(gmesa->buf, TextureColorMode, 0); - WRITE(gmesa->buf, FogMode, 0); - WRITE(gmesa->buf, AntialiasMode, 0); - WRITE(gmesa->buf, LBReadMode, 0); - WRITE(gmesa->buf, GLINTWindow, 0); WRITE(gmesa->buf, StencilMode, 0); - WRITE(gmesa->buf, DepthMode, 0); - WRITE(gmesa->buf, LBWriteMode, 0); - WRITE(gmesa->buf, FBReadMode, 0); WRITE(gmesa->buf, PatternRamMode, 0); WRITE(gmesa->buf, ChromaTestMode, 0); - WRITE(gmesa->buf, DitherMode, 0); - WRITE(gmesa->buf, LogicalOpMode, 0); - WRITE(gmesa->buf, FBWriteMode, 0); WRITE(gmesa->buf, StatisticMode, 0); - - /* Set Gamma to known state */ - CHECK_DMA_BUFFER(gmesa, 9); + WRITE(gmesa->buf, AreaStippleMode, gmesa->AreaStippleMode); + WRITE(gmesa->buf, ScissorMode, gmesa->ScissorMode); + WRITE(gmesa->buf, FogMode, gmesa->FogMode); + WRITE(gmesa->buf, AntialiasMode, gmesa->AntialiasMode); + WRITE(gmesa->buf, LogicalOpMode, gmesa->LogicalOpMode); WRITE(gmesa->buf, TriangleMode, gmesa->TriangleMode); - WRITE(gmesa->buf, GeometryMode, 0); - WRITE(gmesa->buf, NormalizeMode, 0); - WRITE(gmesa->buf, ColorMaterialMode, 0); - WRITE(gmesa->buf, MaterialMode, 0); WRITE(gmesa->buf, PointMode, gmesa->PointMode); WRITE(gmesa->buf, LineMode, gmesa->LineMode); - WRITE(gmesa->buf, TransformMode, 0); - WRITE(gmesa->buf, DeltaMode, 0); - - CHECK_DMA_BUFFER(gmesa, 2); WRITE(gmesa->buf, LBWriteFormat, gmesa->LBWriteFormat); WRITE(gmesa->buf, LBReadFormat, gmesa->LBReadFormat); diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_lock.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_lock.c index 4ef9cb131..1c9ed252e 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_lock.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_lock.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_lock.c,v 1.2 2002/02/26 23:37:33 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_lock.c,v 1.4 2002/11/05 17:46:07 tsi Exp $ */ #include "gamma_context.h" diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_render.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_render.c index 3bf35db0e..d283b641b 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_render.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_render.c @@ -19,7 +19,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> * * 3DLabs Gamma driver. * diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_screen.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_screen.c index f826a5038..ddcd9d0a4 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_screen.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_screen.c @@ -19,7 +19,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> * */ diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_span.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_span.c index 6f6f64b31..3742fc6ba 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_span.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_span.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_span.c,v 1.2 2002/02/26 23:37:33 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_span.c,v 1.4 2002/11/05 17:46:07 tsi Exp $ */ #include "gamma_context.h" #include "gamma_lock.h" @@ -156,7 +156,7 @@ do { \ -#if 0 /* unused */ +#if 0 /* Unused */ /* 32 bit depthbuffer functions. */ #define WRITE_DEPTH( _x, _y, d ) \ diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_state.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_state.c index 7da907805..1703b319d 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_state.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_state.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_state.c,v 1.3 2002/09/10 00:39:37 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_state.c,v 1.5 2002/11/05 17:46:07 tsi Exp $ */ /* * Copyright 2001 by Alan Hourihane. * @@ -20,7 +20,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> * * 3DLabs Gamma driver */ @@ -1050,10 +1050,10 @@ static void gammaDDSetDrawBuffer( GLcontext *ctx, GLenum mode ) switch ( mode ) { case GL_FRONT_LEFT: - gmesa->drawOffset = 0; + gmesa->drawOffset = gmesa->readOffset = 0; break; case GL_BACK_LEFT: - gmesa->drawOffset = gmesa->driScreen->fbHeight * gmesa->driScreen->fbWidth * gmesa->gammaScreen->cpp; + gmesa->drawOffset = gmesa->readOffset = gmesa->driScreen->fbHeight * gmesa->driScreen->fbWidth * gmesa->gammaScreen->cpp; break; } } diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_tex.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_tex.c index 647cc1cd2..755b2371e 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_tex.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_tex.c @@ -1,8 +1,7 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_tex.c,v 1.2 2002/02/26 23:37:33 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_tex.c,v 1.4 2002/11/05 17:46:07 tsi Exp $ */ #include <stdlib.h> #include <stdio.h> -#include <X11/Xarch.h> #include "glheader.h" #include "mtypes.h" @@ -203,10 +202,11 @@ static void gammaTexEnv( GLcontext *ctx, GLenum target, break; case GL_TEXTURE_LOD_BIAS_EXT: -#if 0 /* !?!?! */ +#if 0 /* ?!?!?! */ { struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; gammaTextureObjectPtr t = (gammaTextureObjectPtr) tObj->DriverData; + /* XXX Looks like there's something missing here */ } #endif break; @@ -326,7 +326,7 @@ static void gammaBindTexture( GLcontext *ctx, GLenum target, t->TextureFilterMode = TextureFilterModeEnable; -#if X_BYTE_ORDER == X_LITTLE_ENDIAN +#ifdef MESA_LITTLE_ENDIAN t->TextureFormat = (TF_LittleEndian | #else t->TextureFormat = (TF_BigEndian | diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_texmem.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_texmem.c index 191769f54..7c5de399d 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_texmem.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_texmem.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_texmem.c,v 1.3 2002/09/18 17:11:40 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_texmem.c,v 1.5 2002/11/05 17:46:07 tsi Exp $ */ #include <stdlib.h> #include <stdio.h> @@ -10,6 +10,7 @@ #include "enums.h" #include "mm.h" +#include "glint_dri.h" #include "gamma_context.h" #include "gamma_lock.h" @@ -321,7 +322,7 @@ void gammaPrintLocalLRU( gammaContextPtr gmesa ) void gammaPrintGlobalLRU( gammaContextPtr gmesa ) { int i, j; - drm_gamma_tex_region_t *list = gmesa->sarea->texList; + GAMMATextureRegionPtr list = gmesa->sarea->texList; for (i = 0, j = GAMMA_NR_TEX_REGIONS ; i < GAMMA_NR_TEX_REGIONS ; i++) { fprintf(stderr, "list[%d] age %d next %d prev %d\n", @@ -337,7 +338,7 @@ void gammaPrintGlobalLRU( gammaContextPtr gmesa ) void gammaResetGlobalLRU( gammaContextPtr gmesa ) { - drm_gamma_tex_region_t *list = gmesa->sarea->texList; + GAMMATextureRegionPtr list = gmesa->sarea->texList; int sz = 1 << gmesa->gammaScreen->logTextureGranularity; int i; @@ -369,7 +370,7 @@ void gammaUpdateTexLRU( gammaContextPtr gmesa, gammaTextureObjectPtr t ) int logsz = gmesa->gammaScreen->logTextureGranularity; int start = t->MemBlock->ofs >> logsz; int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - drm_gamma_tex_region_t *list = gmesa->sarea->texList; + GAMMATextureRegionPtr list = gmesa->sarea->texList; gmesa->texAge = ++gmesa->sarea->texAge; @@ -502,7 +503,7 @@ void gammaUploadTexImages( gammaContextPtr gmesa, gammaTextureObjectPtr t ) } ofs = t->MemBlock->ofs; - t->BufAddr = (char *)(long)(gmesa->LBWindowBase + ofs); /* ??? */ + t->BufAddr = (char *)(unsigned long)(gmesa->LBWindowBase + ofs); /* ??? */ if (t == gmesa->CurrentTexObj[0]) gmesa->dirty |= GAMMA_UPLOAD_TEX0; diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_texstate.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_texstate.c index a37f4317f..41446d1ca 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_texstate.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_texstate.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_texstate.c,v 1.3 2002/09/18 17:11:40 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_texstate.c,v 1.5 2002/11/05 17:46:07 tsi Exp $ */ #include <stdlib.h> #include <stdio.h> diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_tris.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_tris.c index a6e78b405..bd7a8797b 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_tris.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_tris.c @@ -19,8 +19,8 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> - * Keith Whitwell, <keithw@valinux.com> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> + * Keith Whitwell, <keith@tungstengraphics.com> * * 3DLabs Gamma driver. */ diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_tris.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_tris.h index 944052914..02bec2869 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_tris.h +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_tris.h @@ -19,8 +19,8 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> - * Keith Whitwell, <keithw@valinux.com> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> + * Keith Whitwell, <keith@tungstengraphics.com> * * 3DLabs Gamma driver. */ diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_vb.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_vb.c index cb8baf807..e9de41858 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_vb.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_vb.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_vb.c,v 1.2 2002/02/26 23:37:34 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_vb.c,v 1.3 2002/10/30 12:51:30 alanh Exp $ */ /* * Copyright 2001 by Alan Hourihane. * @@ -20,8 +20,8 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> - * Keith Whitwell, <keithw@valinux.com> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> + * Keith Whitwell, <keith@tungstengraphics.com> * * 3DLabs Gamma driver. */ @@ -46,7 +46,9 @@ #define GAMMA_RGBA_BIT 0x2 #define GAMMA_XYZW_BIT 0x4 #define GAMMA_PTEX_BIT 0x8 -#define GAMMA_MAX_SETUP 0x10 +#define GAMMA_FOG_BIT 0x10 +#define GAMMA_SPEC_BIT 0x20 +#define GAMMA_MAX_SETUP 0x40 static struct { void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint ); @@ -58,12 +60,9 @@ static struct { GLuint vertex_format; } setup_tab[GAMMA_MAX_SETUP]; - -/* Only one vertex format, atm, so no need to give them names: - */ -#define TINY_VERTEX_FORMAT 0 -#define NOTEX_VERTEX_FORMAT 0 -#define TEX0_VERTEX_FORMAT 0 +#define TINY_VERTEX_FORMAT 1 +#define NOTEX_VERTEX_FORMAT 2 +#define TEX0_VERTEX_FORMAT 3 #define TEX1_VERTEX_FORMAT 0 #define PROJ_TEX1_VERTEX_FORMAT 0 #define TEX2_VERTEX_FORMAT 0 @@ -72,8 +71,8 @@ static struct { #define DO_XYZW (IND & GAMMA_XYZW_BIT) #define DO_RGBA (IND & GAMMA_RGBA_BIT) -#define DO_SPEC 0 -#define DO_FOG 0 +#define DO_SPEC (IND & GAMMA_SPEC_BIT) +#define DO_FOG (IND & GAMMA_FOG_BIT) #define DO_TEX0 (IND & GAMMA_TEX0_BIT) #define DO_TEX1 0 #define DO_TEX2 0 @@ -81,10 +80,11 @@ static struct { #define DO_PTEX (IND & GAMMA_PTEX_BIT) #define VERTEX gammaVertex +#define VERTEX_COLOR gamma_color_t #define GET_VIEWPORT_MAT() 0 #define GET_TEXSOURCE(n) n -#define GET_VERTEX_FORMAT() 0 -#define GET_VERTEX_STORE() (GLubyte *)(GAMMA_CONTEXT(ctx)->verts) +#define GET_VERTEX_FORMAT() GAMMA_CONTEXT(ctx)->vertex_format +#define GET_VERTEX_STORE() GAMMA_CONTEXT(ctx)->verts #define GET_VERTEX_STRIDE_SHIFT() GAMMA_CONTEXT(ctx)->vertex_stride_shift #define INVALIDATE_STORED_VERTICES() #define GET_UBYTE_COLOR_STORE() &GAMMA_CONTEXT(ctx)->UbyteColor @@ -93,7 +93,7 @@ static struct { #define HAVE_HW_VIEWPORT 1 #define HAVE_HW_DIVIDE 1 #define HAVE_RGBA_COLOR 0 /* we're BGRA */ -#define HAVE_TINY_VERTICES 0 +#define HAVE_TINY_VERTICES 1 #define HAVE_NOTEX_VERTICES 1 #define HAVE_TEX0_VERTICES 1 #define HAVE_TEX1_VERTICES 0 @@ -123,11 +123,14 @@ static struct { * Generate vertex emit and interp functions * ***********************************************************************/ - #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT) #define TAG(x) x##_wg #include "tnl_dd/t_dd_vbtmp.h" +#define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT) +#define TAG(x) x##_wgs +#include "tnl_dd/t_dd_vbtmp.h" + #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_TEX0_BIT) #define TAG(x) x##_wgt0 #include "tnl_dd/t_dd_vbtmp.h" @@ -136,83 +139,124 @@ static struct { #define TAG(x) x##_wgpt0 #include "tnl_dd/t_dd_vbtmp.h" +#define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT) +#define TAG(x) x##_wgst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT|\ + GAMMA_PTEX_BIT) +#define TAG(x) x##_wgspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT) +#define TAG(x) x##_wgf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT) +#define TAG(x) x##_wgft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT|\ + GAMMA_PTEX_BIT) +#define TAG(x) x##_wgfpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\ + GAMMA_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\ + GAMMA_TEX0_BIT|GAMMA_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + #define IND (GAMMA_TEX0_BIT) #define TAG(x) x##_t0 #include "tnl_dd/t_dd_vbtmp.h" +#define IND (GAMMA_FOG_BIT) +#define TAG(x) x##_f +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_FOG_BIT|GAMMA_TEX0_BIT) +#define TAG(x) x##_ft0 +#include "tnl_dd/t_dd_vbtmp.h" + #define IND (GAMMA_RGBA_BIT) #define TAG(x) x##_g #include "tnl_dd/t_dd_vbtmp.h" +#define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT) +#define TAG(x) x##_gs +#include "tnl_dd/t_dd_vbtmp.h" + #define IND (GAMMA_RGBA_BIT|GAMMA_TEX0_BIT) #define TAG(x) x##_gt0 #include "tnl_dd/t_dd_vbtmp.h" +#define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT) +#define TAG(x) x##_gst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT) +#define TAG(x) x##_gf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT) +#define TAG(x) x##_gfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT) +#define TAG(x) x##_gft0 +#include "tnl_dd/t_dd_vbtmp.h" +#define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT) +#define TAG(x) x##_gfst0 +#include "tnl_dd/t_dd_vbtmp.h" static void init_setup_tab( void ) { init_wg(); + init_wgs(); init_wgt0(); init_wgpt0(); + init_wgst0(); + init_wgspt0(); + init_wgf(); + init_wgfs(); + init_wgft0(); + init_wgfpt0(); + init_wgfst0(); + init_wgfspt0(); init_t0(); + init_f(); + init_ft0(); init_g(); + init_gs(); init_gt0(); + init_gst0(); + init_gf(); + init_gfs(); + init_gft0(); + init_gfst0(); } - -#if 0 -void gammaPrintSetupFlags(char *msg, GLuint flags ) -{ - fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n", - msg, - (int)flags, - (flags & GAMMA_XYZW_BIT) ? " xyzw," : "", - (flags & GAMMA_RGBA_BIT) ? " rgba," : "", - (flags & GAMMA_SPEC_BIT) ? " spec," : "", - (flags & GAMMA_FOG_BIT) ? " fog," : "", - (flags & GAMMA_TEX0_BIT) ? " tex-0," : "", - (flags & GAMMA_TEX1_BIT) ? " tex-1," : ""); -} -#endif - - void gammaCheckTexSizes( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); gammaContextPtr gmesa = GAMMA_CONTEXT( ctx ); -#if 0 if (!setup_tab[gmesa->SetupIndex].check_tex_sizes(ctx)) { /* Invalidate stored verts */ gmesa->SetupNewInputs = ~0; gmesa->SetupIndex |= GAMMA_PTEX_BIT; - if (/*!gmesa->Fallback && */ - !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { - tnl->Driver.Render.Interp = setup_tab[gmesa->SetupIndex].interp; - tnl->Driver.Render.CopyPV = setup_tab[gmesa->SetupIndex].copy_pv; - } - } -#endif - - if (!setup_tab[gmesa->SetupIndex].check_tex_sizes(ctx)) { - - /* Radeon handles projective textures nicely; just have to change - * up to the new vertex format. - */ -#if 0 - GLuint ind = gmesa->SetupIndex |= (GAMMA_PTEX_BIT|GAMMA_RGBA_BIT); - - if (setup_tab[ind].vertex_format != gmesa->vertex_format) { - RADEON_STATECHANGE(gmesa, 0); - gmesa->vertex_format = setup_tab[ind].vertex_format; - gmesa->vertex_size = setup_tab[ind].vertex_size; - gmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; - } -#endif - if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { tnl->Driver.Render.Interp = setup_tab[gmesa->SetupIndex].interp; tnl->Driver.Render.CopyPV = setup_tab[gmesa->SetupIndex].copy_pv; @@ -236,23 +280,29 @@ void gammaBuildVertices( GLcontext *ctx, return; if (newinputs & VERT_CLIP) { - setup_tab[gmesa->SetupIndex].emit( ctx, start, count, v, stride ); + setup_tab[gmesa->SetupIndex].emit( ctx, start, count, v, stride ); } else { GLuint ind = 0; if (newinputs & VERT_RGBA) ind |= GAMMA_RGBA_BIT; - + + if (newinputs & VERT_SPEC_RGB) + ind |= GAMMA_SPEC_BIT; + if (newinputs & VERT_TEX0) ind |= GAMMA_TEX0_BIT; + if (newinputs & VERT_FOG_COORD) + ind |= GAMMA_FOG_BIT; + if (gmesa->SetupIndex & GAMMA_PTEX_BIT) ind = ~0; ind &= gmesa->SetupIndex; if (ind) { - setup_tab[ind].emit( ctx, start, count, v, stride ); + setup_tab[ind].emit( ctx, start, count, v, stride ); } } } @@ -263,14 +313,26 @@ void gammaChooseVertexState( GLcontext *ctx ) TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint ind = GAMMA_XYZW_BIT|GAMMA_RGBA_BIT; + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + ind |= GAMMA_SPEC_BIT; + + if (ctx->Fog.Enabled) + ind |= GAMMA_FOG_BIT; + if (ctx->Texture._ReallyEnabled) { _tnl_need_projected_coords( ctx, GL_FALSE ); ind |= GAMMA_TEX0_BIT; } else - _tnl_need_projected_coords( ctx, GL_TRUE ); + _tnl_need_projected_coords( ctx, GL_FALSE ); gmesa->SetupIndex = ind; + if (setup_tab[ind].vertex_format != gmesa->vertex_format) { + gmesa->vertex_format = setup_tab[ind].vertex_format; + gmesa->vertex_size = setup_tab[ind].vertex_size; + gmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; + } + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { tnl->Driver.Render.Interp = gamma_interp_extras; tnl->Driver.Render.CopyPV = gamma_copy_pv_extras; diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_vb.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_vb.h index 3a67d3f63..feda25c4c 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_vb.h +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_vb.h @@ -19,8 +19,8 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> - * Keith Whitwell, <keithw@valinux.com> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> + * Keith Whitwell, <keith@tungstengraphics.com> * * 3DLabs Gamma driver. */ diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c index 9d85c9583..9314a4f4f 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c,v 1.13 2002/02/22 21:33:02 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c,v 1.14 2002/10/30 12:51:30 alanh Exp $ */ /* * Copyright 2001 by Alan Hourihane. * @@ -20,7 +20,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Authors: Alan Hourihane, <alanh@tungstengraphics.com> * * 3DLabs Gamma driver */ diff --git a/xc/lib/GL/mesa/src/drv/i810/Imakefile b/xc/lib/GL/mesa/src/drv/i810/Imakefile index 9548f9e15..6694fad01 100644 --- a/xc/lib/GL/mesa/src/drv/i810/Imakefile +++ b/xc/lib/GL/mesa/src/drv/i810/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i810/Imakefile,v 1.22 2002/09/10 00:39:37 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i810/Imakefile,v 1.25 2002/11/25 14:04:51 eich Exp $ #include <Threads.tmpl> @@ -25,23 +25,14 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i810/Imakefile,v 1.22 2002/09/10 00:39:37 #include "../../tnl/Imakefile.inc" #include "../../tnl_dd/Imakefile.inc" #include "../../Imakefile.inc" -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #include "../../X86/Imakefile.inc" #endif #ifdef SparcArchitecture #include "../../SPARC/Imakefile.inc" #endif -#ifndef HaveDrmCommand -#define HaveDrmCommand NO -#endif - -#if HaveDrmCommand -DRMCOMMAND_DEFINES = -DHAVE_DRM_COMMAND -#endif - - DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(MESA_ASM_DEFINES) \ - $(DRMCOMMAND_DEFINES) + DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(MESA_ASM_DEFINES) INCLUDES = $(X_INCLUDES) $(MESA_INCLUDES) $(DRI_INCLUDES) @@ -64,7 +55,7 @@ DRMCOMMAND_DEFINES = -DHAVE_DRM_COMMAND OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(COREMESAOBJS) \ $(MESA_ASM_OBJS) $(COMMONOBJS) $(I810OBJS) $(HIOBJS) -REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) +REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) $(XONLYLIB) #include <Library.tmpl> diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.c b/xc/lib/GL/mesa/src/drv/i810/i810context.c index 0d5ff8812..3dbe38421 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810context.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810context.c @@ -24,11 +24,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810context.c,v 1.2 2002/09/10 00:39:37 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810context.c,v 1.3 2002/10/30 12:51:33 alanh Exp $ */ /* * Authors: - * Keith Whitwell <keithw@precisioninsight.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ @@ -73,8 +73,7 @@ static const GLubyte *i810GetString( GLcontext *ctx, GLenum name ) } } -static void i810BufferSize(GLframebuffer *buffer, - GLuint *width, GLuint *height) +static void i810BufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) { GET_CURRENT_CONTEXT(ctx); i810ContextPtr imesa = I810_CONTEXT(ctx); @@ -126,7 +125,7 @@ i810CreateContext( Display *dpy, const __GLcontextModes *mesaVis, i810ContextPtr imesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private; - drm_i810_sarea_t *saPriv = (drm_i810_sarea_t *) + I810SAREAPtr saPriv = (I810SAREAPtr) (((GLubyte *)sPriv->pSAREA) + i810Screen->sarea_priv_offset); /* Allocate i810 context */ @@ -175,6 +174,7 @@ i810CreateContext( Display *dpy, const __GLcontextModes *mesaVis, ctx->Const.PointSizeGranularity = 1.0; ctx->Driver.GetBufferSize = i810BufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; ctx->Driver.GetString = i810GetString; /* Who owns who? @@ -300,13 +300,12 @@ void i810XMesaSetBackClipRects( i810ContextPtr imesa ) static void i810XMesaWindowMoved( i810ContextPtr imesa ) { switch (imesa->glCtx->Color.DriverDrawBuffer) { - case GL_FRONT_LEFT: - i810XMesaSetFrontClipRects( imesa ); - break; case GL_BACK_LEFT: i810XMesaSetBackClipRects( imesa ); break; + case GL_FRONT_LEFT: default: + i810XMesaSetFrontClipRects( imesa ); break; } @@ -335,14 +334,14 @@ i810MakeCurrent(__DRIcontextPrivate *driContextPriv, if (driContextPriv) { i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate; - _mesa_make_current2(imesa->glCtx, - (GLframebuffer *) driDrawPriv->driverPrivate, - (GLframebuffer *) driReadPriv->driverPrivate); - /* Shouldn't the readbuffer be stored also? */ imesa->driDrawable = driDrawPriv; + _mesa_make_current2(imesa->glCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate); + /* Are these necessary? */ i810XMesaWindowMoved( imesa ); @@ -362,7 +361,7 @@ void i810GetLock( i810ContextPtr imesa, GLuint flags ) { __DRIdrawablePrivate *dPriv = imesa->driDrawable; __DRIscreenPrivate *sPriv = imesa->driScreen; - drm_i810_sarea_t *sarea = imesa->sarea; + I810SAREAPtr sarea = imesa->sarea; int me = imesa->hHWContext; drmGetLock(imesa->driFd, imesa->hHWContext, flags); diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.h b/xc/lib/GL/mesa/src/drv/i810/i810context.h index 0a40c374f..ad0532cff 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810context.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810context.h @@ -21,7 +21,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810context.h,v 1.7 2002/02/22 21:33:03 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810context.h,v 1.9 2002/12/16 16:18:51 dawes Exp $ */ #ifndef I810CONTEXT_INC #define I810CONTEXT_INC @@ -33,7 +33,6 @@ typedef struct i810_texture_object_t *i810TextureObjectPtr; #include <X11/Xlibint.h> #include "mtypes.h" -#include "drm.h" #include "mm.h" #include "i810screen.h" @@ -134,7 +133,7 @@ struct i810_context_t { GLuint BufferSetup[I810_DEST_SETUP_SIZE]; int vertex_size; int vertex_stride_shift; - GLint lastStamp; + unsigned int lastStamp; GLboolean stipple_in_hw; GLenum TexEnvImageFmt[2]; @@ -170,8 +169,8 @@ struct i810_context_t { int dirtyAge; GLboolean scissor; - drm_clip_rect_t draw_rect; - drm_clip_rect_t scissor_rect; + XF86DRIClipRectRec draw_rect; + XF86DRIClipRectRec scissor_rect; drmContext hHWContext; drmLock *driHwLock; @@ -181,7 +180,7 @@ struct i810_context_t { __DRIdrawablePrivate *driDrawable; __DRIscreenPrivate *driScreen; i810ScreenPrivate *i810Screen; - drm_i810_sarea_t *sarea; + I810SAREAPtr sarea; }; diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c index 4ac686f03..1f8a56000 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.c,v 1.6 2002/02/22 21:33:03 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.c,v 1.7 2002/10/30 12:51:33 alanh Exp $ */ #include <stdio.h> #include <unistd.h> @@ -8,29 +8,30 @@ #include "macros.h" #include "dd.h" #include "swrast/swrast.h" - #include "mm.h" + +#include "i810screen.h" +#include "i810_dri.h" + #include "i810context.h" #include "i810ioctl.h" #include "i810state.h" -#include "drm.h" -#include <sys/ioctl.h> - static drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa ) { - drm_i810_dma_t dma; + drmI810DMA dma; drmBufPtr buf; int retcode, i = 0; while (1) { - retcode = ioctl(imesa->driFd, DRM_IOCTL_I810_GETBUF, &dma); + retcode = drmCommandWriteRead(imesa->driFd, DRM_I810_GETBUF, + &dma, sizeof(drmI810DMA)); if (dma.granted == 1 && retcode == 0) break; if (++i > 1000) { - ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH); + drmCommandNone(imesa->driFd, DRM_I810_FLUSH); i = 0; } } @@ -54,7 +55,7 @@ static void i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, i810ContextPtr imesa = I810_CONTEXT( ctx ); __DRIdrawablePrivate *dPriv = imesa->driDrawable; const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); - drm_i810_clear_t clear; + drmI810Clear clear; int i; clear.flags = 0; @@ -90,8 +91,8 @@ static void i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, for (i = 0 ; i < imesa->numClipRects ; ) { int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, imesa->numClipRects); - XF86DRIClipRectRec *box = imesa->pClipRects; - drm_clip_rect_t *b = imesa->sarea->boxes; + XF86DRIClipRectPtr box = imesa->pClipRects; + XF86DRIClipRectPtr b = imesa->sarea->boxes; int n = 0; if (!all) { @@ -117,13 +118,14 @@ static void i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, } } else { for ( ; i < nr ; i++) { - *b++ = *(drm_clip_rect_t *)&box[i]; + *b++ = *(XF86DRIClipRectPtr)&box[i]; n++; } } imesa->sarea->nbox = n; - ioctl(imesa->driFd, DRM_IOCTL_I810_CLEAR, &clear); + drmCommandWrite(imesa->driFd, DRM_I810_CLEAR, + &clear, sizeof(drmI810Clear)); } UNLOCK_HARDWARE( imesa ); @@ -168,7 +170,7 @@ void i810CopyBuffer( const __DRIdrawablePrivate *dPriv ) for ( ; i < nr ; i++) *b++ = pbox[i]; - ioctl(imesa->driFd, DRM_IOCTL_I810_SWAP); + drmCommandNone(imesa->driFd, DRM_I810_SWAP); } tmp = GET_ENQUEUE_AGE(imesa); @@ -219,14 +221,14 @@ void i810WaitAgeLocked( i810ContextPtr imesa, int age ) int i = 0, j; while (++i < 5000) { - ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE); + drmCommandNone(imesa->driFd, DRM_I810_GETAGE); if (GET_DISPATCH_AGE(imesa) >= age) return; for (j = 0 ; j < 1000 ; j++) ; } - ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH); + drmCommandNone(imesa->driFd, DRM_I810_FLUSH); } @@ -235,7 +237,7 @@ void i810WaitAge( i810ContextPtr imesa, int age ) int i = 0, j; while (++i < 5000) { - ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE); + drmCommandNone(imesa->driFd, DRM_I810_GETAGE); if (GET_DISPATCH_AGE(imesa) >= age) return; for (j = 0 ; j < 1000 ; j++) @@ -244,23 +246,23 @@ void i810WaitAge( i810ContextPtr imesa, int age ) i = 0; while (++i < 1000) { - ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE); + drmCommandNone(imesa->driFd, DRM_I810_GETAGE); if (GET_DISPATCH_AGE(imesa) >= age) return; usleep(1000); } LOCK_HARDWARE(imesa); - ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH); + drmCommandNone(imesa->driFd, DRM_I810_FLUSH); UNLOCK_HARDWARE(imesa); } -static int intersect_rect( drm_clip_rect_t *out, - drm_clip_rect_t *a, - drm_clip_rect_t *b ) +static int intersect_rect( XF86DRIClipRectPtr out, + XF86DRIClipRectPtr a, + XF86DRIClipRectPtr b ) { *out = *a; if (b->x1 > out->x1) out->x1 = b->x1; @@ -277,7 +279,7 @@ static int intersect_rect( drm_clip_rect_t *out, static void emit_state( i810ContextPtr imesa ) { GLuint dirty = imesa->dirty; - drm_i810_sarea_t *sarea = imesa->sarea; + I810SAREAPtr sarea = imesa->sarea; if (dirty & I810_UPLOAD_BUFFERS) { memcpy( sarea->BufferState, imesa->BufferSetup, @@ -326,11 +328,11 @@ static void age_imesa( i810ContextPtr imesa, int age ) void i810FlushPrimsLocked( i810ContextPtr imesa ) { - drm_clip_rect_t *pbox = (drm_clip_rect_t *)imesa->pClipRects; + XF86DRIClipRectPtr pbox = (XF86DRIClipRectPtr)imesa->pClipRects; int nbox = imesa->numClipRects; drmBufPtr buffer = imesa->vertex_buffer; - drm_i810_sarea_t *sarea = imesa->sarea; - drm_i810_vertex_t vertex; + I810SAREAPtr sarea = imesa->sarea; + drmI810Vertex vertex; int i; if (imesa->dirty) @@ -356,7 +358,8 @@ void i810FlushPrimsLocked( i810ContextPtr imesa ) sarea->nbox = nbox; vertex.discard = 1; - ioctl(imesa->driFd, DRM_IOCTL_I810_VERTEX, &vertex); + drmCommandWrite(imesa->driFd, DRM_I810_VERTEX, + &vertex, sizeof(drmI810Vertex)); age_imesa(imesa, sarea->last_enqueue); } else @@ -364,7 +367,7 @@ void i810FlushPrimsLocked( i810ContextPtr imesa ) for (i = 0 ; i < nbox ; ) { int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, nbox); - drm_clip_rect_t *b = sarea->boxes; + XF86DRIClipRectPtr b = sarea->boxes; if (imesa->scissor) { sarea->nbox = 0; @@ -402,7 +405,8 @@ void i810FlushPrimsLocked( i810ContextPtr imesa ) if (nr == nbox) vertex.discard = 1; - ioctl(imesa->driFd, DRM_IOCTL_I810_VERTEX, &vertex); + drmCommandWrite(imesa->driFd, DRM_I810_VERTEX, + &vertex, sizeof(drmI810Vertex)); age_imesa(imesa, imesa->sarea->last_enqueue); } } @@ -447,7 +451,7 @@ void i810FlushPrims( i810ContextPtr imesa ) int i810_check_copy(int fd) { - return(ioctl(fd, DRM_IOCTL_I810_DOCOPY)); + return(drmCommandNone(fd, DRM_I810_DOCOPY)); } static void i810Flush( GLcontext *ctx ) diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h index 1eb5bf45a..e287b57b1 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h @@ -1,11 +1,10 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.h,v 1.6 2002/02/22 21:33:03 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.h,v 1.7 2002/10/30 12:51:33 alanh Exp $ */ #ifndef I810_IOCTL_H #define I810_IOCTL_H #include "i810context.h" - void i810EmitPrim( i810ContextPtr imesa ); void i810FlushPrims( i810ContextPtr mmesa ); void i810FlushPrimsLocked( i810ContextPtr mmesa ); diff --git a/xc/lib/GL/mesa/src/drv/i810/i810render.c b/xc/lib/GL/mesa/src/drv/i810/i810render.c index fba9b24d0..b13adeffd 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810render.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810render.c @@ -1,5 +1,3 @@ -/* $Id: i810render.c,v 1.1.1.1 2002/10/22 13:00:16 alanh Exp $ */ - /* * Intel i810 DRI driver for Mesa 3.5 * @@ -24,7 +22,7 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Author: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ @@ -42,6 +40,9 @@ #include "tnl/t_context.h" +#include "i810screen.h" +#include "i810_dri.h" + #include "i810context.h" #include "i810tris.h" #include "i810state.h" diff --git a/xc/lib/GL/mesa/src/drv/i810/i810screen.c b/xc/lib/GL/mesa/src/drv/i810/i810screen.c index adf487b98..a15df1f15 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810screen.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810screen.c @@ -24,11 +24,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810screen.c,v 1.1 2002/02/22 21:33:04 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810screen.c,v 1.2 2002/10/30 12:51:33 alanh Exp $ */ /* * Authors: - * Keith Whitwell <keithw@precisioninsight.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ @@ -41,14 +41,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "matrix.h" #include "simple_list.h" +#include "i810screen.h" +#include "i810_dri.h" + #include "i810state.h" #include "i810tex.h" #include "i810span.h" #include "i810tris.h" #include "i810ioctl.h" -#include "i810_dri.h" - /* static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */ diff --git a/xc/lib/GL/mesa/src/drv/i810/i810screen.h b/xc/lib/GL/mesa/src/drv/i810/i810screen.h index 26e0976a8..4aedbfd76 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810screen.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810screen.h @@ -27,7 +27,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Keith Whitwell <keithw@precisioninsight.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c index 6971eb145..f7ca9124c 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810span.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810span.c @@ -1,10 +1,15 @@ #include "glheader.h" #include "macros.h" #include "mtypes.h" + +#include "i810screen.h" +#include "i810_dri.h" + #include "i810span.h" #include "i810ioctl.h" #include "swrast/swrast.h" + #define DBG 0 #define LOCAL_VARS \ diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.c b/xc/lib/GL/mesa/src/drv/i810/i810state.c index 4ff952f36..eb5a3c0d7 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810state.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810state.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810state.c,v 1.8 2002/09/10 00:39:37 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810state.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */ #include <stdio.h> @@ -9,6 +9,10 @@ #include "dd.h" #include "mm.h" + +#include "i810screen.h" +#include "i810_dri.h" + #include "i810context.h" #include "i810state.h" #include "i810tex.h" @@ -969,7 +973,6 @@ void i810InitStateFuncs(GLcontext *ctx) ctx->Driver.CopyPixels = _swrast_CopyPixels; ctx->Driver.DrawPixels = _swrast_DrawPixels; ctx->Driver.ReadPixels = _swrast_ReadPixels; - ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; /* Swrast hooks for imaging extensions: */ diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c index 59e4671fd..9891e06e0 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tex.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c @@ -21,7 +21,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tex.c,v 1.8 2002/02/22 21:33:04 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tex.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */ #include <stdlib.h> #include <stdio.h> @@ -36,6 +36,10 @@ #include "swrast/swrast.h" #include "mm.h" + +#include "i810screen.h" +#include "i810_dri.h" + #include "i810context.h" #include "i810tex.h" #include "i810state.h" diff --git a/xc/lib/GL/mesa/src/drv/i810/i810texmem.c b/xc/lib/GL/mesa/src/drv/i810/i810texmem.c index a4467ec3c..05a4fe922 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810texmem.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810texmem.c @@ -32,6 +32,10 @@ #include "enums.h" #include "mm.h" + +#include "i810screen.h" +#include "i810_dri.h" + #include "i810context.h" #include "i810tex.h" #include "i810state.h" @@ -230,7 +234,7 @@ void i810PrintLocalLRU( i810ContextPtr imesa ) void i810PrintGlobalLRU( i810ContextPtr imesa ) { int i, j; - drm_i810_tex_region_t *list = imesa->sarea->texList; + I810TexRegionRec *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", @@ -246,7 +250,7 @@ void i810PrintGlobalLRU( i810ContextPtr imesa ) void i810ResetGlobalLRU( i810ContextPtr imesa ) { - drm_i810_tex_region_t *list = imesa->sarea->texList; + I810TexRegionRec *list = imesa->sarea->texList; int sz = 1 << imesa->i810Screen->logTextureGranularity; int i; @@ -278,7 +282,7 @@ void i810UpdateTexLRU( i810ContextPtr imesa, i810TextureObjectPtr t ) int logsz = imesa->i810Screen->logTextureGranularity; int start = t->MemBlock->ofs >> logsz; int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - drm_i810_tex_region_t *list = imesa->sarea->texList; + I810TexRegionRec *list = imesa->sarea->texList; imesa->texAge = ++imesa->sarea->texAge; diff --git a/xc/lib/GL/mesa/src/drv/i810/i810texstate.c b/xc/lib/GL/mesa/src/drv/i810/i810texstate.c index 2fdd336f6..0f0c58421 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810texstate.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810texstate.c @@ -32,6 +32,10 @@ #include "enums.h" #include "mm.h" + +#include "i810screen.h" +#include "i810_dri.h" + #include "i810context.h" #include "i810tex.h" #include "i810state.h" diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.c b/xc/lib/GL/mesa/src/drv/i810/i810tris.c index 0d9b0d995..d2d092955 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.c,v 1.6 2002/02/22 21:33:04 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.c,v 1.7 2002/10/30 12:51:33 alanh Exp $ */ /************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. @@ -28,7 +28,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #include <stdio.h> @@ -44,6 +44,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/t_context.h" #include "tnl/t_pipeline.h" +#include "i810screen.h" +#include "i810_dri.h" + #include "i810tris.h" #include "i810state.h" #include "i810vb.h" @@ -513,9 +516,9 @@ static void i810FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, int i,j; for (i = 2 ; i < n ; i++) { - COPY_DWORDS( j, vb, vertsize, start ); COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) ); COPY_DWORDS( j, vb, vertsize, V(elts[i]) ); + COPY_DWORDS( j, vb, vertsize, start ); } } @@ -523,6 +526,10 @@ static void i810FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, /* Choose render functions */ /**********************************************************************/ +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + #define _I810_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c index d5b817a72..7611c2cb1 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810vb.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c @@ -22,7 +22,7 @@ * * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.c,v 1.11 2002/09/10 00:39:37 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.c,v 1.12 2002/10/30 12:51:34 alanh Exp $ */ #include "glheader.h" #include "mtypes.h" @@ -34,6 +34,9 @@ #include "swrast_setup/swrast_setup.h" #include "tnl/t_context.h" +#include "i810screen.h" +#include "i810_dri.h" + #include "i810context.h" #include "i810vb.h" #include "i810ioctl.h" @@ -103,7 +106,7 @@ static struct { #define GET_VIEWPORT_MAT() I810_CONTEXT(ctx)->ViewportMatrix.m #define GET_TEXSOURCE(n) n #define GET_VERTEX_FORMAT() I810_CONTEXT(ctx)->Setup[I810_CTXREG_VF] -#define GET_VERTEX_STORE() (GLubyte *)(I810_CONTEXT(ctx)->verts) +#define GET_VERTEX_STORE() I810_CONTEXT(ctx)->verts #define GET_VERTEX_STRIDE_SHIFT() I810_CONTEXT(ctx)->vertex_stride_shift #define GET_UBYTE_COLOR_STORE() &I810_CONTEXT(ctx)->UbyteColor #define GET_UBYTE_SPEC_COLOR_STORE() &I810_CONTEXT(ctx)->UbyteSecondaryColor @@ -420,9 +423,9 @@ void i810ChooseVertexState( GLcontext *ctx ) if (ctx->Fog.Enabled) ind |= I810_FOG_BIT; - if (ctx->Texture._ReallyEnabled & 0xf0) + if (ctx->Texture._ReallyEnabled & TEXTURE1_ANY) ind |= I810_TEX1_BIT|I810_TEX0_BIT; - else if (ctx->Texture._ReallyEnabled & 0xf) + else if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY) ind |= I810_TEX0_BIT; imesa->SetupIndex = ind; diff --git a/xc/lib/GL/mesa/src/drv/i830/Imakefile b/xc/lib/GL/mesa/src/drv/i830/Imakefile index c5d312973..656255de5 100644 --- a/xc/lib/GL/mesa/src/drv/i830/Imakefile +++ b/xc/lib/GL/mesa/src/drv/i830/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i830/Imakefile,v 1.4 2002/09/11 00:29:24 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i830/Imakefile,v 1.7 2002/11/25 14:04:51 eich Exp $ #include <Threads.tmpl> @@ -25,20 +25,11 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i830/Imakefile,v 1.4 2002/09/11 00:29:24 #include "../../tnl/Imakefile.inc" #include "../../tnl_dd/Imakefile.inc" #include "../../Imakefile.inc" -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #include "../../X86/Imakefile.inc" #endif -#ifndef HaveDrmCommand -#define HaveDrmCommand NO -#endif - -#if HaveDrmCommand -DRMCOMMAND_DEFINES = -DHAVE_DRM_COMMAND -#endif - - DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(MESA_ASM_DEFINES) \ - $(DRMCOMMAND_DEFINES) + DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(MESA_ASM_DEFINES) INCLUDES = $(X_INCLUDES) $(MESA_INCLUDES) $(DRI_INCLUDES) diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h b/xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h index fd1c5be82..5cc73d6b3 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h,v 1.3 2002/09/09 19:18:47 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h,v 1.4 2002/12/10 01:26:53 dawes Exp $ */ #define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) #define CMD_3D (0x3<<29) @@ -325,163 +325,8 @@ /* STATE3D_MAP_CUBE, p168 TODO */ -/* STATE3D_MAP_FILTER, p169 */ -#define STATE3D_MAP_FILTER_CMD (CMD_3D|(0x1c<<24)|(0x02<<19)) -#define ENABLE_CHROMA_KEY_PARAMS (1<<15) -#define ENABLE_TEXCOLOR_KEY (1<<14) -#define ENABLE_TEXCHROMA_KEY (1<<13) -#define ENABLE_TEXKILLPIX_KEY (1<<12) -#define KEYFILTER_KILL_ON_ANY_MATCH 0 -#define KEYFILTER_KILL_ON_ANY_MISMATCH (1<<11) -#define KEYFILTER_REPLACE_BLACK 0 -#define KEYFILTER_REPLACE_NEAREST (1<<11) -#define ENABLE_MIP_MODE_FILTER (1<<9) -#define MIPFILTER_NONE 0 -#define MIPFILTER_NEAREST (1<<6) -#define MIPFILTER_LINEAR (3<<6) -#define ENABLE_MAG_MODE_FILTER (1<<5) -#define ENABLE_MIN_MODE_FILTER (1<<2) -#define MAG_FILTER(x) ((x)<<3) -#define MIN_FILTER(x) (x) -#define MIP_FILTER_MASK (0x3<<6) -#define MAG_FILTER_MASK (0x3<<3) -#define MIN_FILTER_MASK (0x3<<0) - -#define FILTER_NEAREST 0 -#define FILTER_LINEAR 1 -#define FILTER_ANISOTROPIC 2 - -/* STATE3D_MAP_INFO, p172 */ -#define STATE3D_MAP_INFO_NOCOLR_CMD (CMD_3D|(0x1d<<24)|3) - -#define STATE3D_MAP_INFO_COLR_CMD (CMD_3D|(0x1d<<24)|4) -/* Dword 1 */ -#define MAP_INFO_TEX(unit) ((unit)<<28) -#define MAP_INFO_MASK (3<<28) - -#define MI_FORMAT_MASK ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)) - -#define MAPSURF_8BIT_INDEXED 0 -#define MAPSURF_8BIT (1<<24) -#define MAPSURF_16BIT (2<<24) -#define MAPSURF_32BIT (3<<24) -#define MAPSURF_411 (4<<24) -#define MAPSURF_422 (5<<24) -#define MAPSURF_COMPRESSED (6<<24) -#define MAPSURF_4BIT_INDEXED (7<<24) - -/* Texel formats */ -/* MAPSURF_4BIT_INDEXED */ -#define MT_4BIT_IDX_ARGB8888 (7<<21) - -/* MAPSURF_8BIT_INDEXED */ -#define MT_8BIT_IDX_RGB565 0 -#define MT_8BIT_IDX_ARGB1555 (1<<21) -#define MT_8BIT_IDX_ARGB4444 (2<<21) -#define MT_8BIT_IDX_AY88 (3<<21) -#define MT_8BIT_IDX_ABGR8888 (4<<21) -#define MT_8BIT_IDX_BUMP_88DVDU (5<<21) -#define MT_8BIT_IDX_BUMP_655LDVDU (6<<21) -#define MT_8BIT_IDX_ARGB8888 (7<<21) - -/* MAPSURF_8BIT */ -#define MT_8BIT_I8 0 -#define MT_8BIT_L8 (1<<21) - -/* MAPSURF_16BIT */ -#define MT_16BIT_RGB565 0 -#define MT_16BIT_ARGB1555 (1<<21) -#define MT_16BIT_ARGB4444 (2<<21) -#define MT_16BIT_AY88 (3<<21) -#define MT_16BIT_DIB_ARGB1555_8888 (4<<21) -#define MT_16BIT_BUMP_88DVDU (5<<21) -#define MT_16BIT_BUMP_655LDVDU (6<<21) -#define MT_16BIT_DIB_RGB565_8888 (7<<21) - -/* MAPSURF_32BIT */ -#define MT_32BIT_ARGB8888 0 -#define MT_32BIT_ABGR8888 (1<<21) -#define MT_32BIT_BUMP_XLDVDU_8888 (6<<21) -#define MT_32BIT_DIB_8888 (7<<21) - -/* MAPSURF_411 */ -#define MT_411_YUV411 0 - -/* MAPSURF_422 */ -#define MT_422_YCRCB_SWAPY 0 -#define MT_422_YCRCB_NORMAL (1<<21) -#define MT_422_YCRCB_SWAPUV (2<<21) -#define MT_422_YCRCB_SWAPUVY (3<<21) - -/* MAPSURF_COMPRESSED */ -#define MT_COMPRESS_DXT1 0 -#define MT_COMPRESS_DXT2_3 (1<<21) -#define MT_COMPRESS_DXT4_5 (2<<21) -#define MT_COMPRESS_FXT1 (3<<21) - -#define MAP_INFO_OUTMUX_F0F1F2F3 0 -#define MAP_INFO_OUTMUX_XXF0XXF3 (1<<19) -#define MAP_INFO_OUTMUX_XXF2XXF3 (2<<19) - -#define ENABLE_TEX_COLORSPACE_CONV (1<<18) -#define MAP_INFO_VERTLINESTRIDE_0 0 -#define MAP_INFO_VERTLINESTRIDE_1 (1<<17) -#define MAP_INFO_VERTLINESTRIDEOFS_0 0 -#define MAP_INFO_VERTLINESTRIDEOFS_1 (1<<16) -#define MAP_INFO_FORMAT_2D 0 -#define MAP_INFO_FORMAT_3D (1<<11) -#define MAP_INFO_USE_FENCE (1<<10) -#define MAP_INFO_IS_TILED (1<<9) -#define MAP_INFO_IS_LINEAR 0 -#define MAP_INFO_TILEWALK_XMAJOR 0 -#define MAP_INFO_TILEWALK_YMAJOR (1<<8) -#define MAP_INFO_USE_PALETTE_0 0 -#define MAP_INFO_USE_PALETTE_1 (1<<4) -#define MAP_INFO_USE_PALETTE_N(x) ((x<<4) & (1<<4)) - -/* Dword 2 */ -#define MAP_INFO_HEIGHT(x) ((x)<<16) -#define MAP_INFO_WIDTH(x) (x) - -/* Dword 3 */ -#define MAP_INFO_BASEADDR(x) ((x)&0x3) -/* Dword 4 */ -#define MAP_INFO_DWORD_PITCH(x) ((x)<<2) - -/* Dword 5 */ -#define MAP_INFO_DFLT_COLR(x) (x) - -/* STATE3D_MAP_LOD_CONTROL, p180 */ -#define STATE3D_MAP_LOD_CNTL_CMD (CMD_3D|(0x1c<<24)|(0x04<<19)) -#define ENABLE_TEXLOD_BIAS (1<<7) -#define MAP_LOD_MASK (0x7f) -#define MAP_LOD_BIAS(x) (x) - -/* STATE3D_MAP_LOD_LIMITS, p181 */ -#define STATE3D_MAP_LOD_LIMITS_CMD (CMD_3D|(0x1c<<24)|(0x03<<19)) -#define ENABLE_MAX_MIP_LVL (1<<13) -#define ENABLE_MIN_MIP_LVL (1<<4) -#define LOD_MAX(x) ((x)<<5) -#define LOD_MIN(x) (x) -#define LOD_MAX_MASK (0x1fe0) -#define LOD_MIN_MASK (0xf) - -/* STATE3D_MAP_PALETTE_LOAD, p183 TODO */ -/* STATE3D_MAP_PALETTE_LOAD_32, p184 TODO */ -/* STATE3D_MAP_STREAM_MODIFIER, p186 TODO */ - -/* STATE3D_MAP_TEXEL_STREAM, p188 */ -#define STATE3D_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) -#define DISABLE_TEX_STREAM_BUMP (1<<12) -#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) -#define TEX_MODIFY_UNIT_0 0 -#define TEX_MODIFY_UNIT_1 (1<<8) -#define ENABLE_TEX_STREAM_COORD_SET (1<<7) -#define TEX_STREAM_COORD_SET(x) ((x)<<4) -#define ENABLE_TEX_STREAM_MAP_IDX (1<<3) -#define TEX_STREAM_MAP_IDX(x) (x) /* STATE3D_MODES_1, p190 */ #define STATE3D_MODES_1_CMD (CMD_3D|(0x08<<24)) @@ -722,62 +567,111 @@ #define I830PACKCOLOR8888(r,g,b,a) \ ((a<<24) | (r<<16) | (g<<8) | b) -#if 0 -/* We wont ever use this format, since we will never be using - * more then 4 texture coords. It is here for reference. + +/* Stipple command, carried over from the i810, apparently: */ +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + + + +#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) + +#define TM0S0_ADDRESS_MASK 0xfffffffc +#define TM0S0_USE_FENCE (1<<1) + +#define TM0S1_HEIGHT_SHIFT 21 +#define TM0S1_WIDTH_SHIFT 10 +#define TM0S1_PALETTE_SELECT (1<<9) +#define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) +#define TM0S1_MAPSURF_FORMAT_SHIFT 6 +#define MAPSURF_8BIT_INDEXED (0<<6) +#define MAPSURF_8BIT (1<<6) +#define MAPSURF_16BIT (2<<6) +#define MAPSURF_32BIT (3<<6) +#define MAPSURF_411 (4<<6) +#define MAPSURF_422 (5<<6) +#define MAPSURF_COMPRESSED (6<<6) +#define MAPSURF_4BIT_INDEXED (7<<6) +#define TM0S1_MT_FORMAT_MASK (0x7 << 3) +#define TM0S1_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ +#define MT_8BIT_IDX_ARGB1555 (1<<3) +#define MT_8BIT_IDX_ARGB4444 (2<<3) +#define MT_8BIT_IDX_AY88 (3<<3) +#define MT_8BIT_IDX_ABGR8888 (4<<3) +#define MT_8BIT_IDX_BUMP_88DVDU (5<<3) +#define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) +#define MT_8BIT_IDX_ARGB8888 (7<<3) +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_DIB_ARGB1555_8888 (4<<3) +#define MT_16BIT_BUMP_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_DIB_RGB565_8888 (7<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) +#define MT_32BIT_DIB_8888 (7<<3) +#define MT_411_YUV411 (0<<3) /* SURFACE_411 */ +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define TM0S1_COLORSPACE_CONVERSION (1 << 2) +#define TM0S1_TILED_SURFACE (1 << 1) +#define TM0S1_TILE_WALK (1 << 0) + +#define TM0S2_PITCH_SHIFT 21 +#define TM0S2_CUBE_FACE_ENA_SHIFT 15 +#define TM0S2_MAP_FORMAT (1<<14) +#define TM0S2_VERTICAL_LINE_STRIDE (1<<13) +#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) +#define TM0S2_OUTPUT_CHAN_SHIFT 10 +#define TM0S2_OUTPUT_CHAN_MASK (3<<10) + +#define TM0S3_MIP_FILTER_MASK (0x3<<30) +#define TM0S3_MIP_FILTER_SHIFT 30 +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define TM0S3_MAG_FILTER_MASK (0x3<<28) +#define TM0S3_MAG_FILTER_SHIFT 28 +#define TM0S3_MIN_FILTER_MASK (0x3<<26) +#define TM0S3_MIN_FILTER_SHIFT 26 +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 + +#define TM0S3_LOD_BIAS_SHIFT 17 +#define TM0S3_LOD_BIAS_MASK (0x1ff<<17) +#define TM0S3_MAX_MIP_SHIFT 9 +#define TM0S3_MAX_MIP_MASK (0xff<<9) +#define TM0S3_MIN_MIP_SHIFT 3 +#define TM0S3_MIN_MIP_MASK (0x3f<<3) +#define TM0S3_KILL_PIXEL (1<<2) +#define TM0S3_KEYED_FILTER (1<<1) +#define TM0S3_CHROMA_KEY (1<<0) -typedef struct { - float x; - float y; - float z; - float z_bias; - union { - float w; - float rhw; - } w; - float point_width; - unsigned int argb; - unsigned int fog_spec_rgb; - - float tu0; - float tv0; - float tq0; - float t_4_0; - - float tu1; - float tv1; - float tq1; - float t_4_1; - - float tu2; - float tv2; - float tq2; - float t_4_2; - - float tu3; - float tv3; - float tq3; - float t_4_3; - - float tu4; - float tv4; - float tq4; - float t_4_4; - - float tu5; - float tv5; - float tq5; - float t_4_5; - - float tu6; - float tv6; - float tq6; - float t_4_6; - - float tu7; - float tv7; - float tq7; - float t_4_7; -} i830_full_vertex; -#endif + +/* STATE3D_MAP_TEXEL_STREAM, p188 */ +#define STATE3D_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) +#define DISABLE_TEX_STREAM_BUMP (1<<12) +#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) +#define TEX_MODIFY_UNIT_0 0 +#define TEX_MODIFY_UNIT_1 (1<<8) +#define ENABLE_TEX_STREAM_COORD_SET (1<<7) +#define TEX_STREAM_COORD_SET(x) ((x)<<4) +#define ENABLE_TEX_STREAM_MAP_IDX (1<<3) +#define TEX_STREAM_MAP_IDX(x) (x) diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_context.c b/xc/lib/GL/mesa/src/drv/i830/i830_context.c index 6b1b3ef6d..a0dae5a41 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_context.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_context.c @@ -24,7 +24,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_context.c,v 1.4 2002/09/12 02:20:08 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_context.c,v 1.9 2003/02/06 04:18:00 dawes Exp $ */ /* * Authors: @@ -72,9 +72,7 @@ int I830_DEBUG = (0); * Mesa's Driver Functions ***************************************/ -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define DRIVER_DATE "20020803" +#define DRIVER_DATE "20021115" static const GLubyte *i830DDGetString( GLcontext *ctx, GLenum name ) { @@ -84,7 +82,7 @@ static const GLubyte *i830DDGetString( GLcontext *ctx, GLenum name ) case GL_VENDOR: return (GLubyte *)"2d3D, Inc"; case GL_RENDERER: - return (GLubyte *)"Mesa DRI I845 " DRIVER_DATE; + return (GLubyte *)"Mesa DRI Intel(R) 845G " DRIVER_DATE; default: return 0; } @@ -94,13 +92,41 @@ static const GLubyte *i830DDGetString( GLcontext *ctx, GLenum name ) case GL_VENDOR: return (GLubyte *)"VA Linux, Inc"; case GL_RENDERER: - return (GLubyte *)"Mesa DRI I830 " DRIVER_DATE; + return (GLubyte *)"Mesa DRI Intel(R) 830M " DRIVER_DATE; + default: + return 0; + } + break; + case PCI_CHIP_I855_GM: + switch (name) { + case GL_VENDOR: + return (GLubyte *)"Tungsten Graphics, Inc"; + case GL_RENDERER: + return (GLubyte *)"Mesa DRI Intel(R) 852GM/855GM " DRIVER_DATE; + default: + return 0; + } + break; + case PCI_CHIP_I865_G: + switch (name) { + case GL_VENDOR: + return (GLubyte *)"Tungsten Graphics, Inc"; + case GL_RENDERER: + return (GLubyte *)"Mesa DRI Intel(R) 865G " DRIVER_DATE; default: return 0; } break; default: - return 0; + switch (name) { + case GL_VENDOR: + return (GLubyte *)"Tungsten Graphics, Inc"; + case GL_RENDERER: + return (GLubyte *)"Mesa DRI Unknown Intel Chipset " DRIVER_DATE; + default: + return 0; + } + break; } } @@ -126,8 +152,8 @@ static void i830InitExtensions( GLcontext *ctx ) _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" ); _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); - _mesa_enable_extension( ctx, "GL_ARB_texture_env_combine" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); + _mesa_enable_extension( ctx, "GL_ARB_texture_env_combine" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); _mesa_enable_extension( ctx, "GL_EXT_blend_color" ); _mesa_enable_extension( ctx, "GL_EXT_blend_minmax" ); _mesa_enable_extension( ctx, "GL_EXT_blend_subtract" ); @@ -325,8 +351,10 @@ GLboolean i830CreateContext( Display *dpy, const __GLcontextModes *mesaVis, imesa->CurrentTexObj[0] = 0; imesa->CurrentTexObj[1] = 0; - _math_matrix_ctr (&imesa->ViewportMatrix); + imesa->do_irqs = (imesa->i830Screen->irq_active && + !getenv("I830_NO_IRQS")); + _math_matrix_ctr (&imesa->ViewportMatrix); i830InitExtensions (ctx); i830DDInitStateFuncs( ctx ); @@ -344,6 +372,12 @@ GLboolean i830CreateContext( Display *dpy, const __GLcontextModes *mesaVis, add_debug_flags( getenv("I830_DEBUG") ); #endif + if (getenv("I830_NO_RAST") || + getenv("INTEL_NO_RAST")) { + fprintf(stderr, "disabling 3D rasterization\n"); + FALLBACK(imesa, I830_FALLBACK_USER, 1); + } + return GL_TRUE; } @@ -386,7 +420,7 @@ void i830XMesaSetBackClipRects( i830ContextPtr imesa ) { __DRIdrawablePrivate *dPriv = imesa->driDrawable; - if (dPriv->numBackClipRects == 0) { + if (imesa->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) { imesa->numClipRects = dPriv->numClipRects; imesa->pClipRects = dPriv->pClipRects; imesa->drawX = dPriv->x; @@ -421,10 +455,11 @@ GLboolean i830UnbindContext(__DRIcontextPrivate *driContextPriv) i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate; if (imesa) { /* Might want to change this so texblend isn't always updated */ - imesa->dirty = (I830_UPLOAD_CTX | - I830_UPLOAD_BUFFERS | - I830_UPLOAD_TEXBLEND0 | - I830_UPLOAD_TEXBLEND1); + imesa->dirty |= (I830_UPLOAD_CTX | + I830_UPLOAD_BUFFERS | + I830_UPLOAD_STIPPLE | + I830_UPLOAD_TEXBLEND0 | + I830_UPLOAD_TEXBLEND1); if (imesa->CurrentTexObj[0]) imesa->dirty |= I830_UPLOAD_TEX0; if (imesa->CurrentTexObj[1]) imesa->dirty |= I830_UPLOAD_TEX1; @@ -460,6 +495,41 @@ GLboolean i830MakeCurrent(__DRIcontextPrivate *driContextPriv, return GL_TRUE; } +/* Turn on/off page flipping according to the flags in the sarea: + */ +static void +i830UpdatePageFlipping( i830ContextPtr imesa ) +{ + GLcontext *ctx = imesa->glCtx; + int front = 0; + + switch (ctx->Color.DriverDrawBuffer) { + case GL_FRONT_LEFT: + front = 1; + break; + case GL_BACK_LEFT: + front = 0; + break; + default: + return; + } + + if ( imesa->sarea->pf_current_page == 1 ) + front ^= 1; + + if (front) { + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->fbOffset; + imesa->drawMap = (char *)imesa->driScreen->pFB; + imesa->readMap = (char *)imesa->driScreen->pFB; + } else { + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->backOffset; + imesa->drawMap = imesa->i830Screen->back.map; + imesa->readMap = imesa->i830Screen->back.map; + } + + imesa->dirty |= I830_UPLOAD_BUFFERS; +} + void i830GetLock( i830ContextPtr imesa, GLuint flags ) { __DRIdrawablePrivate *dPriv = imesa->driDrawable; @@ -485,13 +555,15 @@ void i830GetLock( i830ContextPtr imesa, GLuint flags ) if (sarea->ctxOwner != me) { imesa->upload_cliprects = GL_TRUE; imesa->dirty |= (I830_UPLOAD_CTX | - I830_UPLOAD_BUFFERS); + I830_UPLOAD_BUFFERS | + I830_UPLOAD_STIPPLE); if(imesa->CurrentTexObj[0]) imesa->dirty |= I830_UPLOAD_TEX0; if(imesa->CurrentTexObj[1]) imesa->dirty |= I830_UPLOAD_TEX1; if(imesa->TexBlendWordsUsed[0]) imesa->dirty |= I830_UPLOAD_TEXBLEND0; if(imesa->TexBlendWordsUsed[1]) imesa->dirty |= I830_UPLOAD_TEXBLEND1; + sarea->perf_boxes = imesa->perf_boxes | I830_BOX_LOST_CONTEXT; sarea->ctxOwner = me; } @@ -522,6 +594,7 @@ void i830GetLock( i830ContextPtr imesa, GLuint flags ) } if (imesa->lastStamp != dPriv->lastStamp) { + i830UpdatePageFlipping( imesa ); i830XMesaWindowMoved( imesa ); imesa->lastStamp = dPriv->lastStamp; } @@ -539,8 +612,10 @@ void i830SwapBuffers(Display *dpy, void *drawablePrivate) imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate; ctx = imesa->glCtx; if (ctx->Visual.doubleBufferMode) { - _mesa_swapbuffers( ctx ); /* flush pending rendering comands */ - if ( imesa->doPageFlip ) { + /* flush pending rendering comands */ + _mesa_swapbuffers( ctx ); + if ( imesa->sarea->pf_active && + (dPriv->w * dPriv->h * imesa->i830Screen->cpp) > (300*300*4) ) { i830PageFlip( dPriv ); } else { i830CopyBuffer( dPriv ); diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_context.h b/xc/lib/GL/mesa/src/drv/i830/i830_context.h index c6adc86d3..a4e27d75d 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_context.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_context.h @@ -25,7 +25,7 @@ /* Adapted for use in the I830M driver: * Jeff Hartmann <jhartmann@2d3d.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_context.h,v 1.2 2002/09/11 00:29:25 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_context.h,v 1.7 2003/02/06 04:18:01 dawes Exp $ */ #ifndef I830CONTEXT_INC #define I830CONTEXT_INC @@ -165,10 +165,11 @@ struct i830_context_t GLuint dirty; /* I810_UPLOAD_* */ GLuint Setup[I830_CTX_SETUP_SIZE]; GLuint BufferSetup[I830_DEST_SETUP_SIZE]; + GLuint StippleSetup[I830_STP_SETUP_SIZE]; int vertex_size; int vertex_stride_shift; - GLint lastStamp; - GLboolean stipple_in_hw; + unsigned int lastStamp; + GLboolean hw_stipple; GLenum TexEnvImageFmt[2]; @@ -186,7 +187,6 @@ struct i830_context_t */ GLuint needClip; GLframebuffer *glBuffer; - GLboolean doPageFlip; /* These refer to the current draw (front vs. back) buffer: */ @@ -201,7 +201,10 @@ struct i830_context_t int texAge; int ctxAge; int dirtyAge; + int perf_boxes; + int do_irqs; + GLboolean scissor; XF86DRIClipRectRec draw_rect; XF86DRIClipRectRec scissor_rect; @@ -241,9 +244,11 @@ do { \ /* Unlock the hardware using the global current context */ -#define UNLOCK_HARDWARE(imesa) \ - DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext); - +#define UNLOCK_HARDWARE(imesa) \ +do { \ + imesa->perf_boxes |= imesa->sarea->perf_boxes; \ + DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext); \ +} while (0) /* This is the wrong way to do it, I'm sure. Otherwise the drm * bitches that I've already got the heavyweight lock. At worst, @@ -292,6 +297,13 @@ extern int I830_DEBUG; #define DEBUG_SANITY 0x200 #define DEBUG_SYNC 0x400 #define DEBUG_SLEEP 0x800 + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 + #endif diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_debug.c b/xc/lib/GL/mesa/src/drv/i830/i830_debug.c index fef802f8d..09dca2a5f 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_debug.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_debug.c @@ -25,7 +25,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_debug.c,v 1.2 2002/09/11 00:29:25 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_debug.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ /* * Author: @@ -140,6 +140,14 @@ void i830DumpBufferState( i830ContextPtr imesa ) fprintf(stderr, "DR4 : 0x%08x\n", Buffer[I830_DESTREG_DR4]); } +void i830DumpStippleState( i830ContextPtr imesa ) +{ + GLuint *Buffer = imesa->BufferSetup; + + fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "ST1 : 0x%08x\n", Buffer[I830_STPREG_ST1]); +} + void i830DumpTextureState( i830ContextPtr imesa, int unit ) { i830TextureObjectPtr t = imesa->CurrentTexObj[unit]; @@ -341,6 +349,13 @@ void i830EmitHwStateLockedDebug( i830ContextPtr imesa ) i830DumpBufferState(imesa); } + if (imesa->dirty & I830_UPLOAD_STIPPLE) { + fprintf(stderr, "UPLOAD_STIPPLE\n"); + memcpy( imesa->sarea->StippleState,imesa->StippleSetup, + sizeof(imesa->StippleSetup) ); + i830DumpStippleState(imesa); + } + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { memcpy( imesa->sarea->Palette[0],imesa->palette, sizeof(imesa->sarea->Palette[0])); diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_debug.h b/xc/lib/GL/mesa/src/drv/i830/i830_debug.h index a49b82d0b..c61d82153 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_debug.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_debug.h @@ -25,7 +25,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_debug.h,v 1.2 2002/09/11 00:29:25 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_debug.h,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ /* * Author: @@ -41,6 +41,7 @@ void i830DumpContextState( i830ContextPtr imesa ); void i830DumpBufferState( i830ContextPtr imesa ); void i830DumpTextureState( i830ContextPtr imesa, int unit ); void i830DumpTextureBlendState( i830ContextPtr imesa, int unit ); +void i830DumpStippleState( i830ContextPtr imesa ); void i830VertexSanity( i830ContextPtr imesa, drmI830Vertex vertex ); void i830EmitHwStateLockedDebug( i830ContextPtr imesa ); diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c index dcaffec91..3d4c997f2 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c @@ -26,7 +26,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c,v 1.3 2002/09/11 00:29:25 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c,v 1.5 2002/12/10 01:26:53 dawes Exp $ */ /* * Author: @@ -40,6 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include <stdio.h> #include <unistd.h> +#include <errno.h> #include "glheader.h" #include "mtypes.h" @@ -59,70 +60,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drm.h" - -/* - * XXX This is here only while not all of the XFree86 versions of interest - * don't have the drmCommand interfaces. - */ - -#if !defined(HAVE_DRM_COMMAND) -#include <sys/ioctl.h> - -#define DRM_COMMAND_BASE 0x40 - -#define DRM_I830_INIT 0x00 -#define DRM_I830_VERTEX 0x01 -#define DRM_I830_CLEAR 0x02 -#define DRM_I830_FLUSH 0x03 -#define DRM_I830_GETAGE 0x04 -#define DRM_I830_GETBUF 0x05 -#define DRM_I830_SWAP 0x06 -#define DRM_I830_COPY 0x07 -#define DRM_I830_DOCOPY 0x08 - -static int -drmCommandNone(int fd, unsigned long drmCommandIndex) -{ - void *data = NULL; /* dummy */ - unsigned long request; - - request = DRM_IO(DRM_COMMAND_BASE + drmCommandIndex); - - if (ioctl(fd, request, data)) { - return -errno; - } - return 0; -} - -static int -drmCommandWrite(int fd, unsigned long drmCommandIndex, - void *data, unsigned long size ) -{ - unsigned long request; - - request = DRM_IOW(DRM_COMMAND_BASE + drmCommandIndex, size); - - if (ioctl(fd, request, data)) { - return -errno; - } - return 0; -} - -static int -drmCommandWriteRead(int fd, unsigned long drmCommandIndex, - void *data, unsigned long size ) -{ - unsigned long request; - - request = DRM_IOWR(DRM_COMMAND_BASE + drmCommandIndex, size); - - if (ioctl(fd, request, data)) { - return -errno; - } - return 0; -} -#endif - static drmBufPtr i830_get_buffer_ioctl( i830ContextPtr imesa ) { drmI830DMA dma; @@ -137,6 +74,7 @@ static drmBufPtr i830_get_buffer_ioctl( i830ContextPtr imesa ) break; if (++i > 1000) { + imesa->sarea->perf_boxes |= I830_BOX_WAIT; retcode = drmCommandNone(imesa->driFd, DRM_I830_FLUSH); i = 0; } @@ -243,6 +181,7 @@ static void i830ClearWithTris(GLcontext *ctx, GLbitfield mask, memcpy(sarea->BufferState, imesa->BufferSetup, sizeof(imesa->BufferSetup) ); + sarea->StippleState[I830_STPREG_ST1] = 0; old_vertex_prim = imesa->hw_primitive; imesa->hw_primitive = PRIM3D_TRIFAN; @@ -603,6 +542,9 @@ void i830CopyBuffer( const __DRIdrawablePrivate *dPriv ) I830_FIREVERTICES( imesa ); LOCK_HARDWARE( imesa ); + imesa->sarea->perf_boxes |= imesa->perf_boxes; + imesa->perf_boxes = 0; + pbox = dPriv->pClipRects; nbox = dPriv->numClipRects; @@ -631,12 +573,52 @@ void i830CopyBuffer( const __DRIdrawablePrivate *dPriv ) imesa->upload_cliprects = GL_TRUE; } -/* - * XXX implement when full-screen extension is done. +/* Flip the front & back buffes */ void i830PageFlip( const __DRIdrawablePrivate *dPriv ) { - return; + i830ContextPtr imesa; + int tmp, ret; + + if (I830_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate; + + I830_FIREVERTICES( imesa ); + LOCK_HARDWARE( imesa ); + + imesa->sarea->perf_boxes |= imesa->perf_boxes; + imesa->perf_boxes = 0; + + if (dPriv->pClipRects) { + *(XF86DRIClipRectRec *)imesa->sarea->boxes = dPriv->pClipRects[0]; + imesa->sarea->nbox = 1; + } + + ret = drmCommandNone(imesa->driFd, DRM_I830_FLIP); + if (ret) { + fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); + UNLOCK_HARDWARE( imesa ); + exit(1); + } + + tmp = GET_ENQUEUE_AGE(imesa); + UNLOCK_HARDWARE( imesa ); + + /* multiarb will suck the life out of the server without this throttle: + */ + if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) { + i830WaitAge(imesa, imesa->lastSwap); + } + + i830SetDrawBuffer( imesa->glCtx, imesa->glCtx->Color.DriverDrawBuffer ); + imesa->upload_cliprects = GL_TRUE; + imesa->lastSwap = tmp; } /* This waits for *everybody* to finish rendering -- overkill. @@ -644,8 +626,7 @@ void i830PageFlip( const __DRIdrawablePrivate *dPriv ) void i830DmaFinish( i830ContextPtr imesa ) { I830_FIREVERTICES( imesa ); - LOCK_HARDWARE( imesa ); - i830RegetLockQuiescent( imesa ); + LOCK_HARDWARE_QUIESCENT( imesa ); UNLOCK_HARDWARE( imesa ); } @@ -661,6 +642,7 @@ void i830WaitAgeLocked( i830ContextPtr imesa, int age ) while (++i < 5000) { drmCommandNone(imesa->driFd, DRM_I830_GETAGE); if (GET_DISPATCH_AGE(imesa) >= age) return; + imesa->sarea->perf_boxes |= I830_BOX_WAIT; UNLOCK_HARDWARE( imesa ); if (I830_DEBUG & DEBUG_SLEEP) fprintf(stderr, "."); usleep(1); @@ -674,22 +656,37 @@ void i830WaitAgeLocked( i830ContextPtr imesa, int age ) void i830WaitAge( i830ContextPtr imesa, int age ) { int i = 0; - while (++i < 5000) { - drmCommandNone(imesa->driFd, DRM_I830_GETAGE); - if (GET_DISPATCH_AGE(imesa) >= age) return; - } + if (GET_DISPATCH_AGE(imesa) >= age) return; - i = 0; - while (++i < 1000) { + while (1) { drmCommandNone(imesa->driFd, DRM_I830_GETAGE); if (GET_DISPATCH_AGE(imesa) >= age) return; - if (I830_DEBUG & DEBUG_SLEEP) fprintf(stderr, "."); - usleep(1000); - } + imesa->perf_boxes |= I830_BOX_WAIT; - LOCK_HARDWARE(imesa); - drmCommandNone(imesa->driFd, DRM_I830_FLUSH); - UNLOCK_HARDWARE(imesa); + if (imesa->do_irqs) { + drmI830IrqEmit ie; + drmI830IrqWait iw; + int ret; + + ie.irq_seq = &iw.irq_seq; + + LOCK_HARDWARE( imesa ); + ret = drmCommandWriteRead( imesa->driFd, DRM_I830_IRQ_EMIT, &ie, sizeof(ie) ); + if ( ret ) { + fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret ); + exit(1); + } + UNLOCK_HARDWARE(imesa); + + ret = drmCommandWrite( imesa->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) ); + if ( ret ) { + fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret ); + exit(1); + } + } else { + if (++i > 5000) usleep(1); + } + } } static void age_imesa( i830ContextPtr imesa, int age ) @@ -705,11 +702,25 @@ void i830FlushPrimsLocked( i830ContextPtr imesa ) drmBufPtr buffer = imesa->vertex_buffer; I830SAREAPtr sarea = imesa->sarea; drmI830Vertex vertex; - int i; + int i, nr; if (I830_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s dirty: %08x\n", __FUNCTION__, imesa->dirty); + + vertex.idx = buffer->idx; + vertex.used = imesa->vertex_low; + vertex.discard = 0; + sarea->vertex_prim = imesa->hw_primitive; + + /* Reset imesa vars: + */ + imesa->vertex_buffer = 0; + imesa->vertex_addr = 0; + imesa->vertex_low = 0; + imesa->vertex_high = 0; + imesa->vertex_last_prim = 0; + if (imesa->dirty) { if (I830_DEBUG & DEBUG_SANITY) i830EmitHwStateLockedDebug(imesa); @@ -717,25 +728,32 @@ void i830FlushPrimsLocked( i830ContextPtr imesa ) i830EmitHwStateLocked(imesa); } - vertex.idx = buffer->idx; - vertex.used = imesa->vertex_low; - vertex.discard = 0; - sarea->vertex_prim = imesa->hw_primitive; - if (I830_DEBUG & DEBUG_IOCTL) fprintf(stderr,"%s: Vertex idx %d used %d discard %d\n", __FUNCTION__, vertex.idx, vertex.used, vertex.discard); - if (!nbox) + if (!nbox) { vertex.used = 0; + vertex.discard = 1; + if (drmCommandWrite (imesa->driFd, DRM_I830_VERTEX, + &vertex, sizeof(drmI830Vertex))) { + fprintf(stderr, "DRM_I830_VERTEX: %d\n", -errno); + UNLOCK_HARDWARE(imesa); + exit(1); + } + return; + } - for (i = 0 ; i < nbox ; ) { - int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, nbox); + for (i = 0 ; i < nbox ; i = nr ) { XF86DRIClipRectPtr b = sarea->boxes; + int j; + nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, nbox); sarea->nbox = nr - i; - for ( ; i < nr ; i++, b++) - *b++ = pbox[i]; + + for ( j = i ; j < nr ; j++) { + b[j-i] = pbox[j]; + } /* Finished with the buffer? */ @@ -743,21 +761,20 @@ void i830FlushPrimsLocked( i830ContextPtr imesa ) vertex.discard = 1; /* Do a bunch of sanity checks on the vertices sent to the hardware */ - if (I830_DEBUG & DEBUG_SANITY) + if (I830_DEBUG & DEBUG_SANITY) { i830VertexSanity(imesa, vertex); + for ( j = 0 ; j < sarea->nbox ; j++) { + fprintf(stderr, "box %d/%d %d,%d %d,%d\n", + j, sarea->nbox, b[j].x1, b[j].y1, b[j].x2, b[j].y2); + } + } + drmCommandWrite (imesa->driFd, DRM_I830_VERTEX, &vertex, sizeof(drmI830Vertex)); age_imesa(imesa, imesa->sarea->last_enqueue); } - /* Reset imesa vars: - */ - imesa->vertex_buffer = 0; - imesa->vertex_addr = 0; - imesa->vertex_low = 0; - imesa->vertex_high = 0; - imesa->vertex_last_prim = 0; imesa->dirty = 0; imesa->upload_cliprects = GL_FALSE; } diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h index d9d74063a..4c64b8d7a 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h @@ -26,7 +26,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h,v 1.2 2002/09/09 19:18:48 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h,v 1.3 2002/10/30 12:51:35 alanh Exp $ */ /* * Author: @@ -38,8 +38,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h,v 1.2 2002/09/09 19:18:48 dawes Exp $ */ - #ifndef I830_IOCTL_H #define I830_IOCTL_H diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_render.c b/xc/lib/GL/mesa/src/drv/i830/i830_render.c index 65dd263ec..ec14847ad 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_render.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_render.c @@ -26,7 +26,7 @@ * Adapted for use on the I830: * Jeff Hartmann <jhartmann@2d3d.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_render.c,v 1.1 2002/09/09 19:18:48 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_render.c,v 1.2 2002/12/10 01:26:53 dawes Exp $ */ /* * Render unclipped vertex buffers by emitting vertices directly to @@ -38,6 +38,7 @@ #include "macros.h" #include "mem.h" #include "mtypes.h" +#include "enums.h" #include "mmath.h" #include "tnl/t_context.h" @@ -72,9 +73,9 @@ #define HAVE_ELTS 0 static GLuint hw_prim[GL_POLYGON+1] = { - PRIM3D_POINTLIST, - PRIM3D_LINELIST, 0, + PRIM3D_LINELIST, + PRIM3D_LINESTRIP, PRIM3D_LINESTRIP, PRIM3D_TRILIST, PRIM3D_TRISTRIP, @@ -97,7 +98,20 @@ static const GLenum reduced_prim[GL_POLYGON+1] = { GL_TRIANGLES }; -/* Fallback to normal rendering. +static const int scale_prim[GL_POLYGON+1] = { + 0, /* fallback case */ + 1, + 2, + 2, + 1, + 3, + 3, + 0, /* fallback case */ + 0, /* fallback case */ + 3 +}; + +/* Fallback to normal rendering. Should now never be called. */ static void VERT_FALLBACK( GLcontext *ctx, GLuint start, @@ -124,7 +138,7 @@ static void VERT_FALLBACK( GLcontext *ctx, #define GET_CURRENT_VB_MAX_VERTS() \ (((int)imesa->vertex_high - (int)imesa->vertex_low) / (imesa->vertex_size*4)) #define GET_SUBSEQUENT_VB_MAX_VERTS() \ - (I830_DMA_BUF_SZ-4) / (imesa->vertex_size * 4) + (I830_DMA_BUF_SZ-8) / (imesa->vertex_size * 4) #define EMIT_VERTS( ctx, j, nr ) \ i830_emit_contiguous_verts(ctx, j, (j)+(nr)) @@ -137,6 +151,46 @@ static void VERT_FALLBACK( GLcontext *ctx, /* Render pipeline stage */ /**********************************************************************/ +/* Heuristic for i830, which can only emit a single primitive per dma + * buffer, and has only a small number of dma buffers. + */ +static GLboolean choose_render( struct vertex_buffer *VB, int bufsz ) +{ + int nr_prims = 0; + int nr_rprims = 0; + int nr_rverts = 0; + int rprim = 0; + int i = 0, length, flags = 0; + + + for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length) { + flags = VB->Primitive[i]; + length = VB->PrimitiveLength[i]; + if (!length) + continue; + + if (!hw_prim[flags & PRIM_MODE_MASK]) + return GL_FALSE; + + nr_prims++; + nr_rverts += length * scale_prim[flags & PRIM_MODE_MASK]; + + if (reduced_prim[flags&PRIM_MODE_MASK] != rprim) { + nr_rprims++; + rprim = reduced_prim[flags&PRIM_MODE_MASK]; + } + } + + nr_prims += i / bufsz; + nr_rprims += nr_rverts / bufsz; + + if ((nr_prims > nr_rprims * 2) || + (nr_prims > nr_rprims + 3)) + return GL_FALSE; + + return GL_TRUE; +} + static GLboolean i830_run_render( GLcontext *ctx, struct gl_pipeline_stage *stage ) @@ -147,7 +201,8 @@ static GLboolean i830_run_render( GLcontext *ctx, GLuint i, length, flags = 0; /* Don't handle clipping or indexed vertices. */ - if (VB->ClipOrMask || imesa->RenderIndex != 0 || VB->Elts) { + if (VB->ClipOrMask || imesa->RenderIndex != 0 || VB->Elts || + !choose_render( VB, GET_SUBSEQUENT_VB_MAX_VERTS() )) { return GL_TRUE; } diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_screen.c b/xc/lib/GL/mesa/src/drv/i830/i830_screen.c index 71ae60640..0283fb125 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_screen.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_screen.c @@ -24,7 +24,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_screen.c,v 1.2 2002/09/11 00:29:26 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_screen.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ /* * Authors: @@ -150,8 +150,8 @@ static GLboolean i830InitDriver(__DRIscreenPrivate *sPriv) } /* Check that the DRM driver version is compatible */ - if (sPriv->drmMajor != 1 || sPriv->drmMinor < 2) { - __driUtilMessage("i830 DRI driver expected DRM driver version 1.2.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + if (sPriv->drmMajor != 1 || sPriv->drmMinor < 3) { + __driUtilMessage("i830 DRI driver expected DRM driver version 1.3.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); return GL_FALSE; } @@ -250,7 +250,26 @@ static GLboolean i830InitDriver(__DRIscreenPrivate *sPriv) } i830Screen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; - if (1) i830PrintDRIInfo(i830Screen, sPriv, gDRIPriv); + + if (0) i830PrintDRIInfo(i830Screen, sPriv, gDRIPriv); + + i830Screen->drmMinor = sPriv->drmMinor; + + if (sPriv->drmMinor >= 3) { + int ret; + drmI830GetParam gp; + + gp.param = I830_PARAM_IRQ_ACTIVE; + gp.value = &i830Screen->irq_active; + + ret = drmCommandWriteRead( sPriv->fd, DRM_I830_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmI830GetParam: %d\n", ret); + return GL_FALSE; + } + } + return GL_TRUE; } @@ -336,3 +355,39 @@ void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, return (void *) psp; } + +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we'd register new extension functions with the dispatcher. + * + * Note: Most of these are probably already registered - just doing + * this for the benefit of old libGL.so's out there. + */ +#include "glapioffsets.h" + +void __driRegisterExtensions( void ) +{ + int i; + static struct { const char *name; int offset; } funcs[] = { + { "glSecondaryColor3bEXT", _gloffset_SecondaryColor3bEXT }, + { "glSecondaryColor3dEXT", _gloffset_SecondaryColor3dEXT }, + { "glSecondaryColor3fEXT", _gloffset_SecondaryColor3fEXT }, + { "glSecondaryColor3iEXT", _gloffset_SecondaryColor3iEXT }, + { "glSecondaryColor3sEXT", _gloffset_SecondaryColor3sEXT }, + { "glSecondaryColor3ubEXT", _gloffset_SecondaryColor3ubEXT }, + { "glSecondaryColor3uiEXT", _gloffset_SecondaryColor3uiEXT }, + { "glSecondaryColor3usEXT", _gloffset_SecondaryColor3usEXT }, + { "glSecondaryColor3bvEXT", _gloffset_SecondaryColor3bvEXT }, + { "glSecondaryColor3dvEXT", _gloffset_SecondaryColor3dvEXT }, + { "glSecondaryColor3fvEXT", _gloffset_SecondaryColor3fvEXT }, + { "glSecondaryColor3ivEXT", _gloffset_SecondaryColor3ivEXT }, + { "glSecondaryColor3svEXT", _gloffset_SecondaryColor3svEXT }, + { "glSecondaryColor3ubvEXT", _gloffset_SecondaryColor3ubvEXT }, + { "glSecondaryColor3uivEXT", _gloffset_SecondaryColor3uivEXT }, + { "glSecondaryColor3usvEXT", _gloffset_SecondaryColor3usvEXT }, + { "glSecondaryColorPointerEXT", _gloffset_SecondaryColorPointerEXT } + }; + + for (i = 0 ; i < sizeof(funcs) / sizeof(*funcs) ; i++ ) + _glapi_add_entrypoint( funcs[i].name, funcs[i].offset ); +} + diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_screen.h b/xc/lib/GL/mesa/src/drv/i830/i830_screen.h index ca991c78a..b37e862d6 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_screen.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_screen.h @@ -39,17 +39,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri_util.h" -/* All structures go here */ -typedef struct -{ - GLubyte blue; - GLubyte green; - GLubyte red; - GLubyte alpha; -}i830_color; - - - typedef struct { drmHandle handle; drmSize size; @@ -59,37 +48,40 @@ typedef struct { typedef struct { - i830Region front; - i830Region back; - i830Region depth; - i830Region tex; + i830Region front; + i830Region back; + i830Region depth; + i830Region tex; - int deviceID; - int width; - int height; - int mem; + int deviceID; + int width; + int height; + int mem; - int cpp; /* for front and back buffers */ - int bitsPerPixel; + int cpp; /* for front and back buffers */ + int bitsPerPixel; - int fbFormat; - int fbOffset; - int fbStride; + int fbFormat; + int fbOffset; + int fbStride; - int backOffset; - int depthOffset; + int backOffset; + int depthOffset; - int backPitch; - int backPitchBits; + int backPitch; + int backPitchBits; - int textureOffset; - int textureSize; - int logTextureGranularity; + int textureOffset; + int textureSize; + int logTextureGranularity; - __DRIscreenPrivate *driScrnPriv; - drmBufMapPtr bufs; - int use_copy_buf; - unsigned int sarea_priv_offset; + __DRIscreenPrivate *driScrnPriv; + drmBufMapPtr bufs; + int use_copy_buf; + unsigned int sarea_priv_offset; + + int drmMinor; + int irq_active; }i830ScreenPrivate; diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_span.c b/xc/lib/GL/mesa/src/drv/i830/i830_span.c index 232698911..14ad7d536 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_span.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_span.c @@ -25,7 +25,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_span.c,v 1.3 2002/09/11 00:29:26 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_span.c,v 1.4 2002/12/10 01:26:53 dawes Exp $ */ /* * Author: @@ -263,15 +263,25 @@ do { \ #include "stenciltmp.h" static void i830SetReadBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, - GLenum mode) + GLenum mode) { i830ContextPtr imesa = I830_CONTEXT(ctx); - if (mode == GL_FRONT_LEFT) { - imesa->readMap = (char*)imesa->driScreen->pFB; - } else if (mode == GL_BACK_LEFT) { - imesa->readMap = imesa->i830Screen->back.map; - } else { + switch( mode ) { + case GL_FRONT_LEFT: + if ( imesa->sarea->pf_current_page == 1 ) + imesa->readMap = imesa->i830Screen->back.map; + else + imesa->readMap = (char*)imesa->driScreen->pFB; + break; + case GL_BACK_LEFT: + if ( imesa->sarea->pf_current_page == 1 ) + imesa->readMap = (char*)imesa->driScreen->pFB; + else + imesa->readMap = imesa->i830Screen->back.map; + break; + default: ASSERT(0); + break; } } @@ -283,8 +293,8 @@ void i830SpanRenderStart( GLcontext *ctx ) { i830ContextPtr imesa = I830_CONTEXT(ctx); I830_FIREVERTICES(imesa); - i830DmaFinish(imesa); - LOCK_HARDWARE_QUIESCENT(imesa); + LOCK_HARDWARE(imesa); + i830RegetLockQuiescent( imesa ); } void i830SpanRenderFinish( GLcontext *ctx ) diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_state.c b/xc/lib/GL/mesa/src/drv/i830/i830_state.c index 86992d61e..3aef48ccd 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_state.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_state.c @@ -25,7 +25,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.c,v 1.4 2002/09/11 00:29:26 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.c,v 1.6 2003/01/28 22:47:06 dawes Exp $ */ /* * Author: @@ -729,15 +729,71 @@ static void i830DepthMask(GLcontext *ctx, GLboolean flag) imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - if (flag) + if (flag && ctx->Depth.Test) imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; else imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; } -/* The i830 has no stipple hardware */ -static void i830PolygonStipple(GLcontext *ctx, const GLubyte *mask) +/* ============================================================= + * Polygon stipple + * + * The i830 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i,j,k; + int active = (ctx->Polygon.StippleFlag && + imesa->reduced_primitive == GL_TRIANGLES); + GLuint newMask; + + if (active) { + I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE); + imesa->StippleSetup[I830_STPREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; + + for (k = 0 ; k < 8 ; k++) + for (j = 3 ; j >= 0; j--) + for (i = 0 ; i < 4 ; i++, m++) + if (*m != p[j]) { + imesa->hw_stipple = 0; + return; + } + + newMask = (((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | + ((p[3] & 0xf) << 12)); + + + if (newMask == 0xffff || newMask == 0x0) { + /* this is needed to make conform pass */ + imesa->hw_stipple = 0; + return; + } + + imesa->StippleSetup[I830_STPREG_ST1] &= ~0xffff; + imesa->StippleSetup[I830_STPREG_ST1] |= newMask; + imesa->hw_stipple = 1; + + if (active) + imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE; +} + +static void i830PolygonStippleFallback( GLcontext *ctx, const GLubyte *mask ) { + i830ContextPtr imesa = I830_CONTEXT(ctx); + imesa->hw_stipple = 0; + (void) i830PolygonStipple; } /* ============================================================= @@ -761,6 +817,12 @@ static void i830Scissor(GLcontext *ctx, GLint x, GLint y, if (x2 < 0) x2 = 0; if (y2 < 0) y2 = 0; + if (x2 >= imesa->i830Screen->width) x2 = imesa->i830Screen->width-1; + if (y2 >= imesa->i830Screen->height) y2 = imesa->i830Screen->height-1; + if (x1 >= imesa->i830Screen->width) x1 = imesa->i830Screen->width-1; + if (y1 >= imesa->i830Screen->height) y1 = imesa->i830Screen->height-1; + + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); imesa->BufferSetup[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); imesa->BufferSetup[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); @@ -843,33 +905,93 @@ static void i830RenderMode( GLcontext *ctx, GLenum mode ) FALLBACK( imesa, I830_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); } -static void i830SetDrawBuffer(GLcontext *ctx, GLenum mode ) +#if 0 +void i830DrawBuffer(GLcontext *ctx, GLenum mode ) { i830ContextPtr imesa = I830_CONTEXT(ctx); + int front; - if (mode == GL_FRONT_LEFT) { - I830_FIREVERTICES(imesa); - I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + /* + * _DrawDestMask is easier to cope with than <mode>. + */ + switch ( ctx->Color._DrawDestMask ) { + case FRONT_LEFT_BIT: + front = 1; + break; + case BACK_LEFT_BIT: + front = 0; + break; + default: + /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } - imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->fbOffset; + if ( imesa->sarea->pf_current_page == 1 ) + front ^= 1; + + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE ); + I830_FIREVERTICES(imesa); + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + i830XMesaSetFrontClipRects( imesa ); + if (front) { + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->fbOffset; imesa->drawMap = (char *)imesa->driScreen->pFB; imesa->readMap = (char *)imesa->driScreen->pFB; - i830XMesaSetFrontClipRects( imesa ); - FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE ); - } else if (mode == GL_BACK_LEFT) { - I830_FIREVERTICES(imesa); - I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + } else { + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->backOffset; + imesa->drawMap = imesa->i830Screen->back.map; + imesa->readMap = imesa->i830Screen->back.map; + } + + /* We want to update the s/w rast state too so that i830SetBuffer() + * gets called. + */ + _swrast_DrawBuffer(ctx, mode); +} + + +static void i830ReadBuffer(GLcontext *ctx, GLenum mode ) +{ + /* nothing, until h/w glRead/CopyPixels */ +} +#endif + - imesa->BufferSetup[I830_DESTREG_CBUFADDR] = - imesa->i830Screen->backOffset; +void i830SetDrawBuffer(GLcontext *ctx, GLenum mode ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int front = 0; + + switch (mode) { + case GL_FRONT_LEFT: + front = 1; + break; + case GL_BACK_LEFT: + front = 0; + break; + default: + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + if ( imesa->sarea->pf_current_page == 1 ) + front ^= 1; + + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE ); + I830_FIREVERTICES(imesa); + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + i830XMesaSetFrontClipRects( imesa ); + + if (front) { + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->fbOffset; + imesa->drawMap = (char *)imesa->driScreen->pFB; + imesa->readMap = (char *)imesa->driScreen->pFB; + } else { + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->backOffset; imesa->drawMap = imesa->i830Screen->back.map; imesa->readMap = imesa->i830Screen->back.map; - i830XMesaSetBackClipRects( imesa ); - FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE ); - } else { - FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_TRUE ); } } @@ -1098,6 +1220,10 @@ static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; else imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + + /* Also turn off depth writes when GL_DEPTH_TEST is disabled: + */ + i830DepthMask( ctx, state ); break; case GL_SCISSOR_TEST: @@ -1148,8 +1274,8 @@ static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; case GL_TEXTURE_2D: - I830_STATECHANGE(imesa, I830_UPLOAD_CTX); - imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; +/* I830_STATECHANGE(imesa, I830_UPLOAD_CTX); */ +/* imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; */ break; case GL_STENCIL_TEST: @@ -1168,7 +1294,19 @@ static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; case GL_POLYGON_STIPPLE: - FALLBACK(imesa, I830_FALLBACK_STIPPLE, ctx->Polygon.StippleFlag); +#if 0 + /* The stipple command worked on my 855GM box, but not my 845G. + * I'll do more testing later to find out exactly which hardware + * supports it. Disabled for now. + */ + if (imesa->hw_stipple && imesa->reduced_primitive == GL_TRIANGLES) + { + I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE); + imesa->StippleSetup[I830_STPREG_ST1] &= ~ST1_ENABLE; + if (state) + imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE; + } +#endif break; default: @@ -1212,11 +1350,6 @@ void i830EmitDrawingRectangle( i830ContextPtr imesa ) /* Just add in our dirty flag, since we might be called when locked */ /* Might want to modify how this is done. */ -#if 0 - if (imesa->vertex_low != imesa->vertex_last_prim) - i830FlushPrimsLocked(imesa); -#endif - imesa->dirty |= I830_UPLOAD_BUFFERS; if (0) @@ -1262,7 +1395,7 @@ static void i830DepthRange( GLcontext *ctx, void i830PrintDirty( const char *msg, GLuint state ) { - fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n", + fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n", msg, (unsigned int) state, (state & I830_UPLOAD_TEX0) ? "upload-tex0, " : "", @@ -1270,7 +1403,8 @@ void i830PrintDirty( const char *msg, GLuint state ) (state & I830_UPLOAD_CTX) ? "upload-ctx, " : "", (state & I830_UPLOAD_BUFFERS) ? "upload-bufs, " : "", (state & I830_UPLOAD_TEXBLEND0) ? "upload-blend0, " : "", - (state & I830_UPLOAD_TEXBLEND1) ? "upload-blend1, " : "" + (state & I830_UPLOAD_TEXBLEND1) ? "upload-blend1, " : "", + (state & I830_UPLOAD_STIPPLE) ? "stipple, " : "" ); } @@ -1299,7 +1433,8 @@ void i830EmitHwStateLocked( i830ContextPtr imesa ) imesa->CurrentTexObj[i]->Setup, sizeof(imesa->sarea->TexState[i])); /* Update the LRU usage */ - i830UpdateTexLRU(imesa, imesa->CurrentTexObj[i]); + if (imesa->CurrentTexObj[i]->MemBlock) + i830UpdateTexLRU(imesa, imesa->CurrentTexObj[i]); } } /* Need to figure out if texturing state, or enable changed. */ @@ -1315,12 +1450,15 @@ void i830EmitHwStateLocked( i830ContextPtr imesa ) } if (imesa->dirty & I830_UPLOAD_BUFFERS) { - if (I830_DEBUG & DEBUG_STATE) - fprintf(stderr,"\nCopying BufferState to shared area\n"); memcpy( imesa->sarea->BufferState,imesa->BufferSetup, sizeof(imesa->BufferSetup) ); } + if (imesa->dirty & I830_UPLOAD_STIPPLE) { + memcpy( imesa->sarea->StippleState,imesa->StippleSetup, + sizeof(imesa->StippleSetup) ); + } + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { memcpy( imesa->sarea->Palette[0],imesa->palette, sizeof(imesa->sarea->Palette[0])); @@ -1338,6 +1476,7 @@ void i830EmitHwStateLocked( i830ContextPtr imesa ) sizeof(imesa->sarea->Palette[1])); } } + imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK | I830_UPLOAD_TEXBLEND_MASK)); @@ -1564,9 +1703,11 @@ void i830DDInitState( GLcontext *ctx ) imesa->LcsCullMode = CULLMODE_CW; /* GL default */ memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup)); + memset(imesa->StippleSetup, 0, sizeof(imesa->StippleSetup)); - if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT) { + if (imesa->glCtx->Visual.doubleBufferMode && + imesa->sarea->pf_current_page == 0) { imesa->drawMap = i830Screen->back.map; imesa->readMap = i830Screen->back.map; imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->backOffset; @@ -1652,7 +1793,7 @@ void i830DDInitStateFuncs(GLcontext *ctx) ctx->Driver.LineWidth = i830LineWidth; ctx->Driver.PointSize = i830PointSize; ctx->Driver.LogicOpcode = i830LogicOp; - ctx->Driver.PolygonStipple = i830PolygonStipple; + ctx->Driver.PolygonStipple = i830PolygonStippleFallback; ctx->Driver.RenderMode = i830RenderMode; ctx->Driver.Scissor = i830Scissor; ctx->Driver.SetDrawBuffer = i830SetDrawBuffer; diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_state.h b/xc/lib/GL/mesa/src/drv/i830/i830_state.h index 8a4baac26..edfcb3a8c 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_state.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_state.h @@ -25,7 +25,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.h,v 1.2 2002/09/11 00:29:26 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.h,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ /* * Author: @@ -61,6 +61,7 @@ extern void i830DDInitState( GLcontext *ctx ); extern void i830DDInitStateFuncs( GLcontext *ctx ); extern void i830PrintDirty( const char *msg, GLuint state ); +extern void i830SetDrawBuffer(GLcontext *ctx, GLenum mode ); extern void i830Fallback( i830ContextPtr imesa, GLuint bit, GLboolean mode ); #define FALLBACK( imesa, bit, mode ) i830Fallback( imesa, bit, mode ) diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_tex.c b/xc/lib/GL/mesa/src/drv/i830/i830_tex.c index e90c8c12d..7ba5e70ab 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_tex.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_tex.c @@ -25,7 +25,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tex.c,v 1.3 2002/09/11 00:29:26 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tex.c,v 1.4 2002/12/10 01:26:53 dawes Exp $ */ /* * Author: @@ -60,12 +60,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias. */ -static GLuint i830ComputeLodBias(GLfloat bias) +static void i830ComputeLodBias(i830ContextPtr imesa, + i830TextureObjectPtr t, + GLfloat bias) { - int b = (int) (bias * 16.0) + 12; + int b; + + b = (int) (bias * 16.0); if(b > 63) b = 63; else if (b < -64) b = -64; - return (GLuint) (b & MAP_LOD_MASK); + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK; + t->Setup[I830_TEXREG_TM0S3] |= ((b << TM0S3_LOD_BIAS_SHIFT) & + TM0S3_LOD_BIAS_MASK); } static void i830SetTexWrapping(i830TextureObjectPtr tex, @@ -128,9 +134,9 @@ static void i830SetTexFilter(i830ContextPtr imesa, minFilt = FILTER_NEAREST; mipFilt = MIPFILTER_NEAREST; - if(magf == GL_LINEAR) { - bias -= 0.5; - } +/* if(magf == GL_LINEAR && 0) { */ +/* bias -= 0.5; */ +/* } */ break; case GL_LINEAR_MIPMAP_NEAREST: @@ -141,9 +147,9 @@ static void i830SetTexFilter(i830ContextPtr imesa, minFilt = FILTER_NEAREST; mipFilt = MIPFILTER_LINEAR; - if(magf == GL_LINEAR) { - bias -= 0.5; - } +/* if(magf == GL_LINEAR && 0) { */ +/* bias -= 0.5; */ +/* } */ break; case GL_LINEAR_MIPMAP_LINEAR: @@ -169,14 +175,14 @@ static void i830SetTexFilter(i830ContextPtr imesa, break; } - I830_SET_FIELD(t->Setup[I830_TEXREG_MF], - MIN_FILTER_MASK | MIP_FILTER_MASK, - MIN_FILTER(minFilt) | mipFilt); + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_FILTER_MASK; + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIP_FILTER_MASK; + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAG_FILTER_MASK; + t->Setup[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | + (mipFilt << TM0S3_MIP_FILTER_SHIFT) | + (magFilt << TM0S3_MAG_FILTER_SHIFT)); - I830_SET_FIELD(t->Setup[I830_TEXREG_MF], - MAG_FILTER_MASK, MAG_FILTER(magFilt)); - - t->Setup[I830_TEXREG_MLC] |= i830ComputeLodBias(bias); + i830ComputeLodBias(imesa, t, bias); } static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4]) @@ -184,7 +190,7 @@ static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4]) if(I830_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); - t->Setup[I830_TEXREG_MI5] = + t->Setup[I830_TEXREG_TM0S4] = I830PACKCOLOR8888(color[0],color[1],color[2],color[3]); } @@ -230,11 +236,10 @@ static void i830TexParameter( GLcontext *ctx, GLenum target, case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: - /* This isn't the most efficient solution but there doesn't appear to - * be a nice alternative for Radeon. Since there's no LOD clamping, - * we just have to rely on loading the right subset of mipmap levels - * to simulate a clamped LOD. + /* The i830 and its successors can do a lot of this without + * reloading the textures. A project for someone? */ + I830_FIREVERTICES( I830_CONTEXT(ctx) ); i830SwapOutTexObj( imesa, t ); break; @@ -283,8 +288,7 @@ static void i830TexEnv( GLcontext *ctx, GLenum target, { struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; - t->Setup[I830_TEXREG_MLC] &= ~(MLC_LOD_BIAS_MASK); - t->Setup[I830_TEXREG_MLC] |= i830ComputeLodBias(*param); + i830ComputeLodBias(imesa, t, *param); /* Do a state change */ if (t == imesa->CurrentTexObj[unit]) { I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) ); @@ -307,6 +311,7 @@ static void i830TexImage2D( GLcontext *ctx, GLenum target, GLint level, { i830TextureObjectPtr t = (i830TextureObjectPtr) texObj->DriverData; if (t) { + I830_FIREVERTICES( I830_CONTEXT(ctx) ); i830SwapOutTexObj( I830_CONTEXT(ctx), t ); } _mesa_store_teximage2d( ctx, target, level, internalFormat, @@ -327,6 +332,7 @@ static void i830TexSubImage2D( GLcontext *ctx, { i830TextureObjectPtr t = (i830TextureObjectPtr) texObj->DriverData; if (t) { + I830_FIREVERTICES( I830_CONTEXT(ctx) ); i830SwapOutTexObj( I830_CONTEXT(ctx), t ); } _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, @@ -349,17 +355,15 @@ static void i830BindTexture( GLcontext *ctx, GLenum target, /* Initialize non-image-dependent parts of the state: */ t->globj = tObj; - t->Setup[I830_TEXREG_MI0] = STATE3D_MAP_INFO_COLR_CMD; - t->Setup[I830_TEXREG_MI1] = (MAP_INFO_TEX(0) | - MAP_INFO_OUTMUX_F0F1F2F3 | - MAP_INFO_VERTLINESTRIDE_0 | - MAP_INFO_VERTLINESTRIDEOFS_0 | - MAP_INFO_FORMAT_2D | - MAP_INFO_USE_FENCE); - t->Setup[I830_TEXREG_MLC] = (STATE3D_MAP_LOD_CNTL_CMD | - MAP_UNIT(0) | - ENABLE_TEXLOD_BIAS | - MAP_LOD_BIAS(0)); + t->Setup[I830_TEXREG_TM0LI] = STATE3D_LOAD_STATE_IMMEDIATE_2; + t->Setup[I830_TEXREG_TM0S0] = TM0S0_USE_FENCE; + t->Setup[I830_TEXREG_TM0S1] = 0; + t->Setup[I830_TEXREG_TM0S2] = 0; + t->Setup[I830_TEXREG_TM0S3] = 0; + + t->Setup[I830_TEXREG_NOP0] = 0; + t->Setup[I830_TEXREG_NOP1] = 0; + t->Setup[I830_TEXREG_NOP2] = 0; t->Setup[I830_TEXREG_MCS] = (STATE3D_MAP_COORD_SET_CMD | MAP_UNIT(0) | @@ -371,12 +375,6 @@ static void i830BindTexture( GLcontext *ctx, GLenum target, ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); - t->Setup[I830_TEXREG_MF] = (STATE3D_MAP_FILTER_CMD | - MAP_UNIT(0) | - ENABLE_MIP_MODE_FILTER | - MIPFILTER_NEAREST | - ENABLE_MAG_MODE_FILTER | - ENABLE_MIN_MODE_FILTER); t->dirty_images = ~0; diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c b/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c index d54af4daf..9a5bee654 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c @@ -25,7 +25,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_texmem.c,v 1.2 2002/09/11 00:29:26 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_texmem.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ /* * Author: @@ -111,18 +111,22 @@ void i830SwapOutTexObj(i830ContextPtr imesa, i830TextureObjectPtr t) /* Upload an image from mesa's internal copy. */ -static void i830UploadTexLevel( i830TextureObjectPtr t, int level ) +static void i830UploadTexLevel( i830TextureObjectPtr t, int hwlevel ) { - const struct gl_texture_image *image = t->image[level].image; + int level = hwlevel + t->firstLevel; + const struct gl_texture_image *image = t->image[hwlevel].image; int i,j; + if (!image || !image->Data) + return; + if (0) fprintf(stderr, "Uploading level : %d\n", level); switch (image->TexFormat->MesaFormat) { case MESA_FORMAT_I8: case MESA_FORMAT_L8: { - GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset); + GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[hwlevel].offset); GLubyte *src = (GLubyte *)image->Data; for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) { @@ -139,7 +143,7 @@ static void i830UploadTexLevel( i830TextureObjectPtr t, int level ) case MESA_FORMAT_ARGB1555: case MESA_FORMAT_ARGB4444: { - GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset); + GLushort *dst = (GLushort *)(t->BufAddr + t->image[hwlevel].offset); GLushort *src = (GLushort *)image->Data; for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { @@ -153,7 +157,7 @@ static void i830UploadTexLevel( i830TextureObjectPtr t, int level ) case MESA_FORMAT_ARGB8888: { - GLuint *dst = (GLuint *)(t->BufAddr + t->image[level].offset); + GLuint *dst = (GLuint *)(t->BufAddr + t->image[hwlevel].offset); GLuint *src = (GLuint *)image->Data; for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/4)) { @@ -289,9 +293,10 @@ void i830TexturesGone( i830ContextPtr imesa, fprintf(stderr, "%s\n", __FUNCTION__); foreach_s ( t, tmp, &imesa->TexObjList ) { - if (t->MemBlock->ofs >= offset + size || - t->MemBlock->ofs + t->MemBlock->size <= offset) - continue; + if (t->MemBlock == 0 || + 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. @@ -331,13 +336,14 @@ int i830UploadTexImages( i830ContextPtr imesa, i830TextureObjectPtr t ) if (t->MemBlock) break; +/* if (imesa->TexObjList.prev == imesa->CurrentTexObj[0] || imesa->TexObjList.prev == imesa->CurrentTexObj[1]) { fprintf(stderr, "Hit bound texture in upload\n"); - i830PrintLocalLRU( imesa ); + i830PrintLocalLRU( imesa ); return -1; } - +*/ if (imesa->TexObjList.prev == &(imesa->TexObjList)) { fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); mmDumpMemInfo( imesa->texHeap ); @@ -349,13 +355,14 @@ int i830UploadTexImages( i830ContextPtr imesa, i830TextureObjectPtr t ) ofs = t->MemBlock->ofs; t->BufAddr = imesa->i830Screen->tex.map + ofs; - t->Setup[I830_TEXREG_MI3] = imesa->i830Screen->textureOffset + ofs; + t->Setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | + (imesa->i830Screen->textureOffset + ofs)); if (t == imesa->CurrentTexObj[0]) - I830_STATECHANGE(imesa, I830_UPLOAD_TEX0); + imesa->dirty |= I830_UPLOAD_TEX0; if (t == imesa->CurrentTexObj[1]) - I830_STATECHANGE(imesa, I830_UPLOAD_TEX1); + imesa->dirty |= I830_UPLOAD_TEX1; #if 0 if (t == imesa->CurrentTexObj[2]) I830_STATECHANGE(imesa, I830_UPLOAD_TEX2); @@ -363,7 +370,8 @@ int i830UploadTexImages( i830ContextPtr imesa, i830TextureObjectPtr t ) if (t == imesa->CurrentTexObj[3]) I830_STATECHANGE(imesa, I830_UPLOAD_TEX3); #endif - i830UpdateTexLRU( imesa, t ); + if (t->MemBlock) + i830UpdateTexLRU( imesa, t ); } if (imesa->dirtyAge >= GET_DISPATCH_AGE(imesa)) @@ -371,10 +379,11 @@ int i830UploadTexImages( i830ContextPtr imesa, i830TextureObjectPtr t ) numLevels = t->lastLevel - t->firstLevel + 1; for (i = 0 ; i < numLevels ; i++) - if (t->dirty_images & (1<<i)) + if (t->dirty_images & (1<<(i+t->firstLevel))) i830UploadTexLevel( t, i ); t->dirty_images = 0; + imesa->sarea->perf_boxes |= I830_BOX_TEXTURE_LOAD; return 0; } diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c b/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c index 54f038ec7..74e51e539 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c @@ -25,7 +25,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_texstate.c,v 1.2 2002/09/11 00:29:26 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_texstate.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ /* * Author: @@ -114,17 +114,13 @@ static void i830SetTexImages( i830ContextPtr imesa, * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. * Yes, this looks overly complicated, but it's all needed. */ - if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) { - firstLevel = lastLevel = tObj->BaseLevel; - } else { - firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); - firstLevel = MAX2(firstLevel, tObj->BaseLevel); - lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); - lastLevel = MAX2(lastLevel, tObj->BaseLevel); - lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); - lastLevel = MIN2(lastLevel, tObj->MaxLevel); - lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ - } + firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ /* save these values */ t->firstLevel = firstLevel; @@ -158,6 +154,9 @@ static void i830SetTexImages( i830ContextPtr imesa, */ for ( height = i = 0 ; i < numLevels ; i++ ) { t->image[i].image = tObj->Image[firstLevel + i]; + if (!t->image[i].image) { + break; + } t->image[i].offset = height * pitch; t->image[i].internalFormat = baseImage->Format; height += t->image[i].image->Height; @@ -167,23 +166,17 @@ static void i830SetTexImages( i830ContextPtr imesa, t->totalSize = height*pitch; t->max_level = i-1; - t->Setup[I830_TEXREG_MI1] = (MAP_INFO_TEX(0) | - textureFormat | - MAP_INFO_OUTMUX_F0F1F2F3 | - MAP_INFO_VERTLINESTRIDE_0 | - MAP_INFO_VERTLINESTRIDEOFS_0 | - MAP_INFO_FORMAT_2D | - MAP_INFO_USE_FENCE); - t->Setup[I830_TEXREG_MI2] = (((1 << log2Height) - 1) << 16) | - ((1 << log2Width) - 1); - t->Setup[I830_TEXREG_MI4] = ((pitch / 4) - 1) << 2; - - t->Setup[I830_TEXREG_MLL] = (STATE3D_MAP_LOD_LIMITS_CMD | - MAP_UNIT(0) | - ENABLE_MAX_MIP_LVL | - LOD_MAX(0) | - ENABLE_MIN_MIP_LVL | - LOD_MIN(numLevels - 1)); + t->Setup[I830_TEXREG_TM0S1] = + ((((1 << log2Height) - 1) << TM0S1_HEIGHT_SHIFT) | + (((1 << log2Width) - 1) << TM0S1_WIDTH_SHIFT) | + textureFormat); + t->Setup[I830_TEXREG_TM0S2] = + ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT)); + + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; + t->Setup[I830_TEXREG_TM0S3] |= + ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; t->dirty = I830_UPLOAD_TEX0 | I830_UPLOAD_TEX1; LOCK_HARDWARE( imesa ); @@ -1038,85 +1031,147 @@ static void i830SetTexEnvCombine(i830ContextPtr imesa, fprintf(stderr, "%s\n", __FUNCTION__); switch(texUnit->CombineModeRGB) { - case GL_REPLACE: blendop = TEXBLENDOP_ARG1; break; - case GL_MODULATE: blendop = TEXBLENDOP_MODULATE; break; - case GL_ADD: blendop = TEXBLENDOP_ADD; break; + case GL_REPLACE: + blendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + blendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + blendop = TEXBLENDOP_ADD; + break; case GL_ADD_SIGNED_ARB: - blendop = TEXBLENDOP_ADDSIGNED; break; + blendop = TEXBLENDOP_ADDSIGNED; + break; case GL_INTERPOLATE_ARB: - blendop = TEXBLENDOP_BLEND; break; - case GL_SUBTRACT_ARB: blendop = TEXBLENDOP_SUBTRACT; break; - default: return; + blendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT_ARB: + blendop = TEXBLENDOP_SUBTRACT; + break; + default: + return; } switch(texUnit->CombineScaleShiftRGB) { - case 0: blendop |= TEXOP_SCALE_1X; break; - case 1: blendop |= TEXOP_SCALE_2X; break; - case 2: blendop |= TEXOP_SCALE_4X; break; - default: return; + case 0: + blendop |= TEXOP_SCALE_1X; + break; + case 1: + blendop |= TEXOP_SCALE_2X; + break; + case 2: + blendop |= TEXOP_SCALE_4X; + break; + default: + return; } switch(texUnit->CombineModeA) { - case GL_REPLACE: ablendop = TEXBLENDOP_ARG1; break; - case GL_MODULATE: ablendop = TEXBLENDOP_MODULATE; break; - case GL_ADD: ablendop = TEXBLENDOP_ADD; break; + case GL_REPLACE: + ablendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + ablendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + ablendop = TEXBLENDOP_ADD; + break; case GL_ADD_SIGNED_ARB: - ablendop = TEXBLENDOP_ADDSIGNED; break; + ablendop = TEXBLENDOP_ADDSIGNED; + break; case GL_INTERPOLATE_ARB: - ablendop = TEXBLENDOP_BLEND; break; - case GL_SUBTRACT_ARB: ablendop = TEXBLENDOP_SUBTRACT; break; - default: return; + ablendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT_ARB: + ablendop = TEXBLENDOP_SUBTRACT; + break; + default: + return; } switch(texUnit->CombineScaleShiftA) { - case 0: ablendop |= TEXOP_SCALE_1X; break; - case 1: ablendop |= TEXOP_SCALE_2X; break; - case 2: ablendop |= TEXOP_SCALE_4X; break; - default: return; + case 0: + ablendop |= TEXOP_SCALE_1X; + break; + case 1: + ablendop |= TEXOP_SCALE_2X; + break; + case 2: + ablendop |= TEXOP_SCALE_4X; + break; + default: + return; } /* Handle RGB args */ for(i = 0; i < 3; i++) { switch(texUnit->CombineSourceRGB[i]) { - case GL_TEXTURE: args_RGB[i] = texel_op; break; + case GL_TEXTURE: + args_RGB[i] = texel_op; + break; case GL_CONSTANT_ARB: - args_RGB[i] = TEXBLENDARG_FACTOR_N; break; + args_RGB[i] = TEXBLENDARG_FACTOR_N; + break; case GL_PRIMARY_COLOR_ARB: - args_RGB[i] = TEXBLENDARG_DIFFUSE; break; + args_RGB[i] = TEXBLENDARG_DIFFUSE; + break; case GL_PREVIOUS_ARB: - args_RGB[i] = TEXBLENDARG_CURRENT; break; - default: return; + args_RGB[i] = TEXBLENDARG_CURRENT; + break; + default: + return; + } switch(texUnit->CombineOperandRGB[i]) { - case GL_SRC_COLOR: args_RGB[i] |= 0; break; - case GL_ONE_MINUS_SRC_COLOR: args_RGB[i] |= TEXBLENDARG_INV_ARG; break; - case GL_SRC_ALPHA: args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; break; + case GL_SRC_COLOR: + args_RGB[i] |= 0; + break; + case GL_ONE_MINUS_SRC_COLOR: + args_RGB[i] |= TEXBLENDARG_INV_ARG; + break; + case GL_SRC_ALPHA: + args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; + break; case GL_ONE_MINUS_SRC_ALPHA: - args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | - TEXBLENDARG_INV_ARG); - break; - default: return; + args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | + TEXBLENDARG_INV_ARG); + break; + default: + return; } } /* Handle A args */ for(i = 0; i < 3; i++) { switch(texUnit->CombineSourceA[i]) { - case GL_TEXTURE: args_A[i] = texel_op; break; + case GL_TEXTURE: + args_A[i] = texel_op; + break; case GL_CONSTANT_ARB: - args_A[i] = TEXBLENDARG_FACTOR_N; break; + args_A[i] = TEXBLENDARG_FACTOR_N; + break; case GL_PRIMARY_COLOR_ARB: - args_A[i] = TEXBLENDARG_DIFFUSE; break; + args_A[i] = TEXBLENDARG_DIFFUSE; + break; case GL_PREVIOUS_ARB: - args_A[i] = TEXBLENDARG_CURRENT; break; - default: return; + args_A[i] = TEXBLENDARG_CURRENT; + break; + default: + return; + } switch(texUnit->CombineOperandA[i]) { - case GL_SRC_ALPHA: args_A[i] |= 0; break; - case GL_ONE_MINUS_SRC_ALPHA: args_A[i] |= TEXBLENDARG_INV_ARG; break; - default: return; + case GL_SRC_ALPHA: + args_A[i] |= 0; + break; + case GL_ONE_MINUS_SRC_ALPHA: + args_A[i] |= TEXBLENDARG_INV_ARG; + break; + default: + return; } } @@ -1258,14 +1313,10 @@ static void i830TexSetUnit( i830TextureObjectPtr t, GLuint unit ) if(I830_DEBUG&DEBUG_TEXTURE) fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); - /* This will need to be changed when I support more then 2 t units */ - I830_SET_FIELD(t->Setup[I830_TEXREG_MI1], - MAP_INFO_MASK | MAP_INFO_USE_PALETTE_1, - MAP_INFO_TEX(unit) | MAP_INFO_USE_PALETTE_N(unit)); - I830_SET_FIELD(t->Setup[I830_TEXREG_MLC], MAP_UNIT_MASK, MAP_UNIT(unit)); - I830_SET_FIELD(t->Setup[I830_TEXREG_MLL], MAP_UNIT_MASK, MAP_UNIT(unit)); + t->Setup[I830_TEXREG_TM0LI] = (STATE3D_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << unit) | 4); + I830_SET_FIELD(t->Setup[I830_TEXREG_MCS], MAP_UNIT_MASK, MAP_UNIT(unit)); - I830_SET_FIELD(t->Setup[I830_TEXREG_MF], MAP_UNIT_MASK, MAP_UNIT(unit)); t->current_unit = unit; } @@ -1279,7 +1330,8 @@ static void i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) imesa->TexEnabledMask &= ~(I830_TEX_UNIT_ENABLED(unit)); - if (texUnit->_ReallyEnabled == TEXTURE0_2D) { + if (texUnit->_ReallyEnabled == TEXTURE0_2D) + { struct gl_texture_object *tObj = texUnit->_Current; i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; GLuint mcs = t->Setup[I830_TEXREG_MCS] & TEXCOORDTYPE_MASK; @@ -1291,10 +1343,16 @@ static void i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) mcs |= TEXCOORDTYPE_CARTESIAN; } + /* Fallback if there's a texture border */ + if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) { + FALLBACK( imesa, I830_FALLBACK_TEXTURE, GL_TRUE ); + return; + } + /* Upload teximages (not pipelined) */ if (t->dirty_images) { - I830_FIREVERTICES(imesa); +/* I830_FIREVERTICES(imesa); */ i830SetTexImages( imesa, tObj ); if (!t->MemBlock) { FALLBACK( imesa, I830_FALLBACK_TEXTURE, GL_TRUE ); @@ -1314,13 +1372,17 @@ static void i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) } /* Update texture environment if texture object image format or - * texture environment state has changed. + * texture environment state has changed. + * + * KW: doesn't work -- change from tex0 only to tex0+tex1 gets + * missed (need to update last stage flag?). Call + * i830UpdateTexEnv always. */ if (tObj->Image[tObj->BaseLevel]->Format != imesa->TexEnvImageFmt[unit]) { imesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format; - i830UpdateTexEnv( ctx, unit ); } + i830UpdateTexEnv( ctx, unit ); imesa->TexEnabledMask |= I830_TEX_UNIT_ENABLED(unit); } else if (texUnit->_ReallyEnabled) { @@ -1374,7 +1436,8 @@ void i830UpdateTexUnitProj( GLcontext *ctx, GLuint unit, GLboolean state ) i830ContextPtr imesa = I830_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - if (texUnit->_ReallyEnabled == TEXTURE0_2D) { + if (texUnit->_ReallyEnabled == TEXTURE0_2D) + { struct gl_texture_object *tObj = texUnit->_Current; i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; GLuint mcs = t->Setup[I830_TEXREG_MCS] & TEXCOORDTYPE_MASK; diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_tris.c b/xc/lib/GL/mesa/src/drv/i830/i830_tris.c index 970fc0888..75745daa3 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_tris.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_tris.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tris.c,v 1.3 2002/09/11 00:29:26 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tris.c,v 1.4 2002/12/10 01:26:54 dawes Exp $ */ /************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. @@ -549,7 +549,7 @@ static void i830FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, #define POINT_FALLBACK (0) #define LINE_FALLBACK (DD_LINE_STIPPLE) -#define TRI_FALLBACK (DD_TRI_STIPPLE) +#define TRI_FALLBACK (0) #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\ DD_TRI_STIPPLE) #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) @@ -588,8 +588,9 @@ static void i830ChooseRenderState(GLcontext *ctx) if (flags & TRI_FALLBACK) imesa->draw_tri = i830_fallback_tri; - if (flags & DD_TRI_STIPPLE) + if ((flags & DD_TRI_STIPPLE) && !imesa->hw_stipple) { imesa->draw_tri = i830_fallback_tri; + } index |= I830_FALLBACK_BIT; } @@ -666,8 +667,10 @@ static void i830RunPipeline( GLcontext *ctx ) i830ContextPtr imesa = I830_CONTEXT(ctx); if (imesa->new_state) { - if (imesa->new_state & _NEW_TEXTURE) + if (imesa->new_state & _NEW_TEXTURE) { + I830_FIREVERTICES( imesa ); i830UpdateTextureState( ctx ); /* may modify imesa->new_state */ + } if (!imesa->Fallback) { if (imesa->new_state & _I830_NEW_VERTEX) @@ -710,6 +713,7 @@ void i830RasterPrimitive( GLcontext *ctx, { i830ContextPtr imesa = I830_CONTEXT(ctx); GLuint aa = imesa->Setup[I830_CTXREG_AA]; + GLuint st1 = imesa->StippleSetup[I830_STPREG_ST1]; aa &= ~AA_LINE_ENABLE; @@ -752,8 +756,13 @@ void i830RasterPrimitive( GLcontext *ctx, switch (rprim) { case GL_TRIANGLES: aa |= AA_LINE_DISABLE; + if (ctx->Polygon.StippleFlag) + st1 |= ST1_ENABLE; + else + st1 &= ~ST1_ENABLE; break; case GL_LINES: + st1 &= ~ST1_ENABLE; if (ctx->Line.SmoothFlag) { aa |= AA_LINE_ENABLE; } else { @@ -761,6 +770,7 @@ void i830RasterPrimitive( GLcontext *ctx, } break; case GL_POINTS: + st1 &= ~ST1_ENABLE; aa |= AA_LINE_DISABLE; break; default: @@ -771,10 +781,17 @@ void i830RasterPrimitive( GLcontext *ctx, if (aa != imesa->Setup[I830_CTXREG_AA]) { I830_STATECHANGE(imesa, I830_UPLOAD_CTX); - imesa->hw_primitive = hwprim; imesa->Setup[I830_CTXREG_AA] = aa; } - else if (hwprim != imesa->hw_primitive) { + +#if 0 + if (st1 != imesa->StippleSetup[I830_STPREG_ST1]) { + I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE); + imesa->StippleSetup[I830_STPREG_ST1] = st1; + } +#endif + + if (hwprim != imesa->hw_primitive) { I830_STATECHANGE(imesa, 0); imesa->hw_primitive = hwprim; } diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_vb.c b/xc/lib/GL/mesa/src/drv/i830/i830_vb.c index 532849abb..607ab877a 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_vb.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_vb.c @@ -23,7 +23,7 @@ * Adapted for use on the I830M: * Jeff Hartmann <jhartmann@2d3d.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_vb.c,v 1.4 2002/09/11 00:29:26 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_vb.c,v 1.5 2002/12/10 01:26:54 dawes Exp $ */ #include "glheader.h" #include "mtypes.h" @@ -491,13 +491,18 @@ void i830ChooseVertexState( GLcontext *ctx ) if (ctx->Fog.Enabled) ind |= I830_FOG_BIT; + /* unit 1 */ if (ctx->Texture._ReallyEnabled & TEXTURE1_ANY) ind |= I830_TEX1_BIT|I830_TEX0_BIT; + /* unit 0 */ else if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY) ind |= I830_TEX0_BIT; imesa->SetupIndex = ind; + if (I830_DEBUG & (DEBUG_VERTS|DEBUG_STATE)) + i830PrintSetupFlags( __FUNCTION__, ind ); + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { tnl->Driver.Render.Interp = i830_interp_extras; tnl->Driver.Render.CopyPV = i830_copy_pv_extras; diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile index f7e7ebc09..087c5f842 100644 --- a/xc/lib/GL/mesa/src/drv/mga/Imakefile +++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/mga/Imakefile,v 1.22 2002/02/23 00:45:50 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/mga/Imakefile,v 1.24 2002/11/25 14:04:51 eich Exp $ #include <Threads.tmpl> @@ -25,7 +25,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/mga/Imakefile,v 1.22 2002/02/23 00:45:50 #include "../../tnl/Imakefile.inc" #include "../../tnl_dd/Imakefile.inc" #include "../../Imakefile.inc" -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #include "../../X86/Imakefile.inc" #endif #ifdef SparcArchitecture @@ -42,8 +42,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/mga/Imakefile,v 1.22 2002/02/23 00:45:50 DRMOBJS = $(GLXLIBSRC)/dri/drm/xf86drm.o \ $(GLXLIBSRC)/dri/drm/xf86drmHash.o \ $(GLXLIBSRC)/dri/drm/xf86drmRandom.o \ - $(GLXLIBSRC)/dri/drm/xf86drmSL.o \ - $(GLXLIBSRC)/dri/drm/xf86drmMga.o + $(GLXLIBSRC)/dri/drm/xf86drmSL.o #ifdef GlxSoProf LOSRCS = ../../../../lowpc.c @@ -57,7 +56,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/mga/Imakefile,v 1.22 2002/02/23 00:45:50 OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(COREMESAOBJS) \ $(MESA_ASM_OBJS) $(COMMONOBJS) $(MGAOBJS) $(HIOBJS) -REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) +REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) $(XONLYLIB) #include <Library.tmpl> diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c index 191ae3a2f..eda7fa6c9 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.16 2002/09/15 21:07:49 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.18 2002/12/16 16:18:52 dawes Exp $ */ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifdef GLX_DIRECT_RENDERING @@ -31,7 +31,8 @@ #include <X11/Xlibint.h> #include <stdio.h> -#include "drm.h" +#include "xf86drm.h" +#include "mga_common.h" #include "mga_xmesa.h" #include "context.h" #include "matrix.h" @@ -120,6 +121,24 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) mgaScreen->sPriv = sPriv; sPriv->private = (void *)mgaScreen; + if (sPriv->drmMinor >= 1) { + int ret; + drmMGAGetParam gp; + + gp.param = MGA_PARAM_IRQ_NR; + gp.value = &mgaScreen->irq; + + ret = drmCommandWriteRead( sPriv->fd, DRM_MGA_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret); + XFree(mgaScreen); + sPriv->private = NULL; + return GL_FALSE; + } + } + + if (serverInfo->chipset != MGA_CARD_TYPE_G200 && serverInfo->chipset != MGA_CARD_TYPE_G400) { XFree(mgaScreen); @@ -269,7 +288,7 @@ mgaCreateContext( Display *dpy, const __GLcontextModes *mesaVis, mgaContextPtr mmesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private; - drm_mga_sarea_t *saPriv=(drm_mga_sarea_t*)(((char*)sPriv->pSAREA)+ + MGASAREAPrivPtr saPriv=(MGASAREAPrivPtr)(((char*)sPriv->pSAREA)+ mgaScreen->sarea_priv_offset); if (MGA_DEBUG&DEBUG_VERBOSE_DRI) diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h index 5220dd82e..558ab274f 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v 1.10 2002/02/22 21:33:05 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v 1.12 2002/12/16 16:18:52 dawes Exp $ */ #ifndef _MGA_INIT_H_ #define _MGA_INIT_H_ @@ -35,6 +35,7 @@ #include "dri_util.h" #include "mtypes.h" #include "mgaregs.h" +#include "mga_common.h" typedef struct mga_screen_private_s { @@ -45,6 +46,7 @@ typedef struct mga_screen_private_s { int cpp; /* for front and back buffers */ GLint agpMode; + unsigned int irq; /* IRQ number (0 means none) */ unsigned int mAccess; @@ -59,10 +61,10 @@ typedef struct mga_screen_private_s { unsigned int dmaOffset; - unsigned int textureOffset[MGA_NR_TEX_HEAPS]; - unsigned int textureSize[MGA_NR_TEX_HEAPS]; - int logTextureGranularity[MGA_NR_TEX_HEAPS]; - char *texVirtual[MGA_NR_TEX_HEAPS]; + unsigned int textureOffset[DRM_MGA_NR_TEX_HEAPS]; + unsigned int textureSize[DRM_MGA_NR_TEX_HEAPS]; + int logTextureGranularity[DRM_MGA_NR_TEX_HEAPS]; + char *texVirtual[DRM_MGA_NR_TEX_HEAPS]; __DRIscreenPrivate *sPriv; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c index 444cb2bac..70a78fcb1 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.11 2002/09/11 19:49:07 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.13 2002/11/05 17:46:08 tsi Exp $ */ #include <stdio.h> #include "mgacontext.h" diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h index fc0777243..ba7e0504a 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.h,v 1.6 2002/09/11 19:49:07 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.h,v 1.7 2002/10/30 12:51:35 alanh Exp $ */ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifndef MGA_BUFFERS_H diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h index 69eaa47c6..892d47a0a 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.5 2002/02/22 21:33:06 dawes Exp $*/ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.7 2002/12/16 16:18:52 dawes Exp $*/ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifndef MGALIB_INC @@ -32,7 +32,7 @@ #include <X11/Xlibint.h> #include "dri_util.h" #include "mtypes.h" -#include "drm.h" +#include "xf86drm.h" #include "mm.h" #include "mem.h" #include "mga_sarea.h" @@ -120,7 +120,7 @@ typedef struct mga_texture_object_s struct mga_context_t { GLcontext *glCtx; - GLuint lastStamp; /* fullscreen breaks dpriv->laststamp, + unsigned int lastStamp; /* fullscreen breaks dpriv->laststamp, * need to shadow it here. */ /* Bookkeeping for texturing @@ -202,6 +202,9 @@ struct mga_context_t { drmBufPtr vertex_dma_buffer; drmBufPtr iload_buffer; + /* VBI + */ + GLuint vbl_seq; /* Drawable, cliprect and scissor information */ diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.c b/xc/lib/GL/mesa/src/drv/mga/mgadd.c index 6f4f23836..6ce50e672 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadd.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.c @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.c,v 1.13 2002/09/11 19:49:07 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.c,v 1.14 2002/10/30 12:51:35 alanh Exp $ */ #include "mtypes.h" @@ -137,15 +137,17 @@ void mgaDDExtensionsInit( GLcontext *ctx ) _mesa_enable_extension( ctx, "GL_EXT_paletted_texture" ); */ - /* Support multitexture only on the g400. + _mesa_enable_extension( ctx, "GL_ARB_texture_compression" ); + _mesa_enable_extension( ctx, "GL_ARB_multisample" ); + + _mesa_enable_extension( ctx, "GL_SGIS_generate_mipmap" ); + + /* Turn on multitexture and texenv_add for the G400. */ if (MGA_IS_G400(MGA_CONTEXT(ctx))) { _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); - } + _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" ); - /* Turn on texenv_add for the G400. - */ - if (MGA_IS_G400(MGA_CONTEXT(ctx))) { _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); #if defined (MESA_packed_depth_stencil) @@ -164,5 +166,6 @@ void mgaDDExtensionsInit( GLcontext *ctx ) void mgaDDInitDriverFuncs( GLcontext *ctx ) { ctx->Driver.GetBufferSize = mgaBufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; ctx->Driver.GetString = mgaDDGetString; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.h b/xc/lib/GL/mesa/src/drv/mga/mgadd.h index c6e27f8a6..6072e6cfc 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadd.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.h,v 1.2 2001/04/10 16:07:50 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.h,v 1.3 2002/10/30 12:51:35 alanh Exp $ */ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifndef MGADD_INC diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c index 07b5052fe..a21a39793 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c @@ -22,10 +22,10 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * Gareth Hughes <gareth@valinux.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.14 2002/09/18 17:11:40 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.16 2002/12/16 16:18:52 dawes Exp $ */ #include <stdio.h> @@ -45,21 +45,31 @@ #include "mgabuffers.h" -#include "drm.h" -#include "xf86drmMga.h" +#include "xf86drm.h" +#include "mga_common.h" static void mga_iload_dma_ioctl(mgaContextPtr mmesa, unsigned long dest, int length) { drmBufPtr buf = mmesa->iload_buffer; - int ret; + drmMGAIload iload; + int ret, i; if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n", buf->idx, (int) dest, length); - ret = drmMGATextureLoad( mmesa->driFd, buf->idx, dest, length ); + iload.idx = buf->idx; + iload.dstorg = dest; + iload.length = length; + + i = 0; + do { + ret = drmCommandWrite( mmesa->driFd, DRM_MGA_ILOAD, + &iload, sizeof(drmMGAIload) ); + } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); + if ( ret < 0 ) { printf("send iload retcode = %d\n", ret); exit(1); @@ -155,6 +165,7 @@ mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, int ret; int i; static int nrclears; + drmMGAClearRec clear; FLUSH_BATCH( mmesa ); @@ -242,9 +253,13 @@ mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, mmesa->sarea->nbox = n; - ret = drmMGAClear( mmesa->driFd, flags, - clear_color, clear_depth, - color_mask, depth_mask ); + clear.flags = flags; + clear.clear_color = clear_color; + clear.clear_depth = clear_depth; + clear.color_mask = color_mask; + clear.depth_mask = depth_mask; + ret = drmCommandWrite( mmesa->driFd, DRM_MGA_CLEAR, + &clear, sizeof(drmMGAClearRec)); if ( ret ) { fprintf( stderr, "send clear retcode = %d\n", ret ); exit( 1 ); @@ -254,7 +269,7 @@ mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } UNLOCK_HARDWARE( mmesa ); - mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS|MGA_UPLOAD_CONTEXT; } if (mask) @@ -265,6 +280,36 @@ mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, int nrswaps; +void mgaWaitForVBlank( mgaContextPtr mmesa ) +{ + drmVBlank vbl; + int ret; + + if ( !mmesa->mgaScreen->irq ) + return; + + if ( getenv("LIBGL_SYNC_REFRESH") ) { + /* Wait for until the next vertical blank */ + vbl.request.type = DRM_VBLANK_RELATIVE; + vbl.request.sequence = 1; + } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { + /* Wait for at least one vertical blank since the last call */ + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = mmesa->vbl_seq + 1; + } else { + return; + } + + if ((ret = drmWaitVBlank( mmesa->driFd, &vbl ))) { + fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" + " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" + " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); + exit(1); + } + + mmesa->vbl_seq = vbl.reply.sequence; +} + /* * Copy the back buffer to the front buffer. @@ -287,6 +332,8 @@ void mgaSwapBuffers(Display *dpy, void *drawablePrivate) FLUSH_BATCH( mmesa ); + mgaWaitForVBlank( mmesa ); + LOCK_HARDWARE( mmesa ); last_frame = mmesa->sarea->last_frame.head; @@ -340,7 +387,7 @@ void mgaSwapBuffers(Display *dpy, void *drawablePrivate) if (0) fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n"); - ret = drmMGASwapBuffers( mmesa->driFd ); + ret = drmCommandNone( mmesa->driFd, DRM_MGA_SWAP ); if ( ret ) { printf("send swap retcode = %d\n", ret); exit(1); @@ -425,6 +472,7 @@ void mgaFlushVerticesLocked( mgaContextPtr mmesa ) XF86DRIClipRectPtr pbox = mmesa->pClipRects; int nbox = mmesa->numClipRects; drmBufPtr buffer = mmesa->vertex_dma_buffer; + drmMGAVertex vertex; int i; mmesa->vertex_dma_buffer = 0; @@ -459,7 +507,12 @@ void mgaFlushVerticesLocked( mgaContextPtr mmesa ) if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox); - drmMGAFlushVertexBuffer( mmesa->driFd, buffer->idx, buffer->used, 1 ); + vertex.idx = buffer->idx; + vertex.used = buffer->used; + vertex.discard = 1; + drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, + &vertex, sizeof(drmMGAVertex) ); + age_mmesa(mmesa, mmesa->sarea->last_enqueue); } else @@ -500,8 +553,13 @@ void mgaFlushVerticesLocked( mgaContextPtr mmesa ) discard = 1; mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS; - drmMGAFlushVertexBuffer( mmesa->driFd, buffer->idx, - buffer->used, discard ); + + vertex.idx = buffer->idx; + vertex.used = buffer->used; + vertex.discard = discard; + drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, + &vertex, sizeof(drmMGAVertex) ); + age_mmesa(mmesa, mmesa->sarea->last_enqueue); } } @@ -577,11 +635,53 @@ void mgaDDFlush( GLcontext *ctx ) void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer ) { + drmMGAVertex vertex; + if (!buffer) return; - drmMGAFlushVertexBuffer( mmesa->driFd, buffer->idx, 0, 1 ); + vertex.idx = buffer->idx; + vertex.used = 0; + vertex.discard = 1; + drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, + &vertex, sizeof(drmMGAVertex) ); } +int mgaFlushDMA( int fd, drmLockFlags flags ) +{ + drmMGALock lock; + int ret, i = 0; + + memset( &lock, 0, sizeof(drmMGALock) ); + + if ( flags & DRM_LOCK_QUIESCENT ) lock.flags |= DRM_LOCK_QUIESCENT; + if ( flags & DRM_LOCK_FLUSH ) lock.flags |= DRM_LOCK_FLUSH; + if ( flags & DRM_LOCK_FLUSH_ALL ) lock.flags |= DRM_LOCK_FLUSH_ALL; + + do { + ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(drmMGALock) ); + } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY ); + + if ( ret == 0 ) + return 0; + if ( errno != EBUSY ) + return -errno; + + if ( lock.flags & DRM_LOCK_QUIESCENT ) { + /* Only keep trying if we need quiescence. + */ + lock.flags &= ~(DRM_LOCK_FLUSH | DRM_LOCK_FLUSH_ALL); + + do { + ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(drmMGALock) ); + } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY ); + } + + if ( ret == 0 ) { + return 0; + } else { + return -errno; + } +} void mgaDDInitIoctlFuncs( GLcontext *ctx ) { diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h index 0fcd9f67e..7f5fb1c6c 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h @@ -22,10 +22,10 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * Gareth Hughes <gareth@valinux.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v 1.10 2002/09/18 17:11:41 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v 1.11 2002/10/30 12:51:36 alanh Exp $ */ #ifndef MGA_IOCTL_H #define MGA_IOCTL_H @@ -51,6 +51,7 @@ void mgaWaitAge( mgaContextPtr mmesa, int age ); void mgaFlushVertices( mgaContextPtr mmesa ); void mgaFlushVerticesLocked( mgaContextPtr mmesa ); void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer ); +int mgaFlushDMA( int fd, drmLockFlags flags ); void mgaDDFlush( GLcontext *ctx ); void mgaDDFinish( GLcontext *ctx ); @@ -98,9 +99,9 @@ GLuint *mgaAllocDmaLow( mgaContextPtr mmesa, int bytes ) #define UPDATE_LOCK( mmesa, flags ) \ do { \ - GLint ret = drmMGAFlushDMA( mmesa->driFd, flags ); \ + GLint ret = mgaFlushDMA( mmesa->driFd, flags ); \ if ( ret < 0 ) { \ - drmMGAEngineReset( mmesa->driFd ); \ + drmCommandNone( mmesa->driFd, DRM_MGA_RESET ); \ UNLOCK_HARDWARE( mmesa ); \ fprintf( stderr, "%s: flush ret=%d\n", __FUNCTION__, ret ); \ /*fprintf( stderr, "drmMGAFlushDMA: return = %d\n", ret );*/ \ diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapixel.c b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c index 7ab1fb0ad..49692e0e2 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgapixel.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c @@ -22,10 +22,10 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * Gareth Hughes <gareth@valinux.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.c,v 1.7 2002/09/18 17:11:41 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.c,v 1.9 2002/11/05 17:46:08 tsi Exp $ */ #include "enums.h" #include "mtypes.h" @@ -37,8 +37,8 @@ #include "mgapixel.h" #include "mgabuffers.h" -#include "drm.h" -#include "xf86drmMga.h" +#include "xf86drm.h" +#include "mga_common.h" #include "swrast/swrast.h" @@ -220,9 +220,6 @@ mgaTryReadPixels( GLcontext *ctx, GLvoid *pixels ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); -#if 0 - drm_mga_blit_t blit; -#endif GLint size, skipPixels, skipRows; GLint pitch = pack->RowLength ? pack->RowLength : width; GLboolean ok; @@ -230,6 +227,7 @@ mgaTryReadPixels( GLcontext *ctx, GLuint planemask; GLuint source; #if 0 + drmMGABlit blit; GLuint dest; GLint source_pitch, dest_pitch; GLint delta_sx, delta_sy; @@ -357,7 +355,8 @@ mgaTryReadPixels( GLcontext *ctx, mmesa->sarea->nbox = n; - if (n && (retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_BLIT, &blit))) { + if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT, + &blit, sizeof(drmMGABlit)))) { fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode); UNLOCK_HARDWARE( mmesa ); exit(1); @@ -393,20 +392,18 @@ static void do_draw_pix( GLcontext *ctx, const void *pixels, GLuint dest, GLuint planemask) { +#if 0 mgaContextPtr mmesa = MGA_CONTEXT(ctx); + drmMGABlit blit; __DRIdrawablePrivate *dPriv = mmesa->driDrawable; -#if 0 - drm_mga_blit_t blit; XF86DRIClipRectPtr pbox = dPriv->pClipRects; int nbox = dPriv->numClipRects; int retcode, i; -#endif y = dPriv->h - y - height; x += mmesa->drawX; y += mmesa->drawY; -#if 0 blit.dest = dest; blit.planemask = planemask; blit.source = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels)) @@ -459,7 +456,8 @@ static void do_draw_pix( GLcontext *ctx, mmesa->sarea->nbox = n; - if (n && (retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_BLIT, &blit))) { + if (n && (retcode = drmCommandWrite( mmesa->driFd, DRM_MGA_BLIT, + &blit, sizeof(drmMGABlit)))) { fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode); UNLOCK_HARDWARE( mmesa ); exit(1); @@ -684,7 +682,6 @@ void mgaDDInitPixelFuncs( GLcontext *ctx ) ctx->Driver.CopyPixels = _swrast_CopyPixels; ctx->Driver.DrawPixels = _swrast_DrawPixels; ctx->Driver.ReadPixels = _swrast_ReadPixels; - ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; if (getenv("MGA_BLIT_PIXELS")) { ctx->Driver.ReadPixels = mgaDDReadPixels; /* requires agp dest */ diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapixel.h b/xc/lib/GL/mesa/src/drv/mga/mgapixel.h index 3b6f5a4ad..c44fd769a 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgapixel.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgapixel.h @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.h,v 1.4 2002/02/22 21:33:07 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.h,v 1.5 2002/10/30 12:51:36 alanh Exp $ */ #ifndef MGA_PIXELS_H #define MGA_PIXELS_H diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaregs.h b/xc/lib/GL/mesa/src/drv/mga/mgaregs.h index 6e381a9cc..f07dc2de0 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaregs.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaregs.h @@ -19,6 +19,7 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaregs.h,v 1.6 2003/01/12 03:55:46 tsi Exp $ */ #ifndef _MGAREGS_H_ #define _MGAREGS_H_ @@ -37,128 +38,128 @@ #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 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 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 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 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 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 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 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 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 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 AR6_ar6_MASK 0xfffc0000 /* bits 0-17 */ +# define AR6_ar6_SHIFT 0 #define MGAREG_BCOL 0x1c20 #define MGAREG_BESA1CORG 0x3d10 @@ -171,145 +172,145 @@ #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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 BVISF_besviscal_MASK 0xffe00003 /* bits 2-20 */ +# define BVISF_besviscal_SHIFT 2 #define MGAREG_CODECADDR 0x3e44 #define MGAREG_CODECCTL 0x3e40 @@ -318,10 +319,10 @@ #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 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 @@ -350,95 +351,95 @@ #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 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 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 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 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 @@ -446,251 +447,251 @@ #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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 STH_softraphand_MASK 0x3 /* bits 2-31 */ +# define STH_softraphand_SHIFT 2 #define MGAREG_SPECBSTART 0x2c98 #define MGAREG_SPECBXINC 0x2c9c @@ -707,466 +708,466 @@ #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 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 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 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 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 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 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 TST_ramtsten_MASK 0xfffffffe /* bit 0 */ +# define TST_ramtsten_disable 0x0 +# define TST_ramtsten_enable 0x1 +# define TST_ramtstdone_MASK 0xfffffffd /* bit 1 */ +# define TST_ramtstdone_disable 0x0 +# define TST_ramtstdone_enable 0x2 +# define TST_wramtstpass_MASK 0xfffffffb /* bit 2 */ +# define TST_wramtstpass_disable 0x0 +# define TST_wramtstpass_enable 0x4 +# define TST_tcachetstpass_MASK 0xfffffff7 /* bit 3 */ +# define TST_tcachetstpass_disable 0x0 +# define TST_tcachetstpass_enable 0x8 +# define TST_tluttstpass_MASK 0xffffffef /* bit 4 */ +# define TST_tluttstpass_disable 0x0 +# define TST_tluttstpass_enable 0x10 +# define TST_luttstpass_MASK 0xffffffdf /* bit 5 */ +# define TST_luttstpass_disable 0x0 +# define TST_luttstpass_enable 0x20 +# define TST_besramtstpass_MASK 0xffffffbf /* bit 6 */ +# define TST_besramtstpass_disable 0x0 +# define TST_besramtstpass_enable 0x40 +# define TST_ringen_MASK 0xfffffeff /* bit 8 */ +# define TST_ringen_disable 0x0 +# define TST_ringen_enable 0x100 +# define TST_apllbyp_MASK 0xfffffdff /* bit 9 */ +# define TST_apllbyp_disable 0x0 +# define TST_apllbyp_enable 0x200 +# define TST_hiten_MASK 0xfffffbff /* bit 10 */ +# define TST_hiten_disable 0x0 +# define TST_hiten_enable 0x400 +# define TST_tmode_MASK 0xffffc7ff /* bits 11-13 */ +# define TST_tmode_SHIFT 11 +# define TST_tclksel_MASK 0xfffe3fff /* bits 14-16 */ +# define TST_tclksel_SHIFT 14 +# define TST_ringcnten_MASK 0xfffdffff /* bit 17 */ +# define TST_ringcnten_disable 0x0 +# define TST_ringcnten_enable 0x20000 +# define TST_ringcnt_MASK 0xc003ffff /* bits 18-29 */ +# define TST_ringcnt_SHIFT 18 +# define TST_ringcntclksl_MASK 0xbfffffff /* bit 30 */ +# define TST_ringcntclksl_disable 0x0 +# define TST_ringcntclksl_enable 0x40000000 +# define TST_biosboot_MASK 0x7fffffff /* bit 31 */ +# define TST_biosboot_disable 0x0 +# define TST_biosboot_enable 0x80000000 #define MGAREG_TEXBORDERCOL 0x2c5c #define MGAREG_TEXCTL 0x2c30 - #define TMC_tformat_MASK 0xfffffff0 /* bits 0-3 */ - #define TMC_tformat_tw4 0x0 /* val 0, shift 0 */ - #define TMC_tformat_tw8 0x1 /* val 1, shift 0 */ - #define TMC_tformat_tw15 0x2 /* val 2, shift 0 */ - #define TMC_tformat_tw16 0x3 /* val 3, shift 0 */ - #define TMC_tformat_tw12 0x4 /* val 4, shift 0 */ - #define TMC_tformat_tw32 0x6 /* val 6, shift 0 */ - #define TMC_tformat_tw8a 0x7 /* val 7, shift 0 */ - #define TMC_tformat_tw8al 0x8 /* val 8, shift 0 */ - #define TMC_tformat_tw422 0xa /* val 10, shift 0 */ - #define TMC_tpitchlin_MASK 0xfffffeff /* bit 8 */ - #define TMC_tpitchlin_disable 0x0 - #define TMC_tpitchlin_enable 0x100 - #define TMC_tpitchext_MASK 0xfff001ff /* bits 9-19 */ - #define TMC_tpitchext_SHIFT 9 - #define TMC_tpitch_MASK 0xfff8ffff /* bits 16-18 */ - #define TMC_tpitch_SHIFT 16 - #define TMC_owalpha_MASK 0xffbfffff /* bit 22 */ - #define TMC_owalpha_disable 0x0 - #define TMC_owalpha_enable 0x400000 - #define TMC_azeroextend_MASK 0xff7fffff /* bit 23 */ - #define TMC_azeroextend_disable 0x0 - #define TMC_azeroextend_enable 0x800000 - #define TMC_decalckey_MASK 0xfeffffff /* bit 24 */ - #define TMC_decalckey_disable 0x0 - #define TMC_decalckey_enable 0x1000000 - #define TMC_takey_MASK 0xfdffffff /* bit 25 */ - #define TMC_takey_0 0x0 - #define TMC_takey_1 0x2000000 - #define TMC_tamask_MASK 0xfbffffff /* bit 26 */ - #define TMC_tamask_0 0x0 - #define TMC_tamask_1 0x4000000 - #define TMC_clampv_MASK 0xf7ffffff /* bit 27 */ - #define TMC_clampv_disable 0x0 - #define TMC_clampv_enable 0x8000000 - #define TMC_clampu_MASK 0xefffffff /* bit 28 */ - #define TMC_clampu_disable 0x0 - #define TMC_clampu_enable 0x10000000 - #define TMC_tmodulate_MASK 0xdfffffff /* bit 29 */ - #define TMC_tmodulate_disable 0x0 - #define TMC_tmodulate_enable 0x20000000 - #define TMC_strans_MASK 0xbfffffff /* bit 30 */ - #define TMC_strans_disable 0x0 - #define TMC_strans_enable 0x40000000 - #define TMC_itrans_MASK 0x7fffffff /* bit 31 */ - #define TMC_itrans_disable 0x0 - #define TMC_itrans_enable 0x80000000 +# define TMC_tformat_MASK 0xfffffff0 /* bits 0-3 */ +# define TMC_tformat_tw4 0x0 /* val 0, shift 0 */ +# define TMC_tformat_tw8 0x1 /* val 1, shift 0 */ +# define TMC_tformat_tw15 0x2 /* val 2, shift 0 */ +# define TMC_tformat_tw16 0x3 /* val 3, shift 0 */ +# define TMC_tformat_tw12 0x4 /* val 4, shift 0 */ +# define TMC_tformat_tw32 0x6 /* val 6, shift 0 */ +# define TMC_tformat_tw8a 0x7 /* val 7, shift 0 */ +# define TMC_tformat_tw8al 0x8 /* val 8, shift 0 */ +# define TMC_tformat_tw422 0xa /* val 10, shift 0 */ +# define TMC_tpitchlin_MASK 0xfffffeff /* bit 8 */ +# define TMC_tpitchlin_disable 0x0 +# define TMC_tpitchlin_enable 0x100 +# define TMC_tpitchext_MASK 0xfff001ff /* bits 9-19 */ +# define TMC_tpitchext_SHIFT 9 +# define TMC_tpitch_MASK 0xfff8ffff /* bits 16-18 */ +# define TMC_tpitch_SHIFT 16 +# define TMC_owalpha_MASK 0xffbfffff /* bit 22 */ +# define TMC_owalpha_disable 0x0 +# define TMC_owalpha_enable 0x400000 +# define TMC_azeroextend_MASK 0xff7fffff /* bit 23 */ +# define TMC_azeroextend_disable 0x0 +# define TMC_azeroextend_enable 0x800000 +# define TMC_decalckey_MASK 0xfeffffff /* bit 24 */ +# define TMC_decalckey_disable 0x0 +# define TMC_decalckey_enable 0x1000000 +# define TMC_takey_MASK 0xfdffffff /* bit 25 */ +# define TMC_takey_0 0x0 +# define TMC_takey_1 0x2000000 +# define TMC_tamask_MASK 0xfbffffff /* bit 26 */ +# define TMC_tamask_0 0x0 +# define TMC_tamask_1 0x4000000 +# define TMC_clampv_MASK 0xf7ffffff /* bit 27 */ +# define TMC_clampv_disable 0x0 +# define TMC_clampv_enable 0x8000000 +# define TMC_clampu_MASK 0xefffffff /* bit 28 */ +# define TMC_clampu_disable 0x0 +# define TMC_clampu_enable 0x10000000 +# define TMC_tmodulate_MASK 0xdfffffff /* bit 29 */ +# define TMC_tmodulate_disable 0x0 +# define TMC_tmodulate_enable 0x20000000 +# define TMC_strans_MASK 0xbfffffff /* bit 30 */ +# define TMC_strans_disable 0x0 +# define TMC_strans_enable 0x40000000 +# define TMC_itrans_MASK 0x7fffffff /* bit 31 */ +# define TMC_itrans_disable 0x0 +# define TMC_itrans_enable 0x80000000 #define MGAREG_TEXCTL2 0x2c3c - #define TMC_decalblend_MASK 0xfffffffe /* bit 0 */ - #define TMC_decalblend_disable 0x0 - #define TMC_decalblend_enable 0x1 - #define TMC_idecal_MASK 0xfffffffd /* bit 1 */ - #define TMC_idecal_disable 0x0 - #define TMC_idecal_enable 0x2 - #define TMC_decaldis_MASK 0xfffffffb /* bit 2 */ - #define TMC_decaldis_disable 0x0 - #define TMC_decaldis_enable 0x4 - #define TMC_ckstransdis_MASK 0xffffffef /* bit 4 */ - #define TMC_ckstransdis_disable 0x0 - #define TMC_ckstransdis_enable 0x10 - #define TMC_borderen_MASK 0xffffffdf /* bit 5 */ - #define TMC_borderen_disable 0x0 - #define TMC_borderen_enable 0x20 - #define TMC_specen_MASK 0xffffffbf /* bit 6 */ - #define TMC_specen_disable 0x0 - #define TMC_specen_enable 0x40 - #define TMC_dualtex_MASK 0xffffff7f /* bit 7 */ - #define TMC_dualtex_disable 0x0 - #define TMC_dualtex_enable 0x80 - #define TMC_tablefog_MASK 0xfffffeff /* bit 8 */ - #define TMC_tablefog_disable 0x0 - #define TMC_tablefog_enable 0x100 - #define TMC_bumpmap_MASK 0xfffffdff /* bit 9 */ - #define TMC_bumpmap_disable 0x0 - #define TMC_bumpmap_enable 0x200 - #define TMC_map1_MASK 0x7fffffff /* bit 31 */ - #define TMC_map1_disable 0x0 - #define TMC_map1_enable 0x80000000 +# define 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 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 TH_th_MASK 0xffffffc0 /* bits 0-5 */ +# define TH_th_SHIFT 0 +# define TH_rfh_MASK 0xffff81ff /* bits 9-14 */ +# define TH_rfh_SHIFT 9 +# define TH_thmask_MASK 0xe003ffff /* bits 18-28 */ +# define TH_thmask_SHIFT 18 #define MGAREG_TEXORG 0x2c24 - #define TO_texorgmap_MASK 0xfffffffe /* bit 0 */ - #define TO_texorgmap_fb 0x0 - #define TO_texorgmap_sys 0x1 - #define TO_texorgacc_MASK 0xfffffffd /* bit 1 */ - #define TO_texorgacc_pci 0x0 - #define TO_texorgacc_agp 0x2 - #define TO_texorgoffsetsel 0x4 - #define TO_texorg_MASK 0x1f /* bits 5-31 */ - #define TO_texorg_SHIFT 5 +# define TO_texorgmap_MASK 0xfffffffe /* bit 0 */ +# define TO_texorgmap_fb 0x0 +# define TO_texorgmap_sys 0x1 +# define TO_texorgacc_MASK 0xfffffffd /* bit 1 */ +# define TO_texorgacc_pci 0x0 +# define TO_texorgacc_agp 0x2 +# define TO_texorgoffsetsel 0x4 +# define TO_texorg_MASK 0x1f /* bits 5-31 */ +# define TO_texorg_SHIFT 5 #define MGAREG_TEXORG1 0x2ca4 #define MGAREG_TEXORG2 0x2ca8 @@ -1174,26 +1175,26 @@ #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 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 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 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 @@ -1209,167 +1210,167 @@ #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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 +# 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 diff --git a/xc/lib/GL/mesa/src/drv/mga/mgarender.c b/xc/lib/GL/mesa/src/drv/mga/mgarender.c index 928d278b2..2e6f793a2 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgarender.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgarender.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgarender.c,v 1.3 2002/02/22 21:37:18 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgarender.c,v 1.4 2002/10/30 12:51:36 alanh Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c index c06914006..89b820044 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.10 2002/02/26 23:37:35 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.11 2002/10/30 12:51:36 alanh Exp $ */ #include "mtypes.h" #include "mgadd.h" @@ -33,8 +33,6 @@ #include "mgaioctl.h" #include "swrast/swrast.h" -#include "xf86drmMga.h" - #define DBG 0 diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.h b/xc/lib/GL/mesa/src/drv/mga/mgaspan.h index 16bbf2f67..80583daca 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaspan.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.h,v 1.2 2001/04/10 16:07:51 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.h,v 1.3 2002/10/30 12:51:36 alanh Exp $ */ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifndef _MGA_SPAN_H diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c index 8c47cd111..3435f3c19 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.12 2002/02/22 21:44:55 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.13 2002/10/30 12:51:36 alanh Exp $ */ #include <stdio.h> diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.h b/xc/lib/GL/mesa/src/drv/mga/mgastate.h index 5e4a0780b..a9f1039d7 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.h,v 1.4 2002/02/22 21:44:55 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.h,v 1.5 2002/10/30 12:51:36 alanh Exp $ */ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifndef _MGA_STATE_H diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c index 8a8daee32..0ba5e65cb 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.13 2002/02/22 21:44:55 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.14 2002/10/30 12:51:36 alanh Exp $ */ #include <stdlib.h> #include <stdio.h> @@ -189,8 +189,9 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, * got to be better than sticking them way down the end of this * huge list. */ - case GL_RGBA: case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: if ( format == GL_BGRA ) { if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { SET_FORMAT( TMC_tformat_tw32, _mesa_texformat_argb8888 ); @@ -207,8 +208,9 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, TMC_tformat_tw12, _mesa_texformat_argb4444 ); break; - case GL_RGB: case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); break; @@ -256,6 +258,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: /* FIXME: This will report incorrect component sizes... */ SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); break; @@ -266,6 +269,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, case GL_LUMINANCE8: case GL_LUMINANCE12: case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: /* FIXME: This will report incorrect component sizes... */ SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); break; @@ -278,6 +282,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, case GL_LUMINANCE12_ALPHA4: case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: /* FIXME: This will report incorrect component sizes... */ SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); break; @@ -287,6 +292,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, case GL_INTENSITY8: case GL_INTENSITY12: case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: /* FIXME: This will report incorrect component sizes... */ SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); break; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.h b/xc/lib/GL/mesa/src/drv/mga/mgatex.h index 7180ef77d..c9f87d997 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.h,v 1.6 2001/04/10 16:07:51 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.h,v 1.7 2002/10/30 12:51:36 alanh Exp $ */ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifndef MGATEX_INC diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c b/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c index aa26d181e..d561df37c 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c,v 1.2 2001/04/10 16:07:51 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c,v 1.3 2002/10/30 12:51:36 alanh Exp $ */ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #include <stdlib.h> diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c b/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c index 641f29e14..332afd04e 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexmem.c,v 1.6 2002/02/26 23:37:35 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexmem.c,v 1.7 2002/10/30 12:51:36 alanh Exp $ */ #include <stdlib.h> #include <stdio.h> @@ -39,8 +39,6 @@ #include "mem.h" #include "simple_list.h" -#include "xf86drmMga.h" - static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t) { diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c index 17a8f69a1..e47cfc171 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.9 2002/02/22 21:44:56 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.10 2002/10/30 12:51:36 alanh Exp $ */ #include <stdio.h> #include <math.h> @@ -665,9 +665,9 @@ static void mgaFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, int i,j; for (i = 2 ; i < n ; i++) { - EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) start ); EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i-1]) ); EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i]) ); + EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) start ); } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.h b/xc/lib/GL/mesa/src/drv/mga/mgatris.h index fba87485d..88eda91e1 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.h @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.h,v 1.9 2002/02/22 21:44:56 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.h,v 1.10 2002/10/30 12:51:36 alanh Exp $ */ #ifndef MGATRIS_INC #define MGATRIS_INC diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c index f5d7e7e40..7d09ada1f 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c @@ -22,9 +22,9 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.13 2002/02/26 23:37:35 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.14 2002/10/30 12:51:36 alanh Exp $ */ #include "mgacontext.h" #include "mgavb.h" @@ -88,11 +88,12 @@ static struct { #define VERTEX mgaVertex +#define VERTEX_COLOR mga_color_t #define LOCALVARS mgaContextPtr mmesa = MGA_CONTEXT(ctx); #define GET_VIEWPORT_MAT() mmesa->hw_viewport #define GET_TEXSOURCE(n) mmesa->tmu_source[n] #define GET_VERTEX_FORMAT() mmesa->vertex_format -#define GET_VERTEX_STORE() (GLubyte *)(mmesa->verts) +#define GET_VERTEX_STORE() mmesa->verts #define GET_VERTEX_STRIDE_SHIFT() mmesa->vertex_stride_shift #define GET_UBYTE_COLOR_STORE() &mmesa->UbyteColor #define GET_UBYTE_SPEC_COLOR_STORE() &mmesa->UbyteSecondaryColor @@ -124,8 +125,8 @@ static struct { #define IMPORT_FLOAT_COLORS mga_import_float_colors #define IMPORT_FLOAT_SPEC_COLORS mga_import_float_spec_colors -#define INTERP_VERTEX setup_tab[mmesa->SetupIndex].interp -#define COPY_PV_VERTEX setup_tab[mmesa->SetupIndex].copy_pv +#define INTERP_VERTEX setup_tab[MGA_CONTEXT(ctx)->SetupIndex].interp +#define COPY_PV_VERTEX setup_tab[MGA_CONTEXT(ctx)->SetupIndex].copy_pv /*********************************************************************** @@ -406,15 +407,15 @@ void mgaChooseVertexState( GLcontext *ctx ) if (ctx->Fog.Enabled) ind |= MGA_FOG_BIT; - if (ctx->Texture._ReallyEnabled & 0xf0) { - if (ctx->Texture._ReallyEnabled & 0xf) { + if (ctx->Texture._ReallyEnabled & TEXTURE1_ANY) { + if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY) { ind |= MGA_TEX1_BIT|MGA_TEX0_BIT; } else { ind |= MGA_TEX0_BIT; } } - else if (ctx->Texture._ReallyEnabled & 0xf) { + else if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY) { ind |= MGA_TEX0_BIT; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.h b/xc/lib/GL/mesa/src/drv/mga/mgavb.h index c1240a4ef..88cc3108d 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.h,v 1.7 2002/02/22 21:44:56 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.h,v 1.8 2002/10/30 12:51:36 alanh Exp $ */ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifndef MGAVB_INC diff --git a/xc/lib/GL/mesa/src/drv/r128/Imakefile b/xc/lib/GL/mesa/src/drv/r128/Imakefile index ff032a38a..30570971b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/Imakefile +++ b/xc/lib/GL/mesa/src/drv/r128/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.19 2002/02/23 00:45:50 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.21 2002/11/25 14:04:51 eich Exp $ #include <Threads.tmpl> @@ -25,7 +25,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.19 2002/02/23 00:45:50 #include "../../tnl/Imakefile.inc" #include "../../tnl_dd/Imakefile.inc" #include "../../Imakefile.inc" -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #include "../../X86/Imakefile.inc" #endif #ifdef SparcArchitecture @@ -41,8 +41,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.19 2002/02/23 00:45:50 DRMOBJS = $(GLXLIBSRC)/dri/drm/xf86drm.o \ $(GLXLIBSRC)/dri/drm/xf86drmHash.o \ $(GLXLIBSRC)/dri/drm/xf86drmRandom.o \ - $(GLXLIBSRC)/dri/drm/xf86drmSL.o \ - $(GLXLIBSRC)/dri/drm/xf86drmR128.o + $(GLXLIBSRC)/dri/drm/xf86drmSL.o #ifdef GlxSoProf LOSRCS = ../../../../lowpc.c @@ -56,7 +55,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.19 2002/02/23 00:45:50 OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(COREMESAOBJS) \ $(MESA_ASM_OBJS) $(COMMONOBJS) $(R128OBJS) $(HIOBJS) -REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) +REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) $(XONLYLIB) #include <Library.tmpl> diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c index 38342be45..7ee6e8d4f 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.c,v 1.7 2002/02/22 21:44:57 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.c,v 1.8 2002/10/30 12:51:38 alanh Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -218,6 +218,7 @@ void r128DestroyContext( __DRIcontextPrivate *driContextPriv ) r128DestroyTexObj( rmesa, t ); } mmDestroy( rmesa->texHeap[i] ); + rmesa->texHeap[i] = NULL; } foreach_s ( t, next_t, &rmesa->SwappedOut ) { diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.h b/xc/lib/GL/mesa/src/drv/r128/r128_context.h index a0cd5ca60..a4771be22 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.h,v 1.10 2002/02/22 21:44:57 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.h,v 1.12 2002/12/16 16:18:52 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -43,7 +43,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri_util.h" #include "xf86drm.h" -#include "xf86drmR128.h" +#include "r128_common.h" #include "mtypes.h" @@ -202,7 +202,7 @@ struct r128_context { __DRIscreenPrivate *driScreen; /* DRI screen */ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ - int lastStamp; /* mirror driDrawable->lastStamp */ + unsigned int lastStamp; /* mirror driDrawable->lastStamp */ drmContext hHWContext; drmLock *driHwLock; @@ -220,6 +220,10 @@ struct r128_context { GLuint c_textureSwaps; GLuint c_textureBytes; GLuint c_vertexBuffers; + + /* VBI + */ + GLuint vbl_seq; }; #define R128_CONTEXT(ctx) ((r128ContextPtr)(ctx->DriverCtx)) diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c index 36af02ce7..321b40e07 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.c,v 1.14 2002/09/10 00:39:39 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.c,v 1.15 2002/10/30 12:51:38 alanh Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -183,6 +183,7 @@ void r128DDInitExtensions( GLcontext *ctx ) void r128DDInitDriverFuncs( GLcontext *ctx ) { ctx->Driver.GetBufferSize = r128DDGetBufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; ctx->Driver.GetString = r128DDGetString; ctx->Driver.Finish = r128DDFinish; ctx->Driver.Flush = r128DDFlush; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c index 70f56353a..ff9231aaa 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c,v 1.8 2002/02/22 21:44:58 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c,v 1.10 2002/12/16 16:18:53 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -42,6 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #define R128_TIMEOUT 2048 +#define R128_IDLE_RETRY 32 /* ============================================================= @@ -86,7 +87,7 @@ drmBufPtr r128GetBufferLocked( r128ContextPtr rmesa ) } if ( !buf ) { - drmR128EngineReset( fd ); + drmCommandNone( fd, DRM_R128_CCE_RESET); UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "Error: Could not get new VB... exiting\n" ); exit( -1 ); @@ -103,6 +104,7 @@ void r128FlushVerticesLocked( r128ContextPtr rmesa ) int count = rmesa->num_verts; int prim = rmesa->hw_primitive; int fd = rmesa->driScreen->fd; + drmR128Vertex vertex; int i; rmesa->num_verts = 0; @@ -128,7 +130,11 @@ void r128FlushVerticesLocked( r128ContextPtr rmesa ) rmesa->sarea->nbox = nbox; } - drmR128FlushVertexBuffer( fd, prim, buffer->idx, count, 1 ); + vertex.prim = prim; + vertex.idx = buffer->idx; + vertex.count = count; + vertex.discard = 1; + drmCommandWrite( fd, DRM_R128_VERTEX, &vertex, sizeof(drmR128Vertex) ); } else { @@ -149,7 +155,12 @@ void r128FlushVerticesLocked( r128ContextPtr rmesa ) } rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; - drmR128FlushVertexBuffer( fd, prim, buffer->idx, count, discard ); + + vertex.prim = prim; + vertex.idx = buffer->idx; + vertex.count = count; + vertex.discard = discard; + drmCommandWrite( fd, DRM_R128_VERTEX, &vertex, sizeof(drmR128Vertex) ); } } @@ -168,15 +179,24 @@ void r128FireBlitLocked( r128ContextPtr rmesa, drmBufPtr buffer, GLint offset, GLint pitch, GLint format, GLint x, GLint y, GLint width, GLint height ) { + drmR128Blit blit; GLint ret; - ret = drmR128TextureBlit( rmesa->driFd, buffer->idx, - offset, pitch, format, - x, y, width, height ); + blit.idx = buffer->idx; + blit.offset = offset; + blit.pitch = pitch; + blit.format = format; + blit.x = x; + blit.y = y; + blit.width = width; + blit.height = height; + + ret = drmCommandWrite( rmesa->driFd, DRM_R128_BLIT, + &blit, sizeof(drmR128Blit) ); if ( ret ) { UNLOCK_HARDWARE( rmesa ); - fprintf( stderr, "drmR128TextureBlit: return = %d\n", ret ); + fprintf( stderr, "DRM_R128_BLIT: return = %d\n", ret ); exit( 1 ); } } @@ -256,6 +276,8 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) rmesa->hardwareWentIdle = 0; } + r128WaitForVBlank( rmesa ); + nbox = dPriv->numClipRects; for ( i = 0 ; i < nbox ; ) { @@ -270,17 +292,20 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) } rmesa->sarea->nbox = n; - ret = drmR128SwapBuffers( rmesa->driFd ); + ret = drmCommandNone( rmesa->driFd, DRM_R128_SWAP ); if ( ret ) { UNLOCK_HARDWARE( rmesa ); - fprintf( stderr, "drmR128SwapBuffers: return = %d\n", ret ); + fprintf( stderr, "DRM_R128_SWAP: return = %d\n", ret ); exit( 1 ); } } if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) { - drmR128WaitForIdleCCE( rmesa->driFd ); + i = 0; + do { + ret = drmCommandNone(rmesa->driFd, DRM_R128_CCE_IDLE); + } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY ); } UNLOCK_HARDWARE( rmesa ); @@ -325,15 +350,17 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv ) rmesa->hardwareWentIdle = 0; } + r128WaitForVBlank( rmesa ); + /* The kernel will have been initialized to perform page flipping * on a swapbuffers ioctl. */ - ret = drmR128SwapBuffers( rmesa->driFd ); + ret = drmCommandNone( rmesa->driFd, DRM_R128_SWAP ); UNLOCK_HARDWARE( rmesa ); if ( ret ) { - fprintf( stderr, "drmR128SwapBuffers: return = %d\n", ret ); + fprintf( stderr, "DRM_R128_SWAP: return = %d\n", ret ); exit( 1 ); } @@ -373,6 +400,7 @@ static void r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, { r128ContextPtr rmesa = R128_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + drmR128Clear clear; GLuint flags = 0; GLint i; GLint ret; @@ -395,23 +423,23 @@ static void r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } if ( mask & DD_FRONT_LEFT_BIT ) { - flags |= DRM_R128_FRONT; + flags |= DRM_R128_FRONT_BUFFER; mask &= ~DD_FRONT_LEFT_BIT; } if ( mask & DD_BACK_LEFT_BIT ) { - flags |= DRM_R128_BACK; + flags |= DRM_R128_BACK_BUFFER; mask &= ~DD_BACK_LEFT_BIT; } if ( ( mask & DD_DEPTH_BIT ) && ctx->Depth.Mask ) { - flags |= DRM_R128_DEPTH; + flags |= DRM_R128_DEPTH_BUFFER; mask &= ~DD_DEPTH_BIT; } #if 0 /* FIXME: Add stencil support */ if ( mask & DD_STENCIL_BIT ) { - flags |= DRM_R128_DEPTH; + flags |= DRM_R128_DEPTH_BUFFER; mask &= ~DD_STENCIL_BIT; } #endif @@ -468,28 +496,25 @@ static void r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) { fprintf( stderr, - "drmR128Clear: flag 0x%x color %x depth %x nbox %d\n", + "DRM_R128_CLEAR: flag 0x%x color %x depth %x nbox %d\n", flags, (GLuint)rmesa->ClearColor, (GLuint)rmesa->ClearDepth, rmesa->sarea->nbox ); } -/* ret = drmR128Clear( rmesa->driFd, */ -/* flags, */ -/* rmesa->ClearColor, */ -/* rmesa->setup.plane_3d_mask_c, */ -/* rmesa->ClearDepth ); */ + clear.flags = flags; + clear.clear_color = rmesa->ClearColor; + clear.clear_depth = rmesa->ClearDepth; + clear.color_mask = rmesa->setup.plane_3d_mask_c; + clear.depth_mask = ~0; - ret = drmR128Clear( rmesa->driFd, flags, - rmesa->ClearColor, - rmesa->ClearDepth, - rmesa->setup.plane_3d_mask_c, - ~0 ); /* depthmask */ + ret = drmCommandWrite( rmesa->driFd, DRM_R128_CLEAR, + &clear, sizeof(drmR128Clear) ); if ( ret ) { UNLOCK_HARDWARE( rmesa ); - fprintf( stderr, "drmR128Clear: return = %d\n", ret ); + fprintf( stderr, "DRM_R128_CLEAR: return = %d\n", ret ); exit( 1 ); } } @@ -514,6 +539,7 @@ void r128WriteDepthSpanLocked( r128ContextPtr rmesa, const GLubyte mask[] ) { XF86DRIClipRectPtr pbox = rmesa->pClipRects; + drmR128Depth d; int nbox = rmesa->numClipRects; int fd = rmesa->driScreen->fd; int i; @@ -533,7 +559,15 @@ void r128WriteDepthSpanLocked( r128ContextPtr rmesa, rmesa->sarea->nbox = nbox; } - drmR128WriteDepthSpan( fd, n, x, y, depth, mask ); + d.func = DRM_R128_WRITE_SPAN; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = (unsigned int *)depth; + d.mask = (unsigned char *)mask; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); + } else { @@ -547,7 +581,15 @@ void r128WriteDepthSpanLocked( r128ContextPtr rmesa, } rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; - drmR128WriteDepthSpan( fd, n, x, y, depth, mask ); + + d.func = DRM_R128_WRITE_SPAN; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = (unsigned int *)depth; + d.mask = (unsigned char *)mask; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); } } @@ -560,6 +602,7 @@ void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLubyte mask[] ) { XF86DRIClipRectPtr pbox = rmesa->pClipRects; + drmR128Depth d; int nbox = rmesa->numClipRects; int fd = rmesa->driScreen->fd; int i; @@ -579,7 +622,14 @@ void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, rmesa->sarea->nbox = nbox; } - drmR128WriteDepthPixels( fd, n, x, y, depth, mask ); + d.func = DRM_R128_WRITE_PIXELS; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = (unsigned int *)depth; + d.mask = (unsigned char *)mask; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); } else { @@ -593,7 +643,15 @@ void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, } rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; - drmR128WriteDepthPixels( fd, n, x, y, depth, mask ); + + d.func = DRM_R128_WRITE_PIXELS; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = (unsigned int *)depth; + d.mask = (unsigned char *)mask; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); } } @@ -604,6 +662,7 @@ void r128ReadDepthSpanLocked( r128ContextPtr rmesa, GLuint n, GLint x, GLint y ) { XF86DRIClipRectPtr pbox = rmesa->pClipRects; + drmR128Depth d; int nbox = rmesa->numClipRects; int fd = rmesa->driScreen->fd; int i; @@ -623,7 +682,14 @@ void r128ReadDepthSpanLocked( r128ContextPtr rmesa, rmesa->sarea->nbox = nbox; } - drmR128ReadDepthSpan( fd, n, x, y ); + d.func = DRM_R128_READ_SPAN; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = NULL; + d.mask = NULL; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); } else { @@ -637,7 +703,15 @@ void r128ReadDepthSpanLocked( r128ContextPtr rmesa, } rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; - drmR128ReadDepthSpan( fd, n, x, y ); + + d.func = DRM_R128_READ_SPAN; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = NULL; + d.mask = NULL; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); } } @@ -648,6 +722,7 @@ void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[] ) { XF86DRIClipRectPtr pbox = rmesa->pClipRects; + drmR128Depth d; int nbox = rmesa->numClipRects; int fd = rmesa->driScreen->fd; int i; @@ -667,7 +742,14 @@ void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, rmesa->sarea->nbox = nbox; } - drmR128ReadDepthPixels( fd, n, x, y ); + d.func = DRM_R128_READ_PIXELS; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = NULL; + d.mask = NULL; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); } else { @@ -681,7 +763,15 @@ void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, } rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; - drmR128ReadDepthPixels( fd, n, x, y ); + + d.func = DRM_R128_READ_PIXELS; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = NULL; + d.mask = NULL; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); } } @@ -693,20 +783,56 @@ void r128WaitForIdleLocked( r128ContextPtr rmesa ) { int fd = rmesa->r128Screen->driScreen->fd; int to = 0; - int ret; + int ret, i; do { - ret = drmR128WaitForIdleCCE( fd ); + i = 0; + do { + ret = drmCommandNone( fd, DRM_R128_CCE_IDLE); + } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY ); } while ( ( ret == -EBUSY ) && ( to++ < R128_TIMEOUT ) ); if ( ret < 0 ) { - drmR128EngineReset( fd ); + drmCommandNone( fd, DRM_R128_CCE_RESET); UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "Error: Rage 128 timed out... exiting\n" ); exit( -1 ); } } +void r128WaitForVBlank( r128ContextPtr rmesa ) +{ + drmVBlank vbl; + int ret; + + if ( !rmesa->r128Screen->irq ) + return; + + if ( getenv("LIBGL_SYNC_REFRESH") ) { + /* Wait for until the next vertical blank */ + vbl.request.type = DRM_VBLANK_RELATIVE; + vbl.request.sequence = 1; + } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { + /* Wait for at least one vertical blank since the last call */ + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = rmesa->vbl_seq + 1; + } else { + return; + } + + UNLOCK_HARDWARE( rmesa ); + + if ((ret = drmWaitVBlank( rmesa->driFd, &vbl ))) { + fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" + " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" + " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); + exit(1); + } + + rmesa->vbl_seq = vbl.reply.sequence; + + LOCK_HARDWARE( rmesa ); +} void r128DDInitIoctlFuncs( GLcontext *ctx ) { diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h index 96fc3018f..b0f6b363a 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h,v 1.4 2002/02/22 21:44:58 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h,v 1.6 2002/12/16 16:18:53 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_lock.h" #include "xf86drm.h" -#include "xf86drmR128.h" +#include "r128_common.h" #define R128_BUFFER_MAX_DWORDS (R128_BUFFER_SIZE / sizeof(CARD32)) @@ -89,6 +89,7 @@ extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, extern void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ); extern void r128PageFlip( const __DRIdrawablePrivate *dPriv ); +void r128WaitForVBlank( r128ContextPtr rmesa ); extern void r128WaitForIdleLocked( r128ContextPtr rmesa ); diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.c b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c index 272a8a4f1..c55394b54 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.c,v 1.4 2002/02/22 21:44:58 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.c,v 1.5 2002/10/30 12:51:38 alanh Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -86,7 +86,7 @@ void r128GetLock( r128ContextPtr rmesa, GLuint flags ) } for ( i = 0 ; i < rmesa->lastTexHeap ; i++ ) { - if ( sarea->texAge[i] != rmesa->lastTexAge[i] ) { + if ( rmesa->texHeap[i] && sarea->texAge[i] != rmesa->lastTexAge[i] ) { r128AgeTextures( rmesa, i ); } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c index 6556cfe33..dd41022a8 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.6 2002/02/22 21:44:58 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.8 2002/12/16 16:18:53 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -74,6 +74,22 @@ r128CreateScreen( __DRIscreenPrivate *sPriv ) */ r128Screen->IsPCI = r128DRIPriv->IsPCI; r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset; + + if (sPriv->drmMinor >= 3) { + drmR128GetParam gp; + int ret; + + gp.param = R128_PARAM_IRQ_NR; + gp.value = &r128Screen->irq; + + ret = drmCommandWriteRead( sPriv->fd, DRM_R128_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret); + FREE( r128Screen ); + return NULL; + } + } r128Screen->mmio.handle = r128DRIPriv->registerHandle; r128Screen->mmio.size = r128DRIPriv->registerSize; @@ -166,6 +182,9 @@ r128DestroyScreen( __DRIscreenPrivate *sPriv ) { r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private; + if ( !r128Screen ) + return; + if ( !r128Screen->IsPCI ) { drmUnmap( (drmAddress)r128Screen->agpTextures.map, r128Screen->agpTextures.size ); @@ -185,6 +204,7 @@ r128OpenFullScreen( __DRIcontextPrivate *driContextPriv ) { #if 0 r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; + drmR128Fullscreen fullscreen; GLint ret; /* FIXME: Do we need to check this? @@ -197,7 +217,9 @@ r128OpenFullScreen( __DRIcontextPrivate *driContextPriv ) /* Ignore errors. If this fails, we simply don't do page flipping. */ - ret = drmR128FullScreen( rmesa->driFd, GL_TRUE ); + fullscreen.func = DRM_R128_INIT_FULLSCREEN; + ret = drmCommandWrite( rmesa->driFd, DRM_R128_FULLSCREEN, + &fullscreen, sizeof(drmR128Fullscreen) ); UNLOCK_HARDWARE( rmesa ); @@ -214,12 +236,15 @@ r128CloseFullScreen( __DRIcontextPrivate *driContextPriv ) { #if 0 r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; + drmR128Fullscreen fullscreen; LOCK_HARDWARE( rmesa ); r128WaitForIdleLocked( rmesa ); /* Don't care if this fails, we're not page flipping anymore. */ - drmR128FullScreen( rmesa->driFd, GL_FALSE ); + fullscreen.func = DRM_R128_CLEANUP_FULLSCREEN; + drmCommandWrite( rmesa->driFd, DRM_R128_FULLSCREEN, + &fullscreen, sizeof(drmR128Fullscreen) ); UNLOCK_HARDWARE( rmesa ); @@ -277,6 +302,7 @@ r128SwapBuffers(Display *dpy, void *drawablePrivate) ctx = rmesa->glCtx; if (ctx->Visual.doubleBufferMode) { _mesa_swapbuffers( ctx ); /* flush pending rendering comands */ + if ( rmesa->doPageFlip ) { r128PageFlip( dPriv ); } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h index 63e37a8d6..4b1a57292 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.h,v 1.6 2002/02/22 21:44:58 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.h,v 1.7 2002/12/16 16:18:53 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -52,6 +52,7 @@ typedef struct { GLint cpp; GLint IsPCI; /* Current card is a PCI card */ GLint AGPMode; + unsigned int irq; /* IRQ number (0 means none) */ GLuint frontOffset; GLuint frontPitch; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.c b/xc/lib/GL/mesa/src/drv/r128/r128_span.c index 6893abd2f..d87253d32 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_span.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.7 2002/02/22 21:44:58 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.8 2002/10/30 12:51:39 alanh Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * Kevin E. Martin <martin@valinux.com> * */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c index 36f86af8c..dce897bab 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.c,v 1.10 2002/09/10 00:39:39 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.c,v 1.11 2002/10/30 12:51:39 alanh Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -30,7 +30,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Gareth Hughes <gareth@valinux.com> * Kevin E. Martin <martin@valinux.com> - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ @@ -689,13 +689,13 @@ static void r128DDSetDrawBuffer( GLcontext *ctx, GLenum mode ) switch ( mode ) { case GL_FRONT_LEFT: - rmesa->drawOffset = rmesa->r128Screen->frontOffset; - rmesa->drawPitch = rmesa->r128Screen->frontPitch; + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch; FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; case GL_BACK_LEFT: - rmesa->drawOffset = rmesa->r128Screen->backOffset; - rmesa->drawPitch = rmesa->r128Screen->backPitch; + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; default: @@ -718,6 +718,7 @@ static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) { r128ContextPtr rmesa = R128_CONTEXT(ctx); GLuint stipple[32], i; + drmR128Stipple stippleRec; for (i = 0; i < 32; i++) { stipple[31 - i] = ((mask[i*4+0] << 24) | @@ -728,7 +729,11 @@ static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) FLUSH_BATCH( rmesa ); LOCK_HARDWARE( rmesa ); - drmR128PolygonStipple( rmesa->driFd, stipple ); + + stippleRec.mask = stipple; + drmCommandWrite( rmesa->driFd, DRM_R128_STIPPLE, + &stippleRec, sizeof(drmR128Stipple) ); + UNLOCK_HARDWARE( rmesa ); rmesa->new_state |= R128_NEW_CONTEXT; @@ -1226,7 +1231,6 @@ void r128DDInitStateFuncs( GLcontext *ctx ) ctx->Driver.CopyPixels = _swrast_CopyPixels; ctx->Driver.DrawPixels = _swrast_DrawPixels; ctx->Driver.ReadPixels = _swrast_ReadPixels; - ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; /* Swrast hooks for imaging extensions: */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c index 8bbb7332d..034a38b06 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.12 2002/09/18 17:11:41 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.14 2002/11/05 17:46:08 tsi Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -129,7 +129,7 @@ static r128TexObjPtr r128AllocTexObj( struct gl_texture_object *texObj ) r128TexObjPtr t; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t ); + fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj ); } t = (r128TexObjPtr) CALLOC_STRUCT( r128_tex_obj ); diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c index 0bd64ee0b..6f2a90547 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.c,v 1.7 2002/02/22 21:44:58 dawes Exp $ */ /* -*- c-basic-offset: 3 -*- */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.c,v 1.8 2002/10/30 12:51:43 alanh Exp $ */ /* -*- c-basic-offset: 3 -*- */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ @@ -88,7 +88,7 @@ do { \ #define COPY_DWORDS( j, vb, vertsize, v ) \ do { \ for ( j = 0 ; j < vertsize ; j++ ) \ - vb[j] = ((GLuint *)v)[j]; \ + vb[j] = CPU_TO_LE32(((GLuint *)v)[j]); \ vb += vertsize; \ } while (0) #endif @@ -236,33 +236,31 @@ static struct { #define AREA_IS_CCW( a ) (a > 0) #define GET_VERTEX(e) (rmesa->verts + (e<<rmesa->vertex_stride_shift)) -#define R128_COLOR( dst, src ) \ -do { \ - dst[0] = src[2]; \ - dst[1] = src[1]; \ - dst[2] = src[0]; \ - dst[3] = src[3]; \ -} while (0) - -#define R128_SPEC( dst, src ) \ -do { \ - dst[0] = src[2]; \ - dst[1] = src[1]; \ - dst[2] = src[0]; \ -} while (0) - -#define VERT_SET_RGBA( v, c ) R128_COLOR( v->ub4[coloroffset], c ) +#define VERT_SET_RGBA( v, c ) do { \ + r128_color_t *vc = (r128_color_t *)&(v)->ui[coloroffset]; \ + vc->blue = (c)[2]; \ + vc->green = (c)[1]; \ + vc->red = (c)[0]; \ + vc->alpha = (c)[3]; \ + } while (0) #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset] #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx] -#define VERT_SET_SPEC( v, c ) if (havespec) R128_SPEC( v->ub4[5], c ) -#define VERT_COPY_SPEC( v0, v1 ) if (havespec) COPY_3V(v0->ub4[5], v1->ub4[5]) +#define VERT_SET_SPEC( v0, c ) if (havespec) { \ + (v0)->v.specular.red = (c)[0];\ + (v0)->v.specular.green = (c)[1];\ + (v0)->v.specular.blue = (c)[2]; } +#define VERT_COPY_SPEC( v0, v1 ) if (havespec) { \ + (v0)->v.specular.red = v1->v.specular.red; \ + (v0)->v.specular.green = v1->v.specular.green; \ + (v0)->v.specular.blue = v1->v.specular.blue; } + #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5] #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx] #define LOCAL_VARS(n) \ - r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ GLuint color[n], spec[n]; \ GLuint coloroffset = (rmesa->vertex_size == 4 ? 3 : 4); \ GLboolean havespec = (rmesa->vertex_size == 4 ? 0 : 1); \ @@ -501,9 +499,9 @@ static void r128FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, rmesa->num_verts += (n-2) * 3; for (i = 2 ; i < n ; i++) { - COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) start ); COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) VERT(elts[i-1]) ); COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) VERT(elts[i]) ); + COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) start ); } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h index fe1e24cee..755d3320b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.7 2002/02/22 21:44:58 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.8 2002/10/30 12:51:43 alanh Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c index 0a6cc6785..3ceff719c 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.14 2002/09/10 00:39:39 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.15 2002/10/30 12:51:43 alanh Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ @@ -108,7 +108,7 @@ static struct { #define GET_VIEWPORT_MAT() rmesa->hw_viewport #define GET_TEXSOURCE(n) rmesa->tmu_source[n] #define GET_VERTEX_FORMAT() rmesa->vertex_format -#define GET_VERTEX_STORE() (GLubyte *)(rmesa->verts) +#define GET_VERTEX_STORE() rmesa->verts #define GET_VERTEX_STRIDE_SHIFT() rmesa->vertex_stride_shift #define INVALIDATE_STORED_VERTICES() #define GET_UBYTE_COLOR_STORE() &rmesa->UbyteColor diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h index c1f520545..31afa74f1 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.h,v 1.7 2002/02/22 21:44:59 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.h,v 1.8 2002/10/30 12:51:46 alanh Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ diff --git a/xc/lib/GL/mesa/src/drv/r200/Imakefile b/xc/lib/GL/mesa/src/drv/r200/Imakefile new file mode 100644 index 000000000..3ef28c50c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/Imakefile @@ -0,0 +1,79 @@ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r200/Imakefile,v 1.2 2002/11/25 14:04:51 eich Exp $ + +#include <Threads.tmpl> + +#if GlxUseBuiltInDRIDriver +#define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) +#define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) +#define DoExtraLib SharedLibGlx +#define DoDebugLib DebugLibGlx +#define DoProfileLib ProfileLibGlx +#else +#define DoNormalLib SharedLibGlxWithoutPIC +#define DoSharedLib !SharedLibGlxWithoutPIC +#define DoExtrasLib NO +#define DoDebugLib NO +#define DoProfileLib NO +#endif + +#include "../common/Imakefile.inc" +#include "Imakefile.inc" +#include "../../array_cache/Imakefile.inc" +#include "../../math/Imakefile.inc" +#include "../../swrast/Imakefile.inc" +#include "../../swrast_setup/Imakefile.inc" +#include "../../tnl/Imakefile.inc" +#include "../../tnl_dd/Imakefile.inc" +#include "../../Imakefile.inc" +#if defined(i386Architecture) && MesaUseX86Asm +#include "../../X86/Imakefile.inc" +#endif +#ifdef SparcArchitecture +#include "../../SPARC/Imakefile.inc" +#endif + + DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(MESA_ASM_DEFINES) + INCLUDES = $(X_INCLUDES) $(MESA_INCLUDES) $(DRI_INCLUDES) + + DRIOBJS = $(GLXLIBSRC)/dri/dri_util.o + + DRMOBJS = $(GLXLIBSRC)/dri/drm/xf86drm.o \ + $(GLXLIBSRC)/dri/drm/xf86drmHash.o \ + $(GLXLIBSRC)/dri/drm/xf86drmRandom.o \ + $(GLXLIBSRC)/dri/drm/xf86drmSL.o + +#ifdef GlxSoProf + LOSRCS = ../../../../lowpc.c + HISRCS = ../../../../highpc.c + + LOOBJS = ../../../../lowpc.o + HIOBJS = ../../../../highpc.o +#endif + + SRCS = $(R200SRCS) + OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(COREMESAOBJS) \ + $(MESA_ASM_OBJS) $(COMMONOBJS) $(R200OBJS) $(HIOBJS) + +REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) + +#include <Library.tmpl> + +LibraryObjectRule() + +SubdirLibraryRule($(R200OBJS)) +NormalLintTarget($(SRCS)) + +#if !GlxUseBuiltInDRIDriver +LIBNAME = r200_dri.so +SharedDriModuleTarget($(LIBNAME),DONE $(OBJS),$(OBJS)) +InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) + +#ifdef GlxSoProf +SOPROF_LIBNAME = _r200_dri_p +NormalDepLibraryTarget($(SOPROF_LIBNAME),DONE $(OBJS),$(OBJS)) +InstallLibrary($(SOPROF_LIBNAME),$(MODULEDIR)/dri) +#endif +#endif + +DependTarget() + diff --git a/xc/lib/GL/mesa/src/drv/r200/Imakefile.inc b/xc/lib/GL/mesa/src/drv/r200/Imakefile.inc new file mode 100644 index 000000000..f42665d3c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/Imakefile.inc @@ -0,0 +1,182 @@ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r200/Imakefile.inc,v 1.2 2002/11/29 14:41:33 eich Exp $ + +#ifndef MesaDrvSrcDir +#define MesaDrvSrcDir $(GLXLIBSRC)/mesa/src/drv +#endif + +MESADRVSRCDIR = MesaDrvSrcDir + +#ifndef MesaDrvR200BuildDir +#define MesaDrvR200BuildDir /**/ +#endif +MESADRVR200BUILDDIR = MesaDrvR200BuildDir + +#if Malloc0ReturnsNull +ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL +#endif + +#if BuildXF86DRI + DRI_DEFINES = GlxDefines -DX_BYTE_ORDER=ByteOrder + DRI_INCLUDES = -I$(GLXLIBSRC)/dri \ + -I$(GLXLIBSRC)/glx \ + -I$(INCLUDESRC) \ + -I$(INCLUDESRC)/GL \ + -I$(SERVERSRC)/GL/dri \ + -I$(XF86OSSRC) \ + -I$(XF86DRIVERSRC)/ati \ + -I$(XF86COMSRC) \ + -I$(GLXLIBSRC)/dri/drm \ + -I$(GLXLIBSRC)/include \ + -I$(XTOP)/include +#endif + +MESA_INCLUDES = -I$(MESASRCDIR)/src \ + -I$(MESADRVSRCDIR)/common \ + -I$(MESADRVSRCDIR)/r200 + X_INCLUDES = -I$(XINCLUDESRC) -I$(EXTINCSRC) + + R200SRCS = $(MESADRVR200BUILDDIR)r200_context.c \ + $(MESADRVR200BUILDDIR)r200_sanity.c \ + $(MESADRVR200BUILDDIR)r200_state.c \ + $(MESADRVR200BUILDDIR)r200_state_init.c \ + $(MESADRVR200BUILDDIR)r200_swtcl.c \ + $(MESADRVR200BUILDDIR)r200_cmdbuf.c \ + $(MESADRVR200BUILDDIR)r200_ioctl.c \ + $(MESADRVR200BUILDDIR)r200_lock.c \ + $(MESADRVR200BUILDDIR)r200_maos.c \ + $(MESADRVR200BUILDDIR)r200_pixel.c \ + $(MESADRVR200BUILDDIR)r200_screen.c \ + $(MESADRVR200BUILDDIR)r200_span.c \ + $(MESADRVR200BUILDDIR)r200_tcl.c \ + $(MESADRVR200BUILDDIR)r200_tex.c \ + $(MESADRVR200BUILDDIR)r200_texmem.c \ + $(MESADRVR200BUILDDIR)r200_texstate.c \ + $(MESADRVR200BUILDDIR)r200_vtxfmt.c \ + $(MESADRVR200BUILDDIR)r200_vtxfmt_x86.c \ + $(MESADRVR200BUILDDIR)r200_vtxtmp_x86.S \ + $(MESADRVR200BUILDDIR)r200_vtxfmt_sse.c \ + $(MESADRVR200BUILDDIR)r200_vtxfmt_c.c + + R200OBJS = $(MESADRVR200BUILDDIR)r200_context.o \ + $(MESADRVR200BUILDDIR)r200_sanity.o \ + $(MESADRVR200BUILDDIR)r200_state.o \ + $(MESADRVR200BUILDDIR)r200_state_init.o \ + $(MESADRVR200BUILDDIR)r200_swtcl.o \ + $(MESADRVR200BUILDDIR)r200_cmdbuf.o \ + $(MESADRVR200BUILDDIR)r200_ioctl.o \ + $(MESADRVR200BUILDDIR)r200_lock.o \ + $(MESADRVR200BUILDDIR)r200_maos.o \ + $(MESADRVR200BUILDDIR)r200_pixel.o \ + $(MESADRVR200BUILDDIR)r200_screen.o \ + $(MESADRVR200BUILDDIR)r200_span.o \ + $(MESADRVR200BUILDDIR)r200_tcl.o \ + $(MESADRVR200BUILDDIR)r200_tex.o \ + $(MESADRVR200BUILDDIR)r200_texmem.o \ + $(MESADRVR200BUILDDIR)r200_texstate.o \ + $(MESADRVR200BUILDDIR)r200_vtxfmt.o \ + $(MESADRVR200BUILDDIR)r200_vtxfmt_c.o + +#ifdef i386Architecture + R200OBJS += $(MESADRVR200BUILDDIR)r200_vtxfmt_x86.o \ + $(MESADRVR200BUILDDIR)r200_vtxtmp_x86.o \ + $(MESADRVR200BUILDDIR)r200_vtxfmt_sse.o +#endif + + R200UOBJS = $(MESADRVR200BUILDDIR)unshared/r200_context.o \ + $(MESADRVR200BUILDDIR)unshared/r200_sanity.o \ + $(MESADRVR200BUILDDIR)unshared/r200_cmdbuf.o \ + $(MESADRVR200BUILDDIR)unshared/r200_ioctl.o \ + $(MESADRVR200BUILDDIR)unshared/r200_lock.o \ + $(MESADRVR200BUILDDIR)unshared/r200_maos.o \ + $(MESADRVR200BUILDDIR)unshared/r200_pixel.o \ + $(MESADRVR200BUILDDIR)unshared/r200_screen.o \ + $(MESADRVR200BUILDDIR)unshared/r200_span.o \ + $(MESADRVR200BUILDDIR)unshared/r200_state.o \ + $(MESADRVR200BUILDDIR)unshared/r200_state_init.o \ + $(MESADRVR200BUILDDIR)unshared/r200_swtcl.o \ + $(MESADRVR200BUILDDIR)unshared/r200_tcl.o \ + $(MESADRVR200BUILDDIR)unshared/r200_tex.o \ + $(MESADRVR200BUILDDIR)unshared/r200_texmem.o \ + $(MESADRVR200BUILDDIR)unshared/r200_texstate.o \ + $(MESADRVR200BUILDDIR)unshared/r200_vtxfmt.o \ + $(MESADRVR200BUILDDIR)unshared/r200_vtxfmt_c.o + +#ifdef i386Architecture + R200UOBJS += $(MESADRVR200BUILDDIR)unshared/r200_vtxfmt_x86.o \ + $(MESADRVR200BUILDDIR)unshared/r200_vtxtmp_x86.o \ + $(MESADRVR200BUILDDIR)unshared/r200_vtxfmt_sse.o +#endif + + R200DOBJS = $(MESADRVR200BUILDDIR)debugger/r200_context.o \ + $(MESADRVR200BUILDDIR)debugger/r200_sanity.o \ + $(MESADRVR200BUILDDIR)debugger/r200_cmdbuf.o \ + $(MESADRVR200BUILDDIR)debugger/r200_ioctl.o \ + $(MESADRVR200BUILDDIR)debugger/r200_lock.o \ + $(MESADRVR200BUILDDIR)debugger/r200_maos.o \ + $(MESADRVR200BUILDDIR)debugger/r200_pixel.o \ + $(MESADRVR200BUILDDIR)debugger/r200_screen.o \ + $(MESADRVR200BUILDDIR)debugger/r200_span.o \ + $(MESADRVR200BUILDDIR)debugger/r200_state.o \ + $(MESADRVR200BUILDDIR)debugger/r200_state_init.o \ + $(MESADRVR200BUILDDIR)debugger/r200_swtcl.o \ + $(MESADRVR200BUILDDIR)debugger/r200_tcl.o \ + $(MESADRVR200BUILDDIR)debugger/r200_tex.o \ + $(MESADRVR200BUILDDIR)debugger/r200_texmem.o \ + $(MESADRVR200BUILDDIR)debugger/r200_texstate.o \ + $(MESADRVR200BUILDDIR)debugger/r200_vtxfmt.o \ + $(MESADRVR200BUILDDIR)debugger/r200_vtxfmt_c.o + +#ifdef i386Architecture + R200DOBJS += $(MESADRVR200BUILDDIR)debugger/r200_vtxfmt_x86.o \ + $(MESADRVR200BUILDDIR)debugger/r200_vtxtmp_x86.o \ + $(MESADRVR200BUILDDIR)debugger/r200_vtxfmt_sse.o +#endif + + R200POBJS = $(MESADRVR200BUILDDIR)profiled/r200_context.o \ + $(MESADRVR200BUILDDIR)profiled/r200_sanity.o \ + $(MESADRVR200BUILDDIR)profiled/r200_cmdbuf.o \ + $(MESADRVR200BUILDDIR)profiled/r200_ioctl.o \ + $(MESADRVR200BUILDDIR)profiled/r200_lock.o \ + $(MESADRVR200BUILDDIR)profiled/r200_maos.o \ + $(MESADRVR200BUILDDIR)profiled/r200_pixel.o \ + $(MESADRVR200BUILDDIR)profiled/r200_screen.o \ + $(MESADRVR200BUILDDIR)profiled/r200_span.o \ + $(MESADRVR200BUILDDIR)profiled/r200_state.o \ + $(MESADRVR200BUILDDIR)profiled/r200_state_init.o \ + $(MESADRVR200BUILDDIR)profiled/r200_swtcl.o \ + $(MESADRVR200BUILDDIR)profiled/r200_tcl.o \ + $(MESADRVR200BUILDDIR)profiled/r200_tex.o \ + $(MESADRVR200BUILDDIR)profiled/r200_texmem.o \ + $(MESADRVR200BUILDDIR)profiled/r200_texstate.o \ + $(MESADRVR200BUILDDIR)profiled/r200_vtxfmt.o \ + $(MESADRVR200BUILDDIR)profiled/r200_vtxfmt_c.o + +#ifdef i386Architecture + R200POBJS += $(MESADRVR200BUILDDIR)profiled/r200_vtxfmt_x86.o \ + $(MESADRVR200BUILDDIR)profiled/r200_vtxtmp_x86.o \ + $(MESADRVR200BUILDDIR)profiled/r200_vtxfmt_sse.o +#endif + +#ifdef NeedToLinkMesaSrc +LinkSourceFile(r200_context.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_cmdbuf.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_ioctl.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_lock.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_maos.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_pixel.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_screen.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_span.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_sanity.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_state.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_state_init.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_swtcl.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_tcl.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_tex.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_texmem.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_texstate.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_vtxfmt.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_vtxfmt_c.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_vtxfmt_x86.c, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_vtxtmp_x86.S, $(MESADRVSRCDIR)/r200) +LinkSourceFile(r200_vtxfmt_sse.c, $(MESADRVSRCDIR)/r200) +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c b/xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c new file mode 100644 index 000000000..b6b5e640c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c @@ -0,0 +1,343 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c,v 1.1 2002/10/30 12:51:51 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_state.h" +#include "r200_ioctl.h" +#include "r200_tcl.h" +#include "r200_sanity.h" +#include "radeon_reg.h" + +#include "mem.h" +#include "macros.h" +#include "context.h" +#include "swrast/swrast.h" +#include "simple_list.h" + +static void print_state_atom( struct r200_state_atom *state ) +{ + int i; + + fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); + + if (0 & R200_DEBUG & DEBUG_VERBOSE) + for (i = 0 ; i < state->cmd_size ; i++) + fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); + +} + +static void r200_emit_state_list( r200ContextPtr rmesa, + struct r200_state_atom *list ) +{ + struct r200_state_atom *state, *tmp; + char *dest; + + foreach_s( state, tmp, list ) { + if (state->check( rmesa->glCtx, state->idx )) { + dest = r200AllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__); + memcpy( dest, state->cmd, state->cmd_size * 4); + move_to_head( &(rmesa->hw.clean), state ); + if (R200_DEBUG & DEBUG_STATE) + print_state_atom( state ); + } + else if (R200_DEBUG & DEBUG_STATE) + fprintf(stderr, "skip state %s\n", state->name); + } +} + + +void r200EmitState( r200ContextPtr rmesa ) +{ + struct r200_state_atom *state, *tmp; + + if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* Somewhat overkill: + */ + if ( rmesa->lost_context) { + if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS|DEBUG_IOCTL)) + fprintf(stderr, "%s - lost context\n", __FUNCTION__); + + foreach_s( state, tmp, &(rmesa->hw.clean) ) + move_to_tail(&(rmesa->hw.dirty), state ); + + rmesa->lost_context = 0; + } + else { + move_to_tail( &rmesa->hw.dirty, &rmesa->hw.mtl[0] ); + /* odd bug? -- isosurf, cycle between reflect & lit */ + } + + r200_emit_state_list( rmesa, &rmesa->hw.dirty ); +} + + + +/* Fire a section of the retained (indexed_verts) buffer as a regular + * primtive. + */ +extern void r200EmitVbufPrim( r200ContextPtr rmesa, + GLuint primitive, + GLuint vertex_nr ) +{ + drmRadeonCmdHeader *cmd; + + assert(!(primitive & R200_VF_PRIM_WALK_IND)); + + r200EmitState( rmesa ); + + if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS)) + fprintf(stderr, "%s cmd_used/4: %d prim %x nr %d\n", __FUNCTION__, + rmesa->store.cmd_used/4, primitive, vertex_nr); + + cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 3 * sizeof(*cmd), + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; + cmd[1].i = R200_CP_CMD_3D_DRAW_VBUF_2; + cmd[2].i = (primitive | + R200_VF_PRIM_WALK_LIST | + R200_VF_COLOR_ORDER_RGBA | + (vertex_nr << R200_VF_VERTEX_NUMBER_SHIFT)); + + + if (R200_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "\nSyncing\n\n"); + R200_FIREVERTICES( rmesa ); + r200Finish( rmesa->glCtx ); + } +} + + +void r200FlushElts( r200ContextPtr rmesa ) +{ + int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start); + int dwords; + int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 12)) / 2; + + if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS)) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert( rmesa->dma.flush == r200FlushElts ); + rmesa->dma.flush = 0; + + /* Cope with odd number of elts: + */ + rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2; + dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4; + + cmd[1] |= (dwords - 3) << 16; + cmd[2] |= nr << R200_VF_VERTEX_NUMBER_SHIFT; + + if (R200_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); + R200_FIREVERTICES( rmesa ); + r200Finish( rmesa->glCtx ); + } +} + + +GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, + GLuint primitive, + GLuint min_nr ) +{ + drmRadeonCmdHeader *cmd; + GLushort *retval; + + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive); + + assert((primitive & R200_VF_PRIM_WALK_IND)); + + r200EmitState( rmesa ); + + cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, + 12 + min_nr*2, + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; + cmd[1].i = R200_CP_CMD_3D_DRAW_INDX_2; + cmd[2].i = (primitive | + R200_VF_PRIM_WALK_IND | + R200_VF_COLOR_ORDER_RGBA); + + + retval = (GLushort *)(cmd+3); + + if (R200_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s: header 0x%x prim %x \n", + __FUNCTION__, + cmd[1].i, primitive); + + assert(!rmesa->dma.flush); + rmesa->dma.flush = r200FlushElts; + + rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf; + + return retval; +} + + + +void r200EmitVertexAOS( r200ContextPtr rmesa, + GLuint vertex_size, + GLuint offset ) +{ + drmRadeonCmdHeader *cmd; + + if (R200_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL)) + fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n", + __FUNCTION__, vertex_size, offset); + + cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 5 * sizeof(int), + __FUNCTION__ ); + + cmd[0].header.cmd_type = RADEON_CMD_PACKET3; + cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | (2 << 16); + cmd[2].i = 1; + cmd[3].i = vertex_size | (vertex_size << 8); + cmd[4].i = offset; +} + + +void r200EmitAOS( r200ContextPtr rmesa, + struct r200_dma_region **component, + GLuint nr, + GLuint offset ) +{ + drmRadeonCmdHeader *cmd; + int sz = 3 + ((nr/2)*3) + ((nr&1)*2); + int i; + int *tmp; + + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s nr arrays: %d\n", __FUNCTION__, nr); + + cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, sz * sizeof(int), + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].header.cmd_type = RADEON_CMD_PACKET3; + cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | ((sz-3) << 16); + cmd[2].i = nr; + tmp = &cmd[0].i; + cmd += 3; + + for (i = 0 ; i < nr ; i++) { + if (i & 1) { + cmd[0].i |= ((component[i]->aos_stride << 24) | + (component[i]->aos_size << 16)); + cmd[2].i = (component[i]->aos_start + + offset * component[i]->aos_stride * 4); + cmd += 3; + } + else { + cmd[0].i = ((component[i]->aos_stride << 8) | + (component[i]->aos_size << 0)); + cmd[1].i = (component[i]->aos_start + + offset * component[i]->aos_stride * 4); + } + } + + if (R200_DEBUG & DEBUG_VERTS) { + fprintf(stderr, "%s:\n", __FUNCTION__); + for (i = 0 ; i < sz ; i++) + fprintf(stderr, " %d: %x\n", i, tmp[i]); + } +} + +void r200EmitBlit( r200ContextPtr rmesa, + GLuint color_fmt, + GLuint src_pitch, + GLuint src_offset, + GLuint dst_pitch, + GLuint dst_offset, + GLint srcx, GLint srcy, + GLint dstx, GLint dsty, + GLuint w, GLuint h ) +{ + drmRadeonCmdHeader *cmd; + + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n", + __FUNCTION__, + src_pitch, src_offset, srcx, srcy, + dst_pitch, dst_offset, dstx, dsty, + w, h); + + assert( (src_pitch & 63) == 0 ); + assert( (dst_pitch & 63) == 0 ); + assert( (src_offset & 1023) == 0 ); + assert( (dst_offset & 1023) == 0 ); + assert( w < (1<<16) ); + assert( h < (1<<16) ); + + cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 8 * sizeof(int), + __FUNCTION__ ); + + + cmd[0].header.cmd_type = RADEON_CMD_PACKET3; + cmd[1].i = R200_CP_CMD_BITBLT_MULTI | (5 << 16); + cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_S | + RADEON_DP_SRC_SOURCE_MEMORY | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_WR_MSK_DIS ); + + cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10); + cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10); + cmd[5].i = (srcx << 16) | srcy; + cmd[6].i = (dstx << 16) | dsty; /* dst */ + cmd[7].i = (w << 16) | h; +} + + +void r200EmitWait( r200ContextPtr rmesa, GLuint flags ) +{ + if (rmesa->dri.drmMinor >= 6) { + drmRadeonCmdHeader *cmd; + + assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) ); + + cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, 1 * sizeof(int), + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].wait.cmd_type = RADEON_CMD_WAIT; + cmd[0].wait.flags = flags; + } +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_context.c b/xc/lib/GL/mesa/src/drv/r200/r200_context.c new file mode 100644 index 000000000..57f34aaa1 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_context.c @@ -0,0 +1,634 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.c,v 1.2 2002/12/16 16:18:53 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +#include "r200_context.h" +#include "r200_ioctl.h" +#include "r200_state.h" +#include "r200_span.h" +#include "r200_pixel.h" +#include "r200_tex.h" +#include "r200_swtcl.h" +#include "r200_tcl.h" +#include "r200_vtxfmt.h" +#include "r200_maos.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "array_cache/acache.h" + +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" + +#include "attrib.h" +#include "api_arrayelt.h" +#include "context.h" +#include "simple_list.h" +#include "mem.h" +#include "matrix.h" +#include "state.h" +#include "extensions.h" +#include "state.h" +#if defined(USE_X86_ASM) +#include "X86/common_x86_asm.h" +#endif + +#define R200_DATE "20020827" + +#ifndef R200_DEBUG +int R200_DEBUG = (0); +#endif + + + +/* Return the width and height of the given buffer. + */ +static void r200GetBufferSize( GLframebuffer *buffer, + GLuint *width, GLuint *height ) +{ + GET_CURRENT_CONTEXT(ctx); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + LOCK_HARDWARE( rmesa ); + *width = rmesa->dri.drawable->w; + *height = rmesa->dri.drawable->h; + UNLOCK_HARDWARE( rmesa ); +} + +/* Return various strings for glGetString(). + */ +static const GLubyte *r200GetString( GLcontext *ctx, GLenum name ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + static char buffer[128]; + + switch ( name ) { + case GL_VENDOR: + return (GLubyte *)"Tungsten Graphics, Inc."; + + case GL_RENDERER: + sprintf( buffer, "Mesa DRI R200 " R200_DATE); + + /* Append any chipset-specific information. None yet. + */ + + /* Append any AGP-specific information. + */ + switch ( rmesa->r200Screen->AGPMode ) { + case 1: + strncat( buffer, " AGP 1x", 7 ); + break; + case 2: + strncat( buffer, " AGP 2x", 7 ); + break; + case 4: + strncat( buffer, " AGP 4x", 7 ); + break; + } + + /* Append any CPU-specific information. + */ +#ifdef USE_X86_ASM + if ( _mesa_x86_cpu_features ) { + strncat( buffer, " x86", 4 ); + } +#ifdef USE_MMX_ASM + if ( cpu_has_mmx ) { + strncat( buffer, "/MMX", 4 ); + } +#endif +#ifdef USE_3DNOW_ASM + if ( cpu_has_3dnow ) { + strncat( buffer, "/3DNow!", 7 ); + } +#endif +#ifdef USE_SSE_ASM + if ( cpu_has_xmm ) { + strncat( buffer, "/SSE", 4 ); + } +#endif +#endif + + if ( !(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) ) { + strncat( buffer, " TCL", 4 ); + } + else { + strncat( buffer, " NO-TCL", 7 ); + } + + return (GLubyte *)buffer; + + default: + return NULL; + } +} + + + +/* Initialize the extensions supported by this driver. + */ +static void r200InitExtensions( GLcontext *ctx ) +{ + _mesa_enable_imaging_extensions( ctx ); + + _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); + _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" ); + _mesa_enable_extension( ctx, "GL_ARB_texture_env_combine" ); + _mesa_enable_extension( ctx, "GL_ARB_texture_env_dot3" ); + + _mesa_enable_extension( ctx, "GL_EXT_blend_logic_op" ); + _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_env_dot3" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_filter_anisotropic" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" ); + _mesa_enable_extension( ctx, "GL_EXT_secondary_color" ); + _mesa_enable_extension( ctx, "GL_EXT_blend_subtract" ); + _mesa_enable_extension( ctx, "GL_EXT_blend_minmax" ); + +/* _mesa_enable_extension( ctx, "GL_EXT_fog_coord" ); */ + + _mesa_enable_extension( ctx, "GL_MESA_pack_invert" ); + _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" ); + _mesa_enable_extension( ctx, "GL_NV_texture_rectangle" ); + +} + +extern const struct gl_pipeline_stage _r200_render_stage; +extern const struct gl_pipeline_stage _r200_tcl_stage; + +static const struct gl_pipeline_stage *r200_pipeline[] = { + + /* Try and go straight to t&l + */ + &_r200_tcl_stage, + + /* Catch any t&l fallbacks + */ + &_tnl_vertex_transform_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + + /* Try again to go to tcl? + * - no good for asymmetric-twoside (do with multipass) + * - no good for asymmetric-unfilled (do with multipass) + * - good for material + * - good for texgen + * - need to manipulate a bit of state + * + * - worth it/not worth it? + */ + + /* Else do them here. + */ + &_r200_render_stage, + &_tnl_render_stage, /* FALLBACK: */ + 0, +}; + + + +/* Initialize the driver's misc functions. + */ +static void r200InitDriverFuncs( GLcontext *ctx ) +{ + ctx->Driver.GetBufferSize = r200GetBufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + ctx->Driver.GetString = r200GetString; + + ctx->Driver.Error = NULL; + ctx->Driver.DrawPixels = NULL; + ctx->Driver.Bitmap = NULL; +} + +static void add_debug_flags( const char *debug ) +{ + if (strstr(debug, "fall")) + R200_DEBUG |= DEBUG_FALLBACKS; + + if (strstr(debug, "tex")) + R200_DEBUG |= DEBUG_TEXTURE; + + if (strstr(debug, "ioctl")) + R200_DEBUG |= DEBUG_IOCTL; + + if (strstr(debug, "prim")) + R200_DEBUG |= DEBUG_PRIMS; + + if (strstr(debug, "vert")) + R200_DEBUG |= DEBUG_VERTS; + + if (strstr(debug, "state")) + R200_DEBUG |= DEBUG_STATE; + + if (strstr(debug, "code")) + R200_DEBUG |= DEBUG_CODEGEN; + + if (strstr(debug, "vfmt") || strstr(debug, "vtxf")) + R200_DEBUG |= DEBUG_VFMT; + + if (strstr(debug, "verb")) + R200_DEBUG |= DEBUG_VERBOSE; + + if (strstr(debug, "dri")) + R200_DEBUG |= DEBUG_DRI; + + if (strstr(debug, "dma")) + R200_DEBUG |= DEBUG_DMA; + + if (strstr(debug, "san")) + R200_DEBUG |= DEBUG_SANITY; + + if (strstr(debug, "sync")) + R200_DEBUG |= DEBUG_SYNC; + + if (strstr(debug, "pix")) + R200_DEBUG |= DEBUG_PIXEL; +} + +/* Create the device specific context. + */ +GLboolean r200CreateContext( Display *dpy, const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate) +{ + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + r200ScreenPtr r200Screen = (r200ScreenPtr)(sPriv->private); + r200ContextPtr rmesa; + GLcontext *ctx, *shareCtx; + int i; + + assert(dpy); + assert(glVisual); + assert(driContextPriv); + assert(r200Screen); + + /* Allocate the R200 context */ + rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) ); + if ( !rmesa ) + return GL_FALSE; + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + rmesa->glCtx = _mesa_create_context(glVisual, shareCtx, rmesa, GL_TRUE); + if (!rmesa->glCtx) { + FREE(rmesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = rmesa; + + /* Init r200 context data */ + rmesa->dri.display = dpy; + rmesa->dri.context = driContextPriv; + rmesa->dri.screen = sPriv; + rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */ + rmesa->dri.hwContext = driContextPriv->hHWContext; + rmesa->dri.hwLock = &sPriv->pSAREA->lock; + rmesa->dri.fd = sPriv->fd; + rmesa->dri.drmMinor = sPriv->drmMinor; + + rmesa->r200Screen = r200Screen; + rmesa->sarea = (RADEONSAREAPrivPtr)((GLubyte *)sPriv->pSAREA + + r200Screen->sarea_priv_offset); + + + rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address; + + for ( i = 0 ; i < r200Screen->numTexHeaps ; i++ ) { + make_empty_list( &rmesa->texture.objects[i] ); + rmesa->texture.heap[i] = mmInit( 0, r200Screen->texSize[i] ); + rmesa->texture.age[i] = -1; + } + rmesa->texture.numHeaps = r200Screen->numTexHeaps; + make_empty_list( &rmesa->texture.swapped ); + + rmesa->swtcl.RenderIndex = ~0; + rmesa->lost_context = 1; + + /* KW: Set the maximum texture size small enough that we can + * guarentee that both texture units can bind a maximal texture + * and have them both in on-card memory at once. + * Test for 2 textures * 4 bytes/texel * size * size. + */ + ctx = rmesa->glCtx; + if (r200Screen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 2048 * 2048) { + ctx->Const.MaxTextureLevels = 12; /* 2048x2048 */ + } + else if (r200Screen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 1024 * 1024) { + ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */ + } + else if (r200Screen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 512 * 512) { + ctx->Const.MaxTextureLevels = 10; /* 512x512 */ + } + else { + ctx->Const.MaxTextureLevels = 9; /* 256x256 */ + } + + ctx->Const.MaxTextureUnits = 2; + ctx->Const.MaxTextureMaxAnisotropy = 16.0; + + /* No wide points. + */ + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = 1.0; + ctx->Const.MaxPointSizeAA = 1.0; + + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 10.0; + ctx->Const.MaxLineWidthAA = 10.0; + ctx->Const.LineWidthGranularity = 0.0625; + + + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext( ctx ); + _ac_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); + _ae_create_context( ctx ); + + /* Install the customized pipeline: + */ + _tnl_destroy_pipeline( ctx ); + _tnl_install_pipeline( ctx, r200_pipeline ); + + /* Try and keep materials and vertices separate: + */ + _tnl_isolate_materials( ctx, GL_TRUE ); + + + /* Configure swrast to match hardware characteristics: + */ + _swrast_allow_pixel_fog( ctx, GL_FALSE ); + _swrast_allow_vertex_fog( ctx, GL_TRUE ); + + + _math_matrix_ctr( &rmesa->TexGenMatrix[0] ); + _math_matrix_ctr( &rmesa->TexGenMatrix[1] ); + _math_matrix_ctr( &rmesa->tmpmat ); + _math_matrix_set_identity( &rmesa->TexGenMatrix[0] ); + _math_matrix_set_identity( &rmesa->TexGenMatrix[1] ); + _math_matrix_set_identity( &rmesa->tmpmat ); + + r200InitExtensions( ctx ); + r200InitDriverFuncs( ctx ); + r200InitIoctlFuncs( ctx ); + r200InitStateFuncs( ctx ); + r200InitSpanFuncs( ctx ); + r200InitPixelFuncs( ctx ); + r200InitTextureFuncs( ctx ); + r200InitState( rmesa ); + r200InitSwtcl( ctx ); + + rmesa->iw.irq_seq = -1; + rmesa->irqsEmitted = 0; + rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 && + !getenv("R200_NO_IRQS") && + rmesa->r200Screen->irq); + + if (!rmesa->do_irqs) + fprintf(stderr, + "IRQ's not enabled, falling back to busy waits: %d %d %d\n", + rmesa->dri.drmMinor, + !!getenv("R200_NO_IRQS"), + rmesa->r200Screen->irq); + + + rmesa->do_usleeps = !getenv("R200_NO_USLEEPS"); + rmesa->prefer_agp_client_texturing = + (getenv("R200_AGP_CLIENT_TEXTURES") != 0); + + +#if DO_DEBUG + if (getenv("R200_DEBUG")) + add_debug_flags( getenv("R200_DEBUG") ); + if (getenv("RADEON_DEBUG")) + add_debug_flags( getenv("RADEON_DEBUG") ); +#endif + + if (getenv("R200_NO_RAST")) { + fprintf(stderr, "disabling 3D acceleration\n"); + FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1); + } + else if (getenv("R200_NO_TCL")) { + fprintf(stderr, "disabling TCL support\n"); + TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1); + } + else { + if (!getenv("R200_NO_VTXFMT")) { + r200VtxfmtInit( ctx ); + } + _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); + } + return GL_TRUE; +} + + +/* Destroy the device specific context. + */ +/* Destroy the Mesa and driver specific context data. + */ +void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) +{ + GET_CURRENT_CONTEXT(ctx); + r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate; + r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL; + + /* check if we're deleting the currently bound context */ + if (rmesa == current) { + R200_FIREVERTICES( rmesa ); + _mesa_make_current2(NULL, NULL, NULL); + } + + /* Free r200 context resources */ + assert(rmesa); /* should never be null */ + if ( rmesa ) { + if (rmesa->glCtx->Shared->RefCount == 1) { + /* This share group is about to go away, free our private + * texture object data. + */ + r200TexObjPtr t, next_t; + int i; + + for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { + foreach_s ( t, next_t, &rmesa->texture.objects[i] ) { + r200DestroyTexObj( rmesa, t ); + } + mmDestroy( rmesa->texture.heap[i] ); + rmesa->texture.heap[i] = NULL; + } + + foreach_s ( t, next_t, &rmesa->texture.swapped ) { + r200DestroyTexObj( rmesa, t ); + } + } + + _swsetup_DestroyContext( rmesa->glCtx ); + _tnl_DestroyContext( rmesa->glCtx ); + _ac_DestroyContext( rmesa->glCtx ); + _swrast_DestroyContext( rmesa->glCtx ); + + r200DestroySwtcl( rmesa->glCtx ); + + r200ReleaseArrays( rmesa->glCtx, ~0 ); + + if (rmesa->dma.current.buf) { + r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); + r200FlushCmdBuf( rmesa, __FUNCTION__ ); + } + + if (!rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) + if (!getenv("R200_NO_VTXFMT")) + r200VtxfmtDestroy( rmesa->glCtx ); + + /* free the Mesa context */ + rmesa->glCtx->DriverCtx = NULL; + _mesa_destroy_context( rmesa->glCtx ); + + if (rmesa->state.scissor.pClipRects) { + FREE(rmesa->state.scissor.pClipRects); + rmesa->state.scissor.pClipRects = 0; + } + + FREE( rmesa ); + } +} + + + + +void +r200SwapBuffers(Display *dpy, void *drawablePrivate) +{ + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; + (void) dpy; + + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + r200ContextPtr rmesa; + GLcontext *ctx; + rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; + ctx = rmesa->glCtx; + if (ctx->Visual.doubleBufferMode) { + _mesa_swapbuffers( ctx ); /* flush pending rendering comands */ + + if ( rmesa->doPageFlip ) { + r200PageFlip( dPriv ); + } + else { + r200CopyBuffer( dPriv ); + } + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "r200SwapBuffers: drawable has no context!\n"); + } +} + + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +GLboolean +r200MakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) +{ + if ( driContextPriv ) { + r200ContextPtr newR200Ctx = + (r200ContextPtr) driContextPriv->driverPrivate; + + if (R200_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newR200Ctx->glCtx); + + if ( newR200Ctx->dri.drawable != driDrawPriv ) { + newR200Ctx->dri.drawable = driDrawPriv; + r200UpdateWindow( newR200Ctx->glCtx ); + r200UpdateViewportOffset( newR200Ctx->glCtx ); + } + + _mesa_make_current2( newR200Ctx->glCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate ); + + if ( !newR200Ctx->glCtx->Viewport.Width ) { + _mesa_set_viewport( newR200Ctx->glCtx, 0, 0, + driDrawPriv->w, driDrawPriv->h ); + } + + if (newR200Ctx->vb.enabled) + r200VtxfmtMakeCurrent( newR200Ctx->glCtx ); + + _mesa_update_state( newR200Ctx->glCtx ); + r200ValidateState( newR200Ctx->glCtx ); + + } else { + if (R200_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx is null\n", __FUNCTION__); + _mesa_make_current( 0, 0 ); + } + + if (R200_DEBUG & DEBUG_DRI) + fprintf(stderr, "End %s\n", __FUNCTION__); + return GL_TRUE; +} + +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean +r200UnbindContext( __DRIcontextPrivate *driContextPriv ) +{ + r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate; + + if (R200_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, rmesa->glCtx); + + r200VtxfmtUnbindContext( rmesa->glCtx ); + return GL_TRUE; +} + + + + + + diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_context.h b/xc/lib/GL/mesa/src/drv/r200/r200_context.h new file mode 100644 index 000000000..e619a54fc --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_context.h @@ -0,0 +1,925 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_CONTEXT_H__ +#define __R200_CONTEXT_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include <X11/Xlibint.h> +#include "dri_util.h" +#include "xf86drm.h" +#include "radeon_common.h" + +#include "macros.h" +#include "mtypes.h" +#include "r200_reg.h" + +struct r200_context; +typedef struct r200_context r200ContextRec; +typedef struct r200_context *r200ContextPtr; + +#include "r200_lock.h" +#include "r200_screen.h" +#include "mm.h" + +/* Flags for software fallback cases */ +/* See correponding strings in r200_swtcl.c */ +#define R200_FALLBACK_TEXTURE 0x1 +#define R200_FALLBACK_DRAW_BUFFER 0x2 +#define R200_FALLBACK_STENCIL 0x4 +#define R200_FALLBACK_RENDER_MODE 0x8 +#define R200_FALLBACK_BLEND_EQ 0x10 +#define R200_FALLBACK_BLEND_FUNC 0x20 +#define R200_FALLBACK_DISABLE 0x40 + +/* Use the templated vertex format: + */ +#define COLOR_IS_RGBA +#define TAG(x) r200##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +typedef void (*r200_tri_func)( r200ContextPtr, + r200Vertex *, + r200Vertex *, + r200Vertex * ); + +typedef void (*r200_line_func)( r200ContextPtr, + r200Vertex *, + r200Vertex * ); + +typedef void (*r200_point_func)( r200ContextPtr, + r200Vertex * ); + + +struct r200_colorbuffer_state { + GLuint clear; + GLint drawOffset, drawPitch; +}; + + +struct r200_depthbuffer_state { + GLfloat scale; +}; + +struct r200_pixel_state { + GLint readOffset, readPitch; +}; + +struct r200_scissor_state { + XF86DRIClipRectRec rect; + GLboolean enabled; + + GLuint numClipRects; /* Cliprects active */ + GLuint numAllocedClipRects; /* Cliprects available */ + XF86DRIClipRectPtr pClipRects; +}; + +struct r200_stencilbuffer_state { + GLboolean hwBuffer; + GLuint clear; /* rb3d_stencilrefmask value */ +}; + +struct r200_stipple_state { + GLuint mask[32]; +}; + + + +#define TEX_0 0x1 +#define TEX_1 0x2 +#define TEX_ALL 0x3 + +typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr; + +/* Texture object in locally shared texture space. + */ +struct r200_tex_obj { + r200TexObjPtr next, prev; + + struct gl_texture_object *tObj; /* Mesa texture object */ + + PMemBlock memBlock; /* Memory block containing texture */ + GLuint bufAddr; /* Offset to start of locally + shared texture block */ + + GLuint dirty_images; /* Flags for whether or not + images need to be uploaded to + local or AGP texture space */ + + GLuint dirty_state; /* Flags (1 per texunit) for + whether or not this texobj + has dirty hardware state + (pp_*) that needs to be + brought into the + texunit. */ + + GLint heap; /* Texture heap currently stored in */ + + drmRadeonTexImage image[RADEON_MAX_TEXTURE_LEVELS]; + + GLint totalSize; /* Total size of the texture + including all mipmap levels */ + + GLuint pp_txfilter; /* hardware register values */ + GLuint pp_txformat; + GLuint pp_txoffset; + GLuint pp_txsize; /* npot only */ + GLuint pp_txpitch; /* npot only */ + GLuint pp_border_color; + + /* texObj->Image[firstLevel] through texObj->Image[lastLevel] are the + * images to upload. + */ + GLint firstLevel; + GLint lastLevel; +}; + + +struct r200_texture_env_state { + r200TexObjPtr texobj; + GLenum format; + GLenum envMode; +}; + +#define R200_MAX_TEXTURE_UNITS 3 + +struct r200_texture_state { + struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS]; +}; + + +struct r200_state_atom { + struct r200_state_atom *next, *prev; + const char *name; /* for debug */ + int cmd_size; /* size in bytes */ + GLuint idx; + int *cmd; /* one or more cmd's */ + int *lastcmd; /* one or more cmd's */ + GLboolean (*check)( GLcontext *, int ); /* is this state active? */ +}; + + + +/* Trying to keep these relatively short as the variables are becoming + * extravagently long. Drop the R200_ off the front of everything - + * I think we know we're in the r200 driver by now, and keep the + * prefix to 3 letters unless absolutely impossible. + */ + +#define CTX_CMD_0 0 +#define CTX_PP_MISC 1 +#define CTX_PP_FOG_COLOR 2 +#define CTX_RE_SOLID_COLOR 3 +#define CTX_RB3D_BLENDCNTL 4 +#define CTX_RB3D_DEPTHOFFSET 5 +#define CTX_RB3D_DEPTHPITCH 6 +#define CTX_RB3D_ZSTENCILCNTL 7 +#define CTX_CMD_1 8 +#define CTX_PP_CNTL 9 +#define CTX_RB3D_CNTL 10 +#define CTX_RB3D_COLOROFFSET 11 +#define CTX_CMD_2 12 /* why */ +#define CTX_RB3D_COLORPITCH 13 /* why */ +#define CTX_STATE_SIZE 14 + +#define SET_CMD_0 0 +#define SET_SE_CNTL 1 +#define SET_RE_CNTL 2 /* replace se_coord_fmt */ +#define SET_STATE_SIZE 3 + +#define VTE_CMD_0 0 +#define VTE_SE_VTE_CNTL 1 +#define VTE_STATE_SIZE 2 + +#define LIN_CMD_0 0 +#define LIN_RE_LINE_PATTERN 1 +#define LIN_RE_LINE_STATE 2 +#define LIN_CMD_1 3 +#define LIN_SE_LINE_WIDTH 4 +#define LIN_STATE_SIZE 5 + +#define MSK_CMD_0 0 +#define MSK_RB3D_STENCILREFMASK 1 +#define MSK_RB3D_ROPCNTL 2 +#define MSK_RB3D_PLANEMASK 3 +#define MSK_STATE_SIZE 4 + +#define VPT_CMD_0 0 +#define VPT_SE_VPORT_XSCALE 1 +#define VPT_SE_VPORT_XOFFSET 2 +#define VPT_SE_VPORT_YSCALE 3 +#define VPT_SE_VPORT_YOFFSET 4 +#define VPT_SE_VPORT_ZSCALE 5 +#define VPT_SE_VPORT_ZOFFSET 6 +#define VPT_STATE_SIZE 7 + +#define ZBS_CMD_0 0 +#define ZBS_SE_ZBIAS_FACTOR 1 +#define ZBS_SE_ZBIAS_CONSTANT 2 +#define ZBS_STATE_SIZE 3 + +#define MSC_CMD_0 0 +#define MSC_RE_MISC 1 +#define MSC_STATE_SIZE 2 + +#define TAM_CMD_0 0 +#define TAM_DEBUG3 1 +#define TAM_STATE_SIZE 2 + +#define TEX_CMD_0 0 +#define TEX_PP_TXFILTER 1 +#define TEX_PP_TXFORMAT 2 +#define TEX_PP_TXFORMAT_X 3 +#define TEX_PP_TXSIZE 4 +#define TEX_PP_TXPITCH 5 +#define TEX_PP_BORDER_COLOR 6 +#define TEX_CMD_1 7 +#define TEX_PP_TXOFFSET 8 +#define TEX_STATE_SIZE 9 + +#define PIX_CMD_0 0 +#define PIX_PP_TXCBLEND 1 +#define PIX_PP_TXCBLEND2 2 +#define PIX_PP_TXABLEND 3 +#define PIX_PP_TXABLEND2 4 +#define PIX_STATE_SIZE 5 + +#define TF_CMD_0 0 +#define TF_TFACTOR_0 1 +#define TF_TFACTOR_1 2 +#define TF_TFACTOR_2 3 +#define TF_TFACTOR_3 4 +#define TF_TFACTOR_4 5 +#define TF_TFACTOR_5 6 +#define TF_STATE_SIZE 7 + +#define TCL_CMD_0 0 +#define TCL_LIGHT_MODEL_CTL_0 1 +#define TCL_LIGHT_MODEL_CTL_1 2 +#define TCL_PER_LIGHT_CTL_0 3 +#define TCL_PER_LIGHT_CTL_1 4 +#define TCL_PER_LIGHT_CTL_2 5 +#define TCL_PER_LIGHT_CTL_3 6 +#define TCL_CMD_1 7 +#define TCL_UCP_VERT_BLEND_CTL 8 +#define TCL_STATE_SIZE 9 + +#define MSL_CMD_0 0 +#define MSL_MATRIX_SELECT_0 1 +#define MSL_MATRIX_SELECT_1 2 +#define MSL_MATRIX_SELECT_2 3 +#define MSL_MATRIX_SELECT_3 4 +#define MSL_MATRIX_SELECT_4 5 +#define MSL_STATE_SIZE 6 + +#define TCG_CMD_0 0 +#define TCG_TEX_PROC_CTL_2 1 +#define TCG_TEX_PROC_CTL_3 2 +#define TCG_TEX_PROC_CTL_0 3 +#define TCG_TEX_PROC_CTL_1 4 +#define TCG_TEX_CYL_WRAP_CTL 5 +#define TCG_STATE_SIZE 6 + +#define MTL_CMD_0 0 +#define MTL_EMMISSIVE_RED 1 +#define MTL_EMMISSIVE_GREEN 2 +#define MTL_EMMISSIVE_BLUE 3 +#define MTL_EMMISSIVE_ALPHA 4 +#define MTL_AMBIENT_RED 5 +#define MTL_AMBIENT_GREEN 6 +#define MTL_AMBIENT_BLUE 7 +#define MTL_AMBIENT_ALPHA 8 +#define MTL_DIFFUSE_RED 9 +#define MTL_DIFFUSE_GREEN 10 +#define MTL_DIFFUSE_BLUE 11 +#define MTL_DIFFUSE_ALPHA 12 +#define MTL_SPECULAR_RED 13 +#define MTL_SPECULAR_GREEN 14 +#define MTL_SPECULAR_BLUE 15 +#define MTL_SPECULAR_ALPHA 16 +#define MTL_CMD_1 17 +#define MTL_SHININESS 18 +#define MTL_STATE_SIZE 19 + +#define VAP_CMD_0 0 +#define VAP_SE_VAP_CNTL 1 +#define VAP_STATE_SIZE 2 + +/* Replaces a lot of packet info from radeon + */ +#define VTX_CMD_0 0 +#define VTX_VTXFMT_0 1 +#define VTX_VTXFMT_1 2 +#define VTX_TCL_OUTPUT_VTXFMT_0 3 +#define VTX_TCL_OUTPUT_VTXFMT_1 4 +#define VTX_CMD_1 5 +#define VTX_TCL_OUTPUT_COMPSEL 6 +#define VTX_CMD_2 7 +#define VTX_STATE_CNTL 8 +#define VTX_STATE_SIZE 9 + + +#define VTX_COLOR(v,n) (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\ + R200_VTX_COLOR_MASK) + +#define MAT_CMD_0 0 +#define MAT_ELT_0 1 +#define MAT_STATE_SIZE 17 + +#define GRD_CMD_0 0 +#define GRD_VERT_GUARD_CLIP_ADJ 1 +#define GRD_VERT_GUARD_DISCARD_ADJ 2 +#define GRD_HORZ_GUARD_CLIP_ADJ 3 +#define GRD_HORZ_GUARD_DISCARD_ADJ 4 +#define GRD_STATE_SIZE 5 + +/* position changes frequently when lighting in modelpos - separate + * out to new state item? + */ +#define LIT_CMD_0 0 +#define LIT_AMBIENT_RED 1 +#define LIT_AMBIENT_GREEN 2 +#define LIT_AMBIENT_BLUE 3 +#define LIT_AMBIENT_ALPHA 4 +#define LIT_DIFFUSE_RED 5 +#define LIT_DIFFUSE_GREEN 6 +#define LIT_DIFFUSE_BLUE 7 +#define LIT_DIFFUSE_ALPHA 8 +#define LIT_SPECULAR_RED 9 +#define LIT_SPECULAR_GREEN 10 +#define LIT_SPECULAR_BLUE 11 +#define LIT_SPECULAR_ALPHA 12 +#define LIT_POSITION_X 13 +#define LIT_POSITION_Y 14 +#define LIT_POSITION_Z 15 +#define LIT_POSITION_W 16 +#define LIT_DIRECTION_X 17 +#define LIT_DIRECTION_Y 18 +#define LIT_DIRECTION_Z 19 +#define LIT_DIRECTION_W 20 +#define LIT_ATTEN_CONST 21 +#define LIT_ATTEN_LINEAR 22 +#define LIT_ATTEN_QUADRATIC 23 +#define LIT_ATTEN_XXX 24 +#define LIT_CMD_1 25 +#define LIT_SPOT_DCD 26 +#define LIT_SPOT_DCM 27 +#define LIT_SPOT_EXPONENT 28 +#define LIT_SPOT_CUTOFF 29 +#define LIT_SPECULAR_THRESH 30 +#define LIT_RANGE_CUTOFF 31 /* ? */ +#define LIT_RANGE_ATTEN 32 /* ? */ +#define LIT_STATE_SIZE 33 + +/* Fog + */ +#define FOG_CMD_0 0 +#define FOG_R 1 +#define FOG_C 2 +#define FOG_D 3 +#define FOG_PAD 4 +#define FOG_STATE_SIZE 5 + +/* UCP + */ +#define UCP_CMD_0 0 +#define UCP_X 1 +#define UCP_Y 2 +#define UCP_Z 3 +#define UCP_W 4 +#define UCP_STATE_SIZE 5 + +/* GLT - Global ambient + */ +#define GLT_CMD_0 0 +#define GLT_RED 1 +#define GLT_GREEN 2 +#define GLT_BLUE 3 +#define GLT_ALPHA 4 +#define GLT_STATE_SIZE 5 + +/* EYE + */ +#define EYE_CMD_0 0 +#define EYE_X 1 +#define EYE_Y 2 +#define EYE_Z 3 +#define EYE_RESCALE_FACTOR 4 +#define EYE_STATE_SIZE 5 + +/* CST - constant state + */ +#define CST_CMD_0 0 +#define CST_PP_CNTL_X 1 +#define CST_CMD_1 2 +#define CST_RB3D_DEPTHXY_OFFSET 3 +#define CST_CMD_2 4 +#define CST_RE_AUX_SCISSOR_CNTL 5 +#define CST_CMD_3 6 +#define CST_RE_SCISSOR_TL_0 7 +#define CST_RE_SCISSOR_BR_0 8 +#define CST_CMD_4 9 +#define CST_SE_VAP_CNTL_STATUS 10 +#define CST_CMD_5 11 +#define CST_RE_POINTSIZE 12 +#define CST_CMD_6 13 +#define CST_SE_TCL_INPUT_VTX_0 14 +#define CST_SE_TCL_INPUT_VTX_1 15 +#define CST_SE_TCL_INPUT_VTX_2 16 +#define CST_SE_TCL_INPUT_VTX_3 17 +#define CST_STATE_SIZE 18 + + + + +struct r200_hw_state { + /* All state should be on one of these lists: + */ + struct r200_state_atom dirty; /* dirty list head placeholder */ + struct r200_state_atom clean; /* clean list head placeholder */ + + /* Hardware state, stored as cmdbuf commands: + * -- Need to doublebuffer for + * - reviving state after loss of context + * - eliding noop statechange loops? (except line stipple count) + */ + struct r200_state_atom ctx; + struct r200_state_atom set; + struct r200_state_atom vte; + struct r200_state_atom lin; + struct r200_state_atom msk; + struct r200_state_atom vpt; + struct r200_state_atom vap; + struct r200_state_atom vtx; + struct r200_state_atom tcl; + struct r200_state_atom msl; + struct r200_state_atom tcg; + struct r200_state_atom msc; + struct r200_state_atom cst; + struct r200_state_atom tam; + struct r200_state_atom tf; + struct r200_state_atom tex[2]; + struct r200_state_atom zbs; + struct r200_state_atom mtl[2]; + struct r200_state_atom mat[5]; + struct r200_state_atom lit[8]; /* includes vec, scl commands */ + struct r200_state_atom ucp[6]; + struct r200_state_atom pix[6]; /* pixshader stages */ + struct r200_state_atom eye; /* eye pos */ + struct r200_state_atom grd; /* guard band clipping */ + struct r200_state_atom fog; + struct r200_state_atom glt; +}; + +struct r200_state { + /* Derived state for internal purposes: + */ + struct r200_colorbuffer_state color; + struct r200_depthbuffer_state depth; + struct r200_pixel_state pixel; + struct r200_scissor_state scissor; + struct r200_stencilbuffer_state stencil; + struct r200_stipple_state stipple; + struct r200_texture_state texture; +}; + +struct r200_texture { + r200TexObj objects[R200_NR_TEX_HEAPS]; + r200TexObj swapped; + + memHeap_t *heap[R200_NR_TEX_HEAPS]; + GLint age[R200_NR_TEX_HEAPS]; + + GLint numHeaps; +}; + +/* Need refcounting on dma buffers: + */ +struct r200_dma_buffer { + int refcount; /* the number of retained regions in buf */ + drmBufPtr buf; +}; + +#define GET_START(rvb) (rmesa->r200Screen->agp_buffer_offset + \ + (rvb)->address - rmesa->dma.buf0_address + \ + (rvb)->start) + +/* A retained region, eg vertices for indexed vertices. + */ +struct r200_dma_region { + struct r200_dma_buffer *buf; + char *address; /* == buf->address */ + int start, end, ptr; /* offsets from start of buf */ + int aos_start; + int aos_stride; + int aos_size; +}; + + +struct r200_dma { + /* Active dma region. Allocations for vertices and retained + * regions come from here. Also used for emitting random vertices, + * these may be flushed by calling flush_current(); + */ + struct r200_dma_region current; + + void (*flush)( r200ContextPtr ); + + char *buf0_address; /* start of buf[0], for index calcs */ + GLuint nr_released_bufs; /* flush after so many buffers released */ +}; + +struct r200_dri_mirror { + Display *display; /* X server display */ + + __DRIcontextPrivate *context; /* DRI context */ + __DRIscreenPrivate *screen; /* DRI screen */ + __DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */ + + drmContext hwContext; + drmLock *hwLock; + int fd; + int drmMinor; +}; + + +#define R200_CMD_BUF_SZ (8*1024) + +struct r200_store { + GLuint statenr; + GLuint primnr; + char cmd_buf[R200_CMD_BUF_SZ]; + int cmd_used; + int elts_start; +}; + + +/* r200_tcl.c + */ +struct r200_tcl_info { + GLuint vertex_format; + GLint last_offset; + GLuint hw_primitive; + + struct r200_dma_region *aos_components[8]; + GLuint nr_aos_components; + + GLuint *Elts; + + struct r200_dma_region indexed_verts; + struct r200_dma_region obj; + struct r200_dma_region rgba; + struct r200_dma_region spec; + struct r200_dma_region fog; + struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS]; + struct r200_dma_region norm; +}; + + +/* r200_swtcl.c + */ +struct r200_swtcl_info { + GLuint SetupIndex; + GLuint SetupNewInputs; + GLuint RenderIndex; + GLuint vertex_size; + GLuint vertex_stride_shift; + GLuint vertex_format; + char *verts; + + /* Fallback rasterization functions + */ + r200_point_func draw_point; + r200_line_func draw_line; + r200_tri_func draw_tri; + + GLuint hw_primitive; + GLenum render_primitive; + GLuint numverts; + + struct r200_dma_region indexed_verts; +}; + + +struct r200_ioctl { + GLuint vertex_offset; + GLuint vertex_size; +}; + + + +#define R200_MAX_PRIMS 64 + + +/* Want to keep a cache of these around. Each is parameterized by + * only a single value which has only a small range. Only expect a + * few, so just rescan the list each time? + */ +struct dynfn { + struct dynfn *next, *prev; + int key[2]; + char *code; +}; + +struct dfn_lists { + struct dynfn Vertex2f; + struct dynfn Vertex2fv; + struct dynfn Vertex3f; + struct dynfn Vertex3fv; + struct dynfn Color4ub; + struct dynfn Color4ubv; + struct dynfn Color3ub; + struct dynfn Color3ubv; + struct dynfn Color4f; + struct dynfn Color4fv; + struct dynfn Color3f; + struct dynfn Color3fv; + struct dynfn SecondaryColor3ubEXT; + struct dynfn SecondaryColor3ubvEXT; + struct dynfn SecondaryColor3fEXT; + struct dynfn SecondaryColor3fvEXT; + struct dynfn Normal3f; + struct dynfn Normal3fv; + struct dynfn TexCoord2f; + struct dynfn TexCoord2fv; + struct dynfn TexCoord1f; + struct dynfn TexCoord1fv; + struct dynfn MultiTexCoord2fARB; + struct dynfn MultiTexCoord2fvARB; + struct dynfn MultiTexCoord1fARB; + struct dynfn MultiTexCoord1fvARB; +}; + +struct _vb; + +struct dfn_generators { + struct dynfn *(*Vertex2f)( GLcontext *, const int * ); + struct dynfn *(*Vertex2fv)( GLcontext *, const int * ); + struct dynfn *(*Vertex3f)( GLcontext *, const int * ); + struct dynfn *(*Vertex3fv)( GLcontext *, const int * ); + struct dynfn *(*Color4ub)( GLcontext *, const int * ); + struct dynfn *(*Color4ubv)( GLcontext *, const int * ); + struct dynfn *(*Color3ub)( GLcontext *, const int * ); + struct dynfn *(*Color3ubv)( GLcontext *, const int * ); + struct dynfn *(*Color4f)( GLcontext *, const int * ); + struct dynfn *(*Color4fv)( GLcontext *, const int * ); + struct dynfn *(*Color3f)( GLcontext *, const int * ); + struct dynfn *(*Color3fv)( GLcontext *, const int * ); + struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, const int * ); + struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, const int * ); + struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, const int * ); + struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, const int * ); + struct dynfn *(*Normal3f)( GLcontext *, const int * ); + struct dynfn *(*Normal3fv)( GLcontext *, const int * ); + struct dynfn *(*TexCoord2f)( GLcontext *, const int * ); + struct dynfn *(*TexCoord2fv)( GLcontext *, const int * ); + struct dynfn *(*TexCoord1f)( GLcontext *, const int * ); + struct dynfn *(*TexCoord1fv)( GLcontext *, const int * ); + struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, const int * ); + struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, const int * ); + struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, const int * ); + struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, const int * ); +}; + + +struct r200_vb { + /* Keep these first: referenced from codegen templates: + */ + GLint counter, initial_counter; + GLint *dmaptr; + void (*notify)( void ); + GLint vertex_size; + + /* A maximum total of 15 elements per vertex: 3 floats for position, 3 + * floats for normal, 4 floats for color, 4 bytes for secondary color, + * 2 floats for each texture unit (4 floats total). + * + * As soon as the 3rd TMU is supported or cube maps (or 3D textures) are + * supported, this value will grow. + * + * The position data is never actually stored here, so 3 elements could be + * trimmed out of the buffer. + */ + union { float f; int i; r200_color_t color; } vertex[15]; + + GLfloat *normalptr; + GLfloat *floatcolorptr; + r200_color_t *colorptr; + GLfloat *floatspecptr; + r200_color_t *specptr; + GLfloat *texcoordptr[2]; + + GLcontext *context; /* current context : Single thread only! */ +}; + +struct r200_prim { + GLuint start; + GLuint end; + GLuint prim; +}; + +struct r200_vbinfo { + GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ + GLuint primflags; + GLboolean enabled; /* R200_NO_VTXFMT//R200_NO_TCL env vars */ + GLboolean installed; + GLboolean fell_back; + GLboolean recheck; + GLint initial_counter; + GLint nrverts; + GLuint vtxfmt_0, vtxfmt_1; + + GLuint installed_vertex_format; + GLuint installed_color_3f_sz; + + struct r200_prim primlist[R200_MAX_PRIMS]; + int nrprims; + + struct dfn_lists dfn_cache; + struct dfn_generators codegen; + GLvertexformat vtxfmt; +}; + + + + +struct r200_context { + GLcontext *glCtx; /* Mesa context */ + + /* Driver and hardware state management + */ + struct r200_hw_state hw; + struct r200_state state; + + /* Texture object bookkeeping + */ + struct r200_texture texture; + + + /* Rasterization and vertex state: + */ + GLuint TclFallback; + GLuint Fallback; + GLuint NewGLState; + + + /* Temporaries for translating away float colors: + */ + struct gl_client_array UbyteColor; + struct gl_client_array UbyteSecondaryColor; + + /* Vertex buffers + */ + struct r200_ioctl ioctl; + struct r200_dma dma; + struct r200_store store; + + /* Page flipping + */ + GLuint doPageFlip; + + /* Busy waiting + */ + GLuint do_usleeps; + GLuint do_irqs; + GLuint irqsEmitted; + drmRadeonIrqWait iw; + + /* Clientdata textures; + */ + GLuint prefer_agp_client_texturing; + + /* Drawable, cliprect and scissor information + */ + GLuint numClipRects; /* Cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; + unsigned int lastStamp; + GLboolean lost_context; + r200ScreenPtr r200Screen; /* Screen private DRI data */ + RADEONSAREAPrivPtr sarea; /* Private SAREA data */ + + /* TCL stuff + */ + GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS]; + GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS]; + GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS]; + GLuint TexMatEnabled; + GLuint TexMatCompSel; + GLuint TexGenEnabled; + GLuint TexGenInputs; + GLuint TexGenCompSel; + GLmatrix tmpmat; + + /* VBI + */ + GLuint vbl_seq; + + /* r200_tcl.c + */ + struct r200_tcl_info tcl; + + /* r200_swtcl.c + */ + struct r200_swtcl_info swtcl; + + /* r200_vtxfmt.c + */ + struct r200_vbinfo vb; + + /* Mirrors of some DRI state + */ + struct r200_dri_mirror dri; +}; + +#define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx)) + + +static __inline GLuint r200PackColor( GLuint cpp, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + switch ( cpp ) { + case 2: + return PACK_COLOR_565( r, g, b ); + case 4: + return PACK_COLOR_8888( a, r, g, b ); + default: + return 0; + } +} + +#define R200_OLD_PACKETS 0 + + +extern void r200DestroyContext( __DRIcontextPrivate *driContextPriv ); +extern GLboolean r200CreateContext( Display *dpy, + const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate); +extern void r200SwapBuffers(Display *dpy, void *drawablePrivate); +extern GLboolean r200MakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ); +extern GLboolean r200UnbindContext( __DRIcontextPrivate *driContextPriv ); + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 + +#if DO_DEBUG +extern int R200_DEBUG; +#else +#define R200_DEBUG 0 +#endif + +#define DEBUG_TEXTURE 0x001 +#define DEBUG_STATE 0x002 +#define DEBUG_IOCTL 0x004 +#define DEBUG_PRIMS 0x008 +#define DEBUG_VERTS 0x010 +#define DEBUG_FALLBACKS 0x020 +#define DEBUG_VFMT 0x040 +#define DEBUG_CODEGEN 0x080 +#define DEBUG_VERBOSE 0x100 +#define DEBUG_DRI 0x200 +#define DEBUG_DMA 0x400 +#define DEBUG_SANITY 0x800 +#define DEBUG_SYNC 0x1000 +#define DEBUG_PIXEL 0x2000 + +#endif +#endif /* __R200_CONTEXT_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c new file mode 100644 index 000000000..11ffe8b7c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c @@ -0,0 +1,922 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c,v 1.4 2002/12/17 00:32:56 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_state.h" +#include "r200_ioctl.h" +#include "r200_tcl.h" +#include "r200_sanity.h" +#include "radeon_reg.h" + +#include "mem.h" +#include "macros.h" +#include "context.h" +#include "swrast/swrast.h" + +#include <unistd.h> /* for usleep */ + +#define R200_TIMEOUT 512 +#define R200_IDLE_RETRY 16 + + +static void do_usleep( int nr, const char *caller ) +{ + if (0) fprintf(stderr, "usleep %d in %s\n", nr, caller ); + if (1) usleep( nr ); +} + +static void r200WaitForIdle( r200ContextPtr rmesa ); + + +int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ) +{ + int ret, i; + drmRadeonCmdBuffer cmd; + + if (R200_DEBUG & DEBUG_IOCTL) { + fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); + + if (0 & R200_DEBUG & DEBUG_VERBOSE) + for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 ) + fprintf(stderr, "%d: %x\n", i/4, + *(int *)(&rmesa->store.cmd_buf[i])); + } + + if (R200_DEBUG & DEBUG_DMA) + fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__, + rmesa->dma.nr_released_bufs); + + + if (R200_DEBUG & DEBUG_SANITY) { + if (rmesa->state.scissor.enabled) + ret = r200SanityCmdBuffer( rmesa, + rmesa->state.scissor.numClipRects, + rmesa->state.scissor.pClipRects); + else + ret = r200SanityCmdBuffer( rmesa, + rmesa->numClipRects, + rmesa->pClipRects); + if (ret) { + fprintf(stderr, "drmSanityCommandWrite: %d\n", ret); + goto out; + } + } + + + cmd.bufsz = rmesa->store.cmd_used; + cmd.buf = rmesa->store.cmd_buf; + + if (rmesa->state.scissor.enabled) { + cmd.nbox = rmesa->state.scissor.numClipRects; + cmd.boxes = (drmClipRect *)rmesa->state.scissor.pClipRects; + } else { + cmd.nbox = rmesa->numClipRects; + cmd.boxes = (drmClipRect *)rmesa->pClipRects; + } + + ret = drmCommandWrite( rmesa->dri.fd, + DRM_RADEON_CMDBUF, + &cmd, sizeof(cmd) ); + + if (ret) + fprintf(stderr, "drmCommandWrite: %d\n", ret); + + if (R200_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); + r200WaitForIdleLocked( rmesa ); + } + + + out: + rmesa->store.primnr = 0; + rmesa->store.statenr = 0; + rmesa->store.cmd_used = 0; + rmesa->dma.nr_released_bufs = 0; +/* rmesa->lost_context = 0; */ + rmesa->lost_context = 1; + return ret; +} + + +/* Note: does not emit any commands to avoid recursion on + * r200AllocCmdBuf. + */ +void r200FlushCmdBuf( r200ContextPtr rmesa, const char *caller ) +{ + int ret; + + LOCK_HARDWARE( rmesa ); + + ret = r200FlushCmdBufLocked( rmesa, caller ); + + UNLOCK_HARDWARE( rmesa ); + + if (ret) { + fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); + exit(ret); + } +} + + +/* ============================================================= + * Hardware vertex buffer handling + */ + + +void r200RefillCurrentDmaRegion( r200ContextPtr rmesa ) +{ + struct r200_dma_buffer *dmabuf; + int fd = rmesa->dri.fd; + int index = 0; + int size = 0; + drmDMAReq dma; + int ret; + + if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->dma.flush) { + rmesa->dma.flush( rmesa ); + } + + if (rmesa->dma.current.buf) + r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); + + if (rmesa->dma.nr_released_bufs > 4) + r200FlushCmdBuf( rmesa, __FUNCTION__ ); + + dma.context = rmesa->dri.hwContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + dma.request_size = RADEON_BUFFER_SIZE; + dma.request_list = &index; + dma.request_sizes = &size; + dma.granted_count = 0; + + LOCK_HARDWARE(rmesa); /* no need to validate */ + + while (1) { + ret = drmDMA( fd, &dma ); + if (ret == 0) + break; + + if (rmesa->dma.nr_released_bufs) { + r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); + } + + if (rmesa->do_usleeps) { + UNLOCK_HARDWARE( rmesa ); + do_usleep(1, __FUNCTION__); + LOCK_HARDWARE( rmesa ); + } + } + + UNLOCK_HARDWARE(rmesa); + + if (R200_DEBUG & DEBUG_DMA) + fprintf(stderr, "Allocated buffer %d\n", index); + + dmabuf = CALLOC_STRUCT( r200_dma_buffer ); + dmabuf->buf = &rmesa->r200Screen->buffers->list[index]; + dmabuf->refcount = 1; + + rmesa->dma.current.buf = dmabuf; + rmesa->dma.current.address = dmabuf->buf->address; + rmesa->dma.current.end = dmabuf->buf->total; + rmesa->dma.current.start = 0; + rmesa->dma.current.ptr = 0; +} + +void r200ReleaseDmaRegion( r200ContextPtr rmesa, + struct r200_dma_region *region, + const char *caller ) +{ + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); + + if (!region->buf) + return; + + if (rmesa->dma.flush) + rmesa->dma.flush( rmesa ); + + if (--region->buf->refcount == 0) { + drmRadeonCmdHeader *cmd; + + if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) + fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__, + region->buf->buf->idx); + + cmd = (drmRadeonCmdHeader *)r200AllocCmdBuf( rmesa, sizeof(*cmd), + __FUNCTION__ ); + cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD; + cmd->dma.buf_idx = region->buf->buf->idx; + FREE(region->buf); + rmesa->dma.nr_released_bufs++; + } + + region->buf = 0; + region->start = 0; +} + +/* Allocates a region from rmesa->dma.current. If there isn't enough + * space in current, grab a new buffer (and discard what was left of current) + */ +void r200AllocDmaRegion( r200ContextPtr rmesa, + struct r200_dma_region *region, + int bytes, + int alignment ) +{ + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); + + if (rmesa->dma.flush) + rmesa->dma.flush( rmesa ); + + if (region->buf) + r200ReleaseDmaRegion( rmesa, region, __FUNCTION__ ); + + alignment--; + rmesa->dma.current.start = rmesa->dma.current.ptr = + (rmesa->dma.current.ptr + alignment) & ~alignment; + + if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) + r200RefillCurrentDmaRegion( rmesa ); + + region->start = rmesa->dma.current.start; + region->ptr = rmesa->dma.current.start; + region->end = rmesa->dma.current.start + bytes; + region->address = rmesa->dma.current.address; + region->buf = rmesa->dma.current.buf; + region->buf->refcount++; + + rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ + rmesa->dma.current.start = + rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7; +} + +void r200AllocDmaRegionVerts( r200ContextPtr rmesa, + struct r200_dma_region *region, + int numverts, + int vertsize, + int alignment ) +{ + r200AllocDmaRegion( rmesa, region, vertsize * numverts, alignment ); +} + +/* ================================================================ + * SwapBuffers with client-side throttling + */ + +static CARD32 r200GetLastFrame(r200ContextPtr rmesa) +{ + drmRadeonGetParam gp; + int ret; + CARD32 frame; + + gp.param = RADEON_PARAM_LAST_FRAME; + gp.value = (int *)&frame; + ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp) ); + if ( ret ) { + fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret ); + exit(1); + } + + return frame; +} + +static void r200EmitIrqLocked( r200ContextPtr rmesa ) +{ + drmRadeonIrqEmit ie; + int ret; + + ie.irq_seq = &rmesa->iw.irq_seq; + ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_IRQ_EMIT, + &ie, sizeof(ie) ); + if ( ret ) { + fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret ); + exit(1); + } +} + + +static void r200WaitIrq( r200ContextPtr rmesa ) +{ + int ret; + + do { + ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_IRQ_WAIT, + &rmesa->iw, sizeof(rmesa->iw) ); + } while (ret && (errno == EINTR || errno == EAGAIN)); + + if ( ret ) { + fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret ); + exit(1); + } +} + + +static void r200WaitForFrameCompletion( r200ContextPtr rmesa ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + + if (rmesa->do_irqs) { + if (r200GetLastFrame(rmesa) < sarea->last_frame) { + if (!rmesa->irqsEmitted) { + while (r200GetLastFrame (rmesa) < sarea->last_frame) + ; + } + else { + UNLOCK_HARDWARE( rmesa ); + r200WaitIrq( rmesa ); + LOCK_HARDWARE( rmesa ); + } + rmesa->irqsEmitted = 10; + } + + if (rmesa->irqsEmitted) { + r200EmitIrqLocked( rmesa ); + rmesa->irqsEmitted--; + } + } + else { + while (r200GetLastFrame (rmesa) < sarea->last_frame) { + UNLOCK_HARDWARE( rmesa ); + if (rmesa->do_usleeps) + do_usleep(1, __FUNCTION__); + LOCK_HARDWARE( rmesa ); + } + } +} + + + +/* Copy the back color buffer to the front color buffer. + */ +void r200CopyBuffer( const __DRIdrawablePrivate *dPriv ) +{ + r200ContextPtr rmesa; + GLint nbox, i, ret; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; + + if ( R200_DEBUG & DEBUG_IOCTL ) { + fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, rmesa->glCtx ); + } + + R200_FIREVERTICES( rmesa ); + + LOCK_HARDWARE( rmesa ); + + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + r200WaitForFrameCompletion( rmesa ); + + r200WaitForVBlank( rmesa ); + + nbox = rmesa->dri.drawable->numClipRects; /* must be in locked region */ + + for ( i = 0 ; i < nbox ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); + XF86DRIClipRectPtr box = rmesa->dri.drawable->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + GLint n = 0; + + for ( ; i < nr ; i++ ) { + *b++ = box[i]; + n++; + } + rmesa->sarea->nbox = n; + + ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP ); + + if ( ret ) { + fprintf( stderr, "DRM_R200_SWAP_BUFFERS: return = %d\n", ret ); + UNLOCK_HARDWARE( rmesa ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( rmesa ); + rmesa->lost_context = 1; +} + +void r200PageFlip( const __DRIdrawablePrivate *dPriv ) +{ + r200ContextPtr rmesa; + GLint ret; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; + + if ( R200_DEBUG & DEBUG_IOCTL ) { + fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, + rmesa->sarea->pfCurrentPage); + } + + R200_FIREVERTICES( rmesa ); + LOCK_HARDWARE( rmesa ); + + if (!rmesa->dri.drawable->numClipRects) { + UNLOCK_HARDWARE( rmesa ); + usleep( 10000 ); /* throttle invisible client 10ms */ + return; + } + + /* Need to do this for the perf box placement: + */ + { + XF86DRIClipRectPtr box = rmesa->dri.drawable->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + b[0] = box[0]; + rmesa->sarea->nbox = 1; + } + + /* Throttle the frame rate -- only allow a few pending swap buffers + * request at a time. + */ + r200WaitForFrameCompletion( rmesa ); + + r200WaitForVBlank( rmesa ); + + ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); + + UNLOCK_HARDWARE( rmesa ); + + if ( ret ) { + fprintf( stderr, "DRM_R200_FLIP: return = %d\n", ret ); + exit( 1 ); + } + + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch; + } else { + rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch; + } + + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset; + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; +} + + +/* ================================================================ + * Buffer clear + */ +static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + GLuint flags = 0; + GLuint color_mask = 0; + GLint ret, i; + + if ( R200_DEBUG & DEBUG_IOCTL ) { + fprintf( stderr, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n", + __FUNCTION__, all, cx, cy, cw, ch ); + } + + { + LOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( rmesa ); + if ( dPriv->numClipRects == 0 ) + return; + } + + r200EmitState( rmesa ); + + /* Need to cope with lostcontext here as kernel relies on + * some residual state: + */ + R200_FIREVERTICES( rmesa ); + + if ( mask & DD_FRONT_LEFT_BIT ) { + flags |= RADEON_FRONT; + color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ( mask & DD_BACK_LEFT_BIT ) { + flags |= RADEON_BACK; + color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; + mask &= ~DD_BACK_LEFT_BIT; + } + + if ( mask & DD_DEPTH_BIT ) { + if ( ctx->Depth.Mask ) flags |= RADEON_DEPTH; /* FIXME: ??? */ + mask &= ~DD_DEPTH_BIT; + } + + if ( (mask & DD_STENCIL_BIT) && rmesa->state.stencil.hwBuffer ) { + flags |= RADEON_STENCIL; + mask &= ~DD_STENCIL_BIT; + } + + if ( mask ) + _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); + + if ( !flags ) + return; + + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + + LOCK_HARDWARE( rmesa ); + + /* Throttle the number of clear ioctls we do. + */ + while ( 1 ) { + drmRadeonGetParam gp; + int ret; + int clear; + + gp.param = RADEON_PARAM_LAST_CLEAR; + gp.value = (int *)&clear; + ret = drmCommandWriteRead( rmesa->dri.fd, + DRM_RADEON_GETPARAM, &gp, sizeof(gp) ); + + if ( ret ) { + fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret ); + exit(1); + } + + /* Clear throttling needs more thought. + */ + if ( rmesa->sarea->last_clear - clear <= 8 ) { + break; + } + + if (rmesa->do_usleeps) { + UNLOCK_HARDWARE( rmesa ); + do_usleep(1, __FUNCTION__); + LOCK_HARDWARE( rmesa ); + } + } + + + for ( i = 0 ; i < dPriv->numClipRects ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects ); + XF86DRIClipRectPtr box = dPriv->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + drmRadeonClearType clear; + drmRadeonClearRect depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; + GLint n = 0; + + if ( !all ) { + for ( ; i < nr ; i++ ) { + GLint x = box[i].x1; + GLint y = box[i].y1; + GLint w = box[i].x2 - x; + GLint h = box[i].y2 - y; + + if ( x < cx ) w -= cx - x, x = cx; + if ( y < cy ) h -= cy - y, y = cy; + if ( x + w > cx + cw ) w = cx + cw - x; + if ( y + h > cy + ch ) h = cy + ch - y; + if ( w <= 0 ) continue; + if ( h <= 0 ) continue; + + b->x1 = x; + b->y1 = y; + b->x2 = x + w; + b->y2 = y + h; + b++; + n++; + } + } else { + for ( ; i < nr ; i++ ) { + *b++ = box[i]; + n++; + } + } + + rmesa->sarea->nbox = n; + + clear.flags = flags; + clear.clear_color = rmesa->state.color.clear; + clear.clear_depth = 0; /* not used */ + clear.color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; + clear.depth_mask = rmesa->state.stencil.clear; + clear.depth_boxes = depth_boxes; + + n--; + b = rmesa->sarea->boxes; + for ( ; n >= 0 ; n-- ) { + depth_boxes[n].f[RADEON_CLEAR_X1] = (float)b[n].x1; + depth_boxes[n].f[RADEON_CLEAR_Y1] = (float)b[n].y1; + depth_boxes[n].f[RADEON_CLEAR_X2] = (float)b[n].x2; + depth_boxes[n].f[RADEON_CLEAR_Y2] = (float)b[n].y2; + depth_boxes[n].f[RADEON_CLEAR_DEPTH] = ctx->Depth.Clear; + } + + ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR, + &clear, sizeof(drmRadeonClearType)); + + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( rmesa ); + rmesa->lost_context = 1; +} + + +void r200WaitForIdleLocked( r200ContextPtr rmesa ) +{ + int ret; + int i = 0; + + do { + ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_CP_IDLE); + if (ret) + do_usleep( 1, __FUNCTION__ ); + } while (ret && ++i < 100); + + if ( ret < 0 ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "Error: R200 timed out... exiting\n" ); + exit( -1 ); + } +} + +static void r200WaitForIdle( r200ContextPtr rmesa ) +{ + LOCK_HARDWARE(rmesa); + r200WaitForIdleLocked( rmesa ); + UNLOCK_HARDWARE(rmesa); +} + + +void r200WaitForVBlank( r200ContextPtr rmesa ) +{ + drmVBlank vbl; + int ret; + + if ( !rmesa->r200Screen->irq ) + return; + + if ( getenv("LIBGL_SYNC_REFRESH") ) { + /* Wait for until the next vertical blank */ + vbl.request.type = DRM_VBLANK_RELATIVE; + vbl.request.sequence = 1; + } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { + /* Wait for at least one vertical blank since the last call */ + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = rmesa->vbl_seq + 1; + } else { + return; + } + + UNLOCK_HARDWARE( rmesa ); + + if ((ret = drmWaitVBlank( rmesa->dri.fd, &vbl ))) { + fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" + " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" + " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); + exit(1); + } else if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s: drmWaitVBlank returned %d\n", __FUNCTION__, ret); + rmesa->vbl_seq = vbl.reply.sequence; + + LOCK_HARDWARE( rmesa ); +} + + +void r200Flush( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->dma.flush) + rmesa->dma.flush( rmesa ); + + if (!is_empty_list(&rmesa->hw.dirty)) + r200EmitState( rmesa ); + + if (rmesa->store.cmd_used) + r200FlushCmdBuf( rmesa, __FUNCTION__ ); +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +void r200Finish( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + r200Flush( ctx ); + + if (rmesa->do_irqs) { + LOCK_HARDWARE( rmesa ); + r200EmitIrqLocked( rmesa ); + UNLOCK_HARDWARE( rmesa ); + r200WaitIrq( rmesa ); + } + else + r200WaitForIdle( rmesa ); +} + + +/* This version of AllocateMemoryNV allocates only agp memory, and + * only does so after the point at which the driver has been + * initialized. + * + * Theoretically a valid context isn't required. However, in this + * implementation, it is, as I'm using the hardware lock to protect + * the kernel data structures, and the current context to get the + * device fd. + */ +void *r200AllocateMemoryNV(GLsizei size, GLfloat readfreq, + GLfloat writefreq, GLfloat priority) +{ + GET_CURRENT_CONTEXT(ctx); + r200ContextPtr rmesa; + int region_offset; + drmRadeonMemAlloc alloc; + int ret; + + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq, + writefreq, priority); + + if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || rmesa->r200Screen->IsPCI ) + return NULL; + + if (getenv("R200_NO_ALLOC")) + return NULL; + + if (rmesa->dri.drmMinor < 6) + return NULL; + + alloc.region = RADEON_MEM_REGION_AGP; + alloc.alignment = 0; + alloc.size = size; + alloc.region_offset = ®ion_offset; + + ret = drmCommandWriteRead( rmesa->r200Screen->driScreen->fd, + DRM_RADEON_ALLOC, + &alloc, sizeof(alloc)); + + if (ret) { + fprintf(stderr, "%s: DRM_RADEON_ALLOC ret %d\n", __FUNCTION__, ret); + return NULL; + } + + { + char *region_start = (char *)rmesa->r200Screen->agpTextures.map; + return (void *)(region_start + region_offset); + } +} + + +/* Called via glXFreeMemoryNV() */ +void r200FreeMemoryNV(GLvoid *pointer) +{ + GET_CURRENT_CONTEXT(ctx); + r200ContextPtr rmesa; + int region_offset; + drmRadeonMemFree memfree; + int ret; + + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %p\n", __FUNCTION__, pointer); + + if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || rmesa->r200Screen->IsPCI ) { + fprintf(stderr, "%s: no context\n", __FUNCTION__); + return; + } + + if (rmesa->dri.drmMinor < 6) + return; + + region_offset = (char *)pointer - (char *)rmesa->r200Screen->agpTextures.map; + + if (region_offset < 0 || + region_offset > rmesa->r200Screen->agpTextures.size) { + fprintf(stderr, "offset %d outside range 0..%d\n", region_offset, + rmesa->r200Screen->agpTextures.size); + return; + } + + memfree.region = RADEON_MEM_REGION_AGP; + memfree.region_offset = region_offset; + + ret = drmCommandWrite( rmesa->r200Screen->driScreen->fd, + DRM_RADEON_FREE, + &memfree, sizeof(memfree)); + + if (ret) + fprintf(stderr, "%s: DRM_RADEON_FREE ret %d\n", __FUNCTION__, ret); +} + +/* Called via glXGetAGPOffsetMESA() */ +GLuint r200GetAGPOffset(const GLvoid *pointer) +{ + GET_CURRENT_CONTEXT(ctx); + r200ContextPtr rmesa; + GLuint card_offset; + + if (!ctx || !(rmesa = R200_CONTEXT(ctx)) ) { + fprintf(stderr, "%s: no context\n", __FUNCTION__); + return ~0; + } + + if (!r200IsAgpMemory( rmesa, pointer, 0 )) + return ~0; + + if (rmesa->dri.drmMinor < 6) + return ~0; + + card_offset = r200AgpOffsetFromVirtual( rmesa, pointer ); + + return card_offset - rmesa->r200Screen->agp_base; +} + + +GLboolean r200IsAgpMemory( r200ContextPtr rmesa, const GLvoid *pointer, + GLint size ) +{ + int offset = (char *)pointer - (char *)rmesa->r200Screen->agpTextures.map; + int valid = (size >= 0 && + offset >= 0 && + offset + size < rmesa->r200Screen->agpTextures.size); + + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "r200IsAgpMemory( %p ) : %d\n", pointer, valid ); + + return valid; +} + + +GLuint r200AgpOffsetFromVirtual( r200ContextPtr rmesa, const GLvoid *pointer ) +{ + int offset = (char *)pointer - (char *)rmesa->r200Screen->agpTextures.map; + + if (offset < 0 || offset > rmesa->r200Screen->agpTextures.size) + return ~0; + else + return rmesa->r200Screen->agp_texture_offset + offset; +} + + + +void r200InitIoctlFuncs( GLcontext *ctx ) +{ + ctx->Driver.Clear = r200Clear; + ctx->Driver.Finish = r200Finish; + ctx->Driver.Flush = r200Flush; +} + diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.h b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.h new file mode 100644 index 000000000..c9ed316db --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.h @@ -0,0 +1,188 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_ioctl.h,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_IOCTL_H__ +#define __R200_IOCTL_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "simple_list.h" +#include "radeon_dri.h" +#include "r200_lock.h" + +#include "xf86drm.h" +#include "radeon_common.h" + +extern void r200EmitState( r200ContextPtr rmesa ); +extern void r200EmitVertexAOS( r200ContextPtr rmesa, + GLuint vertex_size, + GLuint offset ); + +extern void r200EmitVbufPrim( r200ContextPtr rmesa, + GLuint primitive, + GLuint vertex_nr ); + +extern void r200FlushElts( r200ContextPtr rmesa ); + +extern GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, + GLuint primitive, + GLuint min_nr ); + +extern void r200EmitAOS( r200ContextPtr rmesa, + struct r200_dma_region **regions, + GLuint n, + GLuint offset ); + +extern void r200EmitBlit( r200ContextPtr rmesa, + GLuint color_fmt, + GLuint src_pitch, + GLuint src_offset, + GLuint dst_pitch, + GLuint dst_offset, + GLint srcx, GLint srcy, + GLint dstx, GLint dsty, + GLuint w, GLuint h ); + +extern void r200EmitWait( r200ContextPtr rmesa, GLuint flags ); + +extern void r200FlushCmdBuf( r200ContextPtr rmesa, const char * ); +extern int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ); + +extern void r200RefillCurrentDmaRegion( r200ContextPtr rmesa ); + +extern void r200AllocDmaRegion( r200ContextPtr rmesa, + struct r200_dma_region *region, + int bytes, + int alignment ); + +extern void r200AllocDmaRegionVerts( r200ContextPtr rmesa, + struct r200_dma_region *region, + int numverts, + int vertsize, + int alignment ); + +extern void r200ReleaseDmaRegion( r200ContextPtr rmesa, + struct r200_dma_region *region, + const char *caller ); + +extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable ); +extern void r200PageFlip( const __DRIdrawablePrivate *drawable ); +extern void r200Flush( GLcontext *ctx ); +extern void r200Finish( GLcontext *ctx ); +extern void r200WaitForIdleLocked( r200ContextPtr rmesa ); +extern void r200WaitForVBlank( r200ContextPtr rmesa ); +extern void r200InitIoctlFuncs( GLcontext *ctx ); + +extern void *r200AllocateMemoryNV( GLsizei size, GLfloat readfreq, + GLfloat writefreq, GLfloat priority ); +extern void r200FreeMemoryNV( GLvoid *pointer ); +extern GLuint r200GetAGPOffset( const GLvoid *pointer ); +extern GLboolean r200IsAgpMemory( r200ContextPtr rmesa, const GLvoid *pointer, + GLint size ); + +extern GLuint r200AgpOffsetFromVirtual( r200ContextPtr rmesa, + const GLvoid *pointer ); + +/* ================================================================ + * Helper macros: + */ + +/* Close off the last primitive, if it exists. + */ +#define R200_NEWPRIM( rmesa ) \ +do { \ + if ( rmesa->dma.flush ) \ + rmesa->dma.flush( rmesa ); \ +} while (0) + +/* Can accomodate several state changes and primitive changes without + * actually firing the buffer. + */ +#define R200_STATECHANGE( rmesa, ATOM ) \ +do { \ + R200_NEWPRIM( rmesa ); \ + move_to_head( &(rmesa->hw.dirty), &(rmesa->hw.ATOM)); \ +} while (0) + +#define R200_DB_STATE( ATOM ) \ + memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \ + rmesa->hw.ATOM.cmd_size * 4) + +static __inline int R200_DB_STATECHANGE( + r200ContextPtr rmesa, + struct r200_state_atom *atom ) +{ + if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size*4)) { + int *tmp; + R200_NEWPRIM( rmesa ); + move_to_head( &(rmesa->hw.dirty), atom ); + tmp = atom->cmd; + atom->cmd = atom->lastcmd; + atom->lastcmd = tmp; + return 1; + } + else + return 0; +} + + +/* Fire the buffered vertices no matter what. + */ +#define R200_FIREVERTICES( rmesa ) \ +do { \ + if ( rmesa->store.cmd_used || rmesa->dma.flush ) { \ + r200Flush( rmesa->glCtx ); \ + } \ +} while (0) + +/* Alloc space in the command buffer + */ +static __inline char *r200AllocCmdBuf( r200ContextPtr rmesa, + int bytes, const char *where ) +{ + if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) + r200FlushCmdBuf( rmesa, __FUNCTION__ ); + + { + char *head = rmesa->store.cmd_buf + rmesa->store.cmd_used; + rmesa->store.cmd_used += bytes; + return head; + } +} + + + + +#endif +#endif /* __R200_IOCTL_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_lock.c b/xc/lib/GL/mesa/src/drv/r200/r200_lock.c new file mode 100644 index 000000000..bc433ffac --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_lock.c @@ -0,0 +1,108 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_lock.c,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_lock.h" +#include "r200_tex.h" +#include "r200_state.h" +#include "r200_ioctl.h" + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#endif + +/* Turn on/off page flipping according to the flags in the sarea: + */ +static void +r200UpdatePageFlipping( r200ContextPtr rmesa ) +{ + int use_back; + rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip; + + use_back = (rmesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT); + use_back ^= (rmesa->sarea->pfCurrentPage == 1); + + if (use_back) { + rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch; + } else { + rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch; + } + + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset; + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; +} + + + +/* Update the hardware state. This is called if another context has + * grabbed the hardware lock, which includes the X server. This + * function also updates the driver's window state after the X server + * moves, resizes or restacks a window -- the change will be reflected + * in the drawable position and clip rects. Since the X server grabs + * the hardware lock when it changes the window state, this routine will + * automatically be called after such a change. + */ +void r200GetLock( r200ContextPtr rmesa, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + __DRIscreenPrivate *sPriv = rmesa->dri.screen; + RADEONSAREAPrivPtr sarea = rmesa->sarea; + + drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags ); + + /* The window might have moved, so we might need to get new clip + * rects. + * + * NOTE: This releases and regrabs the hw lock to allow the X server + * to respond to the DRI protocol request for new drawable info. + * Since the hardware state depends on having the latest drawable + * clip rects, all state checking must be done _after_ this call. + */ + DRI_VALIDATE_DRAWABLE_INFO( rmesa->dri.display, sPriv, dPriv ); + + if ( rmesa->lastStamp != dPriv->lastStamp ) { + r200UpdatePageFlipping( rmesa ); + r200SetCliprects( rmesa, rmesa->glCtx->Color.DriverDrawBuffer ); + r200UpdateViewportOffset( rmesa->glCtx ); + rmesa->lastStamp = dPriv->lastStamp; + } + + if ( sarea->ctxOwner != rmesa->dri.hwContext ) { + sarea->ctxOwner = rmesa->dri.hwContext; + } +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_lock.h b/xc/lib/GL/mesa/src/drv/r200/r200_lock.h new file mode 100644 index 000000000..cbc8350e4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_lock.h @@ -0,0 +1,111 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_lock.h,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_LOCK_H__ +#define __R200_LOCK_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void r200GetLock( r200ContextPtr rmesa, GLuint flags ); + +/* Turn DEBUG_LOCKING on to find locking conflicts. + */ +#define DEBUG_LOCKING 0 + +#if DEBUG_LOCKING +extern char *prevLockFile; +extern int prevLockLine; + +#define DEBUG_LOCK() \ + do { \ + prevLockFile = (__FILE__); \ + prevLockLine = (__LINE__); \ + } while (0) + +#define DEBUG_RESET() \ + do { \ + prevLockFile = 0; \ + prevLockLine = 0; \ + } while (0) + +#define DEBUG_CHECK_LOCK() \ + do { \ + if ( prevLockFile ) { \ + fprintf( stderr, \ + "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ + prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ + exit( 1 ); \ + } \ + } while (0) + +#else + +#define DEBUG_LOCK() +#define DEBUG_RESET() +#define DEBUG_CHECK_LOCK() + +#endif + +/* + * !!! We may want to separate locks from locks with validation. This + * could be used to improve performance for those things commands that + * do not do any drawing !!! + */ + + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( rmesa ) \ + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ + DRM_CAS( rmesa->dri.hwLock, rmesa->dri.hwContext, \ + (DRM_LOCK_HELD | rmesa->dri.hwContext), __ret ); \ + if ( __ret ) \ + r200GetLock( rmesa, 0 ); \ + DEBUG_LOCK(); \ + } while (0) + +/* Unlock the hardware. + */ +#define UNLOCK_HARDWARE( rmesa ) \ + do { \ + DRM_UNLOCK( rmesa->dri.fd, \ + rmesa->dri.hwLock, \ + rmesa->dri.hwContext ); \ + DEBUG_RESET(); \ + } while (0) + +#endif +#endif /* __R200_LOCK_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_maos.c b/xc/lib/GL/mesa/src/drv/r200/r200_maos.c new file mode 100644 index 000000000..fd2bd5102 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_maos.c @@ -0,0 +1,12 @@ + + +/* If using new packets, can choose either verts or arrays. + * Otherwise, must use verts. + */ +#include "r200_context.h" +#define R200_MAOS_VERTS 0 +#if (R200_MAOS_VERTS) || (R200_OLD_PACKETS) +#include "r200_maos_verts.c" +#else +#include "r200_maos_arrays.c" +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_maos.h b/xc/lib/GL/mesa/src/drv/r200/r200_maos.h new file mode 100644 index 000000000..e930cb8db --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_maos.h @@ -0,0 +1,46 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_maos.h,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_MAOS_H__ +#define __R200_MAOS_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "r200_context.h" + +extern void r200EmitArrays( GLcontext *ctx, GLuint inputs ); +extern void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c b/xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c new file mode 100644 index 000000000..aa66b7456 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c @@ -0,0 +1,481 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c,v 1.3 2003/02/23 23:59:01 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "mem.h" +#include "mmath.h" +#include "macros.h" + +#include "swrast_setup/swrast_setup.h" +#include "math/m_translate.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_imm_debug.h" + +#include "r200_context.h" +#include "r200_ioctl.h" +#include "r200_state.h" +#include "r200_swtcl.h" +#include "r200_maos.h" + +/* Usage: + * - from r200_tcl_render + * - call r200EmitArrays to ensure uptodate arrays in dma + * - emit primitives (new type?) which reference the data + * -- need to use elts for lineloop, quads, quadstrip/flat + * -- other primitives are all well-formed (need tristrip-1,fake-poly) + * + */ +static void emit_ubyte_rgba3( GLcontext *ctx, + struct r200_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + r200_color_t *out = (r200_color_t *)(rvb->start + rvb->address); + + if (R200_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p\n", + __FUNCTION__, count, stride, out); + + for (i = 0; i < count; i++) { + out->red = *data; + out->green = *(data+1); + out->blue = *(data+2); + out->alpha = 0xFF; + out++; + data += stride; + } +} + + +#if defined(USE_X86_ASM) +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ + : "0" (nr), \ + "D" ((long)dst), \ + "S" ((long)src) ); \ +} while (0) +#else +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int j; \ + for ( j = 0 ; j < nr ; j++ ) \ + dst[j] = ((int *)src)[j]; \ + dst += nr; \ +} while (0) +#endif + + + +static void emit_ubyte_rgba4( GLcontext *ctx, + struct r200_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (R200_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); + + if (stride == 4) { + for (i = 0; i < count; i++) + ((int *)out)[i] = LE32_TO_CPU(((int *)data)[i]); + } else { + for (i = 0; i < count; i++) { + *(int *)out++ = LE32_TO_CPU(*(int *)data); + data += stride; + } + } +} + + +static void emit_ubyte_rgba( GLcontext *ctx, + struct r200_dma_region *rvb, + char *data, + int size, + int stride, + int count ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); + + assert (!rvb->buf); + + if (stride == 0) { + r200AllocDmaRegion( rmesa, rvb, 4, 4 ); + count = 1; + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = 0; + rvb->aos_size = 1; + } + else { + r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */ + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = 1; + rvb->aos_size = 1; + } + + /* Emit the data + */ + switch (size) { + case 3: + emit_ubyte_rgba3( ctx, rvb, data, stride, count ); + break; + case 4: + emit_ubyte_rgba4( ctx, rvb, data, stride, count ); + break; + default: + assert(0); + exit(1); + break; + } +} + + + + +static void emit_vec8( GLcontext *ctx, + struct r200_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (R200_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); + + if (stride == 8) + COPY_DWORDS( out, data, count*2 ); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data+4); + out += 2; + data += stride; + } +} + +static void emit_vec12( GLcontext *ctx, + struct r200_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (R200_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, out, data); + + if (stride == 12) + COPY_DWORDS( out, data, count*3 ); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data+4); + out[2] = *(int *)(data+8); + out += 3; + data += stride; + } +} + +static void emit_vec16( GLcontext *ctx, + struct r200_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (R200_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); + + if (stride == 16) + COPY_DWORDS( out, data, count*4 ); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data+4); + out[2] = *(int *)(data+8); + out[3] = *(int *)(data+12); + out += 4; + data += stride; + } +} + + +static void emit_vector( GLcontext *ctx, + struct r200_dma_region *rvb, + char *data, + int size, + int stride, + int count ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d size %d stride %d\n", + __FUNCTION__, count, size, stride); + + assert (!rvb->buf); + + if (stride == 0) { + r200AllocDmaRegion( rmesa, rvb, size * 4, 4 ); + count = 1; + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = 0; + rvb->aos_size = size; + } + else { + r200AllocDmaRegion( rmesa, rvb, size * count * 4, 4 ); /* alignment? */ + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = size; + rvb->aos_size = size; + } + + /* Emit the data + */ + switch (size) { + case 2: + emit_vec8( ctx, rvb, data, stride, count ); + break; + case 3: + emit_vec12( ctx, rvb, data, stride, count ); + break; + case 4: + emit_vec16( ctx, rvb, data, stride, count ); + break; + default: + assert(0); + exit(1); + break; + } + +} + + + +/* Emit any changed arrays to new agp memory, re-emit a packet to + * update the arrays. + */ +void r200EmitArrays( GLcontext *ctx, GLuint inputs ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; + struct r200_dma_region **component = rmesa->tcl.aos_components; + GLuint nr = 0; + GLuint vfmt0 = 0, vfmt1 = 0; + GLuint count = VB->Count; + + if (R200_DEBUG & DEBUG_VERTS) + _tnl_print_vert_flags( __FUNCTION__, inputs ); + + if (1) { + if (!rmesa->tcl.obj.buf) + emit_vector( ctx, + &rmesa->tcl.obj, + (char *)VB->ObjPtr->data, + VB->ObjPtr->size, + VB->ObjPtr->stride, + count); + + switch( VB->ObjPtr->size ) { + case 4: vfmt0 |= R200_VTX_W0; + case 3: vfmt0 |= R200_VTX_Z0; + case 2: + default: + break; + } + component[nr++] = &rmesa->tcl.obj; + } + + + if (inputs & VERT_NORM) { + if (!rmesa->tcl.norm.buf) + emit_vector( ctx, + &(rmesa->tcl.norm), + (char *)VB->NormalPtr->data, + 3, + VB->NormalPtr->stride, + count); + + vfmt0 |= R200_VTX_N0; + component[nr++] = &rmesa->tcl.norm; + } + + if (inputs & VERT_RGBA) { + if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) { + if (!rmesa->tcl.rgba.buf) + emit_ubyte_rgba( ctx, + &rmesa->tcl.rgba, + (char *)VB->ColorPtr[0]->Ptr, + VB->ColorPtr[0]->Size, + VB->ColorPtr[0]->StrideB, + count); + + vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; + } + else { + int emitsize; + + if (VB->ColorPtr[0]->Size == 4 && + (VB->ColorPtr[0]->StrideB != 0 || + ((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) { + vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; + emitsize = 4; + } + else { + vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT; + emitsize = 3; + } + + if (!rmesa->tcl.rgba.buf) + emit_vector( ctx, + &(rmesa->tcl.rgba), + (char *)VB->ColorPtr[0]->Ptr, + emitsize, + VB->ColorPtr[0]->StrideB, + count); + } + + component[nr++] = &rmesa->tcl.rgba; + } + + + if (inputs & VERT_SPEC_RGB) { + if (!rmesa->tcl.spec.buf) { + if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE) + r200_import_float_spec_colors( ctx ); + + emit_ubyte_rgba( ctx, + &rmesa->tcl.spec, + (char *)VB->SecondaryColorPtr[0]->Ptr, + 3, + VB->SecondaryColorPtr[0]->StrideB, + count); + } + + /* How does this work? + */ + vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT; + component[nr++] = &rmesa->tcl.spec; + } + +/* vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & */ +/* ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1)); */ + + if (inputs & VERT_TEX0) { + if (!rmesa->tcl.tex[0].buf) + emit_vector( ctx, + &(rmesa->tcl.tex[0]), + (char *)VB->TexCoordPtr[0]->data, + VB->TexCoordPtr[0]->size, + VB->TexCoordPtr[0]->stride, + count ); + + vfmt1 |= VB->TexCoordPtr[0]->size << R200_VTX_TEX0_COMP_CNT_SHIFT; + component[nr++] = &rmesa->tcl.tex[0]; + } + + if (inputs & VERT_TEX1) { + if (!rmesa->tcl.tex[1].buf) + emit_vector( ctx, + &(rmesa->tcl.tex[1]), + (char *)VB->TexCoordPtr[1]->data, + VB->TexCoordPtr[1]->size, + VB->TexCoordPtr[1]->stride, + count ); + + vfmt1 |= VB->TexCoordPtr[1]->size << R200_VTX_TEX1_COMP_CNT_SHIFT; + component[nr++] = &rmesa->tcl.tex[1]; + } + + if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || + vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { + R200_STATECHANGE( rmesa, vtx ); + rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0; + rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1; + } + + +/* fprintf(stderr, "VTXFMT_0: %x VTXFMT_1: %x\n", vfmt0, vfmt1); */ + + rmesa->tcl.nr_aos_components = nr; + rmesa->tcl.vertex_format = vfmt0; +} + + +void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + if (R200_DEBUG & DEBUG_VERTS) + _tnl_print_vert_flags( __FUNCTION__, newinputs ); + + if (newinputs & VERT_OBJ) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); + + if (newinputs & VERT_NORM) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); + + if (newinputs & VERT_RGBA) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ ); + + if (newinputs & VERT_SPEC_RGB) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ ); + + if (newinputs & VERT_TEX0) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ ); + + if (newinputs & VERT_TEX1) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ ); +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_maos_vbtmp.h b/xc/lib/GL/mesa/src/drv/r200/r200_maos_vbtmp.h new file mode 100644 index 000000000..ce258d798 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_maos_vbtmp.h @@ -0,0 +1,378 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_maos_vbtmp.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef LOCALVARS +#define LOCALVARS +#endif + +#undef TCL_DEBUG +#ifndef TCL_DEBUG +#define TCL_DEBUG 0 +#endif + +static void TAG(emit)( GLcontext *ctx, + GLuint start, GLuint end, + void *dest ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint (*tc0)[4], (*tc1)[4]; + GLfloat *fog; + GLuint (*tc2)[4], (*norm)[3]; + GLubyte (*col)[4], (*spec)[4]; + GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride; + GLuint tc2_stride, norm_stride; + GLuint (*coord)[4]; + GLuint coord_stride; + GLubyte dummy[4]; + int i; + + union emit_union *v = (union emit_union *)dest; + + + if (R200_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* The vertex code expects Obj to be clean to element 3. To fix + * this, add more vertex code (for obj-2, obj-3) or preferably move + * to maos. + */ + if (VB->ObjPtr->size < 3) { + if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 2 ); + } + + if (DO_W && VB->ObjPtr->size < 4) { + if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 3 ); + } + + coord = (GLuint (*)[4])VB->ObjPtr->data; + coord_stride = VB->ObjPtr->stride; + + if (DO_TEX2) { + const GLuint t2 = GET_TEXSOURCE(2); + tc2 = (GLuint (*)[4])VB->TexCoordPtr[t2]->data; + tc2_stride = VB->TexCoordPtr[t2]->stride; + if (DO_PTEX && VB->TexCoordPtr[t2]->size < 4) { + if (VB->TexCoordPtr[t2]->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_TEX2, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->TexCoordPtr[t2], VB->Count, 3 ); + } + } + + if (DO_TEX1) { + if (VB->TexCoordPtr[1]) { + const GLuint t1 = GET_TEXSOURCE(1); + tc1 = (GLuint (*)[4])VB->TexCoordPtr[t1]->data; + tc1_stride = VB->TexCoordPtr[t1]->stride; + if (DO_PTEX && VB->TexCoordPtr[t1]->size < 4) { + if (VB->TexCoordPtr[t1]->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_TEX1, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->TexCoordPtr[t1], VB->Count, 3 ); + } + } else { + tc1 = (GLuint (*)[4])&ctx->Current.Texcoord[1]; /* could be anything, really */ + tc1_stride = 0; + } + } + + if (DO_TEX0) { + if (VB->TexCoordPtr[0]) { + const GLuint t0 = GET_TEXSOURCE(0); + tc0_stride = VB->TexCoordPtr[t0]->stride; + tc0 = (GLuint (*)[4])VB->TexCoordPtr[t0]->data; + if (DO_PTEX && VB->TexCoordPtr[t0]->size < 4) { + if (VB->TexCoordPtr[t0]->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_TEX0, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->TexCoordPtr[t0], VB->Count, 3 ); + } + } else { + tc0 = (GLuint (*)[4])&ctx->Current.Texcoord[0]; /* could be anything, really */ + tc0_stride = 0; + } + + } + + if (DO_NORM) { + if (VB->NormalPtr) { + norm_stride = VB->NormalPtr->stride; + norm = (GLuint (*)[3])VB->NormalPtr->data; + } else { + norm_stride = 0; + norm = (GLuint (*)[3])&ctx->Current.Normal; + } + } + + if (DO_RGBA) { + if (VB->ColorPtr[0]) { + /* This is incorrect when colormaterial is enabled: + */ + if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) { + if (0) fprintf(stderr, "IMPORTING FLOAT COLORS\n"); + IMPORT_FLOAT_COLORS( ctx ); + } + col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr; + col_stride = VB->ColorPtr[0]->StrideB; + } else { + col = &dummy; /* any old memory is fine */ + col_stride = 0; + } + + } + + if (DO_SPEC) { + if (VB->SecondaryColorPtr[0]) { + if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE) + IMPORT_FLOAT_SPEC_COLORS( ctx ); + spec = (GLubyte (*)[4])VB->SecondaryColorPtr[0]->Ptr; + spec_stride = VB->SecondaryColorPtr[0]->StrideB; + } else { + spec = &dummy; + spec_stride = 0; + } + + } + + if (DO_FOG) { + if (VB->FogCoordPtr) { + fog = VB->FogCoordPtr->data; + fog_stride = VB->FogCoordPtr->stride; + } else { + fog = (GLfloat *)&dummy; *fog = 0; + fog_stride = 0; + } + + } + + + if (VB->importable_data) { + if (start) { + coord = (GLuint (*)[4])((GLubyte *)coord + start * coord_stride); + if (DO_TEX0) + tc0 = (GLuint (*)[4])((GLubyte *)tc0 + start * tc0_stride); + if (DO_TEX1) + tc1 = (GLuint (*)[4])((GLubyte *)tc1 + start * tc1_stride); + if (DO_TEX2) + tc2 = (GLuint (*)[4])((GLubyte *)tc2 + start * tc2_stride); + if (DO_NORM) + norm = (GLuint (*)[3])((GLubyte *)norm + start * norm_stride); + if (DO_RGBA) + STRIDE_4UB(col, start * col_stride); + if (DO_SPEC) + STRIDE_4UB(spec, start * spec_stride); + if (DO_FOG) + STRIDE_F(fog, start * fog_stride); + } + + for (i=start; i < end; i++) { + v[0].ui = coord[0][0]; + v[1].ui = coord[0][1]; + v[2].ui = coord[0][2]; + if (TCL_DEBUG) fprintf(stderr, "%d: %.2f %.2f %.2f ", i, v[0].f, v[1].f, v[2].f); + if (DO_W) { + v[3].ui = coord[0][3]; + if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[3].f); + v += 4; + } + else + v += 3; + coord = (GLuint (*)[4])((GLubyte *)coord + coord_stride); + + if (DO_NORM) { + v[0].ui = norm[0][0]; + v[1].ui = norm[0][1]; + v[2].ui = norm[0][2]; + if (TCL_DEBUG) fprintf(stderr, "norm: %.2f %.2f %.2f ", v[0].f, v[1].f, v[2].f); + v += 3; + norm = (GLuint (*)[3])((GLubyte *)norm + norm_stride); + } + if (DO_RGBA) { + v[0].ui = LE32_TO_CPU(*(GLuint *)&col[0]); + STRIDE_4UB(col, col_stride); + if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui); + v++; + } + if (DO_SPEC || DO_FOG) { + if (DO_SPEC) { + v[0].ub[0] = spec[0][0]; + v[0].ub[1] = spec[0][1]; + v[0].ub[2] = spec[0][2]; + STRIDE_4UB(spec, spec_stride); + } + if (DO_FOG) { + v[0].ub[3] = fog[0] * 255.0; + STRIDE_F(fog, fog_stride); + } + if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui); + v++; + } + if (DO_TEX0) { + v[0].ui = tc0[0][0]; + v[1].ui = tc0[0][1]; + if (TCL_DEBUG) fprintf(stderr, "t0: %.2f %.2f ", v[0].f, v[1].f); + if (DO_PTEX) { + v[2].ui = tc0[0][3]; + if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f); + v += 3; + } + else + v += 2; + tc0 = (GLuint (*)[4])((GLubyte *)tc0 + tc0_stride); + } + if (DO_TEX1) { + v[0].ui = tc1[0][0]; + v[1].ui = tc1[0][1]; + if (TCL_DEBUG) fprintf(stderr, "t1: %.2f %.2f ", v[0].f, v[1].f); + if (DO_PTEX) { + v[2].ui = tc1[0][3]; + if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f); + v += 3; + } + else + v += 2; + tc1 = (GLuint (*)[4])((GLubyte *)tc1 + tc1_stride); + } + if (DO_TEX2) { + v[0].ui = tc2[0][0]; + v[1].ui = tc2[0][1]; + if (DO_PTEX) { + v[2].ui = tc2[0][3]; + v += 3; + } + else + v += 2; + tc2 = (GLuint (*)[4])((GLubyte *)tc2 + tc2_stride); + } + if (TCL_DEBUG) fprintf(stderr, "\n"); + } + } else { + for (i=start; i < end; i++) { + v[0].ui = coord[i][0]; + v[1].ui = coord[i][1]; + v[2].ui = coord[i][2]; + if (DO_W) { + v[3].ui = coord[i][3]; + v += 4; + } + else + v += 3; + + if (DO_NORM) { + v[0].ui = norm[i][0]; + v[1].ui = norm[i][1]; + v[2].ui = norm[i][2]; + v += 3; + } + if (DO_RGBA) { + v[0].ui = LE32_TO_CPU(*(GLuint *)&col[i]); + v++; + } + if (DO_SPEC || DO_FOG) { + if (DO_SPEC) { + v[0].ub[0] = spec[i][0]; + v[0].ub[1] = spec[i][1]; + v[0].ub[2] = spec[i][2]; + } + if (DO_FOG) { + v[0].ub[3] = fog[i] * 255.0; + } + v++; + } + if (DO_TEX0) { + v[0].ui = tc0[i][0]; + v[1].ui = tc0[i][1]; + if (DO_PTEX) { + v[2].ui = tc0[i][3]; + v += 3; + } + else + v += 2; + } + if (DO_TEX1) { + v[0].ui = tc1[i][0]; + v[1].ui = tc1[i][1]; + if (DO_PTEX) { + v[2].ui = tc1[i][3]; + v += 3; + } + else + v += 2; + } + if (DO_TEX2) { + v[0].ui = tc2[i][0]; + v[1].ui = tc2[i][1]; + if (DO_PTEX) { + v[2].ui = tc2[i][3]; + v += 3; + } + else + v += 2; + } + } + } +} + + + +static void TAG(init)( void ) +{ + int sz = 3; + if (DO_W) sz++; + if (DO_NORM) sz += 3; + if (DO_RGBA) sz++; + if (DO_SPEC || DO_FOG) sz++; + if (DO_TEX0) sz += 2; + if (DO_TEX0 && DO_PTEX) sz++; + if (DO_TEX1) sz += 2; + if (DO_TEX1 && DO_PTEX) sz++; + if (DO_TEX2) sz += 2; + if (DO_TEX2 && DO_PTEX) sz++; + + setup_tab[IDX].emit = TAG(emit); + setup_tab[IDX].vertex_format = IND; + setup_tab[IDX].vertex_size = sz; +} + + +#undef IND +#undef TAG +#undef IDX diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_maos_verts.c b/xc/lib/GL/mesa/src/drv/r200/r200_maos_verts.c new file mode 100644 index 000000000..7bc73b7a1 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_maos_verts.c @@ -0,0 +1,335 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_maos_verts.c,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_state.h" +#include "r200_ioctl.h" +#include "r200_tex.h" +#include "r200_tcl.h" +#include "r200_swtcl.h" +#include "r200_maos.h" + +#include "mmath.h" +#include "mtypes.h" +#include "enums.h" +#include "colormac.h" +#include "light.h" + +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_imm_debug.h" + +#define R200_TCL_MAX_SETUP 13 + +union emit_union { float f; GLuint ui; GLubyte ub[4]; }; + +static struct { + void (*emit)( GLcontext *, GLuint, GLuint, void * ); + GLuint vertex_size; + GLuint vertex_format; +} setup_tab[R200_TCL_MAX_SETUP]; + +#define DO_W (IND & R200_CP_VC_FRMT_W0) +#define DO_RGBA (IND & R200_CP_VC_FRMT_PKCOLOR) +#define DO_SPEC (IND & R200_CP_VC_FRMT_PKSPEC) +#define DO_FOG (IND & R200_CP_VC_FRMT_PKSPEC) +#define DO_TEX0 (IND & R200_CP_VC_FRMT_ST0) +#define DO_TEX1 (IND & R200_CP_VC_FRMT_ST1) +#define DO_PTEX (IND & R200_CP_VC_FRMT_Q0) +#define DO_NORM (IND & R200_CP_VC_FRMT_N0) + +#define DO_TEX2 0 +#define DO_TEX3 0 + +#define GET_TEXSOURCE(n) n +#define GET_UBYTE_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteColor +#define GET_UBYTE_SPEC_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteSecondaryColor + +#define IMPORT_FLOAT_COLORS r200_import_float_colors +#define IMPORT_FLOAT_SPEC_COLORS r200_import_float_spec_colors + +/*********************************************************************** + * Generate vertex emit functions * + ***********************************************************************/ + + +/* Defined in order of increasing vertex size: + */ +#define IDX 0 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_PKCOLOR) +#define TAG(x) x##_rgba +#include "r200_maos_vbtmp.h" + +#define IDX 1 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_N0) +#define TAG(x) x##_n +#include "r200_maos_vbtmp.h" + +#define IDX 2 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_PKCOLOR| \ + R200_CP_VC_FRMT_ST0) +#define TAG(x) x##_rgba_st +#include "r200_maos_vbtmp.h" + +#define IDX 3 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_PKCOLOR| \ + R200_CP_VC_FRMT_N0) +#define TAG(x) x##_rgba_n +#include "r200_maos_vbtmp.h" + +#define IDX 4 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_ST0| \ + R200_CP_VC_FRMT_N0) +#define TAG(x) x##_st_n +#include "r200_maos_vbtmp.h" + +#define IDX 5 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_PKCOLOR| \ + R200_CP_VC_FRMT_ST0| \ + R200_CP_VC_FRMT_ST1) +#define TAG(x) x##_rgba_st_st +#include "r200_maos_vbtmp.h" + +#define IDX 6 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_PKCOLOR| \ + R200_CP_VC_FRMT_ST0| \ + R200_CP_VC_FRMT_N0) +#define TAG(x) x##_rgba_st_n +#include "r200_maos_vbtmp.h" + +#define IDX 7 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_PKCOLOR| \ + R200_CP_VC_FRMT_PKSPEC| \ + R200_CP_VC_FRMT_ST0| \ + R200_CP_VC_FRMT_ST1) +#define TAG(x) x##_rgba_spec_st_st +#include "r200_maos_vbtmp.h" + +#define IDX 8 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_ST0| \ + R200_CP_VC_FRMT_ST1| \ + R200_CP_VC_FRMT_N0) +#define TAG(x) x##_st_st_n +#include "r200_maos_vbtmp.h" + +#define IDX 9 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_PKCOLOR| \ + R200_CP_VC_FRMT_PKSPEC| \ + R200_CP_VC_FRMT_ST0| \ + R200_CP_VC_FRMT_ST1| \ + R200_CP_VC_FRMT_N0) +#define TAG(x) x##_rgpa_spec_st_st_n +#include "r200_maos_vbtmp.h" + +#define IDX 10 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_PKCOLOR| \ + R200_CP_VC_FRMT_ST0| \ + R200_CP_VC_FRMT_Q0) +#define TAG(x) x##_rgba_stq +#include "r200_maos_vbtmp.h" + +#define IDX 11 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_PKCOLOR| \ + R200_CP_VC_FRMT_ST1| \ + R200_CP_VC_FRMT_Q1| \ + R200_CP_VC_FRMT_ST0| \ + R200_CP_VC_FRMT_Q0) +#define TAG(x) x##_rgba_stq_stq +#include "r200_maos_vbtmp.h" + +#define IDX 12 +#define IND (R200_CP_VC_FRMT_XY| \ + R200_CP_VC_FRMT_Z| \ + R200_CP_VC_FRMT_W0| \ + R200_CP_VC_FRMT_PKCOLOR| \ + R200_CP_VC_FRMT_PKSPEC| \ + R200_CP_VC_FRMT_ST0| \ + R200_CP_VC_FRMT_Q0| \ + R200_CP_VC_FRMT_ST1| \ + R200_CP_VC_FRMT_Q1| \ + R200_CP_VC_FRMT_N0) +#define TAG(x) x##_w_rgpa_spec_stq_stq_n +#include "r200_maos_vbtmp.h" + + + + + +/*********************************************************************** + * Initialization + ***********************************************************************/ + + +static void init_tcl_verts( void ) +{ + init_rgba(); + init_n(); + init_rgba_n(); + init_rgba_st(); + init_st_n(); + init_rgba_st_st(); + init_rgba_st_n(); + init_rgba_spec_st_st(); + init_st_st_n(); + init_rgpa_spec_st_st_n(); + init_rgba_stq(); + init_rgba_stq_stq(); + init_w_rgpa_spec_stq_stq_n(); +} + + +void r200EmitArrays( GLcontext *ctx, GLuint inputs ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint req = 0; + GLuint vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & + ~(R200_TCL_VTX_Q0|R200_TCL_VTX_Q1)); + int i; + static int firsttime = 1; + + if (firsttime) { + init_tcl_verts(); + firsttime = 0; + } + + if (1) { + req |= R200_CP_VC_FRMT_Z; + if (VB->ObjPtr->size == 4) { + req |= R200_CP_VC_FRMT_W0; + } + } + + if (inputs & VERT_NORM) { + req |= R200_CP_VC_FRMT_N0; + } + + if (inputs & VERT_RGBA) { + req |= R200_CP_VC_FRMT_PKCOLOR; + } + + if (inputs & VERT_SPEC_RGB) { + req |= R200_CP_VC_FRMT_PKSPEC; + } + + if (inputs & VERT_TEX0) { + req |= R200_CP_VC_FRMT_ST0; + + if (VB->TexCoordPtr[0]->size == 4) { + req |= R200_CP_VC_FRMT_Q0; + vtx |= R200_TCL_VTX_Q0; + } + } + + if (inputs & VERT_TEX1) { + req |= R200_CP_VC_FRMT_ST1; + + if (VB->TexCoordPtr[1]->size == 4) { + req |= R200_CP_VC_FRMT_Q1; + vtx |= R200_TCL_VTX_Q1; + } + } + + if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) { + R200_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx; + } + + for (i = 0 ; i < R200_TCL_MAX_SETUP ; i++) + if ((setup_tab[i].vertex_format & req) == req) + break; + + if (rmesa->tcl.vertex_format == setup_tab[i].vertex_format && + rmesa->tcl.indexed_verts.buf) + return; + + if (rmesa->tcl.indexed_verts.buf) + r200ReleaseArrays( ctx, ~0 ); + + r200AllocDmaRegionVerts( rmesa, + &rmesa->tcl.indexed_verts, + VB->Count, + setup_tab[i].vertex_size * 4, + 4); + + setup_tab[i].emit( ctx, 0, VB->Count, + rmesa->tcl.indexed_verts.address + + rmesa->tcl.indexed_verts.start ); + + rmesa->tcl.vertex_format = setup_tab[i].vertex_format; + rmesa->tcl.indexed_verts.aos_start = GET_START( &rmesa->tcl.indexed_verts ); + rmesa->tcl.indexed_verts.aos_size = setup_tab[i].vertex_size; + rmesa->tcl.indexed_verts.aos_stride = setup_tab[i].vertex_size; + + rmesa->tcl.aos_components[0] = &rmesa->tcl.indexed_verts; + rmesa->tcl.nr_aos_components = 1; +} + + + +void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + if (R200_DEBUG & DEBUG_VERTS) + _tnl_print_vert_flags( __FUNCTION__, newinputs ); + + if (newinputs) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.indexed_verts, __FUNCTION__ ); +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_pixel.c b/xc/lib/GL/mesa/src/drv/r200/r200_pixel.c new file mode 100644 index 000000000..bf417c5e8 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_pixel.c @@ -0,0 +1,496 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_pixel.c,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "texutil.h" +#include "r200_context.h" +#include "r200_ioctl.h" +#include "r200_pixel.h" +#include "r200_swtcl.h" + +#include "xf86drm.h" +#include "swrast/swrast.h" + + + + + +static GLboolean +check_color( const GLcontext *ctx, GLenum type, GLenum format, + const struct gl_pixelstore_attrib *packing, + const void *pixels, GLint sz, GLint pitch ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint cpp = rmesa->r200Screen->cpp; + + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if ( (pitch & 63) || + ctx->_ImageTransferState || + packing->SwapBytes || + packing->LsbFirst) { + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: failed 1\n", __FUNCTION__); + return GL_FALSE; + } + + if ( type == GL_UNSIGNED_INT_8_8_8_8_REV && + cpp == 4 && + format == GL_BGRA ) { + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: passed 2\n", __FUNCTION__); + return GL_TRUE; + } + + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: failed\n", __FUNCTION__); + + return GL_FALSE; +} + +static GLboolean +check_color_per_fragment_ops( const GLcontext *ctx ) +{ + int result; + result = (!( ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Scissor.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || + ctx->Color.ColorLogicOpEnabled || + ctx->Texture._ReallyEnabled || + ctx->Depth.OcclusionTest + ) && + ctx->Current.RasterPosValid); + + return result; +} + + + +static GLboolean +clip_pixelrect( const GLcontext *ctx, + const GLframebuffer *buffer, + GLint *x, GLint *y, + GLsizei *width, GLsizei *height, + GLint *size ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + /* left clipping */ + if (*x < buffer->_Xmin) { + *width -= (buffer->_Xmin - *x); + *x = buffer->_Xmin; + } + + /* right clipping */ + if (*x + *width > buffer->_Xmax) + *width -= (*x + *width - buffer->_Xmax - 1); + + if (*width <= 0) + return GL_FALSE; + + /* bottom clipping */ + if (*y < buffer->_Ymin) { + *height -= (buffer->_Ymin - *y); + *y = buffer->_Ymin; + } + + /* top clipping */ + if (*y + *height > buffer->_Ymax) + *height -= (*y + *height - buffer->_Ymax - 1); + + if (*height <= 0) + return GL_FALSE; + + *size = ((*y + *height - 1) * rmesa->r200Screen->frontPitch + + (*x + *width - 1) * rmesa->r200Screen->cpp); + + return GL_TRUE; +} + +static GLboolean +r200TryReadPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *pixels ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLint size; + GLint pitch = pack->RowLength ? pack->RowLength : width; + GLint blit_format; + + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* Only accelerate reading to agp buffers. + */ + if ( !r200IsAgpMemory(rmesa, pixels, + pitch * height * rmesa->r200Screen->cpp ) ) { + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: dest not agp\n", __FUNCTION__); + return GL_FALSE; + } + + /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from + * blitter: + */ + if (!pack->Invert) { + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__); + return GL_FALSE; + } + + if (!check_color(ctx, type, format, pack, pixels, size, pitch)) + return GL_FALSE; + + switch ( rmesa->r200Screen->cpp ) { + case 4: + blit_format = R200_CP_COLOR_FORMAT_ARGB8888; + break; + default: + return GL_FALSE; + } + + + /* Although the blits go on the command buffer, need to do this and + * fire with lock held to guarentee cliprects and drawOffset are + * correct. + * + * This is an unusual situation however, as the code which flushes + * a full command buffer expects to be called unlocked. As a + * workaround, immediately flush the buffer on aquiring the lock. + */ + LOCK_HARDWARE( rmesa ); + + if (rmesa->store.cmd_used) + r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); + + if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height, + &size)) { + UNLOCK_HARDWARE( rmesa ); + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s totally clipped -- nothing to do\n", + __FUNCTION__); + return GL_TRUE; + } + + { + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + int nbox = dPriv->numClipRects; + int src_offset = rmesa->state.color.drawOffset; + int src_pitch = rmesa->state.color.drawPitch * rmesa->r200Screen->cpp; + int dst_offset = r200AgpOffsetFromVirtual( rmesa, pixels); + int dst_pitch = pitch * rmesa->r200Screen->cpp; + XF86DRIClipRectRec *box = dPriv->pClipRects; + int i; + + r200EmitWait( rmesa, RADEON_WAIT_3D ); + + y = dPriv->h - y - height; + x += dPriv->x; + y += dPriv->y; + + + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n", + src_pitch, dst_pitch); + + for (i = 0 ; i < nbox ; i++) + { + GLint bx = box[i].x1; + GLint by = box[i].y1; + GLint bw = box[i].x2 - bx; + GLint bh = box[i].y2 - by; + + if (bx < x) bw -= x - bx, bx = x; + if (by < y) bh -= y - by, by = y; + if (bx + bw > x + width) bw = x + width - bx; + if (by + bh > y + height) bh = y + height - by; + if (bw <= 0) continue; + if (bh <= 0) continue; + + r200EmitBlit( rmesa, + blit_format, + src_pitch, src_offset, + dst_pitch, dst_offset, + bx, by, + bx - x, by - y, + bw, bh ); + } + + r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); + } + UNLOCK_HARDWARE( rmesa ); + + r200Finish( ctx ); /* required by GL */ + + return GL_TRUE; +} + +static void +r200ReadPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *pixels ) +{ + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (!r200TryReadPixels( ctx, x, y, width, height, format, type, pack, + pixels)) + _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, + pixels); +} + + + + +static void do_draw_pix( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint pitch, + const void *pixels, + GLuint dest, GLuint planemask) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + XF86DRIClipRectPtr box = dPriv->pClipRects; + int nbox = dPriv->numClipRects; + int i; + int blit_format; + int size; + int src_offset = r200AgpOffsetFromVirtual( rmesa, pixels); + int src_pitch = pitch * rmesa->r200Screen->cpp; + + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + switch ( rmesa->r200Screen->cpp ) { + case 2: + blit_format = R200_CP_COLOR_FORMAT_RGB565; + break; + case 4: + blit_format = R200_CP_COLOR_FORMAT_ARGB8888; + break; + default: + return; + } + + + LOCK_HARDWARE( rmesa ); + + if (rmesa->store.cmd_used) + r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); + + y -= height; /* cope with pixel zoom */ + + if (!clip_pixelrect(ctx, ctx->DrawBuffer, + &x, &y, &width, &height, + &size)) { + UNLOCK_HARDWARE( rmesa ); + return; + } + + y = dPriv->h - y - height; /* convert from gl to hardware coords */ + x += dPriv->x; + y += dPriv->y; + + + r200EmitWait( rmesa, RADEON_WAIT_3D ); + + for (i = 0 ; i < nbox ; i++ ) + { + GLint bx = box[i].x1; + GLint by = box[i].y1; + GLint bw = box[i].x2 - bx; + GLint bh = box[i].y2 - by; + + if (bx < x) bw -= x - bx, bx = x; + if (by < y) bh -= y - by, by = y; + if (bx + bw > x + width) bw = x + width - bx; + if (by + bh > y + height) bh = y + height - by; + if (bw <= 0) continue; + if (bh <= 0) continue; + + r200EmitBlit( rmesa, + blit_format, + src_pitch, src_offset, + rmesa->state.color.drawPitch * rmesa->r200Screen->cpp, + rmesa->state.color.drawOffset, + bx - x, by - y, + bx, by, + bw, bh ); + } + + r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); + r200WaitForIdleLocked( rmesa ); /* required by GL */ + UNLOCK_HARDWARE( rmesa ); +} + + + + +static GLboolean +r200TryDrawPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLint pitch = unpack->RowLength ? unpack->RowLength : width; + GLuint dest, planemask; + GLuint cpp = rmesa->r200Screen->cpp; + GLint size = width * pitch * cpp; + + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + switch (format) { + case GL_RGB: + case GL_RGBA: + case GL_BGRA: + dest = rmesa->state.color.drawOffset; + + planemask = r200PackColor(cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + if (cpp == 2) + planemask |= planemask << 16; + + if (planemask != ~0) + return GL_FALSE; /* fix me -- should be possible */ + + /* Can't do conversions on agp reads/draws. + */ + if ( !r200IsAgpMemory( rmesa, pixels, size ) ) { + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: not agp memory\n", __FUNCTION__); + return GL_FALSE; + } + + if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) { + return GL_FALSE; + } + if (!check_color_per_fragment_ops(ctx)) { + return GL_FALSE; + } + + if (ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != -1.0F) + return GL_FALSE; + break; + + default: + return GL_FALSE; + } + + if ( r200IsAgpMemory(rmesa, pixels, size) ) + { + do_draw_pix( ctx, x, y, width, height, pitch, pixels, + dest, planemask ); + return GL_TRUE; + } + else if (0) + { + /* Pixels is in regular memory -- get dma buffers and perform + * upload through them. + */ + } + else + return GL_FALSE; +} + +static void +r200DrawPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + if (R200_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (!r200TryDrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels )) + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); +} + + +static void +r200Bitmap( GLcontext *ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (rmesa->Fallback) + _swrast_Bitmap( ctx, px, py, width, height, unpack, bitmap ); + else + r200PointsBitmap( ctx, px, py, width, height, unpack, bitmap ); +} + + + +void r200InitPixelFuncs( GLcontext *ctx ) +{ + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + + if (!getenv("R200_NO_BLITS") && R200_CONTEXT(ctx)->dri.drmMinor >= 6) { + ctx->Driver.ReadPixels = r200ReadPixels; + ctx->Driver.DrawPixels = r200DrawPixels; + if (getenv("R200_HW_BITMAP")) + ctx->Driver.Bitmap = r200Bitmap; + } +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_pixel.h b/xc/lib/GL/mesa/src/drv/r200/r200_pixel.h new file mode 100644 index 000000000..9282d2b14 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_pixel.h @@ -0,0 +1,43 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_pixel.h,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_PIXEL_H__ +#define __R200_PIXEL_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void r200InitPixelFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_reg.h b/xc/lib/GL/mesa/src/drv/r200/r200_reg.h new file mode 100644 index 000000000..f161b490a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_reg.h @@ -0,0 +1,1416 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_reg.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. +*/ + +#ifndef _R200_REG_H_ +#define _R200_REG_H_ + +#define R200_PP_MISC 0x1c14 +#define R200_REF_ALPHA_MASK 0x000000ff +#define R200_ALPHA_TEST_FAIL (0 << 8) +#define R200_ALPHA_TEST_LESS (1 << 8) +#define R200_ALPHA_TEST_LEQUAL (2 << 8) +#define R200_ALPHA_TEST_EQUAL (3 << 8) +#define R200_ALPHA_TEST_GEQUAL (4 << 8) +#define R200_ALPHA_TEST_GREATER (5 << 8) +#define R200_ALPHA_TEST_NEQUAL (6 << 8) +#define R200_ALPHA_TEST_PASS (7 << 8) +#define R200_ALPHA_TEST_OP_MASK (7 << 8) +#define R200_CHROMA_FUNC_FAIL (0 << 16) +#define R200_CHROMA_FUNC_PASS (1 << 16) +#define R200_CHROMA_FUNC_NEQUAL (2 << 16) +#define R200_CHROMA_FUNC_EQUAL (3 << 16) +#define R200_CHROMA_KEY_NEAREST (0 << 18) +#define R200_CHROMA_KEY_ZERO (1 << 18) +#define R200_RIGHT_HAND_CUBE_D3D (0 << 24) +#define R200_RIGHT_HAND_CUBE_OGL (1 << 24) +#define R200_PP_FOG_COLOR 0x1c18 +#define R200_FOG_COLOR_MASK 0x00ffffff +#define R200_FOG_VERTEX (0 << 24) +#define R200_FOG_TABLE (1 << 24) +#define R200_FOG_USE_DEPTH (0 << 25) +#define R200_FOG_USE_W (1 << 25) +#define R200_FOG_USE_DIFFUSE_ALPHA (2 << 25) +#define R200_FOG_USE_SPEC_ALPHA (3 << 25) +#define R200_FOG_USE_VTX_FOG (4 << 25) +#define R200_RE_SOLID_COLOR 0x1c1c +#define R200_RB3D_BLENDCNTL 0x1c20 +#define R200_COMB_FCN_MASK (7 << 12) +#define R200_COMB_FCN_ADD_CLAMP (0 << 12) +#define R200_COMB_FCN_ADD_NOCLAMP (1 << 12) +#define R200_COMB_FCN_SUB_CLAMP (2 << 12) +#define R200_COMB_FCN_SUB_NOCLAMP (3 << 12) +#define R200_COMB_FCN_MIN (4 << 12) +#define R200_COMB_FCN_MAX (5 << 12) +#define R200_COMB_FCN_RSUB_CLAMP (6 << 12) +#define R200_COMB_FCN_RSUB_NOCLAMP (7 << 12) +#define R200_SRC_BLEND_GL_ZERO (32 << 16) +#define R200_SRC_BLEND_GL_ONE (33 << 16) +#define R200_SRC_BLEND_GL_SRC_COLOR (34 << 16) +#define R200_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) +#define R200_SRC_BLEND_GL_DST_COLOR (36 << 16) +#define R200_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) +#define R200_SRC_BLEND_GL_SRC_ALPHA (38 << 16) +#define R200_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) +#define R200_SRC_BLEND_GL_DST_ALPHA (40 << 16) +#define R200_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) +#define R200_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) +#define R200_SRC_BLEND_GL_CONST_COLOR (43 << 16) +#define R200_SRC_BLEND_GL_ONE_MINUS_CONST_COLOR (44 << 16) +#define R200_SRC_BLEND_GL_CONST_ALPHA (45 << 16) +#define R200_SRC_BLEND_GL_ONE_MINUS_CONST_ALPHA (46 << 16) +#define R200_SRC_BLEND_MASK (63 << 16) +#define R200_DST_BLEND_GL_ZERO (32 << 24) +#define R200_DST_BLEND_GL_ONE (33 << 24) +#define R200_DST_BLEND_GL_SRC_COLOR (34 << 24) +#define R200_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) +#define R200_DST_BLEND_GL_DST_COLOR (36 << 24) +#define R200_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) +#define R200_DST_BLEND_GL_SRC_ALPHA (38 << 24) +#define R200_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) +#define R200_DST_BLEND_GL_DST_ALPHA (40 << 24) +#define R200_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) +#define R200_DST_BLEND_GL_CONST_COLOR (43 << 24) +#define R200_DST_BLEND_GL_ONE_MINUS_CONST_COLOR (44 << 24) +#define R200_DST_BLEND_GL_CONST_ALPHA (45 << 24) +#define R200_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA (46 << 24) +#define R200_DST_BLEND_MASK (63 << 24) +#define R200_RB3D_DEPTHOFFSET 0x1c24 +#define R200_RB3D_DEPTHPITCH 0x1c28 +#define R200_DEPTHPITCH_MASK 0x00001ff8 +#define R200_DEPTH_ENDIAN_NO_SWAP (0 << 18) +#define R200_DEPTH_ENDIAN_WORD_SWAP (1 << 18) +#define R200_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) +#define R200_RB3D_ZSTENCILCNTL 0x1c2c +#define R200_DEPTH_FORMAT_MASK (0xf << 0) +#define R200_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) +#define R200_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) +#define R200_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) +#define R200_DEPTH_FORMAT_32BIT_INT_Z (4 << 0) +#define R200_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) +#define R200_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) +#define R200_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) +#define R200_Z_TEST_NEVER (0 << 4) +#define R200_Z_TEST_LESS (1 << 4) +#define R200_Z_TEST_LEQUAL (2 << 4) +#define R200_Z_TEST_EQUAL (3 << 4) +#define R200_Z_TEST_GEQUAL (4 << 4) +#define R200_Z_TEST_GREATER (5 << 4) +#define R200_Z_TEST_NEQUAL (6 << 4) +#define R200_Z_TEST_ALWAYS (7 << 4) +#define R200_Z_TEST_MASK (7 << 4) +#define R200_STENCIL_TEST_NEVER (0 << 12) +#define R200_STENCIL_TEST_LESS (1 << 12) +#define R200_STENCIL_TEST_LEQUAL (2 << 12) +#define R200_STENCIL_TEST_EQUAL (3 << 12) +#define R200_STENCIL_TEST_GEQUAL (4 << 12) +#define R200_STENCIL_TEST_GREATER (5 << 12) +#define R200_STENCIL_TEST_NEQUAL (6 << 12) +#define R200_STENCIL_TEST_ALWAYS (7 << 12) +#define R200_STENCIL_TEST_MASK (0x7 << 12) +#define R200_STENCIL_FAIL_KEEP (0 << 16) +#define R200_STENCIL_FAIL_ZERO (1 << 16) +#define R200_STENCIL_FAIL_REPLACE (2 << 16) +#define R200_STENCIL_FAIL_INC (3 << 16) +#define R200_STENCIL_FAIL_DEC (4 << 16) +#define R200_STENCIL_FAIL_INVERT (5 << 16) +#define R200_STENCIL_FAIL_INC_WRAP (6 << 16) +#define R200_STENCIL_FAIL_DEC_WRAP (7 << 16) +#define R200_STENCIL_FAIL_MASK (0x7 << 16) +#define R200_STENCIL_ZPASS_KEEP (0 << 20) +#define R200_STENCIL_ZPASS_ZERO (1 << 20) +#define R200_STENCIL_ZPASS_REPLACE (2 << 20) +#define R200_STENCIL_ZPASS_INC (3 << 20) +#define R200_STENCIL_ZPASS_DEC (4 << 20) +#define R200_STENCIL_ZPASS_INVERT (5 << 20) +#define R200_STENCIL_ZPASS_INC_WRAP (6 << 20) +#define R200_STENCIL_ZPASS_DEC_WRAP (7 << 20) +#define R200_STENCIL_ZPASS_MASK (0x7 << 20) +#define R200_STENCIL_ZFAIL_KEEP (0 << 24) +#define R200_STENCIL_ZFAIL_ZERO (1 << 24) +#define R200_STENCIL_ZFAIL_REPLACE (2 << 24) +#define R200_STENCIL_ZFAIL_INC (3 << 24) +#define R200_STENCIL_ZFAIL_DEC (4 << 24) +#define R200_STENCIL_ZFAIL_INVERT (5 << 24) +#define R200_STENCIL_ZFAIL_INC_WRAP (6 << 24) +#define R200_STENCIL_ZFAIL_DEC_WRAP (7 << 24) +#define R200_STENCIL_ZFAIL_MASK (0x7 << 24) +#define R200_Z_WRITE_ENABLE (1 << 30) +/*gap*/ +#define R200_PP_CNTL 0x1c38 +#define R200_TEX_0_ENABLE 0x00000010 +#define R200_TEX_1_ENABLE 0x00000020 +#define R200_TEX_2_ENABLE 0x00000040 +#define R200_TEX_3_ENABLE 0x00000080 +#define R200_TEX_4_ENABLE 0x00000100 +#define R200_TEX_5_ENABLE 0x00000200 +#define R200_TEX_ENABLE_MASK 0x000003f0 +#define R200_FILTER_ROUND_MODE_MASK 0x00000400 +#define R200_TEX_BLEND_7_ENABLE 0x00000800 +#define R200_TEX_BLEND_0_ENABLE 0x00001000 +#define R200_TEX_BLEND_1_ENABLE 0x00002000 +#define R200_TEX_BLEND_2_ENABLE 0x00004000 +#define R200_TEX_BLEND_3_ENABLE 0x00008000 +#define R200_TEX_BLEND_4_ENABLE 0x00010000 +#define R200_TEX_BLEND_5_ENABLE 0x00020000 +#define R200_TEX_BLEND_6_ENABLE 0x00040000 +#define R200_MULTI_PASS_ENABLE 0x00080000 +#define R200_SPECULAR_ENABLE 0x00200000 +#define R200_FOG_ENABLE 0x00400000 +#define R200_ALPHA_TEST_ENABLE 0x00800000 +#define R200_ANTI_ALIAS_NONE 0x00000000 +#define R200_ANTI_ALIAS_LINE 0x01000000 +#define R200_ANTI_ALIAS_POLY 0x02000000 +#define R200_ANTI_ALIAS_MASK 0x03000000 +#define R200_RB3D_CNTL 0x1c3c +#define R200_ALPHA_BLEND_ENABLE (1 << 0) +#define R200_PLANE_MASK_ENABLE (1 << 1) +#define R200_DITHER_ENABLE (1 << 2) +#define R200_ROUND_ENABLE (1 << 3) +#define R200_SCALE_DITHER_ENABLE (1 << 4) +#define R200_DITHER_INIT (1 << 5) +#define R200_ROP_ENABLE (1 << 6) +#define R200_STENCIL_ENABLE (1 << 7) +#define R200_Z_ENABLE (1 << 8) +#define R200_DEPTH_XZ_OFFEST_ENABLE (1 << 9) +#define R200_COLOR_FORMAT_ARGB1555 (3 << 10) +#define R200_COLOR_FORMAT_RGB565 (4 << 10) +#define R200_COLOR_FORMAT_ARGB8888 (6 << 10) +#define R200_COLOR_FORMAT_RGB332 (7 << 10) +#define R200_COLOR_FORMAT_Y8 (8 << 10) +#define R200_COLOR_FORMAT_RGB8 (9 << 10) +#define R200_COLOR_FORMAT_YUV422_VYUY (11 << 10) +#define R200_COLOR_FORMAT_YUV422_YVYU (12 << 10) +#define R200_COLOR_FORMAT_aYUV444 (14 << 10) +#define R200_COLOR_FORMAT_ARGB4444 (15 << 10) +#define R200_CLRCMP_FLIP_ENABLE (1 << 14) +#define R200_SEPARATE_ALPHA_ENABLE (1 << 16) +#define R200_RB3D_COLOROFFSET 0x1c40 +#define R200_COLOROFFSET_MASK 0xfffffff0 +#define R200_RE_WIDTH_HEIGHT 0x1c44 +#define R200_RE_WIDTH_SHIFT 0 +#define R200_RE_HEIGHT_SHIFT 16 +#define R200_RB3D_COLORPITCH 0x1c48 +#define R200_COLORPITCH_MASK 0x000001ff8 +#define R200_COLOR_ENDIAN_NO_SWAP (0 << 18) +#define R200_COLOR_ENDIAN_WORD_SWAP (1 << 18) +#define R200_COLOR_ENDIAN_DWORD_SWAP (2 << 18) +#define R200_SE_CNTL 0x1c4c +#define R200_FFACE_CULL_CW (0 << 0) +#define R200_FFACE_CULL_CCW (1 << 0) +#define R200_FFACE_CULL_DIR_MASK (1 << 0) +#define R200_BFACE_CULL (0 << 1) +#define R200_BFACE_SOLID (3 << 1) +#define R200_FFACE_CULL (0 << 3) +#define R200_FFACE_SOLID (3 << 3) +#define R200_FFACE_CULL_MASK (3 << 3) +#define R200_FLAT_SHADE_VTX_0 (0 << 6) +#define R200_FLAT_SHADE_VTX_1 (1 << 6) +#define R200_FLAT_SHADE_VTX_2 (2 << 6) +#define R200_FLAT_SHADE_VTX_LAST (3 << 6) +#define R200_DIFFUSE_SHADE_SOLID (0 << 8) +#define R200_DIFFUSE_SHADE_FLAT (1 << 8) +#define R200_DIFFUSE_SHADE_GOURAUD (2 << 8) +#define R200_DIFFUSE_SHADE_MASK (3 << 8) +#define R200_ALPHA_SHADE_SOLID (0 << 10) +#define R200_ALPHA_SHADE_FLAT (1 << 10) +#define R200_ALPHA_SHADE_GOURAUD (2 << 10) +#define R200_ALPHA_SHADE_MASK (3 << 10) +#define R200_SPECULAR_SHADE_SOLID (0 << 12) +#define R200_SPECULAR_SHADE_FLAT (1 << 12) +#define R200_SPECULAR_SHADE_GOURAUD (2 << 12) +#define R200_SPECULAR_SHADE_MASK (3 << 12) +#define R200_FOG_SHADE_SOLID (0 << 14) +#define R200_FOG_SHADE_FLAT (1 << 14) +#define R200_FOG_SHADE_GOURAUD (2 << 14) +#define R200_FOG_SHADE_MASK (3 << 14) +#define R200_ZBIAS_ENABLE_POINT (1 << 16) +#define R200_ZBIAS_ENABLE_LINE (1 << 17) +#define R200_ZBIAS_ENABLE_TRI (1 << 18) +#define R200_WIDELINE_ENABLE (1 << 20) +#define R200_VTX_PIX_CENTER_D3D (0 << 27) +#define R200_VTX_PIX_CENTER_OGL (1 << 27) +#define R200_ROUND_MODE_TRUNC (0 << 28) +#define R200_ROUND_MODE_ROUND (1 << 28) +#define R200_ROUND_MODE_ROUND_EVEN (2 << 28) +#define R200_ROUND_MODE_ROUND_ODD (3 << 28) +#define R200_ROUND_PREC_16TH_PIX (0 << 30) +#define R200_ROUND_PREC_8TH_PIX (1 << 30) +#define R200_ROUND_PREC_4TH_PIX (2 << 30) +#define R200_ROUND_PREC_HALF_PIX (3 << 30) +#define R200_RE_CNTL 0x1c50 +#define R200_STIPPLE_ENABLE 0x1 +#define R200_SCISSOR_ENABLE 0x2 +#define R200_PATTERN_ENABLE 0x4 +#define R200_PERSPECTIVE_ENABLE 0x8 +#define R200_POINT_SMOOTH 0x20 +#define R200_VTX_STQ0_D3D 0x00010000 +#define R200_VTX_STQ1_D3D 0x00040000 +#define R200_VTX_STQ2_D3D 0x00100000 +#define R200_VTX_STQ3_D3D 0x00400000 +#define R200_VTX_STQ4_D3D 0x01000000 +#define R200_VTX_STQ5_D3D 0x04000000 +/* gap */ +#define R200_RE_STIPPLE_ADDR 0x1cc8 +#define R200_RE_STIPPLE_DATA 0x1ccc +#define R200_RE_LINE_PATTERN 0x1cd0 +#define R200_LINE_PATTERN_MASK 0x0000ffff +#define R200_LINE_REPEAT_COUNT_SHIFT 16 +#define R200_LINE_PATTERN_START_SHIFT 24 +#define R200_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) +#define R200_LINE_PATTERN_BIG_BIT_ORDER (1 << 28) +#define R200_LINE_PATTERN_AUTO_RESET (1 << 29) +#define R200_RE_LINE_STATE 0x1cd4 +#define R200_LINE_CURRENT_PTR_SHIFT 0 +#define R200_LINE_CURRENT_COUNT_SHIFT 8 +#define R200_RE_SCISSOR_TL_0 0x1cd8 +#define R200_RE_SCISSOR_BR_0 0x1cdc +#define R200_RE_SCISSOR_TL_1 0x1ce0 +#define R200_RE_SCISSOR_BR_1 0x1ce4 +#define R200_RE_SCISSOR_TL_2 0x1ce8 +#define R200_RE_SCISSOR_BR_2 0x1cec +/* gap */ +#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 +#define R200_DEPTHX_SHIFT 0 +#define R200_DEPTHY_SHIFT 16 +/* gap */ +#define R200_RB3D_STENCILREFMASK 0x1d7c +#define R200_STENCIL_REF_SHIFT 0 +#define R200_STENCIL_REF_MASK (0xff << 0) +#define R200_STENCIL_MASK_SHIFT 16 +#define R200_STENCIL_VALUE_MASK (0xff << 16) +#define R200_STENCIL_WRITEMASK_SHIFT 24 +#define R200_STENCIL_WRITE_MASK (0xff << 24) +#define R200_RB3D_ROPCNTL 0x1d80 +#define R200_ROP_MASK (15 << 8) +#define R200_ROP_CLEAR (0 << 8) +#define R200_ROP_NOR (1 << 8) +#define R200_ROP_AND_INVERTED (2 << 8) +#define R200_ROP_COPY_INVERTED (3 << 8) +#define R200_ROP_AND_REVERSE (4 << 8) +#define R200_ROP_INVERT (5 << 8) +#define R200_ROP_XOR (6 << 8) +#define R200_ROP_NAND (7 << 8) +#define R200_ROP_AND (8 << 8) +#define R200_ROP_EQUIV (9 << 8) +#define R200_ROP_NOOP (10 << 8) +#define R200_ROP_OR_INVERTED (11 << 8) +#define R200_ROP_COPY (12 << 8) +#define R200_ROP_OR_REVERSE (13 << 8) +#define R200_ROP_OR (14 << 8) +#define R200_ROP_SET (15 << 8) +#define R200_RB3D_PLANEMASK 0x1d84 +/* gap */ +#define R200_SE_VPORT_XSCALE 0x1d98 +#define R200_SE_VPORT_XOFFSET 0x1d9c +#define R200_SE_VPORT_YSCALE 0x1da0 +#define R200_SE_VPORT_YOFFSET 0x1da4 +#define R200_SE_VPORT_ZSCALE 0x1da8 +#define R200_SE_VPORT_ZOFFSET 0x1dac +#define R200_SE_ZBIAS_FACTOR 0x1db0 +#define R200_SE_ZBIAS_CONSTANT 0x1db4 +#define R200_SE_LINE_WIDTH 0x1db8 +#define R200_LINE_WIDTH_SHIFT 0x00000000 +#define R200_MINPOINTSIZE_SHIFT 0x00000010 +/* gap */ +#define R200_SE_VAP_CNTL 0x2080 +#define R200_VAP_TCL_ENABLE 0x00000001 +#define R200_VAP_SINGLE_BUF_STATE_ENABLE 0x00000010 +#define R200_VAP_FORCE_W_TO_ONE 0x00010000 +#define R200_VAP_D3D_TEX_DEFAULT 0x00020000 +#define R200_VAP_VF_MAX_VTX_NUM__SHIFT 18 +#define R200_VAP_DX_CLIP_SPACE_DEF 0x00400000 +#define R200_SE_VF_CNTL 0x2084 +#define R200_VF_PRIM_NONE 0x00000000 +#define R200_VF_PRIM_POINTS 0x00000001 +#define R200_VF_PRIM_LINES 0x00000002 +#define R200_VF_PRIM_LINE_STRIP 0x00000003 +#define R200_VF_PRIM_TRIANGLES 0x00000004 +#define R200_VF_PRIM_TRIANGLE_FAN 0x00000005 +#define R200_VF_PRIM_TRIANGLE_STRIP 0x00000006 +#define R200_VF_PRIM_RECT_LIST 0x00000008 +#define R200_VF_PRIM_3VRT_POINTS 0x00000009 +#define R200_VF_PRIM_3VRT_LINES 0x0000000a +#define R200_VF_PRIM_POINT_SPRITES 0x0000000b +#define R200_VF_PRIM_LINE_LOOP 0x0000000c +#define R200_VF_PRIM_QUADS 0x0000000d +#define R200_VF_PRIM_QUAD_STRIP 0x0000000e +#define R200_VF_PRIM_POLYGON 0x0000000f +#define R200_VF_PRIM_MASK 0x0000000f +#define R200_VF_PRIM_WALK_IND 0x00000010 +#define R200_VF_PRIM_WALK_LIST 0x00000020 +#define R200_VF_PRIM_WALK_RING 0x00000030 +#define R200_VF_PRIM_WALK_MASK 0x00000030 +#define R200_VF_COLOR_ORDER_RGBA 0x00000040 +#define R200_VF_TCL_OUTPUT_VTX_ENABLE 0x00000200 +#define R200_VF_INDEX_SZ_4 0x00000800 +#define R200_VF_VERTEX_NUMBER_MASK 0xffff0000 +#define R200_VF_VERTEX_NUMBER_SHIFT 16 +#define R200_SE_VTX_FMT_0 0x2088 +#define R200_VTX_XY 0 /* always have xy */ +#define R200_VTX_Z0 (1<<0) +#define R200_VTX_W0 (1<<1) +#define R200_VTX_WEIGHT_COUNT_SHIFT (2) +#define R200_VTX_PV_MATRIX_SEL (1<<5) +#define R200_VTX_N0 (1<<6) +#define R200_VTX_POINT_SIZE (1<<7) +#define R200_VTX_DISCRETE_FOG (1<<8) +#define R200_VTX_SHININESS_0 (1<<9) +#define R200_VTX_SHININESS_1 (1<<10) +#define R200_VTX_COLOR_NOT_PRESENT 0 +#define R200_VTX_PK_RGBA 1 +#define R200_VTX_FP_RGB 2 +#define R200_VTX_FP_RGBA 3 +#define R200_VTX_COLOR_MASK 3 +#define R200_VTX_COLOR_0_SHIFT 11 +#define R200_VTX_COLOR_1_SHIFT 13 +#define R200_VTX_COLOR_2_SHIFT 15 +#define R200_VTX_COLOR_3_SHIFT 17 +#define R200_VTX_COLOR_4_SHIFT 19 +#define R200_VTX_COLOR_5_SHIFT 21 +#define R200_VTX_COLOR_6_SHIFT 23 +#define R200_VTX_COLOR_7_SHIFT 25 +#define R200_VTX_XY1 (1<<28) +#define R200_VTX_Z1 (1<<29) +#define R200_VTX_W1 (1<<30) +#define R200_VTX_N1 (1<<31) +#define R200_SE_VTX_FMT_1 0x208c +#define R200_VTX_TEX0_COMP_CNT_SHIFT 0 +#define R200_VTX_TEX1_COMP_CNT_SHIFT 3 +#define R200_VTX_TEX2_COMP_CNT_SHIFT 6 +#define R200_VTX_TEX3_COMP_CNT_SHIFT 9 +#define R200_VTX_TEX4_COMP_CNT_SHIFT 12 +#define R200_VTX_TEX5_COMP_CNT_SHIFT 15 +#define R200_SE_TCL_OUTPUT_VTX_FMT_0 0x2090 +#define R200_SE_TCL_OUTPUT_VTX_FMT_1 0x2094 +/* gap */ +#define R200_SE_VTE_CNTL 0x20b0 +#define R200_VPORT_X_SCALE_ENA 0x00000001 +#define R200_VPORT_X_OFFSET_ENA 0x00000002 +#define R200_VPORT_Y_SCALE_ENA 0x00000004 +#define R200_VPORT_Y_OFFSET_ENA 0x00000008 +#define R200_VPORT_Z_SCALE_ENA 0x00000010 +#define R200_VPORT_Z_OFFSET_ENA 0x00000020 +#define R200_VTX_XY_FMT 0x00000100 +#define R200_VTX_Z_FMT 0x00000200 +#define R200_VTX_W0_FMT 0x00000400 +#define R200_VTX_W0_NORMALIZE 0x00000800 +#define R200_VTX_ST_DENORMALIZED 0x00001000 +/* gap */ +#define R200_SE_VTX_NUM_ARRAYS 0x20c0 +#define R200_SE_VTX_AOS_ATTR01 0x20c4 +#define R200_SE_VTX_AOS_ADDR0 0x20c8 +#define R200_SE_VTX_AOS_ADDR1 0x20cc +#define R200_SE_VTX_AOS_ATTR23 0x20d0 +#define R200_SE_VTX_AOS_ADDR2 0x20d4 +#define R200_SE_VTX_AOS_ADDR3 0x20d8 +#define R200_SE_VTX_AOS_ATTR45 0x20dc +#define R200_SE_VTX_AOS_ADDR4 0x20e0 +#define R200_SE_VTX_AOS_ADDR5 0x20e4 +#define R200_SE_VTX_AOS_ATTR67 0x20e8 +#define R200_SE_VTX_AOS_ADDR6 0x20ec +#define R200_SE_VTX_AOS_ADDR7 0x20f0 +#define R200_SE_VTX_AOS_ATTR89 0x20f4 +#define R200_SE_VTX_AOS_ADDR8 0x20f8 +#define R200_SE_VTX_AOS_ADDR9 0x20fc +#define R200_SE_VTX_AOS_ATTR1011 0x2100 +#define R200_SE_VTX_AOS_ADDR10 0x2104 +#define R200_SE_VTX_AOS_ADDR11 0x2108 +#define R200_SE_VF_MAX_VTX_INDX 0x210c +#define R200_SE_VF_MIN_VTX_INDX 0x2110 +/* gap */ +#define R200_SE_VAP_CNTL_STATUS 0x2140 +#define R200_VC_NO_SWAP (0 << 0) +#define R200_VC_16BIT_SWAP (1 << 0) +#define R200_VC_32BIT_SWAP (2 << 0) +/* gap */ +#define R200_SE_VTX_STATE_CNTL 0x2180 +#define R200_VSC_COLOR_0_ASSEMBLY_CNTL_SHIFT 0x00000000 +#define R200_VSC_COLOR_1_ASSEMBLY_CNTL_SHIFT 0x00000002 +#define R200_VSC_COLOR_2_ASSEMBLY_CNTL_SHIFT 0x00000004 +#define R200_VSC_COLOR_3_ASSEMBLY_CNTL_SHIFT 0x00000006 +#define R200_VSC_COLOR_4_ASSEMBLY_CNTL_SHIFT 0x00000008 +#define R200_VSC_COLOR_5_ASSEMBLY_CNTL_SHIFT 0x0000000a +#define R200_VSC_COLOR_6_ASSEMBLY_CNTL_SHIFT 0x0000000c +#define R200_VSC_COLOR_7_ASSEMBLY_CNTL_SHIFT 0x0000000e +#define R200_VSC_UPDATE_USER_COLOR_0_ENABLE 0x00010000 +#define R200_VSC_UPDATE_USER_COLOR_1_ENABLE 0x00020000 +/* gap */ +#define R200_SE_TCL_VECTOR_INDX_REG 0x2200 +#define R200_SE_TCL_VECTOR_DATA_REG 0x2204 +#define R200_SE_TCL_SCALAR_INDX_REG 0x2208 +#define R200_SE_TCL_SCALAR_DATA_REG 0x220c +/* gap */ +#define R200_SE_TCL_MATRIX_SEL_0 0x2230 +#define R200_MODELVIEW_0_SHIFT (0) +#define R200_MODELVIEW_1_SHIFT (8) +#define R200_MODELVIEW_2_SHIFT (16) +#define R200_MODELVIEW_3_SHIFT (24) +#define R200_SE_TCL_MATRIX_SEL_1 0x2234 +#define R200_IT_MODELVIEW_0_SHIFT (0) +#define R200_IT_MODELVIEW_1_SHIFT (8) +#define R200_IT_MODELVIEW_2_SHIFT (16) +#define R200_IT_MODELVIEW_3_SHIFT (24) +#define R200_SE_TCL_MATRIX_SEL_2 0x2238 +#define R200_MODELPROJECT_0_SHIFT (0) +#define R200_MODELPROJECT_1_SHIFT (8) +#define R200_MODELPROJECT_2_SHIFT (16) +#define R200_MODELPROJECT_3_SHIFT (24) +#define R200_SE_TCL_MATRIX_SEL_3 0x223c +#define R200_TEXMAT_0_SHIFT 0 +#define R200_TEXMAT_1_SHIFT 8 +#define R200_TEXMAT_2_SHIFT 16 +#define R200_TEXMAT_3_SHIFT 24 +#define R200_SE_TCL_MATRIX_SEL_4 0x2240 +#define R200_TEXMAT_4_SHIFT 0 +#define R200_TEXMAT_5_SHIFT 8 +/* gap */ +#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 +#define R200_OUTPUT_XYZW (1<<0) +#define R200_OUTPUT_COLOR_0 (1<<8) +#define R200_OUTPUT_COLOR_1 (1<<9) +#define R200_OUTPUT_TEX_0 (1<<16) +#define R200_OUTPUT_TEX_1 (1<<17) +#define R200_OUTPUT_TEX_2 (1<<18) +#define R200_OUTPUT_TEX_3 (1<<19) +#define R200_OUTPUT_TEX_4 (1<<20) +#define R200_OUTPUT_TEX_5 (1<<21) +#define R200_OUTPUT_TEX_MASK (0x3f<<16) +#define R200_OUTPUT_PT_SIZE (1<<25) +#define R200_FORCE_INORDER_PROC (1<<31) +#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254 +#define R200_VERTEX_POSITION_ADDR__SHIFT 0x00000000 +#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_1 0x2258 +#define R200_VTX_COLOR_0_ADDR__SHIFT 0x00000000 +#define R200_VTX_COLOR_1_ADDR__SHIFT 0x00000008 +#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_2 0x225c +#define R200_VTX_TEX_0_ADDR__SHIFT 0x00000000 +#define R200_VTX_TEX_1_ADDR__SHIFT 0x00000008 +#define R200_VTX_TEX_2_ADDR__SHIFT 0x00000010 +#define R200_VTX_TEX_3_ADDR__SHIFT 0x00000018 +#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_3 0x2260 +#define R200_VTX_TEX_4_ADDR__SHIFT 0x00000000 +#define R200_VTX_TEX_5_ADDR__SHIFT 0x00000008 + +/* gap */ +#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 +#define R200_LIGHTING_ENABLE (1<<0) +#define R200_LIGHT_IN_MODELSPACE (1<<1) +#define R200_LOCAL_VIEWER (1<<2) +#define R200_NORMALIZE_NORMALS (1<<3) +#define R200_RESCALE_NORMALS (1<<4) +#define R200_SPECULAR_LIGHTS (1<<5) +#define R200_DIFFUSE_SPECULAR_COMBINE (1<<6) +#define R200_LIGHT_ALPHA (1<<7) +#define R200_LOCAL_LIGHT_VEC_GL (1<<8) +#define R200_LIGHT_NO_NORMAL_AMBIENT_ONLY (1<<9) +#define R200_LIGHT_TWOSIDE (1<<10) +#define R200_FRONT_SHININESS_SOURCE_SHIFT (0xb) +#define R200_BACK_SHININESS_SOURCE_SHIFT (0xd) +#define R200_LM0_SOURCE_MATERIAL_0 (0) +#define R200_LM0_SOURCE_MATERIAL_1 (1) +#define R200_LM0_SOURCE_VERTEX_SHININESS_0 (2) +#define R200_LM0_SOURCE_VERTEX_SHININESS_1 (3) +#define R200_SE_TCL_LIGHT_MODEL_CTL_1 0x226c +#define R200_LM1_SOURCE_LIGHT_PREMULT (0) +#define R200_LM1_SOURCE_MATERIAL_0 (1) +#define R200_LM1_SOURCE_VERTEX_COLOR_0 (2) +#define R200_LM1_SOURCE_VERTEX_COLOR_1 (3) +#define R200_LM1_SOURCE_VERTEX_COLOR_2 (4) +#define R200_LM1_SOURCE_VERTEX_COLOR_3 (5) +#define R200_LM1_SOURCE_VERTEX_COLOR_4 (6) +#define R200_LM1_SOURCE_VERTEX_COLOR_5 (7) +#define R200_LM1_SOURCE_VERTEX_COLOR_6 (8) +#define R200_LM1_SOURCE_VERTEX_COLOR_7 (9) +#define R200_LM1_SOURCE_MATERIAL_1 (0xf) +#define R200_FRONT_EMISSIVE_SOURCE_SHIFT (0) +#define R200_FRONT_AMBIENT_SOURCE_SHIFT (4) +#define R200_FRONT_DIFFUSE_SOURCE_SHIFT (8) +#define R200_FRONT_SPECULAR_SOURCE_SHIFT (12) +#define R200_BACK_EMISSIVE_SOURCE_SHIFT (16) +#define R200_BACK_AMBIENT_SOURCE_SHIFT (20) +#define R200_BACK_DIFFUSE_SOURCE_SHIFT (24) +#define R200_BACK_SPECULAR_SOURCE_SHIFT (28) +#define R200_SE_TCL_PER_LIGHT_CTL_0 0x2270 +#define R200_LIGHT_0_ENABLE (1<<0) +#define R200_LIGHT_0_ENABLE_AMBIENT (1<<1) +#define R200_LIGHT_0_ENABLE_SPECULAR (1<<2) +#define R200_LIGHT_0_IS_LOCAL (1<<3) +#define R200_LIGHT_0_IS_SPOT (1<<4) +#define R200_LIGHT_0_DUAL_CONE (1<<5) +#define R200_LIGHT_0_ENABLE_RANGE_ATTEN (1<<6) +#define R200_LIGHT_0_CONSTANT_RANGE_ATTEN (1<<7) +#define R200_LIGHT_1_ENABLE (1<<16) +#define R200_LIGHT_1_ENABLE_AMBIENT (1<<17) +#define R200_LIGHT_1_ENABLE_SPECULAR (1<<18) +#define R200_LIGHT_1_IS_LOCAL (1<<19) +#define R200_LIGHT_1_IS_SPOT (1<<20) +#define R200_LIGHT_1_DUAL_CONE (1<<21) +#define R200_LIGHT_1_ENABLE_RANGE_ATTEN (1<<22) +#define R200_LIGHT_1_CONSTANT_RANGE_ATTEN (1<<23) +#define R200_LIGHT_0_SHIFT (0) +#define R200_LIGHT_1_SHIFT (16) +#define R200_SE_TCL_PER_LIGHT_CTL_1 0x2274 +#define R200_LIGHT_2_SHIFT (0) +#define R200_LIGHT_3_SHIFT (16) +#define R200_SE_TCL_PER_LIGHT_CTL_2 0x2278 +#define R200_LIGHT_4_SHIFT (0) +#define R200_LIGHT_5_SHIFT (16) +#define R200_SE_TCL_PER_LIGHT_CTL_3 0x227c +#define R200_LIGHT_6_SHIFT (0) +#define R200_LIGHT_7_SHIFT (16) +/* gap */ +#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 +#define R200_TEXGEN_0_COMP_MASK_SHIFT (0) +#define R200_TEXGEN_1_COMP_MASK_SHIFT (4) +#define R200_TEXGEN_2_COMP_MASK_SHIFT (8) +#define R200_TEXGEN_3_COMP_MASK_SHIFT (12) +#define R200_TEXGEN_4_COMP_MASK_SHIFT (16) +#define R200_TEXGEN_5_COMP_MASK_SHIFT (20) +#define R200_SE_TCL_TEX_PROC_CTL_3 0x22ac +#define R200_TEXGEN_0_INPUT_TEX_SHIFT (0) +#define R200_TEXGEN_1_INPUT_TEX_SHIFT (4) +#define R200_TEXGEN_2_INPUT_TEX_SHIFT (8) +#define R200_TEXGEN_3_INPUT_TEX_SHIFT (12) +#define R200_TEXGEN_4_INPUT_TEX_SHIFT (16) +#define R200_TEXGEN_5_INPUT_TEX_SHIFT (20) +#define R200_SE_TCL_TEX_PROC_CTL_0 0x22b0 +#define R200_TEXGEN_TEXMAT_0_ENABLE (1<<0) +#define R200_TEXGEN_TEXMAT_1_ENABLE (1<<1) +#define R200_TEXGEN_TEXMAT_2_ENABLE (1<<2) +#define R200_TEXGEN_TEXMAT_3_ENABLE (1<<3) +#define R200_TEXGEN_TEXMAT_4_ENABLE (1<<4) +#define R200_TEXGEN_TEXMAT_5_ENABLE (1<<5) +#define R200_TEXMAT_0_ENABLE (1<<8) +#define R200_TEXMAT_1_ENABLE (1<<9) +#define R200_TEXMAT_2_ENABLE (1<<10) +#define R200_TEXMAT_3_ENABLE (1<<11) +#define R200_TEXMAT_4_ENABLE (1<<12) +#define R200_TEXMAT_5_ENABLE (1<<13) +#define R200_TEXGEN_FORCE_W_TO_ONE (1<<16) +#define R200_SE_TCL_TEX_PROC_CTL_1 0x22b4 +#define R200_TEXGEN_INPUT_MASK (0xf) +#define R200_TEXGEN_INPUT_TEXCOORD_0 (0) +#define R200_TEXGEN_INPUT_TEXCOORD_1 (1) +#define R200_TEXGEN_INPUT_TEXCOORD_2 (2) +#define R200_TEXGEN_INPUT_TEXCOORD_3 (3) +#define R200_TEXGEN_INPUT_TEXCOORD_4 (4) +#define R200_TEXGEN_INPUT_TEXCOORD_5 (5) +#define R200_TEXGEN_INPUT_OBJ (8) +#define R200_TEXGEN_INPUT_EYE (9) +#define R200_TEXGEN_INPUT_EYE_NORMAL (0xa) +#define R200_TEXGEN_INPUT_EYE_REFLECT (0xb) +#define R200_TEXGEN_INPUT_SPHERE (0xd) +#define R200_TEXGEN_0_INPUT_SHIFT (0) +#define R200_TEXGEN_1_INPUT_SHIFT (4) +#define R200_TEXGEN_2_INPUT_SHIFT (8) +#define R200_TEXGEN_3_INPUT_SHIFT (12) +#define R200_TEXGEN_4_INPUT_SHIFT (16) +#define R200_TEXGEN_5_INPUT_SHIFT (20) +#define R200_SE_TC_TEX_CYL_WRAP_CTL 0x22b8 +/* gap */ +#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 +#define R200_UCP_IN_CLIP_SPACE (1<<0) +#define R200_UCP_IN_MODEL_SPACE (1<<1) +#define R200_UCP_ENABLE_0 (1<<2) +#define R200_UCP_ENABLE_1 (1<<3) +#define R200_UCP_ENABLE_2 (1<<4) +#define R200_UCP_ENABLE_3 (1<<5) +#define R200_UCP_ENABLE_4 (1<<6) +#define R200_UCP_ENABLE_5 (1<<7) +#define R200_TCL_FOG_MASK (3<<8) +#define R200_TCL_FOG_DISABLE (0<<8) +#define R200_TCL_FOG_EXP (1<<8) +#define R200_TCL_FOG_EXP2 (2<<8) +#define R200_TCL_FOG_LINEAR (3<<8) +#define R200_RNG_BASED_FOG (1<<10) +#define R200_CLIP_DISABLE (1<<11) +#define R200_CULL_FRONT_IS_CW (0<<28) +#define R200_CULL_FRONT_IS_CCW (1<<28) +#define R200_CULL_FRONT (1<<29) +#define R200_CULL_BACK (1<<30) +#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4 +/* gap */ +#define R200_SE_VTX_ST_POS_0_X_4 0x2300 +#define R200_SE_VTX_ST_POS_0_Y_4 0x2304 +#define R200_SE_VTX_ST_POS_0_Z_4 0x2308 +#define R200_SE_VTX_ST_POS_0_W_4 0x230c +#define R200_SE_VTX_ST_NORM_0_X 0x2310 +#define R200_SE_VTX_ST_NORM_0_Y 0x2314 +#define R200_SE_VTX_ST_NORM_0_Z 0x2318 +#define R200_SE_VTX_ST_PVMS 0x231c +#define R200_SE_VTX_ST_CLR_0_R 0x2320 +#define R200_SE_VTX_ST_CLR_0_G 0x2324 +#define R200_SE_VTX_ST_CLR_0_B 0x2328 +#define R200_SE_VTX_ST_CLR_0_A 0x232c +#define R200_SE_VTX_ST_CLR_1_R 0x2330 +#define R200_SE_VTX_ST_CLR_1_G 0x2334 +#define R200_SE_VTX_ST_CLR_1_B 0x2338 +#define R200_SE_VTX_ST_CLR_1_A 0x233c +#define R200_SE_VTX_ST_CLR_2_R 0x2340 +#define R200_SE_VTX_ST_CLR_2_G 0x2344 +#define R200_SE_VTX_ST_CLR_2_B 0x2348 +#define R200_SE_VTX_ST_CLR_2_A 0x234c +#define R200_SE_VTX_ST_CLR_3_R 0x2350 +#define R200_SE_VTX_ST_CLR_3_G 0x2354 +#define R200_SE_VTX_ST_CLR_3_B 0x2358 +#define R200_SE_VTX_ST_CLR_3_A 0x235c +#define R200_SE_VTX_ST_CLR_4_R 0x2360 +#define R200_SE_VTX_ST_CLR_4_G 0x2364 +#define R200_SE_VTX_ST_CLR_4_B 0x2368 +#define R200_SE_VTX_ST_CLR_4_A 0x236c +#define R200_SE_VTX_ST_CLR_5_R 0x2370 +#define R200_SE_VTX_ST_CLR_5_G 0x2374 +#define R200_SE_VTX_ST_CLR_5_B 0x2378 +#define R200_SE_VTX_ST_CLR_5_A 0x237c +#define R200_SE_VTX_ST_CLR_6_R 0x2380 +#define R200_SE_VTX_ST_CLR_6_G 0x2384 +#define R200_SE_VTX_ST_CLR_6_B 0x2388 +#define R200_SE_VTX_ST_CLR_6_A 0x238c +#define R200_SE_VTX_ST_CLR_7_R 0x2390 +#define R200_SE_VTX_ST_CLR_7_G 0x2394 +#define R200_SE_VTX_ST_CLR_7_B 0x2398 +#define R200_SE_VTX_ST_CLR_7_A 0x239c +#define R200_SE_VTX_ST_TEX_0_S 0x23a0 +#define R200_SE_VTX_ST_TEX_0_T 0x23a4 +#define R200_SE_VTX_ST_TEX_0_R 0x23a8 +#define R200_SE_VTX_ST_TEX_0_Q 0x23ac +#define R200_SE_VTX_ST_TEX_1_S 0x23b0 +#define R200_SE_VTX_ST_TEX_1_T 0x23b4 +#define R200_SE_VTX_ST_TEX_1_R 0x23b8 +#define R200_SE_VTX_ST_TEX_1_Q 0x23bc +#define R200_SE_VTX_ST_TEX_2_S 0x23c0 +#define R200_SE_VTX_ST_TEX_2_T 0x23c4 +#define R200_SE_VTX_ST_TEX_2_R 0x23c8 +#define R200_SE_VTX_ST_TEX_2_Q 0x23cc +#define R200_SE_VTX_ST_TEX_3_S 0x23d0 +#define R200_SE_VTX_ST_TEX_3_T 0x23d4 +#define R200_SE_VTX_ST_TEX_3_R 0x23d8 +#define R200_SE_VTX_ST_TEX_3_Q 0x23dc +#define R200_SE_VTX_ST_TEX_4_S 0x23e0 +#define R200_SE_VTX_ST_TEX_4_T 0x23e4 +#define R200_SE_VTX_ST_TEX_4_R 0x23e8 +#define R200_SE_VTX_ST_TEX_4_Q 0x23ec +#define R200_SE_VTX_ST_TEX_5_S 0x23f0 +#define R200_SE_VTX_ST_TEX_5_T 0x23f4 +#define R200_SE_VTX_ST_TEX_5_R 0x23f8 +#define R200_SE_VTX_ST_TEX_5_Q 0x23fc +#define R200_SE_VTX_ST_PNT_SPRT_SZ 0x2400 +#define R200_SE_VTX_ST_DISC_FOG 0x2404 +#define R200_SE_VTX_ST_SHININESS_0 0x2408 +#define R200_SE_VTX_ST_SHININESS_1 0x240c +#define R200_SE_VTX_ST_BLND_WT_0 0x2410 +#define R200_SE_VTX_ST_BLND_WT_1 0x2414 +#define R200_SE_VTX_ST_BLND_WT_2 0x2418 +#define R200_SE_VTX_ST_BLND_WT_3 0x241c +#define R200_SE_VTX_ST_POS_1_X 0x2420 +#define R200_SE_VTX_ST_POS_1_Y 0x2424 +#define R200_SE_VTX_ST_POS_1_Z 0x2428 +#define R200_SE_VTX_ST_POS_1_W 0x242c +#define R200_SE_VTX_ST_NORM_1_X 0x2430 +#define R200_SE_VTX_ST_NORM_1_Y 0x2434 +#define R200_SE_VTX_ST_NORM_1_Z 0x2438 +#define R200_SE_VTX_ST_USR_CLR_0_R 0x2440 +#define R200_SE_VTX_ST_USR_CLR_0_G 0x2444 +#define R200_SE_VTX_ST_USR_CLR_0_B 0x2448 +#define R200_SE_VTX_ST_USR_CLR_0_A 0x244c +#define R200_SE_VTX_ST_USR_CLR_1_R 0x2450 +#define R200_SE_VTX_ST_USR_CLR_1_G 0x2454 +#define R200_SE_VTX_ST_USR_CLR_1_B 0x2458 +#define R200_SE_VTX_ST_USR_CLR_1_A 0x245c +#define R200_SE_VTX_ST_CLR_0_PKD 0x2460 +#define R200_SE_VTX_ST_CLR_1_PKD 0x2464 +#define R200_SE_VTX_ST_CLR_2_PKD 0x2468 +#define R200_SE_VTX_ST_CLR_3_PKD 0x246c +#define R200_SE_VTX_ST_CLR_4_PKD 0x2470 +#define R200_SE_VTX_ST_CLR_5_PKD 0x2474 +#define R200_SE_VTX_ST_CLR_6_PKD 0x2478 +#define R200_SE_VTX_ST_CLR_7_PKD 0x247c +#define R200_SE_VTX_ST_POS_0_X_2 0x2480 +#define R200_SE_VTX_ST_POS_0_Y_2 0x2484 +#define R200_SE_VTX_ST_PAR_CLR_LD 0x2488 +#define R200_SE_VTX_ST_USR_CLR_PKD 0x248c +#define R200_SE_VTX_ST_POS_0_X_3 0x2490 +#define R200_SE_VTX_ST_POS_0_Y_3 0x2494 +#define R200_SE_VTX_ST_POS_0_Z_3 0x2498 +#define R200_SE_VTX_ST_END_OF_PKT 0x249c +/* gap */ +#define R200_RE_POINTSIZE 0x2648 +#define R200_POINTSIZE_SHIFT 0 +#define R200_MAXPOINTSIZE_SHIFT 16 +/* gap */ +#define R200_RE_TOP_LEFT 0x26c0 +#define R200_RE_LEFT_SHIFT 0 +#define R200_RE_TOP_SHIFT 16 +#define R200_RE_MISC 0x26c4 +#define R200_STIPPLE_COORD_MASK 0x1f +#define R200_STIPPLE_X_OFFSET_SHIFT 0 +#define R200_STIPPLE_X_OFFSET_MASK (0x1f << 0) +#define R200_STIPPLE_Y_OFFSET_SHIFT 8 +#define R200_STIPPLE_Y_OFFSET_MASK (0x1f << 8) +#define R200_STIPPLE_LITTLE_BIT_ORDER (0 << 16) +#define R200_STIPPLE_BIG_BIT_ORDER (1 << 16) +/* gap */ +#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 +#define R200_EXCLUSIVE_SCISSOR_0 0x01000000 +#define R200_EXCLUSIVE_SCISSOR_1 0x02000000 +#define R200_EXCLUSIVE_SCISSOR_2 0x04000000 +#define R200_SCISSOR_ENABLE_0 0x10000000 +#define R200_SCISSOR_ENABLE_1 0x20000000 +#define R200_SCISSOR_ENABLE_2 0x40000000 +/* gap */ +#define R200_PP_TXFILTER_0 0x2c00 +#define R200_MAG_FILTER_NEAREST (0 << 0) +#define R200_MAG_FILTER_LINEAR (1 << 0) +#define R200_MAG_FILTER_MASK (1 << 0) +#define R200_MIN_FILTER_NEAREST (0 << 1) +#define R200_MIN_FILTER_LINEAR (1 << 1) +#define R200_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) +#define R200_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) +#define R200_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) +#define R200_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) +#define R200_MIN_FILTER_ANISO_NEAREST (8 << 1) +#define R200_MIN_FILTER_ANISO_LINEAR (9 << 1) +#define R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) +#define R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) +#define R200_MIN_FILTER_MASK (15 << 1) +#define R200_MAX_ANISO_1_TO_1 (0 << 5) +#define R200_MAX_ANISO_2_TO_1 (1 << 5) +#define R200_MAX_ANISO_4_TO_1 (2 << 5) +#define R200_MAX_ANISO_8_TO_1 (3 << 5) +#define R200_MAX_ANISO_16_TO_1 (4 << 5) +#define R200_MAX_ANISO_MASK (7 << 5) +#define R200_MAX_MIP_LEVEL_MASK (0x0f << 16) +#define R200_MAX_MIP_LEVEL_SHIFT 16 +#define R200_YUV_TO_RGB (1 << 20) +#define R200_YUV_TEMPERATURE_COOL (0 << 21) +#define R200_YUV_TEMPERATURE_HOT (1 << 21) +#define R200_YUV_TEMPERATURE_MASK (1 << 21) +#define R200_WRAPEN_S (1 << 22) +#define R200_CLAMP_S_WRAP (0 << 23) +#define R200_CLAMP_S_MIRROR (1 << 23) +#define R200_CLAMP_S_CLAMP_LAST (2 << 23) +#define R200_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) +#define R200_CLAMP_S_CLAMP_BORDER (4 << 23) +#define R200_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) +#define R200_CLAMP_S_MASK (7 << 23) +#define R200_WRAPEN_T (1 << 26) +#define R200_CLAMP_T_WRAP (0 << 27) +#define R200_CLAMP_T_MIRROR (1 << 27) +#define R200_CLAMP_T_CLAMP_LAST (2 << 27) +#define R200_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) +#define R200_CLAMP_T_CLAMP_BORDER (4 << 27) +#define R200_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) +#define R200_CLAMP_T_MASK (7 << 27) +#define R200_KILL_LT_ZERO (1 << 30) +#define R200_BORDER_MODE_OGL (0 << 31) +#define R200_BORDER_MODE_D3D (1 << 31) +#define R200_PP_TXFORMAT_0 0x2c04 +#define R200_TXFORMAT_I8 (0 << 0) +#define R200_TXFORMAT_AI88 (1 << 0) +#define R200_TXFORMAT_RGB332 (2 << 0) +#define R200_TXFORMAT_ARGB1555 (3 << 0) +#define R200_TXFORMAT_RGB565 (4 << 0) +#define R200_TXFORMAT_ARGB4444 (5 << 0) +#define R200_TXFORMAT_ARGB8888 (6 << 0) +#define R200_TXFORMAT_RGBA8888 (7 << 0) +#define R200_TXFORMAT_Y8 (8 << 0) +#define R200_TXFORMAT_AVYU4444 (9 << 0) +#define R200_TXFORMAT_VYUY422 (10 << 0) +#define R200_TXFORMAT_YVYU422 (11 << 0) +#define R200_TXFORMAT_DXT1 (12 << 0) +#define R200_TXFORMAT_DXT23 (14 << 0) +#define R200_TXFORMAT_DXT45 (15 << 0) +#define R200_TXFORMAT_FORMAT_MASK (31 << 0) +#define R200_TXFORMAT_FORMAT_SHIFT 0 +#define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6) +#define R200_TXFORMAT_NON_POWER2 (1 << 7) +#define R200_TXFORMAT_WIDTH_MASK (15 << 8) +#define R200_TXFORMAT_WIDTH_SHIFT 8 +#define R200_TXFORMAT_HEIGHT_MASK (15 << 12) +#define R200_TXFORMAT_HEIGHT_SHIFT 12 +#define R200_TXFORMAT_F5_WIDTH_MASK (15 << 15) /* cube face 5 */ +#define R200_TXFORMAT_F5_WIDTH_SHIFT 15 +#define R200_TXFORMAT_F5_HEIGHT_MASK (15 << 20) +#define R200_TXFORMAT_F5_HEIGHT_SHIFT 20 +#define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24) +#define R200_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) +#define R200_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) +#define R200_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) +#define R200_TXFORMAT_ST_ROUTE_STQ3 (3 << 24) +#define R200_TXFORMAT_ST_ROUTE_STQ4 (4 << 24) +#define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24) +#define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) +#define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) +#define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) +#define R200_PP_TXFORMAT_X_0 0x2c08 +#define R200_DEPTH_LOG2_MASK (0xff << 0) +#define R200_DEPTH_LOG2_SHIFT 0 +#define R200_WRAPEN_Q (1 << 8) +#define R200_CLAMP_Q_WRAP (0 << 9) +#define R200_CLAMP_Q_MIRROR (1 << 9) +#define R200_CLAMP_Q_CLAMP_LAST (2 << 9) +#define R200_CLAMP_Q_MIRROR_CLAMP_LAST (3 << 9) +#define R200_CLAMP_Q_CLAMP_BORDER (6 << 9) +#define R200_CLAMP_Q_MIRROR_CLAMP_BORDER (7 << 9) +#define R200_CLAMP_Q_MASK (7 << 9) +#define R200_MIN_MIP_LEVEL_MASK (0xff << 12) +#define R200_MIN_MIP_LEVEL_SHIFT 12 +#define R200_TEXCOORD_NONPROJ (0 << 16) +#define R200_TEXCOORD_CUBIC_ENV (1 << 16) +#define R200_TEXCOORD_VOLUME (2 << 16) +#define R200_TEXCOORD_PROJ (3 << 16) +#define R200_TEXCOORD_DEPTH (4 << 16) +#define R200_TEXCOORD_1D_PROJ (5 << 16) +#define R200_TEXCOORD_1D (6 << 16) +#define R200_TEXCOORD_ZERO (7 << 16) +#define R200_LOD_BIAS_MASK (0xfff80000) +#define R200_LOD_BIAS_SHIFT 19 +#define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ +#define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */ +#define R200_PP_BORDER_COLOR_0 0x2c14 +#define R200_PP_CUBIC_FACES_0 0x2c18 +#define R200_PP_TXFILTER_1 0x2c20 +#define R200_PP_TXFORMAT_1 0x2c24 +#define R200_PP_TXFORMAT_X_1 0x2c28 +#define R200_PP_TXSIZE_1 0x2c2c +#define R200_PP_TXPITCH_1 0x2c30 +#define R200_PP_BORDER_COLOR_1 0x2c34 +#define R200_PP_CUBIC_FACES_1 0x2c38 +#define R200_PP_TXFILTER_2 0x2c40 +#define R200_PP_TXFORMAT_2 0x2c44 +#define R200_PP_TXSIZE_2 0x2c4c +#define R200_PP_TXFORMAT_X_2 0x2c48 +#define R200_PP_TXPITCH_2 0x2c50 +#define R200_PP_BORDER_COLOR_2 0x2c54 +#define R200_PP_CUBIC_FACES_2 0x2c58 +#define R200_PP_TXFILTER_3 0x2c60 +#define R200_PP_TXFORMAT_3 0x2c64 +#define R200_PP_TXSIZE_3 0x2c6c +#define R200_PP_TXFORMAT_X_3 0x2c68 +#define R200_PP_TXPITCH_3 0x2c70 +#define R200_PP_BORDER_COLOR_3 0x2c74 +#define R200_PP_CUBIC_FACES_3 0x2c78 +#define R200_PP_TXFILTER_4 0x2c80 +#define R200_PP_TXFORMAT_4 0x2c84 +#define R200_PP_TXSIZE_4 0x2c8c +#define R200_PP_TXFORMAT_X_4 0x2c88 +#define R200_PP_TXPITCH_4 0x2c90 +#define R200_PP_BORDER_COLOR_4 0x2c94 +#define R200_PP_CUBIC_FACES_4 0x2c98 +#define R200_PP_TXFILTER_5 0x2ca0 +#define R200_PP_TXFORMAT_5 0x2ca4 +#define R200_PP_TXSIZE_5 0x2cac +#define R200_PP_TXFORMAT_X_5 0x2ca8 +#define R200_PP_TXPITCH_5 0x2cb0 +#define R200_PP_BORDER_COLOR_5 0x2cb4 +#define R200_PP_CUBIC_FACES_5 0x2cb8 +/* gap */ +#define R200_PP_CNTL_X 0x2cc4 +/* gap */ +#define R200_PP_TXOFFSET_0 0x2d00 +#define R200_TXO_ENDIAN_NO_SWAP (0 << 0) +#define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) +#define R200_TXO_ENDIAN_WORD_SWAP (2 << 0) +#define R200_TXO_ENDIAN_HALFDW_SWAP (3 << 0) +#define R200_TXO_OFFSET_MASK 0xffffffe0 +#define R200_TXO_OFFSET_SHIFT 5 +#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 +#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 +#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c +#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 +#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 +#define R200_PP_TXOFFSET_1 0x2d18 +#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c +#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 +#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 +#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 +#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c +#define R200_PP_TXOFFSET_2 0x2d30 +#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 +#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 +#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c +#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 +#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 +#define R200_PP_TXOFFSET_3 0x2d48 +#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c +#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 +#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 +#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 +#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c +#define R200_PP_TXOFFSET_4 0x2d60 +#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 +#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 +#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c +#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 +#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 +#define R200_PP_TXOFFSET_5 0x2d78 +#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c +#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 +#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 +#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 +#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c +/* gap */ +#define R200_PP_TAM_DEBUG3 0x2d9c +/* gap */ +#define R200_PP_TFACTOR_0 0x2ee0 +#define R200_PP_TFACTOR_1 0x2ee4 +#define R200_PP_TFACTOR_2 0x2ee8 +#define R200_PP_TFACTOR_3 0x2eec +#define R200_PP_TFACTOR_4 0x2ef0 +#define R200_PP_TFACTOR_5 0x2ef4 +/* gap */ +#define R200_PP_TXCBLEND_0 0x2f00 +#define R200_TXC_ARG_A_ZERO (0) +#define R200_TXC_ARG_A_CURRENT_COLOR (2) +#define R200_TXC_ARG_A_CURRENT_ALPHA (3) +#define R200_TXC_ARG_A_DIFFUSE_COLOR (4) +#define R200_TXC_ARG_A_DIFFUSE_ALPHA (5) +#define R200_TXC_ARG_A_SPECULAR_COLOR (6) +#define R200_TXC_ARG_A_SPECULAR_ALPHA (7) +#define R200_TXC_ARG_A_TFACTOR_COLOR (8) +#define R200_TXC_ARG_A_TFACTOR_ALPHA (9) +#define R200_TXC_ARG_A_R0_COLOR (10) +#define R200_TXC_ARG_A_R0_ALPHA (11) +#define R200_TXC_ARG_A_R1_COLOR (12) +#define R200_TXC_ARG_A_R1_ALPHA (13) +#define R200_TXC_ARG_A_R2_COLOR (14) +#define R200_TXC_ARG_A_R2_ALPHA (15) +#define R200_TXC_ARG_A_R3_COLOR (16) +#define R200_TXC_ARG_A_R3_ALPHA (17) +#define R200_TXC_ARG_A_R4_COLOR (18) +#define R200_TXC_ARG_A_R4_ALPHA (19) +#define R200_TXC_ARG_A_R5_COLOR (20) +#define R200_TXC_ARG_A_R5_ALPHA (21) +#define R200_TXC_ARG_A_TFACTOR1_COLOR (26) +#define R200_TXC_ARG_A_TFACTOR1_ALPHA (27) +#define R200_TXC_ARG_A_MASK (31 << 0) +#define R200_TXC_ARG_A_SHIFT 0 +#define R200_TXC_ARG_B_ZERO (0<<5) +#define R200_TXC_ARG_B_CURRENT_COLOR (2<<5) +#define R200_TXC_ARG_B_CURRENT_ALPHA (3<<5) +#define R200_TXC_ARG_B_DIFFUSE_COLOR (4<<5) +#define R200_TXC_ARG_B_DIFFUSE_ALPHA (5<<5) +#define R200_TXC_ARG_B_SPECULAR_COLOR (6<<5) +#define R200_TXC_ARG_B_SPECULAR_ALPHA (7<<5) +#define R200_TXC_ARG_B_TFACTOR_COLOR (8<<5) +#define R200_TXC_ARG_B_TFACTOR_ALPHA (9<<5) +#define R200_TXC_ARG_B_R0_COLOR (10<<5) +#define R200_TXC_ARG_B_R0_ALPHA (11<<5) +#define R200_TXC_ARG_B_R1_COLOR (12<<5) +#define R200_TXC_ARG_B_R1_ALPHA (13<<5) +#define R200_TXC_ARG_B_R2_COLOR (14<<5) +#define R200_TXC_ARG_B_R2_ALPHA (15<<5) +#define R200_TXC_ARG_B_R3_COLOR (16<<5) +#define R200_TXC_ARG_B_R3_ALPHA (17<<5) +#define R200_TXC_ARG_B_R4_COLOR (18<<5) +#define R200_TXC_ARG_B_R4_ALPHA (19<<5) +#define R200_TXC_ARG_B_R5_COLOR (20<<5) +#define R200_TXC_ARG_B_R5_ALPHA (21<<5) +#define R200_TXC_ARG_B_TFACTOR1_COLOR (26<<5) +#define R200_TXC_ARG_B_TFACTOR1_ALPHA (27<<5) +#define R200_TXC_ARG_B_MASK (31 << 5) +#define R200_TXC_ARG_B_SHIFT 5 +#define R200_TXC_ARG_C_ZERO (0<<10) +#define R200_TXC_ARG_C_CURRENT_COLOR (2<<10) +#define R200_TXC_ARG_C_CURRENT_ALPHA (3<<10) +#define R200_TXC_ARG_C_DIFFUSE_COLOR (4<<10) +#define R200_TXC_ARG_C_DIFFUSE_ALPHA (5<<10) +#define R200_TXC_ARG_C_SPECULAR_COLOR (6<<10) +#define R200_TXC_ARG_C_SPECULAR_ALPHA (7<<10) +#define R200_TXC_ARG_C_TFACTOR_COLOR (8<<10) +#define R200_TXC_ARG_C_TFACTOR_ALPHA (9<<10) +#define R200_TXC_ARG_C_R0_COLOR (10<<10) +#define R200_TXC_ARG_C_R0_ALPHA (11<<10) +#define R200_TXC_ARG_C_R1_COLOR (12<<10) +#define R200_TXC_ARG_C_R1_ALPHA (13<<10) +#define R200_TXC_ARG_C_R2_COLOR (14<<10) +#define R200_TXC_ARG_C_R2_ALPHA (15<<10) +#define R200_TXC_ARG_C_R3_COLOR (16<<10) +#define R200_TXC_ARG_C_R3_ALPHA (17<<10) +#define R200_TXC_ARG_C_R4_COLOR (18<<10) +#define R200_TXC_ARG_C_R4_ALPHA (19<<10) +#define R200_TXC_ARG_C_R5_COLOR (20<<10) +#define R200_TXC_ARG_C_R5_ALPHA (21<<10) +#define R200_TXC_ARG_C_TFACTOR1_COLOR (26<<10) +#define R200_TXC_ARG_C_TFACTOR1_ALPHA (27<<10) +#define R200_TXC_ARG_C_MASK (31 << 10) +#define R200_TXC_ARG_C_SHIFT 10 +#define R200_TXC_COMP_ARG_A (1 << 16) +#define R200_TXC_COMP_ARG_A_SHIFT (16) +#define R200_TXC_BIAS_ARG_A (1 << 17) +#define R200_TXC_SCALE_ARG_A (1 << 18) +#define R200_TXC_NEG_ARG_A (1 << 19) +#define R200_TXC_COMP_ARG_B (1 << 20) +#define R200_TXC_COMP_ARG_B_SHIFT (20) +#define R200_TXC_BIAS_ARG_B (1 << 21) +#define R200_TXC_SCALE_ARG_B (1 << 22) +#define R200_TXC_NEG_ARG_B (1 << 23) +#define R200_TXC_COMP_ARG_C (1 << 24) +#define R200_TXC_COMP_ARG_C_SHIFT (24) +#define R200_TXC_BIAS_ARG_C (1 << 25) +#define R200_TXC_SCALE_ARG_C (1 << 26) +#define R200_TXC_NEG_ARG_C (1 << 27) +#define R200_TXC_OP_MADD (0 << 28) +#define R200_TXC_OP_CND0 (2 << 28) +#define R200_TXC_OP_LERP (3 << 28) +#define R200_TXC_OP_DOT3 (4 << 28) +#define R200_TXC_OP_DOT4 (5 << 28) +#define R200_TXC_OP_CONDITIONAL (6 << 28) +#define R200_TXC_OP_DOT2_ADD (7 << 28) +#define R200_TXC_OP_MASK (7 << 28) +#define R200_PP_TXCBLEND2_0 0x2f04 +#define R200_TXC_TFACTOR_SEL_SHIFT 0 +#define R200_TXC_TFACTOR_SEL_MASK 0x7 +#define R200_TXC_TFACTOR1_SEL_SHIFT 4 +#define R200_TXC_TFACTOR1_SEL_MASK (0x7 << 4) +#define R200_TXC_SCALE_SHIFT 8 +#define R200_TXC_SCALE_MASK (7 << 8) +#define R200_TXC_SCALE_1X (0 << 8) +#define R200_TXC_SCALE_2X (1 << 8) +#define R200_TXC_SCALE_4X (2 << 8) +#define R200_TXC_SCALE_8X (3 << 8) +#define R200_TXC_SCALE_INV2 (5 << 8) +#define R200_TXC_SCALE_INV4 (6 << 8) +#define R200_TXC_SCALE_INV8 (7 << 8) +#define R200_TXC_CLAMP_SHIFT 12 +#define R200_TXC_CLAMP_MASK (3 << 12) +#define R200_TXC_CLAMP_WRAP (0 << 12) +#define R200_TXC_CLAMP_0_1 (1 << 12) +#define R200_TXC_CLAMP_8_8 (2 << 12) +#define R200_TXC_OUTPUT_REG_MASK (7 << 16) +#define R200_TXC_OUTPUT_REG_NONE (0 << 16) +#define R200_TXC_OUTPUT_REG_R0 (1 << 16) +#define R200_TXC_OUTPUT_REG_R1 (2 << 16) +#define R200_TXC_OUTPUT_REG_R2 (3 << 16) +#define R200_TXC_OUTPUT_REG_R3 (4 << 16) +#define R200_TXC_OUTPUT_REG_R4 (5 << 16) +#define R200_TXC_OUTPUT_REG_R5 (6 << 16) +#define R200_TXC_OUTPUT_MASK_MASK (7 << 20) +#define R200_TXC_OUTPUT_MASK_RGB (0 << 20) +#define R200_TXC_OUTPUT_MASK_RG (1 << 20) +#define R200_TXC_OUTPUT_MASK_RB (2 << 20) +#define R200_TXC_OUTPUT_MASK_R (3 << 20) +#define R200_TXC_OUTPUT_MASK_GB (4 << 20) +#define R200_TXC_OUTPUT_MASK_G (5 << 20) +#define R200_TXC_OUTPUT_MASK_B (6 << 20) +#define R200_TXC_OUTPUT_MASK_NONE (7 << 20) +#define R200_TXC_REPL_NORMAL 0 +#define R200_TXC_REPL_RED 1 +#define R200_TXC_REPL_GREEN 2 +#define R200_TXC_REPL_BLUE 3 +#define R200_TXC_REPL_ARG_A_SHIFT 26 +#define R200_TXC_REPL_ARG_A_MASK (3 << 26) +#define R200_TXC_REPL_ARG_B_SHIFT 28 +#define R200_TXC_REPL_ARG_B_MASK (3 << 28) +#define R200_TXC_REPL_ARG_C_SHIFT 30 +#define R200_TXC_REPL_ARG_C_MASK (3 << 30) +#define R200_PP_TXABLEND_0 0x2f08 +#define R200_TXA_ARG_A_ZERO (0) +#define R200_TXA_ARG_A_CURRENT_ALPHA (2) /* guess */ +#define R200_TXA_ARG_A_CURRENT_BLUE (3) /* guess */ +#define R200_TXA_ARG_A_DIFFUSE_ALPHA (4) +#define R200_TXA_ARG_A_DIFFUSE_BLUE (5) +#define R200_TXA_ARG_A_SPECULAR_ALPHA (6) +#define R200_TXA_ARG_A_SPECULAR_BLUE (7) +#define R200_TXA_ARG_A_TFACTOR_ALPHA (8) +#define R200_TXA_ARG_A_TFACTOR_BLUE (9) +#define R200_TXA_ARG_A_R0_ALPHA (10) +#define R200_TXA_ARG_A_R0_BLUE (11) +#define R200_TXA_ARG_A_R1_ALPHA (12) +#define R200_TXA_ARG_A_R1_BLUE (13) +#define R200_TXA_ARG_A_R2_ALPHA (14) +#define R200_TXA_ARG_A_R2_BLUE (15) +#define R200_TXA_ARG_A_R3_ALPHA (16) +#define R200_TXA_ARG_A_R3_BLUE (17) +#define R200_TXA_ARG_A_R4_ALPHA (18) +#define R200_TXA_ARG_A_R4_BLUE (19) +#define R200_TXA_ARG_A_R5_ALPHA (20) +#define R200_TXA_ARG_A_R5_BLUE (21) +#define R200_TXA_ARG_A_TFACTOR1_ALPHA (26) +#define R200_TXA_ARG_A_TFACTOR1_BLUE (27) +#define R200_TXA_ARG_A_MASK (31 << 0) +#define R200_TXA_ARG_A_SHIFT 0 +#define R200_TXA_ARG_B_ZERO (0<<5) +#define R200_TXA_ARG_B_CURRENT_ALPHA (2<<5) /* guess */ +#define R200_TXA_ARG_B_CURRENT_BLUE (3<<5) /* guess */ +#define R200_TXA_ARG_B_DIFFUSE_ALPHA (4<<5) +#define R200_TXA_ARG_B_DIFFUSE_BLUE (5<<5) +#define R200_TXA_ARG_B_SPECULAR_ALPHA (6<<5) +#define R200_TXA_ARG_B_SPECULAR_BLUE (7<<5) +#define R200_TXA_ARG_B_TFACTOR_ALPHA (8<<5) +#define R200_TXA_ARG_B_TFACTOR_BLUE (9<<5) +#define R200_TXA_ARG_B_R0_ALPHA (10<<5) +#define R200_TXA_ARG_B_R0_BLUE (11<<5) +#define R200_TXA_ARG_B_R1_ALPHA (12<<5) +#define R200_TXA_ARG_B_R1_BLUE (13<<5) +#define R200_TXA_ARG_B_R2_ALPHA (14<<5) +#define R200_TXA_ARG_B_R2_BLUE (15<<5) +#define R200_TXA_ARG_B_R3_ALPHA (16<<5) +#define R200_TXA_ARG_B_R3_BLUE (17<<5) +#define R200_TXA_ARG_B_R4_ALPHA (18<<5) +#define R200_TXA_ARG_B_R4_BLUE (19<<5) +#define R200_TXA_ARG_B_R5_ALPHA (20<<5) +#define R200_TXA_ARG_B_R5_BLUE (21<<5) +#define R200_TXA_ARG_B_TFACTOR1_ALPHA (26<<5) +#define R200_TXA_ARG_B_TFACTOR1_BLUE (27<<5) +#define R200_TXA_ARG_B_MASK (31 << 5) +#define R200_TXA_ARG_B_SHIFT 5 +#define R200_TXA_ARG_C_ZERO (0<<10) +#define R200_TXA_ARG_C_CURRENT_ALPHA (2<<10) /* guess */ +#define R200_TXA_ARG_C_CURRENT_BLUE (3<<10) /* guess */ +#define R200_TXA_ARG_C_DIFFUSE_ALPHA (4<<10) +#define R200_TXA_ARG_C_DIFFUSE_BLUE (5<<10) +#define R200_TXA_ARG_C_SPECULAR_ALPHA (6<<10) +#define R200_TXA_ARG_C_SPECULAR_BLUE (7<<10) +#define R200_TXA_ARG_C_TFACTOR_ALPHA (8<<10) +#define R200_TXA_ARG_C_TFACTOR_BLUE (9<<10) +#define R200_TXA_ARG_C_R0_ALPHA (10<<10) +#define R200_TXA_ARG_C_R0_BLUE (11<<10) +#define R200_TXA_ARG_C_R1_ALPHA (12<<10) +#define R200_TXA_ARG_C_R1_BLUE (13<<10) +#define R200_TXA_ARG_C_R2_ALPHA (14<<10) +#define R200_TXA_ARG_C_R2_BLUE (15<<10) +#define R200_TXA_ARG_C_R3_ALPHA (16<<10) +#define R200_TXA_ARG_C_R3_BLUE (17<<10) +#define R200_TXA_ARG_C_R4_ALPHA (18<<10) +#define R200_TXA_ARG_C_R4_BLUE (19<<10) +#define R200_TXA_ARG_C_R5_ALPHA (20<<10) +#define R200_TXA_ARG_C_R5_BLUE (21<<10) +#define R200_TXA_ARG_C_TFACTOR1_ALPHA (26<<10) +#define R200_TXA_ARG_C_TFACTOR1_BLUE (27<<10) +#define R200_TXA_ARG_C_MASK (31 << 10) +#define R200_TXA_ARG_C_SHIFT 10 +#define R200_TXA_COMP_ARG_A (1 << 16) +#define R200_TXA_COMP_ARG_A_SHIFT (16) +#define R200_TXA_BIAS_ARG_A (1 << 17) +#define R200_TXA_SCALE_ARG_A (1 << 18) +#define R200_TXA_NEG_ARG_A (1 << 19) +#define R200_TXA_COMP_ARG_B (1 << 20) +#define R200_TXA_COMP_ARG_B_SHIFT (20) +#define R200_TXA_BIAS_ARG_B (1 << 21) +#define R200_TXA_SCALE_ARG_B (1 << 22) +#define R200_TXA_NEG_ARG_B (1 << 23) +#define R200_TXA_COMP_ARG_C (1 << 24) +#define R200_TXA_COMP_ARG_C_SHIFT (24) +#define R200_TXA_BIAS_ARG_C (1 << 25) +#define R200_TXA_SCALE_ARG_C (1 << 26) +#define R200_TXA_NEG_ARG_C (1 << 27) +#define R200_TXA_OP_MADD (0 << 28) +#define R200_TXA_OP_CND0 (2 << 28) +#define R200_TXA_OP_LERP (3 << 28) +#define R200_TXA_OP_CONDITIONAL (6 << 28) +#define R200_TXA_OP_MASK (7 << 28) +#define R200_PP_TXABLEND2_0 0x2f0c +#define R200_TXA_TFACTOR_SEL_SHIFT 0 +#define R200_TXA_TFACTOR_SEL_MASK 0x7 +#define R200_TXA_TFACTOR1_SEL_SHIFT 4 +#define R200_TXA_TFACTOR1_SEL_MASK (0x7 << 4) +#define R200_TXA_SCALE_SHIFT 8 +#define R200_TXA_SCALE_MASK (7 << 8) +#define R200_TXA_SCALE_1X (0 << 8) +#define R200_TXA_SCALE_2X (1 << 8) +#define R200_TXA_SCALE_4X (2 << 8) +#define R200_TXA_SCALE_8X (3 << 8) +#define R200_TXA_SCALE_INV2 (5 << 8) +#define R200_TXA_SCALE_INV4 (6 << 8) +#define R200_TXA_SCALE_INV8 (7 << 8) +#define R200_TXA_CLAMP_SHIFT 12 +#define R200_TXA_CLAMP_MASK (3 << 12) +#define R200_TXA_CLAMP_WRAP (0 << 12) +#define R200_TXA_CLAMP_0_1 (1 << 12) +#define R200_TXA_CLAMP_8_8 (2 << 12) +#define R200_TXA_OUTPUT_REG_MASK (7 << 16) +#define R200_TXA_OUTPUT_REG_NONE (0 << 16) +#define R200_TXA_OUTPUT_REG_R0 (1 << 16) +#define R200_TXA_OUTPUT_REG_R1 (2 << 16) +#define R200_TXA_OUTPUT_REG_R2 (3 << 16) +#define R200_TXA_OUTPUT_REG_R3 (4 << 16) +#define R200_TXA_OUTPUT_REG_R4 (5 << 16) +#define R200_TXA_OUTPUT_REG_R5 (6 << 16) +#define R200_TXA_DOT_ALPHA (1 << 20) +#define R200_TXA_REPL_NORMAL 0 +#define R200_TXA_REPL_RED 1 +#define R200_TXA_REPL_GREEN 2 +#define R200_TXA_REPL_ARG_A_SHIFT 26 +#define R200_TXA_REPL_ARG_A_MASK (3 << 26) +#define R200_TXA_REPL_ARG_B_SHIFT 28 +#define R200_TXA_REPL_ARG_B_MASK (3 << 28) +#define R200_TXA_REPL_ARG_C_SHIFT 30 +#define R200_TXA_REPL_ARG_C_MASK (3 << 30) +#define R200_PP_TXCBLEND_1 0x2f10 +#define R200_PP_TXCBLEND2_1 0x2f14 +#define R200_PP_TXABLEND_1 0x2f18 +#define R200_PP_TXABLEND2_1 0x2f1c +#define R200_PP_TXCBLEND_2 0x2f20 +#define R200_PP_TXCBLEND2_2 0x2f24 +#define R200_PP_TXABLEND_2 0x2f28 +#define R200_PP_TXABLEND2_2 0x2f2c +#define R200_PP_TXCBLEND_3 0x2f30 +#define R200_PP_TXCBLEND2_3 0x2f34 +#define R200_PP_TXABLEND_3 0x2f38 +#define R200_PP_TXABLEND2_3 0x2f3c +#define R200_PP_TXCBLEND_4 0x2f40 +#define R200_PP_TXCBLEND2_4 0x2f44 +#define R200_PP_TXABLEND_4 0x2f48 +#define R200_PP_TXABLEND2_4 0x2f4c +#define R200_PP_TXCBLEND_5 0x2f50 +#define R200_PP_TXCBLEND2_5 0x2f54 +#define R200_PP_TXABLEND_5 0x2f58 +#define R200_PP_TXABLEND2_5 0x2f5c +#define R200_PP_TXCBLEND_6 0x2f60 +#define R200_PP_TXCBLEND2_6 0x2f64 +#define R200_PP_TXABLEND_6 0x2f68 +#define R200_PP_TXABLEND2_6 0x2f6c +#define R200_PP_TXCBLEND_7 0x2f70 +#define R200_PP_TXCBLEND2_7 0x2f74 +#define R200_PP_TXABLEND_7 0x2f78 +#define R200_PP_TXABLEND2_7 0x2f7c +/* gap */ +#define R200_RB3D_ABLENDCNTL 0x321C /* see BLENDCTL */ +#define R200_RB3D_CBLENDCNTL 0x3220 /* see BLENDCTL */ + + +/* + * Offsets in TCL vector state. NOTE: Hardwiring matrix positions. + * Multiple contexts could collaberate to eliminate state bouncing. + */ +#define R200_VS_LIGHT_AMBIENT_ADDR 0x00000028 +#define R200_VS_LIGHT_DIFFUSE_ADDR 0x00000030 +#define R200_VS_LIGHT_SPECULAR_ADDR 0x00000038 +#define R200_VS_LIGHT_DIRPOS_ADDR 0x00000040 +#define R200_VS_LIGHT_HWVSPOT_ADDR 0x00000048 +#define R200_VS_LIGHT_ATTENUATION_ADDR 0x00000050 +#define R200_VS_SPOT_DUAL_CONE 0x00000058 +#define R200_VS_GLOBAL_AMBIENT_ADDR 0x0000005C +#define R200_VS_FOG_PARAM_ADDR 0x0000005D +#define R200_VS_EYE_VECTOR_ADDR 0x0000005E +#define R200_VS_UCP_ADDR 0x00000060 +#define R200_VS_PNT_SPRITE_VPORT_SCALE 0x00000068 +#define R200_VS_MATRIX_0_MV 0x00000080 +#define R200_VS_MATRIX_1_INV_MV 0x00000084 +#define R200_VS_MATRIX_2_MVP 0x00000088 +#define R200_VS_MATRIX_3_TEX0 0x0000008C +#define R200_VS_MATRIX_4_TEX1 0x00000090 +#define R200_VS_MATRIX_5_TEX2 0x00000094 +#define R200_VS_MATRIX_6_TEX3 0x00000098 +#define R200_VS_MATRIX_7_TEX4 0x0000009C +#define R200_VS_MATRIX_8_TEX5 0x000000A0 +#define R200_VS_MAT_0_EMISS 0x000000B0 +#define R200_VS_MAT_0_AMB 0x000000B1 +#define R200_VS_MAT_0_DIF 0x000000B2 +#define R200_VS_MAT_0_SPEC 0x000000B3 +#define R200_VS_MAT_1_EMISS 0x000000B4 +#define R200_VS_MAT_1_AMB 0x000000B5 +#define R200_VS_MAT_1_DIF 0x000000B6 +#define R200_VS_MAT_1_SPEC 0x000000B7 +#define R200_VS_EYE2CLIP_MTX 0x000000B8 +#define R200_VS_PNT_SPRITE_ATT_CONST 0x000000BC +#define R200_VS_PNT_SPRITE_EYE_IN_MODEL 0x000000BD +#define R200_VS_PNT_SPRITE_CLAMP 0x000000BE +#define R200_VS_MAX 0x000001C0 + + +/* + * Offsets in TCL scalar state + */ +#define R200_SS_LIGHT_DCD_ADDR 0x00000000 +#define R200_SS_LIGHT_DCM_ADDR 0x00000008 +#define R200_SS_LIGHT_SPOT_EXPONENT_ADDR 0x00000010 +#define R200_SS_LIGHT_SPOT_CUTOFF_ADDR 0x00000018 +#define R200_SS_LIGHT_SPECULAR_THRESH_ADDR 0x00000020 +#define R200_SS_LIGHT_RANGE_CUTOFF_SQRD 0x00000028 +#define R200_SS_LIGHT_RANGE_ATT_CONST 0x00000030 +#define R200_SS_VERT_GUARD_CLIP_ADJ_ADDR 0x00000080 +#define R200_SS_VERT_GUARD_DISCARD_ADJ_ADDR 0x00000081 +#define R200_SS_HORZ_GUARD_CLIP_ADJ_ADDR 0x00000082 +#define R200_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 0x00000083 +#define R200_SS_MAT_0_SHININESS 0x00000100 +#define R200_SS_MAT_1_SHININESS 0x00000101 + + +/* + * Matrix indices + */ +#define R200_MTX_MV 0 +#define R200_MTX_IMV 1 +#define R200_MTX_MVP 2 +#define R200_MTX_TEX0 3 +#define R200_MTX_TEX1 4 +#define R200_MTX_TEX2 5 +#define R200_MTX_TEX3 6 +#define R200_MTX_TEX4 7 +#define R200_MTX_TEX5 8 + +/* Color formats for 2d packets + */ +#define R200_CP_COLOR_FORMAT_CI8 2 +#define R200_CP_COLOR_FORMAT_ARGB1555 3 +#define R200_CP_COLOR_FORMAT_RGB565 4 +#define R200_CP_COLOR_FORMAT_ARGB8888 6 +#define R200_CP_COLOR_FORMAT_RGB332 7 +#define R200_CP_COLOR_FORMAT_RGB8 9 +#define R200_CP_COLOR_FORMAT_ARGB4444 15 + + +/* + * CP type-3 packets + */ +#define R200_CP_CMD_NOP 0xC0001000 +#define R200_CP_CMD_NEXT_CHAR 0xC0001900 +#define R200_CP_CMD_PLY_NEXTSCAN 0xC0001D00 +#define R200_CP_CMD_SET_SCISSORS 0xC0001E00 +#define R200_CP_CMD_LOAD_MICROCODE 0xC0002400 +#define R200_CP_CMD_WAIT_FOR_IDLE 0xC0002600 +#define R200_CP_CMD_3D_DRAW_VBUF 0xC0002800 +#define R200_CP_CMD_3D_DRAW_IMMD 0xC0002900 +#define R200_CP_CMD_3D_DRAW_INDX 0xC0002A00 +#define R200_CP_CMD_LOAD_PALETTE 0xC0002C00 +#define R200_CP_CMD_3D_LOAD_VBPNTR 0xC0002F00 +#define R200_CP_CMD_INDX_BUFFER 0xC0003300 +#define R200_CP_CMD_3D_DRAW_VBUF_2 0xC0003400 +#define R200_CP_CMD_3D_DRAW_IMMD_2 0xC0003500 +#define R200_CP_CMD_3D_DRAW_INDX_2 0xC0003600 +#define R200_CP_CMD_PAINT 0xC0009100 +#define R200_CP_CMD_BITBLT 0xC0009200 +#define R200_CP_CMD_SMALLTEXT 0xC0009300 +#define R200_CP_CMD_HOSTDATA_BLT 0xC0009400 +#define R200_CP_CMD_POLYLINE 0xC0009500 +#define R200_CP_CMD_POLYSCANLINES 0xC0009800 +#define R200_CP_CMD_PAINT_MULTI 0xC0009A00 +#define R200_CP_CMD_BITBLT_MULTI 0xC0009B00 +#define R200_CP_CMD_TRANS_BITBLT 0xC0009C00 + + +#define R200_AGP_TEX_OFFSET 0x02000000 + + + + +#endif + diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c new file mode 100644 index 000000000..2f2bb0d7b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c @@ -0,0 +1,1316 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_sanity.c,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/************************************************************************** + +Copyright 2002 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc, Cedar Park, TX. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#include "r200_context.h" +#include "r200_ioctl.h" +#include "r200_sanity.h" +#include "radeon_reg.h" +#include "r200_reg.h" + +/* Set this '1' to get more verbiage. + */ +#define MORE_VERBOSE 1 + +#if MORE_VERBOSE +#define VERBOSE (R200_DEBUG & DEBUG_VERBOSE) +#define NORMAL (1) +#else +#define VERBOSE 0 +#define NORMAL (R200_DEBUG & DEBUG_VERBOSE) +#endif + + +/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in + * 1.3 cmdbuffers allow all previous state to be updated as well as + * the tcl scalar and vector areas. + */ +static struct { + int start; + int len; + const char *name; +} packet[RADEON_MAX_STATE_PACKETS] = { + { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, + { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, + { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, + { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, + { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, + { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, + { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, + { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, + { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, + { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, + { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, + { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, + { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, + { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, + { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, + { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, + { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, + { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, + { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, + { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, + { R200_PP_TXCBLEND_0, 4, "R200_EMIT_PP_TXCBLEND_0" }, + { R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" }, + { R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" }, + { R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" }, + { R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" }, + { R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" }, + { R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" }, + { R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" }, + { R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" }, + { R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" }, + { R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" }, + { R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" }, + { R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" }, + { R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" }, + { R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" }, + { R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" }, + { R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" }, + { R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" }, + { R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" }, + { R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" }, + { R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" }, + { R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" }, + { R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" }, + { R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" }, + { R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" }, + { R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" }, + { R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" }, + { R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" }, + { R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" }, + { R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" }, + { R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, + { R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, + { R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, + { R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, + { R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, + { R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, + { R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, + { R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, + { R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, + { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" }, +}; + +struct reg_names { + int idx; + const char *name; +}; + +static struct reg_names reg_names[] = { + { R200_PP_MISC, "R200_PP_MISC" }, + { R200_PP_FOG_COLOR, "R200_PP_FOG_COLOR" }, + { R200_RE_SOLID_COLOR, "R200_RE_SOLID_COLOR" }, + { R200_RB3D_BLENDCNTL, "R200_RB3D_BLENDCNTL" }, + { R200_RB3D_DEPTHOFFSET, "R200_RB3D_DEPTHOFFSET" }, + { R200_RB3D_DEPTHPITCH, "R200_RB3D_DEPTHPITCH" }, + { R200_RB3D_ZSTENCILCNTL, "R200_RB3D_ZSTENCILCNTL" }, + { R200_PP_CNTL, "R200_PP_CNTL" }, + { R200_RB3D_CNTL, "R200_RB3D_CNTL" }, + { R200_RB3D_COLOROFFSET, "R200_RB3D_COLOROFFSET" }, + { R200_RE_WIDTH_HEIGHT, "R200_RE_WIDTH_HEIGHT" }, + { R200_RB3D_COLORPITCH, "R200_RB3D_COLORPITCH" }, + { R200_SE_CNTL, "R200_SE_CNTL" }, + { R200_RE_CNTL, "R200_RE_CNTL" }, + { R200_RE_MISC, "R200_RE_MISC" }, + { R200_RE_STIPPLE_ADDR, "R200_RE_STIPPLE_ADDR" }, + { R200_RE_STIPPLE_DATA, "R200_RE_STIPPLE_DATA" }, + { R200_RE_LINE_PATTERN, "R200_RE_LINE_PATTERN" }, + { R200_RE_LINE_STATE, "R200_RE_LINE_STATE" }, + { R200_RE_SCISSOR_TL_0, "R200_RE_SCISSOR_TL_0" }, + { R200_RE_SCISSOR_BR_0, "R200_RE_SCISSOR_BR_0" }, + { R200_RE_SCISSOR_TL_1, "R200_RE_SCISSOR_TL_1" }, + { R200_RE_SCISSOR_BR_1, "R200_RE_SCISSOR_BR_1" }, + { R200_RE_SCISSOR_TL_2, "R200_RE_SCISSOR_TL_2" }, + { R200_RE_SCISSOR_BR_2, "R200_RE_SCISSOR_BR_2" }, + { R200_RB3D_DEPTHXY_OFFSET, "R200_RB3D_DEPTHXY_OFFSET" }, + { R200_RB3D_STENCILREFMASK, "R200_RB3D_STENCILREFMASK" }, + { R200_RB3D_ROPCNTL, "R200_RB3D_ROPCNTL" }, + { R200_RB3D_PLANEMASK, "R200_RB3D_PLANEMASK" }, + { R200_SE_VPORT_XSCALE, "R200_SE_VPORT_XSCALE" }, + { R200_SE_VPORT_XOFFSET, "R200_SE_VPORT_XOFFSET" }, + { R200_SE_VPORT_YSCALE, "R200_SE_VPORT_YSCALE" }, + { R200_SE_VPORT_YOFFSET, "R200_SE_VPORT_YOFFSET" }, + { R200_SE_VPORT_ZSCALE, "R200_SE_VPORT_ZSCALE" }, + { R200_SE_VPORT_ZOFFSET, "R200_SE_VPORT_ZOFFSET" }, + { R200_SE_ZBIAS_FACTOR, "R200_SE_ZBIAS_FACTOR" }, + { R200_SE_ZBIAS_CONSTANT, "R200_SE_ZBIAS_CONSTANT" }, + { R200_SE_LINE_WIDTH, "R200_SE_LINE_WIDTH" }, + { R200_SE_VAP_CNTL, "R200_SE_VAP_CNTL" }, + { R200_SE_VF_CNTL, "R200_SE_VF_CNTL" }, + { R200_SE_VTX_FMT_0, "R200_SE_VTX_FMT_0" }, + { R200_SE_VTX_FMT_1, "R200_SE_VTX_FMT_1" }, + { R200_SE_TCL_OUTPUT_VTX_FMT_0, "R200_SE_TCL_OUTPUT_VTX_FMT_0" }, + { R200_SE_TCL_OUTPUT_VTX_FMT_1, "R200_SE_TCL_OUTPUT_VTX_FMT_1" }, + { R200_SE_VTE_CNTL, "R200_SE_VTE_CNTL" }, + { R200_SE_VTX_NUM_ARRAYS, "R200_SE_VTX_NUM_ARRAYS" }, + { R200_SE_VTX_AOS_ATTR01, "R200_SE_VTX_AOS_ATTR01" }, + { R200_SE_VTX_AOS_ADDR0, "R200_SE_VTX_AOS_ADDR0" }, + { R200_SE_VTX_AOS_ADDR1, "R200_SE_VTX_AOS_ADDR1" }, + { R200_SE_VTX_AOS_ATTR23, "R200_SE_VTX_AOS_ATTR23" }, + { R200_SE_VTX_AOS_ADDR2, "R200_SE_VTX_AOS_ADDR2" }, + { R200_SE_VTX_AOS_ADDR3, "R200_SE_VTX_AOS_ADDR3" }, + { R200_SE_VTX_AOS_ATTR45, "R200_SE_VTX_AOS_ATTR45" }, + { R200_SE_VTX_AOS_ADDR4, "R200_SE_VTX_AOS_ADDR4" }, + { R200_SE_VTX_AOS_ADDR5, "R200_SE_VTX_AOS_ADDR5" }, + { R200_SE_VTX_AOS_ATTR67, "R200_SE_VTX_AOS_ATTR67" }, + { R200_SE_VTX_AOS_ADDR6, "R200_SE_VTX_AOS_ADDR6" }, + { R200_SE_VTX_AOS_ADDR7, "R200_SE_VTX_AOS_ADDR7" }, + { R200_SE_VTX_AOS_ATTR89, "R200_SE_VTX_AOS_ATTR89" }, + { R200_SE_VTX_AOS_ADDR8, "R200_SE_VTX_AOS_ADDR8" }, + { R200_SE_VTX_AOS_ADDR9, "R200_SE_VTX_AOS_ADDR9" }, + { R200_SE_VTX_AOS_ATTR1011, "R200_SE_VTX_AOS_ATTR1011" }, + { R200_SE_VTX_AOS_ADDR10, "R200_SE_VTX_AOS_ADDR10" }, + { R200_SE_VTX_AOS_ADDR11, "R200_SE_VTX_AOS_ADDR11" }, + { R200_SE_VF_MAX_VTX_INDX, "R200_SE_VF_MAX_VTX_INDX" }, + { R200_SE_VF_MIN_VTX_INDX, "R200_SE_VF_MIN_VTX_INDX" }, + { R200_SE_VTX_STATE_CNTL, "R200_SE_VTX_STATE_CNTL" }, + { R200_SE_TCL_VECTOR_INDX_REG, "R200_SE_TCL_VECTOR_INDX_REG" }, + { R200_SE_TCL_VECTOR_DATA_REG, "R200_SE_TCL_VECTOR_DATA_REG" }, + { R200_SE_TCL_SCALAR_INDX_REG, "R200_SE_TCL_SCALAR_INDX_REG" }, + { R200_SE_TCL_SCALAR_DATA_REG, "R200_SE_TCL_SCALAR_DATA_REG" }, + { R200_SE_TCL_MATRIX_SEL_0, "R200_SE_TCL_MATRIX_SEL_0" }, + { R200_SE_TCL_MATRIX_SEL_1, "R200_SE_TCL_MATRIX_SEL_1" }, + { R200_SE_TCL_MATRIX_SEL_2, "R200_SE_TCL_MATRIX_SEL_2" }, + { R200_SE_TCL_MATRIX_SEL_3, "R200_SE_TCL_MATRIX_SEL_3" }, + { R200_SE_TCL_MATRIX_SEL_4, "R200_SE_TCL_MATRIX_SEL_4" }, + { R200_SE_TCL_LIGHT_MODEL_CTL_0, "R200_SE_TCL_LIGHT_MODEL_CTL_0" }, + { R200_SE_TCL_LIGHT_MODEL_CTL_1, "R200_SE_TCL_LIGHT_MODEL_CTL_1" }, + { R200_SE_TCL_PER_LIGHT_CTL_0, "R200_SE_TCL_PER_LIGHT_CTL_0" }, + { R200_SE_TCL_PER_LIGHT_CTL_1, "R200_SE_TCL_PER_LIGHT_CTL_1" }, + { R200_SE_TCL_PER_LIGHT_CTL_2, "R200_SE_TCL_PER_LIGHT_CTL_2" }, + { R200_SE_TCL_PER_LIGHT_CTL_3, "R200_SE_TCL_PER_LIGHT_CTL_3" }, + { R200_SE_TCL_TEX_PROC_CTL_2, "R200_SE_TCL_TEX_PROC_CTL_2" }, + { R200_SE_TCL_TEX_PROC_CTL_3, "R200_SE_TCL_TEX_PROC_CTL_3" }, + { R200_SE_TCL_TEX_PROC_CTL_0, "R200_SE_TCL_TEX_PROC_CTL_0" }, + { R200_SE_TCL_TEX_PROC_CTL_1, "R200_SE_TCL_TEX_PROC_CTL_1" }, + { R200_SE_TC_TEX_CYL_WRAP_CTL, "R200_SE_TC_TEX_CYL_WRAP_CTL" }, + { R200_SE_TCL_UCP_VERT_BLEND_CTL, "R200_SE_TCL_UCP_VERT_BLEND_CTL" }, + { R200_SE_TCL_POINT_SPRITE_CNTL, "R200_SE_TCL_POINT_SPRITE_CNTL" }, + { R200_SE_VTX_ST_POS_0_X_4, "R200_SE_VTX_ST_POS_0_X_4" }, + { R200_SE_VTX_ST_POS_0_Y_4, "R200_SE_VTX_ST_POS_0_Y_4" }, + { R200_SE_VTX_ST_POS_0_Z_4, "R200_SE_VTX_ST_POS_0_Z_4" }, + { R200_SE_VTX_ST_POS_0_W_4, "R200_SE_VTX_ST_POS_0_W_4" }, + { R200_SE_VTX_ST_NORM_0_X, "R200_SE_VTX_ST_NORM_0_X" }, + { R200_SE_VTX_ST_NORM_0_Y, "R200_SE_VTX_ST_NORM_0_Y" }, + { R200_SE_VTX_ST_NORM_0_Z, "R200_SE_VTX_ST_NORM_0_Z" }, + { R200_SE_VTX_ST_PVMS, "R200_SE_VTX_ST_PVMS" }, + { R200_SE_VTX_ST_CLR_0_R, "R200_SE_VTX_ST_CLR_0_R" }, + { R200_SE_VTX_ST_CLR_0_G, "R200_SE_VTX_ST_CLR_0_G" }, + { R200_SE_VTX_ST_CLR_0_B, "R200_SE_VTX_ST_CLR_0_B" }, + { R200_SE_VTX_ST_CLR_0_A, "R200_SE_VTX_ST_CLR_0_A" }, + { R200_SE_VTX_ST_CLR_1_R, "R200_SE_VTX_ST_CLR_1_R" }, + { R200_SE_VTX_ST_CLR_1_G, "R200_SE_VTX_ST_CLR_1_G" }, + { R200_SE_VTX_ST_CLR_1_B, "R200_SE_VTX_ST_CLR_1_B" }, + { R200_SE_VTX_ST_CLR_1_A, "R200_SE_VTX_ST_CLR_1_A" }, + { R200_SE_VTX_ST_CLR_2_R, "R200_SE_VTX_ST_CLR_2_R" }, + { R200_SE_VTX_ST_CLR_2_G, "R200_SE_VTX_ST_CLR_2_G" }, + { R200_SE_VTX_ST_CLR_2_B, "R200_SE_VTX_ST_CLR_2_B" }, + { R200_SE_VTX_ST_CLR_2_A, "R200_SE_VTX_ST_CLR_2_A" }, + { R200_SE_VTX_ST_CLR_3_R, "R200_SE_VTX_ST_CLR_3_R" }, + { R200_SE_VTX_ST_CLR_3_G, "R200_SE_VTX_ST_CLR_3_G" }, + { R200_SE_VTX_ST_CLR_3_B, "R200_SE_VTX_ST_CLR_3_B" }, + { R200_SE_VTX_ST_CLR_3_A, "R200_SE_VTX_ST_CLR_3_A" }, + { R200_SE_VTX_ST_CLR_4_R, "R200_SE_VTX_ST_CLR_4_R" }, + { R200_SE_VTX_ST_CLR_4_G, "R200_SE_VTX_ST_CLR_4_G" }, + { R200_SE_VTX_ST_CLR_4_B, "R200_SE_VTX_ST_CLR_4_B" }, + { R200_SE_VTX_ST_CLR_4_A, "R200_SE_VTX_ST_CLR_4_A" }, + { R200_SE_VTX_ST_CLR_5_R, "R200_SE_VTX_ST_CLR_5_R" }, + { R200_SE_VTX_ST_CLR_5_G, "R200_SE_VTX_ST_CLR_5_G" }, + { R200_SE_VTX_ST_CLR_5_B, "R200_SE_VTX_ST_CLR_5_B" }, + { R200_SE_VTX_ST_CLR_5_A, "R200_SE_VTX_ST_CLR_5_A" }, + { R200_SE_VTX_ST_CLR_6_R, "R200_SE_VTX_ST_CLR_6_R" }, + { R200_SE_VTX_ST_CLR_6_G, "R200_SE_VTX_ST_CLR_6_G" }, + { R200_SE_VTX_ST_CLR_6_B, "R200_SE_VTX_ST_CLR_6_B" }, + { R200_SE_VTX_ST_CLR_6_A, "R200_SE_VTX_ST_CLR_6_A" }, + { R200_SE_VTX_ST_CLR_7_R, "R200_SE_VTX_ST_CLR_7_R" }, + { R200_SE_VTX_ST_CLR_7_G, "R200_SE_VTX_ST_CLR_7_G" }, + { R200_SE_VTX_ST_CLR_7_B, "R200_SE_VTX_ST_CLR_7_B" }, + { R200_SE_VTX_ST_CLR_7_A, "R200_SE_VTX_ST_CLR_7_A" }, + { R200_SE_VTX_ST_TEX_0_S, "R200_SE_VTX_ST_TEX_0_S" }, + { R200_SE_VTX_ST_TEX_0_T, "R200_SE_VTX_ST_TEX_0_T" }, + { R200_SE_VTX_ST_TEX_0_R, "R200_SE_VTX_ST_TEX_0_R" }, + { R200_SE_VTX_ST_TEX_0_Q, "R200_SE_VTX_ST_TEX_0_Q" }, + { R200_SE_VTX_ST_TEX_1_S, "R200_SE_VTX_ST_TEX_1_S" }, + { R200_SE_VTX_ST_TEX_1_T, "R200_SE_VTX_ST_TEX_1_T" }, + { R200_SE_VTX_ST_TEX_1_R, "R200_SE_VTX_ST_TEX_1_R" }, + { R200_SE_VTX_ST_TEX_1_Q, "R200_SE_VTX_ST_TEX_1_Q" }, + { R200_SE_VTX_ST_TEX_2_S, "R200_SE_VTX_ST_TEX_2_S" }, + { R200_SE_VTX_ST_TEX_2_T, "R200_SE_VTX_ST_TEX_2_T" }, + { R200_SE_VTX_ST_TEX_2_R, "R200_SE_VTX_ST_TEX_2_R" }, + { R200_SE_VTX_ST_TEX_2_Q, "R200_SE_VTX_ST_TEX_2_Q" }, + { R200_SE_VTX_ST_TEX_3_S, "R200_SE_VTX_ST_TEX_3_S" }, + { R200_SE_VTX_ST_TEX_3_T, "R200_SE_VTX_ST_TEX_3_T" }, + { R200_SE_VTX_ST_TEX_3_R, "R200_SE_VTX_ST_TEX_3_R" }, + { R200_SE_VTX_ST_TEX_3_Q, "R200_SE_VTX_ST_TEX_3_Q" }, + { R200_SE_VTX_ST_TEX_4_S, "R200_SE_VTX_ST_TEX_4_S" }, + { R200_SE_VTX_ST_TEX_4_T, "R200_SE_VTX_ST_TEX_4_T" }, + { R200_SE_VTX_ST_TEX_4_R, "R200_SE_VTX_ST_TEX_4_R" }, + { R200_SE_VTX_ST_TEX_4_Q, "R200_SE_VTX_ST_TEX_4_Q" }, + { R200_SE_VTX_ST_TEX_5_S, "R200_SE_VTX_ST_TEX_5_S" }, + { R200_SE_VTX_ST_TEX_5_T, "R200_SE_VTX_ST_TEX_5_T" }, + { R200_SE_VTX_ST_TEX_5_R, "R200_SE_VTX_ST_TEX_5_R" }, + { R200_SE_VTX_ST_TEX_5_Q, "R200_SE_VTX_ST_TEX_5_Q" }, + { R200_SE_VTX_ST_PNT_SPRT_SZ, "R200_SE_VTX_ST_PNT_SPRT_SZ" }, + { R200_SE_VTX_ST_DISC_FOG, "R200_SE_VTX_ST_DISC_FOG" }, + { R200_SE_VTX_ST_SHININESS_0, "R200_SE_VTX_ST_SHININESS_0" }, + { R200_SE_VTX_ST_SHININESS_1, "R200_SE_VTX_ST_SHININESS_1" }, + { R200_SE_VTX_ST_BLND_WT_0, "R200_SE_VTX_ST_BLND_WT_0" }, + { R200_SE_VTX_ST_BLND_WT_1, "R200_SE_VTX_ST_BLND_WT_1" }, + { R200_SE_VTX_ST_BLND_WT_2, "R200_SE_VTX_ST_BLND_WT_2" }, + { R200_SE_VTX_ST_BLND_WT_3, "R200_SE_VTX_ST_BLND_WT_3" }, + { R200_SE_VTX_ST_POS_1_X, "R200_SE_VTX_ST_POS_1_X" }, + { R200_SE_VTX_ST_POS_1_Y, "R200_SE_VTX_ST_POS_1_Y" }, + { R200_SE_VTX_ST_POS_1_Z, "R200_SE_VTX_ST_POS_1_Z" }, + { R200_SE_VTX_ST_POS_1_W, "R200_SE_VTX_ST_POS_1_W" }, + { R200_SE_VTX_ST_NORM_1_X, "R200_SE_VTX_ST_NORM_1_X" }, + { R200_SE_VTX_ST_NORM_1_Y, "R200_SE_VTX_ST_NORM_1_Y" }, + { R200_SE_VTX_ST_NORM_1_Z, "R200_SE_VTX_ST_NORM_1_Z" }, + { R200_SE_VTX_ST_USR_CLR_0_R, "R200_SE_VTX_ST_USR_CLR_0_R" }, + { R200_SE_VTX_ST_USR_CLR_0_G, "R200_SE_VTX_ST_USR_CLR_0_G" }, + { R200_SE_VTX_ST_USR_CLR_0_B, "R200_SE_VTX_ST_USR_CLR_0_B" }, + { R200_SE_VTX_ST_USR_CLR_0_A, "R200_SE_VTX_ST_USR_CLR_0_A" }, + { R200_SE_VTX_ST_USR_CLR_1_R, "R200_SE_VTX_ST_USR_CLR_1_R" }, + { R200_SE_VTX_ST_USR_CLR_1_G, "R200_SE_VTX_ST_USR_CLR_1_G" }, + { R200_SE_VTX_ST_USR_CLR_1_B, "R200_SE_VTX_ST_USR_CLR_1_B" }, + { R200_SE_VTX_ST_USR_CLR_1_A, "R200_SE_VTX_ST_USR_CLR_1_A" }, + { R200_SE_VTX_ST_CLR_0_PKD, "R200_SE_VTX_ST_CLR_0_PKD" }, + { R200_SE_VTX_ST_CLR_1_PKD, "R200_SE_VTX_ST_CLR_1_PKD" }, + { R200_SE_VTX_ST_CLR_2_PKD, "R200_SE_VTX_ST_CLR_2_PKD" }, + { R200_SE_VTX_ST_CLR_3_PKD, "R200_SE_VTX_ST_CLR_3_PKD" }, + { R200_SE_VTX_ST_CLR_4_PKD, "R200_SE_VTX_ST_CLR_4_PKD" }, + { R200_SE_VTX_ST_CLR_5_PKD, "R200_SE_VTX_ST_CLR_5_PKD" }, + { R200_SE_VTX_ST_CLR_6_PKD, "R200_SE_VTX_ST_CLR_6_PKD" }, + { R200_SE_VTX_ST_CLR_7_PKD, "R200_SE_VTX_ST_CLR_7_PKD" }, + { R200_SE_VTX_ST_POS_0_X_2, "R200_SE_VTX_ST_POS_0_X_2" }, + { R200_SE_VTX_ST_POS_0_Y_2, "R200_SE_VTX_ST_POS_0_Y_2" }, + { R200_SE_VTX_ST_PAR_CLR_LD, "R200_SE_VTX_ST_PAR_CLR_LD" }, + { R200_SE_VTX_ST_USR_CLR_PKD, "R200_SE_VTX_ST_USR_CLR_PKD" }, + { R200_SE_VTX_ST_POS_0_X_3, "R200_SE_VTX_ST_POS_0_X_3" }, + { R200_SE_VTX_ST_POS_0_Y_3, "R200_SE_VTX_ST_POS_0_Y_3" }, + { R200_SE_VTX_ST_POS_0_Z_3, "R200_SE_VTX_ST_POS_0_Z_3" }, + { R200_SE_VTX_ST_END_OF_PKT, "R200_SE_VTX_ST_END_OF_PKT" }, + { R200_RE_POINTSIZE, "R200_RE_POINTSIZE" }, + { R200_RE_TOP_LEFT, "R200_RE_TOP_LEFT" }, + { R200_RE_AUX_SCISSOR_CNTL, "R200_RE_AUX_SCISSOR_CNTL" }, + { R200_PP_TXFILTER_0, "R200_PP_TXFILTER_0" }, + { R200_PP_TXFORMAT_0, "R200_PP_TXFORMAT_0" }, + { R200_PP_TXSIZE_0, "R200_PP_TXSIZE_0" }, + { R200_PP_TXFORMAT_X_0, "R200_PP_TXFORMAT_X_0" }, + { R200_PP_TXPITCH_0, "R200_PP_TXPITCH_0" }, + { R200_PP_BORDER_COLOR_0, "R200_PP_BORDER_COLOR_0" }, + { R200_PP_CUBIC_FACES_0, "R200_PP_CUBIC_FACES_0" }, + { R200_PP_TXFILTER_1, "R200_PP_TXFILTER_1" }, + { R200_PP_TXFORMAT_1, "R200_PP_TXFORMAT_1" }, + { R200_PP_TXSIZE_1, "R200_PP_TXSIZE_1" }, + { R200_PP_TXFORMAT_X_1, "R200_PP_TXFORMAT_X_1" }, + { R200_PP_TXPITCH_1, "R200_PP_TXPITCH_1" }, + { R200_PP_BORDER_COLOR_1, "R200_PP_BORDER_COLOR_1" }, + { R200_PP_CUBIC_FACES_1, "R200_PP_CUBIC_FACES_1" }, + { R200_PP_TXFILTER_2, "R200_PP_TXFILTER_2" }, + { R200_PP_TXFORMAT_2, "R200_PP_TXFORMAT_2" }, + { R200_PP_TXSIZE_2, "R200_PP_TXSIZE_2" }, + { R200_PP_TXFORMAT_X_2, "R200_PP_TXFORMAT_X_2" }, + { R200_PP_TXPITCH_2, "R200_PP_TXPITCH_2" }, + { R200_PP_BORDER_COLOR_2, "R200_PP_BORDER_COLOR_2" }, + { R200_PP_CUBIC_FACES_2, "R200_PP_CUBIC_FACES_2" }, + { R200_PP_TXFILTER_3, "R200_PP_TXFILTER_3" }, + { R200_PP_TXFORMAT_3, "R200_PP_TXFORMAT_3" }, + { R200_PP_TXSIZE_3, "R200_PP_TXSIZE_3" }, + { R200_PP_TXFORMAT_X_3, "R200_PP_TXFORMAT_X_3" }, + { R200_PP_TXPITCH_3, "R200_PP_TXPITCH_3" }, + { R200_PP_BORDER_COLOR_3, "R200_PP_BORDER_COLOR_3" }, + { R200_PP_CUBIC_FACES_3, "R200_PP_CUBIC_FACES_3" }, + { R200_PP_TXFILTER_4, "R200_PP_TXFILTER_4" }, + { R200_PP_TXFORMAT_4, "R200_PP_TXFORMAT_4" }, + { R200_PP_TXSIZE_4, "R200_PP_TXSIZE_4" }, + { R200_PP_TXFORMAT_X_4, "R200_PP_TXFORMAT_X_4" }, + { R200_PP_TXPITCH_4, "R200_PP_TXPITCH_4" }, + { R200_PP_BORDER_COLOR_4, "R200_PP_BORDER_COLOR_4" }, + { R200_PP_CUBIC_FACES_4, "R200_PP_CUBIC_FACES_4" }, + { R200_PP_TXFILTER_5, "R200_PP_TXFILTER_5" }, + { R200_PP_TXFORMAT_5, "R200_PP_TXFORMAT_5" }, + { R200_PP_TXSIZE_5, "R200_PP_TXSIZE_5" }, + { R200_PP_TXFORMAT_X_5, "R200_PP_TXFORMAT_X_5" }, + { R200_PP_TXPITCH_5, "R200_PP_TXPITCH_5" }, + { R200_PP_BORDER_COLOR_5, "R200_PP_BORDER_COLOR_5" }, + { R200_PP_CUBIC_FACES_5, "R200_PP_CUBIC_FACES_5" }, + { R200_PP_TXOFFSET_0, "R200_PP_TXOFFSET_0" }, + { R200_PP_CUBIC_OFFSET_F1_0, "R200_PP_CUBIC_OFFSET_F1_0" }, + { R200_PP_CUBIC_OFFSET_F2_0, "R200_PP_CUBIC_OFFSET_F2_0" }, + { R200_PP_CUBIC_OFFSET_F3_0, "R200_PP_CUBIC_OFFSET_F3_0" }, + { R200_PP_CUBIC_OFFSET_F4_0, "R200_PP_CUBIC_OFFSET_F4_0" }, + { R200_PP_CUBIC_OFFSET_F5_0, "R200_PP_CUBIC_OFFSET_F5_0" }, + { R200_PP_TXOFFSET_1, "R200_PP_TXOFFSET_1" }, + { R200_PP_CUBIC_OFFSET_F1_1, "R200_PP_CUBIC_OFFSET_F1_1" }, + { R200_PP_CUBIC_OFFSET_F2_1, "R200_PP_CUBIC_OFFSET_F2_1" }, + { R200_PP_CUBIC_OFFSET_F3_1, "R200_PP_CUBIC_OFFSET_F3_1" }, + { R200_PP_CUBIC_OFFSET_F4_1, "R200_PP_CUBIC_OFFSET_F4_1" }, + { R200_PP_CUBIC_OFFSET_F5_1, "R200_PP_CUBIC_OFFSET_F5_1" }, + { R200_PP_TXOFFSET_2, "R200_PP_TXOFFSET_2" }, + { R200_PP_CUBIC_OFFSET_F1_2, "R200_PP_CUBIC_OFFSET_F1_2" }, + { R200_PP_CUBIC_OFFSET_F2_2, "R200_PP_CUBIC_OFFSET_F2_2" }, + { R200_PP_CUBIC_OFFSET_F3_2, "R200_PP_CUBIC_OFFSET_F3_2" }, + { R200_PP_CUBIC_OFFSET_F4_2, "R200_PP_CUBIC_OFFSET_F4_2" }, + { R200_PP_CUBIC_OFFSET_F5_2, "R200_PP_CUBIC_OFFSET_F5_2" }, + { R200_PP_TXOFFSET_3, "R200_PP_TXOFFSET_3" }, + { R200_PP_CUBIC_OFFSET_F1_3, "R200_PP_CUBIC_OFFSET_F1_3" }, + { R200_PP_CUBIC_OFFSET_F2_3, "R200_PP_CUBIC_OFFSET_F2_3" }, + { R200_PP_CUBIC_OFFSET_F3_3, "R200_PP_CUBIC_OFFSET_F3_3" }, + { R200_PP_CUBIC_OFFSET_F4_3, "R200_PP_CUBIC_OFFSET_F4_3" }, + { R200_PP_CUBIC_OFFSET_F5_3, "R200_PP_CUBIC_OFFSET_F5_3" }, + { R200_PP_TXOFFSET_4, "R200_PP_TXOFFSET_4" }, + { R200_PP_CUBIC_OFFSET_F1_4, "R200_PP_CUBIC_OFFSET_F1_4" }, + { R200_PP_CUBIC_OFFSET_F2_4, "R200_PP_CUBIC_OFFSET_F2_4" }, + { R200_PP_CUBIC_OFFSET_F3_4, "R200_PP_CUBIC_OFFSET_F3_4" }, + { R200_PP_CUBIC_OFFSET_F4_4, "R200_PP_CUBIC_OFFSET_F4_4" }, + { R200_PP_CUBIC_OFFSET_F5_4, "R200_PP_CUBIC_OFFSET_F5_4" }, + { R200_PP_TXOFFSET_5, "R200_PP_TXOFFSET_5" }, + { R200_PP_CUBIC_OFFSET_F1_5, "R200_PP_CUBIC_OFFSET_F1_5" }, + { R200_PP_CUBIC_OFFSET_F2_5, "R200_PP_CUBIC_OFFSET_F2_5" }, + { R200_PP_CUBIC_OFFSET_F3_5, "R200_PP_CUBIC_OFFSET_F3_5" }, + { R200_PP_CUBIC_OFFSET_F4_5, "R200_PP_CUBIC_OFFSET_F4_5" }, + { R200_PP_CUBIC_OFFSET_F5_5, "R200_PP_CUBIC_OFFSET_F5_5" }, + { R200_PP_TAM_DEBUG3, "R200_PP_TAM_DEBUG3" }, + { R200_PP_TFACTOR_0, "R200_PP_TFACTOR_0" }, + { R200_PP_TFACTOR_1, "R200_PP_TFACTOR_1" }, + { R200_PP_TFACTOR_2, "R200_PP_TFACTOR_2" }, + { R200_PP_TFACTOR_3, "R200_PP_TFACTOR_3" }, + { R200_PP_TFACTOR_4, "R200_PP_TFACTOR_4" }, + { R200_PP_TFACTOR_5, "R200_PP_TFACTOR_5" }, + { R200_PP_TXCBLEND_0, "R200_PP_TXCBLEND_0" }, + { R200_PP_TXCBLEND2_0, "R200_PP_TXCBLEND2_0" }, + { R200_PP_TXABLEND_0, "R200_PP_TXABLEND_0" }, + { R200_PP_TXABLEND2_0, "R200_PP_TXABLEND2_0" }, + { R200_PP_TXCBLEND_1, "R200_PP_TXCBLEND_1" }, + { R200_PP_TXCBLEND2_1, "R200_PP_TXCBLEND2_1" }, + { R200_PP_TXABLEND_1, "R200_PP_TXABLEND_1" }, + { R200_PP_TXABLEND2_1, "R200_PP_TXABLEND2_1" }, + { R200_PP_TXCBLEND_2, "R200_PP_TXCBLEND_2" }, + { R200_PP_TXCBLEND2_2, "R200_PP_TXCBLEND2_2" }, + { R200_PP_TXABLEND_2, "R200_PP_TXABLEND_2" }, + { R200_PP_TXABLEND2_2, "R200_PP_TXABLEND2_2" }, + { R200_PP_TXCBLEND_3, "R200_PP_TXCBLEND_3" }, + { R200_PP_TXCBLEND2_3, "R200_PP_TXCBLEND2_3" }, + { R200_PP_TXABLEND_3, "R200_PP_TXABLEND_3" }, + { R200_PP_TXABLEND2_3, "R200_PP_TXABLEND2_3" }, + { R200_PP_TXCBLEND_4, "R200_PP_TXCBLEND_4" }, + { R200_PP_TXCBLEND2_4, "R200_PP_TXCBLEND2_4" }, + { R200_PP_TXABLEND_4, "R200_PP_TXABLEND_4" }, + { R200_PP_TXABLEND2_4, "R200_PP_TXABLEND2_4" }, + { R200_PP_TXCBLEND_5, "R200_PP_TXCBLEND_5" }, + { R200_PP_TXCBLEND2_5, "R200_PP_TXCBLEND2_5" }, + { R200_PP_TXABLEND_5, "R200_PP_TXABLEND_5" }, + { R200_PP_TXABLEND2_5, "R200_PP_TXABLEND2_5" }, + { R200_PP_TXCBLEND_6, "R200_PP_TXCBLEND_6" }, + { R200_PP_TXCBLEND2_6, "R200_PP_TXCBLEND2_6" }, + { R200_PP_TXABLEND_6, "R200_PP_TXABLEND_6" }, + { R200_PP_TXABLEND2_6, "R200_PP_TXABLEND2_6" }, + { R200_PP_TXCBLEND_7, "R200_PP_TXCBLEND_7" }, + { R200_PP_TXCBLEND2_7, "R200_PP_TXCBLEND2_7" }, + { R200_PP_TXABLEND_7, "R200_PP_TXABLEND_7" }, + { R200_PP_TXABLEND2_7, "R200_PP_TXABLEND2_7" }, + { R200_RB3D_ABLENDCNTL, "R200_RB3D_ABLENDCNTL" }, + { R200_RB3D_CBLENDCNTL, "R200_RB3D_CBLENDCNTL" }, + { R200_SE_TCL_OUTPUT_VTX_COMP_SEL, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" }, + { R200_PP_CNTL_X, "R200_PP_CNTL_X" }, + { R200_SE_VAP_CNTL_STATUS, "R200_SE_VAP_CNTL_STATUS" }, + { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" }, + { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_1, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_1" }, + { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_2, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_2" }, + { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_3, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_3" }, +}; + +static struct reg_names scalar_names[] = { + { R200_SS_LIGHT_DCD_ADDR, "R200_SS_LIGHT_DCD_ADDR" }, + { R200_SS_LIGHT_DCM_ADDR, "R200_SS_LIGHT_DCM_ADDR" }, + { R200_SS_LIGHT_SPOT_EXPONENT_ADDR, "R200_SS_LIGHT_SPOT_EXPONENT_ADDR" }, + { R200_SS_LIGHT_SPOT_CUTOFF_ADDR, "R200_SS_LIGHT_SPOT_CUTOFF_ADDR" }, + { R200_SS_LIGHT_SPECULAR_THRESH_ADDR, "R200_SS_LIGHT_SPECULAR_THRESH_ADDR" }, + { R200_SS_LIGHT_RANGE_CUTOFF_SQRD, "R200_SS_LIGHT_RANGE_CUTOFF_SQRD" }, + { R200_SS_LIGHT_RANGE_ATT_CONST, "R200_SS_LIGHT_RANGE_ATT_CONST" }, + { R200_SS_VERT_GUARD_CLIP_ADJ_ADDR, "R200_SS_VERT_GUARD_CLIP_ADJ_ADDR" }, + { R200_SS_VERT_GUARD_DISCARD_ADJ_ADDR, "R200_SS_VERT_GUARD_DISCARD_ADJ_ADDR" }, + { R200_SS_HORZ_GUARD_CLIP_ADJ_ADDR, "R200_SS_HORZ_GUARD_CLIP_ADJ_ADDR" }, + { R200_SS_HORZ_GUARD_DISCARD_ADJ_ADDR, "R200_SS_HORZ_GUARD_DISCARD_ADJ_ADDR" }, + { R200_SS_MAT_0_SHININESS, "R200_SS_MAT_0_SHININESS" }, + { R200_SS_MAT_1_SHININESS, "R200_SS_MAT_1_SHININESS" }, + { 1000, "" }, +}; + +/* Puff these out to make them look like normal (dword) registers. + */ +static struct reg_names vector_names[] = { + { 0, "start" }, + { R200_VS_LIGHT_AMBIENT_ADDR, "R200_VS_LIGHT_AMBIENT_ADDR" }, + { R200_VS_LIGHT_DIFFUSE_ADDR, "R200_VS_LIGHT_DIFFUSE_ADDR" }, + { R200_VS_LIGHT_SPECULAR_ADDR, "R200_VS_LIGHT_SPECULAR_ADDR" }, + { R200_VS_LIGHT_DIRPOS_ADDR, "R200_VS_LIGHT_DIRPOS_ADDR" }, + { R200_VS_LIGHT_HWVSPOT_ADDR, "R200_VS_LIGHT_HWVSPOT_ADDR" }, + { R200_VS_LIGHT_ATTENUATION_ADDR, "R200_VS_LIGHT_ATTENUATION_ADDR" }, + { R200_VS_SPOT_DUAL_CONE, "R200_VS_SPOT_DUAL_CONE" }, + { R200_VS_GLOBAL_AMBIENT_ADDR, "R200_VS_GLOBAL_AMBIENT_ADDR" }, + { R200_VS_FOG_PARAM_ADDR, "R200_VS_FOG_PARAM_ADDR" }, + { R200_VS_EYE_VECTOR_ADDR, "R200_VS_EYE_VECTOR_ADDR" }, + { R200_VS_UCP_ADDR, "R200_VS_UCP_ADDR" }, + { R200_VS_PNT_SPRITE_VPORT_SCALE, "R200_VS_PNT_SPRITE_VPORT_SCALE" }, + { R200_VS_MATRIX_0_MV, "R200_VS_MATRIX_0_MV" }, + { R200_VS_MATRIX_1_INV_MV, "R200_VS_MATRIX_1_INV_MV" }, + { R200_VS_MATRIX_2_MVP, "R200_VS_MATRIX_2_MVP" }, + { R200_VS_MATRIX_3_TEX0, "R200_VS_MATRIX_3_TEX0" }, + { R200_VS_MATRIX_4_TEX1, "R200_VS_MATRIX_4_TEX1" }, + { R200_VS_MATRIX_5_TEX2, "R200_VS_MATRIX_5_TEX2" }, + { R200_VS_MATRIX_6_TEX3, "R200_VS_MATRIX_6_TEX3" }, + { R200_VS_MATRIX_7_TEX4, "R200_VS_MATRIX_7_TEX4" }, + { R200_VS_MATRIX_8_TEX5, "R200_VS_MATRIX_8_TEX5" }, + { R200_VS_MAT_0_EMISS, "R200_VS_MAT_0_EMISS" }, + { R200_VS_MAT_0_AMB, "R200_VS_MAT_0_AMB" }, + { R200_VS_MAT_0_DIF, "R200_VS_MAT_0_DIF" }, + { R200_VS_MAT_0_SPEC, "R200_VS_MAT_0_SPEC" }, + { R200_VS_MAT_1_EMISS, "R200_VS_MAT_1_EMISS" }, + { R200_VS_MAT_1_AMB, "R200_VS_MAT_1_AMB" }, + { R200_VS_MAT_1_DIF, "R200_VS_MAT_1_DIF" }, + { R200_VS_MAT_1_SPEC, "R200_VS_MAT_1_SPEC" }, + { R200_VS_EYE2CLIP_MTX, "R200_VS_EYE2CLIP_MTX" }, + { R200_VS_PNT_SPRITE_ATT_CONST, "R200_VS_PNT_SPRITE_ATT_CONST" }, + { R200_VS_PNT_SPRITE_EYE_IN_MODEL, "R200_VS_PNT_SPRITE_EYE_IN_MODEL" }, + { R200_VS_PNT_SPRITE_CLAMP, "R200_VS_PNT_SPRITE_CLAMP" }, + { R200_VS_MAX, "R200_VS_MAX" }, + { 1000, "" }, +}; + +union fi { float f; int i; }; + +#define ISVEC 1 +#define ISFLOAT 2 +#define TOUCHED 4 + +struct reg { + int idx; + struct reg_names *closest; + int flags; + union fi current; + union fi *values; + int nvalues; + int nalloc; + float vmin, vmax; +}; + + +static struct reg regs[Elements(reg_names)+1]; +static struct reg scalars[512+1]; +static struct reg vectors[512*4+1]; + +static int total, total_changed, bufs; + +static void init_regs( void ) +{ + struct reg_names *tmp; + int i; + + for (i = 0 ; i < Elements(regs) ; i++) { + regs[i].idx = reg_names[i].idx; + regs[i].closest = ®_names[i]; + regs[i].flags = 0; + } + + for (i = 0, tmp = scalar_names ; i < Elements(scalars) ; i++) { + if (tmp[1].idx == i) tmp++; + scalars[i].idx = i; + scalars[i].closest = tmp; + scalars[i].flags = ISFLOAT; + } + + for (i = 0, tmp = vector_names ; i < Elements(vectors) ; i++) { + if (tmp[1].idx*4 == i) tmp++; + vectors[i].idx = i; + vectors[i].closest = tmp; + vectors[i].flags = ISFLOAT|ISVEC; + } + + regs[Elements(regs)-1].idx = -1; + scalars[Elements(scalars)-1].idx = -1; + vectors[Elements(vectors)-1].idx = -1; +} + +static int find_or_add_value( struct reg *reg, int val ) +{ + int j; + + for ( j = 0 ; j < reg->nvalues ; j++) + if ( val == reg->values[j].i ) + return 1; + + if (j == reg->nalloc) { + reg->nalloc += 5; + reg->nalloc *= 2; + reg->values = (union fi *) realloc( reg->values, + reg->nalloc * sizeof(union fi) ); + } + + reg->values[reg->nvalues++].i = val; + return 0; +} + +static struct reg *lookup_reg( struct reg *tab, int reg ) +{ + int i; + + for (i = 0 ; tab[i].idx != -1 ; i++) { + if (tab[i].idx == reg) + return &tab[i]; + } + + fprintf(stderr, "*** unknown reg 0x%x\n", reg); + return 0; +} + + +static const char *get_reg_name( struct reg *reg ) +{ + static char tmp[80]; + + if (reg->idx == reg->closest->idx) + return reg->closest->name; + + + if (reg->flags & ISVEC) { + if (reg->idx/4 != reg->closest->idx) + sprintf(tmp, "%s+%d[%d]", + reg->closest->name, + (reg->idx/4) - reg->closest->idx, + reg->idx%4); + else + sprintf(tmp, "%s[%d]", reg->closest->name, reg->idx%4); + } + else { + if (reg->idx != reg->closest->idx) + sprintf(tmp, "%s+%d", reg->closest->name, reg->idx - reg->closest->idx); + else + sprintf(tmp, "%s", reg->closest->name); + } + + return tmp; +} + +static int print_int_reg_assignment( struct reg *reg, int data ) +{ + int changed = (reg->current.i != data); + int ever_seen = find_or_add_value( reg, data ); + + if (VERBOSE || (NORMAL && (changed || !ever_seen))) + fprintf(stderr, " %s <-- 0x%x", get_reg_name(reg), data); + + if (NORMAL) { + if (!ever_seen) + fprintf(stderr, " *** BRAND NEW VALUE"); + else if (changed) + fprintf(stderr, " *** CHANGED"); + } + + reg->current.i = data; + + if (VERBOSE || (NORMAL && (changed || !ever_seen))) + fprintf(stderr, "\n"); + + return changed; +} + + +static int print_float_reg_assignment( struct reg *reg, float data ) +{ + int changed = (reg->current.f != data); + int newmin = (data < reg->vmin); + int newmax = (data > reg->vmax); + + if (VERBOSE || (NORMAL && (newmin || newmax || changed))) + fprintf(stderr, " %s <-- %.3f", get_reg_name(reg), data); + + if (NORMAL) { + if (newmin) { + fprintf(stderr, " *** NEW MIN (prev %.3f)", reg->vmin); + reg->vmin = data; + } + else if (newmax) { + fprintf(stderr, " *** NEW MAX (prev %.3f)", reg->vmax); + reg->vmax = data; + } + else if (changed) { + fprintf(stderr, " *** CHANGED"); + } + } + + reg->current.f = data; + + if (VERBOSE || (NORMAL && (newmin || newmax || changed))) + fprintf(stderr, "\n"); + + return changed; +} + +static int print_reg_assignment( struct reg *reg, int data ) +{ + reg->flags |= TOUCHED; + if (reg->flags & ISFLOAT) + return print_float_reg_assignment( reg, *(float *)&data ); + else + return print_int_reg_assignment( reg, data ); +} + +static void print_reg( struct reg *reg ) +{ + if (reg->flags & TOUCHED) { + if (reg->flags & ISFLOAT) { + fprintf(stderr, " %s == %f\n", get_reg_name(reg), reg->current.f); + } else { + fprintf(stderr, " %s == 0x%x\n", get_reg_name(reg), reg->current.i); + } + } +} + + +static void dump_state( void ) +{ + int i; + + for (i = 0 ; i < Elements(regs) ; i++) + print_reg( ®s[i] ); + + for (i = 0 ; i < Elements(scalars) ; i++) + print_reg( &scalars[i] ); + + for (i = 0 ; i < Elements(vectors) ; i++) + print_reg( &vectors[i] ); +} + + + +static int radeon_emit_packets( + drmRadeonCmdHeader header, + drmRadeonCmdBuffer *cmdbuf ) +{ + int id = (int)header.packet.packet_id; + int sz = packet[id].len; + int *data = (int *)cmdbuf->buf; + int i; + + if (sz * sizeof(int) > cmdbuf->bufsz) { + fprintf(stderr, "Packet overflows cmdbuf\n"); + return -EINVAL; + } + + if (!packet[id].name) { + fprintf(stderr, "*** Unknown packet 0 nr %d\n", id ); + return -EINVAL; + } + + + if (VERBOSE) + fprintf(stderr, "Packet 0 reg %s nr %d\n", packet[id].name, sz ); + + for ( i = 0 ; i < sz ; i++) { + struct reg *reg = lookup_reg( regs, packet[id].start + i*4 ); + if (print_reg_assignment( reg, data[i] )) + total_changed++; + total++; + } + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + + +static int radeon_emit_scalars( + drmRadeonCmdHeader header, + drmRadeonCmdBuffer *cmdbuf ) +{ + int sz = header.scalars.count; + int *data = (int *)cmdbuf->buf; + int start = header.scalars.offset; + int stride = header.scalars.stride; + int i; + + if (VERBOSE) + fprintf(stderr, "emit scalars, start %d stride %d nr %d (end %d)\n", + start, stride, sz, start + stride * sz); + + + for (i = 0 ; i < sz ; i++, start += stride) { + struct reg *reg = lookup_reg( scalars, start ); + if (print_reg_assignment( reg, data[i] )) + total_changed++; + total++; + } + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + + +static int radeon_emit_scalars2( + drmRadeonCmdHeader header, + drmRadeonCmdBuffer *cmdbuf ) +{ + int sz = header.scalars.count; + int *data = (int *)cmdbuf->buf; + int start = header.scalars.offset + 0x100; + int stride = header.scalars.stride; + int i; + + if (VERBOSE) + fprintf(stderr, "emit scalars2, start %d stride %d nr %d (end %d)\n", + start, stride, sz, start + stride * sz); + + if (start + stride * sz > 257) { + fprintf(stderr, "emit scalars OVERFLOW %d/%d/%d\n", start, stride, sz); + return -1; + } + + for (i = 0 ; i < sz ; i++, start += stride) { + struct reg *reg = lookup_reg( scalars, start ); + if (print_reg_assignment( reg, data[i] )) + total_changed++; + total++; + } + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +/* Check: inf/nan/extreme-size? + * Check: table start, end, nr, etc. + */ +static int radeon_emit_vectors( + drmRadeonCmdHeader header, + drmRadeonCmdBuffer *cmdbuf ) +{ + int sz = header.vectors.count; + int *data = (int *)cmdbuf->buf; + int start = header.vectors.offset; + int stride = header.vectors.stride; + int i,j; + + if (VERBOSE) + fprintf(stderr, "emit vectors, start %d stride %d nr %d (end %d) (0x%x)\n", + start, stride, sz, start + stride * sz, header.i); + +/* if (start + stride * (sz/4) > 128) { */ +/* fprintf(stderr, "emit vectors OVERFLOW %d/%d/%d\n", start, stride, sz); */ +/* return -1; */ +/* } */ + + for (i = 0 ; i < sz ; start += stride) { + int changed = 0; + for (j = 0 ; j < 4 ; i++,j++) { + struct reg *reg = lookup_reg( vectors, start*4+j ); + if (print_reg_assignment( reg, data[i] )) + changed = 1; + } + if (changed) + total_changed += 4; + total += 4; + } + + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +#if 0 +static int print_vertex_format( int vfmt ) +{ + if (NORMAL) { + fprintf(stderr, " %s(%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + "vertex format", + vfmt, + "xy,", + (vfmt & R200_VTX_Z0) ? "z," : "", + (vfmt & R200_VTX_W0) ? "w0," : "", + (vfmt & R200_VTX_FPCOLOR) ? "fpcolor," : "", + (vfmt & R200_VTX_FPALPHA) ? "fpalpha," : "", + (vfmt & R200_VTX_PKCOLOR) ? "pkcolor," : "", + (vfmt & R200_VTX_FPSPEC) ? "fpspec," : "", + (vfmt & R200_VTX_FPFOG) ? "fpfog," : "", + (vfmt & R200_VTX_PKSPEC) ? "pkspec," : "", + (vfmt & R200_VTX_ST0) ? "st0," : "", + (vfmt & R200_VTX_ST1) ? "st1," : "", + (vfmt & R200_VTX_Q1) ? "q1," : "", + (vfmt & R200_VTX_ST2) ? "st2," : "", + (vfmt & R200_VTX_Q2) ? "q2," : "", + (vfmt & R200_VTX_ST3) ? "st3," : "", + (vfmt & R200_VTX_Q3) ? "q3," : "", + (vfmt & R200_VTX_Q0) ? "q0," : "", + (vfmt & R200_VTX_N0) ? "n0," : "", + (vfmt & R200_VTX_XY1) ? "xy1," : "", + (vfmt & R200_VTX_Z1) ? "z1," : "", + (vfmt & R200_VTX_W1) ? "w1," : "", + (vfmt & R200_VTX_N1) ? "n1," : ""); + + + if (!find_or_add_value( &others[V_VTXFMT], vfmt )) + fprintf(stderr, " *** NEW VALUE"); + + fprintf(stderr, "\n"); + } + + return 0; +} +#endif + +static char *primname[0x10] = { + "NONE", + "POINTS", + "LINES", + "LINE_STRIP", + "TRIANGLES", + "TRIANGLE_FAN", + "TRIANGLE_STRIP", + "RECT_LIST", + 0, + "3VRT_POINTS", + "3VRT_LINES", + "POINT_SPRITES", + "LINE_LOOP", + "QUADS", + "QUAD_STRIP", + "POLYGON", +}; + +static int print_prim_and_flags( int prim ) +{ + int numverts; + + if (NORMAL) + fprintf(stderr, " %s(%x): %s%s%s%s%s%s\n", + "prim flags", + prim, + ((prim & 0x30) == R200_VF_PRIM_WALK_IND) ? "IND," : "", + ((prim & 0x30) == R200_VF_PRIM_WALK_LIST) ? "LIST," : "", + ((prim & 0x30) == R200_VF_PRIM_WALK_RING) ? "RING," : "", + (prim & R200_VF_COLOR_ORDER_RGBA) ? "RGBA," : "BGRA, ", + (prim & R200_VF_INDEX_SZ_4) ? "INDX-32," : "", + (prim & R200_VF_TCL_OUTPUT_VTX_ENABLE) ? "TCL_OUT_VTX," : ""); + + numverts = prim>>16; + + if (NORMAL) + fprintf(stderr, " prim: %s numverts %d\n", primname[prim&0xf], numverts); + + switch (prim & 0xf) { + case R200_VF_PRIM_NONE: + case R200_VF_PRIM_POINTS: + if (numverts < 1) { + fprintf(stderr, "Bad nr verts for line %d\n", numverts); + return -1; + } + break; + case R200_VF_PRIM_LINES: + case R200_VF_PRIM_POINT_SPRITES: + if ((numverts & 1) || numverts == 0) { + fprintf(stderr, "Bad nr verts for line %d\n", numverts); + return -1; + } + break; + case R200_VF_PRIM_LINE_STRIP: + case R200_VF_PRIM_LINE_LOOP: + if (numverts < 2) { + fprintf(stderr, "Bad nr verts for line_strip %d\n", numverts); + return -1; + } + break; + case R200_VF_PRIM_TRIANGLES: + case R200_VF_PRIM_3VRT_POINTS: + case R200_VF_PRIM_3VRT_LINES: + case R200_VF_PRIM_RECT_LIST: + if (numverts % 3 || numverts == 0) { + fprintf(stderr, "Bad nr verts for tri %d\n", numverts); + return -1; + } + break; + case R200_VF_PRIM_TRIANGLE_FAN: + case R200_VF_PRIM_TRIANGLE_STRIP: + case R200_VF_PRIM_POLYGON: + if (numverts < 3) { + fprintf(stderr, "Bad nr verts for strip/fan %d\n", numverts); + return -1; + } + break; + case R200_VF_PRIM_QUADS: + if (numverts % 4 || numverts == 0) { + fprintf(stderr, "Bad nr verts for quad %d\n", numverts); + return -1; + } + break; + case R200_VF_PRIM_QUAD_STRIP: + if (numverts % 2 || numverts < 4) { + fprintf(stderr, "Bad nr verts for quadstrip %d\n", numverts); + return -1; + } + break; + default: + fprintf(stderr, "Bad primitive\n"); + return -1; + } + return 0; +} + +/* build in knowledge about each packet type + */ +static int radeon_emit_packet3( drmRadeonCmdBuffer *cmdbuf ) +{ + int cmdsz; + int *cmd = (int *)cmdbuf->buf; + int *tmp; + int i, stride, size, start; + + cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); + + if ((cmd[0] & RADEON_CP_PACKET_MASK) != RADEON_CP_PACKET3 || + cmdsz * 4 > cmdbuf->bufsz || + cmdsz > RADEON_CP_PACKET_MAX_DWORDS) { + fprintf(stderr, "Bad packet\n"); + return -EINVAL; + } + + switch( cmd[0] & ~RADEON_CP_PACKET_COUNT_MASK ) { + case R200_CP_CMD_NOP: + if (NORMAL) + fprintf(stderr, "PACKET3_NOP, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_NEXT_CHAR: + if (NORMAL) + fprintf(stderr, "PACKET3_NEXT_CHAR, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_PLY_NEXTSCAN: + if (NORMAL) + fprintf(stderr, "PACKET3_PLY_NEXTSCAN, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_SET_SCISSORS: + if (NORMAL) + fprintf(stderr, "PACKET3_SET_SCISSORS, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_LOAD_MICROCODE: + if (NORMAL) + fprintf(stderr, "PACKET3_LOAD_MICROCODE, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_WAIT_FOR_IDLE: + if (NORMAL) + fprintf(stderr, "PACKET3_WAIT_FOR_IDLE, %d dwords\n", cmdsz); + break; + + case R200_CP_CMD_3D_DRAW_VBUF: + if (NORMAL) + fprintf(stderr, "PACKET3_3D_DRAW_VBUF, %d dwords\n", cmdsz); +/* print_vertex_format(cmd[1]); */ + if (print_prim_and_flags(cmd[2])) + return -EINVAL; + break; + + case R200_CP_CMD_3D_DRAW_IMMD: + if (NORMAL) + fprintf(stderr, "PACKET3_3D_DRAW_IMMD, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_3D_DRAW_INDX: { + int neltdwords; + if (NORMAL) + fprintf(stderr, "PACKET3_3D_DRAW_INDX, %d dwords\n", cmdsz); +/* print_vertex_format(cmd[1]); */ + if (print_prim_and_flags(cmd[2])) + return -EINVAL; + neltdwords = cmd[2]>>16; + neltdwords += neltdwords & 1; + neltdwords /= 2; + if (neltdwords + 3 != cmdsz) + fprintf(stderr, "Mismatch in DRAW_INDX, %d vs cmdsz %d\n", + neltdwords, cmdsz); + break; + } + case R200_CP_CMD_LOAD_PALETTE: + if (NORMAL) + fprintf(stderr, "PACKET3_LOAD_PALETTE, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_3D_LOAD_VBPNTR: + if (NORMAL) { + fprintf(stderr, "PACKET3_3D_LOAD_VBPNTR, %d dwords\n", cmdsz); + fprintf(stderr, " nr arrays: %d\n", cmd[1]); + } + + if (((cmd[1]/2)*3) + ((cmd[1]%2)*2) != cmdsz - 2) { + fprintf(stderr, " ****** MISMATCH %d/%d *******\n", + ((cmd[1]/2)*3) + ((cmd[1]%2)*2) + 2, cmdsz); + return -EINVAL; + } + + if (NORMAL) { + tmp = cmd+2; + for (i = 0 ; i < cmd[1] ; i++) { + if (i & 1) { + stride = (tmp[0]>>24) & 0xff; + size = (tmp[0]>>16) & 0xff; + start = tmp[2]; + tmp += 3; + } + else { + stride = (tmp[0]>>8) & 0xff; + size = (tmp[0]) & 0xff; + start = tmp[1]; + } + fprintf(stderr, " array %d: start 0x%x vsize %d vstride %d\n", + i, start, size, stride ); + } + } + break; + case R200_CP_CMD_PAINT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_PAINT, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_BITBLT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_BITBLT, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_SMALLTEXT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_SMALLTEXT, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_HOSTDATA_BLT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_HOSTDATA_BLT, %d dwords\n", + cmdsz); + break; + case R200_CP_CMD_POLYLINE: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_POLYLINE, %d dwords\n", cmdsz); + break; + case R200_CP_CMD_POLYSCANLINES: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_POLYSCANLINES, %d dwords\n", + cmdsz); + break; + case R200_CP_CMD_PAINT_MULTI: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_PAINT_MULTI, %d dwords\n", + cmdsz); + break; + case R200_CP_CMD_BITBLT_MULTI: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_BITBLT_MULTI, %d dwords\n", + cmdsz); + break; + case R200_CP_CMD_TRANS_BITBLT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_TRANS_BITBLT, %d dwords\n", + cmdsz); + break; + case R200_CP_CMD_3D_DRAW_VBUF_2: + if (NORMAL) + fprintf(stderr, "R200_CP_CMD_3D_DRAW_VBUF_2, %d dwords\n", + cmdsz); + if (print_prim_and_flags(cmd[1])) + return -EINVAL; + break; + case R200_CP_CMD_3D_DRAW_IMMD_2: + if (NORMAL) + fprintf(stderr, "R200_CP_CMD_3D_DRAW_IMMD_2, %d dwords\n", + cmdsz); + if (print_prim_and_flags(cmd[1])) + return -EINVAL; + break; + case R200_CP_CMD_3D_DRAW_INDX_2: + if (NORMAL) + fprintf(stderr, "R200_CP_CMD_3D_DRAW_INDX_2, %d dwords\n", + cmdsz); + if (print_prim_and_flags(cmd[1])) + return -EINVAL; + break; + default: + fprintf(stderr, "UNKNOWN PACKET, %d dwords\n", cmdsz); + break; + } + + cmdbuf->buf += cmdsz * 4; + cmdbuf->bufsz -= cmdsz * 4; + return 0; +} + + +/* Check cliprects for bounds, then pass on to above: + */ +static int radeon_emit_packet3_cliprect( drmRadeonCmdBuffer *cmdbuf ) +{ + XF86DRIClipRectRec *boxes = (XF86DRIClipRectRec *)cmdbuf->boxes; + int i = 0; + + if (VERBOSE && total_changed) { + dump_state(); + total_changed = 0; + } + + if (NORMAL) { + do { + if ( i < cmdbuf->nbox ) { + fprintf(stderr, "Emit box %d/%d %d,%d %d,%d\n", + i, cmdbuf->nbox, + boxes[i].x1, boxes[i].y1, boxes[i].x2, boxes[i].y2); + } + } while ( ++i < cmdbuf->nbox ); + } + + if (cmdbuf->nbox == 1) + cmdbuf->nbox = 0; + + return radeon_emit_packet3( cmdbuf ); +} + + +int r200SanityCmdBuffer( r200ContextPtr rmesa, + int nbox, + XF86DRIClipRectRec *boxes ) +{ + int idx; + drmRadeonCmdBuffer cmdbuf; + drmRadeonCmdHeader header; + static int inited = 0; + + if (!inited) { + init_regs(); + inited = 1; + } + + + cmdbuf.buf = rmesa->store.cmd_buf; + cmdbuf.bufsz = rmesa->store.cmd_used; + cmdbuf.boxes = (drmClipRect *)boxes; + cmdbuf.nbox = nbox; + + while ( cmdbuf.bufsz >= sizeof(header) ) { + + header.i = *(int *)cmdbuf.buf; + cmdbuf.buf += sizeof(header); + cmdbuf.bufsz -= sizeof(header); + + switch (header.header.cmd_type) { + case RADEON_CMD_PACKET: + if (radeon_emit_packets( header, &cmdbuf )) { + fprintf(stderr,"radeon_emit_packets failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_SCALARS: + if (radeon_emit_scalars( header, &cmdbuf )) { + fprintf(stderr,"radeon_emit_scalars failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_SCALARS2: + if (radeon_emit_scalars2( header, &cmdbuf )) { + fprintf(stderr,"radeon_emit_scalars failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_VECTORS: + if (radeon_emit_vectors( header, &cmdbuf )) { + fprintf(stderr,"radeon_emit_vectors failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_DMA_DISCARD: + idx = header.dma.buf_idx; + if (NORMAL) + fprintf(stderr, "RADEON_CMD_DMA_DISCARD buf %d\n", idx); + bufs++; + break; + + case RADEON_CMD_PACKET3: + if (radeon_emit_packet3( &cmdbuf )) { + fprintf(stderr,"radeon_emit_packet3 failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_PACKET3_CLIP: + if (radeon_emit_packet3_cliprect( &cmdbuf )) { + fprintf(stderr,"radeon_emit_packet3_clip failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_WAIT: + break; + + default: + fprintf(stderr,"bad cmd_type %d at %p\n", + header.header.cmd_type, + cmdbuf.buf - sizeof(header)); + return -EINVAL; + } + } + + if (0) + { + static int n = 0; + n++; + if (n == 10) { + fprintf(stderr, "Bufs %d Total emitted %d real changes %d (%.2f%%)\n", + bufs, + total, total_changed, + ((float)total_changed/(float)total*100.0)); + fprintf(stderr, "Total emitted per buf: %.2f\n", + (float)total/(float)bufs); + fprintf(stderr, "Real changes per buf: %.2f\n", + (float)total_changed/(float)bufs); + + bufs = n = total = total_changed = 0; + } + } + + fprintf(stderr, "leaving %s\n\n\n", __FUNCTION__); + + return 0; +} + + +/* Do the same job to a native command stream + * -- pull apart packets after they are built. + * -- understand SCALAR, VECTOR stores + * -- understand INDIRECT registers & trace down into indirect buffers. + */ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_sanity.h b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.h new file mode 100644 index 000000000..10260f211 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.h @@ -0,0 +1,8 @@ +#ifndef R200_SANITY_H +#define R200_SANITY_H + +extern int r200SanityCmdBuffer( r200ContextPtr rmesa, + int nbox, + XF86DRIClipRectRec *boxes ); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_screen.c b/xc/lib/GL/mesa/src/drv/r200/r200_screen.c new file mode 100644 index 000000000..dbaf40f78 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_screen.c @@ -0,0 +1,436 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_screen.c,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include <dlfcn.h> +#include <stdlib.h> + +#include "r200_screen.h" +#include "r200_context.h" +#include "r200_ioctl.h" + +#include "mem.h" +#include "context.h" + +#if 1 +/* Including xf86PciInfo.h introduces a bunch of errors... + */ +#define PCI_CHIP_R200_QD 0x5144 +#define PCI_CHIP_R200_QE 0x5145 +#define PCI_CHIP_R200_QF 0x5146 +#define PCI_CHIP_R200_QG 0x5147 +#define PCI_CHIP_R200_QY 0x5159 +#define PCI_CHIP_R200_QZ 0x515A +#define PCI_CHIP_R200_LW 0x4C57 +#define PCI_CHIP_R200_LY 0x4C59 +#define PCI_CHIP_R200_LZ 0x4C5A +#define PCI_CHIP_RV200_QW 0x5157 +#endif + +static r200ScreenPtr __r200Screen; + +/* Create the device specific screen private data struct. + */ +static r200ScreenPtr +r200CreateScreen( __DRIscreenPrivate *sPriv ) +{ + r200ScreenPtr r200Screen; + RADEONDRIPtr r200DRIPriv = (RADEONDRIPtr)sPriv->pDevPriv; + + /* Check the DRI version */ + { + int major, minor, patch; + if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { + if ( major != 4 || minor < 0 ) { + __driUtilMessage( "R200 DRI driver expected DRI version 4.0.x " + "but got version %d.%d.%d", + major, minor, patch ); + return NULL; + } + } + } + + /* Check that the DDX driver version is compatible */ + if ( sPriv->ddxMajor != 4 || + sPriv->ddxMinor < 0 ) { + __driUtilMessage( "R200 DRI driver expected DDX driver version 4.0.x " + "but got version %d.%d.%d", + sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); + return NULL; + } + + /* Check that the DRM driver version is compatible + * -- R200 support added at 1.5.0. + */ + if ( sPriv->drmMajor != 1 || + sPriv->drmMinor < 5) { + __driUtilMessage( "R200 DRI driver expected DRM driver version 1.5.x " + "but got version %d.%d.%d", + sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); + return NULL; + } + + + + /* Allocate the private area */ + r200Screen = (r200ScreenPtr) CALLOC( sizeof(*r200Screen) ); + if ( !r200Screen ) { + __driUtilMessage("%s: CALLOC r200Screen struct failed", + __FUNCTION__); + return NULL; + } + + + switch ( r200DRIPriv->deviceID ) { + case PCI_CHIP_R200_QD: + case PCI_CHIP_R200_QE: + case PCI_CHIP_R200_QF: + case PCI_CHIP_R200_QG: + case PCI_CHIP_R200_QY: + case PCI_CHIP_R200_QZ: + case PCI_CHIP_RV200_QW: + case PCI_CHIP_R200_LW: + case PCI_CHIP_R200_LY: + case PCI_CHIP_R200_LZ: + __driUtilMessage("r200CreateScreen(): Device isn't an r200!\n"); + FREE( r200Screen ); + return NULL; + default: + r200Screen->chipset = R200_CHIPSET_R200; + break; + } + + + /* This is first since which regions we map depends on whether or + * not we are using a PCI card. + */ + r200Screen->IsPCI = r200DRIPriv->IsPCI; + + { + int ret; + drmRadeonGetParam gp; + + gp.param = RADEON_PARAM_AGP_BUFFER_OFFSET; + gp.value = &r200Screen->agp_buffer_offset; + + ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + FREE( r200Screen ); + fprintf(stderr, "drmR200GetParam: %d\n", ret); + return NULL; + } + + r200Screen->agp_texture_offset = + r200Screen->agp_buffer_offset + 2*1024*1024; + + + if (sPriv->drmMinor >= 6) { + gp.param = RADEON_PARAM_AGP_BASE; + gp.value = &r200Screen->agp_base; + + ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + FREE( r200Screen ); + fprintf(stderr, + "drmR200GetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", + ret); + return NULL; + } + } + + if (sPriv->drmMinor >= 6) { + gp.param = RADEON_PARAM_IRQ_NR; + gp.value = &r200Screen->irq; + + ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + FREE( r200Screen ); + fprintf(stderr, "drmR200GetParam (RADEON_PARAM_IRQ_NR): %d\n", ret); + return NULL; + } + } + + } + + r200Screen->mmio.handle = r200DRIPriv->registerHandle; + r200Screen->mmio.size = r200DRIPriv->registerSize; + if ( drmMap( sPriv->fd, + r200Screen->mmio.handle, + r200Screen->mmio.size, + &r200Screen->mmio.map ) ) { + FREE( r200Screen ); + __driUtilMessage("r200CreateScreen(): drmMap failed\n"); + return NULL; + } + + r200Screen->status.handle = r200DRIPriv->statusHandle; + r200Screen->status.size = r200DRIPriv->statusSize; + if ( drmMap( sPriv->fd, + r200Screen->status.handle, + r200Screen->status.size, + &r200Screen->status.map ) ) { + drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); + FREE( r200Screen ); + __driUtilMessage("r200CreateScreen(): drmMap (2) failed\n"); + return NULL; + } + r200Screen->scratch = (__volatile__ CARD32 *) + ((GLubyte *)r200Screen->status.map + RADEON_SCRATCH_REG_OFFSET); + + r200Screen->buffers = drmMapBufs( sPriv->fd ); + if ( !r200Screen->buffers ) { + drmUnmap( r200Screen->status.map, r200Screen->status.size ); + drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); + FREE( r200Screen ); + __driUtilMessage("r200CreateScreen(): drmMapBufs failed\n"); + return NULL; + } + + if ( !r200Screen->IsPCI ) { + r200Screen->agpTextures.handle = r200DRIPriv->agpTexHandle; + r200Screen->agpTextures.size = r200DRIPriv->agpTexMapSize; + if ( drmMap( sPriv->fd, + r200Screen->agpTextures.handle, + r200Screen->agpTextures.size, + (drmAddressPtr)&r200Screen->agpTextures.map ) ) { + drmUnmapBufs( r200Screen->buffers ); + drmUnmap( r200Screen->status.map, r200Screen->status.size ); + drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); + FREE( r200Screen ); + __driUtilMessage("r200CreateScreen(): IsPCI failed\n"); + return NULL; + } + } + + + + r200Screen->cpp = r200DRIPriv->bpp / 8; + r200Screen->AGPMode = r200DRIPriv->AGPMode; + + r200Screen->frontOffset = r200DRIPriv->frontOffset; + r200Screen->frontPitch = r200DRIPriv->frontPitch; + r200Screen->backOffset = r200DRIPriv->backOffset; + r200Screen->backPitch = r200DRIPriv->backPitch; + r200Screen->depthOffset = r200DRIPriv->depthOffset; + r200Screen->depthPitch = r200DRIPriv->depthPitch; + + r200Screen->texOffset[RADEON_CARD_HEAP] = r200DRIPriv->textureOffset; + r200Screen->texSize[RADEON_CARD_HEAP] = r200DRIPriv->textureSize; + r200Screen->logTexGranularity[RADEON_CARD_HEAP] = + r200DRIPriv->log2TexGran; + + if ( r200Screen->IsPCI ) { + r200Screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; + r200Screen->texOffset[RADEON_AGP_HEAP] = 0; + r200Screen->texSize[RADEON_AGP_HEAP] = 0; + r200Screen->logTexGranularity[RADEON_AGP_HEAP] = 0; + } else { + r200Screen->numTexHeaps = RADEON_NR_TEX_HEAPS; + r200Screen->texOffset[RADEON_AGP_HEAP] = + r200DRIPriv->agpTexOffset + R200_AGP_TEX_OFFSET; + r200Screen->texSize[RADEON_AGP_HEAP] = r200DRIPriv->agpTexMapSize; + r200Screen->logTexGranularity[RADEON_AGP_HEAP] = + r200DRIPriv->log2AGPTexGran; + } + + + r200Screen->driScreen = sPriv; + r200Screen->sarea_priv_offset = r200DRIPriv->sarea_priv_offset; + return r200Screen; +} + +/* Destroy the device specific screen private data struct. + */ +static void +r200DestroyScreen( __DRIscreenPrivate *sPriv ) +{ + r200ScreenPtr r200Screen = (r200ScreenPtr)sPriv->private; + + if (!r200Screen) + return; + + if ( !r200Screen->IsPCI ) { + drmUnmap( r200Screen->agpTextures.map, + r200Screen->agpTextures.size ); + } + drmUnmapBufs( r200Screen->buffers ); + drmUnmap( r200Screen->status.map, r200Screen->status.size ); + drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); + + FREE( r200Screen ); + sPriv->private = NULL; +} + + +/* Initialize the driver specific screen private data. + */ +static GLboolean +r200InitDriver( __DRIscreenPrivate *sPriv ) +{ + __r200Screen = r200CreateScreen( sPriv ); + + sPriv->private = (void *) __r200Screen; + + return sPriv->private ? GL_TRUE : GL_FALSE; +} + + + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +static GLboolean +r200CreateBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + const GLboolean swDepth = GL_FALSE; + const GLboolean swAlpha = GL_FALSE; + const GLboolean swAccum = mesaVis->accumRedBits > 0; + const GLboolean swStencil = mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24; + driDrawPriv->driverPrivate = (void *) + _mesa_create_framebuffer( mesaVis, + swDepth, + swStencil, + swAccum, + swAlpha ); + return (driDrawPriv->driverPrivate != NULL); + } +} + + +static void +r200DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + + + + +/* Fullscreen mode isn't used for much -- could be a way to shrink + * front/back buffers & get more texture memory if the client has + * changed the video resolution. + * + * Pageflipping is now done automatically whenever there is a single + * 3d client. + */ +static GLboolean +r200OpenCloseFullScreen( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} + +static struct __DriverAPIRec r200API = { + r200InitDriver, + r200DestroyScreen, + r200CreateContext, + r200DestroyContext, + r200CreateBuffer, + r200DestroyBuffer, + r200SwapBuffers, + r200MakeCurrent, + r200UnbindContext, + r200OpenCloseFullScreen, + r200OpenCloseFullScreen +}; + + + +/* + * This is the bootstrap function for the driver. + * The __driCreateScreen name is the symbol that libGL.so fetches. + * Return: pointer to a __DRIscreenPrivate. + * + */ +void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *config) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r200API); + return (void *) psp; +} + + +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we'd register new extension functions with the dispatcher. + */ +void +__driRegisterExtensions( void ) +{ + /* dlopen ourself */ + void *dll = dlopen(NULL, RTLD_GLOBAL); + if (dll) { + typedef void *(*registerFunc)(const char *funcName, void *funcAddr); + typedef void (*registerString)(const char *extName); + + /* Get pointers to libGL's __glXRegisterGLXFunction + * and __glXRegisterGLXExtensionString, if they exist. + */ + registerFunc regFunc = (registerFunc) dlsym(dll, "__glXRegisterGLXFunction"); + registerString regString = (registerString) dlsym(dll, "__glXRegisterGLXExtensionString"); + + if (regFunc) { + /* register our GLX extensions with libGL */ + void *p; + p = regFunc("glXAllocateMemoryNV", (void *) r200AllocateMemoryNV); + if (p) + ; /* XXX already registered - what to do, wrap? */ + + p = regFunc("glXFreeMemoryNV", (void *) r200FreeMemoryNV); + if (p) + ; /* XXX already registered - what to do, wrap? */ + + p = regFunc("glXGetAGPOffsetMESA", (void *) r200GetAGPOffset); + if (p) + ; /* XXX already registered - what to do, wrap? */ + } + + if (regString) { + regString("GLX_NV_vertex_array_range"); + regString("GLX_MESA_agp_offset"); + } + + dlclose(dll); + } +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_screen.h b/xc/lib/GL/mesa/src/drv/r200/r200_screen.h new file mode 100644 index 000000000..2b2c8798f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_screen.h @@ -0,0 +1,96 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_screen.h,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_SCREEN_H__ +#define __R200_SCREEN_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include <X11/Xlibint.h> +#include "dri_util.h" +#include "xf86drm.h" +#include "radeon_common.h" +#include "radeon_sarea.h" + +typedef struct { + drmHandle handle; /* Handle to the DRM region */ + drmSize size; /* Size of the DRM region */ + drmAddress map; /* Mapping of the DRM region */ +} r200RegionRec, *r200RegionPtr; + +#define R200_CHIPSET_R200 1 +#define R200_CHIPSET_MOBILITY 2 + + +#define R200_NR_TEX_HEAPS 2 + +typedef struct { + + int chipset; + int cpp; + int IsPCI; /* Current card is a PCI card */ + int AGPMode; + unsigned int irq; /* IRQ number (0 means none) */ + + unsigned int frontOffset; + unsigned int frontPitch; + unsigned int backOffset; + unsigned int backPitch; + + unsigned int depthOffset; + unsigned int depthPitch; + + /* Shared texture data */ + int numTexHeaps; + int texOffset[R200_NR_TEX_HEAPS]; + int texSize[R200_NR_TEX_HEAPS]; + int logTexGranularity[R200_NR_TEX_HEAPS]; + + r200RegionRec mmio; + r200RegionRec status; + r200RegionRec agpTextures; + + drmBufMapPtr buffers; + + __volatile__ CARD32 *scratch; + + __DRIscreenPrivate *driScreen; + unsigned int sarea_priv_offset; + unsigned int agp_buffer_offset; /* offset in card memory space */ + unsigned int agp_texture_offset; /* offset in card memory space */ + unsigned int agp_base; +} r200ScreenRec, *r200ScreenPtr; + +#endif +#endif /* __R200_SCREEN_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_span.c b/xc/lib/GL/mesa/src/drv/r200/r200_span.c new file mode 100644 index 000000000..0d8b77766 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_span.c @@ -0,0 +1,415 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_span.c,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_ioctl.h" +#include "r200_state.h" +#include "r200_span.h" +#include "r200_tex.h" + +#include "swrast/swrast.h" + +#define DBG 0 + +#define LOCAL_VARS \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ + r200ScreenPtr r200Screen = rmesa->r200Screen; \ + __DRIscreenPrivate *sPriv = rmesa->dri.screen; \ + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \ + GLuint pitch = r200Screen->frontPitch * r200Screen->cpp; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(sPriv->pFB + \ + rmesa->state.color.drawOffset + \ + (dPriv->x * r200Screen->cpp) + \ + (dPriv->y * pitch)); \ + char *read_buf = (char *)(sPriv->pFB + \ + rmesa->state.pixel.readOffset + \ + (dPriv->x * r200Screen->cpp) + \ + (dPriv->y * pitch)); \ + GLuint p; \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ + r200ScreenPtr r200Screen = rmesa->r200Screen; \ + __DRIscreenPrivate *sPriv = rmesa->dri.screen; \ + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \ + GLuint height = dPriv->h; \ + GLuint xo = dPriv->x; \ + GLuint yo = dPriv->y; \ + char *buf = (char *)(sPriv->pFB + r200Screen->depthOffset); \ + (void) buf + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + + +#define CLIPPIXEL( _x, _y ) \ + ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) + + +#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \ + if ( _y < miny || _y >= maxy ) { \ + _n1 = 0, _x1 = x; \ + } else { \ + _n1 = _n; \ + _x1 = _x; \ + if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \ + if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \ + } + +#define Y_FLIP( _y ) (height - _y - 1) + + +#define HW_LOCK() + +#define HW_CLIPLOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \ + int _nc = dPriv->numClipRects; \ + \ + 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() \ + } \ + } while (0) + +#define HW_UNLOCK() + + + +/* ================================================================ + * Color buffer + */ + +/* 16 bit, RGB565 color spanline and pixel functions + */ +#define INIT_MONO_PIXEL(p, color) \ + p = PACK_COLOR_565( color[0], color[1], color[2] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \ + (((int)g & 0xfc) << 3) | \ + (((int)b & 0xf8) >> 3)) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \ + rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \ + rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \ + rgba[3] = 0xff; \ + } while (0) + +#define TAG(x) r200##x##_RGB565 +#include "spantmp.h" + +/* 32 bit, ARGB8888 color spanline and pixel functions + */ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ +do { \ + *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \ + (g << 8) | \ + (r << 16) | \ + (a << 24) ); \ +} while (0) + +#define WRITE_PIXEL( _x, _y, p ) \ +do { \ + *(GLuint *)(buf + _x*4 + _y*pitch) = p; \ +} while (0) + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + volatile GLuint *ptr = (volatile GLuint *)(read_buf + _x*4 + _y*pitch); \ + GLuint p = *ptr; \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = (p >> 24) & 0xff; \ +} while (0) + +#define TAG(x) r200##x##_ARGB8888 +#include "spantmp.h" + + + +/* ================================================================ + * Depth buffer + */ + +/* The R200 has depth tiling on all the time, so we have to convert + * the x,y coordinates into the memory bus address (mba) in the same + * manner as the engine. In each case, the linear block address (ba) + * is calculated, and then wired with x and y to produce the final + * memory address. + */ + +#define BIT(x,b) ((x & (1<<b))>>b) +static GLuint r200_mba_z32( r200ContextPtr rmesa, + GLint x, GLint y ) +{ + GLuint pitch = rmesa->r200Screen->frontPitch; + GLuint b = ((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x3FF) >> 5); + GLuint a = + (BIT(x,0) << 2) | + (BIT(y,0) << 3) | + (BIT(x,1) << 4) | + (BIT(y,1) << 5) | + (BIT(x,3) << 6) | + (BIT(x,4) << 7) | + (BIT(x,2) << 8) | + (BIT(y,2) << 9) | + (BIT(y,3) << 10) | + (((pitch & 0x20) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) | + ((b >> 1) << 12); + return a; +} + +static GLuint r200_mba_z16( r200ContextPtr rmesa, GLint x, GLint y ) +{ + GLuint pitch = rmesa->r200Screen->frontPitch; + GLuint b = ((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x3FF) >> 6); + GLuint a = + (BIT(x,0) << 1) | + (BIT(y,0) << 2) | + (BIT(x,1) << 3) | + (BIT(y,1) << 4) | + (BIT(x,2) << 5) | + (BIT(x,4) << 6) | + (BIT(x,5) << 7) | + (BIT(x,3) << 8) | + (BIT(y,2) << 9) | + (BIT(y,3) << 10) | + (((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) | + ((b >> 1) << 12); + return a; +} + + +/* 16-bit depth buffer functions + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + r200_mba_z16( rmesa, _x + xo, _y + yo )) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + r200_mba_z16( rmesa, _x + xo, _y + yo )); + +#define TAG(x) r200##x##_16 +#include "depthtmp.h" + +/* 24 bit depth, 8 bit stencil depthbuffer functions + */ +#define WRITE_DEPTH( _x, _y, d ) \ +do { \ + GLuint offset = r200_mba_z32( rmesa, _x + xo, _y + yo ); \ + GLuint tmp = *(GLuint *)(buf + offset); \ + tmp &= 0xff000000; \ + tmp |= ((d) & 0x00ffffff); \ + *(GLuint *)(buf + offset) = tmp; \ +} while (0) + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + r200_mba_z32( rmesa, _x + xo, \ + _y + yo )) & 0x00ffffff; + +#define TAG(x) r200##x##_24_8 +#include "depthtmp.h" + + +/* ================================================================ + * Stencil buffer + */ + +/* 24 bit depth, 8 bit stencil depthbuffer functions + */ +#define WRITE_STENCIL( _x, _y, d ) \ +do { \ + GLuint offset = r200_mba_z32( rmesa, _x + xo, _y + yo ); \ + GLuint tmp = *(GLuint *)(buf + offset); \ + tmp &= 0x00ffffff; \ + tmp |= (((d) & 0xff) << 24); \ + *(GLuint *)(buf + offset) = tmp; \ +} while (0) + +#define READ_STENCIL( d, _x, _y ) \ +do { \ + GLuint offset = r200_mba_z32( rmesa, _x + xo, _y + yo ); \ + GLuint tmp = *(GLuint *)(buf + offset); \ + tmp &= 0xff000000; \ + d = tmp >> 24; \ +} while (0) + +#define TAG(x) r200##x##_24_8 +#include "stenciltmp.h" + + +static void r200SetReadBuffer( GLcontext *ctx, + GLframebuffer *colorBuffer, + GLenum mode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + switch ( mode ) { + case GL_FRONT_LEFT: + if ( rmesa->doPageFlip && rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->state.pixel.readOffset = rmesa->r200Screen->backOffset; + rmesa->state.pixel.readPitch = rmesa->r200Screen->backPitch; + } else { + rmesa->state.pixel.readOffset = rmesa->r200Screen->frontOffset; + rmesa->state.pixel.readPitch = rmesa->r200Screen->frontPitch; + } + break; + case GL_BACK_LEFT: + if ( rmesa->doPageFlip && rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->state.pixel.readOffset = rmesa->r200Screen->frontOffset; + rmesa->state.pixel.readPitch = rmesa->r200Screen->frontPitch; + } else { + rmesa->state.pixel.readOffset = rmesa->r200Screen->backOffset; + rmesa->state.pixel.readPitch = rmesa->r200Screen->backPitch; + } + break; + default: + assert(0); + break; + } +} + +/* Move locking out to get reasonable span performance (10x better + * than doing this in HW_LOCK above). WaitForIdle() is the main + * culprit. + */ + +static void r200SpanRenderStart( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + R200_FIREVERTICES( rmesa ); + LOCK_HARDWARE( rmesa ); + r200WaitForIdleLocked( rmesa ); + + /* Read & rewrite the first pixel in the frame buffer. This should + * be a noop, right? In fact without this conform fails as reading + * from the framebuffer sometimes produces old results -- the + * on-card read cache gets mixed up and doesn't notice that the + * framebuffer has been updated. + * + * In the worst case this is buggy too as p might get the wrong + * value first time, so really need a hidden pixel somewhere for this. + */ + { + int p; + volatile int *read_buf = (volatile int *)(rmesa->dri.screen->pFB + + rmesa->state.pixel.readOffset); + p = *read_buf; + *read_buf = p; + } +} + +static void r200SpanRenderFinish( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + _swrast_flush( ctx ); + UNLOCK_HARDWARE( rmesa ); +} + +void r200InitSpanFuncs( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + + swdd->SetReadBuffer = r200SetReadBuffer; + + switch ( rmesa->r200Screen->cpp ) { + case 2: + swdd->WriteRGBASpan = r200WriteRGBASpan_RGB565; + swdd->WriteRGBSpan = r200WriteRGBSpan_RGB565; + swdd->WriteMonoRGBASpan = r200WriteMonoRGBASpan_RGB565; + swdd->WriteRGBAPixels = r200WriteRGBAPixels_RGB565; + swdd->WriteMonoRGBAPixels = r200WriteMonoRGBAPixels_RGB565; + swdd->ReadRGBASpan = r200ReadRGBASpan_RGB565; + swdd->ReadRGBAPixels = r200ReadRGBAPixels_RGB565; + break; + + case 4: + swdd->WriteRGBASpan = r200WriteRGBASpan_ARGB8888; + swdd->WriteRGBSpan = r200WriteRGBSpan_ARGB8888; + swdd->WriteMonoRGBASpan = r200WriteMonoRGBASpan_ARGB8888; + swdd->WriteRGBAPixels = r200WriteRGBAPixels_ARGB8888; + swdd->WriteMonoRGBAPixels = r200WriteMonoRGBAPixels_ARGB8888; + swdd->ReadRGBASpan = r200ReadRGBASpan_ARGB8888; + swdd->ReadRGBAPixels = r200ReadRGBAPixels_ARGB8888; + break; + + default: + break; + } + + switch ( rmesa->glCtx->Visual.depthBits ) { + case 16: + swdd->ReadDepthSpan = r200ReadDepthSpan_16; + swdd->WriteDepthSpan = r200WriteDepthSpan_16; + swdd->ReadDepthPixels = r200ReadDepthPixels_16; + swdd->WriteDepthPixels = r200WriteDepthPixels_16; + break; + + case 24: + swdd->ReadDepthSpan = r200ReadDepthSpan_24_8; + swdd->WriteDepthSpan = r200WriteDepthSpan_24_8; + swdd->ReadDepthPixels = r200ReadDepthPixels_24_8; + swdd->WriteDepthPixels = r200WriteDepthPixels_24_8; + + swdd->ReadStencilSpan = r200ReadStencilSpan_24_8; + swdd->WriteStencilSpan = r200WriteStencilSpan_24_8; + swdd->ReadStencilPixels = r200ReadStencilPixels_24_8; + swdd->WriteStencilPixels = r200WriteStencilPixels_24_8; + break; + + default: + break; + } + + swdd->SpanRenderStart = r200SpanRenderStart; + swdd->SpanRenderFinish = r200SpanRenderFinish; +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_span.h b/xc/lib/GL/mesa/src/drv/r200/r200_span.h new file mode 100644 index 000000000..718158a6b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_span.h @@ -0,0 +1,43 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_span.h,v 1.1 2002/10/30 12:51:52 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_SPAN_H__ +#define __R200_SPAN_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void r200InitSpanFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_state.c b/xc/lib/GL/mesa/src/drv/r200/r200_state.c new file mode 100644 index 000000000..a22ab40d8 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_state.c @@ -0,0 +1,2145 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_state.c,v 1.4 2003/02/23 23:59:01 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_ioctl.h" +#include "r200_state.h" +#include "r200_tcl.h" +#include "r200_tex.h" +#include "r200_swtcl.h" +#include "r200_vtxfmt.h" + +#include "mem.h" +#include "mmath.h" +#include "enums.h" +#include "colormac.h" +#include "light.h" +#include "api_arrayelt.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "swrast_setup/swrast_setup.h" + + +/* ============================================================= + * Alpha blending + */ + +static void r200AlphaFunc( GLcontext *ctx, GLenum func, GLchan ref ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC]; + + R200_STATECHANGE( rmesa, ctx ); + + pp_misc &= ~(R200_ALPHA_TEST_OP_MASK | R200_REF_ALPHA_MASK); + pp_misc |= (ref & R200_REF_ALPHA_MASK); + + switch ( func ) { + case GL_NEVER: + pp_misc |= R200_ALPHA_TEST_FAIL; + break; + case GL_LESS: + pp_misc |= R200_ALPHA_TEST_LESS; + break; + case GL_EQUAL: + pp_misc |= R200_ALPHA_TEST_EQUAL; + break; + case GL_LEQUAL: + pp_misc |= R200_ALPHA_TEST_LEQUAL; + break; + case GL_GREATER: + pp_misc |= R200_ALPHA_TEST_GREATER; + break; + case GL_NOTEQUAL: + pp_misc |= R200_ALPHA_TEST_NEQUAL; + break; + case GL_GEQUAL: + pp_misc |= R200_ALPHA_TEST_GEQUAL; + break; + case GL_ALWAYS: + pp_misc |= R200_ALPHA_TEST_PASS; + break; + } + + rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc; +} + +static void r200BlendEquation( GLcontext *ctx, GLenum mode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~R200_COMB_FCN_MASK; + + switch ( mode ) { + case GL_FUNC_ADD_EXT: + case GL_LOGIC_OP: + b |= R200_COMB_FCN_ADD_CLAMP; + break; + + case GL_FUNC_SUBTRACT_EXT: + b |= R200_COMB_FCN_SUB_CLAMP; + break; + + case GL_FUNC_REVERSE_SUBTRACT_EXT: + b |= R200_COMB_FCN_RSUB_CLAMP; + break; + + case GL_MIN_EXT: + b |= R200_COMB_FCN_MIN; + break; + + case GL_MAX_EXT: + b |= R200_COMB_FCN_MAX; + break; + + default: + break; + } + + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b; + if ( ctx->Color.ColorLogicOpEnabled ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_ROP_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ROP_ENABLE; + } +} + +static void r200BlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & + ~(R200_SRC_BLEND_MASK | R200_DST_BLEND_MASK); + + switch ( ctx->Color.BlendSrcRGB ) { + case GL_ZERO: + b |= R200_SRC_BLEND_GL_ZERO; + break; + case GL_ONE: + b |= R200_SRC_BLEND_GL_ONE; + break; + case GL_DST_COLOR: + b |= R200_SRC_BLEND_GL_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + b |= R200_SRC_BLEND_GL_ONE_MINUS_DST_COLOR; + break; + case GL_SRC_ALPHA: + b |= R200_SRC_BLEND_GL_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + b |= R200_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + b |= R200_SRC_BLEND_GL_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + b |= R200_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA; + break; + case GL_SRC_ALPHA_SATURATE: + b |= R200_SRC_BLEND_GL_SRC_ALPHA_SATURATE; + break; + case GL_CONSTANT_COLOR: + b |= R200_SRC_BLEND_GL_CONST_COLOR; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + b |= R200_SRC_BLEND_GL_ONE_MINUS_CONST_COLOR; + break; + case GL_CONSTANT_ALPHA: + b |= R200_SRC_BLEND_GL_CONST_ALPHA; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + b |= R200_SRC_BLEND_GL_ONE_MINUS_CONST_ALPHA; + break; + default: + break; + } + + switch ( ctx->Color.BlendDstRGB ) { + case GL_ZERO: + b |= R200_DST_BLEND_GL_ZERO; + break; + case GL_ONE: + b |= R200_DST_BLEND_GL_ONE; + break; + case GL_SRC_COLOR: + b |= R200_DST_BLEND_GL_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + b |= R200_DST_BLEND_GL_ONE_MINUS_SRC_COLOR; + break; + case GL_SRC_ALPHA: + b |= R200_DST_BLEND_GL_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + b |= R200_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + b |= R200_DST_BLEND_GL_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + b |= R200_DST_BLEND_GL_ONE_MINUS_DST_ALPHA; + break; + case GL_CONSTANT_COLOR: + b |= R200_DST_BLEND_GL_CONST_COLOR; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + b |= R200_DST_BLEND_GL_ONE_MINUS_CONST_COLOR; + break; + case GL_CONSTANT_ALPHA: + b |= R200_DST_BLEND_GL_CONST_ALPHA; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + b |= R200_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA; + break; + default: + break; + } + + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b; +} + +static void r200BlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + r200BlendFunc( ctx, sfactorRGB, dfactorRGB ); +} + + +/* ============================================================= + * Depth testing + */ + +static void r200DepthFunc( GLcontext *ctx, GLenum func ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_TEST_MASK; + + switch ( ctx->Depth.Func ) { + case GL_NEVER: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEVER; + break; + case GL_LESS: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LESS; + break; + case GL_EQUAL: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_EQUAL; + break; + case GL_LEQUAL: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LEQUAL; + break; + case GL_GREATER: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GREATER; + break; + case GL_NOTEQUAL: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEQUAL; + break; + case GL_GEQUAL: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GEQUAL; + break; + case GL_ALWAYS: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_ALWAYS; + break; + } +} + + +static void r200DepthMask( GLcontext *ctx, GLboolean flag ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + R200_STATECHANGE( rmesa, ctx ); + + if ( ctx->Depth.Mask ) { + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_WRITE_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_WRITE_ENABLE; + } +} + + +/* ============================================================= + * Fog + */ + + +static void r200Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + union { int i; float f; } c, d; + GLchan col[4]; + GLuint i; + + c.i = rmesa->hw.fog.cmd[FOG_C]; + d.i = rmesa->hw.fog.cmd[FOG_D]; + + switch (pname) { + case GL_FOG_MODE: + if (!ctx->Fog.Enabled) + return; + R200_STATECHANGE(rmesa, tcl); + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK; + switch (ctx->Fog.Mode) { + case GL_LINEAR: + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_LINEAR; + if (ctx->Fog.Start == ctx->Fog.End) { + c.f = 1.0F; + d.f = 1.0F; + } + else { + c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); + d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start); + } + break; + case GL_EXP: + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP; + c.f = 0.0; + d.f = -ctx->Fog.Density; + break; + case GL_EXP2: + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP2; + c.f = 0.0; + d.f = -(ctx->Fog.Density * ctx->Fog.Density); + break; + default: + return; + } + break; + case GL_FOG_DENSITY: + switch (ctx->Fog.Mode) { + case GL_EXP: + c.f = 0.0; + d.f = -ctx->Fog.Density; + break; + case GL_EXP2: + c.f = 0.0; + d.f = -(ctx->Fog.Density * ctx->Fog.Density); + break; + default: + break; + } + break; + case GL_FOG_START: + case GL_FOG_END: + if (ctx->Fog.Mode == GL_LINEAR) { + if (ctx->Fog.Start == ctx->Fog.End) { + c.f = 1.0F; + d.f = 1.0F; + } else { + c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); + d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start); + } + } + break; + case GL_FOG_COLOR: + R200_STATECHANGE( rmesa, ctx ); + UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color ); + i = r200PackColor( 4, col[0], col[1], col[2], 0 ); + rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_COLOR_MASK; + rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= i; + break; + case GL_FOG_COORDINATE_SOURCE_EXT: + /* What to do? + */ + break; + default: + return; + } + + if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) { + R200_STATECHANGE( rmesa, fog ); + rmesa->hw.fog.cmd[FOG_C] = c.i; + rmesa->hw.fog.cmd[FOG_D] = d.i; + } +} + + +/* ============================================================= + * Scissoring + */ + + +static GLboolean intersect_rect( XF86DRIClipRectPtr out, + XF86DRIClipRectPtr a, + XF86DRIClipRectPtr b ) +{ + *out = *a; + if ( b->x1 > out->x1 ) out->x1 = b->x1; + if ( b->y1 > out->y1 ) out->y1 = b->y1; + if ( b->x2 < out->x2 ) out->x2 = b->x2; + if ( b->y2 < out->y2 ) out->y2 = b->y2; + if ( out->x1 >= out->x2 ) return GL_FALSE; + if ( out->y1 >= out->y2 ) return GL_FALSE; + return GL_TRUE; +} + + +void r200RecalcScissorRects( r200ContextPtr rmesa ) +{ + XF86DRIClipRectPtr out; + int i; + + /* Grow cliprect store? + */ + if (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { + while (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { + rmesa->state.scissor.numAllocedClipRects += 1; /* zero case */ + rmesa->state.scissor.numAllocedClipRects *= 2; + } + + if (rmesa->state.scissor.pClipRects) + FREE(rmesa->state.scissor.pClipRects); + + rmesa->state.scissor.pClipRects = + MALLOC( rmesa->state.scissor.numAllocedClipRects * + sizeof(XF86DRIClipRectRec) ); + + if (!rmesa->state.scissor.numAllocedClipRects) { + rmesa->state.scissor.numAllocedClipRects = 0; + return; + } + } + + out = rmesa->state.scissor.pClipRects; + rmesa->state.scissor.numClipRects = 0; + + for ( i = 0 ; i < rmesa->numClipRects ; i++ ) { + if ( intersect_rect( out, + &rmesa->pClipRects[i], + &rmesa->state.scissor.rect ) ) { + rmesa->state.scissor.numClipRects++; + out++; + } + } +} + + +static void r200UpdateScissor( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if ( rmesa->dri.drawable ) { + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + + int x = ctx->Scissor.X; + int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; + int w = ctx->Scissor.X + ctx->Scissor.Width - 1; + int h = dPriv->h - ctx->Scissor.Y - 1; + + rmesa->state.scissor.rect.x1 = x + dPriv->x; + rmesa->state.scissor.rect.y1 = y + dPriv->y; + rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; + rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; + + r200RecalcScissorRects( rmesa ); + } +} + + +static void r200Scissor( GLcontext *ctx, + GLint x, GLint y, GLsizei w, GLsizei h ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if ( ctx->Scissor.Enabled ) { + R200_FIREVERTICES( rmesa ); /* don't pipeline cliprect changes */ + r200UpdateScissor( ctx ); + } + +} + + +/* ============================================================= + * Culling + */ + +static void r200CullFace( GLcontext *ctx, GLenum unused ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; + GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL]; + + s |= R200_FFACE_SOLID | R200_BFACE_SOLID; + t &= ~(R200_CULL_FRONT | R200_CULL_BACK); + + if ( ctx->Polygon.CullFlag ) { + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + s &= ~R200_FFACE_SOLID; + t |= R200_CULL_FRONT; + break; + case GL_BACK: + s &= ~R200_BFACE_SOLID; + t |= R200_CULL_BACK; + break; + case GL_FRONT_AND_BACK: + s &= ~(R200_FFACE_SOLID | R200_BFACE_SOLID); + t |= (R200_CULL_FRONT | R200_CULL_BACK); + break; + } + } + + if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) { + R200_STATECHANGE(rmesa, set ); + rmesa->hw.set.cmd[SET_SE_CNTL] = s; + } + + if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) { + R200_STATECHANGE(rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t; + } +} + +static void r200FrontFace( GLcontext *ctx, GLenum mode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + R200_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_FFACE_CULL_DIR_MASK; + + R200_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_CULL_FRONT_IS_CCW; + + switch ( mode ) { + case GL_CW: + rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CW; + break; + case GL_CCW: + rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CCW; + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_CULL_FRONT_IS_CCW; + break; + } +} + +/* ============================================================= + * Point state + */ +static void r200PointSize( GLcontext *ctx, GLfloat size ) +{ + if (R200_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s: %f\n", __FUNCTION__, size ); +} + +/* ============================================================= + * Line state + */ +static void r200LineWidth( GLcontext *ctx, GLfloat widthf ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + R200_STATECHANGE( rmesa, lin ); + R200_STATECHANGE( rmesa, set ); + + /* Line width is stored in U6.4 format. + */ + rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff; + rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Line._Width * 16.0); + + if ( widthf > 1.0 ) { + rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_WIDELINE_ENABLE; + } else { + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_WIDELINE_ENABLE; + } +} + +static void r200LineStipple( GLcontext *ctx, GLint factor, GLushort pattern ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + R200_STATECHANGE( rmesa, lin ); + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = + ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern)); +} + + +/* ============================================================= + * Masks + */ +static void r200ColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint mask = r200PackColor( rmesa->r200Screen->cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] ); + + GLuint flag = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & ~R200_PLANE_MASK_ENABLE; + + if (!(r && g && b && a)) + flag |= R200_PLANE_MASK_ENABLE; + + if ( rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] != flag ) { + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = flag; + } + + if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) { + R200_STATECHANGE( rmesa, msk ); + rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask; + } +} + + +/* ============================================================= + * Polygon state + */ + +static void r200PolygonOffset( GLcontext *ctx, + GLfloat factor, GLfloat units ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLfloat constant = units * rmesa->state.depth.scale; + +/* factor *= 2; */ +/* constant *= 2; */ + +/* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */ + + R200_STATECHANGE( rmesa, zbs ); + rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = *(GLuint *)&factor; + rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = *(GLuint *)&constant; +} + +static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint i; + drmRadeonStipple stipple; + + /* Must flip pattern upside down. + */ + for ( i = 0 ; i < 32 ; i++ ) { + rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i]; + } + + /* TODO: push this into cmd mechanism + */ + R200_FIREVERTICES( rmesa ); + LOCK_HARDWARE( rmesa ); + + /* FIXME: Use window x,y offsets into stipple RAM. + */ + stipple.mask = rmesa->state.stipple.mask; + drmCommandWrite( rmesa->dri.fd, DRM_RADEON_STIPPLE, + &stipple, sizeof(drmRadeonStipple) ); + UNLOCK_HARDWARE( rmesa ); +} + +static void r200PolygonMode( GLcontext *ctx, GLenum face, GLenum mode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0; + + /* Can't generally do unfilled via tcl, but some good special + * cases work. + */ + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_UNFILLED, flag); + if (rmesa->TclFallback) { + r200ChooseRenderState( ctx ); + r200ChooseVertexState( ctx ); + } +} + + +/* ============================================================= + * Rendering attributes + * + * We really don't want to recalculate all this every time we bind a + * texture. These things shouldn't change all that often, so it makes + * sense to break them out of the core texture state update routines. + */ + +/* Examine lighting and texture state to determine if separate specular + * should be enabled. + */ +static void r200UpdateSpecular( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + CARD32 p = rmesa->hw.ctx.cmd[CTX_PP_CNTL]; + + R200_STATECHANGE( rmesa, tcl ); + R200_STATECHANGE( rmesa, vtx ); + + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_0_SHIFT); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_1_SHIFT); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_0; + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_1; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHTING_ENABLE; + p &= ~R200_SPECULAR_ENABLE; + + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_DIFFUSE_SPECULAR_COMBINE; + + + if (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) { + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= + ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) | + (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT)); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0; + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE; + p |= R200_SPECULAR_ENABLE; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= + ~R200_DIFFUSE_SPECULAR_COMBINE; + } + else if (ctx->Light.Enabled) { + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= + ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT)); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE; + } else if (ctx->Fog.ColorSumEnabled ) { + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= + ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) | + (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT)); + p |= R200_SPECULAR_ENABLE; + } else { + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= + ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT)); + } + + if (ctx->Fog.Enabled) { + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= + ((R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT)); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1; + } + + if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p; + } + + /* Update vertex/render formats + */ + if (rmesa->TclFallback) { + r200ChooseRenderState( ctx ); + r200ChooseVertexState( ctx ); + } +} + + +/* ============================================================= + * Materials + */ + + +/* Update on colormaterial, material emmissive/ambient, + * lightmodel.globalambient + */ +static void update_global_ambient( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + float *fcmd = (float *)R200_DB_STATE( glt ); + + /* Need to do more if both emmissive & ambient are PREMULT: + */ + if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] & + ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | + (3 << R200_FRONT_AMBIENT_SOURCE_SHIFT))) == 0) + { + COPY_3V( &fcmd[GLT_RED], + ctx->Light.Material[0].Emission); + ACC_SCALE_3V( &fcmd[GLT_RED], + ctx->Light.Model.Ambient, + ctx->Light.Material[0].Ambient); + } + else + { + COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient ); + } + + R200_DB_STATECHANGE(rmesa, &rmesa->hw.glt); +} + +/* Update on change to + * - light[p].colors + * - light[p].enabled + * - material, + * - colormaterial enabled + * - colormaterial bitmask + */ +static void update_light_colors( GLcontext *ctx, GLuint p ) +{ + struct gl_light *l = &ctx->Light.Light[p]; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + if (l->Enabled) { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + float *fcmd = (float *)R200_DB_STATE( lit[p] ); + GLuint bitmask = ctx->Light.ColorMaterialBitmask; + struct gl_material *mat = &ctx->Light.Material[0]; + + COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient ); + COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse ); + COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular ); + + if (!ctx->Light.ColorMaterialEnabled) + bitmask = 0; + + if ((bitmask & FRONT_AMBIENT_BIT) == 0) + SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat->Ambient ); + + if ((bitmask & FRONT_DIFFUSE_BIT) == 0) + SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat->Diffuse ); + + if ((bitmask & FRONT_SPECULAR_BIT) == 0) + SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat->Specular ); + + R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); + } +} + +/* Also fallback for asym colormaterial mode in twoside lighting... + */ +static void check_twoside_fallback( GLcontext *ctx ) +{ + GLboolean fallback = GL_FALSE; + + if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { + if (memcmp( &ctx->Light.Material[0], + &ctx->Light.Material[1], + sizeof(struct gl_material)) != 0) + fallback = GL_TRUE; + else if (ctx->Light.ColorMaterialEnabled && + (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) != + ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1)) + fallback = GL_TRUE; + } + + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_LIGHT_TWOSIDE, fallback ); +} + +static void r200ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ) +{ + if (ctx->Light.ColorMaterialEnabled) { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]; + GLuint mask = ctx->Light.ColorMaterialBitmask; + + /* Default to PREMULT: + */ + light_model_ctl1 &= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | + (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT) | + (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT) | + (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT)); + + if (mask & FRONT_EMISSION_BIT) { + light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << + R200_FRONT_EMISSIVE_SOURCE_SHIFT); + } + + if (mask & FRONT_AMBIENT_BIT) { + light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << + R200_FRONT_AMBIENT_SOURCE_SHIFT); + } + + if (mask & FRONT_DIFFUSE_BIT) { + light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << + R200_FRONT_DIFFUSE_SOURCE_SHIFT); + } + + if (mask & FRONT_SPECULAR_BIT) { + light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << + R200_FRONT_SPECULAR_SOURCE_SHIFT); + } + + if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) { + GLuint p; + + R200_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1; + + for (p = 0 ; p < MAX_LIGHTS; p++) + update_light_colors( ctx, p ); + update_global_ambient( ctx ); + } + } + + check_twoside_fallback( ctx ); +} + +void r200UpdateMaterial( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLfloat *fcmd = (GLfloat *)R200_DB_STATE( mtl[0] ); + GLuint p; + GLuint mask = ~0; + + if (ctx->Light.ColorMaterialEnabled) + mask &= ~ctx->Light.ColorMaterialBitmask; + + if (R200_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if (mask & FRONT_EMISSION_BIT) { + fcmd[MTL_EMMISSIVE_RED] = ctx->Light.Material[0].Emission[0]; + fcmd[MTL_EMMISSIVE_GREEN] = ctx->Light.Material[0].Emission[1]; + fcmd[MTL_EMMISSIVE_BLUE] = ctx->Light.Material[0].Emission[2]; + fcmd[MTL_EMMISSIVE_ALPHA] = ctx->Light.Material[0].Emission[3]; + } + if (mask & FRONT_AMBIENT_BIT) { + fcmd[MTL_AMBIENT_RED] = ctx->Light.Material[0].Ambient[0]; + fcmd[MTL_AMBIENT_GREEN] = ctx->Light.Material[0].Ambient[1]; + fcmd[MTL_AMBIENT_BLUE] = ctx->Light.Material[0].Ambient[2]; + fcmd[MTL_AMBIENT_ALPHA] = ctx->Light.Material[0].Ambient[3]; + } + if (mask & FRONT_DIFFUSE_BIT) { + fcmd[MTL_DIFFUSE_RED] = ctx->Light.Material[0].Diffuse[0]; + fcmd[MTL_DIFFUSE_GREEN] = ctx->Light.Material[0].Diffuse[1]; + fcmd[MTL_DIFFUSE_BLUE] = ctx->Light.Material[0].Diffuse[2]; + fcmd[MTL_DIFFUSE_ALPHA] = ctx->Light.Material[0].Diffuse[3]; + } + if (mask & FRONT_SPECULAR_BIT) { + fcmd[MTL_SPECULAR_RED] = ctx->Light.Material[0].Specular[0]; + fcmd[MTL_SPECULAR_GREEN] = ctx->Light.Material[0].Specular[1]; + fcmd[MTL_SPECULAR_BLUE] = ctx->Light.Material[0].Specular[2]; + fcmd[MTL_SPECULAR_ALPHA] = ctx->Light.Material[0].Specular[3]; + } + if (mask & FRONT_SHININESS_BIT) { + fcmd[MTL_SHININESS] = ctx->Light.Material[0].Shininess; + } + + if (R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] )) { + for (p = 0 ; p < MAX_LIGHTS; p++) + update_light_colors( ctx, p ); + + check_twoside_fallback( ctx ); + update_global_ambient( ctx ); + } + else if (R200_DEBUG & (DEBUG_PRIMS|DEBUG_STATE)) + fprintf(stderr, "%s: Elided noop material call\n", __FUNCTION__); +} + +/* _NEW_LIGHT + * _NEW_MODELVIEW + * _MESA_NEW_NEED_EYE_COORDS + * + * Uses derived state from mesa: + * _VP_inf_norm + * _h_inf_norm + * _Position + * _NormDirection + * _ModelViewInvScale + * _NeedEyeCoords + * _EyeZDir + * + * which are calculated in light.c and are correct for the current + * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW + * and _MESA_NEW_NEED_EYE_COORDS. + */ +static void update_light( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + /* Have to check these, or have an automatic shortcircuit mechanism + * to remove noop statechanges. (Or just do a better job on the + * front end). + */ + { + GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]; + + if (ctx->_NeedEyeCoords) + tmp &= ~R200_LIGHT_IN_MODELSPACE; + else + tmp |= R200_LIGHT_IN_MODELSPACE; + + if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]) + { + R200_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] = tmp; + } + } + + { + GLfloat *fcmd = (GLfloat *)R200_DB_STATE( eye ); + fcmd[EYE_X] = ctx->_EyeZDir[0]; + fcmd[EYE_Y] = ctx->_EyeZDir[1]; + fcmd[EYE_Z] = - ctx->_EyeZDir[2]; + fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale; + R200_DB_STATECHANGE( rmesa, &rmesa->hw.eye ); + } + + +/* R200_STATECHANGE( rmesa, glt ); */ + + if (ctx->Light.Enabled) { + GLint p; + for (p = 0 ; p < MAX_LIGHTS; p++) { + if (ctx->Light.Light[p].Enabled) { + struct gl_light *l = &ctx->Light.Light[p]; + GLfloat *fcmd = (GLfloat *)R200_DB_STATE( lit[p] ); + + if (l->EyePosition[3] == 0.0) { + COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm ); + COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm ); + fcmd[LIT_POSITION_W] = 0; + fcmd[LIT_DIRECTION_W] = 0; + } else { + COPY_4V( &fcmd[LIT_POSITION_X], l->_Position ); + fcmd[LIT_DIRECTION_X] = -l->_NormDirection[0]; + fcmd[LIT_DIRECTION_Y] = -l->_NormDirection[1]; + fcmd[LIT_DIRECTION_Z] = -l->_NormDirection[2]; + fcmd[LIT_DIRECTION_W] = 0; + } + + R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); + } + } + } +} + +static void r200Lightfv( GLcontext *ctx, GLenum light, + GLenum pname, const GLfloat *params ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLint p = light - GL_LIGHT0; + struct gl_light *l = &ctx->Light.Light[p]; + GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd; + + + switch (pname) { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + update_light_colors( ctx, p ); + break; + + case GL_SPOT_DIRECTION: + /* picked up in update_light */ + break; + + case GL_POSITION: { + /* positions picked up in update_light, but can do flag here */ + GLuint flag = (p&1)? R200_LIGHT_1_IS_LOCAL : R200_LIGHT_0_IS_LOCAL; + GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; + + R200_STATECHANGE(rmesa, tcl); + if (l->EyePosition[3] != 0.0F) + rmesa->hw.tcl.cmd[idx] |= flag; + else + rmesa->hw.tcl.cmd[idx] &= ~flag; + break; + } + + case GL_SPOT_EXPONENT: + R200_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_SPOT_EXPONENT] = params[0]; + break; + + case GL_SPOT_CUTOFF: { + GLuint flag = (p&1) ? R200_LIGHT_1_IS_SPOT : R200_LIGHT_0_IS_SPOT; + GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; + + R200_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff; + + R200_STATECHANGE(rmesa, tcl); + if (l->SpotCutoff != 180.0F) + rmesa->hw.tcl.cmd[idx] |= flag; + else + rmesa->hw.tcl.cmd[idx] &= ~flag; + + break; + } + + case GL_CONSTANT_ATTENUATION: + R200_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_ATTEN_CONST] = params[0]; + break; + case GL_LINEAR_ATTENUATION: + R200_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_ATTEN_LINEAR] = params[0]; + break; + case GL_QUADRATIC_ATTENUATION: + R200_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_ATTEN_QUADRATIC] = params[0]; + break; + default: + return; + } + +} + + + + +static void r200LightModelfv( GLcontext *ctx, GLenum pname, + const GLfloat *param ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + switch (pname) { + case GL_LIGHT_MODEL_AMBIENT: + update_global_ambient( ctx ); + break; + + case GL_LIGHT_MODEL_LOCAL_VIEWER: + R200_STATECHANGE( rmesa, tcl ); + if (ctx->Light.Model.LocalViewer) + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LOCAL_VIEWER; + else + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LOCAL_VIEWER; + break; + + case GL_LIGHT_MODEL_TWO_SIDE: + R200_STATECHANGE( rmesa, tcl ); + if (ctx->Light.Model.TwoSide) + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHT_TWOSIDE; + else + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHT_TWOSIDE; + + check_twoside_fallback( ctx ); + + if (rmesa->TclFallback) { + r200ChooseRenderState( ctx ); + r200ChooseVertexState( ctx ); + } + break; + + case GL_LIGHT_MODEL_COLOR_CONTROL: + r200UpdateSpecular(ctx); + break; + + default: + break; + } +} + +static void r200ShadeModel( GLcontext *ctx, GLenum mode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; + + s &= ~(R200_DIFFUSE_SHADE_MASK | + R200_ALPHA_SHADE_MASK | + R200_SPECULAR_SHADE_MASK | + R200_FOG_SHADE_MASK); + + switch ( mode ) { + case GL_FLAT: + s |= (R200_DIFFUSE_SHADE_FLAT | + R200_ALPHA_SHADE_FLAT | + R200_SPECULAR_SHADE_FLAT | + R200_FOG_SHADE_FLAT); + break; + case GL_SMOOTH: + s |= (R200_DIFFUSE_SHADE_GOURAUD | + R200_ALPHA_SHADE_GOURAUD | + R200_SPECULAR_SHADE_GOURAUD | + R200_FOG_SHADE_GOURAUD); + break; + default: + return; + } + + if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) { + R200_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_CNTL] = s; + } +} + + +/* ============================================================= + * User clip planes + */ + +static void r200ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) +{ + GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0; + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; + + R200_STATECHANGE( rmesa, ucp[p] ); + rmesa->hw.ucp[p].cmd[UCP_X] = ip[0]; + rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1]; + rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2]; + rmesa->hw.ucp[p].cmd[UCP_W] = ip[3]; +} + +static void r200UpdateClipPlanes( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint p; + + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { + if (ctx->Transform.ClipEnabled[p]) { + GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; + + R200_STATECHANGE( rmesa, ucp[p] ); + rmesa->hw.ucp[p].cmd[UCP_X] = ip[0]; + rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1]; + rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2]; + rmesa->hw.ucp[p].cmd[UCP_W] = ip[3]; + } + } +} + + +/* ============================================================= + * Stencil + */ + +static void r200StencilFunc( GLcontext *ctx, GLenum func, + GLint ref, GLuint mask ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint refmask = ((ctx->Stencil.Ref << R200_STENCIL_REF_SHIFT) | + (ctx->Stencil.ValueMask << R200_STENCIL_MASK_SHIFT)); + + R200_STATECHANGE( rmesa, ctx ); + R200_STATECHANGE( rmesa, msk ); + + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_STENCIL_TEST_MASK; + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(R200_STENCIL_REF_MASK| + R200_STENCIL_VALUE_MASK); + + switch ( ctx->Stencil.Function ) { + case GL_NEVER: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEVER; + break; + case GL_LESS: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LESS; + break; + case GL_EQUAL: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_EQUAL; + break; + case GL_LEQUAL: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LEQUAL; + break; + case GL_GREATER: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GREATER; + break; + case GL_NOTEQUAL: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEQUAL; + break; + case GL_GEQUAL: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GEQUAL; + break; + case GL_ALWAYS: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_ALWAYS; + break; + } + + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask; +} + +static void r200StencilMask( GLcontext *ctx, GLuint mask ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + R200_STATECHANGE( rmesa, msk ); + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~R200_STENCIL_WRITE_MASK; + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= + (ctx->Stencil.WriteMask << R200_STENCIL_WRITEMASK_SHIFT); +} + +static void r200StencilOp( GLcontext *ctx, GLenum fail, + GLenum zfail, GLenum zpass ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(R200_STENCIL_FAIL_MASK | + R200_STENCIL_ZFAIL_MASK | + R200_STENCIL_ZPASS_MASK); + + switch ( ctx->Stencil.FailFunc ) { + case GL_KEEP: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_KEEP; + break; + case GL_ZERO: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_ZERO; + break; + case GL_REPLACE: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_REPLACE; + break; + case GL_INCR: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC; + break; + case GL_DECR: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC; + break; + case GL_INCR_WRAP_EXT: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC_WRAP; + break; + case GL_DECR_WRAP_EXT: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC_WRAP; + break; + case GL_INVERT: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INVERT; + break; + } + + switch ( ctx->Stencil.ZFailFunc ) { + case GL_KEEP: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_KEEP; + break; + case GL_ZERO: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_ZERO; + break; + case GL_REPLACE: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_REPLACE; + break; + case GL_INCR: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC; + break; + case GL_DECR: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC; + break; + case GL_INCR_WRAP_EXT: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC_WRAP; + break; + case GL_DECR_WRAP_EXT: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC_WRAP; + break; + case GL_INVERT: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INVERT; + break; + } + + switch ( ctx->Stencil.ZPassFunc ) { + case GL_KEEP: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_KEEP; + break; + case GL_ZERO: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_ZERO; + break; + case GL_REPLACE: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_REPLACE; + break; + case GL_INCR: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC; + break; + case GL_DECR: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC; + break; + case GL_INCR_WRAP_EXT: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC_WRAP; + break; + case GL_DECR_WRAP_EXT: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC_WRAP; + break; + case GL_INVERT: + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INVERT; + break; + } +} + +static void r200ClearStencil( GLcontext *ctx, GLint s ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + rmesa->state.stencil.clear = + ((GLuint) ctx->Stencil.Clear | + (0xff << R200_STENCIL_MASK_SHIFT) | + (ctx->Stencil.WriteMask << R200_STENCIL_WRITEMASK_SHIFT)); +} + + +/* ============================================================= + * Window position and viewport transformation + */ + +/* + * To correctly position primitives: + */ +#define SUBPIXEL_X 0.125 +#define SUBPIXEL_Y 0.125 + +void r200UpdateWindow( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + GLfloat xoffset = (GLfloat)dPriv->x; + GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; + const GLfloat *v = ctx->Viewport._WindowMap.m; + + GLfloat sx = v[MAT_SX]; + GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; + GLfloat sy = - v[MAT_SY]; + GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y; + GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale; + GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale; + + R200_FIREVERTICES( rmesa ); + R200_STATECHANGE( rmesa, vpt ); + + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = *(GLuint *)&sx; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = *(GLuint *)&sy; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = *(GLuint *)&sz; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = *(GLuint *)&tz; +} + + + +static void r200Viewport( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + /* Don't pipeline viewport changes, conflict with window offset + * setting below. Could apply deltas to rescue pipelined viewport + * values, or keep the originals hanging around. + */ + R200_FIREVERTICES( R200_CONTEXT(ctx) ); + r200UpdateWindow( ctx ); +} + +static void r200DepthRange( GLcontext *ctx, GLclampd nearval, + GLclampd farval ) +{ + r200UpdateWindow( ctx ); +} + +void r200UpdateViewportOffset( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + GLfloat xoffset = (GLfloat)dPriv->x; + GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; + const GLfloat *v = ctx->Viewport._WindowMap.m; + + GLfloat tx = v[MAT_TX] + xoffset; + GLfloat ty = (- v[MAT_TY]) + yoffset; + + if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != *(GLuint *)&tx || + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != *(GLuint *)&ty ) + { + /* Note: this should also modify whatever data the context reset + * code uses... + */ + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty; + + /* update polygon stipple x/y screen offset */ + { + GLuint stx, sty; + GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC]; + + m &= ~(R200_STIPPLE_X_OFFSET_MASK | + R200_STIPPLE_Y_OFFSET_MASK); + + /* add magic offsets, then invert */ + stx = 31 - ((rmesa->dri.drawable->x - 1) & R200_STIPPLE_COORD_MASK); + sty = 31 - ((rmesa->dri.drawable->y + rmesa->dri.drawable->h - 1) + & R200_STIPPLE_COORD_MASK); + + m |= ((stx << R200_STIPPLE_X_OFFSET_SHIFT) | + (sty << R200_STIPPLE_Y_OFFSET_SHIFT)); + + if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) { + R200_STATECHANGE( rmesa, msc ); + rmesa->hw.msc.cmd[MSC_RE_MISC] = m; + } + } + } + + r200UpdateScissor( ctx ); +} + + + +/* ============================================================= + * Miscellaneous + */ + +static void r200ClearColor( GLcontext *ctx, const GLchan c[4] ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + rmesa->state.color.clear = r200PackColor( rmesa->r200Screen->cpp, + c[0], c[1], c[2], c[3] ); +} + + +static void r200RenderMode( GLcontext *ctx, GLenum mode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + FALLBACK( rmesa, R200_FALLBACK_RENDER_MODE, (mode != GL_RENDER) ); +} + + +static GLuint r200_rop_tab[] = { + R200_ROP_CLEAR, + R200_ROP_AND, + R200_ROP_AND_REVERSE, + R200_ROP_COPY, + R200_ROP_AND_INVERTED, + R200_ROP_NOOP, + R200_ROP_XOR, + R200_ROP_OR, + R200_ROP_NOR, + R200_ROP_EQUIV, + R200_ROP_INVERT, + R200_ROP_OR_REVERSE, + R200_ROP_COPY_INVERTED, + R200_ROP_OR_INVERTED, + R200_ROP_NAND, + R200_ROP_SET, +}; + +static void r200LogicOpCode( GLcontext *ctx, GLenum opcode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint rop = (GLuint)opcode - GL_CLEAR; + + ASSERT( rop < 16 ); + + R200_STATECHANGE( rmesa, msk ); + rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = r200_rop_tab[rop]; +} + + +void r200SetCliprects( r200ContextPtr rmesa, GLenum mode ) +{ + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + + switch ( mode ) { + case GL_FRONT_LEFT: + rmesa->numClipRects = dPriv->numClipRects; + rmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects; + break; + case GL_BACK_LEFT: + /* Can't ignore 2d windows if we are page flipping. + */ + if ( dPriv->numBackClipRects == 0 || rmesa->doPageFlip ) { + rmesa->numClipRects = dPriv->numClipRects; + rmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects; + } + else { + rmesa->numClipRects = dPriv->numBackClipRects; + rmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pBackClipRects; + } + break; + default: + fprintf(stderr, "bad mode in r200SetCliprects\n"); + return; + } + + if (rmesa->state.scissor.enabled) + r200RecalcScissorRects( rmesa ); +} + + +static void r200SetDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr( mode )); + + R200_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */ + + switch ( mode ) { + case GL_FRONT_LEFT: + FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_FALSE ); + if ( rmesa->doPageFlip && rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch; + } else { + rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch; + } + r200SetCliprects( rmesa, GL_FRONT_LEFT ); + break; + case GL_BACK_LEFT: + FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_FALSE ); + if ( rmesa->doPageFlip && rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch; + } else { + rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch; + } + r200SetCliprects( rmesa, GL_BACK_LEFT ); + break; + default: + FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = (rmesa->state.color.drawOffset & + R200_COLOROFFSET_MASK); + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; +} + + +/* ============================================================= + * State enable/disable + */ + +static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint p, flag; + + if ( R200_DEBUG & DEBUG_STATE ) + fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__, + _mesa_lookup_enum_by_nr( cap ), + state ? "GL_TRUE" : "GL_FALSE" ); + + switch ( cap ) { + /* Fast track this one... + */ + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + break; + + case GL_ALPHA_TEST: + R200_STATECHANGE( rmesa, ctx ); + if (state) { + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ALPHA_TEST_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ALPHA_TEST_ENABLE; + } + break; + + case GL_BLEND: + R200_STATECHANGE( rmesa, ctx ); + if (state) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_ALPHA_BLEND_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ALPHA_BLEND_ENABLE; + } + if ( ctx->Color.ColorLogicOpEnabled ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_ROP_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ROP_ENABLE; + } + break; + + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + p = cap-GL_CLIP_PLANE0; + R200_STATECHANGE( rmesa, tcl ); + if (state) { + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0<<p); + r200ClipPlane( ctx, cap, NULL ); + } + else { + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0<<p); + } + break; + + case GL_COLOR_MATERIAL: + r200ColorMaterial( ctx, 0, 0 ); + if (!state) + r200UpdateMaterial( ctx ); + break; + + case GL_CULL_FACE: + r200CullFace( ctx, 0 ); + break; + + case GL_DEPTH_TEST: + R200_STATECHANGE(rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_Z_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_Z_ENABLE; + } + break; + + case GL_DITHER: + R200_STATECHANGE(rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_DITHER_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_DITHER_ENABLE; + } + break; + + case GL_FOG: + R200_STATECHANGE(rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_FOG_ENABLE; + r200Fogfv( ctx, GL_FOG_MODE, 0 ); + } else { + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_FOG_ENABLE; + R200_STATECHANGE(rmesa, tcl); + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK; + } + r200UpdateSpecular( ctx ); /* for PK_SPEC */ + break; + + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + R200_STATECHANGE(rmesa, tcl); + p = cap - GL_LIGHT0; + if (p&1) + flag = (R200_LIGHT_1_ENABLE | + R200_LIGHT_1_ENABLE_AMBIENT | + R200_LIGHT_1_ENABLE_SPECULAR); + else + flag = (R200_LIGHT_0_ENABLE | + R200_LIGHT_0_ENABLE_AMBIENT | + R200_LIGHT_0_ENABLE_SPECULAR); + + if (state) + rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag; + else + rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag; + + /* + */ + update_light_colors( ctx, p ); + break; + + case GL_LIGHTING: + r200UpdateSpecular(ctx); + check_twoside_fallback( ctx ); + break; + + case GL_LINE_SMOOTH: + R200_STATECHANGE( rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ANTI_ALIAS_LINE; + } else { + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_LINE; + } + break; + + case GL_LINE_STIPPLE: + R200_STATECHANGE( rmesa, set ); + if ( state ) { + rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PATTERN_ENABLE; + } else { + rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PATTERN_ENABLE; + } + break; + + case GL_COLOR_LOGIC_OP: + R200_STATECHANGE( rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_ROP_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ROP_ENABLE; + } + break; + + case GL_NORMALIZE: + R200_STATECHANGE( rmesa, tcl ); + if ( state ) { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_NORMALIZE_NORMALS; + } else { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_NORMALIZE_NORMALS; + } + break; + + /* Pointsize registers on r200 don't seem to do anything. Maybe + * have to pass pointsizes as vertex parameters? In any case, + * setting pointmin == pointsizemax == 1.0, and doing nothing + * for aa is enough to satisfy conform. + */ + case GL_POINT_SMOOTH: + break; + + /* These don't really do anything, as we don't use the 3vtx + * primitives yet. + */ +#if 0 + case GL_POLYGON_OFFSET_POINT: + R200_STATECHANGE( rmesa, set ); + if ( state ) { + rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_ZBIAS_ENABLE_POINT; + } else { + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_POINT; + } + break; + + case GL_POLYGON_OFFSET_LINE: + R200_STATECHANGE( rmesa, set ); + if ( state ) { + rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_ZBIAS_ENABLE_LINE; + } else { + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_LINE; + } + break; +#endif + + case GL_POLYGON_OFFSET_FILL: + R200_STATECHANGE( rmesa, set ); + if ( state ) { + rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_ZBIAS_ENABLE_TRI; + } else { + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_TRI; + } + break; + + case GL_POLYGON_SMOOTH: + R200_STATECHANGE( rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ANTI_ALIAS_POLY; + } else { + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_POLY; + } + break; + + case GL_POLYGON_STIPPLE: + R200_STATECHANGE(rmesa, set ); + if ( state ) { + rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_STIPPLE_ENABLE; + } else { + rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_STIPPLE_ENABLE; + } + break; + + case GL_RESCALE_NORMAL_EXT: { + GLboolean tmp = ctx->_NeedEyeCoords ? state : !state; + R200_STATECHANGE( rmesa, tcl ); + if ( tmp ) { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_RESCALE_NORMALS; + } else { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS; + } + break; + } + + case GL_SCISSOR_TEST: + R200_FIREVERTICES( rmesa ); + rmesa->state.scissor.enabled = state; + r200UpdateScissor( ctx ); + break; + + case GL_STENCIL_TEST: + if ( rmesa->state.stencil.hwBuffer ) { + R200_STATECHANGE( rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_STENCIL_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE; + } + } else { + FALLBACK( rmesa, R200_FALLBACK_STENCIL, state ); + } + break; + + case GL_TEXTURE_GEN_Q: + case GL_TEXTURE_GEN_R: + case GL_TEXTURE_GEN_S: + case GL_TEXTURE_GEN_T: + /* Picked up in r200UpdateTextureState. + */ + rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE; + break; + + case GL_COLOR_SUM_EXT: + r200UpdateSpecular ( ctx ); + break; + + default: + return; + } +} + + +void r200LightingSpaceChange( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLboolean tmp; + + if (R200_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords, + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]); + + if (ctx->_NeedEyeCoords) + tmp = ctx->Transform.RescaleNormals; + else + tmp = !ctx->Transform.RescaleNormals; + + R200_STATECHANGE( rmesa, tcl ); + if ( tmp ) { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_RESCALE_NORMALS; + } else { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS; + } + + if (R200_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords, + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]); +} + +/* ============================================================= + * Deferred state management - matrices, textures, other? + */ + + + + +static void upload_matrix( r200ContextPtr rmesa, GLfloat *src, int idx ) +{ + float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0; + int i; + + + for (i = 0 ; i < 4 ; i++) { + *dest++ = src[i]; + *dest++ = src[i+4]; + *dest++ = src[i+8]; + *dest++ = src[i+12]; + } + + R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] ); +} + +static void upload_matrix_t( r200ContextPtr rmesa, GLfloat *src, int idx ) +{ + float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0; + memcpy(dest, src, 16*sizeof(float)); + R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] ); +} + + +static void update_texturematrix( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + GLuint tpc = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0]; + GLuint compsel = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]; + int unit; + + if (R200_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s before COMPSEL: %x\n", __FUNCTION__, + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]); + + rmesa->TexMatEnabled = 0; + rmesa->TexMatCompSel = 0; + + for (unit = 0 ; unit < 2; unit++) { + if (!ctx->Texture.Unit[unit]._ReallyEnabled) + continue; + + if (ctx->TextureMatrix[unit].type != MATRIX_IDENTITY) { + rmesa->TexMatEnabled |= (R200_TEXGEN_TEXMAT_0_ENABLE| + R200_TEXMAT_0_ENABLE) << unit; + + rmesa->TexMatCompSel |= R200_OUTPUT_TEX_0 << unit; + + if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) { + /* Need to preconcatenate any active texgen + * obj/eyeplane matrices: + */ + _math_matrix_mul_matrix( &rmesa->tmpmat, + &rmesa->TexGenMatrix[unit], + &ctx->TextureMatrix[unit] ); + upload_matrix( rmesa, rmesa->tmpmat.m, R200_MTX_TEX0+unit ); + } + else { + upload_matrix( rmesa, ctx->TextureMatrix[unit].m, + R200_MTX_TEX0+unit ); + } + } + else if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) { + upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m, + R200_MTX_TEX0+unit ); + } + } + + tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled); + if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] || + rmesa->TexGenInputs != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1]) { + R200_STATECHANGE(rmesa, tcg); + rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = tpc; + rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = rmesa->TexGenInputs; + } + + compsel &= ~R200_OUTPUT_TEX_MASK; + compsel |= rmesa->TexMatCompSel | rmesa->TexGenCompSel; + if (compsel != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]) { + R200_STATECHANGE(rmesa, vtx); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = compsel; + } +} + + + +void r200ValidateState( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint new_state = rmesa->NewGLState; + + if (new_state & _NEW_TEXTURE) { + r200UpdateTextureState( ctx ); + new_state |= rmesa->NewGLState; /* may add TEXTURE_MATRIX */ + } + + /* Need an event driven matrix update? + */ + if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) + upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, R200_MTX_MVP ); + + /* Need these for lighting (shouldn't upload otherwise) + */ + if (new_state & (_NEW_MODELVIEW)) { + upload_matrix( rmesa, ctx->ModelView.m, R200_MTX_MV ); + upload_matrix_t( rmesa, ctx->ModelView.inv, R200_MTX_IMV ); + } + + /* Does this need to be triggered on eg. modelview for + * texgen-derived objplane/eyeplane matrices? + */ + if (new_state & (_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) { + update_texturematrix( ctx ); + } + + if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) { + update_light( ctx ); + } + + /* emit all active clip planes if projection matrix changes. + */ + if (new_state & (_NEW_PROJECTION)) { + if (ctx->Transform._AnyClip) + r200UpdateClipPlanes( ctx ); + } + + + rmesa->NewGLState = 0; +} + + +static void r200InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + _ae_invalidate_state( ctx, new_state ); + R200_CONTEXT(ctx)->NewGLState |= new_state; + r200VtxfmtInvalidate( ctx ); +} + +static void r200WrapRunPipeline( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (0) + fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->NewGLState); + + /* Validate state: + */ + if (rmesa->NewGLState) + r200ValidateState( ctx ); + + if (tnl->vb.Material) { + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE ); + } + + /* Run the pipeline. + */ + _tnl_run_pipeline( ctx ); + + if (tnl->vb.Material) { + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_FALSE ); + r200UpdateMaterial( ctx ); /* not needed any more? */ + } +} + + +/* Initialize the driver's state functions. + */ +void r200InitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = r200InvalidateState; + ctx->Driver.LightingSpaceChange = r200LightingSpaceChange; + + ctx->Driver.SetDrawBuffer = r200SetDrawBuffer; + + ctx->Driver.AlphaFunc = r200AlphaFunc; + ctx->Driver.BlendEquation = r200BlendEquation; + ctx->Driver.BlendFunc = r200BlendFunc; + ctx->Driver.BlendFuncSeparate = r200BlendFuncSeparate; + ctx->Driver.ClearColor = r200ClearColor; + ctx->Driver.ClearDepth = NULL; + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearStencil = r200ClearStencil; + ctx->Driver.ClipPlane = r200ClipPlane; + ctx->Driver.ColorMask = r200ColorMask; + ctx->Driver.CullFace = r200CullFace; + ctx->Driver.DepthFunc = r200DepthFunc; + ctx->Driver.DepthMask = r200DepthMask; + ctx->Driver.DepthRange = r200DepthRange; + ctx->Driver.Enable = r200Enable; + ctx->Driver.Fogfv = r200Fogfv; + ctx->Driver.FrontFace = r200FrontFace; + ctx->Driver.Hint = NULL; + ctx->Driver.IndexMask = NULL; + ctx->Driver.LightModelfv = r200LightModelfv; + ctx->Driver.Lightfv = r200Lightfv; + ctx->Driver.LineStipple = r200LineStipple; + ctx->Driver.LineWidth = r200LineWidth; + ctx->Driver.LogicOpcode = r200LogicOpCode; + ctx->Driver.PolygonMode = r200PolygonMode; + ctx->Driver.PolygonOffset = r200PolygonOffset; + ctx->Driver.PolygonStipple = r200PolygonStipple; + ctx->Driver.PointSize = r200PointSize; + ctx->Driver.RenderMode = r200RenderMode; + ctx->Driver.Scissor = r200Scissor; + ctx->Driver.ShadeModel = r200ShadeModel; + ctx->Driver.StencilFunc = r200StencilFunc; + ctx->Driver.StencilMask = r200StencilMask; + ctx->Driver.StencilOp = r200StencilOp; + ctx->Driver.Viewport = r200Viewport; + + /* Swrast hooks for imaging extensions: + */ + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = r200UpdateMaterial; + TNL_CONTEXT(ctx)->Driver.RunPipeline = r200WrapRunPipeline; +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_state.h b/xc/lib/GL/mesa/src/drv/r200/r200_state.h new file mode 100644 index 000000000..059823f38 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_state.h @@ -0,0 +1,68 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_state.h,v 1.2 2002/11/05 17:46:08 tsi Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_STATE_H__ +#define __R200_STATE_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "r200_context.h" + +extern void r200InitState( r200ContextPtr rmesa ); +extern void r200InitStateFuncs( GLcontext *ctx ); + +extern void r200UpdateMaterial( GLcontext *ctx ); + +extern void r200SetCliprects( r200ContextPtr rmesa, GLenum mode ); +extern void r200RecalcScissorRects( r200ContextPtr rmesa ); +extern void r200UpdateViewportOffset( GLcontext *ctx ); +extern void r200UpdateWindow( GLcontext *ctx ); + +extern void r200ValidateState( GLcontext *ctx ); + +extern void r200PrintDirty( r200ContextPtr rmesa, + const char *msg ); + + +extern void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +#define FALLBACK( rmesa, bit, mode ) do { \ + if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \ + __FUNCTION__, bit, mode ); \ + r200Fallback( rmesa->glCtx, bit, mode ); \ +} while (0) + +extern void r200LightingSpaceChange( GLcontext *ctx ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c b/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c new file mode 100644 index 000000000..7f63d80ed --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c @@ -0,0 +1,688 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_state_init.c,v 1.4 2003/02/22 06:21:11 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_ioctl.h" +#include "r200_state.h" +#include "r200_tcl.h" +#include "r200_tex.h" +#include "r200_swtcl.h" +#include "r200_vtxfmt.h" + +#include "mem.h" +#include "mmath.h" +#include "enums.h" +#include "colormac.h" +#include "light.h" +#include "api_arrayelt.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "swrast_setup/swrast_setup.h" + +/* ============================================================= + * State initialization + */ + +void r200PrintDirty( r200ContextPtr rmesa, const char *msg ) +{ + struct r200_state_atom *l; + + fprintf(stderr, msg); + fprintf(stderr, ": "); + + foreach(l, &(rmesa->hw.dirty)) { + fprintf(stderr, "%s, ", l->name); + } + + fprintf(stderr, "\n"); +} + +static int cmdpkt( int id ) +{ + drmRadeonCmdHeader h; + h.i = 0; + h.packet.cmd_type = RADEON_CMD_PACKET; + h.packet.packet_id = id; + return h.i; +} + +static int cmdvec( int offset, int stride, int count ) +{ + drmRadeonCmdHeader h; + h.i = 0; + h.vectors.cmd_type = RADEON_CMD_VECTORS; + h.vectors.offset = offset; + h.vectors.stride = stride; + h.vectors.count = count; + return h.i; +} + +static int cmdscl( int offset, int stride, int count ) +{ + drmRadeonCmdHeader h; + h.i = 0; + h.scalars.cmd_type = RADEON_CMD_SCALARS; + h.scalars.offset = offset; + h.scalars.stride = stride; + h.scalars.count = count; + return h.i; +} + +static int cmdscl2( int offset, int stride, int count ) +{ + drmRadeonCmdHeader h; + h.i = 0; + h.scalars.cmd_type = RADEON_CMD_SCALARS2; + h.scalars.offset = offset - 0x100; + h.scalars.stride = stride; + h.scalars.count = count; + return h.i; +} + +#define CHECK( NM, FLAG ) \ +static GLboolean check_##NM( GLcontext *ctx, int idx ) \ +{ \ + (void) idx; \ + return FLAG; \ +} + +#define TCL_CHECK( NM, FLAG ) \ +static GLboolean check_##NM( GLcontext *ctx, int idx ) \ +{ \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ + (void) idx; \ + return !rmesa->TclFallback && (FLAG); \ +} + + + +CHECK( always, GL_TRUE ) +CHECK( tex_any, ctx->Texture._ReallyEnabled ) +CHECK( tex, ctx->Texture.Unit[idx]._ReallyEnabled ) +CHECK( fog, ctx->Fog.Enabled ) +TCL_CHECK( tcl, GL_TRUE ) +TCL_CHECK( tcl_tex_any, ctx->Texture._ReallyEnabled ) +TCL_CHECK( tcl_tex, ctx->Texture.Unit[idx]._ReallyEnabled ) +TCL_CHECK( tcl_lighting, ctx->Light.Enabled ) +TCL_CHECK( tcl_eyespace_or_lighting, ctx->_NeedEyeCoords || ctx->Light.Enabled ) +TCL_CHECK( tcl_light, ctx->Light.Enabled && ctx->Light.Light[idx].Enabled ) +TCL_CHECK( tcl_ucp, ctx->Transform.ClipEnabled[idx] ) +/* TCL_CHECK( tcl_eyespace_or_fog, ctx->_NeedEyeCoords || ctx->Fog.Enabled ) */ + + +static GLboolean check_tcl_eyespace_or_fog( GLcontext *ctx, int idx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + int res; + (void) idx; + res = !rmesa->TclFallback && (ctx->_NeedEyeCoords || ctx->Fog.Enabled); + fprintf(stderr, "%s: %d\n", __FUNCTION__, res); + return res; +} + + +/* Initialize the context's hardware state. + */ +void r200InitState( r200ContextPtr rmesa ) +{ + GLcontext *ctx = rmesa->glCtx; + GLuint color_fmt, depth_fmt, i; + + switch ( rmesa->r200Screen->cpp ) { + case 2: + color_fmt = R200_COLOR_FORMAT_RGB565; + break; + case 4: + color_fmt = R200_COLOR_FORMAT_ARGB8888; + break; + default: + fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); + exit( -1 ); + } + + rmesa->state.color.clear = 0x00000000; + + switch ( ctx->Visual.depthBits ) { + case 16: + rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff; + depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z; + rmesa->state.stencil.clear = 0x00000000; + break; + case 24: + rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff; + depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z; + rmesa->state.stencil.clear = 0xff000000; + break; + default: + fprintf( stderr, "Error: Unsupported depth %d... exiting\n", + ctx->Visual.depthBits ); + exit( -1 ); + } + + /* Only have hw stencil when depth buffer is 24 bits deep */ + rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && + ctx->Visual.depthBits == 24 ); + + rmesa->Fallback = 0; + + if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { + rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch; + } else { + rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; + rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch; + } + + rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset; + rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch; + + /* Initialize lists: + */ + make_empty_list(&(rmesa->hw.dirty)); rmesa->hw.dirty.name = "DIRTY"; + make_empty_list(&(rmesa->hw.clean)); rmesa->hw.clean.name = "CLEAN"; + + +#define ALLOC_STATE( ATOM, CHK, SZ, NM, IDX ) \ + do { \ + rmesa->hw.ATOM.cmd_size = SZ; \ + rmesa->hw.ATOM.cmd = (int *)CALLOC(SZ * sizeof(int)); \ + rmesa->hw.ATOM.lastcmd = (int *)CALLOC(SZ * sizeof(int)); \ + rmesa->hw.ATOM.name = NM; \ + rmesa->hw.ATOM.idx = IDX; \ + rmesa->hw.ATOM.check = check_##CHK; \ + insert_at_head(&(rmesa->hw.dirty), &(rmesa->hw.ATOM)); \ + } while (0) + + + /* Allocate state buffers: + */ + ALLOC_STATE( ctx, always, CTX_STATE_SIZE, "CTX/context", 0 ); + ALLOC_STATE( set, always, SET_STATE_SIZE, "SET/setup", 0 ); + ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 ); + ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 ); + ALLOC_STATE( vpt, always, VPT_STATE_SIZE, "VPT/viewport", 0 ); + ALLOC_STATE( vtx, always, VTX_STATE_SIZE, "VTX/vertex", 0 ); + ALLOC_STATE( vap, always, VAP_STATE_SIZE, "VAP/vap", 0 ); + ALLOC_STATE( vte, always, VTE_STATE_SIZE, "VTE/vte", 0 ); + ALLOC_STATE( msc, always, MSC_STATE_SIZE, "MSC/misc", 0 ); + ALLOC_STATE( cst, always, CST_STATE_SIZE, "CST/constant", 0 ); + ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 ); + ALLOC_STATE( tam, tex_any, TAM_STATE_SIZE, "TAM/tam", 0 ); + ALLOC_STATE( tf, tex_any, TF_STATE_SIZE, "TF/tfactor", 0 ); + ALLOC_STATE( tex[0], tex_any, TEX_STATE_SIZE, "TEX/tex-0", 0 ); + ALLOC_STATE( tex[1], tex_any, TEX_STATE_SIZE, "TEX/tex-1", 1 ); + + ALLOC_STATE( tcl, tcl, TCL_STATE_SIZE, "TCL/tcl", 0 ); + ALLOC_STATE( msl, tcl, MSL_STATE_SIZE, "MSL/matrix-select", 0 ); + ALLOC_STATE( tcg, tcl, TCG_STATE_SIZE, "TCG/texcoordgen", 0 ); + ALLOC_STATE( mtl[0], tcl_lighting, MTL_STATE_SIZE, "MTL0/material0", 0 ); + ALLOC_STATE( grd, tcl, GRD_STATE_SIZE, "GRD/guard-band", 0 ); + ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 0 ); + ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 0 ); + ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 0 ); + ALLOC_STATE( mat[R200_MTX_MV], tcl, MAT_STATE_SIZE, "MAT/modelview", 0 ); + ALLOC_STATE( mat[R200_MTX_IMV], tcl, MAT_STATE_SIZE, "MAT/it-modelview", 0 ); + ALLOC_STATE( mat[R200_MTX_MVP], tcl, MAT_STATE_SIZE, "MAT/modelproject", 0 ); + ALLOC_STATE( mat[R200_MTX_TEX0], tcl_tex, MAT_STATE_SIZE, "MAT/texmat0", 0 ); + ALLOC_STATE( mat[R200_MTX_TEX1], tcl_tex, MAT_STATE_SIZE, "MAT/texmat1", 1 ); + ALLOC_STATE( ucp[0], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-0", 0 ); + ALLOC_STATE( ucp[1], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-1", 1 ); + ALLOC_STATE( ucp[2], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-2", 2 ); + ALLOC_STATE( ucp[3], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-3", 3 ); + ALLOC_STATE( ucp[4], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-4", 4 ); + ALLOC_STATE( ucp[5], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-5", 5 ); + ALLOC_STATE( lit[0], tcl_light, LIT_STATE_SIZE, "LIT/light-0", 0 ); + ALLOC_STATE( lit[1], tcl_light, LIT_STATE_SIZE, "LIT/light-1", 1 ); + ALLOC_STATE( lit[2], tcl_light, LIT_STATE_SIZE, "LIT/light-2", 2 ); + ALLOC_STATE( lit[3], tcl_light, LIT_STATE_SIZE, "LIT/light-3", 3 ); + ALLOC_STATE( lit[4], tcl_light, LIT_STATE_SIZE, "LIT/light-4", 4 ); + ALLOC_STATE( lit[5], tcl_light, LIT_STATE_SIZE, "LIT/light-5", 5 ); + ALLOC_STATE( lit[6], tcl_light, LIT_STATE_SIZE, "LIT/light-6", 6 ); + ALLOC_STATE( lit[7], tcl_light, LIT_STATE_SIZE, "LIT/light-7", 7 ); + ALLOC_STATE( pix[0], always, PIX_STATE_SIZE, "PIX/pixstage-0", 0 ); + ALLOC_STATE( pix[1], tex, PIX_STATE_SIZE, "PIX/pixstage-1", 1 ); + + + /* Fill in the packet headers: + */ + rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(RADEON_EMIT_PP_MISC); + rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(RADEON_EMIT_PP_CNTL); + rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(RADEON_EMIT_RB3D_COLORPITCH); + rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(RADEON_EMIT_RE_LINE_PATTERN); + rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(RADEON_EMIT_SE_LINE_WIDTH); + rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(RADEON_EMIT_RB3D_STENCILREFMASK); + rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(RADEON_EMIT_SE_VPORT_XSCALE); + rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(RADEON_EMIT_SE_CNTL); + rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(RADEON_EMIT_RE_MISC); + rmesa->hw.cst.cmd[CST_CMD_0] = cmdpkt(R200_EMIT_PP_CNTL_X); + rmesa->hw.cst.cmd[CST_CMD_1] = cmdpkt(R200_EMIT_RB3D_DEPTHXY_OFFSET); + rmesa->hw.cst.cmd[CST_CMD_2] = cmdpkt(R200_EMIT_RE_AUX_SCISSOR_CNTL); + rmesa->hw.cst.cmd[CST_CMD_3] = cmdpkt(R200_EMIT_RE_SCISSOR_TL_0); + rmesa->hw.cst.cmd[CST_CMD_4] = cmdpkt(R200_EMIT_SE_VAP_CNTL_STATUS); + rmesa->hw.cst.cmd[CST_CMD_5] = cmdpkt(R200_EMIT_RE_POINTSIZE); + rmesa->hw.cst.cmd[CST_CMD_6] = cmdpkt(R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0); + rmesa->hw.tam.cmd[TAM_CMD_0] = cmdpkt(R200_EMIT_PP_TAM_DEBUG3); + rmesa->hw.tf.cmd[TF_CMD_0] = cmdpkt(R200_EMIT_TFACTOR_0); + rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_0); + rmesa->hw.tex[0].cmd[TEX_CMD_1] = cmdpkt(R200_EMIT_PP_TXOFFSET_0); + rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(R200_EMIT_PP_TXFILTER_1); + rmesa->hw.tex[1].cmd[TEX_CMD_1] = cmdpkt(R200_EMIT_PP_TXOFFSET_1); + rmesa->hw.pix[0].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_0); + rmesa->hw.pix[1].cmd[PIX_CMD_0] = cmdpkt(R200_EMIT_PP_TXCBLEND_1); + rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(RADEON_EMIT_SE_ZBIAS_FACTOR); + rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(R200_EMIT_TCL_LIGHT_MODEL_CTL_0); + rmesa->hw.tcl.cmd[TCL_CMD_1] = cmdpkt(R200_EMIT_TCL_UCP_VERT_BLEND_CTL); + rmesa->hw.tcg.cmd[TCG_CMD_0] = cmdpkt(R200_EMIT_TEX_PROC_CTL_2); + rmesa->hw.msl.cmd[MSL_CMD_0] = cmdpkt(R200_EMIT_MATRIX_SELECT_0); + rmesa->hw.vap.cmd[VAP_CMD_0] = cmdpkt(R200_EMIT_VAP_CTL); + rmesa->hw.vtx.cmd[VTX_CMD_0] = cmdpkt(R200_EMIT_VTX_FMT_0); + rmesa->hw.vtx.cmd[VTX_CMD_1] = cmdpkt(R200_EMIT_OUTPUT_VTX_COMP_SEL); + rmesa->hw.vtx.cmd[VTX_CMD_2] = cmdpkt(R200_EMIT_SE_VTX_STATE_CNTL); + rmesa->hw.vte.cmd[VTE_CMD_0] = cmdpkt(R200_EMIT_VTE_CNTL); + rmesa->hw.mtl[0].cmd[MTL_CMD_0] = + cmdvec( R200_VS_MAT_0_EMISS, 1, 16 ); + rmesa->hw.mtl[0].cmd[MTL_CMD_1] = + cmdscl2( R200_SS_MAT_0_SHININESS, 1, 1 ); + rmesa->hw.grd.cmd[GRD_CMD_0] = + cmdscl( R200_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 ); + rmesa->hw.fog.cmd[FOG_CMD_0] = + cmdvec( R200_VS_FOG_PARAM_ADDR, 1, 4 ); + rmesa->hw.glt.cmd[GLT_CMD_0] = + cmdvec( R200_VS_GLOBAL_AMBIENT_ADDR, 1, 4 ); + rmesa->hw.eye.cmd[EYE_CMD_0] = + cmdvec( R200_VS_EYE_VECTOR_ADDR, 1, 4 ); + + rmesa->hw.mat[R200_MTX_MV].cmd[MAT_CMD_0] = + cmdvec( R200_VS_MATRIX_0_MV, 1, 16); + rmesa->hw.mat[R200_MTX_IMV].cmd[MAT_CMD_0] = + cmdvec( R200_VS_MATRIX_1_INV_MV, 1, 16); + rmesa->hw.mat[R200_MTX_MVP].cmd[MAT_CMD_0] = + cmdvec( R200_VS_MATRIX_2_MVP, 1, 16); + rmesa->hw.mat[R200_MTX_TEX0].cmd[MAT_CMD_0] = + cmdvec( R200_VS_MATRIX_3_TEX0, 1, 16); + rmesa->hw.mat[R200_MTX_TEX1].cmd[MAT_CMD_0] = + cmdvec( R200_VS_MATRIX_4_TEX1, 1, 16); + + for (i = 0 ; i < 8; i++) { + rmesa->hw.lit[i].cmd[LIT_CMD_0] = + cmdvec( R200_VS_LIGHT_AMBIENT_ADDR + i, 8, 24 ); + rmesa->hw.lit[i].cmd[LIT_CMD_1] = + cmdscl( R200_SS_LIGHT_DCD_ADDR + i, 8, 7 ); + } + + for (i = 0 ; i < 6; i++) { + rmesa->hw.ucp[i].cmd[UCP_CMD_0] = + cmdvec( R200_VS_UCP_ADDR + i, 1, 4 ); + } + + /* Initial Harware state: + */ + rmesa->hw.ctx.cmd[CTX_PP_MISC] = (R200_ALPHA_TEST_PASS | + R200_RIGHT_HAND_CUBE_OGL); + + rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = (R200_FOG_VERTEX | + R200_FOG_USE_SPEC_ALPHA); + + rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000; + + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = (R200_COMB_FCN_ADD_CLAMP | + R200_SRC_BLEND_GL_ONE | + R200_DST_BLEND_GL_ZERO ); + + rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHOFFSET] = + rmesa->r200Screen->depthOffset; + + rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHPITCH] = + ((rmesa->r200Screen->depthPitch & + R200_DEPTHPITCH_MASK) | + R200_DEPTH_ENDIAN_NO_SWAP); + + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (depth_fmt | + R200_Z_TEST_LESS | + R200_STENCIL_TEST_ALWAYS | + R200_STENCIL_FAIL_KEEP | + R200_STENCIL_ZPASS_KEEP | + R200_STENCIL_ZFAIL_KEEP | + R200_Z_WRITE_ENABLE); + + rmesa->hw.ctx.cmd[CTX_PP_CNTL] = (R200_ANTI_ALIAS_NONE + | R200_TEX_BLEND_0_ENABLE); + + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = color_fmt; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_DITHER_ENABLE; + + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = (rmesa->state.color.drawOffset & + R200_COLOROFFSET_MASK); + + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch & + R200_COLORPITCH_MASK) | + R200_COLOR_ENDIAN_NO_SWAP); + + rmesa->hw.set.cmd[SET_SE_CNTL] = (R200_FFACE_CULL_CCW | + R200_BFACE_SOLID | + R200_FFACE_SOLID | + R200_FLAT_SHADE_VTX_LAST | + R200_DIFFUSE_SHADE_GOURAUD | + R200_ALPHA_SHADE_GOURAUD | + R200_SPECULAR_SHADE_GOURAUD | + R200_FOG_SHADE_GOURAUD | + R200_VTX_PIX_CENTER_OGL | + R200_ROUND_MODE_TRUNC | + R200_ROUND_PREC_8TH_PIX); + + rmesa->hw.set.cmd[SET_RE_CNTL] = (R200_PERSPECTIVE_ENABLE | + R200_SCISSOR_ENABLE); + + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = ((1 << 16) | 0xffff); + + rmesa->hw.lin.cmd[LIN_RE_LINE_STATE] = + ((0 << R200_LINE_CURRENT_PTR_SHIFT) | + (1 << R200_LINE_CURRENT_COUNT_SHIFT)); + + rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (1 << 4); + + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] = + ((0x00 << R200_STENCIL_REF_SHIFT) | + (0xff << R200_STENCIL_MASK_SHIFT) | + (0xff << R200_STENCIL_WRITEMASK_SHIFT)); + + rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = R200_ROP_COPY; + rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = 0xffffffff; + + rmesa->hw.tam.cmd[TAM_DEBUG3] = 0; + + rmesa->hw.msc.cmd[MSC_RE_MISC] = + ((0 << R200_STIPPLE_X_OFFSET_SHIFT) | + (0 << R200_STIPPLE_Y_OFFSET_SHIFT) | + R200_STIPPLE_BIG_BIT_ORDER); + + + rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0; + rmesa->hw.cst.cmd[CST_RB3D_DEPTHXY_OFFSET] = 0; + rmesa->hw.cst.cmd[CST_RE_AUX_SCISSOR_CNTL] = 0x0; + rmesa->hw.cst.cmd[CST_RE_SCISSOR_TL_0] = 0; + rmesa->hw.cst.cmd[CST_RE_SCISSOR_BR_0] = 0; + rmesa->hw.cst.cmd[CST_SE_VAP_CNTL_STATUS] = +#ifdef MESA_BIG_ENDIAN + R200_VC_32BIT_SWAP; +#else + R200_VC_NO_SWAP; +#endif + rmesa->hw.cst.cmd[CST_RE_POINTSIZE] = 0x100010; + rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_0] = + (0x0 << R200_VERTEX_POSITION_ADDR__SHIFT); + rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_1] = + (0x02 << R200_VTX_COLOR_0_ADDR__SHIFT) | + (0x03 << R200_VTX_COLOR_1_ADDR__SHIFT); + rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_2] = + (0x06 << R200_VTX_TEX_0_ADDR__SHIFT) | + (0x07 << R200_VTX_TEX_1_ADDR__SHIFT) | + (0x08 << R200_VTX_TEX_2_ADDR__SHIFT) | + (0x09 << R200_VTX_TEX_3_ADDR__SHIFT); + rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_3] = + (0x0A << R200_VTX_TEX_4_ADDR__SHIFT) | + (0x0B << R200_VTX_TEX_5_ADDR__SHIFT); + + + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = 0x00000000; + + rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] = R200_BORDER_MODE_OGL; + rmesa->hw.tex[0].cmd[TEX_PP_TXFORMAT] = + (R200_TXFORMAT_ST_ROUTE_STQ0 | + (2 << R200_TXFORMAT_WIDTH_SHIFT) | + (2 << R200_TXFORMAT_HEIGHT_SHIFT)); + rmesa->hw.tex[0].cmd[TEX_PP_TXOFFSET] = 0; + rmesa->hw.tex[0].cmd[TEX_PP_BORDER_COLOR] = 0; + rmesa->hw.tex[0].cmd[TEX_PP_TXFORMAT_X] = + (/* R200_TEXCOORD_PROJ | */ + 0x100000); /* Small default bias */ + + rmesa->hw.pix[0].cmd[PIX_PP_TXCBLEND] = + (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_DIFFUSE_COLOR | + R200_TXC_OP_MADD); + + rmesa->hw.pix[0].cmd[PIX_PP_TXCBLEND2] = + ((0 << R200_TXC_TFACTOR_SEL_SHIFT) | + R200_TXC_SCALE_1X | + R200_TXC_CLAMP_0_1 | + R200_TXC_OUTPUT_REG_R0); + + rmesa->hw.pix[0].cmd[PIX_PP_TXABLEND] = + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_DIFFUSE_ALPHA | + R200_TXA_OP_MADD); + + rmesa->hw.pix[0].cmd[PIX_PP_TXABLEND2] = + ((0 << R200_TXA_TFACTOR_SEL_SHIFT) | + R200_TXA_SCALE_1X | + R200_TXA_CLAMP_0_1 | + R200_TXA_OUTPUT_REG_R0); + + rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] = R200_BORDER_MODE_OGL; + rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] = + (R200_TXFORMAT_ST_ROUTE_STQ1 | + (2 << R200_TXFORMAT_WIDTH_SHIFT) | + (2 << R200_TXFORMAT_HEIGHT_SHIFT)); + rmesa->hw.tex[1].cmd[TEX_PP_TXOFFSET] = 0; + rmesa->hw.tex[1].cmd[TEX_PP_BORDER_COLOR] = 0; + rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT_X] = + (/* R200_TEXCOORD_PROJ | */ + 0x100000); /* Small default bias */ + + rmesa->hw.pix[1].cmd[PIX_PP_TXCBLEND] = + (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_DIFFUSE_COLOR | + R200_TXC_OP_MADD); + + rmesa->hw.pix[1].cmd[PIX_PP_TXCBLEND2] = + ((0 << R200_TXC_TFACTOR_SEL_SHIFT) | + R200_TXC_SCALE_1X | + R200_TXC_CLAMP_0_1 | + R200_TXC_OUTPUT_REG_R0); + + rmesa->hw.pix[1].cmd[PIX_PP_TXABLEND] = + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_DIFFUSE_ALPHA | + R200_TXA_OP_MADD); + + rmesa->hw.pix[1].cmd[PIX_PP_TXABLEND2] = + ((0 << R200_TXA_TFACTOR_SEL_SHIFT) | + R200_TXA_SCALE_1X | + R200_TXA_CLAMP_0_1 | + R200_TXA_OUTPUT_REG_R0); + + rmesa->hw.tf.cmd[TF_TFACTOR_0] = 0; + rmesa->hw.tf.cmd[TF_TFACTOR_1] = 0; + rmesa->hw.tf.cmd[TF_TFACTOR_2] = 0; + rmesa->hw.tf.cmd[TF_TFACTOR_3] = 0; + rmesa->hw.tf.cmd[TF_TFACTOR_4] = 0; + rmesa->hw.tf.cmd[TF_TFACTOR_5] = 0; + + rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = + (R200_VAP_TCL_ENABLE | + (0x9 << R200_VAP_VF_MAX_VTX_NUM__SHIFT)); + + rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = + (R200_VPORT_X_SCALE_ENA | + R200_VPORT_Y_SCALE_ENA | + R200_VPORT_Z_SCALE_ENA | + R200_VPORT_X_OFFSET_ENA | + R200_VPORT_Y_OFFSET_ENA | + R200_VPORT_Z_OFFSET_ENA | +/* FIXME: Turn on for tex rect only */ + R200_VTX_ST_DENORMALIZED | + R200_VTX_W0_FMT); + + + rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = 0; + rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = 0; + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] = + ((R200_VTX_Z0 | R200_VTX_W0 | + (R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT))); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] = 0; + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = (R200_OUTPUT_XYZW); + rmesa->hw.vtx.cmd[VTX_STATE_CNTL] = R200_VSC_UPDATE_USER_COLOR_0_ENABLE; + + + /* Matrix selection */ + rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_0] = + (R200_MTX_MV << R200_MODELVIEW_0_SHIFT); + + rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_1] = + (R200_MTX_IMV << R200_IT_MODELVIEW_0_SHIFT); + + rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_2] = + (R200_MTX_MVP << R200_MODELPROJECT_0_SHIFT); + + rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_3] = + ((R200_MTX_TEX0 << R200_TEXMAT_0_SHIFT) | + (R200_MTX_TEX1 << R200_TEXMAT_1_SHIFT) | + (R200_MTX_TEX2 << R200_TEXMAT_2_SHIFT) | + (R200_MTX_TEX3 << R200_TEXMAT_3_SHIFT)); + + rmesa->hw.msl.cmd[MSL_MATRIX_SELECT_4] = + ((R200_MTX_TEX4 << R200_TEXMAT_4_SHIFT) | + (R200_MTX_TEX5 << R200_TEXMAT_5_SHIFT)); + + + /* General TCL state */ + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] = + (R200_SPECULAR_LIGHTS | + R200_DIFFUSE_SPECULAR_COMBINE | + R200_LOCAL_LIGHT_VEC_GL); + + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = + ((R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_AMBIENT_SOURCE_SHIFT) | + (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_DIFFUSE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_SPECULAR_SOURCE_SHIFT) | + (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_EMISSIVE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_AMBIENT_SOURCE_SHIFT) | + (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_DIFFUSE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_SPECULAR_SOURCE_SHIFT)); + + rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_0] = 0; /* filled in via callbacks */ + rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_1] = 0; + rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_2] = 0; + rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_3] = 0; + + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = + (R200_UCP_IN_CLIP_SPACE | + R200_CULL_FRONT_IS_CCW); + + /* Texgen/Texmat state */ + rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = 0x0; /* masks??? */ + rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_3] = + ((0 << R200_TEXGEN_0_INPUT_TEX_SHIFT) | + (1 << R200_TEXGEN_1_INPUT_TEX_SHIFT) | + (2 << R200_TEXGEN_2_INPUT_TEX_SHIFT) | + (3 << R200_TEXGEN_3_INPUT_TEX_SHIFT) | + (4 << R200_TEXGEN_4_INPUT_TEX_SHIFT) | + (5 << R200_TEXGEN_5_INPUT_TEX_SHIFT)); + rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = 0; + rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = + ((0 << R200_TEXGEN_0_INPUT_SHIFT) | + (1 << R200_TEXGEN_1_INPUT_SHIFT) | + (2 << R200_TEXGEN_2_INPUT_SHIFT) | + (3 << R200_TEXGEN_3_INPUT_SHIFT) | + (4 << R200_TEXGEN_4_INPUT_SHIFT) | + (5 << R200_TEXGEN_5_INPUT_SHIFT)); + rmesa->hw.tcg.cmd[TCG_TEX_CYL_WRAP_CTL] = 0; + + rmesa->TexGenInputs = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1]; + + + for (i = 0 ; i < 8; i++) { + struct gl_light *l = &ctx->Light.Light[i]; + GLenum p = GL_LIGHT0 + i; + *(float *)&(rmesa->hw.lit[i].cmd[LIT_RANGE_CUTOFF]) = FLT_MAX; + + ctx->Driver.Lightfv( ctx, p, GL_AMBIENT, l->Ambient ); + ctx->Driver.Lightfv( ctx, p, GL_DIFFUSE, l->Diffuse ); + ctx->Driver.Lightfv( ctx, p, GL_SPECULAR, l->Specular ); + ctx->Driver.Lightfv( ctx, p, GL_POSITION, 0 ); + ctx->Driver.Lightfv( ctx, p, GL_SPOT_DIRECTION, 0 ); + ctx->Driver.Lightfv( ctx, p, GL_SPOT_EXPONENT, &l->SpotExponent ); + ctx->Driver.Lightfv( ctx, p, GL_SPOT_CUTOFF, &l->SpotCutoff ); + ctx->Driver.Lightfv( ctx, p, GL_CONSTANT_ATTENUATION, + &l->ConstantAttenuation ); + ctx->Driver.Lightfv( ctx, p, GL_LINEAR_ATTENUATION, + &l->LinearAttenuation ); + ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION, + &l->QuadraticAttenuation ); + } + + ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT, + ctx->Light.Model.Ambient ); + + TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx ); + + for (i = 0 ; i < 6; i++) { + ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, NULL ); + } + + ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); + ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); + ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); + ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); + ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); + ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, 0 ); + + rmesa->hw.grd.cmd[GRD_VERT_GUARD_CLIP_ADJ] = IEEE_ONE; + rmesa->hw.grd.cmd[GRD_VERT_GUARD_DISCARD_ADJ] = IEEE_ONE; + rmesa->hw.grd.cmd[GRD_HORZ_GUARD_CLIP_ADJ] = IEEE_ONE; + rmesa->hw.grd.cmd[GRD_HORZ_GUARD_DISCARD_ADJ] = IEEE_ONE; + + rmesa->hw.eye.cmd[EYE_X] = 0; + rmesa->hw.eye.cmd[EYE_Y] = 0; + rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE; + rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE; + + r200LightingSpaceChange( ctx ); + + rmesa->lost_context = 1; +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c b/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c new file mode 100644 index 000000000..12866dc38 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c @@ -0,0 +1,1277 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c,v 1.3 2002/12/23 15:29:26 tsi Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "enums.h" +#include "mem.h" +#include "mmath.h" +#include "macros.h" +#include "image.h" + +#include "swrast_setup/swrast_setup.h" +#include "swrast/s_fog.h" +#include "math/m_translate.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "r200_context.h" +#include "r200_ioctl.h" +#include "r200_state.h" +#include "r200_swtcl.h" +#include "r200_tcl.h" + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + + +#define R200_XYZW_BIT 0x01 +#define R200_RGBA_BIT 0x02 +#define R200_SPEC_BIT 0x04 +#define R200_TEX0_BIT 0x08 +#define R200_TEX1_BIT 0x10 +#define R200_PTEX_BIT 0x20 +#define R200_MAX_SETUP 0x40 + +static void flush_last_swtcl_prim( r200ContextPtr rmesa ); + +static struct { + void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint ); + interp_func interp; + copy_pv_func copy_pv; + GLboolean (*check_tex_sizes)( GLcontext *ctx ); + GLuint vertex_size; + GLuint vertex_stride_shift; + GLuint vertex_format; +} setup_tab[R200_MAX_SETUP]; + + +static int se_vtx_fmt_0[] = { + 0, + + (R200_VTX_XY | + R200_VTX_Z0 | + (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT)), + + (R200_VTX_XY | + R200_VTX_Z0 | + R200_VTX_W0 | + (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) | + (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)), + + (R200_VTX_XY | + R200_VTX_Z0 | + R200_VTX_W0 | + (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) | + (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)), + + (R200_VTX_XY | + R200_VTX_Z0 | + R200_VTX_W0 | + (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) | + (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)), + + (R200_VTX_XY | + R200_VTX_Z0 | + R200_VTX_W0 | + (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) | + (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)) +}; + +static int se_vtx_fmt_1[] = { + 0, + 0, + 0, + ((2 << R200_VTX_TEX0_COMP_CNT_SHIFT)), + ((2 << R200_VTX_TEX0_COMP_CNT_SHIFT) | + (2 << R200_VTX_TEX1_COMP_CNT_SHIFT)), + ((3 << R200_VTX_TEX0_COMP_CNT_SHIFT) | + (3 << R200_VTX_TEX1_COMP_CNT_SHIFT)), +}; + +#define TINY_VERTEX_FORMAT 1 +#define NOTEX_VERTEX_FORMAT 2 +#define TEX0_VERTEX_FORMAT 3 +#define TEX1_VERTEX_FORMAT 4 +#define PROJ_TEX1_VERTEX_FORMAT 5 +#define TEX2_VERTEX_FORMAT 0 +#define TEX3_VERTEX_FORMAT 0 +#define PROJ_TEX3_VERTEX_FORMAT 0 + +#define DO_XYZW (IND & R200_XYZW_BIT) +#define DO_RGBA (IND & R200_RGBA_BIT) +#define DO_SPEC (IND & R200_SPEC_BIT) +#define DO_FOG (IND & R200_SPEC_BIT) +#define DO_TEX0 (IND & R200_TEX0_BIT) +#define DO_TEX1 (IND & R200_TEX1_BIT) +#define DO_TEX2 0 +#define DO_TEX3 0 +#define DO_PTEX (IND & R200_PTEX_BIT) + +#define VERTEX r200Vertex +#define VERTEX_COLOR r200_color_t +#define GET_VIEWPORT_MAT() 0 +#define GET_TEXSOURCE(n) n +#define GET_VERTEX_FORMAT() R200_CONTEXT(ctx)->swtcl.vertex_format +#define GET_VERTEX_STORE() R200_CONTEXT(ctx)->swtcl.verts +#define GET_VERTEX_STRIDE_SHIFT() R200_CONTEXT(ctx)->swtcl.vertex_stride_shift +#define GET_UBYTE_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteColor +#define GET_UBYTE_SPEC_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteSecondaryColor + +#define HAVE_HW_VIEWPORT 1 +#define HAVE_HW_DIVIDE (IND & ~(R200_XYZW_BIT|R200_RGBA_BIT)) +#define HAVE_TINY_VERTICES 1 +#define HAVE_RGBA_COLOR 1 +#define HAVE_NOTEX_VERTICES 1 +#define HAVE_TEX0_VERTICES 1 +#define HAVE_TEX1_VERTICES 1 +#define HAVE_TEX2_VERTICES 0 +#define HAVE_TEX3_VERTICES 0 +#define HAVE_PTEX_VERTICES 1 + +#define CHECK_HW_DIVIDE (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE| \ + DD_TRI_UNFILLED))) + +#define IMPORT_QUALIFIER +#define IMPORT_FLOAT_COLORS r200_import_float_colors +#define IMPORT_FLOAT_SPEC_COLORS r200_import_float_spec_colors + +#define INTERP_VERTEX setup_tab[R200_CONTEXT(ctx)->swtcl.SetupIndex].interp +#define COPY_PV_VERTEX setup_tab[R200_CONTEXT(ctx)->swtcl.SetupIndex].copy_pv + + +/*********************************************************************** + * Generate pv-copying and translation functions * + ***********************************************************************/ + +#define TAG(x) r200_##x +#define IND ~0 +#include "tnl_dd/t_dd_vb.c" +#undef IND + + +/*********************************************************************** + * Generate vertex emit and interp functions * + ***********************************************************************/ + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT) +#define TAG(x) x##_wg +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_TEX1_BIT|\ + R200_PTEX_BIT) +#define TAG(x) x##_wgpt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\ + R200_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\ + R200_TEX0_BIT|R200_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\ + R200_TEX0_BIT|R200_TEX1_BIT) +#define TAG(x) x##_wgfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\ + R200_TEX0_BIT|R200_TEX1_BIT|R200_PTEX_BIT) +#define TAG(x) x##_wgfspt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static void init_setup_tab( void ) +{ + init_wg(); + init_wgt0(); + init_wgpt0(); + init_wgt0t1(); + init_wgpt0t1(); + init_wgfs(); + init_wgfst0(); + init_wgfspt0(); + init_wgfst0t1(); + init_wgfspt0t1(); +} + + + +void r200PrintSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & R200_XYZW_BIT) ? " xyzw," : "", + (flags & R200_RGBA_BIT) ? " rgba," : "", + (flags & R200_SPEC_BIT) ? " spec/fog," : "", + (flags & R200_TEX0_BIT) ? " tex-0," : "", + (flags & R200_TEX1_BIT) ? " tex-1," : "", + (flags & R200_PTEX_BIT) ? " proj-tex," : ""); +} + + + +static void r200SetVertexFormat( GLcontext *ctx, GLuint ind ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + rmesa->swtcl.SetupIndex = ind; + + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = r200_interp_extras; + tnl->Driver.Render.CopyPV = r200_copy_pv_extras; + } + else { + tnl->Driver.Render.Interp = setup_tab[ind].interp; + tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv; + } + + if (setup_tab[ind].vertex_format != rmesa->swtcl.vertex_format) { + int i; + R200_NEWPRIM(rmesa); + i = rmesa->swtcl.vertex_format = setup_tab[ind].vertex_format; + rmesa->swtcl.vertex_size = setup_tab[ind].vertex_size; + rmesa->swtcl.vertex_stride_shift = setup_tab[ind].vertex_stride_shift; + + R200_STATECHANGE( rmesa, vtx ); + rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = se_vtx_fmt_0[i]; + rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = se_vtx_fmt_1[i]; + } + + { + GLuint vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]; + GLuint vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]; + GLuint needproj; + + /* HW perspective divide is a win, but tiny vertex formats are a + * bigger one. + */ + if (setup_tab[ind].vertex_format == TINY_VERTEX_FORMAT || + (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + needproj = GL_TRUE; + vte |= R200_VTX_XY_FMT | R200_VTX_Z_FMT; + vte &= ~R200_VTX_W0_FMT; + vap |= R200_VAP_FORCE_W_TO_ONE; + } + else { + needproj = GL_FALSE; + vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT); + vte |= R200_VTX_W0_FMT; + vap &= ~R200_VAP_FORCE_W_TO_ONE; + } + + _tnl_need_projected_coords( ctx, needproj ); + if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) { + R200_STATECHANGE( rmesa, vte ); + rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte; + } + if (vap != rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]) { + R200_STATECHANGE( rmesa, vap ); + rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = vap; + } + } +} + +static void r200RenderStart( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + if (!setup_tab[rmesa->swtcl.SetupIndex].check_tex_sizes(ctx)) { + r200SetVertexFormat( ctx, rmesa->swtcl.SetupIndex | R200_PTEX_BIT); + } + + if (rmesa->dma.flush != 0 && + rmesa->dma.flush != flush_last_swtcl_prim) + rmesa->dma.flush( rmesa ); +} + + +void r200BuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + GLubyte *v = ((GLubyte *)rmesa->swtcl.verts + + (start << rmesa->swtcl.vertex_stride_shift)); + GLuint stride = 1 << rmesa->swtcl.vertex_stride_shift; + + newinputs |= rmesa->swtcl.SetupNewInputs; + rmesa->swtcl.SetupNewInputs = 0; + + if (!newinputs) + return; + + setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, v, stride ); +} + + +void r200ChooseVertexState( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + GLuint ind = (R200_XYZW_BIT | R200_RGBA_BIT); + + if (!rmesa->TclFallback || rmesa->Fallback) + return; + + if (ctx->Fog.Enabled || (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)) + ind |= R200_SPEC_BIT; + + if (ctx->Texture._ReallyEnabled & TEXTURE1_ANY) + ind |= R200_TEX0_BIT|R200_TEX1_BIT; + else if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY) + ind |= R200_TEX0_BIT; + + r200SetVertexFormat( ctx, ind ); +} + + +/* Flush vertices in the current dma region. + */ +static void flush_last_swtcl_prim( r200ContextPtr rmesa ) +{ + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->dma.current.buf) { + struct r200_dma_region *current = &rmesa->dma.current; + GLuint current_offset = (rmesa->r200Screen->agp_buffer_offset + + current->buf->buf->idx * RADEON_BUFFER_SIZE + + current->start); + + assert (!(rmesa->swtcl.hw_primitive & R200_VF_PRIM_WALK_IND)); + + assert (current->start + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + current->ptr); + + if (rmesa->dma.current.start != rmesa->dma.current.ptr) { + r200EmitVertexAOS( rmesa, + rmesa->swtcl.vertex_size, + current_offset); + + r200EmitVbufPrim( rmesa, + rmesa->swtcl.hw_primitive, + rmesa->swtcl.numverts); + } + + rmesa->swtcl.numverts = 0; + current->start = current->ptr; + + rmesa->dma.flush = 0; + } +} + + +/* Alloc space in the current dma region. + */ +static __inline void *r200AllocDmaLowVerts( r200ContextPtr rmesa, + int nverts, int vsize ) +{ + GLuint bytes = vsize * nverts; + + if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) + r200RefillCurrentDmaRegion( rmesa ); + + if (!rmesa->dma.flush) { + rmesa->dma.flush = flush_last_swtcl_prim; + } + + ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); + ASSERT( rmesa->dma.flush == flush_last_swtcl_prim ); + ASSERT( rmesa->dma.current.start + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + rmesa->dma.current.ptr ); + + + { + GLubyte *head = rmesa->dma.current.address + rmesa->dma.current.ptr; + rmesa->dma.current.ptr += bytes; + rmesa->swtcl.numverts += nverts; + return head; + } + +} + + + + +void r200_emit_contiguous_verts( GLcontext *ctx, GLuint start, GLuint count ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint vertex_size = rmesa->swtcl.vertex_size * 4; + CARD32 *dest = r200AllocDmaLowVerts( rmesa, count-start, vertex_size ); + setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, dest, + vertex_size ); +} + + + +void r200_emit_indexed_verts( GLcontext *ctx, GLuint start, GLuint count ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + r200AllocDmaRegionVerts( rmesa, + &rmesa->swtcl.indexed_verts, + count - start, + rmesa->swtcl.vertex_size * 4, + 64); + + setup_tab[rmesa->swtcl.SetupIndex].emit( + ctx, start, count, + rmesa->swtcl.indexed_verts.address + rmesa->swtcl.indexed_verts.start, + rmesa->swtcl.vertex_size * 4 ); +} + + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Try to simulate missing primitives with indexed vertices. + */ +#define HAVE_POINTS 1 +#define HAVE_LINES 1 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 +#define HAVE_TRI_FANS 1 +#define HAVE_QUADS 1 +#define HAVE_QUAD_STRIPS 1 +#define HAVE_POLYGONS 1 +#define HAVE_ELTS 1 + +static const GLuint hw_prim[GL_POLYGON+1] = { + R200_VF_PRIM_POINTS, + R200_VF_PRIM_LINES, + 0, + R200_VF_PRIM_LINE_STRIP, + R200_VF_PRIM_TRIANGLES, + R200_VF_PRIM_TRIANGLE_STRIP, + R200_VF_PRIM_TRIANGLE_FAN, + R200_VF_PRIM_QUADS, + R200_VF_PRIM_QUAD_STRIP, + R200_VF_PRIM_POLYGON +}; + +static __inline void r200DmaPrimitive( r200ContextPtr rmesa, GLenum prim ) +{ + R200_NEWPRIM( rmesa ); + rmesa->swtcl.hw_primitive = hw_prim[prim]; + assert(rmesa->dma.current.ptr == rmesa->dma.current.start); +} + +static __inline void r200EltPrimitive( r200ContextPtr rmesa, GLenum prim ) +{ + R200_NEWPRIM( rmesa ); + rmesa->swtcl.hw_primitive = hw_prim[prim] | R200_VF_PRIM_WALK_IND; +} + + +static void VERT_FALLBACK( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK ); + tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 ); + tnl->Driver.Render.PrimTabVerts[flags&PRIM_MODE_MASK]( ctx, start, count, flags ); + R200_CONTEXT(ctx)->swtcl.SetupNewInputs = VERT_CLIP; +} + +static void ELT_FALLBACK( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK ); + tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 ); + tnl->Driver.Render.PrimTabElts[flags&PRIM_MODE_MASK]( ctx, start, count, flags ); + R200_CONTEXT(ctx)->swtcl.SetupNewInputs = VERT_CLIP; +} + + +#define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx) +#define ELTS_VARS GLushort *dest +#define INIT( prim ) r200DmaPrimitive( rmesa, prim ) +#define ELT_INIT(prim) r200EltPrimitive( rmesa, prim ) +#define NEW_PRIMITIVE() R200_NEWPRIM( rmesa ) +#define NEW_BUFFER() r200RefillCurrentDmaRegion( rmesa ) +#define GET_CURRENT_VB_MAX_VERTS() \ + (((int)rmesa->dma.current.end - (int)rmesa->dma.current.ptr) / (rmesa->swtcl.vertex_size*4)) +#define GET_SUBSEQUENT_VB_MAX_VERTS() \ + ((RADEON_BUFFER_SIZE) / (rmesa->swtcl.vertex_size*4)) + +#define GET_CURRENT_VB_MAX_ELTS() \ + ((R200_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2) +#define GET_SUBSEQUENT_VB_MAX_ELTS() \ + ((R200_CMD_BUF_SZ - 1024) / 2) + + + +/* How do you extend an existing primitive? + */ +#define ALLOC_ELTS(nr) \ +do { \ + if (rmesa->dma.flush == r200FlushElts && \ + rmesa->store.cmd_used + nr*2 < R200_CMD_BUF_SZ) { \ + \ + dest = (GLushort *)(rmesa->store.cmd_buf + \ + rmesa->store.cmd_used); \ + rmesa->store.cmd_used += nr*2; \ + } \ + else { \ + if (rmesa->dma.flush) { \ + rmesa->dma.flush( rmesa ); \ + } \ + \ + r200EmitVertexAOS( rmesa, \ + rmesa->swtcl.vertex_size, \ + (rmesa->r200Screen->agp_buffer_offset + \ + rmesa->swtcl.indexed_verts.buf->buf->idx * \ + RADEON_BUFFER_SIZE + \ + rmesa->swtcl.indexed_verts.start)); \ + \ + dest = r200AllocEltsOpenEnded( rmesa, \ + rmesa->swtcl.hw_primitive, \ + nr ); \ + } \ +} while (0) + +#define ALLOC_ELTS_NEW_PRIMITIVE(nr) ALLOC_ELTS( nr ) + +#ifdef MESA_BIG_ENDIAN +/* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */ +#define EMIT_ELT(offset, x) do { \ + int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \ + GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \ + (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0) +#else +#define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x) +#endif +#define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x); +#define INCR_ELTS( nr ) dest += nr +#define RELEASE_ELT_VERTS() \ + r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ ) +#define EMIT_VERTS( ctx, j, nr ) \ + r200_emit_contiguous_verts(ctx, j, (j)+(nr)) +#define EMIT_INDEXED_VERTS( ctx, start, count ) \ + r200_emit_indexed_verts( ctx, start, count ) + + +#define TAG(x) r200_dma_##x +#include "tnl_dd/t_dd_dmatmp.h" + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + +static GLboolean r200_run_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i, length, flags = 0; + render_func *tab = TAG(render_tab_verts); + + if (rmesa->swtcl.indexed_verts.buf && (!VB->Elts || stage->changed_inputs)) + RELEASE_ELT_VERTS(); + + + + if ((R200_DEBUG & DEBUG_VERTS) || /* No debug */ + VB->ClipOrMask || /* No clipping */ + rmesa->swtcl.RenderIndex != 0 || /* No per-vertex manipulations */ + ctx->Line.StippleFlag) /* No stipple -- fix me? */ + return GL_TRUE; + + if (VB->Elts) { + tab = TAG(render_tab_elts); + if (!rmesa->swtcl.indexed_verts.buf) + if (!TAG(emit_elt_verts)(ctx, 0, VB->Count)) + return GL_TRUE; /* too many vertices */ + } + + tnl->Driver.Render.Start( ctx ); + + for (i = 0 ; !(flags & PRIM_LAST) ; i += length) + { + flags = VB->Primitive[i]; + length = VB->PrimitiveLength[i]; + + if (R200_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "r200_render.c: prim %s %d..%d\n", + _mesa_lookup_enum_by_nr(flags & PRIM_MODE_MASK), + i, i+length); + + if (length) + tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); + } + + tnl->Driver.Render.Finish( ctx ); + + return GL_FALSE; /* finished the pipe */ +} + + + +static void r200_check_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + GLuint inputs = VERT_OBJ|VERT_CLIP|VERT_RGBA; + + if (ctx->RenderMode == GL_RENDER) { + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + inputs |= VERT_SPEC_RGB; + + if (ctx->Texture.Unit[0]._ReallyEnabled) + inputs |= VERT_TEX(0); + + if (ctx->Texture.Unit[1]._ReallyEnabled) + inputs |= VERT_TEX(1); + + if (ctx->Fog.Enabled) + inputs |= VERT_FOG_COORD; + } + + stage->inputs = inputs; +} + + +static void dtr( struct gl_pipeline_stage *stage ) +{ + (void)stage; +} + + +const struct gl_pipeline_stage _r200_render_stage = +{ + "r200 render", + (_DD_NEW_SEPARATE_SPECULAR | + _NEW_TEXTURE| + _NEW_FOG| + _NEW_RENDERMODE), /* re-check (new inputs) */ + 0, /* re-run (always runs) */ + GL_TRUE, /* active */ + 0, 0, /* inputs (set in check_render), outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + r200_check_render, /* check - initially set to alloc data */ + r200_run_render /* run */ +}; + + + +/**************************************************************************/ + + +static const GLuint reduced_hw_prim[GL_POLYGON+1] = { + R200_VF_PRIM_POINTS, + R200_VF_PRIM_LINES, + R200_VF_PRIM_LINES, + R200_VF_PRIM_LINES, + R200_VF_PRIM_TRIANGLES, + R200_VF_PRIM_TRIANGLES, + R200_VF_PRIM_TRIANGLES, + R200_VF_PRIM_TRIANGLES, + R200_VF_PRIM_TRIANGLES, + R200_VF_PRIM_TRIANGLES +}; + +static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim ); +static void r200RenderPrimitive( GLcontext *ctx, GLenum prim ); +static void r200ResetLineStipple( GLcontext *ctx ); + +#undef HAVE_QUADS +#define HAVE_QUADS 0 + +#undef HAVE_QUAD_STRIPS +#define HAVE_QUAD_STRIPS 0 + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#undef LOCAL_VARS +#define CTX_ARG r200ContextPtr rmesa +#define CTX_ARG2 rmesa +#define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size +#define ALLOC_VERTS( n, size ) r200AllocDmaLowVerts( rmesa, n, size * 4 ) +#define LOCAL_VARS \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ + const GLuint shift = rmesa->swtcl.vertex_stride_shift; \ + const char *r200verts = (char *)rmesa->swtcl.verts; +#define VERT(x) (r200Vertex *)(r200verts + (x << shift)) +#define VERTEX r200Vertex +#define DO_DEBUG_VERTS (1 && (R200_DEBUG & DEBUG_VERTS)) +#define PRINT_VERTEX(v) r200_print_vertex(rmesa->glCtx, v) +#undef TAG +#define TAG(x) r200_##x +#include "tnl_dd/t_dd_triemit.h" + + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define QUAD( a, b, c, d ) r200_quad( rmesa, a, b, c, d ) +#define TRI( a, b, c ) r200_triangle( rmesa, a, b, c ) +#define LINE( a, b ) r200_line( rmesa, a, b ) +#define POINT( a ) r200_point( rmesa, a ) + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define R200_TWOSIDE_BIT 0x01 +#define R200_UNFILLED_BIT 0x02 +#define R200_MAX_TRIFUNC 0x04 + + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[R200_MAX_TRIFUNC]; + + +#define DO_FALLBACK 0 +#define DO_UNFILLED (IND & R200_UNFILLED_BIT) +#define DO_TWOSIDE (IND & R200_TWOSIDE_BIT) +#define DO_FLAT 0 +#define DO_OFFSET 0 +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_INDEX 0 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define TAB rast_tab + +#define DEPTH_SCALE 1.0 +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a < 0) +#define GET_VERTEX(e) (rmesa->swtcl.verts + (e<<rmesa->swtcl.vertex_stride_shift)) + +#define VERT_SET_RGBA( v, c ) v->ui[coloroffset] = LE32_TO_CPU(*(GLuint *)c) +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA( idx ) color[idx] = CPU_TO_LE32(v[idx]->ui[coloroffset]) +#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = LE32_TO_CPU(color[idx]) + +#define VERT_SET_SPEC( v0, c ) if (havespec) { \ + v0->v.specular.red = (c)[0]; \ + v0->v.specular.green = (c)[1]; \ + v0->v.specular.blue = (c)[2]; } +#define VERT_COPY_SPEC( v0, v1 ) if (havespec) { \ + v0->v.specular.red = v1->v.specular.red; \ + v0->v.specular.green = v1->v.specular.green; \ + v0->v.specular.blue = v1->v.specular.blue; } +#define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = CPU_TO_LE32(v[idx]->ui[5]) +#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = LE32_TO_CPU(spec[idx]) + +#undef LOCAL_VARS +#undef TAG +#undef INIT + +#define LOCAL_VARS(n) \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = (rmesa->swtcl.vertex_size == 4 ? 3 : 4); \ + GLboolean havespec = (rmesa->swtcl.vertex_size > 4); \ + (void) color; (void) spec; (void) coloroffset; (void) havespec; + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) r200RasterPrimitive( ctx, reduced_hw_prim[x] ) +#define RENDER_PRIMITIVE rmesa->swtcl.render_primitive +#define TAG(x) x +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R200_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R200_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R200_TWOSIDE_BIT|R200_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + + +static void init_rast_tab( void ) +{ + init(); + init_twoside(); + init_unfilled(); + init_twoside_unfilled(); +} + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define VERT(x) (r200Vertex *)(r200verts + (x << shift)) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + r200_point( rmesa, VERT(start) ) +#define RENDER_LINE( v0, v1 ) \ + r200_line( rmesa, VERT(v0), VERT(v1) ) +#define RENDER_TRI( v0, v1, v2 ) \ + r200_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) \ + r200_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) +#define INIT(x) do { \ + r200RenderPrimitive( ctx, x ); \ +} while (0) +#undef LOCAL_VARS +#define LOCAL_VARS \ + r200ContextPtr rmesa = R200_CONTEXT(ctx); \ + const GLuint shift = rmesa->swtcl.vertex_stride_shift; \ + const char *r200verts = (char *)rmesa->swtcl.verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) elt; (void) stipple; +#define RESET_STIPPLE if ( stipple ) r200ResetLineStipple( ctx ); +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) (x) +#define TAG(x) r200_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) r200_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + +void r200ChooseRenderState( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint index = 0; + GLuint flags = ctx->_TriangleCaps; + + if (!rmesa->TclFallback || rmesa->Fallback) + return; + + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R200_TWOSIDE_BIT; + if (flags & DD_TRI_UNFILLED) index |= R200_UNFILLED_BIT; + + if (index != rmesa->swtcl.RenderIndex) { + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = r200_render_tab_verts; + tnl->Driver.Render.PrimTabElts = r200_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = r200_fast_clipped_poly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + } + + rmesa->swtcl.RenderIndex = index; + } +} + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (rmesa->swtcl.hw_primitive != hwprim) { + R200_NEWPRIM( rmesa ); + rmesa->swtcl.hw_primitive = hwprim; + } +} + +static void r200RenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + rmesa->swtcl.render_primitive = prim; + if (prim < GL_TRIANGLES || !(ctx->_TriangleCaps & DD_TRI_UNFILLED)) + r200RasterPrimitive( ctx, reduced_hw_prim[prim] ); +} + +static void r200RenderFinish( GLcontext *ctx ) +{ +} + +static void r200ResetLineStipple( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + R200_STATECHANGE( rmesa, lin ); +} + + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + +static char *fallbackStrings[] = { + "Texture mode", + "glDrawBuffer(GL_FRONT_AND_BACK)", + "glEnable(GL_STENCIL) without hw stencil buffer", + "glRenderMode(selection or feedback)", + "glBlendEquation", + "glBlendFunc(mode != ADD)" + "R200_NO_RAST" +}; + + +static char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + + +void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = rmesa->Fallback; + + if (mode) { + rmesa->Fallback |= bit; + if (oldfallback == 0) { + R200_FIREVERTICES( rmesa ); + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_TRUE ); + _swsetup_Wakeup( ctx ); + _tnl_need_projected_coords( ctx, GL_TRUE ); + rmesa->swtcl.RenderIndex = ~0; + if (R200_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "R200 begin rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } + } + } + else { + rmesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + tnl->Driver.Render.Start = r200RenderStart; + tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive; + tnl->Driver.Render.Finish = r200RenderFinish; + tnl->Driver.Render.BuildVertices = r200BuildVertices; + tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple; + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_FALSE ); + if (rmesa->TclFallback) { + /* These are already done if rmesa->TclFallback goes to + * zero above. But not if it doesn't (R200_NO_TCL for + * example?) + */ + r200ChooseVertexState( ctx ); + r200ChooseRenderState( ctx ); + } + if (R200_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "R200 end rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } + } + } +} + + + + +/* Cope with depth operations by drawing individual pixels as points??? + */ +void +r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + const GLfloat *rc = ctx->Current.RasterColor; + GLint row, col; + r200Vertex vert; + GLuint orig_vte; + GLuint h; + + + /* Turn off tcl. + */ + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_BITMAP, 1 ); + + /* Choose tiny vertex format + */ + r200SetVertexFormat( ctx, R200_XYZW_BIT | R200_RGBA_BIT ); + + /* Ready for point primitives: + */ + r200RenderPrimitive( ctx, GL_POINTS ); + + /* Turn off the hw viewport transformation: + */ + R200_STATECHANGE( rmesa, vte ); + orig_vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]; + rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VPORT_X_SCALE_ENA | + R200_VPORT_Y_SCALE_ENA | + R200_VPORT_Z_SCALE_ENA | + R200_VPORT_X_OFFSET_ENA | + R200_VPORT_Y_OFFSET_ENA | + R200_VPORT_Z_OFFSET_ENA); + + /* Turn off other stuff: Stipple?, texture?, blending?, etc. + */ + + + /* Populate the vertex + * + * Incorporate FOG into RGBA + */ + if (ctx->Fog.Enabled) { + const GLfloat *fc = ctx->Fog.Color; + GLfloat color[4]; + GLfloat f; + + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) + f = _mesa_z_to_fogfactor(ctx, ctx->Current.FogCoord); + else + f = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + + color[0] = f * rc[0] + (1.F - f) * fc[0]; + color[1] = f * rc[1] + (1.F - f) * fc[1]; + color[2] = f * rc[2] + (1.F - f) * fc[2]; + color[3] = rc[3]; + + UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.red, color[0]); + UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.green, color[1]); + UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.blue, color[2]); + UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.alpha, color[3]); + } + else { + UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.red, rc[0]); + UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.green, rc[1]); + UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.blue, rc[2]); + UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.alpha, rc[3]); + } + + + vert.tv.z = ctx->Current.RasterPos[2]; + + + /* Update window height + */ + LOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( rmesa ); + h = rmesa->dri.drawable->h + rmesa->dri.drawable->y; + px += rmesa->dri.drawable->x; + + /* Clipping handled by existing mechansims in r200_ioctl.c? + */ + for (row=0; row<height; row++) { + const GLubyte *src = (const GLubyte *) + _mesa_image_address( unpack, bitmap, width, height, + GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 ); + + if (unpack->LsbFirst) { + /* Lsb first */ + GLubyte mask = 1U << (unpack->SkipPixels & 0x7); + for (col=0; col<width; col++) { + if (*src & mask) { + vert.tv.x = px+col; + vert.tv.y = h - (py+row) - 1; + r200_point( rmesa, &vert ); + } + src += (mask >> 7); + mask = ((mask << 1) & 0xff) | (mask >> 7); + } + + /* get ready for next row */ + if (mask != 1) + src++; + } + else { + /* Msb first */ + GLubyte mask = 128U >> (unpack->SkipPixels & 0x7); + for (col=0; col<width; col++) { + if (*src & mask) { + vert.tv.x = px+col; + vert.tv.y = h - (py+row) - 1; + r200_point( rmesa, &vert ); + } + src += mask & 1; + mask = ((mask << 7) & 0xff) | (mask >> 1); + } + /* get ready for next row */ + if (mask != 128) + src++; + } + } + + /* Fire outstanding vertices, restore state + */ + R200_STATECHANGE( rmesa, vte ); + rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = orig_vte; + + /* Unfallback + */ + TCL_FALLBACK( ctx, R200_TCL_FALLBACK_BITMAP, 0 ); + + /* Need to restore vertexformat? + */ + if (rmesa->TclFallback) + r200ChooseVertexState( ctx ); +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void r200InitSwtcl( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + init_setup_tab(); + firsttime = 0; + } + + tnl->Driver.Render.Start = r200RenderStart; + tnl->Driver.Render.Finish = r200RenderFinish; + tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple; + tnl->Driver.Render.BuildVertices = r200BuildVertices; + + rmesa->swtcl.verts = (char *)ALIGN_MALLOC( size * 16 * 4, 32 ); + rmesa->swtcl.RenderIndex = ~0; + rmesa->swtcl.render_primitive = GL_TRIANGLES; + rmesa->swtcl.hw_primitive = 0; +} + + +void r200DestroySwtcl( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (rmesa->swtcl.indexed_verts.buf) + r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ ); + + if (rmesa->swtcl.verts) { + ALIGN_FREE(rmesa->swtcl.verts); + rmesa->swtcl.verts = 0; + } + + if (rmesa->UbyteSecondaryColor.Ptr) { + ALIGN_FREE(rmesa->UbyteSecondaryColor.Ptr); + rmesa->UbyteSecondaryColor.Ptr = 0; + } + + if (rmesa->UbyteColor.Ptr) { + ALIGN_FREE(rmesa->UbyteColor.Ptr); + rmesa->UbyteColor.Ptr = 0; + } +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.h b/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.h new file mode 100644 index 000000000..73379dd0d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.h @@ -0,0 +1,79 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_swtcl.h,v 1.2 2002/12/16 16:18:55 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_SWTCL_H__ +#define __R200_SWTCL_H__ + +#include "mtypes.h" +#include "swrast/swrast.h" +#include "r200_context.h" + +extern void r200InitSwtcl( GLcontext *ctx ); +extern void r200DestroySwtcl( GLcontext *ctx ); + +extern void r200ChooseRenderState( GLcontext *ctx ); +extern void r200ChooseVertexState( GLcontext *ctx ); + +extern void r200CheckTexSizes( GLcontext *ctx ); + +extern void r200BuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ); + +extern void r200PrintSetupFlags(char *msg, GLuint flags ); + + +extern void r200_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count ); + +extern void r200_emit_indexed_verts( GLcontext *ctx, + GLuint start, + GLuint count ); + +extern void r200_translate_vertex( GLcontext *ctx, + const r200Vertex *src, + SWvertex *dst ); + +extern void r200_print_vertex( GLcontext *ctx, const r200Vertex *v ); + +extern void r200_import_float_colors( GLcontext *ctx ); +extern void r200_import_float_spec_colors( GLcontext *ctx ); + +extern void r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ); + + +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_tcl.c b/xc/lib/GL/mesa/src/drv/r200/r200_tcl.c new file mode 100644 index 000000000..c199e960f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_tcl.c @@ -0,0 +1,553 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_tcl.c,v 1.2 2002/12/16 16:18:55 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_state.h" +#include "r200_ioctl.h" +#include "r200_tex.h" +#include "r200_tcl.h" +#include "r200_swtcl.h" +#include "r200_maos.h" + +#include "mmath.h" +#include "mtypes.h" +#include "enums.h" +#include "colormac.h" +#include "light.h" + +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" + + + +#define HAVE_POINTS 1 +#define HAVE_LINES 1 +#define HAVE_LINE_LOOP 0 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 +#define HAVE_TRI_FANS 1 +#define HAVE_QUADS 0 /* hw quad verts in wrong order??? */ +#define HAVE_QUAD_STRIPS 1 +#define HAVE_POLYGONS 1 +#define HAVE_ELTS 1 + + +#define HW_POINTS R200_VF_PRIM_POINTS +#define HW_LINES R200_VF_PRIM_LINES +#define HW_LINE_LOOP 0 +#define HW_LINE_STRIP R200_VF_PRIM_LINE_STRIP +#define HW_TRIANGLES R200_VF_PRIM_TRIANGLES +#define HW_TRIANGLE_STRIP_0 R200_VF_PRIM_TRIANGLE_STRIP +#define HW_TRIANGLE_STRIP_1 0 +#define HW_TRIANGLE_FAN R200_VF_PRIM_TRIANGLE_FAN +#define HW_QUADS R200_VF_PRIM_QUADS +#define HW_QUAD_STRIP R200_VF_PRIM_QUAD_STRIP +#define HW_POLYGON R200_VF_PRIM_POLYGON + + +static GLboolean discrete_prim[0x10] = { + 0, /* 0 none */ + 1, /* 1 points */ + 1, /* 2 lines */ + 0, /* 3 line_strip */ + 1, /* 4 tri_list */ + 0, /* 5 tri_fan */ + 0, /* 6 tri_strip */ + 0, /* 7 tri_w_flags */ + 1, /* 8 rect list (unused) */ + 1, /* 9 3vert point */ + 1, /* a 3vert line */ + 0, /* b point sprite */ + 0, /* c line loop */ + 1, /* d quads */ + 0, /* e quad strip */ + 0, /* f polygon */ +}; + + +#define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx) +#define ELTS_VARS GLushort *dest + +#define ELT_INIT(prim, hw_prim) \ + r200TclPrimitive( ctx, prim, hw_prim | R200_VF_PRIM_WALK_IND ) + +#define GET_ELTS() rmesa->tcl.Elts + + +#define NEW_PRIMITIVE() R200_NEWPRIM( rmesa ) +#define NEW_BUFFER() r200RefillCurrentDmaRegion( rmesa ) + +/* Don't really know how many elts will fit in what's left of cmdbuf, + * as there is state to emit, etc: + */ + +#if 0 +#define GET_CURRENT_VB_MAX_ELTS() \ + ((R200_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2) +#define GET_SUBSEQUENT_VB_MAX_ELTS() ((R200_CMD_BUF_SZ - 16) / 2) +#else +/* Testing on isosurf shows a maximum around here. Don't know if it's + * the card or driver or kernel module that is causing the behaviour. + */ +#define GET_CURRENT_VB_MAX_ELTS() 300 +#define GET_SUBSEQUENT_VB_MAX_ELTS() 300 +#endif + +#define RESET_STIPPLE() do { \ + R200_STATECHANGE( rmesa, lin ); \ + r200EmitState( rmesa ); \ +} while (0) + +#define AUTO_STIPPLE( mode ) do { \ + R200_STATECHANGE( rmesa, lin ); \ + if (mode) \ + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] |= \ + R200_LINE_PATTERN_AUTO_RESET; \ + else \ + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \ + ~R200_LINE_PATTERN_AUTO_RESET; \ + r200EmitState( rmesa ); \ +} while (0) + + +/* How do you extend an existing primitive? + */ +#define ALLOC_ELTS(nr) \ +do { \ + if (rmesa->dma.flush == r200FlushElts && \ + rmesa->store.cmd_used + nr*2 < R200_CMD_BUF_SZ) { \ + \ + dest = (GLushort *)(rmesa->store.cmd_buf + \ + rmesa->store.cmd_used); \ + rmesa->store.cmd_used += nr*2; \ + } \ + else { \ + if (rmesa->dma.flush) \ + rmesa->dma.flush( rmesa ); \ + \ + r200EmitAOS( rmesa, \ + rmesa->tcl.aos_components, \ + rmesa->tcl.nr_aos_components, \ + 0 ); \ + \ + dest = r200AllocEltsOpenEnded( rmesa, \ + rmesa->tcl.hw_primitive, \ + nr ); \ + } \ +} while (0) + + + +/* TODO: Try to extend existing primitive if both are identical, + * discrete and there are no intervening state changes. (Somewhat + * duplicates changes to DrawArrays code) + */ +static void EMIT_PRIM( GLcontext *ctx, + GLenum prim, + GLuint hwprim, + GLuint start, + GLuint count) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + r200TclPrimitive( ctx, prim, hwprim ); + + r200EmitAOS( rmesa, + rmesa->tcl.aos_components, + rmesa->tcl.nr_aos_components, + start ); + + /* Why couldn't this packet have taken an offset param? + */ + r200EmitVbufPrim( rmesa, + rmesa->tcl.hw_primitive, + count - start ); +} + + + +/* Try & join small primitives + */ +#if 0 +#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) 0 +#else +#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) \ + ((NR) < 20 || \ + ((NR) < 40 && \ + rmesa->tcl.hw_primitive == (PRIM| \ + R200_VF_TCL_OUTPUT_VTX_ENABLE| \ + R200_VF_PRIM_WALK_IND))) +#endif + +#ifdef MESA_BIG_ENDIAN +/* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */ +#define EMIT_ELT(offset, x) do { \ + int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \ + GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \ + (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0) +#else +#define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x) +#endif +#define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x); +#define INCR_ELTS( nr ) dest += nr +#define RELEASE_ELT_VERTS() \ + r200ReleaseArrays( ctx, ~0 ) + + + +#define TAG(x) tcl_##x +#include "tnl_dd/t_dd_dmatmp2.h" + +/**********************************************************************/ +/* External entrypoints */ +/**********************************************************************/ + +void r200EmitPrimitive( GLcontext *ctx, + GLuint first, + GLuint last, + GLuint flags ) +{ + tcl_render_tab_verts[flags&PRIM_MODE_MASK]( ctx, first, last, flags ); +} + +void r200EmitEltPrimitive( GLcontext *ctx, + GLuint first, + GLuint last, + GLuint flags ) +{ + tcl_render_tab_elts[flags&PRIM_MODE_MASK]( ctx, first, last, flags ); +} + +void r200TclPrimitive( GLcontext *ctx, + GLenum prim, + int hw_prim ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint newprim = hw_prim | R200_VF_TCL_OUTPUT_VTX_ENABLE; + + if (newprim != rmesa->tcl.hw_primitive || + !discrete_prim[hw_prim&0xf]) { + R200_NEWPRIM( rmesa ); + rmesa->tcl.hw_primitive = newprim; + } +} + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + +/* TCL render. + */ +static GLboolean r200_run_tcl_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i,flags = 0,length; + + /* TODO: separate this from the swtnl pipeline + */ + if (rmesa->TclFallback) + return GL_TRUE; /* fallback to software t&l */ + + if (R200_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (VB->Count == 0) + return GL_FALSE; + + r200ReleaseArrays( ctx, stage->changed_inputs ); + r200EmitArrays( ctx, stage->inputs ); + + rmesa->tcl.Elts = VB->Elts; + + for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length) + { + flags = VB->Primitive[i]; + length = VB->PrimitiveLength[i]; + + if (R200_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s: prim %s %d..%d\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(flags & PRIM_MODE_MASK), + i, i+length); + + if (!length) + continue; + + if (rmesa->tcl.Elts) + r200EmitEltPrimitive( ctx, i, i+length, flags ); + else + r200EmitPrimitive( ctx, i, i+length, flags ); + } + + return GL_FALSE; /* finished the pipe */ +} + + + +static void r200_check_tcl_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint inputs = VERT_OBJ; + + /* Validate state: + */ + if (rmesa->NewGLState) + r200ValidateState( ctx ); + + if (0) + fprintf(stderr, "%s: RE %d TGE %d NN %d\n", + __FUNCTION__, + ctx->Texture.Unit[0]._ReallyEnabled, + ctx->Texture.Unit[0].TexGenEnabled, + rmesa->TexGenNeedNormals[0]); + + if (ctx->RenderMode == GL_RENDER) { + /* Make all this event-driven: + */ + if (ctx->Light.Enabled) { + inputs |= VERT_NORM; + + if (ctx->Light.ColorMaterialEnabled) { + inputs |= VERT_RGBA; + } + } + else { + inputs |= VERT_RGBA; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { + inputs |= VERT_SPEC_RGB; + } + } + + if (ctx->Texture.Unit[0]._ReallyEnabled) { + if (ctx->Texture.Unit[0].TexGenEnabled) { + if (rmesa->TexGenNeedNormals[0]) { + inputs |= VERT_NORM; + } + } else { + inputs |= VERT_TEX(0); + } + } + + if (ctx->Texture.Unit[1]._ReallyEnabled) { + if (ctx->Texture.Unit[1].TexGenEnabled) { + if (rmesa->TexGenNeedNormals[1]) { + inputs |= VERT_NORM; + } + } else { + inputs |= VERT_TEX(1); + } + } + + stage->inputs = inputs; + stage->active = 1; + } + else + stage->active = 0; +} + +static void r200_init_tcl_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + stage->check = r200_check_tcl_render; + stage->check( ctx, stage ); +} + +static void dtr( struct gl_pipeline_stage *stage ) +{ + (void)stage; +} + + +/* Initial state for tcl stage. + */ +const struct gl_pipeline_stage _r200_tcl_stage = +{ + "r200 render", + (_DD_NEW_SEPARATE_SPECULAR | + _NEW_LIGHT| + _NEW_TEXTURE| + _NEW_FOG| + _NEW_RENDERMODE), /* re-check (new inputs) */ + 0, /* re-run (always runs) */ + GL_TRUE, /* active */ + 0, 0, /* inputs (set in check_render), outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + r200_init_tcl_render, /* check - initially set to alloc data */ + r200_run_tcl_render /* run */ +}; + + + +/**********************************************************************/ +/* Validate state at pipeline start */ +/**********************************************************************/ + + +/*----------------------------------------------------------------------- + * Manage TCL fallbacks + */ + + +static void transition_to_swtnl( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + R200_NEWPRIM( rmesa ); + rmesa->swtcl.vertex_format = 0; + + r200ChooseVertexState( ctx ); + r200ChooseRenderState( ctx ); + + _mesa_validate_all_lighting_tables( ctx ); + + tnl->Driver.NotifyMaterialChange = + _mesa_validate_all_lighting_tables; + + r200ReleaseArrays( ctx, ~0 ); + + /* Still using the D3D based hardware-rasterizer from the radeon; + * need to put the card into D3D mode to make it work: + */ + R200_STATECHANGE( rmesa, vap ); + rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_TCL_ENABLE; + rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_D3D_TEX_DEFAULT; + + R200_STATECHANGE( rmesa, vte ); + rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~R200_VTX_W0_FMT; + + R200_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_RE_CNTL] |= (R200_VTX_STQ0_D3D | + R200_VTX_STQ1_D3D); +} + + +static void transition_to_hwtnl( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + _tnl_need_projected_coords( ctx, GL_FALSE ); + + r200UpdateMaterial( ctx ); + + tnl->Driver.NotifyMaterialChange = r200UpdateMaterial; + + if ( rmesa->dma.flush ) + rmesa->dma.flush( rmesa ); + + rmesa->dma.flush = 0; + rmesa->swtcl.vertex_format = 0; + + if (rmesa->swtcl.indexed_verts.buf) + r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, + __FUNCTION__ ); + + R200_STATECHANGE( rmesa, vap ); + rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE; + rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_FORCE_W_TO_ONE | + R200_VAP_D3D_TEX_DEFAULT); + + R200_STATECHANGE( rmesa, vte ); + rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT); + rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT; + + R200_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_RE_CNTL] &= ~(R200_VTX_STQ0_D3D | + R200_VTX_STQ1_D3D); + + + if (R200_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "R200 end tcl fallback\n"); +} + + +static char *fallbackStrings[] = { + "Rasterization fallback", + "Unfilled triangles", + "Twosided lighting, differing materials", + "Materials in VB (maybe between begin/end)", + "Texgen unit 0", + "Texgen unit 1", + "Texgen unit 2", + "User disable" +}; + + +static char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + + + +void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint oldfallback = rmesa->TclFallback; + + if (mode) { + rmesa->TclFallback |= bit; + if (oldfallback == 0) { + if (R200_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "R200 begin tcl fallback %s\n", + getFallbackString( bit )); + transition_to_swtnl( ctx ); + } + } + else { + rmesa->TclFallback &= ~bit; + if (oldfallback == bit) { + if (R200_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "R200 end tcl fallback %s\n", + getFallbackString( bit )); + transition_to_hwtnl( ctx ); + } + } +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_tcl.h b/xc/lib/GL/mesa/src/drv/r200/r200_tcl.h new file mode 100644 index 000000000..75f6ab6b4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_tcl.h @@ -0,0 +1,66 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_tcl.h,v 1.2 2002/12/16 16:18:55 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_TCL_H__ +#define __R200_TCL_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "r200_context.h" + +extern void r200TclPrimitive( GLcontext *ctx, GLenum prim, int hw_prim ); +extern void r200EmitEltPrimitive( GLcontext *ctx, GLuint first, GLuint last, + GLuint flags ); +extern void r200EmitPrimitive( GLcontext *ctx, GLuint first, GLuint last, + GLuint flags ); + +extern void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); + +#define R200_TCL_FALLBACK_RASTER 0x1 /* rasterization */ +#define R200_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */ +#define R200_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */ +#define R200_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */ +#define R200_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */ +#define R200_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */ +#define R200_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */ +#define R200_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */ +#define R200_TCL_FALLBACK_BITMAP 0x100 /* draw bitmap with points */ + +#define R200_MAX_TCL_VERTSIZE (4*4) /* using maos now... */ + +#define TCL_FALLBACK( ctx, bit, mode ) r200TclFallback( ctx, bit, mode ) + + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_tex.c b/xc/lib/GL/mesa/src/drv/r200/r200_tex.c new file mode 100644 index 000000000..a025d67ad --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_tex.c @@ -0,0 +1,790 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_tex.c,v 1.2 2002/11/05 17:46:08 tsi Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_state.h" +#include "r200_ioctl.h" +#include "r200_swtcl.h" +#include "r200_tex.h" + +#include "colormac.h" +#include "context.h" +#include "enums.h" +#include "image.h" +#include "mem.h" +#include "mmath.h" +#include "simple_list.h" +#include "texformat.h" +#include "texstore.h" +#include "texutil.h" + + +/* ============================================================= + * Utility functions: + */ + +static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap ) +{ + t->pp_txfilter &= ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK); + + switch ( swrap ) { + case GL_REPEAT: + t->pp_txfilter |= R200_CLAMP_S_WRAP; + break; + case GL_CLAMP: + t->pp_txfilter |= R200_CLAMP_S_CLAMP_LAST; + break; + case GL_CLAMP_TO_EDGE: + t->pp_txfilter |= R200_CLAMP_S_CLAMP_LAST; + break; + } + + switch ( twrap ) { + case GL_REPEAT: + t->pp_txfilter |= R200_CLAMP_T_WRAP; + break; + case GL_CLAMP: + t->pp_txfilter |= R200_CLAMP_T_CLAMP_LAST; + break; + case GL_CLAMP_TO_EDGE: + t->pp_txfilter |= R200_CLAMP_T_CLAMP_LAST; + break; + } +} + +static void r200SetTexMaxAnisotropy( r200TexObjPtr t, GLfloat max ) +{ + t->pp_txfilter &= ~R200_MAX_ANISO_MASK; + + if ( max == 1.0 ) { + t->pp_txfilter |= R200_MAX_ANISO_1_TO_1; + } else if ( max <= 2.0 ) { + t->pp_txfilter |= R200_MAX_ANISO_2_TO_1; + } else if ( max <= 4.0 ) { + t->pp_txfilter |= R200_MAX_ANISO_4_TO_1; + } else if ( max <= 8.0 ) { + t->pp_txfilter |= R200_MAX_ANISO_8_TO_1; + } else { + t->pp_txfilter |= R200_MAX_ANISO_16_TO_1; + } +} + +static void r200SetTexFilter( r200TexObjPtr t, GLenum minf, GLenum magf ) +{ + GLuint anisotropy = (t->pp_txfilter & R200_MAX_ANISO_MASK); + + t->pp_txfilter &= ~(R200_MIN_FILTER_MASK | R200_MAG_FILTER_MASK); + + if ( anisotropy == R200_MAX_ANISO_1_TO_1 ) { + switch ( minf ) { + case GL_NEAREST: + t->pp_txfilter |= R200_MIN_FILTER_NEAREST; + break; + case GL_LINEAR: + t->pp_txfilter |= R200_MIN_FILTER_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: + t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_LINEAR; + break; + } + } else { + switch ( minf ) { + case GL_NEAREST: + t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST; + break; + case GL_LINEAR: + t->pp_txfilter |= R200_MIN_FILTER_ANISO_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_NEAREST: + t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR; + break; + } + } + + switch ( magf ) { + case GL_NEAREST: + t->pp_txfilter |= R200_MAG_FILTER_NEAREST; + break; + case GL_LINEAR: + t->pp_txfilter |= R200_MAG_FILTER_LINEAR; + break; + } +} + +static void r200SetTexBorderColor( r200TexObjPtr t, GLubyte c[4] ) +{ + t->pp_border_color = r200PackColor( 4, c[0], c[1], c[2], c[3] ); +} + + +static r200TexObjPtr r200AllocTexObj( struct gl_texture_object *texObj ) +{ + r200TexObjPtr t; + + t = CALLOC_STRUCT( r200_tex_obj ); + if (!t) + return NULL; + + if ( R200_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t ); + } + + t->tObj = texObj; + make_empty_list( t ); + + /* Initialize non-image-dependent parts of the state: + */ + r200SetTexWrap( t, texObj->WrapS, texObj->WrapT ); + r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); + r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); + r200SetTexBorderColor( t, texObj->BorderColor ); + return t; +} + + +static const struct gl_texture_format * +r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + const GLboolean do32bpt = ( rmesa->r200Screen->cpp == 4 ); + + switch ( internalFormat ) { + case 4: + case GL_RGBA: + if ( format == GL_BGRA ) { + if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { + return &_mesa_texformat_argb8888; + } + else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { + return &_mesa_texformat_argb4444; + } + else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + return &_mesa_texformat_argb1555; + } + } + return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_argb4444; + + case 3: + case GL_RGB: + if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { + return &_mesa_texformat_rgb565; + } + return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_rgb565; + + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_argb4444; + + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; + + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return do32bpt ? &_mesa_texformat_rgba8888 : &_mesa_texformat_rgb565; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return &_mesa_texformat_rgb565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return &_mesa_texformat_al88; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return &_mesa_texformat_al88; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return &_mesa_texformat_al88; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + /* At the moment, glean & conform both fail using the i8 internal + * format. + */ + return &_mesa_texformat_al88; +/* return &_mesa_texformat_i8; */ + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_APPLE || + type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + default: + _mesa_problem(ctx, "unexpected texture format in r200ChoosTexFormat"); + return NULL; + } + + return NULL; /* never get here */ +} + + +static GLboolean +r200ValidateClientStorage( GLcontext *ctx, GLenum target, + GLint internalFormat, + GLint srcWidth, GLint srcHeight, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) + +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + int texelBytes; + + if (0) + fprintf(stderr, "intformat %s format %s type %s\n", + _mesa_lookup_enum_by_nr( internalFormat ), + _mesa_lookup_enum_by_nr( format ), + _mesa_lookup_enum_by_nr( type )); + + if (!ctx->Unpack.ClientStorage) + return 0; + + if (ctx->_ImageTransferState || + texImage->IsCompressed || + texObj->GenerateMipmap) + return 0; + + + /* This list is incomplete, may be different on ppc??? + */ + switch ( internalFormat ) { + case GL_RGBA: + if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) { + texImage->TexFormat = &_mesa_texformat_argb8888; + texelBytes = 4; + } + else + return 0; + break; + + case GL_YCBCR_MESA: + if ( format == GL_YCBCR_MESA && + type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) { + texImage->TexFormat = &_mesa_texformat_ycbcr_rev; + texelBytes = 2; + } + else if ( format == GL_YCBCR_MESA && + (type == GL_UNSIGNED_SHORT_8_8_APPLE || + type == GL_UNSIGNED_BYTE)) { + texImage->TexFormat = &_mesa_texformat_ycbcr; + texelBytes = 2; + } + else + return 0; + break; + + + default: + return 0; + } + + /* Could deal with these packing issues, but currently don't: + */ + if (packing->SkipPixels || + packing->SkipRows || + packing->SwapBytes || + packing->LsbFirst) { + return 0; + } + + { + GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth, + format, type); + + + if (0) + fprintf(stderr, "%s: srcRowStride %d/%x\n", + __FUNCTION__, srcRowStride, srcRowStride); + + /* Could check this later in upload, pitch restrictions could be + * relaxed, but would need to store the image pitch somewhere, + * as packing details might change before image is uploaded: + */ + if (!r200IsAgpMemory( rmesa, pixels, srcHeight * srcRowStride ) || + (srcRowStride & 63)) + return 0; + + + /* Have validated that _mesa_transfer_teximage would be a straight + * memcpy at this point. NOTE: future calls to TexSubImage will + * overwrite the client data. This is explicitly mentioned in the + * extension spec. + */ + texImage->Data = (void *)pixels; + texImage->IsClientData = GL_TRUE; + texImage->RowStride = srcRowStride / texelBytes; + return 1; + } +} + + +static void r200TexImage1D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + + if ( t ) { + r200SwapOutTexObj( rmesa, t ); + } + else { + t = r200AllocTexObj( texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); + return; + } + texObj->DriverData = t; + } + + /* Note, this will call r200ChooseTextureFormat */ + _mesa_store_teximage1d(ctx, target, level, internalFormat, + width, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + + t->dirty_images |= (1 << level); +} + + +static void r200TexSubImage1D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData; + + assert( t ); /* this _should_ be true */ + if ( t ) { + r200SwapOutTexObj( rmesa, t ); + t->dirty_images |= (1 << level); + } + else { + t = r200AllocTexObj(texObj); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); + return; + } + texObj->DriverData = t; + } + + _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, + format, type, pixels, packing, texObj, + texImage); + + t->dirty_images |= (1 << level); +} + + +static void r200TexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData; + + if ( t ) { + r200SwapOutTexObj( rmesa, t ); + } + else { + t = r200AllocTexObj( texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + texObj->DriverData = t; + } + + texImage->IsClientData = GL_FALSE; + + if (r200ValidateClientStorage( ctx, target, + internalFormat, + width, height, + format, type, pixels, + packing, texObj, texImage)) { + if (R200_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: Using client storage\n", __FUNCTION__); + } + else { + if (R200_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__); + + /* Normal path: copy (to cached memory) and eventually upload + * via another copy to agp memory and then a blit... Could + * eliminate one copy by going straight to (permanent) agp. + * + * Note, this will call r200ChooseTextureFormat. + */ + _mesa_store_teximage2d(ctx, target, level, internalFormat, + width, height, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + + t->dirty_images |= (1 << level); + } +} + + +static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + assert( t ); /* this _should_ be true */ + if ( t ) { + r200SwapOutTexObj( rmesa, t ); + } + else { + t = r200AllocTexObj(texObj); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); + return; + } + texObj->DriverData = t; + } + + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, type, pixels, packing, texObj, + texImage); + + t->dirty_images |= (1 << level); +} + + +static void r200TexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + + if ( R200_DEBUG & DEBUG_STATE ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) ); + } + + /* This is incorrect: Need to maintain this data for each of + * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch + * between them according to _ReallyEnabled. + */ + switch ( pname ) { + case GL_TEXTURE_ENV_COLOR: { + GLubyte c[4]; + GLuint envColor; + UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor ); + envColor = r200PackColor( 4, c[0], c[1], c[2], c[3] ); + if ( rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] != envColor ) { + R200_STATECHANGE( rmesa, tf ); + rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] = envColor; + } + break; + } + + case GL_TEXTURE_LOD_BIAS_EXT: { + GLfloat bias; + GLuint b; + const int fixed_one = 0x8000000; + + /* The R200's LOD bias is a signed 2's complement value with a + * range of -16.0 <= bias < 16.0. + * + * NOTE: Add a small bias to the bias for conform mipsel.c test. + */ + bias = *param + .01; + bias = CLAMP( bias, -16.0, 16.0 ); + b = (int)(bias * fixed_one) & R200_LOD_BIAS_MASK; + + if ( (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] & R200_LOD_BIAS_MASK) != b ) { + R200_STATECHANGE( rmesa, tex[unit] ); + rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] &= ~R200_LOD_BIAS_MASK; + rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] |= b; + } + break; + } + + default: + return; + } +} + +static void r200TexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + + if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { + fprintf( stderr, "%s( %s )\n", __FUNCTION__, + _mesa_lookup_enum_by_nr( pname ) ); + } + + if (!t) + return; + + switch ( pname ) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); + r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + r200SetTexWrap( t, texObj->WrapS, texObj->WrapT ); + break; + + case GL_TEXTURE_BORDER_COLOR: + r200SetTexBorderColor( t, texObj->BorderColor ); + break; + + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + /* This isn't the most efficient solution but there doesn't appear to + * be a nice alternative for R200. Since there's no LOD clamping, + * we just have to rely on loading the right subset of mipmap levels + * to simulate a clamped LOD. + */ + r200SwapOutTexObj( rmesa, t ); + break; + + default: + return; + } + + /* Mark this texobj as dirty (one bit per tex unit) + */ + t->dirty_state = TEX_ALL; +} + + + +static void r200BindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj ) +{ + r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + GLuint unit = ctx->Texture.CurrentUnit; + + if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { + fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, texObj, unit ); + } + + if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) { + if ( !t ) { + t = r200AllocTexObj( texObj ); + texObj->DriverData = t; + } + } +} + +static void r200DeleteTexture( GLcontext *ctx, + struct gl_texture_object *texObj ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + + if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { + fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj ); + } + + if ( t ) { + if ( rmesa ) { + R200_FIREVERTICES( rmesa ); + } + r200DestroyTexObj( rmesa, t ); + texObj->DriverData = NULL; + } +} + +static GLboolean r200IsTextureResident( GLcontext *ctx, + struct gl_texture_object *texObj ) +{ + r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + + return ( t && t->memBlock ); +} + + +static void r200InitTextureObjects( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct gl_texture_object *texObj; + GLuint tmp = ctx->Texture.CurrentUnit; + + ctx->Texture.CurrentUnit = 0; + + texObj = ctx->Texture.Unit[0].Current1D; + r200BindTexture( ctx, GL_TEXTURE_1D, texObj ); + move_to_tail( &rmesa->texture.swapped, + (r200TexObjPtr)texObj->DriverData ); + + texObj = ctx->Texture.Unit[0].Current2D; + r200BindTexture( ctx, GL_TEXTURE_2D, texObj ); + move_to_tail( &rmesa->texture.swapped, + (r200TexObjPtr)texObj->DriverData ); + + ctx->Texture.CurrentUnit = 1; + + texObj = ctx->Texture.Unit[1].Current1D; + r200BindTexture( ctx, GL_TEXTURE_1D, texObj ); + move_to_tail( &rmesa->texture.swapped, + (r200TexObjPtr)texObj->DriverData ); + + texObj = ctx->Texture.Unit[1].Current2D; + r200BindTexture( ctx, GL_TEXTURE_2D, texObj ); + move_to_tail( &rmesa->texture.swapped, + (r200TexObjPtr)texObj->DriverData ); + + ctx->Texture.CurrentUnit = tmp; +} + +/* Need: + * - Same GEN_MODE for all active bits + * - Same EyePlane/ObjPlane for all active bits when using Eye/Obj + * - STRQ presumably all supported (matrix means incoming R values + * can end up in STQ, this has implications for vertex support, + * presumably ok if maos is used, though?) + * + * Basically impossible to do this on the fly - just collect some + * basic info & do the checks from ValidateState(). + */ +static void r200TexGen( GLcontext *ctx, + GLenum coord, + GLenum pname, + const GLfloat *params ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint unit = ctx->Texture.CurrentUnit; + rmesa->recheck_texgen[unit] = GL_TRUE; +} + + +void r200InitTextureFuncs( GLcontext *ctx ) +{ + ctx->Driver.ChooseTextureFormat = r200ChooseTextureFormat; + ctx->Driver.TexImage1D = r200TexImage1D; + ctx->Driver.TexImage2D = r200TexImage2D; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = r200TexSubImage1D; + ctx->Driver.TexSubImage2D = r200TexSubImage2D; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; + ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; + ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; + ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; + ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + ctx->Driver.BindTexture = r200BindTexture; + ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */ + ctx->Driver.DeleteTexture = r200DeleteTexture; + ctx->Driver.IsTextureResident = r200IsTextureResident; + ctx->Driver.PrioritizeTexture = NULL; + ctx->Driver.ActiveTexture = NULL; + ctx->Driver.UpdateTexturePalette = NULL; + + ctx->Driver.TexEnv = r200TexEnv; + ctx->Driver.TexParameter = r200TexParameter; + ctx->Driver.TexGen = r200TexGen; + + r200InitTextureObjects( ctx ); +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_tex.h b/xc/lib/GL/mesa/src/drv/r200/r200_tex.h new file mode 100644 index 000000000..e9efe31b3 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_tex.h @@ -0,0 +1,55 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_tex.h,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_TEX_H__ +#define __R200_TEX_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void r200UpdateTextureState( GLcontext *ctx ); + +extern int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t ); + +extern void r200AgeTextures( r200ContextPtr rmesa, int heap ); +extern void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ); +extern void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t ); + +extern void r200PrintLocalLRU( r200ContextPtr rmesa, int heap ); +extern void r200PrintGlobalLRU( r200ContextPtr rmesa, int heap ); +extern void r200UpdateTexLRU( r200ContextPtr rmesa, r200TexObjPtr t ); + +extern void r200InitTextureFuncs( GLcontext *ctx ); + +#endif +#endif /* __R200_TEX_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c b/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c new file mode 100644 index 000000000..fa4252d02 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c @@ -0,0 +1,737 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_texmem.c,v 1.5 2002/12/17 00:32:56 dawes Exp $ */ +/************************************************************************** + +Copyright (C) Tungsten Graphics 2002. All Rights Reserved. +The Weather Channel, Inc. funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 +license. This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation on the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR THEIR +SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_reg.h" +#include "r200_context.h" +#include "r200_state.h" +#include "r200_ioctl.h" +#include "r200_swtcl.h" +#include "r200_tex.h" + +#include "context.h" +#include "colormac.h" +#include "mmath.h" +#include "macros.h" +#include "simple_list.h" +#include "enums.h" +#include "mem.h" + +#include <unistd.h> /* for usleep */ + +/* Destroy hardware state associated with texture `t'. + */ +void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) +{ + if ( !t ) + return; + + if ( R200_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); + } + + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + if ( t->tObj ) + t->tObj->DriverData = NULL; + + if ( rmesa ) { + if ( t == rmesa->state.texture.unit[0].texobj ) { + rmesa->state.texture.unit[0].texobj = NULL; + remove_from_list( &rmesa->hw.tex[0] ); + make_empty_list( &rmesa->hw.tex[0] ); + } + + if ( t == rmesa->state.texture.unit[1].texobj ) { + rmesa->state.texture.unit[1].texobj = NULL; + remove_from_list( &rmesa->hw.tex[1] ); + make_empty_list( &rmesa->hw.tex[1] ); + } + } + + remove_from_list( t ); + FREE( t ); +} + + +/* Keep track of swapped out texture objects. + */ +void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) +{ + if ( R200_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); + } + + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + t->dirty_images = ~0; + move_to_tail( &rmesa->texture.swapped, t ); +} + +/* Print out debugging information about texture LRU. + */ +void r200PrintLocalLRU( r200ContextPtr rmesa, int heap ) +{ + r200TexObjPtr t; + int sz = 1 << (rmesa->r200Screen->logTexGranularity[heap]); + + fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); + + foreach ( t, &rmesa->texture.objects[heap] ) { + if (!t->memBlock) + continue; + if (!t->tObj) { + fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n", + t->memBlock->ofs / sz, + t->memBlock->ofs, + t->memBlock->size ); + } else { + fprintf( stderr, "Texture at 0x%x sz 0x%x\n", + t->memBlock->ofs, + t->memBlock->size ); + } + } + + fprintf( stderr, "\n" ); +} + +void r200PrintGlobalLRU( r200ContextPtr rmesa, int heap ) +{ + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int i, j; + + fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); + + for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_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 == RADEON_NR_TEX_REGIONS ) break; + } + + if ( j != RADEON_NR_TEX_REGIONS ) { + fprintf( stderr, "Loop detected in global LRU\n" ); + for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d\n", + i, list[i].age, list[i].next, list[i].prev ); + } + } + + fprintf( stderr, "\n" ); +} + +/* Reset the global texture LRU. + */ +static void r200ResetGlobalLRU( r200ContextPtr rmesa, int heap ) +{ + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = 1 << rmesa->r200Screen->logTexGranularity[heap]; + int i; + + /* + * (Re)initialize the global circular LRU list. The last element in + * the array (RADEON_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 <= rmesa->r200Screen->texSize[heap] ; i++ ) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = RADEON_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = RADEON_NR_TEX_REGIONS; + list[RADEON_NR_TEX_REGIONS].prev = i; + list[RADEON_NR_TEX_REGIONS].next = 0; + rmesa->sarea->texAge[heap] = 0; +} + +/* Update the local and glock texture LRUs. + */ +void r200UpdateTexLRU(r200ContextPtr rmesa, r200TexObjPtr t ) +{ + int heap = t->heap; + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = rmesa->r200Screen->logTexGranularity[heap]; + int i, start, end; + + rmesa->texture.age[heap] = ++rmesa->sarea->texAge[heap]; + + if ( !t->memBlock ) + return; + + start = t->memBlock->ofs >> sz; + end = (t->memBlock->ofs + t->memBlock->size-1) >> sz; + + /* Update our local LRU */ + move_to_head( &rmesa->texture.objects[heap], t ); + + /* Update the global LRU */ + for ( i = start ; i <= end ; i++ ) { + list[i].in_use = 1; + list[i].age = rmesa->texture.age[heap]; + + /* remove_from_list(i) */ + list[(CARD32)list[i].next].prev = list[i].prev; + list[(CARD32)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) */ + list[i].prev = RADEON_NR_TEX_REGIONS; + list[i].next = list[RADEON_NR_TEX_REGIONS].next; + list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i; + list[RADEON_NR_TEX_REGIONS].next = i; + } + + if ( 0 ) { + r200PrintGlobalLRU( rmesa, t->heap ); + r200PrintLocalLRU( rmesa, t->heap ); + } +} + +/* Update our notion of what textures have been changed since we last + * held the lock. This pertains to both our local textures and the + * textures belonging to other clients. Keep track of other client's + * textures by pushing a placeholder texture onto the LRU list -- these + * are denoted by (tObj == NULL). + */ +static void r200TexturesGone( r200ContextPtr rmesa, int heap, + int offset, int size, int in_use ) +{ + r200TexObjPtr t, tmp; + + foreach_s ( t, tmp, &rmesa->texture.objects[heap] ) { + if ( !t->memBlock || + t->memBlock->ofs >= offset + size || + t->memBlock->ofs + t->memBlock->size <= offset ) + continue; + + /* It overlaps - kick it out. Need to hold onto the currently + * bound objects, however. + */ + r200SwapOutTexObj( rmesa, t ); + } + + if ( in_use ) { + t = (r200TexObjPtr) CALLOC( sizeof(*t) ); + if ( !t ) return; + + t->memBlock = mmAllocMem( rmesa->texture.heap[heap], size, 0, offset ); + if ( !t->memBlock ) { + fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", + (int)size, (int)offset ); + mmDumpMemInfo( rmesa->texture.heap[heap] ); + return; + } + insert_at_head( &rmesa->texture.objects[heap], t ); + } +} + +/* Update our client's shared texture state. If another client has + * modified a region in which we have textures, then we need to figure + * out which of our textures has been removed, and update our global + * LRU. + */ +void r200AgeTextures( r200ContextPtr rmesa, int heap ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + + if ( sarea->texAge[heap] != rmesa->texture.age[heap] ) { + int sz = 1 << rmesa->r200Screen->logTexGranularity[heap]; + int nr = 0; + int idx; + + for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ; + idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ; + idx = sarea->texList[heap][idx].prev, nr++ ) + { + /* If switching texturing schemes, then the SAREA might not + * have been properly cleared, so we need to reset the + * global texture LRU. + */ + if ( idx * sz > rmesa->r200Screen->texSize[heap] ) { + nr = RADEON_NR_TEX_REGIONS; + break; + } + + if ( sarea->texList[heap][idx].age > rmesa->texture.age[heap] ) { + r200TexturesGone( rmesa, heap, idx * sz, sz, + sarea->texList[heap][idx].in_use ); + } + } + + if ( nr == RADEON_NR_TEX_REGIONS ) { + r200TexturesGone( rmesa, heap, 0, + rmesa->r200Screen->texSize[heap], 0 ); + r200ResetGlobalLRU( rmesa, heap ); + } + + rmesa->texture.age[heap] = sarea->texAge[heap]; + } +} + + +/* ------------------------------------------------------------ + * Texture image conversions + */ + + +static void r200UploadAGPClientSubImage( r200ContextPtr rmesa, + r200TexObjPtr t, + struct gl_texture_image *texImage, + GLint hwlevel, + GLint x, GLint y, + GLint width, GLint height ) +{ + const struct gl_texture_format *texFormat = texImage->TexFormat; + GLuint pitch = t->image[0].width * texFormat->TexelBytes; + int blit_format; + int srcOffset; + + + switch ( texFormat->TexelBytes ) { + case 1: + blit_format = R200_CP_COLOR_FORMAT_CI8; + break; + case 2: + blit_format = R200_CP_COLOR_FORMAT_RGB565; + break; + case 4: + blit_format = R200_CP_COLOR_FORMAT_ARGB8888; + break; + default: + return; + } + + t->image[hwlevel].data = texImage->Data; + srcOffset = r200AgpOffsetFromVirtual( rmesa, texImage->Data ); + + assert( srcOffset != ~0 ); + + /* Don't currently need to cope with small pitches? + */ + width = texImage->Width; + height = texImage->Height; + + r200EmitWait( rmesa, RADEON_WAIT_3D ); + + r200EmitBlit( rmesa, blit_format, + pitch, + srcOffset, + t->image[0].width * texFormat->TexelBytes, /* dst pitch! */ + t->bufAddr, + x, + y, + t->image[hwlevel].x + x, + t->image[hwlevel].y + y, + width, + height ); + + r200EmitWait( rmesa, RADEON_WAIT_2D ); +} + +static void r200UploadRectSubImage( r200ContextPtr rmesa, + r200TexObjPtr t, + struct gl_texture_image *texImage, + GLint x, GLint y, + GLint width, GLint height ) +{ + const struct gl_texture_format *texFormat = texImage->TexFormat; + int blit_format, blit_pitch, done; + + switch ( texFormat->TexelBytes ) { + case 1: + blit_format = R200_CP_COLOR_FORMAT_CI8; + break; + case 2: + blit_format = R200_CP_COLOR_FORMAT_RGB565; + break; + case 4: + blit_format = R200_CP_COLOR_FORMAT_ARGB8888; + break; + default: + return; + } + + t->image[0].data = texImage->Data; + + /* Currently don't need to cope with small pitches. + */ + width = texImage->Width; + height = texImage->Height; + blit_pitch = t->pp_txpitch + 32; + + if (rmesa->prefer_agp_client_texturing && texImage->IsClientData) { + /* In this case, could also use agp texturing. This is + * currently disabled, but has been tested & works. + */ + t->pp_txoffset = r200AgpOffsetFromVirtual( rmesa, texImage->Data ); + t->pp_txpitch = texImage->RowStride * texFormat->TexelBytes - 32; + + if (R200_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, + "Using agp texturing for rectangular client texture\n"); + + /* Release FB memory allocated for this image: + */ + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + } + else if (texImage->IsClientData) { + /* Data already in agp memory, with usable pitch. + */ + r200EmitBlit( rmesa, + blit_format, + texImage->RowStride * texFormat->TexelBytes, + r200AgpOffsetFromVirtual( rmesa, texImage->Data ), + blit_pitch, t->bufAddr, + 0, 0, + 0, 0, + width, height ); + } + else { + /* Data not in agp memory, or bad pitch. + */ + for (done = 0; done < height ; ) { + struct r200_dma_region region; + int lines = MIN2( height - done, RADEON_BUFFER_SIZE / blit_pitch ); + int src_pitch = texImage->RowStride * texFormat->TexelBytes; + char *tex = (char *)texImage->Data + done * src_pitch; + + memset(®ion, 0, sizeof(region)); + r200AllocDmaRegion( rmesa, ®ion, lines * blit_pitch, 64 ); + + /* Copy texdata to dma: + */ + if (0) + fprintf(stderr, "%s: src_pitch %d blit_pitch %d\n", + __FUNCTION__, src_pitch, blit_pitch); + + if (src_pitch == blit_pitch) { + memcpy( region.address, tex, lines * src_pitch ); + } + else { + char *buf = region.address; + int i; + for (i = 0 ; i < lines ; i++) { + memcpy( buf, tex, src_pitch ); + buf += blit_pitch; + tex += src_pitch; + } + } + + r200EmitWait( rmesa, RADEON_WAIT_3D ); + + /* Blit to framebuffer + */ + r200EmitBlit( rmesa, + blit_format, + blit_pitch, GET_START( ®ion ), + blit_pitch, t->bufAddr, + 0, 0, + 0, done, + width, lines ); + + r200EmitWait( rmesa, RADEON_WAIT_2D ); + + r200ReleaseDmaRegion( rmesa, ®ion, __FUNCTION__ ); + done += lines; + } + } +} + + +/* Upload the texture image associated with texture `t' at level `level' + * at the address relative to `start'. + */ +static void r200UploadSubImage( r200ContextPtr rmesa, + r200TexObjPtr t, + GLint hwlevel, + GLint x, GLint y, GLint width, GLint height ) +{ + struct gl_texture_image *texImage; + const struct gl_texture_format *texFormat; + GLint texelsPerDword = 0; + GLuint format, pitch, offset; + GLint imageWidth, imageHeight; + GLint ret; + drmRadeonTexture tex; + drmRadeonTexImage tmp; + int level = hwlevel + t->firstLevel; + + if ( R200_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s level %d %dx%d\n", __FUNCTION__, + level, width, height); + } + + /* Ensure we have a valid texture to upload */ + if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) { + _mesa_problem(NULL, "bad texture level in r200UploadSubimage"); + return; + } + + texImage = t->tObj->Image[level]; + if ( !texImage ) { + if ( R200_DEBUG & DEBUG_TEXTURE ) + fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level ); + return; + } + if ( !texImage->Data ) { + if ( R200_DEBUG & DEBUG_TEXTURE ) + fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ ); + return; + } + + + if (t->tObj->Target == GL_TEXTURE_RECTANGLE_NV) { + assert(level == 0); + assert(hwlevel == 0); + if ( R200_DEBUG & DEBUG_TEXTURE ) + fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__); + r200UploadRectSubImage( rmesa, t, texImage, x, y, width, height ); + return; + } + else if (texImage->IsClientData) { + if ( R200_DEBUG & DEBUG_TEXTURE ) + fprintf( stderr, "%s: image data is in agp client storage\n", + __FUNCTION__); + r200UploadAGPClientSubImage( rmesa, t, texImage, hwlevel, + x, y, width, height ); + return; + } + else if ( R200_DEBUG & DEBUG_TEXTURE ) + fprintf( stderr, "%s: image data is in normal memory\n", + __FUNCTION__); + + + texFormat = texImage->TexFormat; + + switch ( texFormat->TexelBytes ) { + case 1: + texelsPerDword = 4; + break; + case 2: + texelsPerDword = 2; + break; + case 4: + texelsPerDword = 1; + break; + } + + format = t->pp_txformat & R200_TXFORMAT_FORMAT_MASK; + + imageWidth = texImage->Width; + imageHeight = texImage->Height; + + offset = t->bufAddr; + pitch = (t->image[0].width * texFormat->TexelBytes) / 64; + + + if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) + { + GLint imageX = 0; + GLint imageY = 0; + GLint blitX = t->image[hwlevel].x; + GLint blitY = t->image[hwlevel].y; + GLint blitWidth = t->image[hwlevel].width; + GLint blitHeight = t->image[hwlevel].height; + fprintf( stderr, " upload image: %d,%d at %d,%d\n", + imageWidth, imageHeight, imageX, imageY ); + fprintf( stderr, " upload blit: %d,%d at %d,%d\n", + blitWidth, blitHeight, blitX, blitY ); + fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x " + "level: %d/%d format: %x\n", + (GLuint)offset, (GLuint)pitch, hwlevel, level, format ); + } + + t->image[hwlevel].data = texImage->Data; + + tex.offset = offset; + tex.pitch = pitch; + tex.format = format; + tex.width = imageWidth; + tex.height = imageHeight; + tex.image = &tmp; + + memcpy( &tmp, &t->image[hwlevel], sizeof(drmRadeonTexImage) ); + + LOCK_HARDWARE( rmesa ); + do { + ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE, + &tex, sizeof(drmRadeonTexture) ); + if (ret) { + if (R200_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n"); + usleep(1); + } + } while ( ret && errno == EAGAIN ); + + UNLOCK_HARDWARE( rmesa ); + + if ( ret ) { + fprintf( stderr, "DRM_R200_TEXTURE: return = %d\n", ret ); + fprintf( stderr, " offset=0x%08x pitch=0x%x format=%d\n", + offset, pitch, format ); + fprintf( stderr, " image width=%d height=%d\n", + imageWidth, imageHeight ); + fprintf( stderr, " blit width=%d height=%d data=%p\n", + t->image[hwlevel].width, t->image[hwlevel].height, + t->image[hwlevel].data ); + exit( 1 ); + } +} + + + +/* Upload the texture images associated with texture `t'. This might + * require removing our own and/or other client's texture objects to + * make room for these images. + */ +int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t ) +{ + const int numLevels = t->lastLevel - t->firstLevel + 1; + int heap; + r200TexObjPtr t0 = rmesa->state.texture.unit[0].texobj; + r200TexObjPtr t1 = rmesa->state.texture.unit[1].texobj; + + if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { + fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, + rmesa->glCtx, t->tObj, t->totalSize, + t->firstLevel, t->lastLevel ); + } + + if ( !t || t->totalSize == 0 ) + return 0; + + if (R200_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "\nSyncing\n\n"); + R200_FIREVERTICES( rmesa ); + r200Finish( rmesa->glCtx ); + } + + LOCK_HARDWARE( rmesa ); + + /* Choose the heap appropriately */ + heap = t->heap = RADEON_CARD_HEAP; + + /* Do we need to eject LRU texture objects? */ + if ( !t->memBlock ) { + /* Allocate a memory block on a 1k boundary (1<<10 == 1024) */ + t->memBlock = mmAllocMem( rmesa->texture.heap[heap], + t->totalSize, 10, 0 ); + + + /* Kick out textures until the requested texture fits */ + while ( !t->memBlock ) { + if ( rmesa->texture.objects[heap].prev == t0 || + rmesa->texture.objects[heap].prev == t1 ) { + fprintf( stderr, + "r200UploadTexImages: ran into bound texture\n" ); + UNLOCK_HARDWARE( rmesa ); + return -1; + } + if ( rmesa->texture.objects[heap].prev == + &rmesa->texture.objects[heap] ) { + if ( rmesa->r200Screen->IsPCI ) { + fprintf( stderr, "r200UploadTexImages: upload texture " + "failure on local texture heaps, sz=%d\n", + t->totalSize ); + UNLOCK_HARDWARE( rmesa ); + return -1; + } else { + fprintf( stderr, "r200UploadTexImages: upload texture " + "failure on both local and AGP texture heaps, " + "sz=%d\n", + t->totalSize ); + UNLOCK_HARDWARE( rmesa ); + return -1; + } + } + + r200SwapOutTexObj( rmesa, rmesa->texture.objects[heap].prev ); + + t->memBlock = mmAllocMem( rmesa->texture.heap[heap], + t->totalSize, 12, 0 ); + } + + /* Set the base offset of the texture image */ + t->bufAddr = rmesa->r200Screen->texOffset[heap] + t->memBlock->ofs; + t->pp_txoffset = t->bufAddr; + + /* Mark this texobj as dirty on all units: + */ + t->dirty_state = TEX_ALL; + } + + /* Let the world know we've used this memory recently */ + r200UpdateTexLRU( rmesa, t ); + UNLOCK_HARDWARE( rmesa ); + + /* Upload any images that are new */ + if (t->dirty_images) { + int hwlevel; + for ( hwlevel = 0 ; hwlevel < numLevels ; hwlevel++ ) { + if ( t->dirty_images & (1 << (hwlevel+t->firstLevel)) ) { + r200UploadSubImage( rmesa, t, hwlevel, + 0, 0, + t->image[hwlevel].width, + t->image[hwlevel].height ); + } + } + t->dirty_images = 0; + } + + + + if (R200_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "\nSyncing\n\n"); + r200Finish( rmesa->glCtx ); + } + + return 0; +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_texstate.c b/xc/lib/GL/mesa/src/drv/r200/r200_texstate.c new file mode 100644 index 000000000..e25bfebda --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_texstate.c @@ -0,0 +1,1519 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_texstate.c,v 1.3 2003/02/15 22:18:47 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "r200_context.h" +#include "r200_state.h" +#include "r200_ioctl.h" +#include "r200_swtcl.h" +#include "r200_tex.h" +#include "r200_tcl.h" + +#include "colormac.h" +#include "context.h" +#include "enums.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "simple_list.h" +#include "texformat.h" + + +static void r200SetTexImages( r200ContextPtr rmesa, + struct gl_texture_object *tObj, + GLenum target ) +{ + r200TexObjPtr t = (r200TexObjPtr)tObj->DriverData; + const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel]; + GLint totalSize; + GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0; + GLint x, y, width, height; + GLint i; + GLint firstLevel=0, lastLevel=0, numLevels; + GLint log2Width, log2Height; + GLuint txformat = 0; + + t->pp_txfilter &= ~R200_YUV_TO_RGB; + + /* Set the hardware texture format + */ + switch (baseImage->TexFormat->MesaFormat) { + case MESA_FORMAT_I8: + txformat = R200_TXFORMAT_I8; + break; + case MESA_FORMAT_AL88: + txformat = R200_TXFORMAT_AI88; + break; + case MESA_FORMAT_RGBA8888: + txformat = R200_TXFORMAT_RGBA8888; + break; + case MESA_FORMAT_ARGB8888: + txformat = R200_TXFORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + txformat = R200_TXFORMAT_RGB565; + break; + case MESA_FORMAT_ARGB1555: + txformat = R200_TXFORMAT_ARGB1555; + break; + case MESA_FORMAT_ARGB4444: + txformat = R200_TXFORMAT_ARGB4444; + break; + case MESA_FORMAT_YCBCR: + txformat = R200_TXFORMAT_YVYU422; + t->pp_txfilter |= R200_YUV_TO_RGB; + break; + case MESA_FORMAT_YCBCR_REV: + txformat = R200_TXFORMAT_VYUY422; + t->pp_txfilter |= R200_YUV_TO_RGB; + break; + default: + _mesa_problem(NULL, "unexpected texture format in r200TexImage2D"); + return; + } + + t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK | + R200_TXFORMAT_ALPHA_IN_MAP); + t->pp_txformat |= txformat; + + if ( txformat == R200_TXFORMAT_RGBA8888 || + txformat == R200_TXFORMAT_ARGB8888 || + txformat == R200_TXFORMAT_ARGB4444 || + txformat == R200_TXFORMAT_ARGB1555 || + txformat == R200_TXFORMAT_AI88 ) { + t->pp_txformat |= R200_TXFORMAT_ALPHA_IN_MAP; + } + + /* The R200 has a 64-byte minimum pitch for all blits. We + * calculate the equivalent number of texels to simplify the + * calculation of the texture image area. + */ + switch ( baseImage->TexFormat->TexelBytes ) { + case 1: + texelsPerDword = 4; + blitPitch = 64; + break; + case 2: + texelsPerDword = 2; + blitPitch = 32; + break; + case 4: + texelsPerDword = 1; + blitPitch = 16; + break; + default: + assert(0); + } + + /* Select the larger of the two widths for our global texture image + * coordinate space. As the R200 has very strict offset rules, we + * can't upload mipmaps directly and have to reference their location + * from the aligned start of the whole image. + */ + blitWidth = MAX2( baseImage->Width, blitPitch ); + + /* Calculate mipmap offsets and dimensions. + */ + totalSize = 0; + x = 0; + y = 0; + + /* Compute which mipmap levels we really want to send to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + * Yes, this looks overly complicated, but it's all needed. + */ + if (R200_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, + "%s: BaseLevel %d MinLod %f MaxLod %f MaxLevel %d\n", + __FUNCTION__, + tObj->BaseLevel, tObj->MinLod, tObj->MaxLod, + tObj->MaxLevel); + + + switch (target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + log2Width = tObj->Image[firstLevel]->WidthLog2; + log2Height = tObj->Image[firstLevel]->HeightLog2; + break; + case GL_TEXTURE_RECTANGLE_NV: + firstLevel = lastLevel = 0; + log2Width = log2Height = 1; /* ? */ + break; + default: + return; + } + + /* save these values */ + t->firstLevel = firstLevel; + t->lastLevel = lastLevel; + + numLevels = lastLevel - firstLevel + 1; + + if (R200_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, + "%s: firstLevel %d last Level %d w,h: %d,%d log(w,h) %d,%d\n", + __FUNCTION__, firstLevel, lastLevel, + tObj->Image[firstLevel]->Width, + tObj->Image[firstLevel]->Height, + tObj->Image[firstLevel]->WidthLog2, + tObj->Image[firstLevel]->HeightLog2); + + + assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS); + + for ( i = 0 ; i < numLevels ; i++ ) { + const struct gl_texture_image *texImage; + GLuint size; + + texImage = tObj->Image[i + firstLevel]; + if ( !texImage ) + break; + + width = texImage->Width; + height = texImage->Height; + + /* Texture images have a minimum pitch of 32 bytes (half of the + * 64-byte minimum pitch for blits). For images that have a + * width smaller than this, we must pad each texture image + * scanline out to this amount. + */ + if ( width < blitPitch / 2 ) { + width = blitPitch / 2; + } + + if (target == GL_TEXTURE_RECTANGLE_NV) + size = ((width*baseImage->TexFormat->TexelBytes+63)&~63) * height; + else + size = width * height * baseImage->TexFormat->TexelBytes; + + totalSize += size; + + if (target != GL_TEXTURE_RECTANGLE_NV) { + while ( width < blitWidth && height > 1 ) { + width *= 2; + height /= 2; + } + } + + t->image[i].x = x; + t->image[i].y = y; + t->image[i].width = width; + t->image[i].height = height; + + /* While blits must have a pitch of at least 64 bytes, mipmaps + * must be aligned on a 32-byte boundary (just like each texture + * image scanline). + */ + if ( width >= blitWidth ) { + y += height; + } else { + x += width; + if ( x >= blitWidth ) { + x = 0; + y++; + } + } + + if ( 0 ) + fprintf( stderr, "level=%d p=%d %dx%d -> %dx%d at (%d,%d)\n", + i, blitWidth, baseImage->Width, baseImage->Height, + t->image[i].width, t->image[i].height, + t->image[i].x, t->image[i].y ); + } + + /* Align the total size of texture memory block. + */ + t->totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + + /* Hardware state: + */ + t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK; + t->pp_txfilter |= (numLevels - 1) << R200_MAX_MIP_LEVEL_SHIFT; + + t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK | + R200_TXFORMAT_HEIGHT_MASK); + t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) | + (log2Height << R200_TXFORMAT_HEIGHT_SHIFT)); + + t->pp_txsize = (((tObj->Image[firstLevel]->Width - 1) << 0) | + ((tObj->Image[firstLevel]->Height - 1) << 16)); + + /* Only need to round to nearest 32 for textures, but the blitter + * requires 64-byte aligned pitches, and we may/may not need the + * blitter. + */ + t->pp_txpitch = ((tObj->Image[firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63); + t->pp_txpitch -= 32; + + t->dirty_state = TEX_ALL; + + r200UploadTexImages( rmesa, t ); +} + + + +/* ================================================================ + * Texture combine functions + */ + +#define R200_DISABLE 0 +#define R200_REPLACE 1 +#define R200_MODULATE 2 +#define R200_DECAL 3 +#define R200_BLEND 4 +#define R200_ADD 5 +#define R200_MAX_COMBFUNC 6 + +static GLuint r200_color_combine[][R200_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_DIFFUSE_COLOR | + R200_TXC_OP_MADD), + + /* GL_REPLACE = 0x00802800 + */ + (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R0_COLOR | + R200_TXC_OP_MADD), + + /* GL_MODULATE = 0x00800142 + */ + (R200_TXC_ARG_A_DIFFUSE_COLOR | /* current starts in DIFFUSE */ + R200_TXC_ARG_B_R0_COLOR | + R200_TXC_ARG_C_ZERO | + R200_TXC_OP_MADD), + + /* GL_DECAL = 0x008c2d42 + */ + (R200_TXC_ARG_A_DIFFUSE_COLOR | + R200_TXC_ARG_B_R0_COLOR | + R200_TXC_ARG_C_R0_ALPHA | + R200_TXC_OP_LERP), + + /* GL_BLEND = 0x008c2902 + */ + (R200_TXC_ARG_A_DIFFUSE_COLOR | + R200_TXC_ARG_B_TFACTOR_COLOR | + R200_TXC_ARG_C_R0_COLOR | + R200_TXC_OP_LERP), + + /* GL_ADD = 0x00812802 + */ + (R200_TXC_ARG_A_DIFFUSE_COLOR | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R0_COLOR | + R200_TXC_COMP_ARG_B | + R200_TXC_OP_MADD), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R0_COLOR | + R200_TXC_OP_MADD), + + /* GL_REPLACE = 0x00803000 + */ + (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R1_COLOR | + R200_TXC_OP_MADD), + + /* GL_MODULATE = 0x00800182 + */ + (R200_TXC_ARG_A_R0_COLOR | /* current in R0 thereafter */ + R200_TXC_ARG_B_R1_COLOR | + R200_TXC_ARG_C_ZERO | + R200_TXC_OP_MADD), + + /* GL_DECAL = 0x008c3582 + */ + (R200_TXC_ARG_A_R0_COLOR | + R200_TXC_ARG_B_R1_COLOR | + R200_TXC_ARG_C_R1_ALPHA | + R200_TXC_OP_LERP), + + /* GL_BLEND = 0x008c3102 + */ + (R200_TXC_ARG_A_R0_COLOR | + R200_TXC_ARG_B_TFACTOR_COLOR | + R200_TXC_ARG_C_R1_COLOR | + R200_TXC_OP_LERP), + + /* GL_ADD = 0x00813002 + */ + (R200_TXC_ARG_A_R0_COLOR | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R1_COLOR | + R200_TXC_COMP_ARG_B | + R200_TXC_OP_MADD), + }, + + /* Unit 2: + */ + { + /* Disable combiner stage + */ + (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R0_COLOR | + R200_TXC_OP_MADD), + + /* GL_REPLACE = 0x00803800 + */ + (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R2_COLOR | + R200_TXC_OP_MADD), + + /* GL_MODULATE = 0x008001c2 + */ + (R200_TXC_ARG_A_R0_COLOR | + R200_TXC_ARG_B_R2_COLOR | + R200_TXC_ARG_C_ZERO | + R200_TXC_OP_MADD), + + /* GL_DECAL = 0x008c3dc2 + */ + (R200_TXC_ARG_A_R0_COLOR | + R200_TXC_ARG_B_R2_COLOR | + R200_TXC_ARG_C_R2_ALPHA | + R200_TXC_OP_LERP), + + /* GL_BLEND = 0x008c3902 + */ + (R200_TXC_ARG_A_R0_COLOR | + R200_TXC_ARG_B_TFACTOR_COLOR | + R200_TXC_ARG_C_R2_COLOR | + R200_TXC_OP_LERP), + + /* GL_ADD = 0x00813802 + */ + (R200_TXC_ARG_A_R0_COLOR | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R2_COLOR | + R200_TXC_COMP_ARG_B | + R200_TXC_OP_MADD), + } +}; + +static GLuint r200_alpha_combine[][R200_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_DIFFUSE_ALPHA | + R200_TXA_OP_MADD), + + + /* GL_REPLACE = 0x00800500 + */ + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R0_ALPHA | + R200_TXA_OP_MADD), + + /* GL_MODULATE = 0x00800051 + */ + (R200_TXA_ARG_A_DIFFUSE_ALPHA | + R200_TXA_ARG_B_R0_ALPHA | + R200_TXA_ARG_C_ZERO | + R200_TXA_OP_MADD), + + /* GL_DECAL = 0x00800100 + */ + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_DIFFUSE_ALPHA | + R200_TXA_OP_MADD), + + /* GL_BLEND = 0x00800051 + */ + (R200_TXA_ARG_A_DIFFUSE_ALPHA | + R200_TXA_ARG_B_TFACTOR_ALPHA | + R200_TXA_ARG_C_R0_ALPHA | + R200_TXA_OP_LERP), + + /* GL_ADD = 0x00800051 + */ + (R200_TXA_ARG_A_DIFFUSE_ALPHA | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R0_ALPHA | + R200_TXC_COMP_ARG_B | + R200_TXA_OP_MADD), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R0_ALPHA | + R200_TXA_OP_MADD), + + /* GL_REPLACE = 0x00800600 + */ + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R1_ALPHA | + R200_TXA_OP_MADD), + + /* GL_MODULATE = 0x00800061 + */ + (R200_TXA_ARG_A_R0_ALPHA | + R200_TXA_ARG_B_R1_ALPHA | + R200_TXA_ARG_C_ZERO | + R200_TXA_OP_MADD), + + /* GL_DECAL = 0x00800100 + */ + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R0_ALPHA | + R200_TXA_OP_MADD), + + /* GL_BLEND = 0x00800061 + */ + (R200_TXA_ARG_A_R0_ALPHA | + R200_TXA_ARG_B_TFACTOR_ALPHA | + R200_TXA_ARG_C_R1_ALPHA | + R200_TXA_OP_LERP), + + /* GL_ADD = 0x00800061 + */ + (R200_TXA_ARG_A_R0_ALPHA | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R1_ALPHA | + R200_TXC_COMP_ARG_B | + R200_TXA_OP_MADD), + }, + + /* Unit 2: + */ + { + /* Disable combiner stage + */ + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R0_ALPHA | + R200_TXA_OP_MADD), + + /* GL_REPLACE = 0x00800700 + */ + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R2_ALPHA | + R200_TXA_OP_MADD), + + /* GL_MODULATE = 0x00800071 + */ + (R200_TXA_ARG_A_R0_ALPHA | + R200_TXA_ARG_B_R2_ALPHA | + R200_TXA_ARG_C_ZERO | + R200_TXA_OP_MADD), + + /* GL_DECAL = 0x00800100 + */ + (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R0_ALPHA | + R200_TXA_OP_MADD), + + /* GL_BLEND = 0x00800071 + */ + (R200_TXA_ARG_A_R0_ALPHA | + R200_TXA_ARG_B_TFACTOR_ALPHA | + R200_TXA_ARG_C_R2_ALPHA | + R200_TXA_OP_LERP), + + /* GL_ADD = 0x00800021 + */ + (R200_TXA_ARG_A_R0_ALPHA | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R2_ALPHA | + R200_TXC_COMP_ARG_B | + R200_TXA_OP_MADD), + } +}; + + +/* GL_ARB_texture_env_combine support + */ + +/* The color tables have combine functions for GL_SRC_COLOR, + * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. + */ +static GLuint r200_register_color[][R200_MAX_TEXTURE_UNITS] = +{ + { + R200_TXC_ARG_A_R0_COLOR, + R200_TXC_ARG_A_R1_COLOR, + R200_TXC_ARG_A_R2_COLOR + }, + { + R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A, + R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A, + R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A + }, + { + R200_TXC_ARG_A_R0_ALPHA, + R200_TXC_ARG_A_R1_ALPHA, + R200_TXC_ARG_A_R2_ALPHA + }, + { + R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A, + R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A, + R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A + }, +}; + +static GLuint r200_tfactor_color[] = +{ + R200_TXC_ARG_A_TFACTOR_COLOR, + R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A, + R200_TXC_ARG_A_TFACTOR_ALPHA, + R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A +}; + +static GLuint r200_primary_color[] = +{ + R200_TXC_ARG_A_DIFFUSE_COLOR, + R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A, + R200_TXC_ARG_A_DIFFUSE_ALPHA, + R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A +}; + + +/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. + */ +static GLuint r200_register_alpha[][R200_MAX_TEXTURE_UNITS] = +{ + { + R200_TXA_ARG_A_R0_ALPHA, + R200_TXA_ARG_A_R1_ALPHA, + R200_TXA_ARG_A_R2_ALPHA + }, + { + R200_TXA_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A, + R200_TXA_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A, + R200_TXA_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A + }, +}; + +static GLuint r200_tfactor_alpha[] = +{ + R200_TXA_ARG_A_TFACTOR_ALPHA, + R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A +}; + +static GLuint r200_primary_alpha[] = +{ + R200_TXA_ARG_A_DIFFUSE_ALPHA, + R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A +}; + + + +/* Extract the arg from slot A, shift it into the correct argument slot + * and set the corresponding complement bit. + */ +#define R200_COLOR_ARG( n, arg ) \ +do { \ + color_combine |= \ + ((color_arg[n] & R200_TXC_ARG_A_MASK) \ + << R200_TXC_ARG_##arg##_SHIFT); \ + color_combine |= \ + ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \ + << R200_TXC_COMP_ARG_##arg##_SHIFT); \ +} while (0) + +#define R200_ALPHA_ARG( n, arg ) \ +do { \ + alpha_combine |= \ + ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \ + << R200_TXA_ARG_##arg##_SHIFT); \ + alpha_combine |= \ + ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \ + << R200_TXA_COMP_ARG_##arg##_SHIFT); \ +} while (0) + + +/* ================================================================ + * Texture unit state management + */ + +static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint color_combine, alpha_combine; + GLuint color_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2]; + GLuint alpha_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2]; + + if ( R200_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, ctx, unit ); + } + + /* Set the texture environment state. Isn't this nice and clean? + * The R200 will automagically set the texture alpha to 0xff when + * the texture format does not include an alpha component. This + * reduces the amount of special-casing we have to do, alpha-only + * textures being a notable exception. + */ + if ( !texUnit->_ReallyEnabled ) { + /* Don't cache these results. + */ + rmesa->state.texture.unit[unit].format = 0; + rmesa->state.texture.unit[unit].envMode = 0; + color_combine = r200_color_combine[unit][R200_DISABLE]; + alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; + } + else { + const struct gl_texture_object *tObj = texUnit->_Current; + const GLenum format = tObj->Image[tObj->BaseLevel]->Format; + GLuint color_arg[3], alpha_arg[3]; + GLuint i, numColorArgs = 0, numAlphaArgs = 0; + GLuint RGBshift = texUnit->CombineScaleShiftRGB; + GLuint Ashift = texUnit->CombineScaleShiftA; + + switch ( texUnit->EnvMode ) { + case GL_REPLACE: + switch ( format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = r200_color_combine[unit][R200_REPLACE]; + alpha_combine = r200_alpha_combine[unit][R200_REPLACE]; + break; + case GL_ALPHA: + color_combine = r200_color_combine[unit][R200_DISABLE]; + alpha_combine = r200_alpha_combine[unit][R200_REPLACE]; + break; + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + color_combine = r200_color_combine[unit][R200_REPLACE]; + alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_MODULATE: + switch ( format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = r200_color_combine[unit][R200_MODULATE]; + alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; + break; + case GL_ALPHA: + color_combine = r200_color_combine[unit][R200_DISABLE]; + alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; + break; + case GL_RGB: + case GL_LUMINANCE: + case GL_YCBCR_MESA: + color_combine = r200_color_combine[unit][R200_MODULATE]; + alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_DECAL: + switch ( format ) { + case GL_RGBA: + case GL_RGB: + case GL_YCBCR_MESA: + color_combine = r200_color_combine[unit][R200_DECAL]; + alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = r200_color_combine[unit][R200_DISABLE]; + alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_BLEND: + switch ( format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_YCBCR_MESA: + color_combine = r200_color_combine[unit][R200_BLEND]; + alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; + break; + case GL_ALPHA: + color_combine = r200_color_combine[unit][R200_DISABLE]; + alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; + break; + case GL_INTENSITY: + color_combine = r200_color_combine[unit][R200_BLEND]; + alpha_combine = r200_alpha_combine[unit][R200_BLEND]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_ADD: + switch ( format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_YCBCR_MESA: + color_combine = r200_color_combine[unit][R200_ADD]; + alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; + break; + case GL_ALPHA: + color_combine = r200_color_combine[unit][R200_DISABLE]; + alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; + break; + case GL_INTENSITY: + color_combine = r200_color_combine[unit][R200_ADD]; + alpha_combine = r200_alpha_combine[unit][R200_ADD]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_COMBINE: + /* Don't cache these results. + */ + rmesa->state.texture.unit[unit].format = 0; + rmesa->state.texture.unit[unit].envMode = 0; + + /* Step 0: + * Calculate how many arguments we need to process. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + numColorArgs = 1; + break; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED: + case GL_SUBTRACT: + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + numColorArgs = 2; + break; + case GL_INTERPOLATE: + numColorArgs = 3; + break; + default: + return; + } + + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + numAlphaArgs = 1; + break; + case GL_SUBTRACT: + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED: + numAlphaArgs = 2; + break; + case GL_INTERPOLATE: + numAlphaArgs = 3; + break; + default: + return; + } + + /* Step 1: + * Extract the color and alpha combine function arguments. + */ + for ( i = 0 ; i < numColorArgs ; i++ ) { + const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR; + assert(op >= 0); + assert(op <= 3); + switch ( texUnit->CombineSourceRGB[i] ) { + case GL_TEXTURE: + color_arg[i] = r200_register_color[op][unit]; + break; + case GL_CONSTANT: + color_arg[i] = r200_tfactor_color[op]; + break; + case GL_PRIMARY_COLOR: + color_arg[i] = r200_primary_color[op]; + break; + case GL_PREVIOUS: + if (unit == 0) + color_arg[i] = r200_primary_color[op]; + else + color_arg[i] = r200_register_color[op][0]; + break; + default: + return; + } + } + + for ( i = 0 ; i < numAlphaArgs ; i++ ) { + const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA; + assert(op >= 0); + assert(op <= 1); + switch ( texUnit->CombineSourceA[i] ) { + case GL_TEXTURE: + alpha_arg[i] = r200_register_alpha[op][unit]; + break; + case GL_CONSTANT: + alpha_arg[i] = r200_tfactor_alpha[op]; + break; + case GL_PRIMARY_COLOR: + alpha_arg[i] = r200_primary_alpha[op]; + break; + case GL_PREVIOUS: + if (unit == 0) + alpha_arg[i] = r200_primary_alpha[op]; + else + alpha_arg[i] = r200_register_alpha[op][0]; + break; + default: + return; + } + } + + /* Step 2: + * Build up the color and alpha combine functions. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + color_combine = (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_OP_MADD); + R200_COLOR_ARG( 0, C ); + break; + case GL_MODULATE: + color_combine = (R200_TXC_ARG_C_ZERO | + R200_TXC_OP_MADD); + R200_COLOR_ARG( 0, A ); + R200_COLOR_ARG( 1, B ); + break; + case GL_ADD: + color_combine = (R200_TXC_ARG_B_ZERO | + R200_TXC_COMP_ARG_B | + R200_TXC_OP_MADD); + R200_COLOR_ARG( 0, A ); + R200_COLOR_ARG( 1, C ); + break; + case GL_SUBTRACT: + color_combine = (R200_TXC_ARG_B_ZERO | + R200_TXC_COMP_ARG_B | + R200_TXC_NEG_ARG_C | + R200_TXC_OP_MADD); + R200_COLOR_ARG( 0, A ); + R200_COLOR_ARG( 1, C ); + break; + case GL_ADD_SIGNED: + color_combine = (R200_TXC_ARG_B_ZERO | + R200_TXC_COMP_ARG_B | + R200_TXC_BIAS_ARG_C | /* new */ + R200_TXC_OP_MADD); /* was ADDSIGNED */ + R200_COLOR_ARG( 0, A ); + R200_COLOR_ARG( 1, C ); + break; + case GL_INTERPOLATE: + color_combine = (R200_TXC_OP_LERP); + R200_COLOR_ARG( 0, B ); + R200_COLOR_ARG( 1, A ); + R200_COLOR_ARG( 2, C ); + break; + + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + RGBshift = 0; + Ashift = 0; + /* FALLTHROUGH */ + + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + /* DOT3 works differently on R200 than on R100. On R100, just + * setting the DOT3 mode did everything for you. On R200, the + * driver has to enable the biasing (the -0.5 in the combine + * equation), and it has add the 4x scale factor. The hardware + * only supports up to 8x in the post filter, so 2x part of it + * happens on the inputs going into the combiner. + */ + + RGBshift++; + Ashift = RGBshift; + + color_combine = (R200_TXC_ARG_C_ZERO | + R200_TXC_OP_DOT3 | + R200_TXC_BIAS_ARG_A | + R200_TXC_BIAS_ARG_B | + R200_TXC_SCALE_ARG_A | + R200_TXC_SCALE_ARG_B); + R200_COLOR_ARG( 0, A ); + R200_COLOR_ARG( 1, B ); + break; + + default: + return; + } + + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + alpha_combine = (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_OP_MADD); + R200_ALPHA_ARG( 0, C ); + break; + case GL_MODULATE: + alpha_combine = (R200_TXA_ARG_C_ZERO | + R200_TXA_OP_MADD); + R200_ALPHA_ARG( 0, A ); + R200_ALPHA_ARG( 1, B ); + break; + case GL_ADD: + alpha_combine = (R200_TXA_ARG_B_ZERO | + R200_TXC_COMP_ARG_B | + R200_TXA_OP_MADD); + R200_ALPHA_ARG( 0, A ); + R200_ALPHA_ARG( 1, C ); + break; + case GL_SUBTRACT: + alpha_combine = (R200_TXA_ARG_B_ZERO | + R200_TXC_COMP_ARG_B | + R200_TXC_NEG_ARG_C | + R200_TXA_OP_MADD); + R200_ALPHA_ARG( 0, A ); + R200_ALPHA_ARG( 1, C ); + break; + case GL_ADD_SIGNED: + alpha_combine = (R200_TXA_ARG_B_ZERO | + R200_TXC_COMP_ARG_B | + R200_TXC_BIAS_ARG_C | /* new */ + R200_TXA_OP_MADD); /* was ADDSIGNED */ + R200_ALPHA_ARG( 0, A ); + R200_ALPHA_ARG( 1, C ); + break; + case GL_INTERPOLATE: + alpha_combine = (R200_TXA_OP_LERP); + R200_ALPHA_ARG( 0, B ); + R200_ALPHA_ARG( 1, A ); + R200_ALPHA_ARG( 2, C ); + break; + default: + return; + } + + if ( texUnit->CombineModeRGB == GL_DOT3_RGB ) { + alpha_scale |= R200_TXA_DOT_ALPHA; + } + + /* Step 3: + * Apply the scale factor. The EXT version of the DOT3 extension does + * not support the scale factor, but the ARB version (and the version in + * OpenGL 1.3) does. + */ + color_scale &= ~R200_TXC_SCALE_MASK; + alpha_scale &= ~R200_TXA_SCALE_MASK; + color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT); + alpha_scale |= (Ashift << R200_TXA_SCALE_SHIFT); + + /* All done! + */ + break; + + default: + return; + } + } + + if ( rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] != color_combine || + rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] != alpha_combine || + rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] != color_scale || + rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] != alpha_scale) { + R200_STATECHANGE( rmesa, pix[unit] ); + rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] = color_combine; + rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] = alpha_combine; + rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] = color_scale; + rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] = alpha_scale; + } +} + +#define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \ + R200_MIN_FILTER_MASK | \ + R200_MAG_FILTER_MASK | \ + R200_MAX_ANISO_MASK | \ + R200_YUV_TO_RGB | \ + R200_YUV_TEMPERATURE_MASK | \ + R200_CLAMP_S_MASK | \ + R200_CLAMP_T_MASK) + +#define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \ + R200_TXFORMAT_HEIGHT_MASK | \ + R200_TXFORMAT_FORMAT_MASK | \ + R200_TXFORMAT_ALPHA_IN_MAP | \ + R200_TXFORMAT_NON_POWER2) + + + +static void import_tex_obj_state( r200ContextPtr rmesa, + int unit, + r200TexObjPtr texobj ) +{ + GLuint *cmd = R200_DB_STATE( tex[unit] ); + + cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; + cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; + cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; + cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; + cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */ + cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */ + cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset; + cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; + texobj->dirty_state &= ~(1<<unit); + + R200_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] ); +} + + + + +static void set_texgen_matrix( r200ContextPtr rmesa, + GLuint unit, + GLfloat *s_plane, + GLfloat *t_plane ) +{ + static const GLfloat scale_identity[4] = { 1,1,1,1 }; + + if (!TEST_EQ_4V( s_plane, scale_identity) || + !(TEST_EQ_4V( t_plane, scale_identity))) { + rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit; + rmesa->TexGenMatrix[unit].m[0] = s_plane[0]; + rmesa->TexGenMatrix[unit].m[4] = s_plane[1]; + rmesa->TexGenMatrix[unit].m[8] = s_plane[2]; + rmesa->TexGenMatrix[unit].m[12] = s_plane[3]; + + rmesa->TexGenMatrix[unit].m[1] = t_plane[0]; + rmesa->TexGenMatrix[unit].m[5] = t_plane[1]; + rmesa->TexGenMatrix[unit].m[9] = t_plane[2]; + rmesa->TexGenMatrix[unit].m[13] = t_plane[3]; + rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + } +} + +/* Ignoring the Q texcoord for now. + * + * Returns GL_FALSE if fallback required. + */ +static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4; + GLuint tmp = rmesa->TexGenEnabled; + + rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); + rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit); + rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit); + rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); + rmesa->TexGenNeedNormals[unit] = 0; + + if (0) + fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit); + + if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) { + /* Disabled, no fallback: + */ + rmesa->TexGenInputs |= + (R200_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; + return GL_TRUE; + } + else if (texUnit->TexGenEnabled & Q_BIT) { + /* Very easy to do this, in fact would remove a fallback case + * elsewhere, but I haven't done it yet... Fallback: + */ + fprintf(stderr, "fallback Q_BIT\n"); + return GL_FALSE; + } + else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) || + texUnit->GenModeS != texUnit->GenModeT) { + /* Mixed modes, fallback: + */ +/* fprintf(stderr, "fallback mixed texgen\n"); */ + return GL_FALSE; + } + else + rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit; + + switch (texUnit->GenModeS) { + case GL_OBJECT_LINEAR: + rmesa->TexGenInputs |= R200_TEXGEN_INPUT_OBJ << inputshift; + set_texgen_matrix( rmesa, unit, + texUnit->ObjectPlaneS, + texUnit->ObjectPlaneT); + break; + + case GL_EYE_LINEAR: + rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE << inputshift; + set_texgen_matrix( rmesa, unit, + texUnit->EyePlaneS, + texUnit->EyePlaneT); + break; + + case GL_REFLECTION_MAP_NV: + rmesa->TexGenNeedNormals[unit] = GL_TRUE; + rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_REFLECT<<inputshift; + break; + + case GL_NORMAL_MAP_NV: + rmesa->TexGenNeedNormals[unit] = GL_TRUE; + rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift; + break; + + case GL_SPHERE_MAP: + rmesa->TexGenNeedNormals[unit] = GL_TRUE; + rmesa->TexGenInputs |= R200_TEXGEN_INPUT_SPHERE<<inputshift; + break; + + default: + /* Unsupported mode, fallback: + */ + /* fprintf(stderr, "fallback unsupported texgen\n"); */ + return GL_FALSE; + } + + rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit; + + if (tmp != rmesa->TexGenEnabled) { + rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + } + + if (0) + fprintf(stderr, "%s unit %d neednormals %d\n", __FUNCTION__, unit, + rmesa->TexGenNeedNormals[unit]); + + return GL_TRUE; +} + + +static void disable_tex( GLcontext *ctx, int unit ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit)) { + /* Texture unit disabled */ + rmesa->state.texture.unit[unit].texobj = 0; + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((R200_TEX_0_ENABLE | + R200_TEX_BLEND_0_ENABLE) << unit); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_BLEND_0_ENABLE; + + R200_STATECHANGE( rmesa, tcl ); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); + + if (rmesa->TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) { + TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE); + } + + /* Actually want to keep all units less than max active texture + * enabled, right? Fix this for >2 texunits. + */ + if (unit == 0) + r200UpdateTextureEnv( ctx, unit ); + + + { + GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4; + GLuint tmp = rmesa->TexGenEnabled; + + rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit); + rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit); + rmesa->TexGenEnabled &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); + rmesa->TexGenNeedNormals[unit] = 0; + rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); + rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); + + if (tmp != rmesa->TexGenEnabled) { + rmesa->recheck_texgen[unit] = GL_TRUE; + rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + } + } + } +} + +static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; + + /* Need to load the 2d images associated with this unit. + */ + if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { + t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; + t->dirty_images = ~0; + } + + if ( t->dirty_images ) { + R200_FIREVERTICES( rmesa ); + r200SetTexImages( rmesa, tObj, GL_TEXTURE_2D ); + if ( !t->memBlock ) + return GL_FALSE; + } + + return GL_TRUE; +} + +static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; + + if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) { + t->pp_txformat |= R200_TXFORMAT_NON_POWER2; + t->dirty_images = ~0; + } + + if ( t->dirty_images ) { + R200_FIREVERTICES( rmesa ); + r200SetTexImages( rmesa, tObj, GL_TEXTURE_RECTANGLE_NV ); + if ( !t->memBlock && !rmesa->prefer_agp_client_texturing ) + return GL_FALSE; + } + + return GL_TRUE; +} + + +static GLboolean update_tex_common( GLcontext *ctx, int unit ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; + GLenum format; + + /* Fallback if there's a texture border */ + if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) + return GL_FALSE; + + /* Update state if this is a different texture object to last + * time. + */ + if ( rmesa->state.texture.unit[unit].texobj != t ) { + rmesa->state.texture.unit[unit].texobj = t; + t->dirty_state |= 1<<unit; + r200UpdateTexLRU( rmesa, t ); /* XXX: should be locked! */ + } + + + /* Newly enabled? + */ + if ( 1|| !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit))) { + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_0_ENABLE | + R200_TEX_BLEND_0_ENABLE) << unit; + + R200_STATECHANGE( rmesa, vtx ); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3); + + rmesa->recheck_texgen[unit] = GL_TRUE; + } + + if (t->dirty_state & (1<<unit)) { + import_tex_obj_state( rmesa, unit, t ); + } + + if (rmesa->recheck_texgen[unit]) { + GLboolean fallback = !r200_validate_texgen( ctx, unit ); + TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback); + rmesa->recheck_texgen[unit] = 0; + rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + } + + format = tObj->Image[tObj->BaseLevel]->Format; + if ( rmesa->state.texture.unit[unit].format != format || + rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) { + rmesa->state.texture.unit[unit].format = format; + rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode; + r200UpdateTextureEnv( ctx, unit ); + } + + return GL_TRUE; +} + + + +static GLboolean r200UpdateTextureUnit( GLcontext *ctx, int unit ) +{ + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + + if ( texUnit->_ReallyEnabled & (TEXTURE0_RECT) ) { + return (enable_tex_rect( ctx, unit ) && + update_tex_common( ctx, unit )); + } + else if ( texUnit->_ReallyEnabled & (TEXTURE0_1D|TEXTURE0_2D) ) { + return (enable_tex_2d( ctx, unit ) && + update_tex_common( ctx, unit )); + } + else if ( texUnit->_ReallyEnabled ) { + return GL_FALSE; + } + else { + disable_tex( ctx, unit ); + return GL_TRUE; + } +} + + +void r200UpdateTextureState( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLboolean ok; + GLuint dbg; + + ok = (r200UpdateTextureUnit( ctx, 0 ) && + r200UpdateTextureUnit( ctx, 1 )); + + FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok ); + + if (rmesa->TclFallback) + r200ChooseVertexState( ctx ); + + /* + * T0 hang workaround ------------- + */ +#if 1 + if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE && + (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) { + + R200_STATECHANGE(rmesa, ctx); + R200_STATECHANGE(rmesa, tex[1]); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE; + rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; + rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= 0x08000000; + } + else { + if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) && + (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) { + R200_STATECHANGE(rmesa, tex[1]); + rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000; + } + } +#endif + +#if 1 + /* + * Texture cache LRU hang workaround ------------- + */ + dbg = 0x0; + if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_0_ENABLE) && + ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & + 0x04) == 0))) + { + dbg |= 0x02; + } + + if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) && + ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & + 0x04) == 0))) + { + dbg |= 0x04; + } + + if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) { + R200_STATECHANGE( rmesa, tam ); + rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg; + if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg); + } +#endif +} + +/* + also tests for higher texunits: + + ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) && + ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)) || + ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) && + ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0))) + + ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) && + ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)) || + ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) && + ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0))) + +*/ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c new file mode 100644 index 000000000..5bcf46add --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c @@ -0,0 +1,1153 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c,v 1.3 2002/12/16 16:18:55 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "glheader.h" +#include "r200_context.h" +#include "r200_state.h" +#include "r200_ioctl.h" +#include "r200_tex.h" +#include "r200_tcl.h" +#include "r200_vtxfmt.h" + +#include "api_noop.h" +#include "api_arrayelt.h" +#include "context.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" +#include "enums.h" +#include "glapi.h" +#include "colormac.h" +#include "light.h" +#include "state.h" +#include "vtxfmt.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_array_api.h" + +struct r200_vb vb; + +static void r200FlushVertices( GLcontext *, GLuint ); + +static void count_func( const char *name, struct dynfn *l ) +{ + int i = 0; + struct dynfn *f; + foreach (f, l) i++; + if (i) fprintf(stderr, "%s: %d\n", name, i ); +} + +static void count_funcs( r200ContextPtr rmesa ) +{ + count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f ); + count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv ); + count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f ); + count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv ); + count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub ); + count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv ); + count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub ); + count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv ); + count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f ); + count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv ); + count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f ); + count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv ); + count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); + count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); + count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); + count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); + count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f ); + count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv ); + count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f ); + count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv ); + count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f ); + count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv ); + count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); + count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); +} + + +void r200_copy_to_current( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT); + assert(vb.context == ctx); + + if (rmesa->vb.vtxfmt_0 & R200_VTX_N0) { + ctx->Current.Normal[0] = vb.normalptr[0]; + ctx->Current.Normal[1] = vb.normalptr[1]; + ctx->Current.Normal[2] = vb.normalptr[2]; + } + + switch( VTX_COLOR(rmesa->vb.vtxfmt_0, 0) ) { + case R200_VTX_PK_RGBA: + ctx->Current.Color[0] = UBYTE_TO_FLOAT( vb.colorptr->red ); + ctx->Current.Color[1] = UBYTE_TO_FLOAT( vb.colorptr->green ); + ctx->Current.Color[2] = UBYTE_TO_FLOAT( vb.colorptr->blue ); + ctx->Current.Color[3] = UBYTE_TO_FLOAT( vb.colorptr->alpha ); + break; + + case R200_VTX_FP_RGB: + ctx->Current.Color[0] = vb.floatcolorptr[0]; + ctx->Current.Color[1] = vb.floatcolorptr[1]; + ctx->Current.Color[2] = vb.floatcolorptr[2]; + break; + + case R200_VTX_FP_RGBA: + ctx->Current.Color[0] = vb.floatcolorptr[0]; + ctx->Current.Color[1] = vb.floatcolorptr[1]; + ctx->Current.Color[2] = vb.floatcolorptr[2]; + ctx->Current.Color[3] = vb.floatcolorptr[3]; + break; + + default: + break; + } + + if (VTX_COLOR(rmesa->vb.vtxfmt_0, 1) == R200_VTX_PK_RGBA) { + ctx->Current.SecondaryColor[0] = UBYTE_TO_FLOAT( vb.specptr->red ); + ctx->Current.SecondaryColor[1] = UBYTE_TO_FLOAT( vb.specptr->green ); + ctx->Current.SecondaryColor[2] = UBYTE_TO_FLOAT( vb.specptr->blue ); + } + + if (rmesa->vb.vtxfmt_1 & (7 << R200_VTX_TEX0_COMP_CNT_SHIFT)) { + ctx->Current.Texcoord[0][0] = vb.texcoordptr[0][0]; + ctx->Current.Texcoord[0][1] = vb.texcoordptr[0][1]; + ctx->Current.Texcoord[0][2] = 0.0F; + ctx->Current.Texcoord[0][3] = 1.0F; + } + + if (rmesa->vb.vtxfmt_1 & (7 << R200_VTX_TEX1_COMP_CNT_SHIFT)) { + ctx->Current.Texcoord[1][0] = vb.texcoordptr[1][0]; + ctx->Current.Texcoord[1][1] = vb.texcoordptr[1][1]; + ctx->Current.Texcoord[1][2] = 0.0F; + ctx->Current.Texcoord[1][3] = 1.0F; + } + + ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; +} + +static GLboolean discreet_gl_prim[GL_POLYGON+1] = { + 1, /* 0 points */ + 1, /* 1 lines */ + 0, /* 2 line_strip */ + 0, /* 3 line_loop */ + 1, /* 4 tris */ + 0, /* 5 tri_fan */ + 0, /* 6 tri_strip */ + 1, /* 7 quads */ + 0, /* 8 quadstrip */ + 0, /* 9 poly */ +}; + +static void flush_prims( r200ContextPtr rmesa ) +{ + int i,j; + struct r200_dma_region tmp = rmesa->dma.current; + + tmp.buf->refcount++; + tmp.aos_size = vb.vertex_size; + tmp.aos_stride = vb.vertex_size; + tmp.aos_start = GET_START(&tmp); + + rmesa->dma.current.ptr = rmesa->dma.current.start += + (vb.initial_counter - vb.counter) * vb.vertex_size * 4; + + rmesa->tcl.vertex_format = rmesa->vb.vtxfmt_0; + rmesa->tcl.aos_components[0] = &tmp; + rmesa->tcl.nr_aos_components = 1; + rmesa->dma.flush = 0; + + /* Optimize the primitive list: + */ + if (rmesa->vb.nrprims > 1) { + for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) { + int pj = rmesa->vb.primlist[j].prim & 0xf; + int pi = rmesa->vb.primlist[i].prim & 0xf; + + if (pj == pi && discreet_gl_prim[pj] && + rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) { + rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end; + } + else { + j++; + if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i]; + } + } + rmesa->vb.nrprims = j+1; + } + + if (rmesa->vb.vtxfmt_0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || + rmesa->vb.vtxfmt_1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { + R200_STATECHANGE( rmesa, vtx ); + rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = rmesa->vb.vtxfmt_0; + rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = rmesa->vb.vtxfmt_1; + } + + + for (i = 0 ; i < rmesa->vb.nrprims; i++) { + if (R200_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i, + _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim & + PRIM_MODE_MASK ), + rmesa->vb.primlist[i].start, + rmesa->vb.primlist[i].end); + + if (rmesa->vb.primlist[i].start < rmesa->vb.primlist[i].end) + r200EmitPrimitive( vb.context, + rmesa->vb.primlist[i].start, + rmesa->vb.primlist[i].end, + rmesa->vb.primlist[i].prim ); + } + + rmesa->vb.nrprims = 0; + r200ReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ ); +} + + +static void start_prim( r200ContextPtr rmesa, GLuint mode ) +{ + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s %d\n", __FUNCTION__, vb.initial_counter - vb.counter); + + rmesa->vb.primlist[rmesa->vb.nrprims].start = vb.initial_counter - vb.counter; + rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode; +} + +static void note_last_prim( r200ContextPtr rmesa, GLuint flags ) +{ + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s %d\n", __FUNCTION__, vb.initial_counter - vb.counter); + + if (rmesa->vb.prim[0] != GL_POLYGON+1) { + rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags; + rmesa->vb.primlist[rmesa->vb.nrprims].end = vb.initial_counter - vb.counter; + + if (++(rmesa->vb.nrprims) == R200_MAX_PRIMS) + flush_prims( rmesa ); + } +} + + +static void copy_vertex( r200ContextPtr rmesa, GLuint n, GLfloat *dst ) +{ + GLuint i; + GLfloat *src = (GLfloat *)(rmesa->dma.current.address + + rmesa->dma.current.ptr + + (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) * + vb.vertex_size * 4); + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n); + + for (i = 0 ; i < vb.vertex_size; i++) { + dst[i] = src[i]; + } +} + +/* NOTE: This actually reads the copied vertices back from uncached + * memory. Could also use the counter/notify mechanism to populate + * tmp on the fly as vertices are generated. + */ +static GLuint copy_dma_verts( r200ContextPtr rmesa, GLfloat (*tmp)[15] ) +{ + GLuint ovf, i; + GLuint nr = (vb.initial_counter - vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start; + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr); + + switch( rmesa->vb.prim[0] ) + { + case GL_POINTS: + return 0; + case GL_LINES: + ovf = nr&1; + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + case GL_TRIANGLES: + ovf = nr%3; + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + case GL_QUADS: + ovf = nr&3; + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + case GL_LINE_STRIP: + if (nr == 0) + return 0; + copy_vertex( rmesa, nr-1, tmp[0] ); + return 1; + case GL_LINE_LOOP: + case GL_TRIANGLE_FAN: + case GL_POLYGON: + if (nr == 0) + return 0; + else if (nr == 1) { + copy_vertex( rmesa, 0, tmp[0] ); + return 1; + } else { + copy_vertex( rmesa, 0, tmp[0] ); + copy_vertex( rmesa, nr-1, tmp[1] ); + return 2; + } + case GL_TRIANGLE_STRIP: + ovf = MIN2( nr-1, 2 ); + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + case GL_QUAD_STRIP: + ovf = MIN2( nr-1, 2 ); + if (nr > 2) ovf += nr&1; + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + default: + assert(0); + return 0; + } +} + +static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) +{ + GLcontext *ctx = vb.context; + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) + fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); + + if (ctx->Driver.NeedFlush) + r200FlushVertices( ctx, ctx->Driver.NeedFlush ); + + if (ctx->NewState) + _mesa_update_state( ctx ); /* clear state so fell_back sticks */ + + _tnl_wakeup_exec( ctx ); + + assert( rmesa->dma.flush == 0 ); + rmesa->vb.fell_back = GL_TRUE; + rmesa->vb.installed = GL_FALSE; +/* vb.context = 0; */ +} + + +static void VFMT_FALLBACK( const char *caller ) +{ + GLcontext *ctx = vb.context; + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLfloat tmp[3][15]; + GLuint i, prim; + GLuint ind0 = rmesa->vb.vtxfmt_0; + GLuint ind1 = rmesa->vb.vtxfmt_1; + GLuint nrverts; + GLfloat alpha = 1.0; + + if (R200_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT)) + fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); + + if (rmesa->vb.prim[0] == GL_POLYGON+1) { + VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); + return; + } + + /* Copy vertices out of dma: + */ + nrverts = copy_dma_verts( rmesa, tmp ); + + /* Finish the prim at this point: + */ + note_last_prim( rmesa, 0 ); + flush_prims( rmesa ); + + /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl. + */ + prim = rmesa->vb.prim[0]; + ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; + _tnl_wakeup_exec( ctx ); + + assert(rmesa->dma.flush == 0); + rmesa->vb.fell_back = GL_TRUE; + rmesa->vb.installed = GL_FALSE; + vb.context = 0; + glBegin( prim ); + + if (rmesa->vb.installed_color_3f_sz == 4) + alpha = ctx->Current.Color[3]; + + /* Replay saved vertices + */ + for (i = 0 ; i < nrverts; i++) { + GLuint offset = 3; + if (ind0 & R200_VTX_N0) { + glNormal3fv( &tmp[i][offset] ); + offset += 3; + } + + if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { + glColor4ubv( (GLubyte *)&tmp[i][offset] ); + offset++; + } + else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { + glColor4fv( &tmp[i][offset] ); + offset+=4; + } + else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { + glColor3fv( &tmp[i][offset] ); + offset+=3; + } + + if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { + _glapi_Dispatch->SecondaryColor3ubvEXT( (GLubyte *)&tmp[i][offset] ); + offset++; + } + + if (ind1 & (7 << R200_VTX_TEX0_COMP_CNT_SHIFT)) { + glTexCoord2fv( &tmp[i][offset] ); + offset += 2; + } + + if (ind1 & (7 << R200_VTX_TEX1_COMP_CNT_SHIFT)) { + glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, &tmp[i][offset] ); + offset += 2; + } + + glVertex3fv( &tmp[i][0] ); + } + + /* Replay current vertex + */ + if (ind0 & R200_VTX_N0) + glNormal3fv( vb.normalptr ); + + if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) + glColor4ub( vb.colorptr->red, vb.colorptr->green, vb.colorptr->blue, vb.colorptr->alpha ); + else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) + glColor4fv( vb.floatcolorptr ); + else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { + if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) + glColor4f( vb.floatcolorptr[0], + vb.floatcolorptr[1], + vb.floatcolorptr[2], + alpha ); + else + glColor3fv( vb.floatcolorptr ); + } + + if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) + _glapi_Dispatch->SecondaryColor3ubEXT( vb.specptr->red, vb.specptr->green, vb.specptr->blue ); + + if (ind1 & (7 << R200_VTX_TEX0_COMP_CNT_SHIFT)) + glTexCoord2fv( vb.texcoordptr[0] ); + + if (ind1 & (7 << R200_VTX_TEX1_COMP_CNT_SHIFT)) + glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, vb.texcoordptr[1] ); +} + + + +static void wrap_buffer( void ) +{ + GLcontext *ctx = vb.context; + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLfloat tmp[3][15]; + GLuint i, nrverts; + + if (R200_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS)) + fprintf(stderr, "%s %d\n", __FUNCTION__, vb.initial_counter - vb.counter); + + /* Don't deal with parity. + */ + if ((((vb.initial_counter - vb.counter) - + rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) { + vb.counter++; + vb.initial_counter++; + return; + } + + /* Copy vertices out of dma: + */ + if (rmesa->vb.prim[0] == GL_POLYGON+1) + nrverts = 0; + else { + nrverts = copy_dma_verts( rmesa, tmp ); + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%d vertices to copy\n", nrverts); + + /* Finish the prim at this point: + */ + note_last_prim( rmesa, 0 ); + } + + /* Fire any buffered primitives + */ + flush_prims( rmesa ); + + /* Get new buffer + */ + r200RefillCurrentDmaRegion( rmesa ); + + /* Reset counter, dmaptr + */ + vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address); + vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / + (vb.vertex_size * 4); + vb.counter--; + vb.initial_counter = vb.counter; + vb.notify = wrap_buffer; + + rmesa->dma.flush = flush_prims; + + /* Restart wrapped primitive: + */ + if (rmesa->vb.prim[0] != GL_POLYGON+1) + start_prim( rmesa, rmesa->vb.prim[0] ); + + + /* Reemit saved vertices + */ + for (i = 0 ; i < nrverts; i++) { + if (R200_DEBUG & DEBUG_VERTS) { + int j; + fprintf(stderr, "re-emit vertex %d to %p\n", i, vb.dmaptr); + if (R200_DEBUG & DEBUG_VERBOSE) + for (j = 0 ; j < vb.vertex_size; j++) + fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]); + } + + memcpy( vb.dmaptr, tmp[i], vb.vertex_size * 4 ); + vb.dmaptr += vb.vertex_size; + vb.counter--; + } +} + + + +static GLboolean check_vtx_fmt( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint ind0 = R200_VTX_Z0; + GLuint ind1 = 0; + + if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag) + return GL_FALSE; + + if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) + ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); + + /* Make all this event-driven: + */ + if (ctx->Light.Enabled) { + ind0 |= R200_VTX_N0; + + /* TODO: make this data driven: If we receive only ubytes, send + * color as ubytes. Also check if converting (with free + * checking for overflow) is cheaper than sending floats + * directly. + */ + if (ctx->Light.ColorMaterialEnabled) { + if (1 || ctx->Color.AlphaEnabled) + ind0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; + else + ind0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT; + } + } + else { + /* TODO: make this data driven? + */ + ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { + ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT; + } + } + + if (ctx->Texture.Unit[0]._ReallyEnabled) { + if (ctx->Texture.Unit[0].TexGenEnabled) { + if (rmesa->TexGenNeedNormals[0]) { + ind0 |= R200_VTX_N0; + } + } else { + if (ctx->Current.Texcoord[0][2] != 0.0F || + ctx->Current.Texcoord[0][3] != 1.0) { + if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) + fprintf(stderr, "%s: rq0\n", __FUNCTION__); + return GL_FALSE; + } + ind1 |= 2 << R200_VTX_TEX0_COMP_CNT_SHIFT; + } + } + + if (ctx->Texture.Unit[1]._ReallyEnabled) { + if (ctx->Texture.Unit[1].TexGenEnabled) { + if (rmesa->TexGenNeedNormals[1]) { + ind0 |= R200_VTX_N0; + } + } else { + if (ctx->Current.Texcoord[1][2] != 0.0F || + ctx->Current.Texcoord[1][3] != 1.0) { + if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) + fprintf(stderr, "%s: rq1\n", __FUNCTION__); + return GL_FALSE; + } + ind1 |= 2 << R200_VTX_TEX1_COMP_CNT_SHIFT; + } + } + + if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) + fprintf(stderr, "%s: format: 0x%x, 0x%x\n", __FUNCTION__, ind0, ind1 ); + + R200_NEWPRIM(rmesa); + rmesa->vb.vtxfmt_0 = ind0; + rmesa->vb.vtxfmt_1 = ind1; + rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; + + vb.vertex_size = 3; + vb.normalptr = ctx->Current.Normal; + vb.colorptr = NULL; + vb.floatcolorptr = ctx->Current.Color; + vb.specptr = NULL; + vb.floatspecptr = ctx->Current.SecondaryColor; + vb.texcoordptr[0] = ctx->Current.Texcoord[0]; + vb.texcoordptr[1] = ctx->Current.Texcoord[1]; + + /* Run through and initialize the vertex components in the order + * the hardware understands: + */ + if (ind0 & R200_VTX_N0) { + vb.normalptr = &vb.vertex[vb.vertex_size].f; + vb.vertex_size += 3; + vb.normalptr[0] = ctx->Current.Normal[0]; + vb.normalptr[1] = ctx->Current.Normal[1]; + vb.normalptr[2] = ctx->Current.Normal[2]; + } + + if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { + vb.colorptr = &vb.vertex[vb.vertex_size].color; + vb.vertex_size += 1; + UNCLAMPED_FLOAT_TO_CHAN( vb.colorptr->red, ctx->Current.Color[0] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.colorptr->green, ctx->Current.Color[1] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.colorptr->blue, ctx->Current.Color[2] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.colorptr->alpha, ctx->Current.Color[3] ); + } + else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { + vb.floatcolorptr = &vb.vertex[vb.vertex_size].f; + vb.vertex_size += 4; + vb.floatcolorptr[0] = ctx->Current.Color[0]; + vb.floatcolorptr[1] = ctx->Current.Color[1]; + vb.floatcolorptr[2] = ctx->Current.Color[2]; + vb.floatcolorptr[3] = ctx->Current.Color[3]; + } + else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { + vb.floatcolorptr = &vb.vertex[vb.vertex_size].f; + vb.vertex_size += 3; + vb.floatcolorptr[0] = ctx->Current.Color[0]; + vb.floatcolorptr[1] = ctx->Current.Color[1]; + vb.floatcolorptr[2] = ctx->Current.Color[2]; + } + + if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { + vb.specptr = &vb.vertex[vb.vertex_size].color; + vb.vertex_size += 1; + UNCLAMPED_FLOAT_TO_CHAN( vb.specptr->red, ctx->Current.SecondaryColor[0] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.specptr->green, ctx->Current.SecondaryColor[1] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.specptr->blue, ctx->Current.SecondaryColor[2] ); + } + + + if (ind1 & (7 << R200_VTX_TEX0_COMP_CNT_SHIFT)) { + vb.texcoordptr[0] = &vb.vertex[vb.vertex_size].f; + vb.vertex_size += 2; + vb.texcoordptr[0][0] = ctx->Current.Texcoord[0][0]; + vb.texcoordptr[0][1] = ctx->Current.Texcoord[0][1]; + } + + if (ind1 & (7 << R200_VTX_TEX1_COMP_CNT_SHIFT)) { + vb.texcoordptr[1] = &vb.vertex[vb.vertex_size].f; + vb.vertex_size += 2; + vb.texcoordptr[1][0] = ctx->Current.Texcoord[1][0]; + vb.texcoordptr[1][1] = ctx->Current.Texcoord[1][1]; + } + + if (rmesa->vb.installed_vertex_format != rmesa->vb.vtxfmt_0) { + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "reinstall on vertex_format change\n"); + _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); + rmesa->vb.installed_vertex_format = rmesa->vb.vtxfmt_0; + } + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s -- success\n", __FUNCTION__); + + return GL_TRUE; +} + + +void r200VtxfmtInvalidate( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + rmesa->vb.recheck = GL_TRUE; + rmesa->vb.fell_back = GL_FALSE; +} + + +static void r200NewList( GLcontext *ctx, GLuint list, GLenum mode ) +{ + VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); +} + + +static void r200VtxfmtValidate( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (ctx->Driver.NeedFlush) + ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); + + rmesa->vb.recheck = GL_FALSE; + + if (check_vtx_fmt( ctx )) { + if (!rmesa->vb.installed) { + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "reinstall (new install)\n"); + + _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); + ctx->Driver.FlushVertices = r200FlushVertices; + ctx->Driver.NewList = r200NewList; + rmesa->vb.installed = GL_TRUE; + vb.context = ctx; + } + else if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s: already installed", __FUNCTION__); + } + else { + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s: failed\n", __FUNCTION__); + + if (rmesa->vb.installed) { + if (rmesa->dma.flush) + rmesa->dma.flush( rmesa ); + _tnl_wakeup_exec( ctx ); + rmesa->vb.installed = GL_FALSE; + vb.context = 0; + } + } +} + + + +/* Materials: + */ +static void r200_Materialfv( GLenum face, GLenum pname, + const GLfloat *params ) +{ + GLcontext *ctx = vb.context; + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->vb.prim[0] != GL_POLYGON+1) { + VFMT_FALLBACK( __FUNCTION__ ); + glMaterialfv( face, pname, params ); + return; + } + _mesa_noop_Materialfv( face, pname, params ); + r200UpdateMaterial( vb.context ); +} + + +/* Begin/End + */ +static void r200_Begin( GLenum mode ) +{ + GLcontext *ctx = vb.context; + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s( %s )\n", __FUNCTION__, + _mesa_lookup_enum_by_nr( mode )); + + if (mode > GL_POLYGON) { + _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); + return; + } + + if (rmesa->vb.prim[0] != GL_POLYGON+1) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); + return; + } + + if (ctx->NewState) + _mesa_update_state( ctx ); + + if (rmesa->NewGLState) + r200ValidateState( ctx ); + + if (rmesa->vb.recheck) + r200VtxfmtValidate( ctx ); + + if (!rmesa->vb.installed) { + glBegin( mode ); + return; + } + + + if (rmesa->dma.flush && vb.counter < 12) { + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__); + flush_prims( rmesa ); + } + + /* Need to arrange to save vertices here? Or always copy from dma (yuk)? + */ + if (!rmesa->dma.flush) { + if (rmesa->dma.current.ptr + 12*vb.vertex_size*4 > + rmesa->dma.current.end) { + R200_NEWPRIM( rmesa ); + r200RefillCurrentDmaRegion( rmesa ); + } + + vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr); + vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / + (vb.vertex_size * 4); + vb.counter--; + vb.initial_counter = vb.counter; + vb.notify = wrap_buffer; + rmesa->dma.flush = flush_prims; + vb.context->Driver.NeedFlush |= FLUSH_STORED_VERTICES; + } + + + rmesa->vb.prim[0] = mode; + start_prim( rmesa, mode | PRIM_BEGIN ); +} + + + +static void r200_End( void ) +{ + GLcontext *ctx = vb.context; + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->vb.prim[0] == GL_POLYGON+1) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); + return; + } + + note_last_prim( rmesa, PRIM_END ); + rmesa->vb.prim[0] = GL_POLYGON+1; +} + + +/* Fallback on difficult entrypoints: + */ +#define PRE_LOOPBACK( FUNC ) \ +do { \ + if (R200_DEBUG & DEBUG_VFMT) \ + fprintf(stderr, "%s\n", __FUNCTION__); \ + VFMT_FALLBACK( __FUNCTION__ ); \ +} while (0) +#define TAG(x) r200_fallback_##x +#include "vtxfmt_tmp.h" + + + +static GLboolean r200NotifyBegin( GLcontext *ctx, GLenum p ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(!rmesa->vb.installed); + + if (ctx->NewState) + _mesa_update_state( ctx ); + + if (rmesa->NewGLState) + r200ValidateState( ctx ); + + if (ctx->Driver.NeedFlush) + ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); + + if (rmesa->vb.recheck) + r200VtxfmtValidate( ctx ); + + if (!rmesa->vb.installed) { + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s -- failed\n", __FUNCTION__); + return GL_FALSE; + } + + r200_Begin( p ); + return GL_TRUE; +} + +static void r200FlushVertices( GLcontext *ctx, GLuint flags ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(rmesa->vb.installed); + assert(vb.context == ctx); + + if (flags & FLUSH_UPDATE_CURRENT) { + r200_copy_to_current( ctx ); + if (R200_DEBUG & DEBUG_VFMT) + fprintf(stderr, "reinstall on update_current\n"); + _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); + ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; + } + + if (flags & FLUSH_STORED_VERTICES) { + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + assert (rmesa->dma.flush == 0 || + rmesa->dma.flush == flush_prims); + if (rmesa->dma.flush == flush_prims) + flush_prims( R200_CONTEXT( ctx ) ); + ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; + } +} + + + +/* At this point, don't expect very many versions of each function to + * be generated, so not concerned about freeing them? + */ + + +void r200VtxfmtInit( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + GLvertexformat *vfmt = &(rmesa->vb.vtxfmt); + + MEMSET( vfmt, 0, sizeof(GLvertexformat) ); + + /* Hook in chooser functions for codegen, etc: + */ + r200VtxfmtInitChoosers( vfmt ); + + /* Handled fully in supported states, but no codegen: + */ + vfmt->Materialfv = r200_Materialfv; + vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ + vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */ + vfmt->Begin = r200_Begin; + vfmt->End = r200_End; + + /* Fallback for performance reasons: (Fix with cva/elt path here and + * dmatmp2.h style primitive-merging) + * + * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow + * a driver-hook. + */ + vfmt->DrawArrays = r200_fallback_DrawArrays; + vfmt->DrawElements = r200_fallback_DrawElements; + vfmt->DrawRangeElements = r200_fallback_DrawRangeElements; + + + /* Not active in supported states; just keep ctx->Current uptodate: + */ + vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT; + vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT; + vfmt->EdgeFlag = _mesa_noop_EdgeFlag; + vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv; + vfmt->Indexi = _mesa_noop_Indexi; + vfmt->Indexiv = _mesa_noop_Indexiv; + + + /* Active but unsupported -- fallback if we receive these: + */ + vfmt->CallList = r200_fallback_CallList; + vfmt->EvalCoord1f = r200_fallback_EvalCoord1f; + vfmt->EvalCoord1fv = r200_fallback_EvalCoord1fv; + vfmt->EvalCoord2f = r200_fallback_EvalCoord2f; + vfmt->EvalCoord2fv = r200_fallback_EvalCoord2fv; + vfmt->EvalMesh1 = r200_fallback_EvalMesh1; + vfmt->EvalMesh2 = r200_fallback_EvalMesh2; + vfmt->EvalPoint1 = r200_fallback_EvalPoint1; + vfmt->EvalPoint2 = r200_fallback_EvalPoint2; + vfmt->TexCoord3f = r200_fallback_TexCoord3f; + vfmt->TexCoord3fv = r200_fallback_TexCoord3fv; + vfmt->TexCoord4f = r200_fallback_TexCoord4f; + vfmt->TexCoord4fv = r200_fallback_TexCoord4fv; + vfmt->MultiTexCoord3fARB = r200_fallback_MultiTexCoord3fARB; + vfmt->MultiTexCoord3fvARB = r200_fallback_MultiTexCoord3fvARB; + vfmt->MultiTexCoord4fARB = r200_fallback_MultiTexCoord4fARB; + vfmt->MultiTexCoord4fvARB = r200_fallback_MultiTexCoord4fvARB; + vfmt->Vertex4f = r200_fallback_Vertex4f; + vfmt->Vertex4fv = r200_fallback_Vertex4fv; + + (void)r200_fallback_vtxfmt; + + TNL_CONTEXT(ctx)->Driver.NotifyBegin = r200NotifyBegin; + + vb.context = ctx; + rmesa->vb.enabled = 1; + rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; + rmesa->vb.primflags = 0; + + make_empty_list( &rmesa->vb.dfn_cache.Vertex2f ); + make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv ); + make_empty_list( &rmesa->vb.dfn_cache.Vertex3f ); + make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv ); + make_empty_list( &rmesa->vb.dfn_cache.Color4ub ); + make_empty_list( &rmesa->vb.dfn_cache.Color4ubv ); + make_empty_list( &rmesa->vb.dfn_cache.Color3ub ); + make_empty_list( &rmesa->vb.dfn_cache.Color3ubv ); + make_empty_list( &rmesa->vb.dfn_cache.Color4f ); + make_empty_list( &rmesa->vb.dfn_cache.Color4fv ); + make_empty_list( &rmesa->vb.dfn_cache.Color3f ); + make_empty_list( &rmesa->vb.dfn_cache.Color3fv ); + make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); + make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); + make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); + make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); + make_empty_list( &rmesa->vb.dfn_cache.Normal3f ); + make_empty_list( &rmesa->vb.dfn_cache.Normal3fv ); + make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f ); + make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv ); + make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f ); + make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv ); + make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); + make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); + + r200InitCodegen( &rmesa->vb.codegen ); +} + +static void free_funcs( struct dynfn *l ) +{ + struct dynfn *f, *tmp; + foreach_s (f, tmp, l) { + remove_from_list( f ); + ALIGN_FREE( f->code ); + FREE( f ); + } +} + +void r200VtxfmtUnbindContext( GLcontext *ctx ) +{ + if (R200_CONTEXT(ctx)->vb.installed) { + assert(vb.context == ctx); + VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); + } + + TNL_CONTEXT(ctx)->Driver.NotifyBegin = 0; +} + + +void r200VtxfmtMakeCurrent( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + +#if defined(THREADS) + static GLboolean ThreadSafe = GL_FALSE; /* In thread-safe mode? */ + if (!ThreadSafe) { + static unsigned long knownID; + static GLboolean firstCall = GL_TRUE; + if (firstCall) { + knownID = _glthread_GetID(); + firstCall = GL_FALSE; + } + else if (knownID != _glthread_GetID()) { + ThreadSafe = GL_TRUE; + + if (R200_DEBUG & (DEBUG_DRI|DEBUG_VFMT)) + fprintf(stderr, "**** Multithread situation!\n"); + } + } + if (ThreadSafe) + return; +#endif + + if (rmesa->vb.enabled) { + TNL_CONTEXT(ctx)->Driver.NotifyBegin = r200NotifyBegin; + } +} + + +void r200VtxfmtDestroy( GLcontext *ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + + count_funcs( rmesa ); + free_funcs( &rmesa->vb.dfn_cache.Vertex2f ); + free_funcs( &rmesa->vb.dfn_cache.Vertex2fv ); + free_funcs( &rmesa->vb.dfn_cache.Vertex3f ); + free_funcs( &rmesa->vb.dfn_cache.Vertex3fv ); + free_funcs( &rmesa->vb.dfn_cache.Color4ub ); + free_funcs( &rmesa->vb.dfn_cache.Color4ubv ); + free_funcs( &rmesa->vb.dfn_cache.Color3ub ); + free_funcs( &rmesa->vb.dfn_cache.Color3ubv ); + free_funcs( &rmesa->vb.dfn_cache.Color4f ); + free_funcs( &rmesa->vb.dfn_cache.Color4fv ); + free_funcs( &rmesa->vb.dfn_cache.Color3f ); + free_funcs( &rmesa->vb.dfn_cache.Color3fv ); + free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); + free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); + free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); + free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); + free_funcs( &rmesa->vb.dfn_cache.Normal3f ); + free_funcs( &rmesa->vb.dfn_cache.Normal3fv ); + free_funcs( &rmesa->vb.dfn_cache.TexCoord2f ); + free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv ); + free_funcs( &rmesa->vb.dfn_cache.TexCoord1f ); + free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv ); + free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); + free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); +} + diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h new file mode 100644 index 000000000..42982b519 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h @@ -0,0 +1,128 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __R200_VTXFMT_H__ +#define __R200_VTXFMT_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "r200_context.h" + + + +extern struct r200_vb vb; + + +extern void r200VtxfmtUpdate( GLcontext *ctx ); +extern void r200VtxfmtInit( GLcontext *ctx ); +extern void r200VtxfmtInvalidate( GLcontext *ctx ); +extern void r200VtxfmtDestroy( GLcontext *ctx ); +extern void r200VtxfmtInitChoosers( GLvertexformat *vfmt ); + +extern void r200VtxfmtMakeCurrent( GLcontext *ctx ); +extern void r200VtxfmtUnbindContext( GLcontext *ctx ); + +extern void r200_copy_to_current( GLcontext *ctx ); + +#define DFN( FUNC, CACHE) \ +do { \ + char *start = (char *)&FUNC; \ + char *end = (char *)&FUNC##_end; \ + insert_at_head( &CACHE, dfn ); \ + dfn->key[0] = key[0]; \ + dfn->key[1] = key[1]; \ + dfn->code = ALIGN_MALLOC( end - start, 16 ); \ + memcpy (dfn->code, start, end - start); \ +} \ +while ( 0 ) + +#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \ +do { \ + int *icode = (int *)(CODE+OFFSET); \ + assert (*icode == CHECKVAL); \ + *icode = (int)NEWVAL; \ +} while (0) + + +/* Useful for figuring out the offsets: + */ +#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ +do { \ + while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ + fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__, \ + __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL)); \ + *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ + OFFSET += 4; \ +} while (0) + +/* + */ +void r200InitCodegen( struct dfn_generators *gen ); +void r200InitX86Codegen( struct dfn_generators *gen ); +void r200InitSSECodegen( struct dfn_generators *gen ); + + + +/* Defined in r200_vtxfmt_x86.c + */ +struct dynfn *r200_makeX86Vertex2f( GLcontext *, const int * ); +struct dynfn *r200_makeX86Vertex2fv( GLcontext *, const int * ); +struct dynfn *r200_makeX86Vertex3f( GLcontext *, const int * ); +struct dynfn *r200_makeX86Vertex3fv( GLcontext *, const int * ); +struct dynfn *r200_makeX86Color4ub( GLcontext *, const int * ); +struct dynfn *r200_makeX86Color4ubv( GLcontext *, const int * ); +struct dynfn *r200_makeX86Color3ub( GLcontext *, const int * ); +struct dynfn *r200_makeX86Color3ubv( GLcontext *, const int * ); +struct dynfn *r200_makeX86Color4f( GLcontext *, const int * ); +struct dynfn *r200_makeX86Color4fv( GLcontext *, const int * ); +struct dynfn *r200_makeX86Color3f( GLcontext *, const int * ); +struct dynfn *r200_makeX86Color3fv( GLcontext *, const int * ); +struct dynfn *r200_makeX86SecondaryColor3ubEXT( GLcontext *, const int * ); +struct dynfn *r200_makeX86SecondaryColor3ubvEXT( GLcontext *, const int * ); +struct dynfn *r200_makeX86SecondaryColor3fEXT( GLcontext *, const int * ); +struct dynfn *r200_makeX86SecondaryColor3fvEXT( GLcontext *, const int * ); +struct dynfn *r200_makeX86Normal3f( GLcontext *, const int * ); +struct dynfn *r200_makeX86Normal3fv( GLcontext *, const int * ); +struct dynfn *r200_makeX86TexCoord2f( GLcontext *, const int * ); +struct dynfn *r200_makeX86TexCoord2fv( GLcontext *, const int * ); +struct dynfn *r200_makeX86TexCoord1f( GLcontext *, const int * ); +struct dynfn *r200_makeX86TexCoord1fv( GLcontext *, const int * ); +struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *, const int * ); +struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *, const int * ); +struct dynfn *r200_makeX86MultiTexCoord1fARB( GLcontext *, const int * ); +struct dynfn *r200_makeX86MultiTexCoord1fvARB( GLcontext *, const int * ); + + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c new file mode 100644 index 000000000..c9ae7003e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c @@ -0,0 +1,795 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "mtypes.h" +#include "colormac.h" +#include "simple_list.h" +#include "api_noop.h" +#include "vtxfmt.h" + +#include "r200_vtxfmt.h" + +/* Fallback versions of all the entrypoints for situations where + * codegen isn't available. This is still a lot faster than the + * vb/pipeline implementation in Mesa. + */ +static void r200_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) +{ + int i; + + *vb.dmaptr++ = *(int *)&x; + *vb.dmaptr++ = *(int *)&y; + *vb.dmaptr++ = *(int *)&z; + + for (i = 3; i < vb.vertex_size; i++) + *vb.dmaptr++ = vb.vertex[i].i; + + if (--vb.counter == 0) + vb.notify(); +} + + +static void r200_Vertex3fv( const GLfloat *v ) +{ + int i; + + *vb.dmaptr++ = *(int *)&v[0]; + *vb.dmaptr++ = *(int *)&v[1]; + *vb.dmaptr++ = *(int *)&v[2]; + + for (i = 3; i < vb.vertex_size; i++) + *vb.dmaptr++ = vb.vertex[i].i; + + if (--vb.counter == 0) + vb.notify(); +} + + +static void r200_Vertex2f( GLfloat x, GLfloat y ) +{ + int i; + + *vb.dmaptr++ = *(int *)&x; + *vb.dmaptr++ = *(int *)&y; + *vb.dmaptr++ = 0; + + for (i = 3; i < vb.vertex_size; i++) + *vb.dmaptr++ = vb.vertex[i].i; + + if (--vb.counter == 0) + vb.notify(); +} + + +static void r200_Vertex2fv( const GLfloat *v ) +{ + int i; + + *vb.dmaptr++ = *(int *)&v[0]; + *vb.dmaptr++ = *(int *)&v[1]; + *vb.dmaptr++ = 0; + + for (i = 3; i < vb.vertex_size; i++) + *vb.dmaptr++ = vb.vertex[i].i; + + if (--vb.counter == 0) + vb.notify(); +} + + + +/* Color for ubyte (packed) color formats: + */ +static void r200_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b ) +{ + r200_color_t *dest = vb.colorptr; + dest->red = r; + dest->green = g; + dest->blue = b; + dest->alpha = 0xff; +} + +static void r200_Color3ubv_ub( const GLubyte *v ) +{ + r200_color_t *dest = vb.colorptr; + dest->red = v[0]; + dest->green = v[1]; + dest->blue = v[2]; + dest->alpha = 0xff; +} + +static void r200_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + r200_color_t *dest = vb.colorptr; + dest->red = r; + dest->green = g; + dest->blue = b; + dest->alpha = a; +} + +static void r200_Color4ubv_ub( const GLubyte *v ) +{ + *(GLuint *)vb.colorptr = LE32_TO_CPU(*(GLuint *)v); +} + + +static void r200_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) +{ + r200_color_t *dest = vb.colorptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); + dest->alpha = 255; +} + +static void r200_Color3fv_ub( const GLfloat *v ) +{ + r200_color_t *dest = vb.colorptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); + dest->alpha = 255; +} + +static void r200_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) +{ + r200_color_t *dest = vb.colorptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); +} + +static void r200_Color4fv_ub( const GLfloat *v ) +{ + r200_color_t *dest = vb.colorptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); +} + + +/* Color for float color+alpha formats: + */ +static void r200_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); + dest[3] = 1.0; +} + +static void r200_Color3ubv_4f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); + dest[3] = 1.0; +} + +static void r200_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); + dest[3] = UBYTE_TO_FLOAT(a); +} + +static void r200_Color4ubv_4f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); + dest[3] = UBYTE_TO_FLOAT(v[3]); +} + + +static void r200_Color3f_4f( GLfloat r, GLfloat g, GLfloat b ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; + dest[3] = 1.0; +} + +static void r200_Color3fv_4f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; + dest[3] = 1.0; +} + +static void r200_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; + dest[3] = a; +} + +static void r200_Color4fv_4f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; + dest[3] = v[3]; +} + + +/* Color for float color formats: + */ +static void r200_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); +} + +static void r200_Color3ubv_3f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); +} + +static void r200_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); + vb.context->Current.Color[3] = UBYTE_TO_FLOAT(a); +} + +static void r200_Color4ubv_3f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); + vb.context->Current.Color[3] = UBYTE_TO_FLOAT(v[3]); +} + + +static void r200_Color3f_3f( GLfloat r, GLfloat g, GLfloat b ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; +} + +static void r200_Color3fv_3f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; +} + +static void r200_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; + vb.context->Current.Color[3] = a; +} + +static void r200_Color4fv_3f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; + vb.context->Current.Color[3] = v[3]; +} + + +/* Secondary Color: + */ +static void r200_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b ) +{ + r200_color_t *dest = vb.specptr; + dest->red = r; + dest->green = g; + dest->blue = b; + dest->alpha = 0xff; +} + +static void r200_SecondaryColor3ubvEXT_ub( const GLubyte *v ) +{ + r200_color_t *dest = vb.specptr; + dest->red = v[0]; + dest->green = v[1]; + dest->blue = v[2]; + dest->alpha = 0xff; +} + +static void r200_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) +{ + r200_color_t *dest = vb.specptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); + dest->alpha = 255; +} + +static void r200_SecondaryColor3fvEXT_ub( const GLfloat *v ) +{ + r200_color_t *dest = vb.specptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); + dest->alpha = 255; +} + +static void r200_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b ) +{ + GLfloat *dest = vb.floatspecptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); + dest[3] = 1.0; +} + +static void r200_SecondaryColor3ubvEXT_3f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatspecptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); + dest[3] = 1.0; +} + +static void r200_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b ) +{ + GLfloat *dest = vb.floatspecptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; + dest[3] = 1.0; +} + +static void r200_SecondaryColor3fvEXT_3f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatspecptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; + dest[3] = 1.0; +} + + + +/* Normal + */ +static void r200_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 ) +{ + GLfloat *dest = vb.normalptr; + dest[0] = n0; + dest[1] = n1; + dest[2] = n2; +} + +static void r200_Normal3fv( const GLfloat *v ) +{ + GLfloat *dest = vb.normalptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; +} + + +/* TexCoord + */ +static void r200_TexCoord1f( GLfloat s ) +{ + GLfloat *dest = vb.texcoordptr[0]; + dest[0] = s; + dest[1] = 0; +} + +static void r200_TexCoord1fv( const GLfloat *v ) +{ + GLfloat *dest = vb.texcoordptr[0]; + dest[0] = v[0]; + dest[1] = 0; +} + +static void r200_TexCoord2f( GLfloat s, GLfloat t ) +{ + GLfloat *dest = vb.texcoordptr[0]; + dest[0] = s; + dest[1] = t; +} + +static void r200_TexCoord2fv( const GLfloat *v ) +{ + GLfloat *dest = vb.texcoordptr[0]; + dest[0] = v[0]; + dest[1] = v[1]; +} + + +/* MultiTexcoord + */ +static void r200_MultiTexCoord1fARB( GLenum target, GLfloat s ) +{ + GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + dest[0] = s; + dest[1] = 0; +} + +static void r200_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) +{ + GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + dest[0] = v[0]; + dest[1] = 0; +} + +static void r200_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) +{ + GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + dest[0] = s; + dest[1] = t; +} + +static void r200_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) +{ + GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + dest[0] = v[0]; + dest[1] = v[1]; +} + +static struct dynfn *lookup( struct dynfn *l, const int *key ) +{ + struct dynfn *f; + + foreach( f, l ) { + if (f->key[0] == key[0] && f->key[1] == key[1]) + return f; + } + + return 0; +} + +/* Can't use the loopback template for this: + */ + +#define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \ +static void choose_##FN ARGS1 \ +{ \ + r200ContextPtr rmesa = R200_CONTEXT(vb.context); \ + int key[2]; \ + struct dynfn *dfn; \ + \ + key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ + key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ + \ + dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ + if (dfn == 0) \ + dfn = rmesa->vb.codegen.FN( vb.context, key ); \ + else if (R200_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \ + \ + if (dfn) \ + vb.context->Exec->FN = (FNTYPE)(dfn->code); \ + else { \ + if (R200_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ + vb.context->Exec->FN = r200_##FN; \ + } \ + \ + vb.context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ + vb.context->Exec->FN ARGS2; \ +} + + + +/* For the _3f case, only allow one color function to be hooked in at + * a time. Eventually, use a similar mechanism to allow selecting the + * color component of the vertex format based on client behaviour. + * + * Note: Perform these actions even if there is a codegen or cached + * codegen version of the chosen function. + */ +#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 ) \ +static void choose_##FN ARGS1 \ +{ \ + GLcontext *ctx = vb.context; \ + r200ContextPtr rmesa = R200_CONTEXT(vb.context); \ + int key[2]; \ + struct dynfn *dfn; \ + \ + key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ + key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ + \ + if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) { \ + ctx->Exec->FN = r200_##FN##_ub; \ + } \ + else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) { \ + \ + if (rmesa->vb.installed_color_3f_sz != NR) { \ + rmesa->vb.installed_color_3f_sz = NR; \ + if (NR == 3) ctx->Current.Color[3] = 1.0; \ + if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \ + r200_copy_to_current( ctx ); \ + _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \ + ctx->Exec->FN ARGS2; \ + return; \ + } \ + } \ + \ + ctx->Exec->FN = r200_##FN##_3f; \ + } \ + else { \ + ctx->Exec->FN = r200_##FN##_4f; \ + } \ + \ + \ + dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ + if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \ + \ + if (dfn) { \ + if (R200_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \ + ctx->Exec->FN = (FNTYPE)dfn->code; \ + } \ + else if (R200_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \ + \ + ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ + ctx->Exec->FN ARGS2; \ +} + + + +/* Right now there are both _ub and _3f versions of the secondary color + * functions. Currently, we only set-up the hardware to use the _ub versions. + * The _3f versions are needed for the cases where secondary color isn't used + * in the vertex format, but it still needs to be stored in the context + * state vector. + */ +#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \ +static void choose_##FN ARGS1 \ +{ \ + r200ContextPtr rmesa = R200_CONTEXT(vb.context); \ + int key[2]; \ + struct dynfn *dfn; \ + \ + key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ + key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ + \ + dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ + if (dfn == 0) \ + dfn = rmesa->vb.codegen.FN( vb.context, key ); \ + else if (R200_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \ + \ + if (dfn) \ + vb.context->Exec->FN = (FNTYPE)(dfn->code); \ + else { \ + if (R200_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ + vb.context->Exec->FN = (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \ + ? r200_##FN##_ub : r200_##FN##_3f; \ + } \ + \ + vb.context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ + vb.context->Exec->FN ARGS2; \ +} + + + + + +/* VTXFMT_0 + */ +#define MASK_XYZW (R200_VTX_W0|R200_VTX_Z0) +#define MASK_NORM (MASK_XYZW|R200_VTX_N0) +#define MASK_COLOR (MASK_NORM |(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_0_SHIFT)) +#define MASK_SPEC (MASK_COLOR|(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_1_SHIFT)) + +/* VTXFMT_1 + */ +#define MASK_ST0 (0x7 << R200_VTX_TEX0_COMP_CNT_SHIFT) + + + +typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat ); +typedef void (*p3f)( GLfloat, GLfloat, GLfloat ); +typedef void (*p2f)( GLfloat, GLfloat ); +typedef void (*p1f)( GLfloat ); +typedef void (*pe2f)( GLenum, GLfloat, GLfloat ); +typedef void (*pe1f)( GLenum, GLfloat ); +typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte ); +typedef void (*p3ub)( GLubyte, GLubyte, GLubyte ); +typedef void (*pfv)( const GLfloat * ); +typedef void (*pefv)( GLenum, const GLfloat * ); +typedef void (*pubv)( const GLubyte * ); + + +CHOOSE(Normal3f, p3f, MASK_NORM, 0, + (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) +CHOOSE(Normal3fv, pfv, MASK_NORM, 0, + (const GLfloat *v), (v)) + +CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, 0, + (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d)) +CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, 0, + (const GLubyte *v), (v)) +CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, 0, + (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) +CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, 0, + (const GLubyte *v), (v)) + +CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, 0, + (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d)) +CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, 0, + (const GLfloat *v), (v)) +CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, 0, + (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) +CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, 0, + (const GLfloat *v), (v)) + + +CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, 0, + (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) +CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, 0, + (const GLubyte *v), (v)) +CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, 0, + (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) +CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, 0, + (const GLfloat *v), (v)) + +CHOOSE(TexCoord2f, p2f, ~0, MASK_ST0, + (GLfloat a,GLfloat b), (a,b)) +CHOOSE(TexCoord2fv, pfv, ~0, MASK_ST0, + (const GLfloat *v), (v)) +CHOOSE(TexCoord1f, p1f, ~0, MASK_ST0, + (GLfloat a), (a)) +CHOOSE(TexCoord1fv, pfv, ~0, MASK_ST0, + (const GLfloat *v), (v)) + +CHOOSE(MultiTexCoord2fARB, pe2f, ~0, ~0, + (GLenum u,GLfloat a,GLfloat b), (u,a,b)) +CHOOSE(MultiTexCoord2fvARB, pefv, ~0, ~0, + (GLenum u,const GLfloat *v), (u,v)) +CHOOSE(MultiTexCoord1fARB, pe1f, ~0, ~0, + (GLenum u,GLfloat a), (u,a)) +CHOOSE(MultiTexCoord1fvARB, pefv, ~0, ~0, + (GLenum u,const GLfloat *v), (u,v)) + +CHOOSE(Vertex3f, p3f, ~0, ~0, + (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) +CHOOSE(Vertex3fv, pfv, ~0, ~0, + (const GLfloat *v), (v)) +CHOOSE(Vertex2f, p2f, ~0, ~0, + (GLfloat a,GLfloat b), (a,b)) +CHOOSE(Vertex2fv, pfv, ~0, ~0, + (const GLfloat *v), (v)) + + + + + +void r200VtxfmtInitChoosers( GLvertexformat *vfmt ) +{ + vfmt->Color3f = choose_Color3f; + vfmt->Color3fv = choose_Color3fv; + vfmt->Color3ub = choose_Color3ub; + vfmt->Color3ubv = choose_Color3ubv; + vfmt->Color4f = choose_Color4f; + vfmt->Color4fv = choose_Color4fv; + vfmt->Color4ub = choose_Color4ub; + vfmt->Color4ubv = choose_Color4ubv; + vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT; + vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; + vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; + vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; + vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; + vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; + vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; + vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; + vfmt->Normal3f = choose_Normal3f; + vfmt->Normal3fv = choose_Normal3fv; + vfmt->TexCoord1f = choose_TexCoord1f; + vfmt->TexCoord1fv = choose_TexCoord1fv; + vfmt->TexCoord2f = choose_TexCoord2f; + vfmt->TexCoord2fv = choose_TexCoord2fv; + vfmt->Vertex2f = choose_Vertex2f; + vfmt->Vertex2fv = choose_Vertex2fv; + vfmt->Vertex3f = choose_Vertex3f; + vfmt->Vertex3fv = choose_Vertex3fv; +} + + +static struct dynfn *codegen_noop( GLcontext *ctx, const int *key ) +{ + (void) ctx; (void) key; + return 0; +} + +void r200InitCodegen( struct dfn_generators *gen ) +{ + gen->Vertex3f = codegen_noop; + gen->Vertex3fv = codegen_noop; + gen->Color4ub = codegen_noop; + gen->Color4ubv = codegen_noop; + gen->Normal3f = codegen_noop; + gen->Normal3fv = codegen_noop; + gen->TexCoord2f = codegen_noop; + gen->TexCoord2fv = codegen_noop; + gen->MultiTexCoord2fARB = codegen_noop; + gen->MultiTexCoord2fvARB = codegen_noop; + gen->Vertex2f = codegen_noop; + gen->Vertex2fv = codegen_noop; + gen->Color3ub = codegen_noop; + gen->Color3ubv = codegen_noop; + gen->Color4f = codegen_noop; + gen->Color4fv = codegen_noop; + gen->Color3f = codegen_noop; + gen->Color3fv = codegen_noop; + gen->SecondaryColor3fEXT = codegen_noop; + gen->SecondaryColor3fvEXT = codegen_noop; + gen->SecondaryColor3ubEXT = codegen_noop; + gen->SecondaryColor3ubvEXT = codegen_noop; + gen->TexCoord1f = codegen_noop; + gen->TexCoord1fv = codegen_noop; + gen->MultiTexCoord1fARB = codegen_noop; + gen->MultiTexCoord1fvARB = codegen_noop; + + if (!getenv("R200_NO_CODEGEN")) { +#if defined(USE_X86_ASM) + r200InitX86Codegen( gen ); +#endif + +#if defined(USE_SSE_ASM) + r200InitSSECodegen( gen ); +#endif + } +} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c new file mode 100644 index 000000000..667647235 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c @@ -0,0 +1,96 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include <stdio.h> +#include <assert.h> +#include "mem.h" +#include "simple_list.h" +#include "r200_vtxfmt.h" + +#if defined(USE_SSE_ASM) + +/* Build specialized versions of the immediate calls on the fly for + * the current state. ???P4 SSE2 versions??? + */ + + +static struct dynfn *makeSSENormal3fv( GLcontext *ctx, const int *key ) +{ + /* Requires P4 (sse2?) + */ + static unsigned char temp[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $0x12345678,%edx */ + 0xf3, 0x0f, 0x7e, 0x00, /* movq (%eax),%xmm0 */ + 0x66, 0x0f, 0x6e, 0x48, 0x08, /* movd 0x8(%eax),%xmm1 */ + 0x66, 0x0f, 0xd6, 0x42, 0x0c, /* movq %xmm0,0xc(%edx) */ + 0x66, 0x0f, 0x7e, 0x4a, 0x14, /* movd %xmm1,0x14(%edx) */ + 0xc3, /* ret */ + }; + + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + insert_at_head( &rmesa->vb.dfn_cache.Normal3fv, dfn ); + dfn->key[0] = key[0]; + dfn->key[1] = key[1]; + + dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 5, 0x0, (int)vb.normalptr); + return dfn; +} + +void r200InitSSECodegen( struct dfn_generators *gen ) +{ + /* Need to: + * - check kernel sse support + * - check p4/sse2 + */ + (void) makeSSENormal3fv; +} + + +#else + +void r200InitSSECodegen( struct dfn_generators *gen ) +{ + (void) gen; +} + +#endif + + + + diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c new file mode 100644 index 000000000..b1a0b4afd --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c @@ -0,0 +1,463 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include <stdio.h> +#include <assert.h> +#include "mem.h" +#include "mmath.h" +#include "simple_list.h" +#include "r200_vtxfmt.h" + +#if defined(USE_X86_ASM) + +#define EXTERN( FUNC ) \ +extern const char *FUNC; \ +extern const char *FUNC##_end + +EXTERN ( _x86_Normal3fv ); +EXTERN ( _x86_Normal3f ); +EXTERN ( _x86_Vertex3fv_6 ); +EXTERN ( _x86_Vertex3fv_8 ); +EXTERN ( _x86_Vertex3fv ); +EXTERN ( _x86_Vertex3f_4 ); +EXTERN ( _x86_Vertex3f_6 ); +EXTERN ( _x86_Vertex3f ); +EXTERN ( _x86_Color4ubv_ub ); +EXTERN ( _x86_Color4ubv_4f ); +EXTERN ( _x86_Color4ub_ub ); +EXTERN ( _x86_Color3fv_3f ); +EXTERN ( _x86_Color3f_3f ); +EXTERN ( _x86_TexCoord2fv ); +EXTERN ( _x86_TexCoord2f ); +EXTERN ( _x86_MultiTexCoord2fvARB ); +EXTERN ( _x86_MultiTexCoord2fvARB_2 ); +EXTERN ( _x86_MultiTexCoord2fARB ); +EXTERN ( _x86_MultiTexCoord2fARB_2 ); + + +/* Build specialized versions of the immediate calls on the fly for + * the current state. Generic x86 versions. + */ + +struct dynfn *r200_makeX86Vertex3f( GLcontext *ctx, const int *key ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__, + key[0], key[1], vb.vertex_size ); + + switch (vb.vertex_size) { + case 4: { + + DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f ); + FIXUP(dfn->code, 2, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 25, 0x0, (int)&vb.vertex[3]); + FIXUP(dfn->code, 36, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 46, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 51, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 60, 0x0, (int)&vb.notify); + break; + } + case 6: { + + DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f ); + FIXUP(dfn->code, 3, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 28, 0x0, (int)&vb.vertex[3]); + FIXUP(dfn->code, 34, 0x0, (int)&vb.vertex[4]); + FIXUP(dfn->code, 40, 0x0, (int)&vb.vertex[5]); + FIXUP(dfn->code, 57, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 63, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 70, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 79, 0x0, (int)&vb.notify); + break; + } + default: { + + DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f ); + FIXUP(dfn->code, 3, 0x0, (int)&vb.vertex[3]); + FIXUP(dfn->code, 9, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 37, 0x0, vb.vertex_size-3); + FIXUP(dfn->code, 44, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 50, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 56, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 67, 0x0, (int)&vb.notify); + break; + } + } + + return dfn; +} + + + +struct dynfn *r200_makeX86Vertex3fv( GLcontext *ctx, const int *key ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__, + key[0], key[1], vb.vertex_size ); + + switch (vb.vertex_size) { + case 6: { + + DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv ); + FIXUP(dfn->code, 1, 0x00000000, (int)&vb.dmaptr); + FIXUP(dfn->code, 27, 0x0000001c, (int)&vb.vertex[3]); + FIXUP(dfn->code, 33, 0x00000020, (int)&vb.vertex[4]); + FIXUP(dfn->code, 45, 0x00000024, (int)&vb.vertex[5]); + FIXUP(dfn->code, 56, 0x00000000, (int)&vb.dmaptr); + FIXUP(dfn->code, 61, 0x00000004, (int)&vb.counter); + FIXUP(dfn->code, 67, 0x00000004, (int)&vb.counter); + FIXUP(dfn->code, 76, 0x00000008, (int)&vb.notify); + break; + } + + + case 8: { + + DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv ); + FIXUP(dfn->code, 1, 0x00000000, (int)&vb.dmaptr); + FIXUP(dfn->code, 27, 0x0000001c, (int)&vb.vertex[3]); + FIXUP(dfn->code, 33, 0x00000020, (int)&vb.vertex[4]); + FIXUP(dfn->code, 45, 0x0000001c, (int)&vb.vertex[5]); + FIXUP(dfn->code, 51, 0x00000020, (int)&vb.vertex[6]); + FIXUP(dfn->code, 63, 0x00000024, (int)&vb.vertex[7]); + FIXUP(dfn->code, 74, 0x00000000, (int)&vb.dmaptr); + FIXUP(dfn->code, 79, 0x00000004, (int)&vb.counter); + FIXUP(dfn->code, 85, 0x00000004, (int)&vb.counter); + FIXUP(dfn->code, 94, 0x00000008, (int)&vb.notify); + break; + } + + + + default: { + + DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv ); + FIXUP(dfn->code, 8, 0x01010101, (int)&vb.dmaptr); + FIXUP(dfn->code, 32, 0x00000006, vb.vertex_size-3); + FIXUP(dfn->code, 37, 0x00000058, (int)&vb.vertex[3]); + FIXUP(dfn->code, 45, 0x01010101, (int)&vb.dmaptr); + FIXUP(dfn->code, 50, 0x02020202, (int)&vb.counter); + FIXUP(dfn->code, 58, 0x02020202, (int)&vb.counter); + FIXUP(dfn->code, 67, 0x0, (int)&vb.notify); + break; + } + } + + return dfn; +} + +struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + int i = 0; + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + + DFN ( _x86_Normal3fv, rmesa->vb.dfn_cache.Normal3fv ); + + FIXUP2(dfn->code, i, 0x0, (int)vb.normalptr); + FIXUP2(dfn->code, i, 0x4, 4+(int)vb.normalptr); + FIXUP2(dfn->code, i, 0x8, 8+(int)vb.normalptr); + fprintf(stderr, "%s done\n", __FUNCTION__); + return dfn; +} + +struct dynfn *r200_makeX86Normal3f( GLcontext *ctx, const int *key ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + + DFN ( _x86_Normal3f, rmesa->vb.dfn_cache.Normal3f ); + FIXUP(dfn->code, 1, 0x12345678, (int)vb.normalptr); + return dfn; +} + +struct dynfn *r200_makeX86Color4ubv( GLcontext *ctx, const int *key ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + + if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { + DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); + FIXUP(dfn->code, 5, 0x12345678, (int)vb.colorptr); + return dfn; + } + else { + + DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); + FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); + FIXUP(dfn->code, 27, 0xdeadbeaf, (int)vb.floatcolorptr); + FIXUP(dfn->code, 33, 0xdeadbeaf, (int)vb.floatcolorptr+4); + FIXUP(dfn->code, 55, 0xdeadbeaf, (int)vb.floatcolorptr+8); + FIXUP(dfn->code, 61, 0xdeadbeaf, (int)vb.floatcolorptr+12); + return dfn; + } +} + +struct dynfn *r200_makeX86Color4ub( GLcontext *ctx, const int *key ) +{ + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + + if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); + FIXUP(dfn->code, 18, 0x0, (int)vb.colorptr); + FIXUP(dfn->code, 24, 0x0, (int)vb.colorptr+1); + FIXUP(dfn->code, 30, 0x0, (int)vb.colorptr+2); + FIXUP(dfn->code, 36, 0x0, (int)vb.colorptr+3); + return dfn; + } + else + return 0; +} + + +struct dynfn *r200_makeX86Color3fv( GLcontext *ctx, const int *key ) +{ + if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) + return 0; + else + { + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + + DFN ( _x86_Color3fv_3f, rmesa->vb.dfn_cache.Color3fv ); + FIXUP(dfn->code, 5, 0x0, (int)vb.floatcolorptr); + return dfn; + } +} + +struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key ) +{ + if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) + return 0; + else + { + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + + DFN ( _x86_Color3f_3f, rmesa->vb.dfn_cache.Color3f ); + FIXUP(dfn->code, 1, 0x12345678, (int)vb.floatcolorptr); + return dfn; + } +} + + + +struct dynfn *r200_makeX86TexCoord2fv( GLcontext *ctx, const int *key ) +{ + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); + + DFN ( _x86_TexCoord2fv, rmesa->vb.dfn_cache.TexCoord2fv ); + FIXUP(dfn->code, 5, 0x12345678, (int)vb.texcoordptr[0]); + return dfn; +} + +struct dynfn *r200_makeX86TexCoord2f( GLcontext *ctx, const int *key ) +{ + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); + + DFN ( _x86_TexCoord2f, rmesa->vb.dfn_cache.TexCoord2f ); + FIXUP(dfn->code, 1, 0x12345678, (int)vb.texcoordptr[0]); + return dfn; +} + +struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key ) +{ +#if 0 + static char temp[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ + 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ + 0x83, 0xe0, 0x01, /* and $0x1,%eax */ + 0x8b, 0x11, /* mov (%ecx),%edx */ + 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ + 0x8b, 0x49, 0x04, /* mov 0x4(%ecx),%ecx */ + 0x89, 0x90, 0, 0, 0, 0,/* mov %edx,DEST(%eax) */ + 0x89, 0x88, 0, 0, 0, 0,/* mov %ecx,DEST+8(%eax) */ + 0xc3, /* ret */ + }; + static char temp2[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ + 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ + 0x83, 0xe0, 0x01, /* and $0x1,%eax */ + 0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%edx */ + 0x8b, 0x01, /* mov (%ecx),%eax */ + 0x89, 0x02, /* mov %eax,(%edx) */ + 0x8b, 0x41, 0x04, /* mov 0x4(%ecx),%eax */ + 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ + 0xc3, /* ret */ + }; +#endif + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); + + if (vb.texcoordptr[1] == vb.texcoordptr[0]+4) { + DFN ( _x86_MultiTexCoord2fvARB, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 26, 0xdeadbeef, (int)vb.texcoordptr[0]); + FIXUP(dfn->code, 32, 0xdeadbeef, (int)vb.texcoordptr[0]+4); + } else { + DFN ( _x86_MultiTexCoord2fvARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 19, 0x0, (int)vb.texcoordptr); + } + return dfn; +} + +struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx, + const int *key ) +{ +#if 0 + static char temp[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ + 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ + 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ + 0x83, 0xe0, 0x01, /* and $0x1,%eax */ + 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ + 0x89, 0x90, 0, 0, 0, 0, /* mov %edx,DEST(%eax) */ + 0x89, 0x88, 0, 0, 0, 0, /* mov %ecx,DEST+8(%eax) */ + 0xc3, /* ret */ + }; + + static char temp2[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ + 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ + 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ + 0x83, 0xe0, 0x01, /* and $0x1,%eax */ + 0x8b, 0x04, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%eax */ + 0x89, 0x10, /* mov %edx,(%eax) */ + 0x89, 0x48, 0x04, /* mov %ecx,0x4(%eax) */ + 0xc3, /* ret */ + }; +#endif + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); + + if (vb.texcoordptr[1] == vb.texcoordptr[0]+4) { + DFN ( _x86_MultiTexCoord2fARB, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 25, 0xdeadbeef, (int)vb.texcoordptr[0]); + FIXUP(dfn->code, 31, 0xdeadbeef, (int)vb.texcoordptr[0]+4); + } + else { + /* Note: this might get generated multiple times, even though the + * actual emitted code is the same. + */ + DFN ( _x86_MultiTexCoord2fARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 23, 0x0, (int)vb.texcoordptr); + } + return dfn; +} + + +void r200InitX86Codegen( struct dfn_generators *gen ) +{ + gen->Vertex3f = r200_makeX86Vertex3f; + gen->Vertex3fv = r200_makeX86Vertex3fv; + gen->Color4ub = r200_makeX86Color4ub; /* PKCOLOR only */ + gen->Color4ubv = r200_makeX86Color4ubv; /* PKCOLOR only */ + gen->Normal3f = r200_makeX86Normal3f; + gen->Normal3fv = r200_makeX86Normal3fv; + gen->TexCoord2f = r200_makeX86TexCoord2f; + gen->TexCoord2fv = r200_makeX86TexCoord2fv; + gen->MultiTexCoord2fARB = r200_makeX86MultiTexCoord2fARB; + gen->MultiTexCoord2fvARB = r200_makeX86MultiTexCoord2fvARB; + gen->Color3f = r200_makeX86Color3f; + gen->Color3fv = r200_makeX86Color3fv; + + /* Not done: + */ +/* gen->Vertex2f = r200_makeX86Vertex2f; */ +/* gen->Vertex2fv = r200_makeX86Vertex2fv; */ +/* gen->Color3ub = r200_makeX86Color3ub; */ +/* gen->Color3ubv = r200_makeX86Color3ubv; */ +/* gen->Color4f = r200_makeX86Color4f; */ +/* gen->Color4fv = r200_makeX86Color4fv; */ +/* gen->TexCoord1f = r200_makeX86TexCoord1f; */ +/* gen->TexCoord1fv = r200_makeX86TexCoord1fv; */ +/* gen->MultiTexCoord1fARB = r200_makeX86MultiTexCoord1fARB; */ +/* gen->MultiTexCoord1fvARB = r200_makeX86MultiTexCoord1fvARB; */ +} + + +#else + +void r200InitX86Codegen( struct dfn_generators *gen ) +{ + (void) gen; +} + +#endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S b/xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S new file mode 100644 index 000000000..fb965de0b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S @@ -0,0 +1,410 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S,v 1.2 2002/11/07 18:31:59 tsi Exp $ */ +/************************************************************************** + +Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#define GLOBL( x ) \ +.globl x; \ +x##: + +.data +.align 4 +GLOBL( _x86_Normal3fv) + movl 4(%esp), %eax /* load 'v' off stack */ + movl (%eax), %ecx /* load v[0] */ + movl 4(%eax), %edx /* load v[1] */ + movl 8(%eax), %eax /* load v[2] */ + movl %ecx, 0 /* store v[0] to current vertex */ + movl %edx, 4 /* store v[1] to current vertex */ + movl %eax, 8 /* store v[2] to current vertex */ + ret +GLOBL ( _x86_Normal3fv_end ) + +/* + vertex 3f vertex size 4 +*/ + +GLOBL ( _x86_Vertex3f_4 ) + movl (0), %ecx + movl 4(%esp), %eax + movl 8(%esp), %edx + movl %eax, (%ecx) + movl %edx, 4(%ecx) + movl 12(%esp), %eax + movl (0), %edx + movl %eax, 8(%ecx) + movl %edx, 12(%ecx) + movl (0), %eax + addl $16, %ecx + dec %eax + movl %ecx, (0) + movl %eax, (0) + je .1 + ret +.1: jmp *0 + +GLOBL ( _x86_Vertex3f_4_end ) + +/* + vertex 3f vertex size 6 +*/ +GLOBL ( _x86_Vertex3f_6 ) + push %edi + movl (0), %edi + movl 8(%esp), %eax + movl 12(%esp), %edx + movl 16(%esp), %ecx + movl %eax, (%edi) + movl %edx, 4(%edi) + movl %ecx, 8(%edi) + movl (0), %eax + movl (0), %edx + movl (0), %ecx + movl %eax, 12(%edi) + movl %edx, 16(%edi) + movl %ecx, 20(%edi) + addl $24, %edi + movl (0), %eax + movl %edi, (0) + dec %eax + pop %edi + movl %eax, (0) + je .2 + ret +.2: jmp *0 +GLOBL ( _x86_Vertex3f_6_end ) +/* + vertex 3f generic size +*/ +GLOBL ( _x86_Vertex3f ) + push %edi + push %esi + movl $0, %esi + movl (0), %edi + movl 12(%esp), %eax + movl 16(%esp), %edx + movl 20(%esp), %ecx + movl %eax, (%edi) + movl %edx, 4(%edi) + movl %ecx, 8(%edi) + addl $12, %edi + movl $0, %ecx + repz + movsl %ds:(%esi), %es:(%edi) + movl (0), %eax + movl %edi, (0) + dec %eax + movl %eax, (0) + pop %esi + pop %edi + je .3 + ret +.3: jmp *0 + +GLOBL ( _x86_Vertex3f_end ) + +/* + Vertex 3fv vertex size 6 +*/ +GLOBL ( _x86_Vertex3fv_6 ) + movl (0), %eax + movl 4(%esp), %ecx + movl (%ecx), %edx + movl %edx, (%eax) + movl 4(%ecx), %edx + movl 8(%ecx), %ecx + movl %edx, 4(%eax) + movl %ecx, 8(%eax) + movl (28), %edx + movl (32), %ecx + movl %edx, 12(%eax) + movl %ecx, 16(%eax) + movl (36), %edx + movl %edx, 20(%eax) + addl $24, %eax + movl %eax, 0 + movl 4, %eax + dec %eax + movl %eax, 4 + je .4 + ret +.4: jmp *8 + +GLOBL ( _x86_Vertex3fv_6_end ) + +/* + Vertex 3fv vertex size 8 +*/ +GLOBL ( _x86_Vertex3fv_8 ) + movl (0), %eax + movl 4(%esp), %ecx + movl (%ecx), %edx + movl %edx ,(%eax) + movl 4(%ecx) ,%edx + movl 8(%ecx) ,%ecx + movl %edx, 4(%eax) + movl %ecx, 8(%eax) + movl (28), %edx + movl (32), %ecx + movl %edx, 12(%eax) + movl %ecx, 16(%eax) + movl (28), %edx + movl (32), %ecx + movl %edx, 20(%eax) + movl %ecx, 24(%eax) + movl (36), %edx + movl %edx, 28(%eax) + addl $32, %eax + movl %eax, (0) + movl 4, %eax + dec %eax + movl %eax, (4) + je .5 + ret +.5: jmp *8 + +GLOBL ( _x86_Vertex3fv_8_end ) + +/* + Vertex 3fv generic vertex size +*/ +GLOBL ( _x86_Vertex3fv ) + movl 4(%esp), %edx + push %edi + push %esi + movl (0x1010101), %edi + movl (%edx), %eax + movl 4(%edx), %ecx + movl 8(%edx), %esi + movl %eax, (%edi) + movl %ecx, 4(%edi) + movl %esi, 8(%edi) + addl $12, %edi + movl $6, %ecx + movl $0x58, %esi + repz + movsl %ds:(%esi), %es:(%edi) + movl %edi, (0x1010101) + movl (0x2020202), %eax + pop %esi + pop %edi + dec %eax + movl %eax, (0x2020202) + je .6 + ret +.6: jmp *0 +GLOBL ( _x86_Vertex3fv_end ) + +/* + Normal 3f +*/ +GLOBL ( _x86_Normal3f ) + movl $0x12345678, %edx + movl 4(%esp), %eax + movl %eax, (%edx) + movl 8(%esp), %eax + movl %eax, 4(%edx) + movl 12(%esp), %eax + movl %eax, 8(%edx) + ret +GLOBL ( _x86_Normal3f_end ) + +/* + Color 4ubv_ub +*/ +GLOBL ( _x86_Color4ubv_ub ) + movl 4(%esp), %eax + movl $0x12345678, %edx + movl (%eax), %eax + movl %eax, (%edx) + ret +GLOBL ( _x86_Color4ubv_ub_end ) + +/* + Color 4ubv 4f +*/ +GLOBL ( _x86_Color4ubv_4f ) + push %ebx + movl $0, %edx + xor %eax, %eax + xor %ecx, %ecx + movl 8(%esp), %ebx + movl (%ebx), %ebx + mov %bl, %al + mov %bh, %cl + movl (%edx,%eax,4),%eax + movl (%edx,%ecx,4),%ecx + movl %eax, (0xdeadbeaf) + movl %ecx, (0xdeadbeaf) + xor %eax, %eax + xor %ecx, %ecx + shr $16, %ebx + mov %bl, %al + mov %bh, %cl + movl (%edx,%eax,4), %eax + movl (%edx,%ecx,4), %ecx + movl %eax, (0xdeadbeaf) + movl %ecx, (0xdeadbeaf) + pop %ebx + ret +GLOBL ( _x86_Color4ubv_4f_end ) + +/* + + Color4ub_ub +*/ +GLOBL( _x86_Color4ub_ub ) + push %ebx + movl 8(%esp), %eax + movl 12(%esp), %edx + movl 16(%esp), %ecx + movl 20(%esp), %ebx + mov %al, (0) + mov %dl, (0) + mov %cl, (0) + mov %bl, (0) + pop %ebx + ret +GLOBL( _x86_Color4ub_ub_end ) + +/* + Color3fv_3f +*/ +GLOBL( _x86_Color3fv_3f ) + movl 4(%esp), %eax + movl $0, %edx + movl (%eax), %ecx + movl %ecx, (%edx) + movl 4(%eax), %ecx + movl %ecx, 4(%edx) + movl 8(%eax), %ecx + movl %ecx, 8(%edx) + ret +GLOBL( _x86_Color3fv_3f_end ) + +/* + Color3f_3f +*/ +GLOBL( _x86_Color3f_3f ) + movl $0x12345678, %edx + movl 4(%esp), %eax + movl %eax, (%edx) + movl 8(%esp,1), %eax + movl %eax, 4(%edx) + movl 12(%esp), %eax + movl %eax, 8(%edx) + ret +GLOBL( _x86_Color3f_3f_end ) + +/* + TexCoord2fv +*/ + +GLOBL( _x86_TexCoord2fv ) + movl 4(%esp), %eax + movl $0x12345678, %edx + movl (%eax), %ecx + movl 4(%eax), %eax + movl %ecx, (%edx) + movl %eax, 4(%edx) + ret + +GLOBL( _x86_TexCoord2fv_end ) +/* + TexCoord2f +*/ +GLOBL( _x86_TexCoord2f ) + movl $0x12345678, %edx + movl 4(%esp), %eax + movl 8(%esp), %ecx + movl %eax, (%edx) + movl %ecx, 4(%edx) + ret +GLOBL( _x86_TexCoord2f_end ) + +/* + MultiTexCoord2fvARB st0/st1 +*/ +GLOBL( _x86_MultiTexCoord2fvARB ) + + movl 4(%esp), %eax + movl 8(%esp), %ecx + sub $0x84c0, %eax + and $1, %eax + movl (%ecx), %edx + shl $3, %eax + movl 4(%ecx), %ecx + movl %edx, 0xdeadbeef(%eax) + movl %ecx, 0xdeadbeef(%eax) + ret +GLOBL( _x86_MultiTexCoord2fvARB_end ) +/* + MultiTexCoord2fvARB +*/ + +GLOBL( _x86_MultiTexCoord2fvARB_2 ) + movl 4(%esp,1), %eax + movl 8(%esp,1), %ecx + sub $0x84c0, %eax + and $0x1, %eax + movl 0(,%eax,4), %edx + movl (%ecx), %eax + movl %eax, (%edx) + movl 4(%ecx), %eax + movl %eax, 4(%edx) + ret + +GLOBL( _x86_MultiTexCoord2fvARB_2_end ) + +/* + MultiTexCoord2fARB st0/st1 +*/ +GLOBL( _x86_MultiTexCoord2fARB ) + movl 4(%esp), %eax + movl 8(%esp), %edx + sub $0x84c0, %eax + movl 12(%esp), %ecx + and $1, %eax + shl $3, %eax + movl %edx, 0xdeadbeef(%eax) + movl %ecx, 0xdeadbeef(%eax) + ret +GLOBL( _x86_MultiTexCoord2fARB_end ) + +/* + MultiTexCoord2fARB +*/ +GLOBL( _x86_MultiTexCoord2fARB_2 ) + movl 4(%esp), %eax + movl 8(%esp), %edx + sub $0x84c0, %eax + movl 12(%esp,1), %ecx + and $1,%eax + movl 0(,%eax,4), %eax + movl %edx, (%eax) + movl %ecx, 4(%eax) + ret +GLOBL( _x86_MultiTexCoord2fARB_2_end ) diff --git a/xc/lib/GL/mesa/src/drv/radeon/Imakefile b/xc/lib/GL/mesa/src/drv/radeon/Imakefile index 2a0922ccf..7cb34f1c3 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/Imakefile +++ b/xc/lib/GL/mesa/src/drv/radeon/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/radeon/Imakefile,v 1.9 2002/02/23 00:45:50 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/radeon/Imakefile,v 1.11 2002/11/25 14:04:51 eich Exp $ #include <Threads.tmpl> @@ -25,7 +25,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/radeon/Imakefile,v 1.9 2002/02/23 00:45:5 #include "../../tnl/Imakefile.inc" #include "../../tnl_dd/Imakefile.inc" #include "../../Imakefile.inc" -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #include "../../X86/Imakefile.inc" #endif #ifdef SparcArchitecture @@ -40,8 +40,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/radeon/Imakefile,v 1.9 2002/02/23 00:45:5 DRMOBJS = $(GLXLIBSRC)/dri/drm/xf86drm.o \ $(GLXLIBSRC)/dri/drm/xf86drmHash.o \ $(GLXLIBSRC)/dri/drm/xf86drmRandom.o \ - $(GLXLIBSRC)/dri/drm/xf86drmSL.o \ - $(GLXLIBSRC)/dri/drm/xf86drmRadeon.o + $(GLXLIBSRC)/dri/drm/xf86drmSL.o #ifdef GlxSoProf LOSRCS = ../../../../lowpc.c @@ -55,7 +54,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/radeon/Imakefile,v 1.9 2002/02/23 00:45:5 OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(COREMESAOBJS) \ $(MESA_ASM_OBJS) $(COMMONOBJS) $(RADEONOBJS) $(HIOBJS) -REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) +REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) $(XONLYLIB) #include <Library.tmpl> diff --git a/xc/lib/GL/mesa/src/drv/radeon/Imakefile.inc b/xc/lib/GL/mesa/src/drv/radeon/Imakefile.inc index e564cf074..175a3e3bf 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/Imakefile.inc +++ b/xc/lib/GL/mesa/src/drv/radeon/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/radeon/Imakefile.inc,v 1.3 2002/02/22 21:45:00 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/radeon/Imakefile.inc,v 1.4 2002/10/30 12:51:54 alanh Exp $ #ifndef MesaDrvSrcDir #define MesaDrvSrcDir $(GLXLIBSRC)/mesa/src/drv @@ -26,7 +26,8 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL -I$(XF86DRIVERSRC)/ati \ -I$(XF86COMSRC) \ -I$(GLXLIBSRC)/dri/drm \ - -I$(GLXLIBSRC)/include + -I$(GLXLIBSRC)/include \ + -I$(XTOP)/include #endif MESA_INCLUDES = -I$(MESASRCDIR)/src \ @@ -35,81 +36,141 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src \ X_INCLUDES = -I$(XINCLUDESRC) -I$(EXTINCSRC) RADEONSRCS = $(MESADRVRADEONBUILDDIR)radeon_context.c \ + $(MESADRVRADEONBUILDDIR)radeon_compat.c \ $(MESADRVRADEONBUILDDIR)radeon_ioctl.c \ $(MESADRVRADEONBUILDDIR)radeon_lock.c \ - $(MESADRVRADEONBUILDDIR)radeon_render.c \ + $(MESADRVRADEONBUILDDIR)radeon_maos.c \ + $(MESADRVRADEONBUILDDIR)radeon_sanity.c \ $(MESADRVRADEONBUILDDIR)radeon_screen.c \ $(MESADRVRADEONBUILDDIR)radeon_span.c \ $(MESADRVRADEONBUILDDIR)radeon_state.c \ + $(MESADRVRADEONBUILDDIR)radeon_state_init.c \ + $(MESADRVRADEONBUILDDIR)radeon_swtcl.c \ + $(MESADRVRADEONBUILDDIR)radeon_tcl.c \ $(MESADRVRADEONBUILDDIR)radeon_tex.c \ $(MESADRVRADEONBUILDDIR)radeon_texmem.c \ $(MESADRVRADEONBUILDDIR)radeon_texstate.c \ - $(MESADRVRADEONBUILDDIR)radeon_tris.c \ - $(MESADRVRADEONBUILDDIR)radeon_vb.c + $(MESADRVRADEONBUILDDIR)radeon_vtxfmt.c \ + $(MESADRVRADEONBUILDDIR)radeon_vtxfmt_x86.c \ + $(MESADRVRADEONBUILDDIR)radeon_vtxtmp_x86.S \ + $(MESADRVRADEONBUILDDIR)radeon_vtxfmt_sse.c \ + $(MESADRVRADEONBUILDDIR)radeon_vtxfmt_c.c RADEONOBJS = $(MESADRVRADEONBUILDDIR)radeon_context.o \ + $(MESADRVRADEONBUILDDIR)radeon_compat.o \ $(MESADRVRADEONBUILDDIR)radeon_ioctl.o \ $(MESADRVRADEONBUILDDIR)radeon_lock.o \ - $(MESADRVRADEONBUILDDIR)radeon_render.o \ + $(MESADRVRADEONBUILDDIR)radeon_maos.o \ + $(MESADRVRADEONBUILDDIR)radeon_sanity.o \ $(MESADRVRADEONBUILDDIR)radeon_screen.o \ $(MESADRVRADEONBUILDDIR)radeon_span.o \ $(MESADRVRADEONBUILDDIR)radeon_state.o \ + $(MESADRVRADEONBUILDDIR)radeon_state_init.o \ + $(MESADRVRADEONBUILDDIR)radeon_swtcl.o \ + $(MESADRVRADEONBUILDDIR)radeon_tcl.o \ $(MESADRVRADEONBUILDDIR)radeon_tex.o \ $(MESADRVRADEONBUILDDIR)radeon_texmem.o \ $(MESADRVRADEONBUILDDIR)radeon_texstate.o \ - $(MESADRVRADEONBUILDDIR)radeon_tris.o \ - $(MESADRVRADEONBUILDDIR)radeon_vb.o + $(MESADRVRADEONBUILDDIR)radeon_vtxfmt.o \ + $(MESADRVRADEONBUILDDIR)radeon_vtxfmt_c.o + +#ifdef i386Architecture + RADEONOBJS += $(MESADRVRADEONBUILDDIR)radeon_vtxfmt_x86.o \ + $(MESADRVRADEONBUILDDIR)radeon_vtxtmp_x86.o \ + $(MESADRVRADEONBUILDDIR)radeon_vtxfmt_sse.o +#endif RADEONUOBJS = $(MESADRVRADEONBUILDDIR)unshared/radeon_context.o \ + $(MESADRVRADEONBUILDDIR)unshared/radeon_compat.o \ $(MESADRVRADEONBUILDDIR)unshared/radeon_ioctl.o \ $(MESADRVRADEONBUILDDIR)unshared/radeon_lock.o \ - $(MESADRVRADEONBUILDDIR)unshared/radeon_render.o \ + $(MESADRVRADEONBUILDDIR)unshared/radeon_maos.o \ + $(MESADRVRADEONBUILDDIR)unshared/radeon_sanity.o \ $(MESADRVRADEONBUILDDIR)unshared/radeon_screen.o \ $(MESADRVRADEONBUILDDIR)unshared/radeon_span.o \ $(MESADRVRADEONBUILDDIR)unshared/radeon_state.o \ + $(MESADRVRADEONBUILDDIR)unshared/radeon_state_init.o \ + $(MESADRVRADEONBUILDDIR)unshared/radeon_swtcl.o \ + $(MESADRVRADEONBUILDDIR)unshared/radeon_tcl.o \ $(MESADRVRADEONBUILDDIR)unshared/radeon_tex.o \ $(MESADRVRADEONBUILDDIR)unshared/radeon_texmem.o \ $(MESADRVRADEONBUILDDIR)unshared/radeon_texstate.o \ - $(MESADRVRADEONBUILDDIR)unshared/radeon_tris.o \ - $(MESADRVRADEONBUILDDIR)unshared/radeon_vb.o + $(MESADRVRADEONBUILDDIR)unshared/radeon_vtxfmt.o \ + $(MESADRVRADEONBUILDDIR)unshared/radeon_vtxfmt_c.o + +#ifdef i386Architecture + RADEONUOBJS += $(MESADRVRADEONBUILDDIR)unshared/radeon_vtxfmt_x86.o \ + $(MESADRVRADEONBUILDDIR)unshared/radeon_vtxtmp_x86.o \ + $(MESADRVRADEONBUILDDIR)unshared/radeon_vtxfmt_sse.o +#endif RADEONDOBJS = $(MESADRVRADEONBUILDDIR)debugger/radeon_context.o \ + $(MESADRVRADEONBUILDDIR)debugger/radeon_compat.o \ $(MESADRVRADEONBUILDDIR)debugger/radeon_ioctl.o \ $(MESADRVRADEONBUILDDIR)debugger/radeon_lock.o \ - $(MESADRVRADEONBUILDDIR)debugger/radeon_render.o \ + $(MESADRVRADEONBUILDDIR)debugger/radeon_maos.o \ + $(MESADRVRADEONBUILDDIR)debugger/radeon_sanity.o \ $(MESADRVRADEONBUILDDIR)debugger/radeon_screen.o \ $(MESADRVRADEONBUILDDIR)debugger/radeon_span.o \ $(MESADRVRADEONBUILDDIR)debugger/radeon_state.o \ + $(MESADRVRADEONBUILDDIR)debugger/radeon_state_init.o \ + $(MESADRVRADEONBUILDDIR)debugger/radeon_swtcl.o \ + $(MESADRVRADEONBUILDDIR)debugger/radeon_tcl.o \ $(MESADRVRADEONBUILDDIR)debugger/radeon_tex.o \ $(MESADRVRADEONBUILDDIR)debugger/radeon_texmem.o \ $(MESADRVRADEONBUILDDIR)debugger/radeon_texstate.o \ - $(MESADRVRADEONBUILDDIR)debugger/radeon_tris.o \ - $(MESADRVRADEONBUILDDIR)debugger/radeon_vb.o + $(MESADRVRADEONBUILDDIR)debugger/radeon_vtxfmt.o \ + $(MESADRVRADEONBUILDDIR)debugger/radeon_vtxfmt_c.o + +#ifdef i386Architecture + RADEONDOBJS += $(MESADRVRADEONBUILDDIR)debugger/radeon_vtxfmt_x86.o \ + $(MESADRVRADEONBUILDDIR)debugger/radeon_vtxtmp_x86.o \ + $(MESADRVRADEONBUILDDIR)debugger/radeon_vtxfmt_sse.o +#endif RADEONPOBJS = $(MESADRVRADEONBUILDDIR)profiled/radeon_context.o \ + $(MESADRVRADEONBUILDDIR)profiled/radeon_compat.o \ $(MESADRVRADEONBUILDDIR)profiled/radeon_ioctl.o \ $(MESADRVRADEONBUILDDIR)profiled/radeon_lock.o \ - $(MESADRVRADEONBUILDDIR)profiled/radeon_render.o \ + $(MESADRVRADEONBUILDDIR)profiled/radeon_maos.o \ + $(MESADRVRADEONBUILDDIR)profiled/radeon_sanity.o \ $(MESADRVRADEONBUILDDIR)profiled/radeon_screen.o \ $(MESADRVRADEONBUILDDIR)profiled/radeon_span.o \ $(MESADRVRADEONBUILDDIR)profiled/radeon_state.o \ + $(MESADRVRADEONBUILDDIR)profiled/radeon_state_init.o \ + $(MESADRVRADEONBUILDDIR)profiled/radeon_swtcl.o \ + $(MESADRVRADEONBUILDDIR)profiled/radeon_tcl.o \ $(MESADRVRADEONBUILDDIR)profiled/radeon_tex.o \ $(MESADRVRADEONBUILDDIR)profiled/radeon_texmem.o \ $(MESADRVRADEONBUILDDIR)profiled/radeon_texstate.o \ - $(MESADRVRADEONBUILDDIR)profiled/radeon_tris.o \ - $(MESADRVRADEONBUILDDIR)profiled/radeon_vb.o + $(MESADRVRADEONBUILDDIR)profiled/radeon_vtxfmt.o \ + $(MESADRVRADEONBUILDDIR)profiled/radeon_vtxfmt_c.o + +#ifdef i386Architecture + RADEONPOBJS += $(MESADRVRADEONBUILDDIR)profiled/radeon_vtxfmt_x86.o \ + $(MESADRVRADEONBUILDDIR)profiled/radeon_vtxtmp_x86.o \ + $(MESADRVRADEONBUILDDIR)profiled/radeon_vtxfmt_sse.o +#endif #ifdef NeedToLinkMesaSrc LinkSourceFile(radeon_context.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_compat.c, $(MESADRVSRCDIR)/radeon) LinkSourceFile(radeon_ioctl.c, $(MESADRVSRCDIR)/radeon) LinkSourceFile(radeon_lock.c, $(MESADRVSRCDIR)/radeon) -LinkSourceFile(radeon_render.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_maos.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_sanity.c, $(MESADRVSRCDIR)/radeon) LinkSourceFile(radeon_screen.c, $(MESADRVSRCDIR)/radeon) LinkSourceFile(radeon_span.c, $(MESADRVSRCDIR)/radeon) LinkSourceFile(radeon_state.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_state_init.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_swtcl.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_tcl.c, $(MESADRVSRCDIR)/radeon) LinkSourceFile(radeon_tex.c, $(MESADRVSRCDIR)/radeon) LinkSourceFile(radeon_texmem.c, $(MESADRVSRCDIR)/radeon) LinkSourceFile(radeon_texstate.c, $(MESADRVSRCDIR)/radeon) -LinkSourceFile(radeon_tris.c, $(MESADRVSRCDIR)/radeon) -LinkSourceFile(radeon_vb.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_vtxfmt.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_vtxfmt_c.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_vtxfmt_x86.c, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_vtxtmp_x86.S, $(MESADRVSRCDIR)/radeon) +LinkSourceFile(radeon_vtxfmt_sse.c, $(MESADRVSRCDIR)/radeon) #endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_compat.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_compat.c new file mode 100644 index 000000000..5737c4d85 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_compat.c @@ -0,0 +1,301 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_compat.c,v 1.1 2002/10/30 12:51:54 alanh Exp $ */ +/************************************************************************** + +Copyright 2002 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc., Austin, 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "mem.h" + +static struct { + int start; + int len; + const char *name; +} packet[RADEON_MAX_STATE_PACKETS] = { + { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, + { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, + { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, + { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, + { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, + { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, + { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, + { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, + { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, + { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, + { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, + { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, + { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, + { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, + { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, + { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, + { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, + { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, + { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, + { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, +}; + + +static void radeonCompatEmitPacket( radeonContextPtr rmesa, + struct radeon_state_atom *state ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + radeon_context_regs_t *ctx = &sarea->ContextState; + radeon_texture_regs_t *tex0 = &sarea->TexState[0]; + radeon_texture_regs_t *tex1 = &sarea->TexState[1]; + int i; + int *buf = state->cmd; + + for ( i = 0 ; i < state->cmd_size ; ) { + drmRadeonCmdHeader *header = (drmRadeonCmdHeader *)&buf[i++]; + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s %d: %s\n", __FUNCTION__, header->packet.packet_id, + packet[(int)header->packet.packet_id].name); + + switch (header->packet.packet_id) { + case RADEON_EMIT_PP_MISC: + ctx->pp_misc = buf[i++]; + ctx->pp_fog_color = buf[i++]; + ctx->re_solid_color = buf[i++]; + ctx->rb3d_blendcntl = buf[i++]; + ctx->rb3d_depthoffset = buf[i++]; + ctx->rb3d_depthpitch = buf[i++]; + ctx->rb3d_zstencilcntl = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_CONTEXT; + break; + case RADEON_EMIT_PP_CNTL: + ctx->pp_cntl = buf[i++]; + ctx->rb3d_cntl = buf[i++]; + ctx->rb3d_coloroffset = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_CONTEXT; + break; + case RADEON_EMIT_RB3D_COLORPITCH: + ctx->rb3d_colorpitch = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_CONTEXT; + break; + case RADEON_EMIT_RE_LINE_PATTERN: + ctx->re_line_pattern = buf[i++]; + ctx->re_line_state = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_LINE; + break; + case RADEON_EMIT_SE_LINE_WIDTH: + ctx->se_line_width = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_LINE; + break; + case RADEON_EMIT_PP_LUM_MATRIX: + ctx->pp_lum_matrix = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_BUMPMAP; + break; + case RADEON_EMIT_PP_ROT_MATRIX_0: + ctx->pp_rot_matrix_0 = buf[i++]; + ctx->pp_rot_matrix_1 = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_BUMPMAP; + break; + case RADEON_EMIT_RB3D_STENCILREFMASK: + ctx->rb3d_stencilrefmask = buf[i++]; + ctx->rb3d_ropcntl = buf[i++]; + ctx->rb3d_planemask = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_MASKS; + break; + case RADEON_EMIT_SE_VPORT_XSCALE: + ctx->se_vport_xscale = buf[i++]; + ctx->se_vport_xoffset = buf[i++]; + ctx->se_vport_yscale = buf[i++]; + ctx->se_vport_yoffset = buf[i++]; + ctx->se_vport_zscale = buf[i++]; + ctx->se_vport_zoffset = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_VIEWPORT; + break; + case RADEON_EMIT_SE_CNTL: + ctx->se_cntl = buf[i++]; + ctx->se_coord_fmt = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_VERTFMT; + break; + case RADEON_EMIT_SE_CNTL_STATUS: + ctx->se_cntl_status = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_SETUP; + break; + case RADEON_EMIT_RE_MISC: + ctx->re_misc = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_MISC; + break; + case RADEON_EMIT_PP_TXFILTER_0: + tex0->pp_txfilter = buf[i++]; + tex0->pp_txformat = buf[i++]; + tex0->pp_txoffset = buf[i++]; + tex0->pp_txcblend = buf[i++]; + tex0->pp_txablend = buf[i++]; + tex0->pp_tfactor = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_TEX0; + break; + case RADEON_EMIT_PP_BORDER_COLOR_0: + tex0->pp_border_color = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_TEX0; + break; + case RADEON_EMIT_PP_TXFILTER_1: + tex1->pp_txfilter = buf[i++]; + tex1->pp_txformat = buf[i++]; + tex1->pp_txoffset = buf[i++]; + tex1->pp_txcblend = buf[i++]; + tex1->pp_txablend = buf[i++]; + tex1->pp_tfactor = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_TEX1; + break; + case RADEON_EMIT_PP_BORDER_COLOR_1: + tex1->pp_border_color = buf[i++]; + sarea->dirty |= RADEON_UPLOAD_TEX1; + break; + + case RADEON_EMIT_SE_ZBIAS_FACTOR: + i++; + i++; + break; + + case RADEON_EMIT_PP_TXFILTER_2: + case RADEON_EMIT_PP_BORDER_COLOR_2: + case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT: + case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED: + default: + /* These states aren't understood by radeon drm 1.1 */ + fprintf(stderr, "Tried to emit unsupported state\n"); + return; + } + } +} + + + +static void radeonCompatEmitStateLocked( radeonContextPtr rmesa ) +{ + struct radeon_state_atom *state, *tmp; + + if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->lost_context) { + if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS|DEBUG_IOCTL)) + fprintf(stderr, "%s - lost context\n", __FUNCTION__); + + foreach_s( state, tmp, &(rmesa->hw.clean) ) + move_to_tail(&(rmesa->hw.dirty), state ); + + rmesa->lost_context = 0; + } + + foreach_s( state, tmp, &(rmesa->hw.dirty) ) { + if (!state->is_tcl) + radeonCompatEmitPacket( rmesa, state ); + move_to_head( &(rmesa->hw.clean), state ); + } +} + + + +static void radeonCompatEmitPrimitiveLocked( radeonContextPtr rmesa, + GLuint hw_primitive, + GLuint nverts, + XF86DRIClipRectPtr pbox, + GLuint nbox ) +{ + int i; + + for ( i = 0 ; i < nbox ; ) { + int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + drmRadeonVertex vtx; + + rmesa->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS; + rmesa->sarea->nbox = nr - i; + + for ( ; i < nr ; i++) + *b++ = pbox[i]; + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, + "RadeonFlushVertexBuffer: prim %x buf %d verts %d " + "disc %d nbox %d\n", + hw_primitive, + rmesa->dma.current.buf->buf->idx, + nverts, + nr == nbox, + rmesa->sarea->nbox ); + + vtx.prim = hw_primitive; + vtx.idx = rmesa->dma.current.buf->buf->idx; + vtx.count = nverts; + vtx.discard = (nr == nbox); + + drmCommandWrite( rmesa->dri.fd, + DRM_RADEON_VERTEX, + &vtx, sizeof(vtx)); + } +} + + + +/* No 'start' for 1.1 vertices ioctl: only one vertex prim/buffer! + */ +void radeonCompatEmitPrimitive( radeonContextPtr rmesa, + GLuint vertex_format, + GLuint hw_primitive, + GLuint nrverts ) +{ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + LOCK_HARDWARE( rmesa ); + + radeonCompatEmitStateLocked( rmesa ); + rmesa->sarea->vc_format = vertex_format; + + if (rmesa->state.scissor.enabled) { + radeonCompatEmitPrimitiveLocked( rmesa, + hw_primitive, + nrverts, + rmesa->state.scissor.pClipRects, + rmesa->state.scissor.numClipRects ); + } + else { + radeonCompatEmitPrimitiveLocked( rmesa, + hw_primitive, + nrverts, + rmesa->pClipRects, + rmesa->numClipRects ); + } + + + UNLOCK_HARDWARE( rmesa ); +} + diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c index 690e30af4..15e62e161 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v 1.4 2002/09/10 00:39:39 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v 1.7 2003/02/08 21:26:45 dawes Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -31,18 +31,20 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ -#include <stdlib.h> #include "radeon_context.h" #include "radeon_ioctl.h" #include "radeon_state.h" #include "radeon_span.h" #include "radeon_tex.h" -#include "radeon_tris.h" -#include "radeon_vb.h" +#include "radeon_swtcl.h" +#include "radeon_tcl.h" +#include "radeon_vtxfmt.h" +#include "radeon_maos.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" @@ -51,6 +53,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_pipeline.h" +#include "api_arrayelt.h" #include "context.h" #include "simple_list.h" #include "mem.h" @@ -60,27 +63,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "X86/common_x86_asm.h" #endif -#define RADEON_DATE "20020221" +#define RADEON_DATE "20020611" #ifndef RADEON_DEBUG -int RADEON_DEBUG = (0 -/* | DEBUG_ALWAYS_SYNC */ -/* | DEBUG_VERBOSE_API */ -/* | DEBUG_VERBOSE_MSG */ -/* | DEBUG_VERBOSE_LRU */ -/* | DEBUG_VERBOSE_DRI */ -/* | DEBUG_VERBOSE_IOCTL */ -/* | DEBUG_VERBOSE_2D */ -/* | DEBUG_VERBOSE_TEXTURE */ - ); +int RADEON_DEBUG = (0); #endif -/* Return the width and height of the current color buffer. +/* Return the width and height of the given buffer. */ static void radeonGetBufferSize( GLframebuffer *buffer, - GLuint *width, GLuint *height ) + GLuint *width, GLuint *height ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -100,10 +94,10 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name ) switch ( name ) { case GL_VENDOR: - return (GLubyte *)"VA Linux Systems, Inc."; + return (GLubyte *)"Tungsten Graphics, Inc."; case GL_RENDERER: - sprintf( buffer, "Mesa DRI Radeon " RADEON_DATE ); + sprintf( buffer, "Mesa DRI Radeon " RADEON_DATE); /* Append any chipset-specific information. None yet. */ @@ -144,6 +138,18 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name ) } #endif #endif + + if ( rmesa->dri.drmMinor < 3 ) { + strncat( buffer, " DRM-COMPAT", 11 ); + } + + if ( !(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) ) { + strncat( buffer, " TCL", 4 ); + } + else { + strncat( buffer, " NO-TCL", 7 ); + } + return (GLubyte *)buffer; default: @@ -151,76 +157,80 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name ) } } -/* Send all commands to the hardware. If vertex buffers or indirect - * buffers are in use, then we need to make sure they are sent to the - * hardware. All commands that are normally sent to the ring are - * already considered `flushed'. - */ -static void radeonFlush( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - RADEON_FIREVERTICES( rmesa ); - - if ( rmesa->boxes ) { - LOCK_HARDWARE( rmesa ); - radeonPerformanceBoxesLocked( rmesa ); - UNLOCK_HARDWARE( rmesa ); - } - - /* Log the performance counters if necessary */ - radeonPerformanceCounters( rmesa ); -} - -/* Make sure all commands have been sent to the hardware and have - * completed processing. +/* Extension strings exported by the R100 driver. */ -static void radeonFinish( GLcontext *ctx ) +static const char * const radeon_extensions[] = { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - /* Bump the performance counter */ - rmesa->c_drawWaits++; - radeonFlush( ctx ); - LOCK_HARDWARE( rmesa ); - radeonWaitForIdleLocked( rmesa ); - UNLOCK_HARDWARE( rmesa ); -} - + "GL_ARB_multisample", + "GL_ARB_multitexture", + "GL_ARB_texture_border_clamp", + "GL_ARB_texture_compression", + "GL_ARB_texture_env_add", + "GL_ARB_texture_env_combine", + "GL_ARB_texture_env_dot3", + "GL_ARB_texture_mirrored_repeat", + "GL_EXT_blend_logic_op", + "GL_EXT_blend_subtract", +/* "GL_EXT_fog_coord", */ + "GL_EXT_secondary_color", + "GL_EXT_texture_env_add", + "GL_EXT_texture_env_combine", + "GL_EXT_texture_env_dot3", + "GL_EXT_texture_filter_anisotropic", + "GL_EXT_texture_lod_bias", + "GL_ATI_texture_mirror_once", + "GL_IBM_texture_mirrored_repeat", + "GL_NV_blend_square", + "GL_SGIS_generate_mipmap", + "GL_SGIS_texture_border_clamp", + NULL +}; /* Initialize the extensions supported by this driver. */ static void radeonInitExtensions( GLcontext *ctx ) { + unsigned i; _mesa_enable_imaging_extensions( ctx ); - _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); - _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" ); - - _mesa_enable_extension( ctx, "GL_EXT_blend_logic_op" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_env_dot3" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_filter_anisotropic" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" ); - + for ( i = 0 ; radeon_extensions[i] != NULL ; i++ ) { + _mesa_enable_extension( ctx, radeon_extensions[i] ); + } } extern const struct gl_pipeline_stage _radeon_render_stage; -extern const struct gl_pipeline_stage _radeon_tcl_render_stage; +extern const struct gl_pipeline_stage _radeon_tcl_stage; static const struct gl_pipeline_stage *radeon_pipeline[] = { + + /* Try and go straight to t&l + */ + &_radeon_tcl_stage, + + /* Catch any t&l fallbacks + */ &_tnl_vertex_transform_stage, &_tnl_normal_transform_stage, &_tnl_lighting_stage, &_tnl_fog_coordinate_stage, &_tnl_texgen_stage, &_tnl_texture_transform_stage, - /* REMOVE: point attenuation stage */ -#if 1 - &_radeon_render_stage, /* ADD: unclipped rastersetup-to-dma */ -#endif - &_tnl_render_stage, + + /* Try again to go to tcl? + * - no good for asymmetric-twoside (do with multipass) + * - no good for asymmetric-unfilled (do with multipass) + * - good for material + * - good for texgen + * - need to manipulate a bit of state + * + * - worth it/not worth it? + */ + + /* Else do them here. + */ + &_radeon_render_stage, + &_tnl_render_stage, /* FALLBACK: */ 0, }; @@ -231,9 +241,8 @@ static const struct gl_pipeline_stage *radeon_pipeline[] = { static void radeonInitDriverFuncs( GLcontext *ctx ) { ctx->Driver.GetBufferSize = radeonGetBufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; ctx->Driver.GetString = radeonGetString; - ctx->Driver.Finish = radeonFinish; - ctx->Driver.Flush = radeonFlush; ctx->Driver.Error = NULL; ctx->Driver.DrawPixels = NULL; @@ -286,11 +295,20 @@ radeonCreateContext( Display *dpy, const __GLcontextModes *glVisual, rmesa->dri.hwLock = &sPriv->pSAREA->lock; rmesa->dri.fd = sPriv->fd; + /* If we don't have 1.3, fallback to the 1.1 interfaces. + */ + if (getenv("RADEON_COMPAT") || sPriv->drmMinor < 3 ) + rmesa->dri.drmMinor = 1; + else + rmesa->dri.drmMinor = sPriv->drmMinor; + rmesa->radeonScreen = radeonScreen; rmesa->sarea = (RADEONSAREAPrivPtr)((GLubyte *)sPriv->pSAREA + radeonScreen->sarea_priv_offset); + rmesa->dma.buf0_address = rmesa->radeonScreen->buffers->list[0].address; + for ( i = 0 ; i < radeonScreen->numTexHeaps ; i++ ) { make_empty_list( &rmesa->texture.objects[i] ); rmesa->texture.heap[i] = mmInit( 0, radeonScreen->texSize[i] ); @@ -299,9 +317,8 @@ radeonCreateContext( Display *dpy, const __GLcontextModes *glVisual, rmesa->texture.numHeaps = radeonScreen->numTexHeaps; make_empty_list( &rmesa->texture.swapped ); - rmesa->RenderIndex = ~0; - rmesa->state.hw.dirty = RADEON_UPLOAD_CONTEXT_ALL; - rmesa->upload_cliprects = 1; + rmesa->swtcl.RenderIndex = ~0; + rmesa->lost_context = 1; /* KW: Set the maximum texture size small enough that we can * guarentee that both texture units can bind a maximal texture @@ -338,17 +355,20 @@ radeonCreateContext( Display *dpy, const __GLcontextModes *glVisual, ctx->Const.MaxLineWidthAA = 10.0; ctx->Const.LineWidthGranularity = 0.0625; + /* Set maxlocksize (and hence vb size) small enough to avoid + * fallbacks in radeon_tcl.c. ie. guarentee that all vertices can + * fit in a single dma buffer for indexed rendering of quad strips, + * etc. + */ + ctx->Const.MaxArrayLockSize = + MIN2( ctx->Const.MaxArrayLockSize, + RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE ); + if (getenv("LIBGL_PERFORMANCE_BOXES")) rmesa->boxes = 1; else rmesa->boxes = 0; - { - const char *debug = getenv("LIBGL_DEBUG"); - if (debug && strstr(debug, "fallbacks")) { - rmesa->debugFallbacks = GL_TRUE; - } - } /* Initialize the software rasterizer and helper modules. */ @@ -356,29 +376,150 @@ radeonCreateContext( Display *dpy, const __GLcontextModes *glVisual, _ac_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); - + _ae_create_context( ctx ); /* Install the customized pipeline: */ _tnl_destroy_pipeline( ctx ); _tnl_install_pipeline( ctx, radeon_pipeline ); + /* Try and keep materials and vertices separate: + */ + _tnl_isolate_materials( ctx, GL_TRUE ); + + +/* _mesa_allow_light_in_model( ctx, GL_FALSE ); */ + /* Configure swrast to match hardware characteristics: */ _swrast_allow_pixel_fog( ctx, GL_FALSE ); _swrast_allow_vertex_fog( ctx, GL_TRUE ); - radeonInitVB( ctx ); + + _math_matrix_ctr( &rmesa->TexGenMatrix[0] ); + _math_matrix_ctr( &rmesa->TexGenMatrix[1] ); + _math_matrix_ctr( &rmesa->tmpmat ); + _math_matrix_set_identity( &rmesa->TexGenMatrix[0] ); + _math_matrix_set_identity( &rmesa->TexGenMatrix[1] ); + _math_matrix_set_identity( &rmesa->tmpmat ); + radeonInitExtensions( ctx ); radeonInitDriverFuncs( ctx ); radeonInitIoctlFuncs( ctx ); radeonInitStateFuncs( ctx ); radeonInitSpanFuncs( ctx ); radeonInitTextureFuncs( ctx ); - radeonInitTriFuncs( ctx ); - radeonInitState( rmesa ); + radeonInitSwtcl( ctx ); + + rmesa->do_irqs = (rmesa->radeonScreen->irq && !getenv("RADEON_NO_IRQS")); + rmesa->irqsEmitted = 0; + rmesa->iw.irq_seq = -1; + + rmesa->do_usleeps = !getenv("RADEON_NO_USLEEPS"); + +#if DO_DEBUG + if (getenv("RADEON_DEBUG_FALLBACKS")) + RADEON_DEBUG |= DEBUG_FALLBACKS; + + if (getenv("RADEON_DEBUG_TEXTURE")) + RADEON_DEBUG |= DEBUG_TEXTURE; + + if (getenv("RADEON_DEBUG_IOCTL")) + RADEON_DEBUG |= DEBUG_IOCTL; + + if (getenv("RADEON_DEBUG_PRIMS")) + RADEON_DEBUG |= DEBUG_PRIMS; + + if (getenv("RADEON_DEBUG_VERTS")) + RADEON_DEBUG |= DEBUG_VERTS; + + if (getenv("RADEON_DEBUG_STATE")) + RADEON_DEBUG |= DEBUG_STATE; + + if (getenv("RADEON_DEBUG_CODEGEN")) + RADEON_DEBUG |= DEBUG_CODEGEN; + + if (getenv("RADEON_DEBUG_VTXFMT")) + RADEON_DEBUG |= DEBUG_VFMT; + + if (getenv("RADEON_DEBUG_VERBOSE")) + RADEON_DEBUG |= DEBUG_VERBOSE; + + if (getenv("RADEON_DEBUG_DRI")) + RADEON_DEBUG |= DEBUG_DRI; + + if (getenv("RADEON_DEBUG_DMA")) + RADEON_DEBUG |= DEBUG_DMA; + if (getenv("RADEON_DEBUG_SANITY")) + RADEON_DEBUG |= DEBUG_SANITY; + + if (getenv("RADEON_DEBUG")) + { + const char *debug = getenv("RADEON_DEBUG"); + if (strstr(debug, "fall")) + RADEON_DEBUG |= DEBUG_FALLBACKS; + + if (strstr(debug, "tex")) + RADEON_DEBUG |= DEBUG_TEXTURE; + + if (strstr(debug, "ioctl")) + RADEON_DEBUG |= DEBUG_IOCTL; + + if (strstr(debug, "prim")) + RADEON_DEBUG |= DEBUG_PRIMS; + + if (strstr(debug, "vert")) + RADEON_DEBUG |= DEBUG_VERTS; + + if (strstr(debug, "state")) + RADEON_DEBUG |= DEBUG_STATE; + + if (strstr(debug, "code")) + RADEON_DEBUG |= DEBUG_CODEGEN; + + if (strstr(debug, "vfmt") || strstr(debug, "vtxf")) + RADEON_DEBUG |= DEBUG_VFMT; + + if (strstr(debug, "verb")) + RADEON_DEBUG |= DEBUG_VERBOSE; + + if (strstr(debug, "dri")) + RADEON_DEBUG |= DEBUG_DRI; + + if (strstr(debug, "dma")) + RADEON_DEBUG |= DEBUG_DMA; + + if (strstr(debug, "san")) + RADEON_DEBUG |= DEBUG_SANITY; + } + + +#endif + + if (getenv("RADEON_NO_RAST")) { + fprintf(stderr, "disabling 3D acceleration\n"); + FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1); + } + else if (getenv("RADEON_TCL_FORCE_ENABLE")) { + fprintf(stderr, "Enabling TCL support... this will probably crash\n"); + fprintf(stderr, " your card if it isn't capable of TCL!\n"); + rmesa->radeonScreen->chipset |= RADEON_CHIPSET_TCL; + } else if (getenv("RADEON_TCL_FORCE_DISABLE") || + rmesa->dri.drmMinor < 3 || + !(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)) { + rmesa->radeonScreen->chipset &= ~RADEON_CHIPSET_TCL; + fprintf(stderr, "disabling TCL support\n"); + TCL_FALLBACK(rmesa->glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1); + } + + if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) { + if (!getenv("RADEON_NO_VTXFMT")) + radeonVtxfmtInit( ctx ); + + _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); + } return GL_TRUE; } @@ -396,6 +537,7 @@ radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) /* check if we're deleting the currently bound context */ if (rmesa == current) { + RADEON_FIREVERTICES( rmesa ); _mesa_make_current2(NULL, NULL, NULL); } @@ -414,6 +556,7 @@ radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) radeonDestroyTexObj( rmesa, t ); } mmDestroy( rmesa->texture.heap[i] ); + rmesa->texture.heap[i] = NULL; } foreach_s ( t, next_t, &rmesa->texture.swapped ) { @@ -426,12 +569,27 @@ radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) _ac_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); - radeonFreeVB( rmesa->glCtx ); + radeonDestroySwtcl( rmesa->glCtx ); + + radeonReleaseArrays( rmesa->glCtx, ~0 ); + if (rmesa->dma.current.buf) { + radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); + radeonFlushCmdBuf( rmesa, __FUNCTION__ ); + } + + if (!rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) + if (!getenv("RADEON_NO_VTXFMT")) + radeonVtxfmtDestroy( rmesa->glCtx ); /* free the Mesa context */ rmesa->glCtx->DriverCtx = NULL; _mesa_destroy_context( rmesa->glCtx ); + if (rmesa->state.scissor.pClipRects) { + FREE(rmesa->state.scissor.pClipRects); + rmesa->state.scissor.pClipRects = 0; + } + FREE( rmesa ); } @@ -508,6 +666,7 @@ radeonSwapBuffers(Display *dpy, void *drawablePrivate) ctx = rmesa->glCtx; if (ctx->Visual.doubleBufferMode) { _mesa_swapbuffers( ctx ); /* flush pending rendering comands */ + if ( rmesa->doPageFlip ) { radeonPageFlip( dPriv ); } @@ -532,21 +691,14 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, __DRIdrawablePrivate *driReadPriv ) { if ( driContextPriv ) { - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr oldRadeonCtx = ctx ? RADEON_CONTEXT(ctx) : NULL; - radeonContextPtr newRadeonCtx = (radeonContextPtr) driContextPriv->driverPrivate; - - if ( newRadeonCtx != oldRadeonCtx ) { - newRadeonCtx->state.hw.dirty = RADEON_UPLOAD_CONTEXT_ALL; - if ( newRadeonCtx->state.texture.unit[0].texobj ) - newRadeonCtx->state.hw.dirty |= RADEON_UPLOAD_TEX0; - if ( newRadeonCtx->state.texture.unit[1].texobj ) - newRadeonCtx->state.hw.dirty |= RADEON_UPLOAD_TEX1; - } + radeonContextPtr newRadeonCtx = + (radeonContextPtr) driContextPriv->driverPrivate; + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newRadeonCtx->glCtx); if ( newRadeonCtx->dri.drawable != driDrawPriv ) { newRadeonCtx->dri.drawable = driDrawPriv; - newRadeonCtx->upload_cliprects = 1; radeonUpdateWindow( newRadeonCtx->glCtx ); radeonUpdateViewportOffset( newRadeonCtx->glCtx ); } @@ -559,10 +711,18 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, _mesa_set_viewport( newRadeonCtx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h ); } + + if (newRadeonCtx->vb.enabled) + radeonVtxfmtMakeCurrent( newRadeonCtx->glCtx ); + } else { + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, NULL); _mesa_make_current( 0, 0 ); } + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "End %s\n", __FUNCTION__); return GL_TRUE; } @@ -571,61 +731,30 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, static GLboolean radeonUnbindContext( __DRIcontextPrivate *driContextPriv ) { - return GL_TRUE; -} - -/* Initialize the fullscreen mode. - */ -static GLboolean -radeonOpenFullScreen( __DRIcontextPrivate *driContextPriv ) -{ -#if 0 - radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; - GLint ret; - - /* FIXME: Do we need to check this? - */ - if ( !rmesa->glCtx->Visual.doubleBufferMode ) - return GL_TRUE; - - LOCK_HARDWARE( rmesa ); - radeonWaitForIdleLocked( rmesa ); - - /* Ignore errors. If this fails, we simply don't do page flipping. - */ - ret = drmRadeonFullScreen( rmesa->driFd, GL_TRUE ); + radeonContextPtr rmesa = (radeonContextPtr) driContextPriv->driverPrivate; - UNLOCK_HARDWARE( rmesa ); + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, rmesa->glCtx); - rmesa->doPageFlip = ( ret == 0 ); -#endif + radeonVtxfmtUnbindContext( rmesa->glCtx ); return GL_TRUE; } -/* Shut down the fullscreen mode. +/* Fullscreen mode isn't used for much -- could be a way to shrink + * front/back buffers & get more texture memory if the client has + * changed the video resolution. + * + * Pageflipping is now done automatically whenever there is a single + * 3d client. */ static GLboolean -radeonCloseFullScreen( __DRIcontextPrivate *driContextPriv ) +radeonOpenCloseFullScreen( __DRIcontextPrivate *driContextPriv ) { -#if 0 - radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; - - LOCK_HARDWARE( rmesa ); - radeonWaitForIdleLocked( rmesa ); - - /* Don't care if this fails, we're not page flipping anymore. - */ - drmRadeonFullScreen( rmesa->driFd, GL_FALSE ); - - UNLOCK_HARDWARE( rmesa ); - - rmesa->doPageFlip = GL_FALSE; - rmesa->currentPage = 0; -#endif return GL_TRUE; } + /* This function is called by libGL.so as soon as libGL.so is loaded. * This is where we'd register new extension functions with the dispatcher. */ @@ -646,8 +775,8 @@ static struct __DriverAPIRec radeonAPI = { radeonSwapBuffers, radeonMakeCurrent, radeonUnbindContext, - radeonOpenFullScreen, - radeonCloseFullScreen + radeonOpenCloseFullScreen, + radeonOpenCloseFullScreen }; diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h index 736f4c654..051bbbcf5 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v 1.4 2002/09/10 00:39:39 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v 1.6 2002/12/16 16:18:58 dawes Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -31,7 +31,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keith_whitwell@yahoo.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #ifndef __RADEON_CONTEXT_H__ @@ -39,34 +39,24 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING -#include <X11/Xlibint.h> - -#include "dri_util.h" - -#include "xf86drm.h" -#include "xf86drmRadeon.h" - -#include "macros.h" -#include "mtypes.h" - -#include "radeon_reg.h" - struct radeon_context; typedef struct radeon_context radeonContextRec; typedef struct radeon_context *radeonContextPtr; +#include "mtypes.h" #include "radeon_lock.h" #include "radeon_screen.h" #include "mm.h" /* Flags for software fallback cases */ -/* See correponding strings in radeon_tris.c */ +/* See correponding strings in radeon_swtcl.c */ #define RADEON_FALLBACK_TEXTURE 0x0001 #define RADEON_FALLBACK_DRAW_BUFFER 0x0002 #define RADEON_FALLBACK_STENCIL 0x0004 #define RADEON_FALLBACK_RENDER_MODE 0x0008 #define RADEON_FALLBACK_BLEND_EQ 0x0010 #define RADEON_FALLBACK_BLEND_FUNC 0x0020 +#define RADEON_FALLBACK_DISABLE 0x0040 /* Use the templated vertex format: */ @@ -87,12 +77,9 @@ typedef void (*radeon_line_func)( radeonContextPtr, typedef void (*radeon_point_func)( radeonContextPtr, radeonVertex * ); -typedef void (*radeon_prim_func)( GLcontext *ctx ); - struct radeon_colorbuffer_state { GLuint clear; - GLint drawOffset, drawPitch; }; @@ -109,6 +96,10 @@ struct radeon_pixel_state { struct radeon_scissor_state { XF86DRIClipRectRec rect; GLboolean enabled; + + GLuint numClipRects; /* Cliprects active */ + GLuint numAllocedClipRects; /* Cliprects available */ + XF86DRIClipRectPtr pClipRects; }; struct radeon_stencilbuffer_state { @@ -122,8 +113,9 @@ struct radeon_stipple_state { -#define TEX_0 1 -#define TEX_1 2 +#define TEX_0 0x1 +#define TEX_1 0x2 +#define TEX_ALL 0x3 typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; @@ -142,7 +134,13 @@ struct radeon_tex_obj { images need to be uploaded to local or AGP texture space */ - GLint bound; /* Texture unit currently bound to */ + GLuint dirty_state; /* Flags (1 per texunit) for + whether or not this texobj + has dirty hardware state + (pp_*) that needs to be + brought into the + texunit. */ + GLint heap; /* Texture heap currently stored in */ drmRadeonTexImage image[RADEON_MAX_TEXTURE_LEVELS]; @@ -173,10 +171,253 @@ struct radeon_texture_state { struct radeon_texture_env_state unit[RADEON_MAX_TEXTURE_UNITS]; }; -struct radeon_state { - drmRadeonState hw; + +struct radeon_state_atom { + struct radeon_state_atom *next, *prev; + const char *name; /* for debug */ + int cmd_size; /* size in bytes */ + GLuint is_tcl; + int *cmd; /* one or more cmd's */ + int *lastcmd; /* one or more cmd's */ + GLboolean (*check)( GLcontext * ); /* is this state active? */ +}; + + + +/* Trying to keep these relatively short as the variables are becoming + * extravagently long. Drop the RADEON_ off the front of everything - + * I think we know we're in the radeon driver by now, and keep the + * prefix to 3 letters unless absolutely impossible. + */ + +#define CTX_CMD_0 0 +#define CTX_PP_MISC 1 +#define CTX_PP_FOG_COLOR 2 +#define CTX_RE_SOLID_COLOR 3 +#define CTX_RB3D_BLENDCNTL 4 +#define CTX_RB3D_DEPTHOFFSET 5 +#define CTX_RB3D_DEPTHPITCH 6 +#define CTX_RB3D_ZSTENCILCNTL 7 +#define CTX_CMD_1 8 +#define CTX_PP_CNTL 9 +#define CTX_RB3D_CNTL 10 +#define CTX_RB3D_COLOROFFSET 11 +#define CTX_CMD_2 12 +#define CTX_RB3D_COLORPITCH 13 +#define CTX_STATE_SIZE 14 + +#define SET_CMD_0 0 +#define SET_SE_CNTL 1 +#define SET_SE_COORDFMT 2 +#define SET_CMD_1 3 +#define SET_SE_CNTL_STATUS 4 +#define SET_STATE_SIZE 5 + +#define LIN_CMD_0 0 +#define LIN_RE_LINE_PATTERN 1 +#define LIN_RE_LINE_STATE 2 +#define LIN_CMD_1 3 +#define LIN_SE_LINE_WIDTH 4 +#define LIN_STATE_SIZE 5 + +#define MSK_CMD_0 0 +#define MSK_RB3D_STENCILREFMASK 1 +#define MSK_RB3D_ROPCNTL 2 +#define MSK_RB3D_PLANEMASK 3 +#define MSK_STATE_SIZE 4 + +#define VPT_CMD_0 0 +#define VPT_SE_VPORT_XSCALE 1 +#define VPT_SE_VPORT_XOFFSET 2 +#define VPT_SE_VPORT_YSCALE 3 +#define VPT_SE_VPORT_YOFFSET 4 +#define VPT_SE_VPORT_ZSCALE 5 +#define VPT_SE_VPORT_ZOFFSET 6 +#define VPT_STATE_SIZE 7 + +#define MSC_CMD_0 0 +#define MSC_RE_MISC 1 +#define MSC_STATE_SIZE 2 + +#define TEX_CMD_0 0 +#define TEX_PP_TXFILTER 1 +#define TEX_PP_TXFORMAT 2 +#define TEX_PP_TXOFFSET 3 +#define TEX_PP_TXCBLEND 4 +#define TEX_PP_TXABLEND 5 +#define TEX_PP_TFACTOR 6 +#define TEX_CMD_1 7 +#define TEX_PP_BORDER_COLOR 8 +#define TEX_STATE_SIZE 9 + +#define ZBS_CMD_0 0 +#define ZBS_SE_ZBIAS_FACTOR 1 +#define ZBS_SE_ZBIAS_CONSTANT 2 +#define ZBS_STATE_SIZE 3 + +#define TCL_CMD_0 0 +#define TCL_OUTPUT_VTXFMT 1 +#define TCL_OUTPUT_VTXSEL 2 +#define TCL_MATRIX_SELECT_0 3 +#define TCL_MATRIX_SELECT_1 4 +#define TCL_UCP_VERT_BLEND_CTL 5 +#define TCL_TEXTURE_PROC_CTL 6 +#define TCL_LIGHT_MODEL_CTL 7 +#define TCL_PER_LIGHT_CTL_0 8 +#define TCL_PER_LIGHT_CTL_1 9 +#define TCL_PER_LIGHT_CTL_2 10 +#define TCL_PER_LIGHT_CTL_3 11 +#define TCL_STATE_SIZE 12 + +#define MTL_CMD_0 0 +#define MTL_EMMISSIVE_RED 1 +#define MTL_EMMISSIVE_GREEN 2 +#define MTL_EMMISSIVE_BLUE 3 +#define MTL_EMMISSIVE_ALPHA 4 +#define MTL_AMBIENT_RED 5 +#define MTL_AMBIENT_GREEN 6 +#define MTL_AMBIENT_BLUE 7 +#define MTL_AMBIENT_ALPHA 8 +#define MTL_DIFFUSE_RED 9 +#define MTL_DIFFUSE_GREEN 10 +#define MTL_DIFFUSE_BLUE 11 +#define MTL_DIFFUSE_ALPHA 12 +#define MTL_SPECULAR_RED 13 +#define MTL_SPECULAR_GREEN 14 +#define MTL_SPECULAR_BLUE 15 +#define MTL_SPECULAR_ALPHA 16 +#define MTL_SHININESS 17 +#define MTL_STATE_SIZE 18 + +#define VTX_CMD_0 0 +#define VTX_SE_COORD_FMT 1 +#define VTX_STATE_SIZE 2 + +#define MAT_CMD_0 0 +#define MAT_ELT_0 1 +#define MAT_STATE_SIZE 17 + +#define GRD_CMD_0 0 +#define GRD_VERT_GUARD_CLIP_ADJ 1 +#define GRD_VERT_GUARD_DISCARD_ADJ 2 +#define GRD_HORZ_GUARD_CLIP_ADJ 3 +#define GRD_HORZ_GUARD_DISCARD_ADJ 4 +#define GRD_STATE_SIZE 5 + +/* position changes frequently when lighting in modelpos - separate + * out to new state item? + */ +#define LIT_CMD_0 0 +#define LIT_AMBIENT_RED 1 +#define LIT_AMBIENT_GREEN 2 +#define LIT_AMBIENT_BLUE 3 +#define LIT_AMBIENT_ALPHA 4 +#define LIT_DIFFUSE_RED 5 +#define LIT_DIFFUSE_GREEN 6 +#define LIT_DIFFUSE_BLUE 7 +#define LIT_DIFFUSE_ALPHA 8 +#define LIT_SPECULAR_RED 9 +#define LIT_SPECULAR_GREEN 10 +#define LIT_SPECULAR_BLUE 11 +#define LIT_SPECULAR_ALPHA 12 +#define LIT_POSITION_X 13 +#define LIT_POSITION_Y 14 +#define LIT_POSITION_Z 15 +#define LIT_POSITION_W 16 +#define LIT_DIRECTION_X 17 +#define LIT_DIRECTION_Y 18 +#define LIT_DIRECTION_Z 19 +#define LIT_DIRECTION_W 20 +#define LIT_ATTEN_CONST 21 +#define LIT_ATTEN_LINEAR 22 +#define LIT_ATTEN_QUADRATIC 23 +#define LIT_ATTEN_XXX 24 +#define LIT_CMD_1 25 +#define LIT_SPOT_DCD 26 +#define LIT_SPOT_EXPONENT 27 +#define LIT_SPOT_CUTOFF 28 +#define LIT_SPECULAR_THRESH 29 +#define LIT_RANGE_CUTOFF 30 /* ? */ +#define LIT_RANGE_ATTEN 31 /* ? */ +#define LIT_STATE_SIZE 32 + +/* Fog + */ +#define FOG_CMD_0 0 +#define FOG_R 1 +#define FOG_C 2 +#define FOG_D 3 +#define FOG_PAD 4 +#define FOG_STATE_SIZE 5 + +/* UCP + */ +#define UCP_CMD_0 0 +#define UCP_X 1 +#define UCP_Y 2 +#define UCP_Z 3 +#define UCP_W 4 +#define UCP_STATE_SIZE 5 + +/* GLT - Global ambient + */ +#define GLT_CMD_0 0 +#define GLT_RED 1 +#define GLT_GREEN 2 +#define GLT_BLUE 3 +#define GLT_ALPHA 4 +#define GLT_STATE_SIZE 5 + +/* EYE + */ +#define EYE_CMD_0 0 +#define EYE_X 1 +#define EYE_Y 2 +#define EYE_Z 3 +#define EYE_RESCALE_FACTOR 4 +#define EYE_STATE_SIZE 5 + +#define SHN_CMD_0 0 +#define SHN_SHININESS 1 +#define SHN_STATE_SIZE 2 + + + +struct radeon_hw_state { + /* All state should be on one of these lists: + */ + struct radeon_state_atom dirty; /* dirty list head placeholder */ + struct radeon_state_atom clean; /* clean list head placeholder */ + + /* Hardware state, stored as cmdbuf commands: + * -- Need to doublebuffer for + * - reviving state after loss of context + * - eliding noop statechange loops? (except line stipple count) + */ + struct radeon_state_atom ctx; + struct radeon_state_atom set; + struct radeon_state_atom lin; + struct radeon_state_atom msk; + struct radeon_state_atom vpt; + struct radeon_state_atom tcl; + struct radeon_state_atom msc; + struct radeon_state_atom tex[2]; + struct radeon_state_atom zbs; + struct radeon_state_atom mtl; + struct radeon_state_atom mat[5]; + struct radeon_state_atom lit[8]; /* includes vec, scl commands */ + struct radeon_state_atom ucp[6]; + struct radeon_state_atom eye; /* eye pos */ + struct radeon_state_atom grd; /* guard band clipping */ + struct radeon_state_atom fog; + struct radeon_state_atom glt; +}; + +struct radeon_state { + /* Derived state for internal purposes: + */ struct radeon_colorbuffer_state color; struct radeon_depthbuffer_state depth; struct radeon_pixel_state pixel; @@ -196,13 +437,40 @@ struct radeon_texture { GLint numHeaps; }; +/* Need refcounting on dma buffers: + */ +struct radeon_dma_buffer { + int refcount; /* the number of retained regions in buf */ + drmBufPtr buf; +}; + +#define GET_START(rvb) (rmesa->radeonScreen->agp_buffer_offset + \ + (rvb)->address - rmesa->dma.buf0_address + \ + (rvb)->start) + +/* A retained region, eg vertices for indexed vertices. + */ +struct radeon_dma_region { + struct radeon_dma_buffer *buf; + char *address; /* == buf->address */ + int start, end, ptr; /* offsets from start of buf */ + int aos_start; + int aos_stride; + int aos_size; +}; + struct radeon_dma { - drmBufPtr buffer; - drmBufPtr retained; - GLubyte *address; - GLuint low, high, last; - GLuint offset; + /* Active dma region. Allocations for vertices and retained + * regions come from here. Also used for emitting random vertices, + * these may be flushed by calling flush_current(); + */ + struct radeon_dma_region current; + + void (*flush)( radeonContextPtr ); + + char *buf0_address; /* start of buf[0], for index calcs */ + GLuint nr_released_bufs; /* flush after so many buffers released */ }; struct radeon_dri_mirror { @@ -215,14 +483,205 @@ struct radeon_dri_mirror { drmContext hwContext; drmLock *hwLock; int fd; + int drmMinor; }; + +#define RADEON_CMD_BUF_SZ (8*1024) + struct radeon_store { - radeonTexObjPtr texture[2][RADEON_MAX_STATES]; - drmRadeonState state[RADEON_MAX_STATES]; - drmRadeonPrim prim[RADEON_MAX_PRIMS]; GLuint statenr; GLuint primnr; + char cmd_buf[RADEON_CMD_BUF_SZ]; + int cmd_used; + int elts_start; +}; + + +/* radeon_tcl.c + */ +struct radeon_tcl_info { + GLuint vertex_format; + GLint last_offset; + GLuint hw_primitive; + + struct radeon_dma_region *aos_components[8]; + GLuint nr_aos_components; + + GLuint *Elts; + + struct radeon_dma_region indexed_verts; + struct radeon_dma_region obj; + struct radeon_dma_region rgba; + struct radeon_dma_region spec; + struct radeon_dma_region fog; + struct radeon_dma_region tex[RADEON_MAX_TEXTURE_UNITS]; + struct radeon_dma_region norm; +}; + + +/* radeon_swtcl.c + */ +struct radeon_swtcl_info { + GLuint SetupIndex; + GLuint SetupNewInputs; + GLuint RenderIndex; + GLuint vertex_size; + GLuint vertex_stride_shift; + GLuint vertex_format; + char *verts; + + /* Fallback rasterization functions + */ + radeon_point_func draw_point; + radeon_line_func draw_line; + radeon_tri_func draw_tri; + + GLuint hw_primitive; + GLenum render_primitive; + GLuint numverts; + + struct radeon_dma_region indexed_verts; +}; + + +struct radeon_ioctl { + GLuint vertex_offset; + GLuint vertex_size; +}; + + + +#define RADEON_MAX_PRIMS 64 + + +/* Want to keep a cache of these around. Each is parameterized by + * only a single value which has only a small range. Only expect a + * few, so just rescan the list each time? + */ +struct dynfn { + struct dynfn *next, *prev; + int key; + char *code; +}; + +struct dfn_lists { + struct dynfn Vertex2f; + struct dynfn Vertex2fv; + struct dynfn Vertex3f; + struct dynfn Vertex3fv; + struct dynfn Color4ub; + struct dynfn Color4ubv; + struct dynfn Color3ub; + struct dynfn Color3ubv; + struct dynfn Color4f; + struct dynfn Color4fv; + struct dynfn Color3f; + struct dynfn Color3fv; + struct dynfn SecondaryColor3ubEXT; + struct dynfn SecondaryColor3ubvEXT; + struct dynfn SecondaryColor3fEXT; + struct dynfn SecondaryColor3fvEXT; + struct dynfn Normal3f; + struct dynfn Normal3fv; + struct dynfn TexCoord2f; + struct dynfn TexCoord2fv; + struct dynfn TexCoord1f; + struct dynfn TexCoord1fv; + struct dynfn MultiTexCoord2fARB; + struct dynfn MultiTexCoord2fvARB; + struct dynfn MultiTexCoord1fARB; + struct dynfn MultiTexCoord1fvARB; +}; + +struct _vb; + +struct dfn_generators { + struct dynfn *(*Vertex2f)( GLcontext *, int ); + struct dynfn *(*Vertex2fv)( GLcontext *, int ); + struct dynfn *(*Vertex3f)( GLcontext *, int ); + struct dynfn *(*Vertex3fv)( GLcontext *, int ); + struct dynfn *(*Color4ub)( GLcontext *, int ); + struct dynfn *(*Color4ubv)( GLcontext *, int ); + struct dynfn *(*Color3ub)( GLcontext *, int ); + struct dynfn *(*Color3ubv)( GLcontext *, int ); + struct dynfn *(*Color4f)( GLcontext *, int ); + struct dynfn *(*Color4fv)( GLcontext *, int ); + struct dynfn *(*Color3f)( GLcontext *, int ); + struct dynfn *(*Color3fv)( GLcontext *, int ); + struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, int ); + struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, int ); + struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, int ); + struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, int ); + struct dynfn *(*Normal3f)( GLcontext *, int ); + struct dynfn *(*Normal3fv)( GLcontext *, int ); + struct dynfn *(*TexCoord2f)( GLcontext *, int ); + struct dynfn *(*TexCoord2fv)( GLcontext *, int ); + struct dynfn *(*TexCoord1f)( GLcontext *, int ); + struct dynfn *(*TexCoord1fv)( GLcontext *, int ); + struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, int ); + struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, int ); + struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, int ); + struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, int ); +}; + + +struct radeon_vb { + /* Keep these first: referenced from codegen templates: + */ + GLint counter, initial_counter; + GLint *dmaptr; + void (*notify)( void ); + GLint vertex_size; + + /* A maximum total of 15 elements per vertex: 3 floats for position, 3 + * floats for normal, 4 floats for color, 4 bytes for secondary color, + * 2 floats for each texture unit (4 floats total). + * + * As soon as the 3rd TMU is supported or cube maps (or 3D textures) are + * supported, this value will grow. + * + * The position data is never actually stored here, so 3 elements could be + * trimmed out of the buffer. + */ + union { float f; int i; radeon_color_t color; } vertex[15]; + + GLfloat *normalptr; + GLfloat *floatcolorptr; + radeon_color_t *colorptr; + GLfloat *floatspecptr; + radeon_color_t *specptr; + GLfloat *texcoordptr[2]; + + GLcontext *context; /* current context : Single thread only! */ +}; + +struct radeon_prim { + GLuint start; + GLuint end; + GLuint prim; +}; + +struct radeon_vbinfo { + GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ + GLuint primflags; + GLboolean enabled; /* RADEON_NO_VTXFMT//RADEON_NO_TCL env vars */ + GLboolean installed; + GLboolean fell_back; + GLboolean recheck; + GLint initial_counter; + GLint nrverts; + GLuint vertex_format; + + GLuint installed_vertex_format; + GLuint installed_color_3f_sz; + + struct radeon_prim primlist[RADEON_MAX_PRIMS]; + int nrprims; + + struct dfn_lists dfn_cache; + struct dfn_generators codegen; + GLvertexformat vtxfmt; }; @@ -233,31 +692,20 @@ struct radeon_context { /* Driver and hardware state management */ + struct radeon_hw_state hw; struct radeon_state state; /* Texture object bookkeeping */ struct radeon_texture texture; - /* Fallback rasterization functions - */ - radeon_point_func draw_point; - radeon_line_func draw_line; - radeon_tri_func draw_tri; /* Rasterization and vertex state: */ - GLuint NewGLState; + GLuint TclFallback; GLuint Fallback; - GLuint SetupIndex; - GLuint SetupNewInputs; - GLuint RenderIndex; + GLuint NewGLState; - GLuint vertex_size; - GLuint vertex_stride_shift; - GLuint vertex_format; - GLuint num_verts; - char *verts; /* Temporaries for translating away float colors: */ @@ -266,34 +714,61 @@ struct radeon_context { /* Vertex buffers */ + struct radeon_ioctl ioctl; struct radeon_dma dma; - struct radeon_store store; - GLboolean upload_cliprects; - - GLuint hw_primitive; - GLenum render_primitive; /* Page flipping */ GLuint doPageFlip; - GLuint currentPage; + + /* Busy waiting + */ + GLuint do_usleeps; + GLuint do_irqs; + GLuint irqsEmitted; + drmRadeonIrqWait iw; /* Drawable, cliprect and scissor information */ GLuint numClipRects; /* Cliprects for the draw buffer */ XF86DRIClipRectPtr pClipRects; - GLuint lastStamp; + unsigned int lastStamp; + GLboolean lost_context; + radeonScreenPtr radeonScreen; /* Screen private DRI data */ + RADEONSAREAPrivPtr sarea; /* Private SAREA data */ - /* Mirrors of some DRI state + /* TCL stuff */ - struct radeon_dri_mirror dri; + GLmatrix TexGenMatrix[RADEON_MAX_TEXTURE_UNITS]; + GLboolean recheck_texgen[RADEON_MAX_TEXTURE_UNITS]; + GLboolean TexGenNeedNormals[RADEON_MAX_TEXTURE_UNITS]; + GLuint TexMatEnabled; + GLuint TexGenEnabled; + GLmatrix tmpmat; + GLuint last_ReallyEnabled; + + /* VBI + */ + GLuint vbl_seq; - radeonScreenPtr radeonScreen; /* Screen private DRI data */ - RADEONSAREAPrivPtr sarea; /* Private SAREA data */ + /* radeon_tcl.c + */ + struct radeon_tcl_info tcl; + + /* radeon_swtcl.c + */ + struct radeon_swtcl_info swtcl; + + /* radeon_vtxfmt.c + */ + struct radeon_vbinfo vb; - GLboolean debugFallbacks; + /* Mirrors of some DRI state + */ + struct radeon_dri_mirror dri; + /* Performance counters */ GLuint boxes; /* Draw performance boxes */ @@ -322,11 +797,12 @@ static __inline GLuint radeonPackColor( GLuint cpp, } } +#define RADEON_OLD_PACKETS 1 /* ================================================================ * Debugging: */ -#define DO_DEBUG 0 +#define DO_DEBUG 1 #if DO_DEBUG extern int RADEON_DEBUG; @@ -334,14 +810,18 @@ extern int RADEON_DEBUG; #define RADEON_DEBUG 0 #endif -#define DEBUG_ALWAYS_SYNC 0x01 -#define DEBUG_VERBOSE_API 0x02 -#define DEBUG_VERBOSE_MSG 0x04 -#define DEBUG_VERBOSE_LRU 0x08 -#define DEBUG_VERBOSE_DRI 0x10 -#define DEBUG_VERBOSE_IOCTL 0x20 -#define DEBUG_VERBOSE_2D 0x40 -#define DEBUG_VERBOSE_TEXTURE 0x80 +#define DEBUG_TEXTURE 0x001 +#define DEBUG_STATE 0x002 +#define DEBUG_IOCTL 0x004 +#define DEBUG_PRIMS 0x008 +#define DEBUG_VERTS 0x010 +#define DEBUG_FALLBACKS 0x020 +#define DEBUG_VFMT 0x040 +#define DEBUG_CODEGEN 0x080 +#define DEBUG_VERBOSE 0x100 +#define DEBUG_DRI 0x200 +#define DEBUG_DMA 0x400 +#define DEBUG_SANITY 0x800 #endif #endif /* __RADEON_CONTEXT_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c index 223301ccb..9f0c5065b 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v 1.7 2002/09/16 18:05:19 eich Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v 1.11 2003/01/29 22:04:59 dawes Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -31,480 +31,704 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ #include "radeon_context.h" #include "radeon_state.h" #include "radeon_ioctl.h" +#include "radeon_tcl.h" +#include "radeon_sanity.h" + +#include "radeon_macros.h" /* for INREG() */ #include "mem.h" #include "macros.h" #include "swrast/swrast.h" +#include "simple_list.h" #define RADEON_TIMEOUT 512 +#define RADEON_IDLE_RETRY 16 + +#include <unistd.h> /* for usleep() */ + +static void do_usleep( int nr, const char *caller ) +{ + if (0) fprintf(stderr, "usleep %d in %s\n", nr, caller ); + if (1) usleep( nr ); +} +static void radeonWaitForIdle( radeonContextPtr rmesa ); /* ============================================================= - * Hardware vertex buffer handling + * Kernel command buffer handling */ -/* Get a new VB from the pool of vertex buffers in AGP space. - */ -drmBufPtr radeonGetBufferLocked( radeonContextPtr rmesa ) +static void print_state_atom( struct radeon_state_atom *state ) { - int fd = rmesa->dri.fd; - int index = 0; - int size = 0; - drmDMAReq dma; - drmBufPtr buf = NULL; - int to = 0; - int ret; + int i; - dma.context = rmesa->dri.hwContext; - dma.send_count = 0; - dma.send_list = NULL; - dma.send_sizes = NULL; - dma.flags = 0; - dma.request_count = 1; - dma.request_size = RADEON_BUFFER_SIZE; - dma.request_list = &index; - dma.request_sizes = &size; - dma.granted_count = 0; + fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); - while ( !buf && ( to++ < RADEON_TIMEOUT ) ) { - ret = drmDMA( fd, &dma ); + if (RADEON_DEBUG & DEBUG_VERBOSE) + for (i = 0 ; i < state->cmd_size ; i++) + fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); + +} + +static void radeon_emit_state_list( radeonContextPtr rmesa, + struct radeon_state_atom *list ) +{ + struct radeon_state_atom *state, *tmp; + char *dest; + + /* From Felix Kuhling: similar to some other lockups, glaxium will + * lock with what we believe to be a normal command stream, but + * sprinkling some magic waits arounds allows it to run + * uninterrupted. This has a slight effect on q3 framerates, but + * it might now be possible to remove the zbs hack, below. + * + * Felix reports that this can be narrowed down to just + * tcl,tex0,tex1 state, but that's pretty much every statechange, + * so let's just put the wait in always (unless Felix wants to + * narrow it down further...) + */ + if (1) { + drmRadeonCmdHeader *cmd; + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sizeof(*cmd), + __FUNCTION__ ); + cmd->wait.cmd_type = RADEON_CMD_WAIT; + cmd->wait.flags = RADEON_WAIT_3D; + } - if ( ret == 0 ) { - buf = &rmesa->radeonScreen->buffers->list[index]; - buf->used = 0; - /* Bump the performance counter */ - rmesa->c_vertexBuffers++; - return buf; + foreach_s( state, tmp, list ) { + if (state->check( rmesa->glCtx )) { + dest = radeonAllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__); + memcpy( dest, state->cmd, state->cmd_size * 4); + move_to_head( &(rmesa->hw.clean), state ); + if (RADEON_DEBUG & DEBUG_STATE) + print_state_atom( state ); } + else if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "skip state %s\n", state->name); } +} - if ( !buf ) { - UNLOCK_HARDWARE( rmesa ); - fprintf( stderr, "Error: Could not get new VB... exiting\n" ); - exit( -1 ); + +void radeonEmitState( radeonContextPtr rmesa ) +{ + struct radeon_state_atom *state, *tmp; + + if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* Somewhat overkill: + */ + if (rmesa->lost_context) { + if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS|DEBUG_IOCTL)) + fprintf(stderr, "%s - lost context\n", __FUNCTION__); + + foreach_s( state, tmp, &(rmesa->hw.clean) ) + move_to_tail(&(rmesa->hw.dirty), state ); + + rmesa->lost_context = 0; + } + else if (1) { + /* This is a darstardly kludge to work around a lockup that I + * haven't otherwise figured out. + */ + move_to_tail(&(rmesa->hw.dirty), &(rmesa->hw.zbs) ); } - return buf; + if (!(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)) { + foreach_s( state, tmp, &(rmesa->hw.dirty) ) { + if (state->is_tcl) { + move_to_head( &(rmesa->hw.clean), state ); + } + } + } + + radeon_emit_state_list( rmesa, &rmesa->hw.dirty ); } -static GLboolean intersect_rect( XF86DRIClipRectPtr out, - XF86DRIClipRectPtr a, - XF86DRIClipRectPtr b ) + +/* Fire a section of the retained (indexed_verts) buffer as a regular + * primtive. + */ +extern void radeonEmitVbufPrim( radeonContextPtr rmesa, + GLuint vertex_format, + GLuint primitive, + GLuint vertex_nr ) { - *out = *a; - if ( b->x1 > out->x1 ) out->x1 = b->x1; - if ( b->y1 > out->y1 ) out->y1 = b->y1; - if ( b->x2 < out->x2 ) out->x2 = b->x2; - if ( b->y2 < out->y2 ) out->y2 = b->y2; - if ( out->x1 >= out->x2 ) return GL_FALSE; - if ( out->y1 >= out->y2 ) return GL_FALSE; - return GL_TRUE; + drmRadeonCmdHeader *cmd; + + + assert(rmesa->dri.drmMinor >= 3); + assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); + + radeonEmitState( rmesa ); + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s cmd_used/4: %d\n", __FUNCTION__, + rmesa->store.cmd_used/4); + +#if RADEON_OLD_PACKETS + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 6 * sizeof(*cmd), + __FUNCTION__ ); + cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; + cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM | (3 << 16); + cmd[2].i = rmesa->ioctl.vertex_offset; + cmd[3].i = vertex_nr; + cmd[4].i = vertex_format; + cmd[5].i = (primitive | + RADEON_CP_VC_CNTL_PRIM_WALK_LIST | + RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | + RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | + (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT)); + + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s: header 0x%x offt 0x%x vfmt 0x%x vfcntl %x \n", + __FUNCTION__, + cmd[1].i, cmd[2].i, cmd[4].i, cmd[5].i); +#else + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 4 * sizeof(*cmd), + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; + cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_VBUF | (1 << 16); + cmd[2].i = vertex_format; + cmd[3].i = (primitive | + RADEON_CP_VC_CNTL_PRIM_WALK_LIST | + RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | + RADEON_CP_VC_CNTL_MAOS_ENABLE | + RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | + (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT)); + + + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s: header 0x%x vfmt 0x%x vfcntl %x \n", + __FUNCTION__, + cmd[1].i, cmd[2].i, cmd[3].i); +#endif } -static void emit_state( radeonContextPtr rmesa, - drmRadeonState *dest, - int dirty ) -{ - struct radeon_state *state = &rmesa->state; - if ( dirty & RADEON_UPLOAD_CONTEXT ) - memcpy( &dest->context, &state->hw.context, sizeof(dest->context) ); +void radeonFlushElts( radeonContextPtr rmesa ) +{ + int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start); + int dwords; +#if RADEON_OLD_PACKETS + int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 24)) / 2; +#else + int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 16)) / 2; +#endif - if ( dirty & RADEON_UPLOAD_VERTFMT ) - memcpy( &dest->vertex, &state->hw.vertex, sizeof(dest->vertex) ); + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); - if ( dirty & RADEON_UPLOAD_LINE ) - memcpy( &dest->line, &state->hw.line, sizeof(dest->line) ); + assert( rmesa->dma.flush == radeonFlushElts ); + rmesa->dma.flush = 0; - if ( dirty & RADEON_UPLOAD_BUMPMAP ) - memcpy( &dest->bumpmap, &state->hw.bumpmap, sizeof(dest->bumpmap) ); + /* Cope with odd number of elts: + */ + rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2; + dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4; + +#if RADEON_OLD_PACKETS + cmd[1] |= (dwords - 3) << 16; + cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT; +#else + cmd[1] |= (dwords - 3) << 16; + cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT; +#endif +} - if ( dirty & RADEON_UPLOAD_MASKS ) - memcpy( &dest->mask, &state->hw.mask, sizeof(dest->mask) ); - if ( dirty & RADEON_UPLOAD_VIEWPORT ) - memcpy( &dest->viewport, &state->hw.viewport, sizeof(dest->viewport) ); +GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa, + GLuint vertex_format, + GLuint primitive, + GLuint min_nr ) +{ + drmRadeonCmdHeader *cmd; + GLushort *retval; + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %d\n", __FUNCTION__, min_nr); + + assert(rmesa->dri.drmMinor >= 3); + assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); + + radeonEmitState( rmesa ); + +#if RADEON_OLD_PACKETS + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, + 24 + min_nr*2, + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; + cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM; + cmd[2].i = rmesa->ioctl.vertex_offset; + cmd[3].i = 0xffff; + cmd[4].i = vertex_format; + cmd[5].i = (primitive | + RADEON_CP_VC_CNTL_PRIM_WALK_IND | + RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | + RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE); + + retval = (GLushort *)(cmd+6); +#else + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, + 16 + min_nr*2, + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; + cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_INDX; + cmd[2].i = vertex_format; + cmd[3].i = (primitive | + RADEON_CP_VC_CNTL_PRIM_WALK_IND | + RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | + RADEON_CP_VC_CNTL_MAOS_ENABLE | + RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE); + + retval = (GLushort *)(cmd+4); +#endif - if ( dirty & RADEON_UPLOAD_SETUP ) { - memcpy( &dest->setup1, &state->hw.setup1, sizeof(dest->setup1) ); - memcpy( &dest->setup2, &state->hw.setup2, sizeof(dest->setup2) ); - } + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s: header 0x%x vfmt 0x%x prim %x \n", + __FUNCTION__, + cmd[1].i, vertex_format, primitive); - if ( dirty & RADEON_UPLOAD_MISC ) - memcpy( &dest->misc, &state->hw.misc, sizeof(dest->misc) ); + assert(!rmesa->dma.flush); + rmesa->dma.flush = radeonFlushElts; - if ( dirty & RADEON_UPLOAD_ZBIAS ) - memcpy( &dest->zbias, &state->hw.zbias, sizeof(dest->zbias) ); + rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf; - /* Assemble the texture state, combining the texture object and - * texture environment state into the hardware texture unit state. - */ - if ( dirty & RADEON_UPLOAD_TEX0 ) { - radeonTexObjPtr t0 = state->texture.unit[0].texobj; + return retval; +} - dest->texture[0].pp_txfilter = t0->pp_txfilter | state->hw.texture[0].pp_txfilter; - dest->texture[0].pp_txformat = t0->pp_txformat | RADEON_TXFORMAT_ST_ROUTE_STQ0; - dest->texture[0].pp_txoffset = t0->pp_txoffset; - dest->texture[0].pp_border_color = t0->pp_border_color; - dest->texture[0].pp_txcblend = state->hw.texture[0].pp_txcblend; - dest->texture[0].pp_txablend = state->hw.texture[0].pp_txablend; - dest->texture[0].pp_tfactor = state->hw.texture[0].pp_tfactor; - } - if ( dirty & RADEON_UPLOAD_TEX1 ) { - radeonTexObjPtr t1 = state->texture.unit[1].texobj; - dest->texture[1].pp_txfilter = t1->pp_txfilter | state->hw.texture[1].pp_txfilter; - dest->texture[1].pp_txformat = t1->pp_txformat | RADEON_TXFORMAT_ST_ROUTE_STQ1; - dest->texture[1].pp_txoffset = t1->pp_txoffset; - dest->texture[1].pp_border_color = t1->pp_border_color; - dest->texture[1].pp_txcblend = state->hw.texture[1].pp_txcblend; - dest->texture[1].pp_txablend = state->hw.texture[1].pp_txablend; - dest->texture[1].pp_tfactor = state->hw.texture[1].pp_tfactor; - } +void radeonEmitVertexAOS( radeonContextPtr rmesa, + GLuint vertex_size, + GLuint offset ) +{ +#if RADEON_OLD_PACKETS + rmesa->ioctl.vertex_size = vertex_size; + rmesa->ioctl.vertex_offset = offset; +#else + drmRadeonCmdHeader *cmd; + assert(rmesa->dri.drmMinor >= 3); + + if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL)) + fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n", + __FUNCTION__, vertex_size, offset); + + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 5 * sizeof(int), + __FUNCTION__ ); + + cmd[0].i = 0; + cmd[0].header.cmd_type = RADEON_CMD_PACKET3; + cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (2 << 16); + cmd[2].i = 1; + cmd[3].i = vertex_size | (vertex_size << 8); + cmd[4].i = offset; +#endif } + -#if 0 -static void print_values( const char *name, const void *vals, int sz ) +void radeonEmitAOS( radeonContextPtr rmesa, + struct radeon_dma_region **component, + GLuint nr, + GLuint offset ) { - const int *ivals = (const int *)vals; +#if RADEON_OLD_PACKETS + assert( nr == 1 ); + assert( component[0]->aos_size == component[0]->aos_stride ); + rmesa->ioctl.vertex_size = component[0]->aos_size; + rmesa->ioctl.vertex_offset = + (component[0]->aos_start + offset * component[0]->aos_stride * 4); +#else + drmRadeonCmdHeader *cmd; + int sz = 3 + (nr/2 * 3) + (nr & 1) * 2; int i; + int *tmp; + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(rmesa->dri.drmMinor >= 3); + + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sz * sizeof(int), + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].header.cmd_type = RADEON_CMD_PACKET3; + cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | ((sz-3) << 16); + cmd[2].i = nr; + tmp = &cmd[0].i; + cmd += 3; + + for (i = 0 ; i < nr ; i++) { + if (i & 1) { + cmd[0].i |= ((component[i]->aos_stride << 24) | + (component[i]->aos_size << 16)); + cmd[2].i = (component[i]->aos_start + + offset * component[i]->aos_stride * 4); + cmd += 3; + } + else { + cmd[0].i = ((component[i]->aos_stride << 8) | + (component[i]->aos_size << 0)); + cmd[1].i = (component[i]->aos_start + + offset * component[i]->aos_stride * 4); + } + } - for (i = 0; i < sz/4 ; i++) - fprintf(stderr, "%s %d: 0x%x\n", name, i, ivals[i]); -} + if (RADEON_DEBUG & DEBUG_VERTS) { + fprintf(stderr, "%s:\n", __FUNCTION__); + for (i = 0 ; i < sz ; i++) + fprintf(stderr, " %d: %x\n", i, tmp[i]); + } #endif -/* -static void print_state( drmRadeonState *state ) -{ - int dirty = state->dirty; +} - if ( dirty & RADEON_UPLOAD_CONTEXT ) - print_values( "CONTEXT", &state->context, sizeof(state->context) ); - if ( dirty & RADEON_UPLOAD_VERTFMT ) - print_values( "VERTFMT", &state->vertex, sizeof(state->vertex) ); +static int radeonFlushCmdBufLocked( radeonContextPtr rmesa, + const char * caller ) +{ + int ret, i; + drmRadeonCmdBuffer cmd; - if ( dirty & RADEON_UPLOAD_LINE ) - print_values( "LINE", &state->line, sizeof(state->line) ); + if (RADEON_DEBUG & DEBUG_IOCTL) { + fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - if ( dirty & RADEON_UPLOAD_BUMPMAP ) - print_values( "BUMPMAP", &state->bumpmap, sizeof(state->bumpmap) ); + if (RADEON_DEBUG & DEBUG_VERBOSE) + for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 ) + fprintf(stderr, "%d: %x\n", i/4, + *(int *)(&rmesa->store.cmd_buf[i])); + } - if ( dirty & RADEON_UPLOAD_MASKS ) - print_values( "MASKS", &state->mask, sizeof(state->mask) ); + if (RADEON_DEBUG & DEBUG_DMA) + fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__, + rmesa->dma.nr_released_bufs); - if ( dirty & RADEON_UPLOAD_VIEWPORT ) - print_values( "VIEWPORT", &state->viewport, sizeof(state->viewport) ); - if ( dirty & RADEON_UPLOAD_SETUP ) { - print_values( "SETUP", &state->setup1, sizeof(state->setup1) ); - print_values( "SETUP2", &state->setup2, sizeof(state->setup2) ); + if (RADEON_DEBUG & DEBUG_SANITY) { + if (rmesa->state.scissor.enabled) + ret = radeonSanityCmdBuffer( rmesa, + rmesa->state.scissor.numClipRects, + rmesa->state.scissor.pClipRects); + else + ret = radeonSanityCmdBuffer( rmesa, + rmesa->numClipRects, + rmesa->pClipRects); } - if ( dirty & RADEON_UPLOAD_MISC ) - print_values( "MISC", &state->misc, sizeof(state->misc) ); + cmd.bufsz = rmesa->store.cmd_used; + cmd.buf = rmesa->store.cmd_buf; - if ( dirty & RADEON_UPLOAD_ZBIAS ) - print_values( "ZBIAS", &state->zbias, sizeof(state->zbias) ); + if (rmesa->state.scissor.enabled) { + cmd.nbox = rmesa->state.scissor.numClipRects; + cmd.boxes = (drmClipRect *)rmesa->state.scissor.pClipRects; + } else { + cmd.nbox = rmesa->numClipRects; + cmd.boxes = (drmClipRect *)rmesa->pClipRects; + } - if ( dirty & RADEON_UPLOAD_TEX0 ) - print_values( "TEX0", &state->texture[0], sizeof(state->texture[0]) ); + ret = drmCommandWrite( rmesa->dri.fd, + DRM_RADEON_CMDBUF, + &cmd, sizeof(cmd) ); - if ( dirty & RADEON_UPLOAD_TEX1 ) - print_values( "TEX1", &state->texture[1], sizeof(state->texture[1]) ); + rmesa->store.primnr = 0; + rmesa->store.statenr = 0; + rmesa->store.cmd_used = 0; + rmesa->dma.nr_released_bufs = 0; + rmesa->lost_context = 1; + return ret; } -*/ -static void emit_prim( radeonContextPtr rmesa ) -{ - GLuint prim = rmesa->store.primnr++; - GLuint dirty = rmesa->state.hw.dirty; - rmesa->store.prim[prim].prim = rmesa->hw_primitive; - rmesa->store.prim[prim].start = rmesa->dma.last; - rmesa->store.prim[prim].finish = rmesa->dma.low; - rmesa->store.prim[prim].vc_format = rmesa->vertex_format; - - if (rmesa->hw_primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND) - rmesa->store.prim[prim].numverts = rmesa->dma.offset / 64; - else - rmesa->store.prim[prim].numverts = rmesa->num_verts; +/* Note: does not emit any commands to avoid recursion on + * radeonAllocCmdBuf. + */ +void radeonFlushCmdBuf( radeonContextPtr rmesa, const char *caller ) +{ + int ret; - rmesa->num_verts = 0; - rmesa->dma.last = rmesa->dma.low; + + assert (rmesa->dri.drmMinor >= 3); + LOCK_HARDWARE( rmesa ); + ret = radeonFlushCmdBufLocked( rmesa, caller ); + UNLOCK_HARDWARE( rmesa ); - /* Make sure we keep a copy of the initial state. - */ - if (prim == 0) { - dirty = RADEON_UPLOAD_CONTEXT_ALL; - if (rmesa->state.texture.unit[0].texobj) dirty |= RADEON_UPLOAD_TEX0; - if (rmesa->state.texture.unit[1].texobj) dirty |= RADEON_UPLOAD_TEX1; + if (ret) { + fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); + exit(ret); } +} - if (dirty) - { - GLuint state = rmesa->store.statenr++; - - emit_state( rmesa, &rmesa->store.state[state], dirty ); -/* fprintf(stderr, "emit state %d, dirty %x rmesa->dirty %x\n", */ -/* state, dirty, rmesa->state.hw.dirty ); */ - rmesa->store.state[state].dirty = rmesa->state.hw.dirty; /* override */ - rmesa->store.texture[0][state] = rmesa->state.texture.unit[0].texobj; - rmesa->store.texture[1][state] = rmesa->state.texture.unit[1].texobj; - rmesa->state.hw.dirty = 0; -/* print_state( &rmesa->store.state[state] ); */ - } - - rmesa->store.prim[prim].stateidx = rmesa->store.statenr - 1; - -/* fprintf(stderr, "emit_prim %d hwprim 0x%x vfmt 0x%x %d..%d %d verts stateidx %x\n", */ -/* prim, */ -/* rmesa->store.prim[prim].prim, */ -/* rmesa->store.prim[prim].vc_format, */ -/* rmesa->store.prim[prim].start, */ -/* rmesa->store.prim[prim].finish, */ -/* rmesa->store.prim[prim].numverts, */ -/* rmesa->store.prim[prim].stateidx); */ -} +/* ============================================================= + * Hardware vertex buffer handling + */ -void radeonFlushPrimsLocked( radeonContextPtr rmesa ) +void radeonRefillCurrentDmaRegion( radeonContextPtr rmesa ) { - XF86DRIClipRectPtr pbox = (XF86DRIClipRectPtr)rmesa->pClipRects; - int nbox = rmesa->numClipRects; - drmBufPtr buffer = rmesa->dma.buffer; - RADEONSAREAPrivPtr sarea = rmesa->sarea; + struct radeon_dma_buffer *dmabuf; int fd = rmesa->dri.fd; - int discard_sz = rmesa->dma.high - rmesa->dma.low < 4096; - int discard = (rmesa->dma.retained != rmesa->dma.buffer && - discard_sz); - int i; + int index = 0; + int size = 0; + drmDMAReq dma; + int ret; - if ( !nbox ) - rmesa->store.primnr = 0; - else if ( nbox >= RADEON_NR_SAREA_CLIPRECTS ) { - rmesa->upload_cliprects = 1; - for ( i = 0 ; i < rmesa->store.statenr ; i++ ) - rmesa->store.state[0].dirty |= rmesa->store.state[i].dirty; - if ( !rmesa->store.texture[0][0] ) - rmesa->store.state[0].dirty &= ~RADEON_UPLOAD_TEX0; - if ( !rmesa->store.texture[1][0] ) - rmesa->store.state[0].dirty &= ~RADEON_UPLOAD_TEX1; + if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->dma.flush) { + rmesa->dma.flush( rmesa ); } + if (rmesa->dma.current.buf) + radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); -/* fprintf(stderr, "%s: boxes: %d prims: %d states: %d vertexstore: 0x%x\n", */ -/* __FUNCTION__, */ -/* sarea->nbox, rmesa->store.primnr, rmesa->store.statenr, */ -/* rmesa->dma.low - rmesa->store.prim[0].start); */ + if (rmesa->dma.nr_released_bufs > 4) + radeonFlushCmdBuf( rmesa, __FUNCTION__ ); - if ( !rmesa->upload_cliprects || !rmesa->store.primnr ) - { - if ( nbox == 1 ) { - sarea->nbox = 0; - } else { - sarea->nbox = nbox; - } + dma.context = rmesa->dri.hwContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + dma.request_size = RADEON_BUFFER_SIZE; + dma.request_list = &index; + dma.request_sizes = &size; + dma.granted_count = 0; -/* fprintf(stderr, "case a %d boxes %d prims %d states\n", */ -/* sarea->nbox, rmesa->store.primnr, rmesa->store.statenr); */ - if (discard || rmesa->store.primnr) - drmRadeonFlushPrims( fd, - buffer->idx, - discard, - rmesa->store.statenr, - rmesa->store.state, - rmesa->store.primnr, - rmesa->store.prim); - } - else - { - for ( i = 0 ; i < nbox ; ) { - int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = sarea->boxes; - int discard_now = 0; - - /* TODO: Precalculate this intersection: - */ - if ( rmesa->state.scissor.enabled ) { - sarea->nbox = 0; - - for ( ; i < nr ; i++ ) { - *b = pbox[i]; - if ( intersect_rect( b, b, &rmesa->state.scissor.rect ) ) { - sarea->nbox++; - b++; - } - } - - /* Culled? - */ - if ( !sarea->nbox ) { - if ( nr < nbox ) continue; - rmesa->store.primnr = 0; - } - } else { - sarea->nbox = nr - i; - for ( ; i < nr ; i++) { - *b++ = pbox[i]; - } - } + LOCK_HARDWARE(rmesa); /* no need to validate */ - /* Finished with the buffer? - */ - if ( nr == nbox ) { - discard_now = discard; - } + ret = drmDMA( fd, &dma ); + + if (ret != 0) { + /* Free some up this way? + */ + if (rmesa->dma.nr_released_bufs) { + radeonFlushCmdBufLocked( rmesa, __FUNCTION__ ); + } + + if (RADEON_DEBUG & DEBUG_DMA) + fprintf(stderr, "Waiting for buffers\n"); + + radeonWaitForIdleLocked( rmesa ); + ret = drmDMA( fd, &dma ); -/* fprintf(stderr, "case a %d boxes %d prims %d states, discard: %d\n", */ -/* sarea->nbox, rmesa->store.primnr, rmesa->store.statenr, discard); */ - drmRadeonFlushPrims( fd, - buffer->idx, - discard_now, - rmesa->store.statenr, - rmesa->store.state, - rmesa->store.primnr, - rmesa->store.prim); + if ( ret != 0 ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "Error: Could not get dma buffer... exiting\n" ); + exit( -1 ); } } - if (discard_sz) { - rmesa->dma.buffer = 0; - rmesa->dma.address = 0; - rmesa->dma.low = 0; - rmesa->dma.high = 0; - } - else { - rmesa->dma.low = (rmesa->dma.low + 0x7) & ~0x7; /* alignment */ - } - rmesa->dma.last = rmesa->dma.low; - rmesa->store.primnr = 0; - rmesa->store.statenr = 0; - rmesa->upload_cliprects = 0; - rmesa->num_verts = 0; -} + UNLOCK_HARDWARE(rmesa); -void radeonFlushPrimsGetBuffer( radeonContextPtr rmesa ) -{ - if (rmesa->dma.low != rmesa->dma.last) - emit_prim( rmesa ); + if (RADEON_DEBUG & DEBUG_DMA) + fprintf(stderr, "Allocated buffer %d\n", index); - LOCK_HARDWARE(rmesa); + dmabuf = CALLOC_STRUCT( radeon_dma_buffer ); + dmabuf->buf = &rmesa->radeonScreen->buffers->list[index]; + dmabuf->refcount = 1; - if (rmesa->dma.buffer) { - rmesa->dma.low = rmesa->dma.high; /* force discard */ - rmesa->dma.last = rmesa->dma.low; - radeonFlushPrimsLocked( rmesa ); - } + rmesa->dma.current.buf = dmabuf; + rmesa->dma.current.address = dmabuf->buf->address; + rmesa->dma.current.end = dmabuf->buf->total; + rmesa->dma.current.start = 0; + rmesa->dma.current.ptr = 0; - rmesa->dma.buffer = radeonGetBufferLocked( rmesa ); - rmesa->dma.high = rmesa->dma.buffer->total; - rmesa->dma.address = (GLubyte *)rmesa->dma.buffer->address; - rmesa->dma.low = 0; - rmesa->num_verts = 0; - rmesa->dma.last = rmesa->dma.low; - UNLOCK_HARDWARE(rmesa); + rmesa->c_vertexBuffers++; } - -void radeonFlushPrims( radeonContextPtr rmesa ) +void radeonReleaseDmaRegion( radeonContextPtr rmesa, + struct radeon_dma_region *region, + const char *caller ) { - if (rmesa->dma.buffer) { - if (rmesa->dma.low != rmesa->dma.last) - emit_prim( rmesa ); + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); + + if (!region->buf) + return; - LOCK_HARDWARE( rmesa ); - radeonFlushPrimsLocked( rmesa ); - UNLOCK_HARDWARE( rmesa ); + if (rmesa->dma.flush) + rmesa->dma.flush( rmesa ); + + if (--region->buf->refcount == 0) { + drmRadeonCmdHeader *cmd; + + if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) + fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__, + region->buf->buf->idx); + + cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sizeof(*cmd), + __FUNCTION__ ); + cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD; + cmd->dma.buf_idx = region->buf->buf->idx; + FREE(region->buf); + rmesa->dma.nr_released_bufs++; } + + region->buf = 0; + region->start = 0; } -void radeonEmitPrim( radeonContextPtr rmesa ) +/* Allocates a region from rmesa->dma.current. If there isn't enough + * space in current, grab a new buffer (and discard what was left of current) + */ +void radeonAllocDmaRegion( radeonContextPtr rmesa, + struct radeon_dma_region *region, + int bytes, + int alignment ) { - ASSERT(rmesa->dma.buffer); - emit_prim( rmesa ); + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); - if (rmesa->store.primnr == RADEON_MAX_PRIMS || - rmesa->store.statenr == RADEON_MAX_STATES) { - LOCK_HARDWARE(rmesa); - radeonFlushPrimsLocked(rmesa); - UNLOCK_HARDWARE(rmesa); - } - else { - rmesa->dma.low = (rmesa->dma.low + 0x7) & ~0x7; /* alignment */ - rmesa->dma.last = rmesa->dma.low; - rmesa->num_verts = 0; - } + if (rmesa->dma.flush) + rmesa->dma.flush( rmesa ); + + if (region->buf) + radeonReleaseDmaRegion( rmesa, region, __FUNCTION__ ); + + alignment--; + rmesa->dma.current.start = rmesa->dma.current.ptr = + (rmesa->dma.current.ptr + alignment) & ~alignment; + + if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) + radeonRefillCurrentDmaRegion( rmesa ); + + region->start = rmesa->dma.current.start; + region->ptr = rmesa->dma.current.start; + region->end = rmesa->dma.current.start + bytes; + region->address = rmesa->dma.current.address; + region->buf = rmesa->dma.current.buf; + region->buf->refcount++; + + rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ + rmesa->dma.current.start = + rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7; + + if ( rmesa->dri.drmMinor < 3 ) + radeonRefillCurrentDmaRegion( rmesa ); } +void radeonAllocDmaRegionVerts( radeonContextPtr rmesa, + struct radeon_dma_region *region, + int numverts, + int vertsize, + int alignment ) +{ + radeonAllocDmaRegion( rmesa, region, vertsize * numverts, alignment ); +} /* ================================================================ - * Texture uploads + * SwapBuffers with client-side throttling */ -void radeonFireBlitLocked( radeonContextPtr rmesa, drmBufPtr buffer, - GLint offset, GLint pitch, GLint format, - GLint x, GLint y, GLint width, GLint height ) +static CARD32 radeonGetLastFrame (radeonContextPtr rmesa) { -#if 0 - GLint ret; + unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map; + int ret; + CARD32 frame; + + if (rmesa->dri.screen->drmMinor >= 4) { + drmRadeonGetParam gp; - ret = drmRadeonTextureBlit( rmesa->dri.fd, buffer->idx, - offset, pitch, format, - x, y, width, height ); + gp.param = RADEON_PARAM_LAST_FRAME; + gp.value = (int *)&frame; + ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp) ); + } + else + ret = -EINVAL; +#ifndef __alpha__ + if ( ret == -EINVAL ) { + frame = INREG( RADEON_LAST_FRAME_REG ); + ret = 0; + } +#endif if ( ret ) { - UNLOCK_HARDWARE( rmesa ); - fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret ); - exit( 1 ); + fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret ); + exit(1); } -#endif + + return frame; } +static void radeonEmitIrqLocked( radeonContextPtr rmesa ) +{ + drmRadeonIrqEmit ie; + int ret; + + ie.irq_seq = &rmesa->iw.irq_seq; + ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_IRQ_EMIT, + &ie, sizeof(ie) ); + if ( ret ) { + fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret ); + exit(1); + } +} -/* ================================================================ - * SwapBuffers with client-side throttling - */ -#define RADEON_MAX_OUTSTANDING 2 +static void radeonWaitIrq( radeonContextPtr rmesa ) +{ + int ret; + + do { + ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_IRQ_WAIT, + &rmesa->iw, sizeof(rmesa->iw) ); + } while (ret && (errno == EINTR || errno == EAGAIN)); -static void delay( void ) { -/* Prevent an optimizing compiler from removing a spin loop */ + if ( ret ) { + fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret ); + exit(1); + } } -static int radeonWaitForFrameCompletion( radeonContextPtr rmesa ) + +static void radeonWaitForFrameCompletion( radeonContextPtr rmesa ) { - unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map; RADEONSAREAPrivPtr sarea = rmesa->sarea; - CARD32 frame; - int wait = 0; - int i; - while ( 1 ) { - frame = INREG( RADEON_LAST_FRAME_REG ); - if ( sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) { - break; + if (rmesa->do_irqs) { + if (radeonGetLastFrame(rmesa) < sarea->last_frame) { + if (!rmesa->irqsEmitted) { + while (radeonGetLastFrame (rmesa) < sarea->last_frame) + ; + } + else { + UNLOCK_HARDWARE( rmesa ); + radeonWaitIrq( rmesa ); + LOCK_HARDWARE( rmesa ); + } + rmesa->irqsEmitted = 10; } - wait++; - /* Spin in place a bit so we aren't hammering the bus */ - for ( i = 0 ; i < 1024 ; i++ ) { - delay(); + + if (rmesa->irqsEmitted) { + radeonEmitIrqLocked( rmesa ); + rmesa->irqsEmitted--; + } + } + else { + while (radeonGetLastFrame (rmesa) < sarea->last_frame) { + UNLOCK_HARDWARE( rmesa ); + if (rmesa->do_usleeps) + do_usleep(1, __FUNCTION__); + LOCK_HARDWARE( rmesa ); } } - - return wait; } /* Copy the back color buffer to the front color buffer. @@ -520,26 +744,22 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv ) rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void*)rmesa->glCtx ); + if ( RADEON_DEBUG & DEBUG_IOCTL ) { + fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, rmesa->glCtx ); } RADEON_FIREVERTICES( rmesa ); LOCK_HARDWARE( rmesa ); - nbox = rmesa->dri.drawable->numClipRects; /* must be in locked region */ /* Throttle the frame rate -- only allow one pending swap buffers * request at a time. */ - if ( !radeonWaitForFrameCompletion( rmesa ) ) { - rmesa->hardwareWentIdle = 1; - } else { - rmesa->hardwareWentIdle = 0; - } + radeonWaitForFrameCompletion( rmesa ); + radeonWaitForVBlank( rmesa ); - nbox = dPriv->numClipRects; + nbox = rmesa->dri.drawable->numClipRects; /* must be in locked region */ for ( i = 0 ; i < nbox ; ) { GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); @@ -553,28 +773,16 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv ) } rmesa->sarea->nbox = n; - ret = drmRadeonSwapBuffers( rmesa->dri.fd ); + ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP ); if ( ret ) { - fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret ); + fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret ); UNLOCK_HARDWARE( rmesa ); exit( 1 ); } } UNLOCK_HARDWARE( rmesa ); - - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT_ALL ); - if ( rmesa->state.texture.unit[0].texobj ) - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - if ( rmesa->state.texture.unit[1].texobj ) - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); - - - rmesa->upload_cliprects = 1; - - /* Log the performance counters if necessary */ - radeonPerformanceCounters( rmesa ); } void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) @@ -588,61 +796,54 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "\n%s( %p ): page=%d\n\n", - __FUNCTION__, (void*)rmesa->glCtx, rmesa->currentPage ); + if ( RADEON_DEBUG & DEBUG_IOCTL ) { + fprintf(stderr, "%s %d\n", __FUNCTION__, + rmesa->sarea->pfCurrentPage ); } RADEON_FIREVERTICES( rmesa ); LOCK_HARDWARE( rmesa ); - /* Throttle the frame rate -- only allow one pending swap buffers - * request at a time. + /* Need to do this for the perf box placement: */ - if ( !radeonWaitForFrameCompletion( rmesa ) ) { - rmesa->hardwareWentIdle = 1; - } else { - rmesa->hardwareWentIdle = 0; + if (rmesa->dri.drawable->numClipRects) + { + XF86DRIClipRectPtr box = rmesa->dri.drawable->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + b[0] = box[0]; + rmesa->sarea->nbox = 1; } - /* The kernel will have been initialized to perform page flipping - * on a swapbuffers ioctl. + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. */ - ret = drmRadeonSwapBuffers( rmesa->dri.fd ); + radeonWaitForFrameCompletion( rmesa ); + radeonWaitForVBlank( rmesa ); + + ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); UNLOCK_HARDWARE( rmesa ); if ( ret ) { - fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret ); + fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); exit( 1 ); } - if ( rmesa->currentPage == 0 ) { + if ( rmesa->sarea->pfCurrentPage == 1 ) { rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; - rmesa->currentPage = 1; } else { rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; - rmesa->currentPage = 0; } - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - rmesa->state.hw.context.rb3d_coloroffset = rmesa->state.color.drawOffset; - rmesa->state.hw.context.rb3d_colorpitch = rmesa->state.color.drawPitch; - - /* Log the performance counters if necessary */ - radeonPerformanceCounters( rmesa ); + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset; + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; } -void radeonPerformanceCounters( radeonContextPtr rmesa ) -{ -} - -void radeonPerformanceBoxesLocked( radeonContextPtr rmesa ) -{ -} /* ================================================================ * Buffer clear @@ -659,25 +860,29 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all, CARD32 clear; GLuint flags = 0; GLuint color_mask = 0; -/* GLuint depth_mask = 0; */ GLint ret, i; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + if ( RADEON_DEBUG & DEBUG_IOCTL ) { fprintf( stderr, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n", __FUNCTION__, all, cx, cy, cw, ch ); } - RADEON_FIREVERTICES( rmesa ); + radeonEmitState( rmesa ); + + /* Need to cope with lostcontext here as kernel relies on + * some residual state: + */ + RADEON_FIREVERTICES( rmesa ); if ( mask & DD_FRONT_LEFT_BIT ) { flags |= RADEON_FRONT; - color_mask = rmesa->state.hw.mask.rb3d_planemask; + color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; mask &= ~DD_FRONT_LEFT_BIT; } if ( mask & DD_BACK_LEFT_BIT ) { flags |= RADEON_BACK; - color_mask = rmesa->state.hw.mask.rb3d_planemask; + color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; mask &= ~DD_BACK_LEFT_BIT; } @@ -691,107 +896,127 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all, mask &= ~DD_STENCIL_BIT; } - if ( flags ) { - /* Flip top to bottom */ - cx += dPriv->x; - cy = dPriv->y + dPriv->h - cy - ch; + if ( mask ) + _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); - LOCK_HARDWARE( rmesa ); + if ( !flags ) + return; - /* Throttle the number of clear ioctls we do. - */ - while ( 1 ) { + + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + + LOCK_HARDWARE( rmesa ); + + /* Throttle the number of clear ioctls we do. + */ + while ( 1 ) { + int ret; + + if (rmesa->dri.screen->drmMinor >= 4) { + drmRadeonGetParam gp; + + gp.param = RADEON_PARAM_LAST_CLEAR; + gp.value = (int *)&clear; + ret = drmCommandWriteRead( rmesa->dri.fd, + DRM_RADEON_GETPARAM, &gp, sizeof(gp) ); + } else + ret = -EINVAL; + +#ifndef __alpha__ + if ( ret == -EINVAL ) { clear = INREG( RADEON_LAST_CLEAR_REG ); - if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) { - break; - } - /* Spin in place a bit so we aren't hammering the bus */ - for ( i = 0 ; i < 1024 ; i++ ) { - delay(); - } + ret = 0; + } +#endif + if ( ret ) { + fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret ); + exit(1); + } + if ( RADEON_DEBUG & DEBUG_IOCTL ) { + fprintf( stderr, "%s( %d )\n", __FUNCTION__, (int)clear ); + if ( ret ) fprintf( stderr, " ( RADEON_LAST_CLEAR register read directly )\n" ); } - /* Emit any new MASKS state. This ioctl uses the old - * sarea-based state mechanism, which is why I'm not using - * emit_state() above. Time for a new ioctl? - */ - if ( rmesa->state.hw.dirty ) { - memcpy( &sarea->ContextState, &rmesa->state.hw, - sizeof(sarea->ContextState)); - sarea->dirty |= RADEON_UPLOAD_CONTEXT_ALL; + if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) { + break; } + if ( rmesa->do_usleeps ) { + UNLOCK_HARDWARE( rmesa ); + do_usleep(1, __FUNCTION__); + LOCK_HARDWARE( rmesa ); + } + } - for ( i = 0 ; i < dPriv->numClipRects ; ) { - GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects ); - XF86DRIClipRectPtr box = dPriv->pClipRects; - XF86DRIClipRectPtr b = rmesa->sarea->boxes; - GLint n = 0; - - if ( !all ) { - for ( ; i < nr ; i++ ) { - GLint x = box[i].x1; - GLint y = box[i].y1; - GLint w = box[i].x2 - x; - GLint h = box[i].y2 - y; - - if ( x < cx ) w -= cx - x, x = cx; - if ( y < cy ) h -= cy - y, y = cy; - if ( x + w > cx + cw ) w = cx + cw - x; - if ( y + h > cy + ch ) h = cy + ch - y; - if ( w <= 0 ) continue; - if ( h <= 0 ) continue; - - b->x1 = x; - b->y1 = y; - b->x2 = x + w; - b->y2 = y + h; - b++; - n++; - } - } else { - for ( ; i < nr ; i++ ) { - *b++ = box[i]; - n++; - } - } + for ( i = 0 ; i < dPriv->numClipRects ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects ); + XF86DRIClipRectPtr box = dPriv->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + drmRadeonClearType clear; + drmRadeonClearRect depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; + GLint n = 0; - rmesa->sarea->nbox = n; - -/* fprintf( stderr, */ -/* "drmRadeonClear: flag 0x%x color %x depth %x sten %x nbox %d\n", */ -/* flags, */ -/* rmesa->state.color.clear, */ -/* rmesa->state.depth.clear, */ -/* rmesa->state.stencil.clear, */ -/* rmesa->sarea->nbox ); */ - - ret = drmRadeonClear( rmesa->dri.fd, flags, - rmesa->state.color.clear, - rmesa->state.depth.clear, - rmesa->state.hw.mask.rb3d_planemask, - rmesa->state.stencil.clear, - rmesa->sarea->boxes, rmesa->sarea->nbox ); - - if ( ret ) { - UNLOCK_HARDWARE( rmesa ); - fprintf( stderr, "drmRadeonClear: return = %d\n", ret ); - exit( 1 ); + if ( !all ) { + for ( ; i < nr ; i++ ) { + GLint x = box[i].x1; + GLint y = box[i].y1; + GLint w = box[i].x2 - x; + GLint h = box[i].y2 - y; + + if ( x < cx ) w -= cx - x, x = cx; + if ( y < cy ) h -= cy - y, y = cy; + if ( x + w > cx + cw ) w = cx + cw - x; + if ( y + h > cy + ch ) h = cy + ch - y; + if ( w <= 0 ) continue; + if ( h <= 0 ) continue; + + b->x1 = x; + b->y1 = y; + b->x2 = x + w; + b->y2 = y + h; + b++; + n++; + } + } else { + for ( ; i < nr ; i++ ) { + *b++ = box[i]; + n++; } } - UNLOCK_HARDWARE( rmesa ); + rmesa->sarea->nbox = n; - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT_ALL ); - if ( rmesa->state.texture.unit[0].texobj ) - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - if ( rmesa->state.texture.unit[1].texobj ) - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); - rmesa->upload_cliprects = 1; + clear.flags = flags; + clear.clear_color = rmesa->state.color.clear; + clear.clear_depth = rmesa->state.depth.clear; + clear.color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; + clear.depth_mask = rmesa->state.stencil.clear; + clear.depth_boxes = depth_boxes; + + n--; + b = rmesa->sarea->boxes; + for ( ; n >= 0 ; n-- ) { + depth_boxes[n].f[RADEON_CLEAR_X1] = (float)b[n].x1; + depth_boxes[n].f[RADEON_CLEAR_Y1] = (float)b[n].y1; + depth_boxes[n].f[RADEON_CLEAR_X2] = (float)b[n].x2; + depth_boxes[n].f[RADEON_CLEAR_Y2] = (float)b[n].y2; + depth_boxes[n].f[RADEON_CLEAR_DEPTH] = + (float)rmesa->state.depth.clear; + } + + ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR, + &clear, sizeof(drmRadeonClearType)); + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret ); + exit( 1 ); + } } - if ( mask ) - _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); + UNLOCK_HARDWARE( rmesa ); } @@ -799,10 +1024,22 @@ void radeonWaitForIdleLocked( radeonContextPtr rmesa ) { int fd = rmesa->dri.fd; int to = 0; - int ret; + int ret, i = 0; + + rmesa->c_drawWaits++; do { - ret = drmRadeonWaitForIdleCP( fd ); + do { + ret = drmCommandNone( fd, DRM_RADEON_CP_IDLE); + } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY ); + if (ret && ret != -EBUSY) { + /* + * JO - I'm reluctant to print this message while holding the lock + * + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "%s: CP idle %d\n", __FUNCTION__, ret); + */ + } } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) ); if ( ret < 0 ) { @@ -813,32 +1050,91 @@ void radeonWaitForIdleLocked( radeonContextPtr rmesa ) } -void radeonInitIoctlFuncs( GLcontext *ctx ) +static void radeonWaitForIdle( radeonContextPtr rmesa ) { - ctx->Driver.Clear = radeonClear; + LOCK_HARDWARE(rmesa); + radeonWaitForIdleLocked( rmesa ); + UNLOCK_HARDWARE(rmesa); } +void radeonWaitForVBlank( radeonContextPtr rmesa ) +{ + drmVBlank vbl; + int ret; + + if ( !rmesa->radeonScreen->irq ) + return; + + if ( getenv("LIBGL_SYNC_REFRESH") ) { + /* Wait for at least one vertical blank since the last call */ + vbl.request.type = DRM_VBLANK_RELATIVE; + vbl.request.sequence = 1; + } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { + /* Wait for at least one vertical blank since the last call */ + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = rmesa->vbl_seq + 1; + } else { + return; + } + + UNLOCK_HARDWARE( rmesa ); + + if ((ret = drmWaitVBlank( rmesa->dri.fd, &vbl ))) { + fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" + " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" + " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); + exit(1); + } else if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s: drmWaitVBlank returned %d\n", __FUNCTION__, ret); + + rmesa->vbl_seq = vbl.reply.sequence; + + LOCK_HARDWARE( rmesa ); +} -void radeonReleaseRetainedBuffer( radeonContextPtr rmesa ) +void radeonFlush( GLcontext *ctx ) { - ASSERT(rmesa->dma.retained); + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - if (rmesa->dma.retained && - rmesa->dma.retained != rmesa->dma.buffer) { - RADEON_FIREVERTICES(rmesa); /* FIX ME: dependency tracking for retained */ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); -/* fprintf(stderr, "releaseRetained: retained %p current %p\n", */ -/* rmesa->dma.retained, rmesa->dma.buffer); */ - - LOCK_HARDWARE(rmesa); - drmRadeonFlushPrims( rmesa->dri.fd, - rmesa->dma.retained->idx, - 1, - 0, rmesa->store.state, - 0, rmesa->store.prim); - UNLOCK_HARDWARE(rmesa); + if (rmesa->dma.flush) + rmesa->dma.flush( rmesa ); + + if (rmesa->dri.drmMinor >= 3) { + if (!is_empty_list(&rmesa->hw.dirty)) + radeonEmitState( rmesa ); + + if (rmesa->store.cmd_used) + radeonFlushCmdBuf( rmesa, __FUNCTION__ ); + } +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +void radeonFinish( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonFlush( ctx ); + + if (rmesa->do_irqs) { + LOCK_HARDWARE( rmesa ); + radeonEmitIrqLocked( rmesa ); + UNLOCK_HARDWARE( rmesa ); + radeonWaitIrq( rmesa ); } + else + radeonWaitForIdle( rmesa ); +} + - rmesa->dma.retained = 0; +void radeonInitIoctlFuncs( GLcontext *ctx ) +{ + ctx->Driver.Clear = radeonClear; + ctx->Driver.Finish = radeonFinish; + ctx->Driver.Flush = radeonFlush; } + diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h index a56b39e16..8777ae278 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h,v 1.4 2002/09/16 18:05:20 eich Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h,v 1.6 2002/12/16 16:18:58 dawes Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -39,90 +39,138 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING -#include "radeon_dri.h" +#include "simple_list.h" #include "radeon_lock.h" -#include "xf86drm.h" -#include "xf86drmRadeon.h" -#define RADEON_BUFFER_MAX_DWORDS (RADEON_BUFFER_SIZE / sizeof(CARD32)) +extern void radeonEmitState( radeonContextPtr rmesa ); +extern void radeonEmitVertexAOS( radeonContextPtr rmesa, + GLuint vertex_size, + GLuint offset ); +extern void radeonEmitVbufPrim( radeonContextPtr rmesa, + GLuint vertex_format, + GLuint primitive, + GLuint vertex_nr ); + +extern void radeonFlushElts( radeonContextPtr rmesa ); + +extern GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa, + GLuint vertex_format, + GLuint primitive, + GLuint min_nr ); + +extern void radeonEmitAOS( radeonContextPtr rmesa, + struct radeon_dma_region **regions, + GLuint n, + GLuint offset ); + + + +extern void radeonFlushCmdBuf( radeonContextPtr rmesa, const char * ); +extern void radeonRefillCurrentDmaRegion( radeonContextPtr rmesa ); + +extern void radeonAllocDmaRegion( radeonContextPtr rmesa, + struct radeon_dma_region *region, + int bytes, + int alignment ); + +extern void radeonAllocDmaRegionVerts( radeonContextPtr rmesa, + struct radeon_dma_region *region, + int numverts, + int vertsize, + int alignment ); + +extern void radeonReleaseDmaRegion( radeonContextPtr rmesa, + struct radeon_dma_region *region, + const char *caller ); -extern drmBufPtr radeonGetBufferLocked( radeonContextPtr rmesa ); -extern void radeonEmitPrim( radeonContextPtr rmesa ); -extern void radeonFlushPrims( radeonContextPtr rmesa ); -extern void radeonFlushPrimsLocked( radeonContextPtr rmesa ); -extern void radeonFlushPrimsGetBuffer( radeonContextPtr rmesa ); -extern void radeonFireBlitLocked( radeonContextPtr rmesa, - drmBufPtr buffer, - GLint offset, GLint pitch, GLint format, - GLint x, GLint y, - GLint width, GLint height ); extern void radeonCopyBuffer( const __DRIdrawablePrivate *drawable ); extern void radeonPageFlip( const __DRIdrawablePrivate *drawable ); +extern void radeonFlush( GLcontext *ctx ); +extern void radeonFinish( GLcontext *ctx ); extern void radeonWaitForIdleLocked( radeonContextPtr rmesa ); -extern void radeonPerformanceCounters( radeonContextPtr rmesa ); -extern void radeonPerformanceBoxesLocked( radeonContextPtr rmesa ); +extern void radeonWaitForVBlank( radeonContextPtr rmesa ); extern void radeonInitIoctlFuncs( GLcontext *ctx ); -extern void radeonReleaseRetainedBuffer( radeonContextPtr rmesa ); +extern void radeonGetAllParams( radeonContextPtr rmesa ); + +/* radeon_compat.c: + */ +extern void radeonCompatEmitPrimitive( radeonContextPtr rmesa, + GLuint vertex_format, + GLuint hw_primitive, + GLuint nrverts ); /* ================================================================ * Helper macros: */ +/* Close off the last primitive, if it exists. + */ +#define RADEON_NEWPRIM( rmesa ) \ +do { \ + if ( rmesa->dma.flush ) \ + rmesa->dma.flush( rmesa ); \ +} while (0) + /* Can accomodate several state changes and primitive changes without * actually firing the buffer. */ -#define RADEON_STATECHANGE( rmesa, flag ) \ -do { \ - if ( 0 ) radeonPrintDirty( __FUNCTION__, flag ); \ - if ( rmesa->dma.low != rmesa->dma.last ) \ - radeonEmitPrim( rmesa ); \ - rmesa->state.hw.dirty |= flag; \ +#define RADEON_STATECHANGE( rmesa, ATOM ) \ +do { \ + RADEON_NEWPRIM( rmesa ); \ + move_to_head( &(rmesa->hw.dirty), &(rmesa->hw.ATOM)); \ } while (0) +#define RADEON_DB_STATE( ATOM ) \ + memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \ + rmesa->hw.ATOM.cmd_size * 4) + +static __inline int RADEON_DB_STATECHANGE( + radeonContextPtr rmesa, + struct radeon_state_atom *atom ) +{ + if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size*4)) { + int *tmp; + RADEON_NEWPRIM( rmesa ); + move_to_head( &(rmesa->hw.dirty), atom ); + tmp = atom->cmd; + atom->cmd = atom->lastcmd; + atom->lastcmd = tmp; + return 1; + } + else + return 0; +} + /* Fire the buffered vertices no matter what. */ -#define RADEON_FIREVERTICES( rmesa ) \ -do { \ - if ( rmesa->store.primnr || rmesa->dma.low != rmesa->dma.last ) { \ - if ( 0 ) \ - fprintf( stderr, "RADEON_FIREVERTICES in %s\n",__FUNCTION__ ); \ - radeonFlushPrims( rmesa ); \ - } \ +#define RADEON_FIREVERTICES( rmesa ) \ +do { \ + if ( rmesa->store.cmd_used || rmesa->dma.flush ) { \ + radeonFlush( rmesa->glCtx ); \ + } \ } while (0) - -static __inline void *radeonAllocDmaLow( radeonContextPtr rmesa, +/* Alloc space in the command buffer + */ +static __inline char *radeonAllocCmdBuf( radeonContextPtr rmesa, int bytes, const char *where ) { - if ( rmesa->dma.low + bytes > rmesa->dma.high ) { - if (0) fprintf( stderr, "%s flush for %d (%d/%d/%d)\n", - where, bytes, rmesa->dma.last, - rmesa->dma.low, rmesa->dma.high ); - radeonFlushPrimsGetBuffer( rmesa ); - } + if (rmesa->store.cmd_used + bytes > RADEON_CMD_BUF_SZ) + radeonFlushCmdBuf( rmesa, __FUNCTION__ ); + + assert(rmesa->dri.drmMinor >= 3); { - GLubyte *head = rmesa->dma.address + rmesa->dma.low; - if (0) fprintf( stderr, "%s: alloc %d (%d/%d/%d)\n", - where, bytes, rmesa->dma.last, - rmesa->dma.low, rmesa->dma.high ); - rmesa->dma.low += bytes; + char *head = rmesa->store.cmd_buf + rmesa->store.cmd_used; + rmesa->store.cmd_used += bytes; return head; } } -static __inline void *radeonAllocDmaHigh( radeonContextPtr rmesa, int bytes ) -{ - if ( rmesa->dma.low + bytes > rmesa->dma.high ) - radeonFlushPrimsGetBuffer( rmesa ); - - rmesa->dma.high -= bytes; - return (void *)(rmesa->dma.address + rmesa->dma.high); -} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c index 0c05f507b..7afa8ea9c 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c,v 1.4 2002/02/22 21:45:00 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c,v 1.5 2002/10/30 12:51:55 alanh Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -38,12 +38,47 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_lock.h" #include "radeon_tex.h" #include "radeon_state.h" +#include "radeon_ioctl.h" #if DEBUG_LOCKING char *prevLockFile = NULL; int prevLockLine = 0; #endif +/* Turn on/off page flipping according to the flags in the sarea: + */ +static void +radeonUpdatePageFlipping( radeonContextPtr rmesa ) +{ + int use_back; + + if (rmesa->dri.drmMinor < 3) + return; + + rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip; + + use_back = (rmesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT); + use_back ^= (rmesa->sarea->pfCurrentPage == 1); + + if ( RADEON_DEBUG & DEBUG_VERBOSE ) + fprintf(stderr, "%s allow %d current %d\n", __FUNCTION__, + rmesa->doPageFlip, + rmesa->sarea->pfCurrentPage ); + + if ( use_back ) { + rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; + rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; + } else { + rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; + rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; + } + + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset; + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; +} + + /* Update the hardware state. This is called if another context has * grabbed the hardware lock, which includes the X server. This @@ -73,6 +108,7 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags ) DRI_VALIDATE_DRAWABLE_INFO( rmesa->dri.display, sPriv, dPriv ); if ( rmesa->lastStamp != dPriv->lastStamp ) { + radeonUpdatePageFlipping( rmesa ); radeonSetCliprects( rmesa, rmesa->glCtx->Color.DriverDrawBuffer ); radeonUpdateViewportOffset( rmesa->glCtx ); rmesa->lastStamp = dPriv->lastStamp; @@ -81,24 +117,8 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags ) if ( sarea->ctxOwner != rmesa->dri.hwContext ) { sarea->ctxOwner = rmesa->dri.hwContext; - rmesa->upload_cliprects = 1; - if ( rmesa->store.statenr ) { - rmesa->store.state[0].dirty = RADEON_UPLOAD_CONTEXT_ALL; - if ( rmesa->store.texture[0][0] ) - rmesa->store.state[0].dirty |= RADEON_UPLOAD_TEX0; - if ( rmesa->store.texture[1][0] ) - rmesa->store.state[0].dirty |= RADEON_UPLOAD_TEX1; - } - else { - rmesa->state.hw.dirty = RADEON_UPLOAD_CONTEXT_ALL; - if ( rmesa->state.texture.unit[0].texobj ) - rmesa->state.hw.dirty |= RADEON_UPLOAD_TEX0; - if ( rmesa->state.texture.unit[1].texobj ) - rmesa->state.hw.dirty |= RADEON_UPLOAD_TEX1; - } - for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { - if ( sarea->texAge[i] != rmesa->texture.age[i] ) { + if ( rmesa->texture.heap[i] && sarea->texAge[i] != rmesa->texture.age[i] ) { radeonAgeTextures( rmesa, i ); } } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h index 9cb77646a..5402df83c 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h,v 1.2 2002/02/22 21:45:00 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h,v 1.3 2002/10/30 12:51:55 alanh Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -85,17 +85,18 @@ extern int prevLockLine; * do not do any drawing !!! */ + /* Lock the hardware and validate our state. */ -#define LOCK_HARDWARE( rmesa ) \ - do { \ - char __ret = 0; \ - DEBUG_CHECK_LOCK(); \ - DRM_CAS( rmesa->dri.hwLock, rmesa->dri.hwContext, \ - (DRM_LOCK_HELD | rmesa->dri.hwContext), __ret ); \ - if ( __ret ) \ - radeonGetLock( rmesa, 0 ); \ - DEBUG_LOCK(); \ +#define LOCK_HARDWARE( rmesa ) \ + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ + DRM_CAS( rmesa->dri.hwLock, rmesa->dri.hwContext, \ + (DRM_LOCK_HELD | rmesa->dri.hwContext), __ret ); \ + if ( __ret ) \ + radeonGetLock( rmesa, 0 ); \ + DEBUG_LOCK(); \ } while (0) /* Unlock the hardware. diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.c new file mode 100644 index 000000000..c62edd715 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.c @@ -0,0 +1,12 @@ + + +/* If using new packets, can choose either verts or arrays. + * Otherwise, must use verts. + */ +#include "radeon_context.h" +#define RADEON_MAOS_VERTS 1 +#if (RADEON_MAOS_VERTS) || (RADEON_OLD_PACKETS) +#include "radeon_maos_verts.c" +#else +#include "radeon_maos_arrays.c" +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.h new file mode 100644 index 000000000..f4907fe15 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.h @@ -0,0 +1,47 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_maos.h,v 1.1 2002/10/30 12:51:55 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + Tungsten Grahpics Inc., Austin, 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAHPICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#ifndef __RADEON_MAOS_H__ +#define __RADEON_MAOS_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_context.h" + +extern void radeonEmitArrays( GLcontext *ctx, GLuint inputs ); +extern void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c new file mode 100644 index 000000000..08375d673 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c @@ -0,0 +1,592 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c,v 1.1 2002/10/30 12:51:55 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "mem.h" +#include "mmath.h" +#include "macros.h" + +#include "swrast_setup/swrast_setup.h" +#include "math/m_translate.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_imm_debug.h" + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_swtcl.h" +#include "radeon_maos.h" + +/* Usage: + * - from radeon_tcl_render + * - call radeonEmitArrays to ensure uptodate arrays in dma + * - emit primitives (new type?) which reference the data + * -- need to use elts for lineloop, quads, quadstrip/flat + * -- other primitives are all well-formed (need tristrip-1,fake-poly) + * + */ +static void emit_ubyte_rgba3( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + radeon_color_t *out = (radeon_color_t *)(rvb->start + rvb->address); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p\n", + __FUNCTION__, count, stride, out); + + for (i = 0; i < count; i++) { + out->red = *data; + out->green = *(data+1); + out->blue = *(data+2); + out->alpha = 0xFF; + out++; + data += stride; + } +} + + +#if defined(USE_X86_ASM) +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ + : "0" (nr), \ + "D" ((long)dst), \ + "S" ((long)src) ); \ +} while (0) +#else +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int j; \ + for ( j = 0 ; j < nr ; j++ ) \ + dst[j] = ((int *)src)[j]; \ + dst += nr; \ +} while (0) +#endif + + + +static void emit_ubyte_rgba4( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); + + if (stride == 4) + COPY_DWORDS( out, data, count ); + else + for (i = 0; i < count; i++) { + *out++ = LE32_TO_CPU(*(int *)data); + data += stride; + } +} + + +static void emit_ubyte_rgba( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int size, + int stride, + int count ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); + + assert (!rvb->buf); + + if (stride == 0) { + radeonAllocDmaRegion( rmesa, rvb, 4, 4 ); + count = 1; + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = 0; + rvb->aos_size = 1; + } + else { + radeonAllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */ + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = 1; + rvb->aos_size = 1; + } + + /* Emit the data + */ + switch (size) { + case 3: + emit_ubyte_rgba3( ctx, rvb, data, stride, count ); + break; + case 4: + emit_ubyte_rgba4( ctx, rvb, data, stride, count ); + break; + default: + assert(0); + exit(1); + break; + } +} + + + + +static void emit_vec8( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); + + if (stride == 8) + COPY_DWORDS( out, data, count*2 ); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data+4); + out += 2; + data += stride; + } +} + +static void emit_vec12( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, out, data); + + if (stride == 12) + COPY_DWORDS( out, data, count*3 ); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data+4); + out[2] = *(int *)(data+8); + out += 3; + data += stride; + } +} + +static void emit_vec16( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); + + if (stride == 16) + COPY_DWORDS( out, data, count*4 ); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data+4); + out[2] = *(int *)(data+8); + out[3] = *(int *)(data+12); + out += 4; + data += stride; + } +} + + +static void emit_vector( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int size, + int stride, + int count ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); + + assert (!rvb->buf); + + if (stride == 0) { + radeonAllocDmaRegion( rmesa, rvb, size * 4, 4 ); + count = 1; + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = 0; + rvb->aos_size = size; + } + else { + radeonAllocDmaRegion( rmesa, rvb, size * count * 4, 4 ); /* alignment? */ + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = size; + rvb->aos_size = size; + } + + /* Emit the data + */ + switch (size) { + case 2: + emit_vec8( ctx, rvb, data, stride, count ); + break; + case 3: + emit_vec12( ctx, rvb, data, stride, count ); + break; + case 4: + emit_vec16( ctx, rvb, data, stride, count ); + break; + default: + assert(0); + exit(1); + break; + } + +} + + + +static void emit_s0_vec( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); + + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = 0; + out += 2; + data += stride; + } +} + +static void emit_stq_vec( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int stride, + int count ) +{ + int i; + int *out = (int *)(rvb->address + rvb->start); + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d\n", + __FUNCTION__, count, stride); + + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data+4); + out[2] = *(int *)(data+12); + out += 3; + data += stride; + } +} + + + + +static void emit_tex_vector( GLcontext *ctx, + struct radeon_dma_region *rvb, + char *data, + int size, + int stride, + int count ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int emitsize; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); + + assert (!rvb->buf); + + switch (size) { + case 4: emitsize = 3; break; + default: emitsize = 2; break; + } + + + if (stride == 0) { + radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize, 4 ); + count = 1; + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = 0; + rvb->aos_size = emitsize; + } + else { + radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize * count, 4 ); + rvb->aos_start = GET_START(rvb); + rvb->aos_stride = emitsize; + rvb->aos_size = emitsize; + } + + + /* Emit the data + */ + switch (size) { + case 1: + emit_s0_vec( ctx, rvb, data, stride, count ); + break; + case 2: + emit_vec8( ctx, rvb, data, stride, count ); + break; + case 3: + emit_vec8( ctx, rvb, data, stride, count ); + break; + case 4: + emit_stq_vec( ctx, rvb, data, stride, count ); + break; + default: + assert(0); + exit(1); + break; + } +} + + + + +/* Emit any changed arrays to new agp memory, re-emit a packet to + * update the arrays. + */ +void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; + struct radeon_dma_region **component = rmesa->tcl.aos_components; + GLuint nr = 0; + GLuint vfmt = 0; + GLuint count = VB->Count; + GLuint vtx; + + if (RADEON_DEBUG & DEBUG_VERTS) + _tnl_print_vert_flags( __FUNCTION__, inputs ); + + if (1) { + if (!rmesa->tcl.obj.buf) + emit_vector( ctx, + &rmesa->tcl.obj, + (char *)VB->ObjPtr->data, + VB->ObjPtr->size, + VB->ObjPtr->stride, + count); + + switch( VB->ObjPtr->size ) { + case 4: vfmt |= RADEON_CP_VC_FRMT_W0; + case 3: vfmt |= RADEON_CP_VC_FRMT_Z; + case 2: vfmt |= RADEON_CP_VC_FRMT_XY; + default: + } + component[nr++] = &rmesa->tcl.obj; + } + + + if (inputs & VERT_NORM) { + if (!rmesa->tcl.norm.buf) + emit_vector( ctx, + &(rmesa->tcl.norm), + (char *)VB->NormalPtr->data, + 3, + VB->NormalPtr->stride, + count); + + vfmt |= RADEON_CP_VC_FRMT_N0; + component[nr++] = &rmesa->tcl.norm; + } + + if (inputs & VERT_RGBA) { + if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) { + if (!rmesa->tcl.rgba.buf) + emit_ubyte_rgba( ctx, + &rmesa->tcl.rgba, + (char *)VB->ColorPtr[0]->Ptr, + VB->ColorPtr[0]->Size, + VB->ColorPtr[0]->StrideB, + count); + + vfmt |= RADEON_CP_VC_FRMT_PKCOLOR; + } + else { + int emitsize; + + if (VB->ColorPtr[0]->Size == 4 && + (VB->ColorPtr[0]->StrideB != 0 || + ((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) { + vfmt |= RADEON_CP_VC_FRMT_FPCOLOR | RADEON_CP_VC_FRMT_FPALPHA; + emitsize = 4; + } + else { + vfmt |= RADEON_CP_VC_FRMT_FPCOLOR; + emitsize = 3; + } + + + if (!rmesa->tcl.rgba.buf) + emit_vector( ctx, + &(rmesa->tcl.rgba), + (char *)VB->ColorPtr[0]->Ptr, + emitsize, + VB->ColorPtr[0]->StrideB, + count); + } + + component[nr++] = &rmesa->tcl.rgba; + } + + + if (inputs & VERT_SPEC_RGB) { + if (!rmesa->tcl.spec.buf) { + if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE) + radeon_import_float_spec_colors( ctx ); + + emit_ubyte_rgba( ctx, + &rmesa->tcl.spec, + (char *)VB->SecondaryColorPtr[0]->Ptr, + 3, + VB->SecondaryColorPtr[0]->StrideB, + count); + } + + vfmt |= RADEON_CP_VC_FRMT_PKSPEC; + component[nr++] = &rmesa->tcl.spec; + } + + vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & + ~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1)); + + if (inputs & VERT_TEX0) { + if (!rmesa->tcl.tex[0].buf) + emit_tex_vector( ctx, + &(rmesa->tcl.tex[0]), + (char *)VB->TexCoordPtr[0]->data, + VB->TexCoordPtr[0]->size, + VB->TexCoordPtr[0]->stride, + count ); + + switch( VB->TexCoordPtr[0]->size ) { + case 4: + vtx |= RADEON_TCL_VTX_Q0; + vfmt |= RADEON_CP_VC_FRMT_Q0; + default: + vfmt |= RADEON_CP_VC_FRMT_ST0; + } + component[nr++] = &rmesa->tcl.tex[0]; + } + + if (inputs & VERT_TEX1) { + if (!rmesa->tcl.tex[1].buf) + emit_tex_vector( ctx, + &(rmesa->tcl.tex[1]), + (char *)VB->TexCoordPtr[1]->data, + VB->TexCoordPtr[1]->size, + VB->TexCoordPtr[1]->stride, + count ); + + switch( VB->TexCoordPtr[1]->size ) { + case 4: + vtx |= RADEON_TCL_VTX_Q1; + vfmt |= RADEON_CP_VC_FRMT_Q1; + default: + vfmt |= RADEON_CP_VC_FRMT_ST1; + } + component[nr++] = &rmesa->tcl.tex[1]; + } + + if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) { + RADEON_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx; + } + + rmesa->tcl.nr_aos_components = nr; + rmesa->tcl.vertex_format = vfmt; +} + + +void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + + if (RADEON_DEBUG & DEBUG_VERTS) + _tnl_print_vert_flags( __FUNCTION__, newinputs ); + + if (newinputs & VERT_OBJ) + radeonReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); + + if (newinputs & VERT_NORM) + radeonReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); + + if (newinputs & VERT_RGBA) + radeonReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ ); + + if (newinputs & VERT_SPEC_RGB) + radeonReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ ); + + if (newinputs & VERT_TEX0) + radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ ); + + if (newinputs & VERT_TEX1) + radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ ); +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_vbtmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_vbtmp.h new file mode 100644 index 000000000..8ce767774 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_vbtmp.h @@ -0,0 +1,371 @@ +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 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. + * + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef LOCALVARS +#define LOCALVARS +#endif + +#undef TCL_DEBUG +#ifndef TCL_DEBUG +#define TCL_DEBUG 0 +#endif + +static void TAG(emit)( GLcontext *ctx, + GLuint start, GLuint end, + void *dest ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint (*tc0)[4], (*tc1)[4]; + GLfloat *fog; + GLuint (*tc2)[4], (*norm)[3]; + GLubyte (*col)[4], (*spec)[4]; + GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride; + GLuint tc2_stride, norm_stride; + GLuint (*coord)[4]; + GLuint coord_stride; + GLubyte dummy[4]; + int i; + + union emit_union *v = (union emit_union *)dest; + + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* The vertex code expects Obj to be clean to element 3. To fix + * this, add more vertex code (for obj-2, obj-3) or preferably move + * to maos. + */ + if (VB->ObjPtr->size < 3) { + if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 2 ); + } + + if (DO_W && VB->ObjPtr->size < 4) { + if (VB->ObjPtr->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->ObjPtr, VB->Count, 3 ); + } + + coord = (GLuint (*)[4])VB->ObjPtr->data; + coord_stride = VB->ObjPtr->stride; + + if (DO_TEX2) { + const GLuint t2 = GET_TEXSOURCE(2); + tc2 = (GLuint (*)[4])VB->TexCoordPtr[t2]->data; + tc2_stride = VB->TexCoordPtr[t2]->stride; + if (DO_PTEX && VB->TexCoordPtr[t2]->size < 4) { + if (VB->TexCoordPtr[t2]->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_TEX2, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->TexCoordPtr[t2], VB->Count, 3 ); + } + } + + if (DO_TEX1) { + if (VB->TexCoordPtr[1]) { + const GLuint t1 = GET_TEXSOURCE(1); + tc1 = (GLuint (*)[4])VB->TexCoordPtr[t1]->data; + tc1_stride = VB->TexCoordPtr[t1]->stride; + if (DO_PTEX && VB->TexCoordPtr[t1]->size < 4) { + if (VB->TexCoordPtr[t1]->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_TEX1, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->TexCoordPtr[t1], VB->Count, 3 ); + } + } else { + tc1 = (GLuint (*)[4])&ctx->Current.Texcoord[1]; /* could be anything, really */ + tc1_stride = 0; + } + } + + if (DO_TEX0) { + if (VB->TexCoordPtr[0]) { + const GLuint t0 = GET_TEXSOURCE(0); + tc0_stride = VB->TexCoordPtr[t0]->stride; + tc0 = (GLuint (*)[4])VB->TexCoordPtr[t0]->data; + if (DO_PTEX && VB->TexCoordPtr[t0]->size < 4) { + if (VB->TexCoordPtr[t0]->flags & VEC_NOT_WRITEABLE) { + VB->import_data( ctx, VERT_TEX0, VEC_NOT_WRITEABLE ); + } + _mesa_vector4f_clean_elem( VB->TexCoordPtr[t0], VB->Count, 3 ); + } + } else { + tc0 = (GLuint (*)[4])&ctx->Current.Texcoord[0]; /* could be anything, really */ + tc0_stride = 0; + } + + } + + if (DO_NORM) { + if (VB->NormalPtr) { + norm_stride = VB->NormalPtr->stride; + norm = (GLuint (*)[3])VB->NormalPtr->data; + } else { + norm_stride = 0; + norm = (GLuint (*)[3])&ctx->Current.Normal; + } + } + + if (DO_RGBA) { + if (VB->ColorPtr[0]) { + /* This is incorrect when colormaterial is enabled: + */ + if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) { + if (0) fprintf(stderr, "IMPORTING FLOAT COLORS\n"); + IMPORT_FLOAT_COLORS( ctx ); + } + col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr; + col_stride = VB->ColorPtr[0]->StrideB; + } else { + col = &dummy; /* any old memory is fine */ + col_stride = 0; + } + + } + + if (DO_SPEC) { + if (VB->SecondaryColorPtr[0]) { + if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE) + IMPORT_FLOAT_SPEC_COLORS( ctx ); + spec = (GLubyte (*)[4])VB->SecondaryColorPtr[0]->Ptr; + spec_stride = VB->SecondaryColorPtr[0]->StrideB; + } else { + spec = &dummy; + spec_stride = 0; + } + + } + + if (DO_FOG) { + if (VB->FogCoordPtr) { + fog = VB->FogCoordPtr->data; + fog_stride = VB->FogCoordPtr->stride; + } else { + fog = (GLfloat *)&dummy; *fog = 0; + fog_stride = 0; + } + + } + + + if (VB->importable_data) { + if (start) { + coord = (GLuint (*)[4])((GLubyte *)coord + start * coord_stride); + if (DO_TEX0) + tc0 = (GLuint (*)[4])((GLubyte *)tc0 + start * tc0_stride); + if (DO_TEX1) + tc1 = (GLuint (*)[4])((GLubyte *)tc1 + start * tc1_stride); + if (DO_TEX2) + tc2 = (GLuint (*)[4])((GLubyte *)tc2 + start * tc2_stride); + if (DO_NORM) + norm = (GLuint (*)[3])((GLubyte *)norm + start * norm_stride); + if (DO_RGBA) + STRIDE_4UB(col, start * col_stride); + if (DO_SPEC) + STRIDE_4UB(spec, start * spec_stride); + if (DO_FOG) + STRIDE_F(fog, start * fog_stride); + } + + for (i=start; i < end; i++) { + v[0].ui = coord[0][0]; + v[1].ui = coord[0][1]; + v[2].ui = coord[0][2]; + if (TCL_DEBUG) fprintf(stderr, "%d: %.2f %.2f %.2f ", i, v[0].f, v[1].f, v[2].f); + if (DO_W) { + v[3].ui = coord[0][3]; + if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[3].f); + v += 4; + } + else + v += 3; + coord = (GLuint (*)[4])((GLubyte *)coord + coord_stride); + + if (DO_NORM) { + v[0].ui = norm[0][0]; + v[1].ui = norm[0][1]; + v[2].ui = norm[0][2]; + if (TCL_DEBUG) fprintf(stderr, "norm: %.2f %.2f %.2f ", v[0].f, v[1].f, v[2].f); + v += 3; + norm = (GLuint (*)[3])((GLubyte *)norm + norm_stride); + } + if (DO_RGBA) { + v[0].ui = LE32_TO_CPU(*(GLuint *)&col[0]); + STRIDE_4UB(col, col_stride); + if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui); + v++; + } + if (DO_SPEC || DO_FOG) { + if (DO_SPEC) { + v[0].specular.red = spec[0][0]; + v[0].specular.green = spec[0][1]; + v[0].specular.blue = spec[0][2]; + STRIDE_4UB(spec, spec_stride); + } + if (DO_FOG) { + v[0].specular.alpha = fog[0] * 255.0; + STRIDE_F(fog, fog_stride); + } + if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui); + v++; + } + if (DO_TEX0) { + v[0].ui = tc0[0][0]; + v[1].ui = tc0[0][1]; + if (TCL_DEBUG) fprintf(stderr, "t0: %.2f %.2f ", v[0].f, v[1].f); + if (DO_PTEX) { + v[2].ui = tc0[0][3]; + if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f); + v += 3; + } + else + v += 2; + tc0 = (GLuint (*)[4])((GLubyte *)tc0 + tc0_stride); + } + if (DO_TEX1) { + v[0].ui = tc1[0][0]; + v[1].ui = tc1[0][1]; + if (TCL_DEBUG) fprintf(stderr, "t1: %.2f %.2f ", v[0].f, v[1].f); + if (DO_PTEX) { + v[2].ui = tc1[0][3]; + if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f); + v += 3; + } + else + v += 2; + tc1 = (GLuint (*)[4])((GLubyte *)tc1 + tc1_stride); + } + if (DO_TEX2) { + v[0].ui = tc2[0][0]; + v[1].ui = tc2[0][1]; + if (DO_PTEX) { + v[2].ui = tc2[0][3]; + v += 3; + } + else + v += 2; + tc2 = (GLuint (*)[4])((GLubyte *)tc2 + tc2_stride); + } + if (TCL_DEBUG) fprintf(stderr, "\n"); + } + } else { + for (i=start; i < end; i++) { + v[0].ui = coord[i][0]; + v[1].ui = coord[i][1]; + v[2].ui = coord[i][2]; + if (DO_W) { + v[3].ui = coord[i][3]; + v += 4; + } + else + v += 3; + + if (DO_NORM) { + v[0].ui = norm[i][0]; + v[1].ui = norm[i][1]; + v[2].ui = norm[i][2]; + v += 3; + } + if (DO_RGBA) { + v[0].ui = LE32_TO_CPU(*(GLuint *)&col[i]); + v++; + } + if (DO_SPEC || DO_FOG) { + if (DO_SPEC) { + v[0].specular.red = spec[i][0]; + v[0].specular.green = spec[i][1]; + v[0].specular.blue = spec[i][2]; + } + if (DO_FOG) { + v[0].specular.alpha = fog[i] * 255.0; + } + v++; + } + if (DO_TEX0) { + v[0].ui = tc0[i][0]; + v[1].ui = tc0[i][1]; + if (DO_PTEX) { + v[2].ui = tc0[i][3]; + v += 3; + } + else + v += 2; + } + if (DO_TEX1) { + v[0].ui = tc1[i][0]; + v[1].ui = tc1[i][1]; + if (DO_PTEX) { + v[2].ui = tc1[i][3]; + v += 3; + } + else + v += 2; + } + if (DO_TEX2) { + v[0].ui = tc2[i][0]; + v[1].ui = tc2[i][1]; + if (DO_PTEX) { + v[2].ui = tc2[i][3]; + v += 3; + } + else + v += 2; + } + } + } +} + + + +static void TAG(init)( void ) +{ + int sz = 3; + if (DO_W) sz++; + if (DO_NORM) sz += 3; + if (DO_RGBA) sz++; + if (DO_SPEC || DO_FOG) sz++; + if (DO_TEX0) sz += 2; + if (DO_TEX0 && DO_PTEX) sz++; + if (DO_TEX1) sz += 2; + if (DO_TEX1 && DO_PTEX) sz++; + if (DO_TEX2) sz += 2; + if (DO_TEX2 && DO_PTEX) sz++; + + setup_tab[IDX].emit = TAG(emit); + setup_tab[IDX].vertex_format = IND; + setup_tab[IDX].vertex_size = sz; +} + + +#undef IND +#undef TAG +#undef IDX diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_verts.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_verts.c new file mode 100644 index 000000000..d91375489 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_verts.c @@ -0,0 +1,336 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_maos_verts.c,v 1.1 2002/10/30 12:51:55 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc., Austin, 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_tex.h" +#include "radeon_tcl.h" +#include "radeon_swtcl.h" +#include "radeon_maos.h" + +#include "mmath.h" +#include "mtypes.h" +#include "enums.h" +#include "colormac.h" +#include "light.h" + +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_imm_debug.h" + +#define RADEON_TCL_MAX_SETUP 13 + +union emit_union { float f; GLuint ui; radeon_color_t specular; }; + +static struct { + void (*emit)( GLcontext *, GLuint, GLuint, void * ); + GLuint vertex_size; + GLuint vertex_format; +} setup_tab[RADEON_TCL_MAX_SETUP]; + +#define DO_W (IND & RADEON_CP_VC_FRMT_W0) +#define DO_RGBA (IND & RADEON_CP_VC_FRMT_PKCOLOR) +#define DO_SPEC (IND & RADEON_CP_VC_FRMT_PKSPEC) +#define DO_FOG (IND & RADEON_CP_VC_FRMT_PKSPEC) +#define DO_TEX0 (IND & RADEON_CP_VC_FRMT_ST0) +#define DO_TEX1 (IND & RADEON_CP_VC_FRMT_ST1) +#define DO_PTEX (IND & RADEON_CP_VC_FRMT_Q0) +#define DO_NORM (IND & RADEON_CP_VC_FRMT_N0) + +#define DO_TEX2 0 +#define DO_TEX3 0 + +#define GET_TEXSOURCE(n) n +#define GET_UBYTE_COLOR_STORE() &RADEON_CONTEXT(ctx)->UbyteColor +#define GET_UBYTE_SPEC_COLOR_STORE() &RADEON_CONTEXT(ctx)->UbyteSecondaryColor + +#define IMPORT_FLOAT_COLORS radeon_import_float_colors +#define IMPORT_FLOAT_SPEC_COLORS radeon_import_float_spec_colors + +/*********************************************************************** + * Generate vertex emit functions * + ***********************************************************************/ + + +/* Defined in order of increasing vertex size: + */ +#define IDX 0 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_PKCOLOR) +#define TAG(x) x##_rgba +#include "radeon_maos_vbtmp.h" + +#define IDX 1 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_N0) +#define TAG(x) x##_n +#include "radeon_maos_vbtmp.h" + +#define IDX 2 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_PKCOLOR| \ + RADEON_CP_VC_FRMT_ST0) +#define TAG(x) x##_rgba_st +#include "radeon_maos_vbtmp.h" + +#define IDX 3 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_PKCOLOR| \ + RADEON_CP_VC_FRMT_N0) +#define TAG(x) x##_rgba_n +#include "radeon_maos_vbtmp.h" + +#define IDX 4 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_ST0| \ + RADEON_CP_VC_FRMT_N0) +#define TAG(x) x##_st_n +#include "radeon_maos_vbtmp.h" + +#define IDX 5 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_PKCOLOR| \ + RADEON_CP_VC_FRMT_ST0| \ + RADEON_CP_VC_FRMT_ST1) +#define TAG(x) x##_rgba_st_st +#include "radeon_maos_vbtmp.h" + +#define IDX 6 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_PKCOLOR| \ + RADEON_CP_VC_FRMT_ST0| \ + RADEON_CP_VC_FRMT_N0) +#define TAG(x) x##_rgba_st_n +#include "radeon_maos_vbtmp.h" + +#define IDX 7 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_PKCOLOR| \ + RADEON_CP_VC_FRMT_PKSPEC| \ + RADEON_CP_VC_FRMT_ST0| \ + RADEON_CP_VC_FRMT_ST1) +#define TAG(x) x##_rgba_spec_st_st +#include "radeon_maos_vbtmp.h" + +#define IDX 8 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_ST0| \ + RADEON_CP_VC_FRMT_ST1| \ + RADEON_CP_VC_FRMT_N0) +#define TAG(x) x##_st_st_n +#include "radeon_maos_vbtmp.h" + +#define IDX 9 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_PKCOLOR| \ + RADEON_CP_VC_FRMT_PKSPEC| \ + RADEON_CP_VC_FRMT_ST0| \ + RADEON_CP_VC_FRMT_ST1| \ + RADEON_CP_VC_FRMT_N0) +#define TAG(x) x##_rgpa_spec_st_st_n +#include "radeon_maos_vbtmp.h" + +#define IDX 10 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_PKCOLOR| \ + RADEON_CP_VC_FRMT_ST0| \ + RADEON_CP_VC_FRMT_Q0) +#define TAG(x) x##_rgba_stq +#include "radeon_maos_vbtmp.h" + +#define IDX 11 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_PKCOLOR| \ + RADEON_CP_VC_FRMT_ST1| \ + RADEON_CP_VC_FRMT_Q1| \ + RADEON_CP_VC_FRMT_ST0| \ + RADEON_CP_VC_FRMT_Q0) +#define TAG(x) x##_rgba_stq_stq +#include "radeon_maos_vbtmp.h" + +#define IDX 12 +#define IND (RADEON_CP_VC_FRMT_XY| \ + RADEON_CP_VC_FRMT_Z| \ + RADEON_CP_VC_FRMT_W0| \ + RADEON_CP_VC_FRMT_PKCOLOR| \ + RADEON_CP_VC_FRMT_PKSPEC| \ + RADEON_CP_VC_FRMT_ST0| \ + RADEON_CP_VC_FRMT_Q0| \ + RADEON_CP_VC_FRMT_ST1| \ + RADEON_CP_VC_FRMT_Q1| \ + RADEON_CP_VC_FRMT_N0) +#define TAG(x) x##_w_rgpa_spec_stq_stq_n +#include "radeon_maos_vbtmp.h" + + + + + +/*********************************************************************** + * Initialization + ***********************************************************************/ + + +static void init_tcl_verts( void ) +{ + init_rgba(); + init_n(); + init_rgba_n(); + init_rgba_st(); + init_st_n(); + init_rgba_st_st(); + init_rgba_st_n(); + init_rgba_spec_st_st(); + init_st_st_n(); + init_rgpa_spec_st_st_n(); + init_rgba_stq(); + init_rgba_stq_stq(); + init_w_rgpa_spec_stq_stq_n(); +} + + +void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint req = 0; + GLuint vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] & + ~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1)); + int i; + static int firsttime = 1; + + if (firsttime) { + init_tcl_verts(); + firsttime = 0; + } + + if (1) { + req |= RADEON_CP_VC_FRMT_Z; + if (VB->ObjPtr->size == 4) { + req |= RADEON_CP_VC_FRMT_W0; + } + } + + if (inputs & VERT_NORM) { + req |= RADEON_CP_VC_FRMT_N0; + } + + if (inputs & VERT_RGBA) { + req |= RADEON_CP_VC_FRMT_PKCOLOR; + } + + if (inputs & VERT_SPEC_RGB) { + req |= RADEON_CP_VC_FRMT_PKSPEC; + } + + if (inputs & VERT_TEX0) { + req |= RADEON_CP_VC_FRMT_ST0; + + if (VB->TexCoordPtr[0]->size == 4) { + req |= RADEON_CP_VC_FRMT_Q0; + vtx |= RADEON_TCL_VTX_Q0; + } + } + + if (inputs & VERT_TEX1) { + req |= RADEON_CP_VC_FRMT_ST1; + + if (VB->TexCoordPtr[1]->size == 4) { + req |= RADEON_CP_VC_FRMT_Q1; + vtx |= RADEON_TCL_VTX_Q1; + } + } + + if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) { + RADEON_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx; + } + + for (i = 0 ; i < RADEON_TCL_MAX_SETUP ; i++) + if ((setup_tab[i].vertex_format & req) == req) + break; + + if (rmesa->tcl.vertex_format == setup_tab[i].vertex_format && + rmesa->tcl.indexed_verts.buf) + return; + + if (rmesa->tcl.indexed_verts.buf) + radeonReleaseArrays( ctx, ~0 ); + + radeonAllocDmaRegionVerts( rmesa, + &rmesa->tcl.indexed_verts, + VB->Count, + setup_tab[i].vertex_size * 4, + 4); + + setup_tab[i].emit( ctx, 0, VB->Count, + rmesa->tcl.indexed_verts.address + + rmesa->tcl.indexed_verts.start ); + + rmesa->tcl.vertex_format = setup_tab[i].vertex_format; + rmesa->tcl.indexed_verts.aos_start = GET_START( &rmesa->tcl.indexed_verts ); + rmesa->tcl.indexed_verts.aos_size = setup_tab[i].vertex_size; + rmesa->tcl.indexed_verts.aos_stride = setup_tab[i].vertex_size; + + rmesa->tcl.aos_components[0] = &rmesa->tcl.indexed_verts; + rmesa->tcl.nr_aos_components = 1; +} + + + +void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + + if (RADEON_DEBUG & DEBUG_VERTS) + _tnl_print_vert_flags( __FUNCTION__, newinputs ); + + if (newinputs) + radeonReleaseDmaRegion( rmesa, &rmesa->tcl.indexed_verts, __FUNCTION__ ); +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c new file mode 100644 index 000000000..51c1d45c5 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c @@ -0,0 +1,979 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c,v 1.1 2002/10/30 12:51:55 alanh Exp $ */ +/************************************************************************** + +Copyright 2002 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc, Cedar Park, TX. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_sanity.h" + +/* Set this '1' to get more verbiage. + */ +#define MORE_VERBOSE 1 + +#if MORE_VERBOSE +#define VERBOSE (RADEON_DEBUG & DEBUG_VERBOSE) +#define NORMAL (1) +#else +#define VERBOSE 0 +#define NORMAL (RADEON_DEBUG & DEBUG_VERBOSE) +#endif + + +/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in + * 1.3 cmdbuffers allow all previous state to be updated as well as + * the tcl scalar and vector areas. + */ +static struct { + int start; + int len; + const char *name; +} packet[RADEON_MAX_STATE_PACKETS] = { + { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, + { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, + { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, + { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, + { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, + { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, + { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, + { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, + { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, + { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, + { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, + { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, + { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, + { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, + { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, + { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, + { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, + { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, + { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, + { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, +}; + +struct reg_names { + int idx; + const char *name; +}; + +static struct reg_names reg_names[] = { + { RADEON_PP_MISC, "RADEON_PP_MISC" }, + { RADEON_PP_FOG_COLOR, "RADEON_PP_FOG_COLOR" }, + { RADEON_RE_SOLID_COLOR, "RADEON_RE_SOLID_COLOR" }, + { RADEON_RB3D_BLENDCNTL, "RADEON_RB3D_BLENDCNTL" }, + { RADEON_RB3D_DEPTHOFFSET, "RADEON_RB3D_DEPTHOFFSET" }, + { RADEON_RB3D_DEPTHPITCH, "RADEON_RB3D_DEPTHPITCH" }, + { RADEON_RB3D_ZSTENCILCNTL, "RADEON_RB3D_ZSTENCILCNTL" }, + { RADEON_PP_CNTL, "RADEON_PP_CNTL" }, + { RADEON_RB3D_CNTL, "RADEON_RB3D_CNTL" }, + { RADEON_RB3D_COLOROFFSET, "RADEON_RB3D_COLOROFFSET" }, + { RADEON_RB3D_COLORPITCH, "RADEON_RB3D_COLORPITCH" }, + { RADEON_SE_CNTL, "RADEON_SE_CNTL" }, + { RADEON_SE_COORD_FMT, "RADEON_SE_COORDFMT" }, + { RADEON_SE_CNTL_STATUS, "RADEON_SE_CNTL_STATUS" }, + { RADEON_RE_LINE_PATTERN, "RADEON_RE_LINE_PATTERN" }, + { RADEON_RE_LINE_STATE, "RADEON_RE_LINE_STATE" }, + { RADEON_SE_LINE_WIDTH, "RADEON_SE_LINE_WIDTH" }, + { RADEON_RB3D_STENCILREFMASK, "RADEON_RB3D_STENCILREFMASK" }, + { RADEON_RB3D_ROPCNTL, "RADEON_RB3D_ROPCNTL" }, + { RADEON_RB3D_PLANEMASK, "RADEON_RB3D_PLANEMASK" }, + { RADEON_SE_VPORT_XSCALE, "RADEON_SE_VPORT_XSCALE" }, + { RADEON_SE_VPORT_XOFFSET, "RADEON_SE_VPORT_XOFFSET" }, + { RADEON_SE_VPORT_YSCALE, "RADEON_SE_VPORT_YSCALE" }, + { RADEON_SE_VPORT_YOFFSET, "RADEON_SE_VPORT_YOFFSET" }, + { RADEON_SE_VPORT_ZSCALE, "RADEON_SE_VPORT_ZSCALE" }, + { RADEON_SE_VPORT_ZOFFSET, "RADEON_SE_VPORT_ZOFFSET" }, + { RADEON_RE_MISC, "RADEON_RE_MISC" }, + { RADEON_PP_TXFILTER_0, "RADEON_PP_TXFILTER_0" }, + { RADEON_PP_TXFILTER_1, "RADEON_PP_TXFILTER_1" }, + { RADEON_PP_TXFILTER_2, "RADEON_PP_TXFILTER_2" }, + { RADEON_PP_TXFORMAT_0, "RADEON_PP_TXFORMAT_0" }, + { RADEON_PP_TXFORMAT_1, "RADEON_PP_TXFORMAT_1" }, + { RADEON_PP_TXFORMAT_2, "RADEON_PP_TXFORMAT_3" }, + { RADEON_PP_TXOFFSET_0, "RADEON_PP_TXOFFSET_0" }, + { RADEON_PP_TXOFFSET_1, "RADEON_PP_TXOFFSET_1" }, + { RADEON_PP_TXOFFSET_2, "RADEON_PP_TXOFFSET_3" }, + { RADEON_PP_TXCBLEND_0, "RADEON_PP_TXCBLEND_0" }, + { RADEON_PP_TXCBLEND_1, "RADEON_PP_TXCBLEND_1" }, + { RADEON_PP_TXCBLEND_2, "RADEON_PP_TXCBLEND_3" }, + { RADEON_PP_TXABLEND_0, "RADEON_PP_TXABLEND_0" }, + { RADEON_PP_TXABLEND_1, "RADEON_PP_TXABLEND_1" }, + { RADEON_PP_TXABLEND_2, "RADEON_PP_TXABLEND_3" }, + { RADEON_PP_TFACTOR_0, "RADEON_PP_TFACTOR_0" }, + { RADEON_PP_TFACTOR_1, "RADEON_PP_TFACTOR_1" }, + { RADEON_PP_TFACTOR_2, "RADEON_PP_TFACTOR_3" }, + { RADEON_PP_BORDER_COLOR_0, "RADEON_PP_BORDER_COLOR_0" }, + { RADEON_PP_BORDER_COLOR_1, "RADEON_PP_BORDER_COLOR_1" }, + { RADEON_PP_BORDER_COLOR_2, "RADEON_PP_BORDER_COLOR_3" }, + { RADEON_SE_ZBIAS_FACTOR, "RADEON_SE_ZBIAS_FACTOR" }, + { RADEON_SE_ZBIAS_CONSTANT, "RADEON_SE_ZBIAS_CONSTANT" }, + { RADEON_SE_TCL_OUTPUT_VTX_FMT, "RADEON_SE_TCL_OUTPUT_VTXFMT" }, + { RADEON_SE_TCL_OUTPUT_VTX_SEL, "RADEON_SE_TCL_OUTPUT_VTXSEL" }, + { RADEON_SE_TCL_MATRIX_SELECT_0, "RADEON_SE_TCL_MATRIX_SELECT_0" }, + { RADEON_SE_TCL_MATRIX_SELECT_1, "RADEON_SE_TCL_MATRIX_SELECT_1" }, + { RADEON_SE_TCL_UCP_VERT_BLEND_CTL, "RADEON_SE_TCL_UCP_VERT_BLEND_CTL" }, + { RADEON_SE_TCL_TEXTURE_PROC_CTL, "RADEON_SE_TCL_TEXTURE_PROC_CTL" }, + { RADEON_SE_TCL_LIGHT_MODEL_CTL, "RADEON_SE_TCL_LIGHT_MODEL_CTL" }, + { RADEON_SE_TCL_PER_LIGHT_CTL_0, "RADEON_SE_TCL_PER_LIGHT_CTL_0" }, + { RADEON_SE_TCL_PER_LIGHT_CTL_1, "RADEON_SE_TCL_PER_LIGHT_CTL_1" }, + { RADEON_SE_TCL_PER_LIGHT_CTL_2, "RADEON_SE_TCL_PER_LIGHT_CTL_2" }, + { RADEON_SE_TCL_PER_LIGHT_CTL_3, "RADEON_SE_TCL_PER_LIGHT_CTL_3" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, "RADEON_SE_TCL_EMMISSIVE_RED" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN, "RADEON_SE_TCL_EMMISSIVE_GREEN" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE, "RADEON_SE_TCL_EMMISSIVE_BLUE" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA, "RADEON_SE_TCL_EMMISSIVE_ALPHA" }, + { RADEON_SE_TCL_MATERIAL_AMBIENT_RED, "RADEON_SE_TCL_AMBIENT_RED" }, + { RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN, "RADEON_SE_TCL_AMBIENT_GREEN" }, + { RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE, "RADEON_SE_TCL_AMBIENT_BLUE" }, + { RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA, "RADEON_SE_TCL_AMBIENT_ALPHA" }, + { RADEON_SE_TCL_MATERIAL_DIFFUSE_RED, "RADEON_SE_TCL_DIFFUSE_RED" }, + { RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN, "RADEON_SE_TCL_DIFFUSE_GREEN" }, + { RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE, "RADEON_SE_TCL_DIFFUSE_BLUE" }, + { RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA, "RADEON_SE_TCL_DIFFUSE_ALPHA" }, + { RADEON_SE_TCL_MATERIAL_SPECULAR_RED, "RADEON_SE_TCL_SPECULAR_RED" }, + { RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN, "RADEON_SE_TCL_SPECULAR_GREEN" }, + { RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE, "RADEON_SE_TCL_SPECULAR_BLUE" }, + { RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA, "RADEON_SE_TCL_SPECULAR_ALPHA" }, + { RADEON_SE_TCL_SHININESS, "RADEON_SE_TCL_SHININESS" }, + { RADEON_SE_COORD_FMT, "RADEON_SE_COORD_FMT" } +}; + +static struct reg_names scalar_names[] = { + { RADEON_SS_LIGHT_DCD_ADDR, "LIGHT_DCD" }, + { RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR, "LIGHT_SPOT_EXPONENT" }, + { RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR, "LIGHT_SPOT_CUTOFF" }, + { RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR, "LIGHT_SPECULAR_THRESH" }, + { RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR, "LIGHT_RANGE_CUTOFF" }, + { RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR, "VERT_GUARD_CLIP" }, + { RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR, "VERT_GUARD_DISCARD" }, + { RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR, "HORZ_GUARD_CLIP" }, + { RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR, "HORZ_GUARD_DISCARD" }, + { RADEON_SS_SHININESS, "SHININESS" }, + { 1000, "" }, +}; + +/* Puff these out to make them look like normal (dword) registers. + */ +static struct reg_names vector_names[] = { + { RADEON_VS_MATRIX_0_ADDR * 4, "MATRIX_0" }, + { RADEON_VS_MATRIX_1_ADDR * 4, "MATRIX_1" }, + { RADEON_VS_MATRIX_2_ADDR * 4, "MATRIX_2" }, + { RADEON_VS_MATRIX_3_ADDR * 4, "MATRIX_3" }, + { RADEON_VS_MATRIX_4_ADDR * 4, "MATRIX_4" }, + { RADEON_VS_MATRIX_5_ADDR * 4, "MATRIX_5" }, + { RADEON_VS_MATRIX_6_ADDR * 4, "MATRIX_6" }, + { RADEON_VS_MATRIX_7_ADDR * 4, "MATRIX_7" }, + { RADEON_VS_MATRIX_8_ADDR * 4, "MATRIX_8" }, + { RADEON_VS_MATRIX_9_ADDR * 4, "MATRIX_9" }, + { RADEON_VS_MATRIX_10_ADDR * 4, "MATRIX_10" }, + { RADEON_VS_MATRIX_11_ADDR * 4, "MATRIX_11" }, + { RADEON_VS_MATRIX_12_ADDR * 4, "MATRIX_12" }, + { RADEON_VS_MATRIX_13_ADDR * 4, "MATRIX_13" }, + { RADEON_VS_MATRIX_14_ADDR * 4, "MATRIX_14" }, + { RADEON_VS_MATRIX_15_ADDR * 4, "MATRIX_15" }, + { RADEON_VS_LIGHT_AMBIENT_ADDR * 4, "LIGHT_AMBIENT" }, + { RADEON_VS_LIGHT_DIFFUSE_ADDR * 4, "LIGHT_DIFFUSE" }, + { RADEON_VS_LIGHT_SPECULAR_ADDR * 4, "LIGHT_SPECULAR" }, + { RADEON_VS_LIGHT_DIRPOS_ADDR * 4, "LIGHT_DIRPOS" }, + { RADEON_VS_LIGHT_HWVSPOT_ADDR * 4, "LIGHT_HWVSPOT" }, + { RADEON_VS_LIGHT_ATTENUATION_ADDR * 4, "LIGHT_ATTENUATION" }, + { RADEON_VS_MATRIX_EYE2CLIP_ADDR * 4, "MATRIX_EYE2CLIP" }, + { RADEON_VS_UCP_ADDR * 4, "UCP" }, + { RADEON_VS_GLOBAL_AMBIENT_ADDR * 4, "GLOBAL_AMBIENT" }, + { RADEON_VS_FOG_PARAM_ADDR * 4, "FOG_PARAM" }, + { RADEON_VS_EYE_VECTOR_ADDR * 4, "EYE_VECTOR" }, + { 1000, "" }, +}; + +union fi { float f; int i; }; + +#define ISVEC 1 +#define ISFLOAT 2 +#define TOUCHED 4 + +struct reg { + int idx; + struct reg_names *closest; + int flags; + union fi current; + union fi *values; + int nvalues; + int nalloc; + float vmin, vmax; +}; + + +static struct reg regs[Elements(reg_names)+1]; +static struct reg scalars[512+1]; +static struct reg vectors[512*4+1]; + +static int total, total_changed, bufs; + +static void init_regs( void ) +{ + struct reg_names *tmp; + int i; + + for (i = 0 ; i < Elements(regs) ; i++) { + regs[i].idx = reg_names[i].idx; + regs[i].closest = ®_names[i]; + regs[i].flags = 0; + } + + for (i = 0, tmp = scalar_names ; i < Elements(scalars) ; i++) { + if (tmp[1].idx == i) tmp++; + scalars[i].idx = i; + scalars[i].closest = tmp; + scalars[i].flags = ISFLOAT; + } + + for (i = 0, tmp = vector_names ; i < Elements(vectors) ; i++) { + if (tmp[1].idx*4 == i) tmp++; + vectors[i].idx = i; + vectors[i].closest = tmp; + vectors[i].flags = ISFLOAT|ISVEC; + } + + regs[Elements(regs)-1].idx = -1; + scalars[Elements(scalars)-1].idx = -1; + vectors[Elements(vectors)-1].idx = -1; +} + +static int find_or_add_value( struct reg *reg, int val ) +{ + int j; + + for ( j = 0 ; j < reg->nvalues ; j++) + if ( val == reg->values[j].i ) + return 1; + + if (j == reg->nalloc) { + reg->nalloc += 5; + reg->nalloc *= 2; + reg->values = (union fi *) realloc( reg->values, + reg->nalloc * sizeof(union fi) ); + } + + reg->values[reg->nvalues++].i = val; + return 0; +} + +static struct reg *lookup_reg( struct reg *tab, int reg ) +{ + int i; + + for (i = 0 ; tab[i].idx != -1 ; i++) { + if (tab[i].idx == reg) + return &tab[i]; + } + + fprintf(stderr, "*** unknown reg 0x%x\n", reg); + return 0; +} + + +static const char *get_reg_name( struct reg *reg ) +{ + static char tmp[80]; + + if (reg->idx == reg->closest->idx) + return reg->closest->name; + + + if (reg->flags & ISVEC) { + if (reg->idx/4 != reg->closest->idx) + sprintf(tmp, "%s+%d[%d]", + reg->closest->name, + (reg->idx/4) - reg->closest->idx, + reg->idx%4); + else + sprintf(tmp, "%s[%d]", reg->closest->name, reg->idx%4); + } + else { + if (reg->idx != reg->closest->idx) + sprintf(tmp, "%s+%d", reg->closest->name, reg->idx - reg->closest->idx); + else + sprintf(tmp, "%s", reg->closest->name); + } + + return tmp; +} + +static int print_int_reg_assignment( struct reg *reg, int data ) +{ + int changed = (reg->current.i != data); + int ever_seen = find_or_add_value( reg, data ); + + if (VERBOSE || (NORMAL && (changed || !ever_seen))) + fprintf(stderr, " %s <-- 0x%x", get_reg_name(reg), data); + + if (NORMAL) { + if (!ever_seen) + fprintf(stderr, " *** BRAND NEW VALUE"); + else if (changed) + fprintf(stderr, " *** CHANGED"); + } + + reg->current.i = data; + + if (VERBOSE || (NORMAL && (changed || !ever_seen))) + fprintf(stderr, "\n"); + + return changed; +} + + +static int print_float_reg_assignment( struct reg *reg, float data ) +{ + int changed = (reg->current.f != data); + int newmin = (data < reg->vmin); + int newmax = (data > reg->vmax); + + if (VERBOSE || (NORMAL && (newmin || newmax || changed))) + fprintf(stderr, " %s <-- %.3f", get_reg_name(reg), data); + + if (NORMAL) { + if (newmin) { + fprintf(stderr, " *** NEW MIN (prev %.3f)", reg->vmin); + reg->vmin = data; + } + else if (newmax) { + fprintf(stderr, " *** NEW MAX (prev %.3f)", reg->vmax); + reg->vmax = data; + } + else if (changed) { + fprintf(stderr, " *** CHANGED"); + } + } + + reg->current.f = data; + + if (VERBOSE || (NORMAL && (newmin || newmax || changed))) + fprintf(stderr, "\n"); + + return changed; +} + +static int print_reg_assignment( struct reg *reg, int data ) +{ + reg->flags |= TOUCHED; + if (reg->flags & ISFLOAT) + return print_float_reg_assignment( reg, *(float *)&data ); + else + return print_int_reg_assignment( reg, data ); +} + +static void print_reg( struct reg *reg ) +{ + if (reg->flags & TOUCHED) { + if (reg->flags & ISFLOAT) { + fprintf(stderr, " %s == %f\n", get_reg_name(reg), reg->current.f); + } else { + fprintf(stderr, " %s == 0x%x\n", get_reg_name(reg), reg->current.i); + } + } +} + + +static void dump_state( void ) +{ + int i; + + for (i = 0 ; i < Elements(regs) ; i++) + print_reg( ®s[i] ); + + for (i = 0 ; i < Elements(scalars) ; i++) + print_reg( &scalars[i] ); + + for (i = 0 ; i < Elements(vectors) ; i++) + print_reg( &vectors[i] ); +} + + + +static int radeon_emit_packets( + drmRadeonCmdHeader header, + drmRadeonCmdBuffer *cmdbuf ) +{ + int id = (int)header.packet.packet_id; + int sz = packet[id].len; + int *data = (int *)cmdbuf->buf; + int i; + + if (sz * sizeof(int) > cmdbuf->bufsz) { + fprintf(stderr, "Packet overflows cmdbuf\n"); + return -EINVAL; + } + + if (!packet[id].name) { + fprintf(stderr, "*** Unknown packet 0 nr %d\n", id ); + return -EINVAL; + } + + + if (VERBOSE) + fprintf(stderr, "Packet 0 reg %s nr %d\n", packet[id].name, sz ); + + for ( i = 0 ; i < sz ; i++) { + struct reg *reg = lookup_reg( regs, packet[id].start + i*4 ); + if (print_reg_assignment( reg, data[i] )) + total_changed++; + total++; + } + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + + +static int radeon_emit_scalars( + drmRadeonCmdHeader header, + drmRadeonCmdBuffer *cmdbuf ) +{ + int sz = header.scalars.count; + int *data = (int *)cmdbuf->buf; + int start = header.scalars.offset; + int stride = header.scalars.stride; + int i; + + if (VERBOSE) + fprintf(stderr, "emit scalars, start %d stride %d nr %d (end %d)\n", + start, stride, sz, start + stride * sz); + + + for (i = 0 ; i < sz ; i++, start += stride) { + struct reg *reg = lookup_reg( scalars, start ); + if (print_reg_assignment( reg, data[i] )) + total_changed++; + total++; + } + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + + +static int radeon_emit_scalars2( + drmRadeonCmdHeader header, + drmRadeonCmdBuffer *cmdbuf ) +{ + int sz = header.scalars.count; + int *data = (int *)cmdbuf->buf; + int start = header.scalars.offset + 0x100; + int stride = header.scalars.stride; + int i; + + if (VERBOSE) + fprintf(stderr, "emit scalars2, start %d stride %d nr %d (end %d)\n", + start, stride, sz, start + stride * sz); + + if (start + stride * sz > 257) { + fprintf(stderr, "emit scalars OVERFLOW %d/%d/%d\n", start, stride, sz); + return -1; + } + + for (i = 0 ; i < sz ; i++, start += stride) { + struct reg *reg = lookup_reg( scalars, start ); + if (print_reg_assignment( reg, data[i] )) + total_changed++; + total++; + } + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +/* Check: inf/nan/extreme-size? + * Check: table start, end, nr, etc. + */ +static int radeon_emit_vectors( + drmRadeonCmdHeader header, + drmRadeonCmdBuffer *cmdbuf ) +{ + int sz = header.vectors.count; + int *data = (int *)cmdbuf->buf; + int start = header.vectors.offset; + int stride = header.vectors.stride; + int i,j; + + if (VERBOSE) + fprintf(stderr, "emit vectors, start %d stride %d nr %d (end %d) (0x%x)\n", + start, stride, sz, start + stride * sz, header.i); + +/* if (start + stride * (sz/4) > 128) { */ +/* fprintf(stderr, "emit vectors OVERFLOW %d/%d/%d\n", start, stride, sz); */ +/* return -1; */ +/* } */ + + for (i = 0 ; i < sz ; start += stride) { + int changed = 0; + for (j = 0 ; j < 4 ; i++,j++) { + struct reg *reg = lookup_reg( vectors, start*4+j ); + if (print_reg_assignment( reg, data[i] )) + changed = 1; + } + if (changed) + total_changed += 4; + total += 4; + } + + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + + +static int print_vertex_format( int vfmt ) +{ + if (NORMAL) { + fprintf(stderr, " %s(%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + "vertex format", + vfmt, + "xy,", + (vfmt & RADEON_CP_VC_FRMT_Z) ? "z," : "", + (vfmt & RADEON_CP_VC_FRMT_W0) ? "w0," : "", + (vfmt & RADEON_CP_VC_FRMT_FPCOLOR) ? "fpcolor," : "", + (vfmt & RADEON_CP_VC_FRMT_FPALPHA) ? "fpalpha," : "", + (vfmt & RADEON_CP_VC_FRMT_PKCOLOR) ? "pkcolor," : "", + (vfmt & RADEON_CP_VC_FRMT_FPSPEC) ? "fpspec," : "", + (vfmt & RADEON_CP_VC_FRMT_FPFOG) ? "fpfog," : "", + (vfmt & RADEON_CP_VC_FRMT_PKSPEC) ? "pkspec," : "", + (vfmt & RADEON_CP_VC_FRMT_ST0) ? "st0," : "", + (vfmt & RADEON_CP_VC_FRMT_ST1) ? "st1," : "", + (vfmt & RADEON_CP_VC_FRMT_Q1) ? "q1," : "", + (vfmt & RADEON_CP_VC_FRMT_ST2) ? "st2," : "", + (vfmt & RADEON_CP_VC_FRMT_Q2) ? "q2," : "", + (vfmt & RADEON_CP_VC_FRMT_ST3) ? "st3," : "", + (vfmt & RADEON_CP_VC_FRMT_Q3) ? "q3," : "", + (vfmt & RADEON_CP_VC_FRMT_Q0) ? "q0," : "", + (vfmt & RADEON_CP_VC_FRMT_N0) ? "n0," : "", + (vfmt & RADEON_CP_VC_FRMT_XY1) ? "xy1," : "", + (vfmt & RADEON_CP_VC_FRMT_Z1) ? "z1," : "", + (vfmt & RADEON_CP_VC_FRMT_W1) ? "w1," : "", + (vfmt & RADEON_CP_VC_FRMT_N1) ? "n1," : ""); + + +/* if (!find_or_add_value( &others[V_VTXFMT], vfmt )) */ +/* fprintf(stderr, " *** NEW VALUE"); */ + + fprintf(stderr, "\n"); + } + + return 0; +} + +static char *primname[0xf] = { + "NONE", + "POINT", + "LINE", + "LINE_STRIP", + "TRI_LIST", + "TRI_FAN", + "TRI_STRIP", + "TRI_TYPE_2", + "RECT_LIST", + "3VRT_POINT_LIST", + "3VRT_LINE_LIST", +}; + +static int print_prim_and_flags( int prim ) +{ + int numverts; + + if (NORMAL) + fprintf(stderr, " %s(%x): %s%s%s%s%s%s%s\n", + "prim flags", + prim, + ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_IND) ? "IND," : "", + ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_LIST) ? "LIST," : "", + ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_RING) ? "RING," : "", + (prim & RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA) ? "RGBA," : "BGRA, ", + (prim & RADEON_CP_VC_CNTL_MAOS_ENABLE) ? "MAOS," : "", + (prim & RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE) ? "RADEON," : "", + (prim & RADEON_CP_VC_CNTL_TCL_ENABLE) ? "TCL," : ""); + + if ((prim & 0xf) > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST) { + fprintf(stderr, " *** Bad primitive: %x\n", prim & 0xf); + return -1; + } + + numverts = prim>>16; + + if (NORMAL) + fprintf(stderr, " prim: %s numverts %d\n", primname[prim&0xf], numverts); + + switch (prim & 0xf) { + case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE: + case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT: + if (numverts < 1) { + fprintf(stderr, "Bad nr verts for line %d\n", numverts); + return -1; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE: + if ((numverts & 1) || numverts == 0) { + fprintf(stderr, "Bad nr verts for line %d\n", numverts); + return -1; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP: + if (numverts < 2) { + fprintf(stderr, "Bad nr verts for line_strip %d\n", numverts); + return -1; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST: + case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST: + case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST: + case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST: + if (numverts % 3 || numverts == 0) { + fprintf(stderr, "Bad nr verts for tri %d\n", numverts); + return -1; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN: + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP: + if (numverts < 3) { + fprintf(stderr, "Bad nr verts for strip/fan %d\n", numverts); + return -1; + } + break; + default: + fprintf(stderr, "Bad primitive\n"); + return -1; + } + return 0; +} + +/* build in knowledge about each packet type + */ +static int radeon_emit_packet3( drmRadeonCmdBuffer *cmdbuf ) +{ + int cmdsz; + int *cmd = (int *)cmdbuf->buf; + int *tmp; + int i, stride, size, start; + + cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); + + if ((cmd[0] & RADEON_CP_PACKET_MASK) != RADEON_CP_PACKET3 || + cmdsz * 4 > cmdbuf->bufsz || + cmdsz > RADEON_CP_PACKET_MAX_DWORDS) { + fprintf(stderr, "Bad packet\n"); + return -EINVAL; + } + + switch( cmd[0] & ~RADEON_CP_PACKET_COUNT_MASK ) { + case RADEON_CP_PACKET3_NOP: + if (NORMAL) + fprintf(stderr, "PACKET3_NOP, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_NEXT_CHAR: + if (NORMAL) + fprintf(stderr, "PACKET3_NEXT_CHAR, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_PLY_NEXTSCAN: + if (NORMAL) + fprintf(stderr, "PACKET3_PLY_NEXTSCAN, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_SET_SCISSORS: + if (NORMAL) + fprintf(stderr, "PACKET3_SET_SCISSORS, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM: + if (NORMAL) + fprintf(stderr, "PACKET3_3D_RNDR_GEN_INDX_PRIM, %d dwords\n", + cmdsz); + break; + case RADEON_CP_PACKET3_LOAD_MICROCODE: + if (NORMAL) + fprintf(stderr, "PACKET3_LOAD_MICROCODE, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_WAIT_FOR_IDLE: + if (NORMAL) + fprintf(stderr, "PACKET3_WAIT_FOR_IDLE, %d dwords\n", cmdsz); + break; + + case RADEON_CP_PACKET3_3D_DRAW_VBUF: + if (NORMAL) + fprintf(stderr, "PACKET3_3D_DRAW_VBUF, %d dwords\n", cmdsz); + print_vertex_format(cmd[1]); + print_prim_and_flags(cmd[2]); + break; + + case RADEON_CP_PACKET3_3D_DRAW_IMMD: + if (NORMAL) + fprintf(stderr, "PACKET3_3D_DRAW_IMMD, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_3D_DRAW_INDX: { + int neltdwords; + if (NORMAL) + fprintf(stderr, "PACKET3_3D_DRAW_INDX, %d dwords\n", cmdsz); + print_vertex_format(cmd[1]); + print_prim_and_flags(cmd[2]); + neltdwords = cmd[2]>>16; + neltdwords += neltdwords & 1; + neltdwords /= 2; + if (neltdwords + 3 != cmdsz) + fprintf(stderr, "Mismatch in DRAW_INDX, %d vs cmdsz %d\n", + neltdwords, cmdsz); + break; + } + case RADEON_CP_PACKET3_LOAD_PALETTE: + if (NORMAL) + fprintf(stderr, "PACKET3_LOAD_PALETTE, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_3D_LOAD_VBPNTR: + if (NORMAL) { + fprintf(stderr, "PACKET3_3D_LOAD_VBPNTR, %d dwords\n", cmdsz); + fprintf(stderr, " nr arrays: %d\n", cmd[1]); + } + + if (cmd[1]/2 + cmd[1]%2 != cmdsz - 3) { + fprintf(stderr, " ****** MISMATCH %d/%d *******\n", + cmd[1]/2 + cmd[1]%2 + 3, cmdsz); + return -EINVAL; + } + + if (NORMAL) { + tmp = cmd+2; + for (i = 0 ; i < cmd[1] ; i++) { + if (i & 1) { + stride = (tmp[0]>>24) & 0xff; + size = (tmp[0]>>16) & 0xff; + start = tmp[2]; + tmp += 3; + } + else { + stride = (tmp[0]>>8) & 0xff; + size = (tmp[0]) & 0xff; + start = tmp[1]; + } + fprintf(stderr, " array %d: start 0x%x vsize %d vstride %d\n", + i, start, size, stride ); + } + } + break; + case RADEON_CP_PACKET3_CNTL_PAINT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_PAINT, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_CNTL_BITBLT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_BITBLT, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_CNTL_SMALLTEXT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_SMALLTEXT, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_HOSTDATA_BLT, %d dwords\n", + cmdsz); + break; + case RADEON_CP_PACKET3_CNTL_POLYLINE: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_POLYLINE, %d dwords\n", cmdsz); + break; + case RADEON_CP_PACKET3_CNTL_POLYSCANLINES: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_POLYSCANLINES, %d dwords\n", + cmdsz); + break; + case RADEON_CP_PACKET3_CNTL_PAINT_MULTI: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_PAINT_MULTI, %d dwords\n", + cmdsz); + break; + case RADEON_CP_PACKET3_CNTL_BITBLT_MULTI: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_BITBLT_MULTI, %d dwords\n", + cmdsz); + break; + case RADEON_CP_PACKET3_CNTL_TRANS_BITBLT: + if (NORMAL) + fprintf(stderr, "PACKET3_CNTL_TRANS_BITBLT, %d dwords\n", + cmdsz); + break; + default: + fprintf(stderr, "UNKNOWN PACKET, %d dwords\n", cmdsz); + break; + } + + cmdbuf->buf += cmdsz * 4; + cmdbuf->bufsz -= cmdsz * 4; + return 0; +} + + +/* Check cliprects for bounds, then pass on to above: + */ +static int radeon_emit_packet3_cliprect( drmRadeonCmdBuffer *cmdbuf ) +{ + XF86DRIClipRectRec *boxes = (XF86DRIClipRectRec *)cmdbuf->boxes; + int i = 0; + + if (VERBOSE && total_changed) { + dump_state(); + total_changed = 0; + } + else fprintf(stderr, "total_changed zero\n"); + + if (NORMAL) { + do { + if ( i < cmdbuf->nbox ) { + fprintf(stderr, "Emit box %d/%d %d,%d %d,%d\n", + i, cmdbuf->nbox, + boxes[i].x1, boxes[i].y1, boxes[i].x2, boxes[i].y2); + } + } while ( ++i < cmdbuf->nbox ); + } + + if (cmdbuf->nbox == 1) + cmdbuf->nbox = 0; + + return radeon_emit_packet3( cmdbuf ); +} + + +int radeonSanityCmdBuffer( radeonContextPtr rmesa, + int nbox, + XF86DRIClipRectRec *boxes ) +{ + int idx; + drmRadeonCmdBuffer cmdbuf; + drmRadeonCmdHeader header; + static int inited = 0; + + if (!inited) { + init_regs(); + inited = 1; + } + + cmdbuf.buf = rmesa->store.cmd_buf; + cmdbuf.bufsz = rmesa->store.cmd_used; + cmdbuf.boxes = (drmClipRect *)boxes; + cmdbuf.nbox = nbox; + + while ( cmdbuf.bufsz >= sizeof(header) ) { + + header.i = *(int *)cmdbuf.buf; + cmdbuf.buf += sizeof(header); + cmdbuf.bufsz -= sizeof(header); + + switch (header.header.cmd_type) { + case RADEON_CMD_PACKET: + if (radeon_emit_packets( header, &cmdbuf )) { + fprintf(stderr,"radeon_emit_packets failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_SCALARS: + if (radeon_emit_scalars( header, &cmdbuf )) { + fprintf(stderr,"radeon_emit_scalars failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_SCALARS2: + if (radeon_emit_scalars2( header, &cmdbuf )) { + fprintf(stderr,"radeon_emit_scalars failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_VECTORS: + if (radeon_emit_vectors( header, &cmdbuf )) { + fprintf(stderr,"radeon_emit_vectors failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_DMA_DISCARD: + idx = header.dma.buf_idx; + if (NORMAL) + fprintf(stderr, "RADEON_CMD_DMA_DISCARD buf %d\n", idx); + bufs++; + break; + + case RADEON_CMD_PACKET3: + if (radeon_emit_packet3( &cmdbuf )) { + fprintf(stderr,"radeon_emit_packet3 failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_PACKET3_CLIP: + if (radeon_emit_packet3_cliprect( &cmdbuf )) { + fprintf(stderr,"radeon_emit_packet3_clip failed\n"); + return -EINVAL; + } + break; + + case RADEON_CMD_WAIT: + break; + + default: + fprintf(stderr,"bad cmd_type %d at %p\n", + header.header.cmd_type, + cmdbuf.buf - sizeof(header)); + return -EINVAL; + } + } + + if (0) + { + static int n = 0; + n++; + if (n == 10) { + fprintf(stderr, "Bufs %d Total emitted %d real changes %d (%.2f%%)\n", + bufs, + total, total_changed, + ((float)total_changed/(float)total*100.0)); + fprintf(stderr, "Total emitted per buf: %.2f\n", + (float)total/(float)bufs); + fprintf(stderr, "Real changes per buf: %.2f\n", + (float)total_changed/(float)bufs); + + bufs = n = total = total_changed = 0; + } + } + + return 0; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.h new file mode 100644 index 000000000..58e8335dd --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.h @@ -0,0 +1,8 @@ +#ifndef RADEON_SANITY_H +#define RADEON_SANITY_H + +extern int radeonSanityCmdBuffer( radeonContextPtr rmesa, + int nbox, + XF86DRIClipRectRec *boxes ); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c index 443cdfc3a..a45974624 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.4 2002/02/22 21:45:00 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.6 2002/12/16 16:18:58 dawes Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -35,11 +35,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "radeon_screen.h" -#include "radeon_context.h" -#include "radeon_ioctl.h" - #include "mem.h" + #if 1 /* Including xf86PciInfo.h introduces a bunch of errors... */ @@ -47,6 +45,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define PCI_CHIP_RADEON_QE 0x5145 #define PCI_CHIP_RADEON_QF 0x5146 #define PCI_CHIP_RADEON_QG 0x5147 + +#define PCI_CHIP_RADEON_QY 0x5159 +#define PCI_CHIP_RADEON_QZ 0x515A + +#define PCI_CHIP_RADEON_LW 0x4C57 /* mobility 7 - has tcl */ + +#define PCI_CHIP_RADEON_LY 0x4C59 +#define PCI_CHIP_RADEON_LZ 0x4C5A + +#define PCI_CHIP_RV200_QW 0x5157 /* a confusing name for a radeon */ #endif @@ -62,7 +70,9 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) int major, minor, patch; if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { if ( major != 4 || minor < 0 ) { - __driUtilMessage( "Radeon DRI driver expected DRI version 4.0.x but got version %d.%d.%d", major, minor, patch ); + __driUtilMessage( "Radeon DRI driver expected DRI version 4.0.x " + "but got version %d.%d.%d", + major, minor, patch ); return NULL; } } @@ -71,29 +81,78 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) /* Check that the DDX driver version is compatible */ if ( sPriv->ddxMajor != 4 || sPriv->ddxMinor < 0 ) { - __driUtilMessage( "Radeon DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); + __driUtilMessage( "Radeon DRI driver expected DDX driver version 4.0.x " + "but got version %d.%d.%d", + sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); return NULL; } /* Check that the DRM driver version is compatible */ + /* KW: Check minor number here too -- compatibility mode is broken + * atm. + */ if ( sPriv->drmMajor != 1 || - sPriv->drmMinor < 2 ) { - __driUtilMessage( "Radeon DRI driver expected DRM driver version 1.2.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); + sPriv->drmMinor < 3) { + __driUtilMessage( "Radeon DRI driver expected DRM driver version 1.3.x " + "or newer but got version %d.%d.%d", + sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); return NULL; } + /* Allocate the private area */ radeonScreen = (radeonScreenPtr) CALLOC( sizeof(*radeonScreen) ); if ( !radeonScreen ) { - __driUtilMessage("radeonCreateScreen(): CALLOC radeonScreen struct failed"); + __driUtilMessage("%s: CALLOC radeonScreen struct failed", + __FUNCTION__); return NULL; } + if ( sPriv->drmMinor < 3 || + getenv("RADEON_COMPAT")) { + fprintf( stderr, "Radeon DRI driver:\n\t" + "Compatibility mode for DRM driver version %d.%d.%d\n\t" + "TCL will be disabled, expect reduced performance\n\t" + "(prefer DRM radeon.o 1.3.x or newer)\n\t", + sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); + } + + /* This is first since which regions we map depends on whether or * not we are using a PCI card. */ radeonScreen->IsPCI = radeonDRIPriv->IsPCI; + if (sPriv->drmMinor >= 3) { + int ret; + drmRadeonGetParam gp; + + gp.param = RADEON_PARAM_AGP_BUFFER_OFFSET; + gp.value = &radeonScreen->agp_buffer_offset; + + ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + FREE( radeonScreen ); + fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret); + return NULL; + } + + if (sPriv->drmMinor >= 6) { + gp.param = RADEON_PARAM_IRQ_NR; + gp.value = &radeonScreen->irq; + + ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + FREE( radeonScreen ); + fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret); + return NULL; + } + } + + } + radeonScreen->mmio.handle = radeonDRIPriv->registerHandle; radeonScreen->mmio.size = radeonDRIPriv->registerSize; if ( drmMap( sPriv->fd, @@ -144,16 +203,21 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) } } - + radeonScreen->chipset = 0; switch ( radeonDRIPriv->deviceID ) { + default: + fprintf(stderr, "unknown chip id, assuming full radeon support\n"); case PCI_CHIP_RADEON_QD: case PCI_CHIP_RADEON_QE: case PCI_CHIP_RADEON_QF: case PCI_CHIP_RADEON_QG: - radeonScreen->chipset = RADEON_CARD_TYPE_RADEON; - break; - default: - radeonScreen->chipset = RADEON_CARD_TYPE_RADEON; + case PCI_CHIP_RV200_QW: + case PCI_CHIP_RADEON_LW: + radeonScreen->chipset |= RADEON_CHIPSET_TCL; + case PCI_CHIP_RADEON_QY: + case PCI_CHIP_RADEON_QZ: + case PCI_CHIP_RADEON_LY: + case PCI_CHIP_RADEON_LZ: break; } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h index b5f11bcad..12cecd0dc 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h,v 1.3 2002/02/22 21:45:01 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h,v 1.5 2002/12/16 16:18:58 dawes Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -39,24 +39,33 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING -#include <X11/Xlibint.h> +/* + * IMPORTS: these headers contain all the DRI, X and kernel-related + * definitions that we need. + */ #include "dri_util.h" -#include "xf86drm.h" -#include "xf86drmRadeon.h" +#include "radeon_common.h" +#include "radeon_dri.h" +#include "radeon_reg.h" #include "radeon_sarea.h" + typedef struct { drmHandle handle; /* Handle to the DRM region */ drmSize size; /* Size of the DRM region */ drmAddress map; /* Mapping of the DRM region */ } radeonRegionRec, *radeonRegionPtr; +/* chipset features */ +#define RADEON_CHIPSET_TCL (1 << 0) + typedef struct { int chipset; int cpp; int IsPCI; /* Current card is a PCI card */ int AGPMode; + unsigned int irq; /* IRQ number (0 means none) */ unsigned int frontOffset; unsigned int frontPitch; @@ -82,6 +91,7 @@ typedef struct { __DRIscreenPrivate *driScreen; unsigned int sarea_priv_offset; + unsigned int agp_buffer_offset; /* offset in card memory space */ } radeonScreenRec, *radeonScreenPtr; extern radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c index 41a2668df..044073320 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_span.c,v 1.5 2002/02/22 21:45:01 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_span.c,v 1.6 2002/10/30 12:51:56 alanh Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -31,7 +31,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ @@ -292,12 +292,22 @@ static void radeonSetReadBuffer( GLcontext *ctx, switch ( mode ) { case GL_FRONT_LEFT: - rmesa->state.pixel.readOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.pixel.readPitch = rmesa->radeonScreen->frontPitch; + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->state.pixel.readOffset = rmesa->radeonScreen->backOffset; + rmesa->state.pixel.readPitch = rmesa->radeonScreen->backPitch; + } else { + rmesa->state.pixel.readOffset = rmesa->radeonScreen->frontOffset; + rmesa->state.pixel.readPitch = rmesa->radeonScreen->frontPitch; + } break; case GL_BACK_LEFT: - rmesa->state.pixel.readOffset = rmesa->radeonScreen->backOffset; - rmesa->state.pixel.readPitch = rmesa->radeonScreen->backPitch; + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->state.pixel.readOffset = rmesa->radeonScreen->frontOffset; + rmesa->state.pixel.readPitch = rmesa->radeonScreen->frontPitch; + } else { + rmesa->state.pixel.readOffset = rmesa->radeonScreen->backOffset; + rmesa->state.pixel.readPitch = rmesa->radeonScreen->backPitch; + } break; default: assert(0); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c index 9077ee43f..fd921f8f9 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.5 2002/09/16 18:05:20 eich Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.8 2002/12/16 16:18:58 dawes Exp $ */ /* * Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California. * @@ -25,19 +25,23 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #include "radeon_context.h" -#include "radeon_state.h" #include "radeon_ioctl.h" -#include "radeon_tris.h" -#include "radeon_vb.h" +#include "radeon_state.h" +#include "radeon_tcl.h" #include "radeon_tex.h" +#include "radeon_swtcl.h" +#include "radeon_vtxfmt.h" +#include "mem.h" #include "mmath.h" #include "enums.h" #include "colormac.h" +#include "light.h" +#include "api_arrayelt.h" #include "swrast/swrast.h" #include "array_cache/acache.h" @@ -46,6 +50,14 @@ #include "swrast_setup/swrast_setup.h" +#define MODEL_PROJ 0 +#define MODEL 1 +#define MODEL_IT 2 +#define TEXMAT_0 3 +#define TEXMAT_1 4 +#define TEXMAT_2 5 + + /* ============================================================= * Alpha blending */ @@ -53,55 +65,56 @@ static void radeonAlphaFunc( GLcontext *ctx, GLenum func, GLchan ref ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC]; - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); + RADEON_STATECHANGE( rmesa, ctx ); - rmesa->state.hw.context.pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | - RADEON_REF_ALPHA_MASK); + pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK); + pp_misc |= (ref & RADEON_REF_ALPHA_MASK); switch ( func ) { case GL_NEVER: - rmesa->state.hw.context.pp_misc |= RADEON_ALPHA_TEST_FAIL; + pp_misc |= RADEON_ALPHA_TEST_FAIL; break; case GL_LESS: - rmesa->state.hw.context.pp_misc |= RADEON_ALPHA_TEST_LESS; + pp_misc |= RADEON_ALPHA_TEST_LESS; break; case GL_EQUAL: - rmesa->state.hw.context.pp_misc |= RADEON_ALPHA_TEST_EQUAL; + pp_misc |= RADEON_ALPHA_TEST_EQUAL; break; case GL_LEQUAL: - rmesa->state.hw.context.pp_misc |= RADEON_ALPHA_TEST_LEQUAL; + pp_misc |= RADEON_ALPHA_TEST_LEQUAL; break; case GL_GREATER: - rmesa->state.hw.context.pp_misc |= RADEON_ALPHA_TEST_GREATER; + pp_misc |= RADEON_ALPHA_TEST_GREATER; break; case GL_NOTEQUAL: - rmesa->state.hw.context.pp_misc |= RADEON_ALPHA_TEST_NEQUAL; + pp_misc |= RADEON_ALPHA_TEST_NEQUAL; break; case GL_GEQUAL: - rmesa->state.hw.context.pp_misc |= RADEON_ALPHA_TEST_GEQUAL; + pp_misc |= RADEON_ALPHA_TEST_GEQUAL; break; case GL_ALWAYS: - rmesa->state.hw.context.pp_misc |= RADEON_ALPHA_TEST_PASS; + pp_misc |= RADEON_ALPHA_TEST_PASS; break; } - rmesa->state.hw.context.pp_misc |= (ref & RADEON_REF_ALPHA_MASK); + rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc; } static void radeonBlendEquation( GLcontext *ctx, GLenum mode ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint b = rmesa->state.hw.context.rb3d_blendcntl & ~RADEON_COMB_FCN_MASK; + GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK; GLboolean fallback = GL_FALSE; switch ( mode ) { - case GL_FUNC_ADD_EXT: + case GL_FUNC_ADD: case GL_LOGIC_OP: b |= RADEON_COMB_FCN_ADD_CLAMP; break; - case GL_FUNC_SUBTRACT_EXT: + case GL_FUNC_SUBTRACT: b |= RADEON_COMB_FCN_SUB_CLAMP; break; @@ -112,12 +125,12 @@ static void radeonBlendEquation( GLcontext *ctx, GLenum mode ) FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, fallback ); if ( !fallback ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - rmesa->state.hw.context.rb3d_blendcntl = b; + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b; if ( ctx->Color.ColorLogicOpEnabled ) { - rmesa->state.hw.context.rb3d_cntl |= RADEON_ROP_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE; } else { - rmesa->state.hw.context.rb3d_cntl &= ~RADEON_ROP_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE; } } } @@ -125,8 +138,8 @@ static void radeonBlendEquation( GLcontext *ctx, GLenum mode ) static void radeonBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint b = rmesa->state.hw.context.rb3d_blendcntl & ~(RADEON_SRC_BLEND_MASK | - RADEON_DST_BLEND_MASK); + GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & + ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK); GLboolean fallback = GL_FALSE; switch ( ctx->Color.BlendSrcRGB ) { @@ -142,6 +155,12 @@ static void radeonBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) case GL_ONE_MINUS_DST_COLOR: b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR; break; + case GL_SRC_COLOR: + b |= RADEON_SRC_BLEND_GL_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR; + break; case GL_SRC_ALPHA: b |= RADEON_SRC_BLEND_GL_SRC_ALPHA; break; @@ -184,6 +203,12 @@ static void radeonBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) case GL_ONE_MINUS_SRC_ALPHA: b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA; break; + case GL_DST_COLOR: + b |= RADEON_DST_BLEND_GL_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR; + break; case GL_DST_ALPHA: b |= RADEON_DST_BLEND_GL_DST_ALPHA; break; @@ -200,8 +225,8 @@ static void radeonBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback ); if ( !fallback ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - rmesa->state.hw.context.rb3d_blendcntl = b; + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b; } } @@ -221,33 +246,33 @@ static void radeonDepthFunc( GLcontext *ctx, GLenum func ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - rmesa->state.hw.context.rb3d_zstencilcntl &= ~RADEON_Z_TEST_MASK; + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK; switch ( ctx->Depth.Func ) { case GL_NEVER: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_Z_TEST_NEVER; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEVER; break; case GL_LESS: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_Z_TEST_LESS; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LESS; break; case GL_EQUAL: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_Z_TEST_EQUAL; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_EQUAL; break; case GL_LEQUAL: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_Z_TEST_LEQUAL; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LEQUAL; break; case GL_GREATER: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_Z_TEST_GREATER; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GREATER; break; case GL_NOTEQUAL: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_Z_TEST_NEQUAL; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEQUAL; break; case GL_GEQUAL: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_Z_TEST_GEQUAL; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GEQUAL; break; case GL_ALWAYS: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_Z_TEST_ALWAYS; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_ALWAYS; break; } } @@ -256,19 +281,19 @@ static void radeonDepthFunc( GLcontext *ctx, GLenum func ) static void radeonDepthMask( GLcontext *ctx, GLboolean flag ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); + RADEON_STATECHANGE( rmesa, ctx ); if ( ctx->Depth.Mask ) { - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_Z_WRITE_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_WRITE_ENABLE; } else { - rmesa->state.hw.context.rb3d_zstencilcntl &= ~RADEON_Z_WRITE_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_WRITE_ENABLE; } } static void radeonClearDepth( GLcontext *ctx, GLclampd d ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint format = (rmesa->state.hw.context.rb3d_zstencilcntl & + GLuint format = (rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] & RADEON_DEPTH_FORMAT_MASK); switch ( format ) { @@ -286,22 +311,157 @@ static void radeonClearDepth( GLcontext *ctx, GLclampd d ) * Fog */ + static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLchan c[4]; + union { int i; float f; } c, d; + GLchan col[4]; + + c.i = rmesa->hw.fog.cmd[FOG_C]; + d.i = rmesa->hw.fog.cmd[FOG_D]; + + switch (pname) { + case GL_FOG_MODE: + if (!ctx->Fog.Enabled) + return; + RADEON_STATECHANGE(rmesa, tcl); + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK; + switch (ctx->Fog.Mode) { + case GL_LINEAR: + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR; + if (ctx->Fog.Start == ctx->Fog.End) { + c.f = 1.0F; + d.f = 1.0F; + } + else { + c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); + d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start); + } + break; + case GL_EXP: + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP; + c.f = 0.0; + d.f = ctx->Fog.Density; + break; + case GL_EXP2: + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2; + c.f = 0.0; + d.f = -(ctx->Fog.Density * ctx->Fog.Density); + break; + default: + return; + } + break; + case GL_FOG_DENSITY: + switch (ctx->Fog.Mode) { + case GL_EXP: + c.f = 0.0; + d.f = ctx->Fog.Density; + break; + case GL_EXP2: + c.f = 0.0; + d.f = -(ctx->Fog.Density * ctx->Fog.Density); + break; + default: + break; + } + break; + case GL_FOG_START: + case GL_FOG_END: + if (ctx->Fog.Mode == GL_LINEAR) { + if (ctx->Fog.Start == ctx->Fog.End) { + c.f = 1.0F; + d.f = 1.0F; + } else { + c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); + d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start); + } + } + break; + case GL_FOG_COLOR: + RADEON_STATECHANGE( rmesa, ctx ); + UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color ); + rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = + radeonPackColor( 4, col[0], col[1], col[2], 0 ); + break; + case GL_FOG_COORDINATE_SOURCE_EXT: + /* What to do? + */ + break; + default: + return; + } - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - UNCLAMPED_FLOAT_TO_RGB_CHAN( c, ctx->Fog.Color ); - rmesa->state.hw.context.pp_fog_color = - radeonPackColor( 4, c[0], c[1], c[2], 0 ); + if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) { + RADEON_STATECHANGE( rmesa, fog ); + rmesa->hw.fog.cmd[FOG_C] = c.i; + rmesa->hw.fog.cmd[FOG_D] = d.i; + } } /* ============================================================= - * Clipping + * Scissoring */ + +static GLboolean intersect_rect( XF86DRIClipRectPtr out, + XF86DRIClipRectPtr a, + XF86DRIClipRectPtr b ) +{ + *out = *a; + if ( b->x1 > out->x1 ) out->x1 = b->x1; + if ( b->y1 > out->y1 ) out->y1 = b->y1; + if ( b->x2 < out->x2 ) out->x2 = b->x2; + if ( b->y2 < out->y2 ) out->y2 = b->y2; + if ( out->x1 >= out->x2 ) return GL_FALSE; + if ( out->y1 >= out->y2 ) return GL_FALSE; + return GL_TRUE; +} + + +void radeonRecalcScissorRects( radeonContextPtr rmesa ) +{ + XF86DRIClipRectPtr out; + int i; + + /* Grow cliprect store? + */ + if (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { + while (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { + rmesa->state.scissor.numAllocedClipRects += 1; /* zero case */ + rmesa->state.scissor.numAllocedClipRects *= 2; + } + + if (rmesa->state.scissor.pClipRects) + FREE(rmesa->state.scissor.pClipRects); + + rmesa->state.scissor.pClipRects = + MALLOC( rmesa->state.scissor.numAllocedClipRects * + sizeof(XF86DRIClipRectRec) ); + + if (!rmesa->state.scissor.numAllocedClipRects) { +/* FALLBACK( rmesa, RADEON_FALLBACK_MEMORY, GL_TRUE ); */ + rmesa->state.scissor.numAllocedClipRects = 0; + return; + } + } + + out = rmesa->state.scissor.pClipRects; + rmesa->state.scissor.numClipRects = 0; + + for ( i = 0 ; i < rmesa->numClipRects ; i++ ) { + if ( intersect_rect( out, + &rmesa->pClipRects[i], + &rmesa->state.scissor.rect ) ) { + rmesa->state.scissor.numClipRects++; + out++; + } + } +} + + static void radeonUpdateScissor( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -319,8 +479,7 @@ static void radeonUpdateScissor( GLcontext *ctx ) rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; - if ( ctx->Scissor.Enabled ) - rmesa->upload_cliprects = 1; + radeonRecalcScissorRects( rmesa ); } } @@ -330,10 +489,11 @@ static void radeonScissor( GLcontext *ctx, { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if ( ctx->Scissor.Enabled ) + if ( ctx->Scissor.Enabled ) { RADEON_FIREVERTICES( rmesa ); /* don't pipeline cliprect changes */ + radeonUpdateScissor( ctx ); + } - radeonUpdateScissor( ctx ); } @@ -344,27 +504,37 @@ static void radeonScissor( GLcontext *ctx, static void radeonCullFace( GLcontext *ctx, GLenum unused ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint s = rmesa->state.hw.setup1.se_cntl; + GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; + GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL]; s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID; + t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK); if ( ctx->Polygon.CullFlag ) { switch ( ctx->Polygon.CullFaceMode ) { case GL_FRONT: s &= ~RADEON_FFACE_SOLID; + t |= RADEON_CULL_FRONT; break; case GL_BACK: s &= ~RADEON_BFACE_SOLID; + t |= RADEON_CULL_BACK; break; case GL_FRONT_AND_BACK: s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID); + t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK); break; } } - if ( rmesa->state.hw.setup1.se_cntl != s ) { - RADEON_STATECHANGE(rmesa, RADEON_UPLOAD_SETUP); - rmesa->state.hw.setup1.se_cntl = s; + if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) { + RADEON_STATECHANGE(rmesa, set ); + rmesa->hw.set.cmd[SET_SE_CNTL] = s; + } + + if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) { + RADEON_STATECHANGE(rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t; } } @@ -372,15 +542,19 @@ static void radeonFrontFace( GLcontext *ctx, GLenum mode ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_SETUP ); - rmesa->state.hw.setup1.se_cntl &= ~RADEON_FFACE_CULL_DIR_MASK; + RADEON_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK; + + RADEON_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW; switch ( mode ) { case GL_CW: - rmesa->state.hw.setup1.se_cntl |= RADEON_FFACE_CULL_CW; + rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW; break; case GL_CCW: - rmesa->state.hw.setup1.se_cntl |= RADEON_FFACE_CULL_CCW; + rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CCW; + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW; break; } } @@ -393,15 +567,16 @@ static void radeonLineWidth( GLcontext *ctx, GLfloat widthf ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_LINE | RADEON_UPLOAD_SETUP ); + RADEON_STATECHANGE( rmesa, lin ); + RADEON_STATECHANGE( rmesa, set ); /* Line width is stored in U6.4 format. */ - rmesa->state.hw.line.se_line_width = (GLuint)(widthf * 16.0); + rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0); if ( widthf > 1.0 ) { - rmesa->state.hw.setup1.se_cntl |= RADEON_WIDELINE_ENABLE; + rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_WIDELINE_ENABLE; } else { - rmesa->state.hw.setup1.se_cntl &= ~RADEON_WIDELINE_ENABLE; + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE; } } @@ -409,10 +584,9 @@ static void radeonLineStipple( GLcontext *ctx, GLint factor, GLushort pattern ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_LINE ); - - rmesa->state.hw.line.re_line_pattern = ((((GLuint)factor & 0xff) << 16) | - ((GLuint)pattern)); + RADEON_STATECHANGE( rmesa, lin ); + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = + ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern)); } @@ -430,9 +604,9 @@ static void radeonColorMask( GLcontext *ctx, ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP] ); - if ( rmesa->state.hw.mask.rb3d_planemask != mask ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_MASKS ); - rmesa->state.hw.mask.rb3d_planemask = mask; + if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) { + RADEON_STATECHANGE( rmesa, msk ); + rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask; } } @@ -447,15 +621,16 @@ static void radeonPolygonOffset( GLcontext *ctx, radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLfloat constant = units * rmesa->state.depth.scale; - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_ZBIAS ); - rmesa->state.hw.zbias.se_zbias_factor = *(GLuint *)&factor; - rmesa->state.hw.zbias.se_zbias_constant = *(GLuint *)&constant; + RADEON_STATECHANGE( rmesa, zbs ); + rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = *(GLuint *)&factor; + rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = *(GLuint *)&constant; } static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint i; + drmRadeonStipple stipple; /* Must flip pattern upside down. */ @@ -463,15 +638,34 @@ static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask ) rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i]; } + /* TODO: push this into cmd mechanism + */ RADEON_FIREVERTICES( rmesa ); LOCK_HARDWARE( rmesa ); /* FIXME: Use window x,y offsets into stipple RAM. */ - drmRadeonPolygonStipple( rmesa->dri.fd, rmesa->state.stipple.mask ); + stipple.mask = rmesa->state.stipple.mask; + drmCommandWrite( rmesa->dri.fd, DRM_RADEON_STIPPLE, + &stipple, sizeof(drmRadeonStipple) ); UNLOCK_HARDWARE( rmesa ); } +static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0; + + /* Can't generally do unfilled via tcl, but some good special + * cases work. + */ + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag); + if (rmesa->TclFallback) { + radeonChooseRenderState( ctx ); + radeonChooseVertexState( ctx ); + } +} + /* ============================================================= * Rendering attributes @@ -487,34 +681,478 @@ static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask ) static void radeonUpdateSpecular( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - CARD32 p = rmesa->state.hw.context.pp_cntl; + CARD32 p = rmesa->hw.ctx.cmd[CTX_PP_CNTL]; - if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && - ctx->Light.Enabled) { + if ( ctx->_TriangleCaps & DD_SEPARATE_SPECULAR ) { p |= RADEON_SPECULAR_ENABLE; } else { p &= ~RADEON_SPECULAR_ENABLE; } - if ( rmesa->state.hw.context.pp_cntl != p ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - rmesa->state.hw.context.pp_cntl = p; + if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p; + } + + /* Bizzare: have to leave lighting enabled to get fog. + */ + RADEON_STATECHANGE( rmesa, tcl ); + if ((ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; + } + else if (ctx->Fog.Enabled) { + if (ctx->Light.Enabled) { + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; + } else { + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; + } + } + else if (ctx->Light.Enabled) { + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; + } else if (ctx->Fog.ColorSumEnabled ) { + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; + } else { + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; + } + + /* Update vertex/render formats + */ + if (rmesa->TclFallback) { + radeonChooseRenderState( ctx ); + radeonChooseVertexState( ctx ); + } +} + + +/* ============================================================= + * Materials + */ + + +/* Update on colormaterial, material emmissive/ambient, + * lightmodel.globalambient + */ +static void update_global_ambient( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + float *fcmd = (float *)RADEON_DB_STATE( glt ); + + /* Need to do more if both emmissive & ambient are PREMULT: + */ + if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] & + ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | + (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0) + { + COPY_3V( &fcmd[GLT_RED], + ctx->Light.Material[0].Emission); + ACC_SCALE_3V( &fcmd[GLT_RED], + ctx->Light.Model.Ambient, + ctx->Light.Material[0].Ambient); + } + else + { + COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient ); + } + + RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt); +} + +/* Update on change to + * - light[p].colors + * - light[p].enabled + * - material, + * - colormaterial enabled + * - colormaterial bitmask + */ +static void update_light_colors( GLcontext *ctx, GLuint p ) +{ + struct gl_light *l = &ctx->Light.Light[p]; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + if (l->Enabled) { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + float *fcmd = (float *)RADEON_DB_STATE( lit[p] ); + GLuint bitmask = ctx->Light.ColorMaterialBitmask; + struct gl_material *mat = &ctx->Light.Material[0]; + + COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient ); + COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse ); + COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular ); + + if (!ctx->Light.ColorMaterialEnabled) + bitmask = 0; + + if ((bitmask & FRONT_AMBIENT_BIT) == 0) + SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat->Ambient ); + + if ((bitmask & FRONT_DIFFUSE_BIT) == 0) + SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat->Diffuse ); + + if ((bitmask & FRONT_SPECULAR_BIT) == 0) + SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat->Specular ); + + RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); + } +} + +/* Also fallback for asym colormaterial mode in twoside lighting... + */ +static void check_twoside_fallback( GLcontext *ctx ) +{ + GLboolean fallback = GL_FALSE; + + if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { + if (memcmp( &ctx->Light.Material[0], + &ctx->Light.Material[1], + sizeof(struct gl_material)) != 0) + fallback = GL_TRUE; + else if (ctx->Light.ColorMaterialEnabled && + (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) != + ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1)) + fallback = GL_TRUE; + } + + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback ); +} + +static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ) +{ + if (ctx->Light.ColorMaterialEnabled) { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint light_model_ctl = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; + GLuint mask = ctx->Light.ColorMaterialBitmask; + + /* Default to PREMULT: + */ + light_model_ctl &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | + (3 << RADEON_AMBIENT_SOURCE_SHIFT) | + (3 << RADEON_DIFFUSE_SOURCE_SHIFT) | + (3 << RADEON_SPECULAR_SOURCE_SHIFT)); + + if (mask & FRONT_EMISSION_BIT) { + light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << + RADEON_EMISSIVE_SOURCE_SHIFT); + } + + if (mask & FRONT_AMBIENT_BIT) { + light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << + RADEON_AMBIENT_SOURCE_SHIFT); + } + + if (mask & FRONT_DIFFUSE_BIT) { + light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << + RADEON_DIFFUSE_SOURCE_SHIFT); + } + + if (mask & FRONT_SPECULAR_BIT) { + light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << + RADEON_SPECULAR_SOURCE_SHIFT); + } + + if (light_model_ctl != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) { + GLuint p; + + RADEON_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl; + + for (p = 0 ; p < MAX_LIGHTS; p++) + update_light_colors( ctx, p ); + update_global_ambient( ctx ); + } + } + + check_twoside_fallback( ctx ); +} + +void radeonUpdateMaterial( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl ); + GLuint p; + GLuint mask = ~0; + + if (ctx->Light.ColorMaterialEnabled) + mask &= ~ctx->Light.ColorMaterialBitmask; + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if (mask & FRONT_EMISSION_BIT) { + fcmd[MTL_EMMISSIVE_RED] = ctx->Light.Material[0].Emission[0]; + fcmd[MTL_EMMISSIVE_GREEN] = ctx->Light.Material[0].Emission[1]; + fcmd[MTL_EMMISSIVE_BLUE] = ctx->Light.Material[0].Emission[2]; + fcmd[MTL_EMMISSIVE_ALPHA] = ctx->Light.Material[0].Emission[3]; + } + if (mask & FRONT_AMBIENT_BIT) { + fcmd[MTL_AMBIENT_RED] = ctx->Light.Material[0].Ambient[0]; + fcmd[MTL_AMBIENT_GREEN] = ctx->Light.Material[0].Ambient[1]; + fcmd[MTL_AMBIENT_BLUE] = ctx->Light.Material[0].Ambient[2]; + fcmd[MTL_AMBIENT_ALPHA] = ctx->Light.Material[0].Ambient[3]; + } + if (mask & FRONT_DIFFUSE_BIT) { + fcmd[MTL_DIFFUSE_RED] = ctx->Light.Material[0].Diffuse[0]; + fcmd[MTL_DIFFUSE_GREEN] = ctx->Light.Material[0].Diffuse[1]; + fcmd[MTL_DIFFUSE_BLUE] = ctx->Light.Material[0].Diffuse[2]; + fcmd[MTL_DIFFUSE_ALPHA] = ctx->Light.Material[0].Diffuse[3]; + } + if (mask & FRONT_SPECULAR_BIT) { + fcmd[MTL_SPECULAR_RED] = ctx->Light.Material[0].Specular[0]; + fcmd[MTL_SPECULAR_GREEN] = ctx->Light.Material[0].Specular[1]; + fcmd[MTL_SPECULAR_BLUE] = ctx->Light.Material[0].Specular[2]; + fcmd[MTL_SPECULAR_ALPHA] = ctx->Light.Material[0].Specular[3]; + } + if (mask & FRONT_SHININESS_BIT) { + fcmd[MTL_SHININESS] = ctx->Light.Material[0].Shininess; + } + + if (RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl )) { + for (p = 0 ; p < MAX_LIGHTS; p++) + update_light_colors( ctx, p ); + + check_twoside_fallback( ctx ); + update_global_ambient( ctx ); + } + else if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_STATE)) + fprintf(stderr, "%s: Elided noop material call\n", __FUNCTION__); +} + +/* _NEW_LIGHT + * _NEW_MODELVIEW + * _MESA_NEW_NEED_EYE_COORDS + * + * Uses derived state from mesa: + * _VP_inf_norm + * _h_inf_norm + * _Position + * _NormDirection + * _ModelViewInvScale + * _NeedEyeCoords + * _EyeZDir + * + * which are calculated in light.c and are correct for the current + * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW + * and _MESA_NEW_NEED_EYE_COORDS. + */ +static void update_light( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + /* Have to check these, or have an automatic shortcircuit mechanism + * to remove noop statechanges. (Or just do a better job on the + * front end). + */ + { + GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; + + if (ctx->_NeedEyeCoords) + tmp &= ~RADEON_LIGHT_IN_MODELSPACE; + else + tmp |= RADEON_LIGHT_IN_MODELSPACE; + + + /* Leave this test disabled: (unexplained q3 lockup) (even with + new packets) + */ + if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) + { + RADEON_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp; + } + } + + { + GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye ); + fcmd[EYE_X] = ctx->_EyeZDir[0]; + fcmd[EYE_Y] = ctx->_EyeZDir[1]; + fcmd[EYE_Z] = - ctx->_EyeZDir[2]; + fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale; + RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye ); + } + + +/* RADEON_STATECHANGE( rmesa, glt ); */ + + if (ctx->Light.Enabled) { + GLint p; + for (p = 0 ; p < MAX_LIGHTS; p++) { + if (ctx->Light.Light[p].Enabled) { + struct gl_light *l = &ctx->Light.Light[p]; + GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] ); + + if (l->EyePosition[3] == 0.0) { + COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm ); + COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm ); + fcmd[LIT_POSITION_W] = 0; + fcmd[LIT_DIRECTION_W] = 0; + } else { + COPY_4V( &fcmd[LIT_POSITION_X], l->_Position ); + fcmd[LIT_DIRECTION_X] = -l->_NormDirection[0]; + fcmd[LIT_DIRECTION_Y] = -l->_NormDirection[1]; + fcmd[LIT_DIRECTION_Z] = -l->_NormDirection[2]; + fcmd[LIT_DIRECTION_W] = 0; + } + + RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); + } + } + } +} + +static void radeonLightfv( GLcontext *ctx, GLenum light, + GLenum pname, const GLfloat *params ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLint p = light - GL_LIGHT0; + struct gl_light *l = &ctx->Light.Light[p]; + GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd; + + + switch (pname) { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + update_light_colors( ctx, p ); + break; + + case GL_SPOT_DIRECTION: + /* picked up in update_light */ + break; + + case GL_POSITION: { + /* positions picked up in update_light, but can do flag here */ + GLuint flag = (p&1)? RADEON_LIGHT_1_IS_LOCAL : RADEON_LIGHT_0_IS_LOCAL; + GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; + + RADEON_STATECHANGE(rmesa, tcl); + if (l->EyePosition[3] != 0.0F) + rmesa->hw.tcl.cmd[idx] |= flag; + else + rmesa->hw.tcl.cmd[idx] &= ~flag; + break; + } + + case GL_SPOT_EXPONENT: + RADEON_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_SPOT_EXPONENT] = params[0]; + break; + + case GL_SPOT_CUTOFF: { + GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT; + GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; + + RADEON_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff; + + RADEON_STATECHANGE(rmesa, tcl); + if (l->SpotCutoff != 180.0F) + rmesa->hw.tcl.cmd[idx] |= flag; + else + rmesa->hw.tcl.cmd[idx] &= ~flag; + break; + } + + case GL_CONSTANT_ATTENUATION: + RADEON_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_ATTEN_CONST] = params[0]; + break; + case GL_LINEAR_ATTENUATION: + RADEON_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_ATTEN_LINEAR] = params[0]; + break; + case GL_QUADRATIC_ATTENUATION: + RADEON_STATECHANGE(rmesa, lit[p]); + fcmd[LIT_ATTEN_QUADRATIC] = params[0]; + break; + default: + return; } + } + + static void radeonLightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) { - if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) { - radeonUpdateSpecular(ctx); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + switch (pname) { + case GL_LIGHT_MODEL_AMBIENT: + update_global_ambient( ctx ); + break; + + case GL_LIGHT_MODEL_LOCAL_VIEWER: + RADEON_STATECHANGE( rmesa, tcl ); + if (ctx->Light.Model.LocalViewer) + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER; + else + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER; + break; + + case GL_LIGHT_MODEL_TWO_SIDE: + RADEON_STATECHANGE( rmesa, tcl ); + if (ctx->Light.Model.TwoSide) + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE; + else + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE; + + check_twoside_fallback( ctx ); + + if (rmesa->TclFallback) { + radeonChooseRenderState( ctx ); + radeonChooseVertexState( ctx ); + } + break; + + case GL_LIGHT_MODEL_COLOR_CONTROL: + radeonUpdateSpecular(ctx); + + RADEON_STATECHANGE( rmesa, tcl ); + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= + ~RADEON_DIFFUSE_SPECULAR_COMBINE; + else + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= + RADEON_DIFFUSE_SPECULAR_COMBINE; + break; + + default: + break; } } static void radeonShadeModel( GLcontext *ctx, GLenum mode ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint s = rmesa->state.hw.setup1.se_cntl; + GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; s &= ~(RADEON_DIFFUSE_SHADE_MASK | RADEON_ALPHA_SHADE_MASK | @@ -538,9 +1176,45 @@ static void radeonShadeModel( GLcontext *ctx, GLenum mode ) return; } - if ( rmesa->state.hw.setup1.se_cntl != s ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_SETUP ); - rmesa->state.hw.setup1.se_cntl = s; + if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) { + RADEON_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_CNTL] = s; + } +} + + +/* ============================================================= + * User clip planes + */ + +static void radeonClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) +{ + GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; + + RADEON_STATECHANGE( rmesa, ucp[p] ); + rmesa->hw.ucp[p].cmd[UCP_X] = ip[0]; + rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1]; + rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2]; + rmesa->hw.ucp[p].cmd[UCP_W] = ip[3]; +} + +static void radeonUpdateClipPlanes( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint p; + + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { + if (ctx->Transform.ClipEnabled[p]) { + GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; + + RADEON_STATECHANGE( rmesa, ucp[p] ); + rmesa->hw.ucp[p].cmd[UCP_X] = ip[0]; + rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1]; + rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2]; + rmesa->hw.ucp[p].cmd[UCP_W] = ip[3]; + } } } @@ -556,50 +1230,50 @@ static void radeonStencilFunc( GLcontext *ctx, GLenum func, GLuint refmask = ((ctx->Stencil.Ref << RADEON_STENCIL_REF_SHIFT) | (ctx->Stencil.ValueMask << RADEON_STENCIL_MASK_SHIFT)); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS ); + RADEON_STATECHANGE( rmesa, ctx ); + RADEON_STATECHANGE( rmesa, msk ); - rmesa->state.hw.context.rb3d_zstencilcntl &= ~RADEON_STENCIL_TEST_MASK; - rmesa->state.hw.mask.rb3d_stencilrefmask &= ~(RADEON_STENCIL_REF_MASK| - RADEON_STENCIL_VALUE_MASK); + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK; + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK| + RADEON_STENCIL_VALUE_MASK); switch ( ctx->Stencil.Function ) { case GL_NEVER: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_TEST_NEVER; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER; break; case GL_LESS: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_TEST_LESS; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS; break; case GL_EQUAL: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_TEST_EQUAL; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL; break; case GL_LEQUAL: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_TEST_LEQUAL; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL; break; case GL_GREATER: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_TEST_GREATER; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER; break; case GL_NOTEQUAL: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_TEST_NEQUAL; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL; break; case GL_GEQUAL: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_TEST_GEQUAL; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL; break; case GL_ALWAYS: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_TEST_ALWAYS; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS; break; } - rmesa->state.hw.mask.rb3d_stencilrefmask |= refmask; + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask; } static void radeonStencilMask( GLcontext *ctx, GLuint mask ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_MASKS ); - rmesa->state.hw.mask.rb3d_stencilrefmask &= ~RADEON_STENCIL_WRITE_MASK; - - rmesa->state.hw.mask.rb3d_stencilrefmask |= + RADEON_STATECHANGE( rmesa, msk ); + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK; + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= (ctx->Stencil.WriteMask << RADEON_STENCIL_WRITEMASK_SHIFT); } @@ -608,71 +1282,71 @@ static void radeonStencilOp( GLcontext *ctx, GLenum fail, { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - rmesa->state.hw.context.rb3d_zstencilcntl &= ~(RADEON_STENCIL_FAIL_MASK | + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK | RADEON_STENCIL_ZFAIL_MASK | RADEON_STENCIL_ZPASS_MASK); switch ( ctx->Stencil.FailFunc ) { case GL_KEEP: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_FAIL_KEEP; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP; break; case GL_ZERO: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_FAIL_ZERO; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO; break; case GL_REPLACE: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_FAIL_REPLACE; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE; break; case GL_INCR: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_FAIL_INC; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC; break; case GL_DECR: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_FAIL_DEC; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC; break; case GL_INVERT: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_FAIL_INVERT; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT; break; } switch ( ctx->Stencil.ZFailFunc ) { case GL_KEEP: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZFAIL_KEEP; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP; break; case GL_ZERO: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZFAIL_ZERO; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO; break; case GL_REPLACE: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZFAIL_REPLACE; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE; break; case GL_INCR: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZFAIL_INC; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC; break; case GL_DECR: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZFAIL_DEC; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC; break; case GL_INVERT: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZFAIL_INVERT; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT; break; } switch ( ctx->Stencil.ZPassFunc ) { case GL_KEEP: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZPASS_KEEP; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP; break; case GL_ZERO: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZPASS_ZERO; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO; break; case GL_REPLACE: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZPASS_REPLACE; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE; break; case GL_INCR: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZPASS_INC; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC; break; case GL_DECR: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZPASS_DEC; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC; break; case GL_INVERT: - rmesa->state.hw.context.rb3d_zstencilcntl |= RADEON_STENCIL_ZPASS_INVERT; + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT; break; } } @@ -681,9 +1355,10 @@ static void radeonClearStencil( GLcontext *ctx, GLint s ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - rmesa->state.stencil.clear = ((GLuint) ctx->Stencil.Clear | - (0xff << RADEON_STENCIL_MASK_SHIFT) | - (ctx->Stencil.WriteMask << RADEON_STENCIL_WRITEMASK_SHIFT)); + rmesa->state.stencil.clear = + ((GLuint) ctx->Stencil.Clear | + (0xff << RADEON_STENCIL_MASK_SHIFT) | + (ctx->Stencil.WriteMask << RADEON_STENCIL_WRITEMASK_SHIFT)); } @@ -695,6 +1370,7 @@ static void radeonClearStencil( GLcontext *ctx, GLint s ) * To correctly position primitives: */ #define SUBPIXEL_X 0.125 +#define SUBPIXEL_Y 0.125 void radeonUpdateWindow( GLcontext *ctx ) { @@ -707,20 +1383,18 @@ void radeonUpdateWindow( GLcontext *ctx ) GLfloat sx = v[MAT_SX]; GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; GLfloat sy = - v[MAT_SY]; - GLfloat ty = (- v[MAT_TY]) + yoffset; + GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y; GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale; GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale; - -/* fprintf(stderr, "radeonUpdateWindow %d,%d %dx%d\n", */ -/* dPriv->x, dPriv->y, dPriv->w, dPriv->h); */ - - RADEON_STATECHANGE(rmesa, RADEON_UPLOAD_VIEWPORT); - rmesa->state.hw.viewport.se_vport_xscale = *(GLuint *)&sx; - rmesa->state.hw.viewport.se_vport_xoffset = *(GLuint *)&tx; - rmesa->state.hw.viewport.se_vport_yscale = *(GLuint *)&sy; - rmesa->state.hw.viewport.se_vport_yoffset = *(GLuint *)&ty; - rmesa->state.hw.viewport.se_vport_zscale = *(GLuint *)&sz; - rmesa->state.hw.viewport.se_vport_zoffset = *(GLuint *)&tz; + RADEON_FIREVERTICES( rmesa ); + RADEON_STATECHANGE( rmesa, vpt ); + + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = *(GLuint *)&sx; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = *(GLuint *)&sy; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = *(GLuint *)&sz; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = *(GLuint *)&tz; } @@ -753,29 +1427,19 @@ void radeonUpdateViewportOffset( GLcontext *ctx ) GLfloat tx = v[MAT_TX] + xoffset; GLfloat ty = (- v[MAT_TY]) + yoffset; - if ( rmesa->state.hw.viewport.se_vport_xoffset != tx || - rmesa->state.hw.viewport.se_vport_yoffset != ty ) + if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != *(GLuint *)&tx || + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != *(GLuint *)&ty ) { - rmesa->state.hw.viewport.se_vport_xoffset = *(GLuint *)&tx; - rmesa->state.hw.viewport.se_vport_yoffset = *(GLuint *)&ty; - - if (rmesa->store.statenr) { - int i; - rmesa->store.state[0].dirty |= RADEON_UPLOAD_VIEWPORT; - /* Note: assume vport x/yoffset are constant over the buffer: - */ - for (i = 0 ; i < rmesa->store.statenr ; i++) { - rmesa->store.state[i].viewport.se_vport_xoffset = *(GLuint *)&tx; - rmesa->store.state[i].viewport.se_vport_yoffset = *(GLuint *)&ty; - } - } else { - rmesa->state.hw.dirty |= RADEON_UPLOAD_VIEWPORT; - } - + /* Note: this should also modify whatever data the context reset + * code uses... + */ + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty; + /* update polygon stipple x/y screen offset */ { GLuint stx, sty; - GLuint m = rmesa->state.hw.misc.re_misc; + GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC]; m &= ~(RADEON_STIPPLE_X_OFFSET_MASK | RADEON_STIPPLE_Y_OFFSET_MASK); @@ -788,9 +1452,9 @@ void radeonUpdateViewportOffset( GLcontext *ctx ) m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) | (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT)); - if ( rmesa->state.hw.misc.re_misc != m ) { - rmesa->state.hw.misc.re_misc = m; - RADEON_STATECHANGE(rmesa, RADEON_UPLOAD_MISC); + if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) { + RADEON_STATECHANGE( rmesa, msc ); + rmesa->hw.msc.cmd[MSC_RE_MISC] = m; } } } @@ -845,8 +1509,8 @@ static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode ) ASSERT( rop < 16 ); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_MASKS ); - rmesa->state.hw.mask.rb3d_ropcntl = radeon_rop_tab[rop]; + RADEON_STATECHANGE( rmesa, msk ); + rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop]; } @@ -860,7 +1524,9 @@ void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode ) rmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects; break; case GL_BACK_LEFT: - if ( dPriv->numBackClipRects == 0 ) { + /* Can't ignore 2d windows if we are page flipping. + */ + if ( dPriv->numBackClipRects == 0 || rmesa->doPageFlip ) { rmesa->numClipRects = dPriv->numClipRects; rmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects; } @@ -870,10 +1536,12 @@ void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode ) } break; default: + fprintf(stderr, "bad mode in radeonSetCliprects\n"); return; } - rmesa->upload_cliprects = 1; + if (rmesa->state.scissor.enabled) + radeonRecalcScissorRects( rmesa ); } @@ -881,19 +1549,37 @@ static void radeonSetDrawBuffer( GLcontext *ctx, GLenum mode ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr( mode )); + RADEON_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */ switch ( mode ) { case GL_FRONT_LEFT: FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE ); - rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; + rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; + } else { + rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; + rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; + } + rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset; + rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch; radeonSetCliprects( rmesa, GL_FRONT_LEFT ); break; case GL_BACK_LEFT: FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE ); - rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; + rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; + } else { + rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; + rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; + } + rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset; + rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch; radeonSetCliprects( rmesa, GL_BACK_LEFT ); break; default: @@ -901,10 +1587,10 @@ static void radeonSetDrawBuffer( GLcontext *ctx, GLenum mode ) return; } - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - rmesa->state.hw.context.rb3d_coloroffset = (rmesa->state.color.drawOffset & + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = (rmesa->state.color.drawOffset & RADEON_COLOROFFSET_MASK); - rmesa->state.hw.context.rb3d_colorpitch = rmesa->state.color.drawPitch; + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; } @@ -915,9 +1601,10 @@ static void radeonSetDrawBuffer( GLcontext *ctx, GLenum mode ) static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint p, flag; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) - fprintf( stderr, "%s( %s = %s )\n",__FUNCTION__, + if ( RADEON_DEBUG & DEBUG_STATE ) + fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr( cap ), state ? "GL_TRUE" : "GL_FALSE" ); @@ -930,369 +1617,487 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) break; case GL_ALPHA_TEST: - RADEON_STATECHANGE(rmesa, RADEON_UPLOAD_CONTEXT); + RADEON_STATECHANGE( rmesa, ctx ); if (state) { - rmesa->state.hw.context.pp_cntl |= RADEON_ALPHA_TEST_ENABLE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE; } else { - rmesa->state.hw.context.pp_cntl &= ~RADEON_ALPHA_TEST_ENABLE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE; } break; case GL_BLEND: - RADEON_STATECHANGE(rmesa, RADEON_UPLOAD_CONTEXT); + RADEON_STATECHANGE( rmesa, ctx ); if (state) { - rmesa->state.hw.context.rb3d_cntl |= RADEON_ALPHA_BLEND_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE; + } + if ( ctx->Color.ColorLogicOpEnabled ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE; } else { - rmesa->state.hw.context.rb3d_cntl &= ~RADEON_ALPHA_BLEND_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE; } break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + p = cap-GL_CLIP_PLANE0; + RADEON_STATECHANGE( rmesa, tcl ); + if (state) { + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p); + radeonClipPlane( ctx, cap, NULL ); + } + else { + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p); + } + break; + + case GL_COLOR_MATERIAL: + radeonColorMaterial( ctx, 0, 0 ); + if (!state) + radeonUpdateMaterial( ctx ); + break; + case GL_CULL_FACE: radeonCullFace( ctx, 0 ); break; case GL_DEPTH_TEST: - RADEON_STATECHANGE(rmesa, RADEON_UPLOAD_CONTEXT); + RADEON_STATECHANGE(rmesa, ctx ); if ( state ) { - rmesa->state.hw.context.rb3d_cntl |= RADEON_Z_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE; } else { - rmesa->state.hw.context.rb3d_cntl &= ~RADEON_Z_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE; } break; case GL_DITHER: - RADEON_STATECHANGE(rmesa, RADEON_UPLOAD_CONTEXT); + RADEON_STATECHANGE(rmesa, ctx ); if ( state ) { - rmesa->state.hw.context.rb3d_cntl |= RADEON_DITHER_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE; } else { - rmesa->state.hw.context.rb3d_cntl &= ~RADEON_DITHER_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE; } break; case GL_FOG: - RADEON_STATECHANGE(rmesa, RADEON_UPLOAD_CONTEXT); + RADEON_STATECHANGE(rmesa, ctx ); if ( state ) { - rmesa->state.hw.context.pp_cntl |= RADEON_FOG_ENABLE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE; + radeonFogfv( ctx, GL_FOG_MODE, 0 ); } else { - rmesa->state.hw.context.pp_cntl &= ~RADEON_FOG_ENABLE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE; + RADEON_STATECHANGE(rmesa, tcl); + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK; } + radeonUpdateSpecular( ctx ); /* for PK_SPEC */ + if (rmesa->TclFallback) + radeonChooseVertexState( ctx ); + break; + + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + RADEON_STATECHANGE(rmesa, tcl); + p = cap - GL_LIGHT0; + if (p&1) + flag = (RADEON_LIGHT_1_ENABLE | + RADEON_LIGHT_1_ENABLE_AMBIENT | + RADEON_LIGHT_1_ENABLE_SPECULAR); + else + flag = (RADEON_LIGHT_0_ENABLE | + RADEON_LIGHT_0_ENABLE_AMBIENT | + RADEON_LIGHT_0_ENABLE_SPECULAR); + + if (state) + rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag; + else + rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag; + + /* + */ + update_light_colors( ctx, p ); break; case GL_LIGHTING: + RADEON_STATECHANGE(rmesa, tcl); + if (state) { +/* rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; */ +/* rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; */ + } + else { +/* rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; */ +/* rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; */ + } radeonUpdateSpecular(ctx); + check_twoside_fallback( ctx ); break; case GL_LINE_SMOOTH: - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); + RADEON_STATECHANGE( rmesa, ctx ); if ( state ) { - rmesa->state.hw.context.pp_cntl |= RADEON_ANTI_ALIAS_LINE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE; } else { - rmesa->state.hw.context.pp_cntl &= ~RADEON_ANTI_ALIAS_LINE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE; } break; case GL_LINE_STIPPLE: - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); + RADEON_STATECHANGE( rmesa, ctx ); if ( state ) { - rmesa->state.hw.context.pp_cntl |= RADEON_PATTERN_ENABLE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE; } else { - rmesa->state.hw.context.pp_cntl &= ~RADEON_PATTERN_ENABLE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE; } break; case GL_COLOR_LOGIC_OP: - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); + RADEON_STATECHANGE( rmesa, ctx ); if ( state ) { - rmesa->state.hw.context.rb3d_cntl |= RADEON_ROP_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE; } else { - rmesa->state.hw.context.rb3d_cntl &= ~RADEON_ROP_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE; } break; - - case GL_POLYGON_OFFSET_POINT: - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_SETUP ); + + case GL_NORMALIZE: + RADEON_STATECHANGE( rmesa, tcl ); if ( state ) { - rmesa->state.hw.setup1.se_cntl |= RADEON_ZBIAS_ENABLE_POINT; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS; } else { - rmesa->state.hw.setup1.se_cntl &= ~RADEON_ZBIAS_ENABLE_POINT; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS; + } + break; + + case GL_POLYGON_OFFSET_POINT: + if (rmesa->dri.drmMinor == 1) { + radeonChooseRenderState( ctx ); + } + else { + RADEON_STATECHANGE( rmesa, set ); + if ( state ) { + rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT; + } else { + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT; + } } break; case GL_POLYGON_OFFSET_LINE: - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_SETUP ); - if ( state ) { - rmesa->state.hw.setup1.se_cntl |= RADEON_ZBIAS_ENABLE_LINE; - } else { - rmesa->state.hw.setup1.se_cntl &= ~RADEON_ZBIAS_ENABLE_LINE; + if (rmesa->dri.drmMinor == 1) { + radeonChooseRenderState( ctx ); + } + else { + RADEON_STATECHANGE( rmesa, set ); + if ( state ) { + rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE; + } else { + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE; + } } break; case GL_POLYGON_OFFSET_FILL: - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_SETUP ); - if ( state ) { - rmesa->state.hw.setup1.se_cntl |= RADEON_ZBIAS_ENABLE_TRI; - } else { - rmesa->state.hw.setup1.se_cntl &= ~RADEON_ZBIAS_ENABLE_TRI; + if (rmesa->dri.drmMinor == 1) { + radeonChooseRenderState( ctx ); + } + else { + RADEON_STATECHANGE( rmesa, set ); + if ( state ) { + rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI; + } else { + rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI; + } } break; case GL_POLYGON_SMOOTH: - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); + RADEON_STATECHANGE( rmesa, ctx ); if ( state ) { - rmesa->state.hw.context.pp_cntl |= RADEON_ANTI_ALIAS_POLY; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY; } else { - rmesa->state.hw.context.pp_cntl &= ~RADEON_ANTI_ALIAS_POLY; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY; } break; case GL_POLYGON_STIPPLE: - RADEON_STATECHANGE(rmesa, RADEON_UPLOAD_CONTEXT); + RADEON_STATECHANGE(rmesa, ctx ); if ( state ) { - rmesa->state.hw.context.pp_cntl |= RADEON_STIPPLE_ENABLE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE; } else { - rmesa->state.hw.context.pp_cntl &= ~RADEON_STIPPLE_ENABLE; + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE; } break; + case GL_RESCALE_NORMAL_EXT: { + GLboolean tmp = ctx->_NeedEyeCoords ? state : !state; + RADEON_STATECHANGE( rmesa, tcl ); + if ( tmp ) { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS; + } else { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS; + } + break; + } + case GL_SCISSOR_TEST: RADEON_FIREVERTICES( rmesa ); rmesa->state.scissor.enabled = state; - rmesa->upload_cliprects = 1; + radeonUpdateScissor( ctx ); break; case GL_STENCIL_TEST: if ( rmesa->state.stencil.hwBuffer ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); + RADEON_STATECHANGE( rmesa, ctx ); if ( state ) { - rmesa->state.hw.context.rb3d_cntl |= RADEON_STENCIL_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE; } else { - rmesa->state.hw.context.rb3d_cntl &= ~RADEON_STENCIL_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE; } } else { FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state ); } break; + case GL_TEXTURE_GEN_Q: + case GL_TEXTURE_GEN_R: + case GL_TEXTURE_GEN_S: + case GL_TEXTURE_GEN_T: + /* Picked up in radeonUpdateTextureState. + */ + rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE; + break; + + case GL_COLOR_SUM_EXT: + radeonUpdateSpecular ( ctx ); + break; + default: return; } } +static void radeonLightingSpaceChange( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLboolean tmp; + RADEON_STATECHANGE( rmesa, tcl ); + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s %d\n", __FUNCTION__, ctx->_NeedEyeCoords); + + if (ctx->_NeedEyeCoords) + tmp = ctx->Transform.RescaleNormals; + else + tmp = !ctx->Transform.RescaleNormals; + + if ( tmp ) { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS; + } else { + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS; + } +} + /* ============================================================= - * State initialization, management + * Deferred state management - matrices, textures, other? */ -void radeonPrintDirty( const char *msg, GLuint state ) -{ - fprintf( stderr, - "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n", - msg, - state, - (state & RADEON_UPLOAD_CONTEXT) ? "context, " : "", - (state & RADEON_UPLOAD_LINE) ? "line, " : "", - (state & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "", - (state & RADEON_UPLOAD_MASKS) ? "masks, " : "", - (state & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "", - (state & RADEON_UPLOAD_SETUP) ? "setup, " : "", - (state & RADEON_UPLOAD_TCL) ? "tcl, " : "", - (state & RADEON_UPLOAD_MISC) ? "misc, " : "", - (state & RADEON_UPLOAD_TEX0) ? "tex0, " : "", - (state & RADEON_UPLOAD_TEX1) ? "tex1, " : "", - (state & RADEON_UPLOAD_TEX2) ? "tex2, " : ""); -} +static void upload_matrix( radeonContextPtr rmesa, GLfloat *src, int idx ) +{ + float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0; + int i; + + for (i = 0 ; i < 4 ; i++) { + *dest++ = src[i]; + *dest++ = src[i+4]; + *dest++ = src[i+8]; + *dest++ = src[i+12]; + } -static void radeonInvalidateState( GLcontext *ctx, GLuint new_state ) + RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] ); +} + +static void upload_matrix_t( radeonContextPtr rmesa, GLfloat *src, int idx ) { - _swrast_InvalidateState( ctx, new_state ); - _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); - _tnl_InvalidateState( ctx, new_state ); - RADEON_CONTEXT(ctx)->NewGLState |= new_state; + float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0; + memcpy(dest, src, 16*sizeof(float)); + RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] ); } +static void update_texturematrix( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL]; + GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]; + int unit; + rmesa->TexMatEnabled = 0; -/* Initialize the context's hardware state. - */ -void radeonInitState( radeonContextPtr rmesa ) -{ - GLcontext *ctx = rmesa->glCtx; - GLuint color_fmt, depth_fmt; + for (unit = 0 ; unit < 2; unit++) { + if (!ctx->Texture.Unit[unit]._ReallyEnabled) { + } + else if (ctx->TextureMatrix[unit].type != MATRIX_IDENTITY) { + GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4; + + rmesa->TexMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE| + RADEON_TEXMAT_0_ENABLE) << unit; + + if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) { + /* Need to preconcatenate any active texgen + * obj/eyeplane matrices: + */ + _math_matrix_mul_matrix( &rmesa->tmpmat, + &rmesa->TexGenMatrix[unit], + &ctx->TextureMatrix[unit] ); + upload_matrix( rmesa, rmesa->tmpmat.m, TEXMAT_0+unit ); + } + else { + rmesa->TexMatEnabled |= + (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; + upload_matrix( rmesa, ctx->TextureMatrix[unit].m, + TEXMAT_0+unit ); + } + } + else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) { + upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m, + TEXMAT_0+unit ); + } + } - switch ( rmesa->radeonScreen->cpp ) { - case 2: - color_fmt = RADEON_COLOR_FORMAT_RGB565; - break; - case 4: - color_fmt = RADEON_COLOR_FORMAT_ARGB8888; - break; - default: - fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); - exit( -1 ); + + tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled); + + vs &= ~((0xf << RADEON_TCL_TEX_0_OUTPUT_SHIFT) | + (0xf << RADEON_TCL_TEX_1_OUTPUT_SHIFT)); + + if (tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) + vs |= RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT; + else + vs |= RADEON_TCL_TEX_INPUT_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT; + + if (tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) + vs |= RADEON_TCL_TEX_COMPUTED_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT; + else + vs |= RADEON_TCL_TEX_INPUT_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT; + + if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] || + vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) { + + RADEON_STATECHANGE(rmesa, tcl); + rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs; } +} - rmesa->state.color.clear = 0x00000000; - switch ( ctx->Visual.depthBits ) { - case 16: - rmesa->state.depth.clear = 0x0000ffff; - rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff; - depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; - rmesa->state.stencil.clear = 0x00000000; - break; - case 24: - rmesa->state.depth.clear = 0x00ffffff; - rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff; - depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; - rmesa->state.stencil.clear = 0xffff0000; - break; - default: - fprintf( stderr, "Error: Unsupported depth %d... exiting\n", - ctx->Visual.depthBits ); - exit( -1 ); + +void radeonValidateState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint new_state = rmesa->NewGLState; + + if (new_state & _NEW_TEXTURE) { + radeonUpdateTextureState( ctx ); + new_state |= rmesa->NewGLState; /* may add TEXTURE_MATRIX */ } - /* Only have hw stencil when depth buffer is 24 bits deep */ - rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && - ctx->Visual.depthBits == 24 ); + /* Need an event driven matrix update? + */ + if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) + upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ ); - rmesa->RenderIndex = ~0; - rmesa->Fallback = 0; - rmesa->render_primitive = GL_TRIANGLES; - rmesa->hw_primitive = RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST; + /* Need these for lighting (shouldn't upload otherwise) + */ + if (new_state & (_NEW_MODELVIEW)) { + upload_matrix( rmesa, ctx->ModelView.m, MODEL ); + upload_matrix_t( rmesa, ctx->ModelView.inv, MODEL_IT ); + } - if ( ctx->Visual.doubleBufferMode ) { - rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; - } else { - rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; + /* Does this need to be triggered on eg. modelview for + * texgen-derived objplane/eyeplane matrices? + */ + if (new_state & _NEW_TEXTURE_MATRIX) { + update_texturematrix( ctx ); + } + + if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) { + update_light( ctx ); } - rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset; - rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch; - /* Harware state: + /* emit all active clip planes if projection matrix changes. */ - rmesa->state.hw.context.pp_misc = (RADEON_ALPHA_TEST_PASS | - RADEON_CHROMA_FUNC_FAIL | - RADEON_CHROMA_KEY_NEAREST | - RADEON_SHADOW_FUNC_EQUAL | - RADEON_SHADOW_PASS_1 | - RADEON_RIGHT_HAND_CUBE_OGL); + if (new_state & (_NEW_PROJECTION)) { + if (ctx->Transform._AnyClip) + radeonUpdateClipPlanes( ctx ); + } - rmesa->state.hw.context.pp_fog_color = ((0x00000000 & RADEON_FOG_COLOR_MASK) | - RADEON_FOG_VERTEX | - RADEON_FOG_USE_DEPTH); - rmesa->state.hw.context.re_solid_color = 0x00000000; + rmesa->NewGLState = 0; +} - rmesa->state.hw.context.rb3d_blendcntl = (RADEON_COMB_FCN_ADD_CLAMP | - RADEON_SRC_BLEND_GL_ONE | - RADEON_DST_BLEND_GL_ZERO ); - rmesa->state.hw.context.rb3d_depthoffset = rmesa->radeonScreen->depthOffset; +static void radeonInvalidateState( GLcontext *ctx, GLuint new_state ) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + _ae_invalidate_state( ctx, new_state ); + RADEON_CONTEXT(ctx)->NewGLState |= new_state; + radeonVtxfmtInvalidate( ctx ); +} - rmesa->state.hw.context.rb3d_depthpitch = ((rmesa->radeonScreen->depthPitch & - RADEON_DEPTHPITCH_MASK) | - RADEON_DEPTH_ENDIAN_NO_SWAP); +static void radeonWrapRunPipeline( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); - rmesa->state.hw.context.rb3d_zstencilcntl = (depth_fmt | - RADEON_Z_TEST_LESS | - RADEON_STENCIL_TEST_ALWAYS | - RADEON_STENCIL_FAIL_KEEP | - RADEON_STENCIL_ZPASS_KEEP | - RADEON_STENCIL_ZFAIL_KEEP | - RADEON_Z_WRITE_ENABLE); + if (0) + fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->NewGLState); - rmesa->state.hw.context.pp_cntl = (RADEON_SCISSOR_ENABLE | - RADEON_ANTI_ALIAS_NONE); + /* Validate state: + */ + if (rmesa->NewGLState) + radeonValidateState( ctx ); - rmesa->state.hw.context.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | - color_fmt | - RADEON_ZBLOCK16); + if (tnl->vb.Material) { + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE ); + } - rmesa->state.hw.context.rb3d_coloroffset = (rmesa->state.color.drawOffset & - RADEON_COLOROFFSET_MASK); + /* Run the pipeline. + */ + _tnl_run_pipeline( ctx ); - rmesa->state.hw.context.re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) | - (0x7ff << RADEON_RE_HEIGHT_SHIFT)); - - rmesa->state.hw.context.rb3d_colorpitch = ((rmesa->state.color.drawPitch & - RADEON_COLORPITCH_MASK) | - RADEON_COLOR_ENDIAN_NO_SWAP); - - rmesa->state.hw.setup1.se_cntl = (RADEON_FFACE_CULL_CCW | - RADEON_BFACE_SOLID | - RADEON_FFACE_SOLID | - RADEON_FLAT_SHADE_VTX_LAST | - RADEON_DIFFUSE_SHADE_GOURAUD | - RADEON_ALPHA_SHADE_GOURAUD | - RADEON_SPECULAR_SHADE_GOURAUD | - RADEON_FOG_SHADE_GOURAUD | - RADEON_VPORT_XY_XFORM_ENABLE | - RADEON_VPORT_Z_XFORM_ENABLE | - RADEON_VTX_PIX_CENTER_OGL | - RADEON_ROUND_MODE_TRUNC | - RADEON_ROUND_PREC_8TH_PIX); - - rmesa->state.hw.vertex.se_coord_fmt = ( -#if 1 - RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | - RADEON_VTX_Z_PRE_MULT_1_OVER_W0 | -#else - RADEON_VTX_W0_IS_NOT_1_OVER_W0 | -#endif - RADEON_TEX1_W_ROUTING_USE_Q1); - - rmesa->state.hw.setup2.se_cntl_status = (RADEON_VC_NO_SWAP | - RADEON_TCL_BYPASS); - - rmesa->state.hw.line.re_line_pattern = ((0x0000 & RADEON_LINE_PATTERN_MASK) | - (0 << RADEON_LINE_REPEAT_COUNT_SHIFT) | - (0 << RADEON_LINE_PATTERN_START_SHIFT) | - RADEON_LINE_PATTERN_LITTLE_BIT_ORDER); - - rmesa->state.hw.line.re_line_state = ((0 << RADEON_LINE_CURRENT_PTR_SHIFT) | - (1 << RADEON_LINE_CURRENT_COUNT_SHIFT)); - - rmesa->state.hw.line.se_line_width = (1 << 4); - - rmesa->state.hw.bumpmap.pp_lum_matrix = 0x00000000; - rmesa->state.hw.bumpmap.pp_rot_matrix_0 = 0x00000000; - rmesa->state.hw.bumpmap.pp_rot_matrix_1 = 0x00000000; - - rmesa->state.hw.mask.rb3d_stencilrefmask = ((0x00 << RADEON_STENCIL_REF_SHIFT) | - (0xff << RADEON_STENCIL_MASK_SHIFT) | - (0xff << RADEON_STENCIL_WRITEMASK_SHIFT)); - - rmesa->state.hw.mask.rb3d_ropcntl = RADEON_ROP_COPY; - rmesa->state.hw.mask.rb3d_planemask = 0xffffffff; - - rmesa->state.hw.viewport.se_vport_xscale = 0x00000000; - rmesa->state.hw.viewport.se_vport_xoffset = 0x00000000; - rmesa->state.hw.viewport.se_vport_yscale = 0x00000000; - rmesa->state.hw.viewport.se_vport_yoffset = 0x00000000; - rmesa->state.hw.viewport.se_vport_zscale = 0x00000000; - rmesa->state.hw.viewport.se_vport_zoffset = 0x00000000; - - rmesa->state.hw.misc.re_misc = ((0 << RADEON_STIPPLE_X_OFFSET_SHIFT) | - (0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) | - RADEON_STIPPLE_BIG_BIT_ORDER); - - rmesa->state.hw.dirty = RADEON_UPLOAD_CONTEXT_ALL; + if (tnl->vb.Material) { + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE ); + radeonUpdateMaterial( ctx ); /* not needed any more? */ + } } + + + /* Initialize the driver's state functions. */ void radeonInitStateFuncs( GLcontext *ctx ) { ctx->Driver.UpdateState = radeonInvalidateState; + ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange; ctx->Driver.SetDrawBuffer = radeonSetDrawBuffer; @@ -1304,6 +2109,7 @@ void radeonInitStateFuncs( GLcontext *ctx ) ctx->Driver.ClearDepth = radeonClearDepth; ctx->Driver.ClearIndex = NULL; ctx->Driver.ClearStencil = radeonClearStencil; + ctx->Driver.ClipPlane = radeonClipPlane; ctx->Driver.ColorMask = radeonColorMask; ctx->Driver.CullFace = radeonCullFace; ctx->Driver.DepthFunc = radeonDepthFunc; @@ -1315,12 +2121,15 @@ void radeonInitStateFuncs( GLcontext *ctx ) ctx->Driver.Hint = NULL; ctx->Driver.IndexMask = NULL; ctx->Driver.LightModelfv = radeonLightModelfv; - ctx->Driver.Lightfv = NULL; + ctx->Driver.Lightfv = radeonLightfv; ctx->Driver.LineStipple = radeonLineStipple; ctx->Driver.LineWidth = radeonLineWidth; ctx->Driver.LogicOpcode = radeonLogicOpCode; - ctx->Driver.PolygonMode = NULL; - ctx->Driver.PolygonOffset = radeonPolygonOffset; + ctx->Driver.PolygonMode = radeonPolygonMode; + + if (RADEON_CONTEXT(ctx)->dri.drmMinor > 1) + ctx->Driver.PolygonOffset = radeonPolygonOffset; + ctx->Driver.PolygonStipple = radeonPolygonStipple; ctx->Driver.RenderMode = radeonRenderMode; ctx->Driver.Scissor = radeonScissor; @@ -1337,7 +2146,6 @@ void radeonInitStateFuncs( GLcontext *ctx ) ctx->Driver.CopyPixels = _swrast_CopyPixels; ctx->Driver.DrawPixels = _swrast_DrawPixels; ctx->Driver.ReadPixels = _swrast_ReadPixels; - ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; /* Swrast hooks for imaging extensions: */ @@ -1345,4 +2153,7 @@ void radeonInitStateFuncs( GLcontext *ctx ) ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial; + TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline; } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h index b34e17133..45a368d95 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.h,v 1.3 2002/09/16 18:05:20 eich Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.h,v 1.5 2002/11/05 17:46:09 tsi Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -44,20 +44,33 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void radeonInitState( radeonContextPtr rmesa ); extern void radeonInitStateFuncs( GLcontext *ctx ); -extern void radeonUpdateWindow( GLcontext *ctx ); +extern void radeonUpdateMaterial( GLcontext *ctx ); + extern void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode ); +extern void radeonRecalcScissorRects( radeonContextPtr rmesa ); extern void radeonUpdateViewportOffset( GLcontext *ctx ); +extern void radeonUpdateWindow( GLcontext *ctx ); -extern void radeonPrintDirty( const char *msg, GLuint state ); +extern void radeonValidateState( GLcontext *ctx ); + +extern void radeonPrintDirty( radeonContextPtr rmesa, + const char *msg ); extern void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); #define FALLBACK( rmesa, bit, mode ) do { \ - if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n",__FUNCTION__, \ - bit, mode ); \ + if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \ + __FUNCTION__, bit, mode ); \ radeonFallback( rmesa->glCtx, bit, mode ); \ } while (0) +#define MODEL_PROJ 0 +#define MODEL 1 +#define MODEL_IT 2 +#define TEXMAT_0 3 +#define TEXMAT_1 4 +#define TEXMAT_2 5 + #endif #endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state_init.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state_init.c new file mode 100644 index 000000000..79c07e863 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state_init.c @@ -0,0 +1,556 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state_init.c,v 1.3 2003/02/22 06:21:11 dawes Exp $ */ +/* + * Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_tcl.h" +#include "radeon_tex.h" +#include "radeon_swtcl.h" +#include "radeon_vtxfmt.h" + +#include "mem.h" +#include "mmath.h" +#include "enums.h" +#include "colormac.h" +#include "light.h" +#include "api_arrayelt.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "swrast_setup/swrast_setup.h" + +/* ============================================================= + * State initialization + */ + +void radeonPrintDirty( radeonContextPtr rmesa, const char *msg ) +{ + struct radeon_state_atom *l; + + fprintf(stderr, msg); + fprintf(stderr, ": "); + + foreach(l, &(rmesa->hw.dirty)) { + fprintf(stderr, "%s, ", l->name); + } + + fprintf(stderr, "\n"); +} + +static int cmdpkt( int id ) +{ + drmRadeonCmdHeader h; + h.i = 0; + h.packet.cmd_type = RADEON_CMD_PACKET; + h.packet.packet_id = id; + return h.i; +} + +static int cmdvec( int offset, int stride, int count ) +{ + drmRadeonCmdHeader h; + h.i = 0; + h.vectors.cmd_type = RADEON_CMD_VECTORS; + h.vectors.offset = offset; + h.vectors.stride = stride; + h.vectors.count = count; + return h.i; +} + +static int cmdscl( int offset, int stride, int count ) +{ + drmRadeonCmdHeader h; + h.i = 0; + h.scalars.cmd_type = RADEON_CMD_SCALARS; + h.scalars.offset = offset; + h.scalars.stride = stride; + h.scalars.count = count; + return h.i; +} + +#define CHECK( NM, FLAG ) \ +static GLboolean check_##NM( GLcontext *ctx ) \ +{ \ + return FLAG; \ +} + +#define TCL_CHECK( NM, FLAG ) \ +static GLboolean check_##NM( GLcontext *ctx ) \ +{ \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + return !rmesa->TclFallback && (FLAG); \ +} + + +CHECK( always, GL_TRUE ) +CHECK( tex0, ctx->Texture.Unit[0]._ReallyEnabled ) +CHECK( tex1, ctx->Texture.Unit[1]._ReallyEnabled ) +CHECK( fog, ctx->Fog.Enabled ) +TCL_CHECK( tcl, GL_TRUE ) +TCL_CHECK( tcl_tex0, ctx->Texture.Unit[0]._ReallyEnabled ) +TCL_CHECK( tcl_tex1, ctx->Texture.Unit[1]._ReallyEnabled ) +TCL_CHECK( tcl_lighting, ctx->Light.Enabled ) +TCL_CHECK( tcl_eyespace_or_lighting, ctx->_NeedEyeCoords || ctx->Light.Enabled ) +TCL_CHECK( tcl_lit0, ctx->Light.Enabled && ctx->Light.Light[0].Enabled ) +TCL_CHECK( tcl_lit1, ctx->Light.Enabled && ctx->Light.Light[1].Enabled ) +TCL_CHECK( tcl_lit2, ctx->Light.Enabled && ctx->Light.Light[2].Enabled ) +TCL_CHECK( tcl_lit3, ctx->Light.Enabled && ctx->Light.Light[3].Enabled ) +TCL_CHECK( tcl_lit4, ctx->Light.Enabled && ctx->Light.Light[4].Enabled ) +TCL_CHECK( tcl_lit5, ctx->Light.Enabled && ctx->Light.Light[5].Enabled ) +TCL_CHECK( tcl_lit6, ctx->Light.Enabled && ctx->Light.Light[6].Enabled ) +TCL_CHECK( tcl_lit7, ctx->Light.Enabled && ctx->Light.Light[7].Enabled ) +TCL_CHECK( tcl_ucp0, ctx->Transform.ClipEnabled[0] ) +TCL_CHECK( tcl_ucp1, ctx->Transform.ClipEnabled[1] ) +TCL_CHECK( tcl_ucp2, ctx->Transform.ClipEnabled[2] ) +TCL_CHECK( tcl_ucp3, ctx->Transform.ClipEnabled[3] ) +TCL_CHECK( tcl_ucp4, ctx->Transform.ClipEnabled[4] ) +TCL_CHECK( tcl_ucp5, ctx->Transform.ClipEnabled[5] ) +TCL_CHECK( tcl_eyespace_or_fog, ctx->_NeedEyeCoords || ctx->Fog.Enabled ) + + + +/* Initialize the context's hardware state. + */ +void radeonInitState( radeonContextPtr rmesa ) +{ + GLcontext *ctx = rmesa->glCtx; + GLuint color_fmt, depth_fmt, i; + + switch ( rmesa->radeonScreen->cpp ) { + case 2: + color_fmt = RADEON_COLOR_FORMAT_RGB565; + break; + case 4: + color_fmt = RADEON_COLOR_FORMAT_ARGB8888; + break; + default: + fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); + exit( -1 ); + } + + rmesa->state.color.clear = 0x00000000; + + switch ( ctx->Visual.depthBits ) { + case 16: + rmesa->state.depth.clear = 0x0000ffff; + rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff; + depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; + rmesa->state.stencil.clear = 0x00000000; + break; + case 24: + rmesa->state.depth.clear = 0x00ffffff; + rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff; + depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; + rmesa->state.stencil.clear = 0xff000000; + break; + default: + fprintf( stderr, "Error: Unsupported depth %d... exiting\n", + ctx->Visual.depthBits ); + exit( -1 ); + } + + /* Only have hw stencil when depth buffer is 24 bits deep */ + rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && + ctx->Visual.depthBits == 24 ); + + rmesa->Fallback = 0; + + if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { + rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; + rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; + } else { + rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; + rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; + } + rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset; + rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch; + + /* Initialize lists: + */ + make_empty_list(&(rmesa->hw.dirty)); + make_empty_list(&(rmesa->hw.clean)); + + +#define ALLOC_STATE( ATOM, CHK, SZ, NM, FLAG ) \ + do { \ + rmesa->hw.ATOM.cmd_size = SZ; \ + rmesa->hw.ATOM.cmd = (int *)CALLOC(SZ * sizeof(int)); \ + rmesa->hw.ATOM.lastcmd = (int *)CALLOC(SZ * sizeof(int)); \ + rmesa->hw.ATOM.name = NM; \ + rmesa->hw.ATOM.is_tcl = FLAG; \ + rmesa->hw.ATOM.check = check_##CHK; \ + insert_at_head(&(rmesa->hw.dirty), &(rmesa->hw.ATOM)); \ + } while (0) + + + /* Allocate state buffers: + */ + ALLOC_STATE( ctx, always, CTX_STATE_SIZE, "CTX/context", 0 ); + ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 ); + ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 ); + ALLOC_STATE( vpt, always, VPT_STATE_SIZE, "VPT/viewport", 0 ); + ALLOC_STATE( set, always, SET_STATE_SIZE, "SET/setup", 0 ); + ALLOC_STATE( msc, always, MSC_STATE_SIZE, "MSC/misc", 0 ); + ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 ); + ALLOC_STATE( tcl, always, TCL_STATE_SIZE, "TCL/tcl", 1 ); + ALLOC_STATE( mtl, tcl_lighting, MTL_STATE_SIZE, "MTL/material", 1 ); + ALLOC_STATE( grd, always, GRD_STATE_SIZE, "GRD/guard-band", 1 ); + ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 1 ); + ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 1 ); + ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 1 ); + ALLOC_STATE( tex[0], tex0, TEX_STATE_SIZE, "TEX/tex-0", 0 ); + ALLOC_STATE( tex[1], tex1, TEX_STATE_SIZE, "TEX/tex-1", 0 ); + ALLOC_STATE( mat[0], tcl, MAT_STATE_SIZE, "MAT/modelproject", 1 ); + ALLOC_STATE( mat[1], tcl_eyespace_or_fog, MAT_STATE_SIZE, "MAT/modelview", 1 ); + ALLOC_STATE( mat[2], tcl_eyespace_or_lighting, MAT_STATE_SIZE, "MAT/it-modelview", 1 ); + ALLOC_STATE( mat[3], tcl_tex0, MAT_STATE_SIZE, "MAT/texmat0", 1 ); + ALLOC_STATE( mat[4], tcl_tex1, MAT_STATE_SIZE, "MAT/texmat1", 1 ); + ALLOC_STATE( ucp[0], tcl_ucp0, UCP_STATE_SIZE, "UCP/userclip-0", 1 ); + ALLOC_STATE( ucp[1], tcl_ucp1, UCP_STATE_SIZE, "UCP/userclip-1", 1 ); + ALLOC_STATE( ucp[2], tcl_ucp2, UCP_STATE_SIZE, "UCP/userclip-2", 1 ); + ALLOC_STATE( ucp[3], tcl_ucp3, UCP_STATE_SIZE, "UCP/userclip-3", 1 ); + ALLOC_STATE( ucp[4], tcl_ucp4, UCP_STATE_SIZE, "UCP/userclip-4", 1 ); + ALLOC_STATE( ucp[5], tcl_ucp5, UCP_STATE_SIZE, "UCP/userclip-5", 1 ); + ALLOC_STATE( lit[0], tcl_lit0, LIT_STATE_SIZE, "LIT/light-0", 1 ); + ALLOC_STATE( lit[1], tcl_lit1, LIT_STATE_SIZE, "LIT/light-1", 1 ); + ALLOC_STATE( lit[2], tcl_lit2, LIT_STATE_SIZE, "LIT/light-2", 1 ); + ALLOC_STATE( lit[3], tcl_lit3, LIT_STATE_SIZE, "LIT/light-3", 1 ); + ALLOC_STATE( lit[4], tcl_lit4, LIT_STATE_SIZE, "LIT/light-4", 1 ); + ALLOC_STATE( lit[5], tcl_lit5, LIT_STATE_SIZE, "LIT/light-5", 1 ); + ALLOC_STATE( lit[6], tcl_lit6, LIT_STATE_SIZE, "LIT/light-6", 1 ); + ALLOC_STATE( lit[7], tcl_lit7, LIT_STATE_SIZE, "LIT/light-7", 1 ); + + + /* Fill in the packet headers: + */ + rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(RADEON_EMIT_PP_MISC); + rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(RADEON_EMIT_PP_CNTL); + rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(RADEON_EMIT_RB3D_COLORPITCH); + rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(RADEON_EMIT_RE_LINE_PATTERN); + rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(RADEON_EMIT_SE_LINE_WIDTH); + rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(RADEON_EMIT_RB3D_STENCILREFMASK); + rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(RADEON_EMIT_SE_VPORT_XSCALE); + rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(RADEON_EMIT_SE_CNTL); + rmesa->hw.set.cmd[SET_CMD_1] = cmdpkt(RADEON_EMIT_SE_CNTL_STATUS); + rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(RADEON_EMIT_RE_MISC); + rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(RADEON_EMIT_PP_TXFILTER_0); + rmesa->hw.tex[0].cmd[TEX_CMD_1] = cmdpkt(RADEON_EMIT_PP_BORDER_COLOR_0); + rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(RADEON_EMIT_PP_TXFILTER_1); + rmesa->hw.tex[1].cmd[TEX_CMD_1] = cmdpkt(RADEON_EMIT_PP_BORDER_COLOR_1); + rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(RADEON_EMIT_SE_ZBIAS_FACTOR); + rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT); + rmesa->hw.mtl.cmd[MTL_CMD_0] = + cmdpkt(RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED); + rmesa->hw.grd.cmd[GRD_CMD_0] = + cmdscl( RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 ); + rmesa->hw.fog.cmd[FOG_CMD_0] = + cmdvec( RADEON_VS_FOG_PARAM_ADDR, 1, 4 ); + rmesa->hw.glt.cmd[GLT_CMD_0] = + cmdvec( RADEON_VS_GLOBAL_AMBIENT_ADDR, 1, 4 ); + rmesa->hw.eye.cmd[EYE_CMD_0] = + cmdvec( RADEON_VS_EYE_VECTOR_ADDR, 1, 4 ); + + for (i = 0 ; i < 5; i++) { + rmesa->hw.mat[i].cmd[MAT_CMD_0] = + cmdvec( RADEON_VS_MATRIX_0_ADDR + i*4, 1, 16); + } + + for (i = 0 ; i < 8; i++) { + rmesa->hw.lit[i].cmd[LIT_CMD_0] = + cmdvec( RADEON_VS_LIGHT_AMBIENT_ADDR + i, 8, 24 ); + rmesa->hw.lit[i].cmd[LIT_CMD_1] = + cmdscl( RADEON_SS_LIGHT_DCD_ADDR + i, 8, 6 ); + } + + for (i = 0 ; i < 6; i++) { + rmesa->hw.ucp[i].cmd[UCP_CMD_0] = + cmdvec( RADEON_VS_UCP_ADDR + i, 1, 4 ); + } + + rmesa->last_ReallyEnabled = -1; + + /* Initial Harware state: + */ + rmesa->hw.ctx.cmd[CTX_PP_MISC] = (RADEON_ALPHA_TEST_PASS | + RADEON_CHROMA_FUNC_FAIL | + RADEON_CHROMA_KEY_NEAREST | + RADEON_SHADOW_FUNC_EQUAL | + RADEON_SHADOW_PASS_1 | + RADEON_RIGHT_HAND_CUBE_OGL); + + rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = (RADEON_FOG_VERTEX | + RADEON_FOG_USE_DEPTH); + + rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000; + + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = (RADEON_COMB_FCN_ADD_CLAMP | + RADEON_SRC_BLEND_GL_ONE | + RADEON_DST_BLEND_GL_ZERO ); + + rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHOFFSET] = + rmesa->radeonScreen->depthOffset; + + rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHPITCH] = + ((rmesa->radeonScreen->depthPitch & + RADEON_DEPTHPITCH_MASK) | + RADEON_DEPTH_ENDIAN_NO_SWAP); + + rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (depth_fmt | + RADEON_Z_TEST_LESS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_FAIL_KEEP | + RADEON_STENCIL_ZPASS_KEEP | + RADEON_STENCIL_ZFAIL_KEEP | + RADEON_Z_WRITE_ENABLE); + + rmesa->hw.ctx.cmd[CTX_PP_CNTL] = (RADEON_SCISSOR_ENABLE | + RADEON_ANTI_ALIAS_NONE); + + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = (RADEON_PLANE_MASK_ENABLE | + color_fmt | + (1<<15)); + + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE; + + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = (rmesa->state.color.drawOffset & + RADEON_COLOROFFSET_MASK); + + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch & + RADEON_COLORPITCH_MASK) | + RADEON_COLOR_ENDIAN_NO_SWAP); + + rmesa->hw.set.cmd[SET_SE_CNTL] = (RADEON_FFACE_CULL_CCW | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | +/* RADEON_BADVTX_CULL_DISABLE | */ + RADEON_FLAT_SHADE_VTX_LAST | + RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_ALPHA_SHADE_GOURAUD | + RADEON_SPECULAR_SHADE_GOURAUD | + RADEON_FOG_SHADE_GOURAUD | + RADEON_VPORT_XY_XFORM_ENABLE | + RADEON_VPORT_Z_XFORM_ENABLE | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_TRUNC | + RADEON_ROUND_PREC_8TH_PIX); + + rmesa->hw.set.cmd[SET_SE_CNTL_STATUS] = +#ifdef MESA_BIG_ENDIAN + RADEON_VC_32BIT_SWAP; +#else + RADEON_VC_NO_SWAP; +#endif + + if (!(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)) { + rmesa->hw.set.cmd[SET_SE_CNTL_STATUS] |= RADEON_TCL_BYPASS; + } + + rmesa->hw.set.cmd[SET_SE_COORDFMT] = ( + RADEON_VTX_W0_IS_NOT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_Q1); + + + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = ((1 << 16) | 0xffff); + + rmesa->hw.lin.cmd[LIN_RE_LINE_STATE] = + ((0 << RADEON_LINE_CURRENT_PTR_SHIFT) | + (1 << RADEON_LINE_CURRENT_COUNT_SHIFT)); + + rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (1 << 4); + + rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] = + ((0x00 << RADEON_STENCIL_REF_SHIFT) | + (0xff << RADEON_STENCIL_MASK_SHIFT) | + (0xff << RADEON_STENCIL_WRITEMASK_SHIFT)); + + rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = RADEON_ROP_COPY; + rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = 0xffffffff; + + rmesa->hw.msc.cmd[MSC_RE_MISC] = + ((0 << RADEON_STIPPLE_X_OFFSET_SHIFT) | + (0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) | + RADEON_STIPPLE_BIG_BIT_ORDER); + + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = 0x00000000; + rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = 0x00000000; + + rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] = RADEON_BORDER_MODE_OGL; + rmesa->hw.tex[0].cmd[TEX_PP_TXFORMAT] = + (RADEON_TXFORMAT_ENDIAN_NO_SWAP | + RADEON_TXFORMAT_PERSPECTIVE_ENABLE | + RADEON_TXFORMAT_ST_ROUTE_STQ0 | + (2 << RADEON_TXFORMAT_WIDTH_SHIFT) | + (2 << RADEON_TXFORMAT_HEIGHT_SHIFT)); + rmesa->hw.tex[0].cmd[TEX_PP_TXOFFSET] = 0x2000; + rmesa->hw.tex[0].cmd[TEX_PP_BORDER_COLOR] = 0; + rmesa->hw.tex[0].cmd[TEX_PP_TXCBLEND] = + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX); + rmesa->hw.tex[0].cmd[TEX_PP_TXABLEND] = + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX); + rmesa->hw.tex[0].cmd[TEX_PP_TFACTOR] = 0; + + rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] = RADEON_BORDER_MODE_OGL; + rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] = + (RADEON_TXFORMAT_ENDIAN_NO_SWAP | + RADEON_TXFORMAT_PERSPECTIVE_ENABLE | + RADEON_TXFORMAT_ST_ROUTE_STQ1 | + (2 << RADEON_TXFORMAT_WIDTH_SHIFT) | + (2 << RADEON_TXFORMAT_HEIGHT_SHIFT)); + rmesa->hw.tex[1].cmd[TEX_PP_TXOFFSET] = 0x8000; + rmesa->hw.tex[1].cmd[TEX_PP_BORDER_COLOR] = 0; + rmesa->hw.tex[1].cmd[TEX_PP_TXCBLEND] = + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX); + rmesa->hw.tex[1].cmd[TEX_PP_TXABLEND] = + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX); + rmesa->hw.tex[1].cmd[TEX_PP_TFACTOR] = 0; + + /* Can oly add ST1 at the time of doing some multitex but can keep + * it after that. Errors if DIFFUSE is missing. + */ + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = + (RADEON_TCL_VTX_Z0 | + RADEON_TCL_VTX_W0 | + RADEON_TCL_VTX_PK_DIFFUSE + ); /* need to keep this uptodate */ + + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = + ( RADEON_TCL_COMPUTE_XYZW | + (RADEON_TCL_TEX_INPUT_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) | + (RADEON_TCL_TEX_INPUT_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) | + (RADEON_TCL_TEX_INPUT_TEX_2 << RADEON_TCL_TEX_2_OUTPUT_SHIFT)); + + + /* XXX */ + rmesa->hw.tcl.cmd[TCL_MATRIX_SELECT_0] = + ((MODEL << RADEON_MODELVIEW_0_SHIFT) | + (MODEL_IT << RADEON_IT_MODELVIEW_0_SHIFT)); + + rmesa->hw.tcl.cmd[TCL_MATRIX_SELECT_1] = + ((MODEL_PROJ << RADEON_MODELPROJECT_0_SHIFT) | + (TEXMAT_0 << RADEON_TEXMAT_0_SHIFT) | + (TEXMAT_1 << RADEON_TEXMAT_1_SHIFT)); + + rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = + (RADEON_UCP_IN_CLIP_SPACE | + RADEON_CULL_FRONT_IS_CCW); + + rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = 0; + + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = + (RADEON_SPECULAR_LIGHTS | + RADEON_DIFFUSE_SPECULAR_COMBINE | + RADEON_LOCAL_LIGHT_VEC_GL | + (RADEON_LM_SOURCE_STATE_PREMULT << RADEON_EMISSIVE_SOURCE_SHIFT) | + (RADEON_LM_SOURCE_STATE_PREMULT << RADEON_AMBIENT_SOURCE_SHIFT) | + (RADEON_LM_SOURCE_STATE_PREMULT << RADEON_DIFFUSE_SOURCE_SHIFT) | + (RADEON_LM_SOURCE_STATE_PREMULT << RADEON_SPECULAR_SOURCE_SHIFT)); + + for (i = 0 ; i < 8; i++) { + struct gl_light *l = &ctx->Light.Light[i]; + GLenum p = GL_LIGHT0 + i; + *(float *)&(rmesa->hw.lit[i].cmd[LIT_RANGE_CUTOFF]) = FLT_MAX; + + ctx->Driver.Lightfv( ctx, p, GL_AMBIENT, l->Ambient ); + ctx->Driver.Lightfv( ctx, p, GL_DIFFUSE, l->Diffuse ); + ctx->Driver.Lightfv( ctx, p, GL_SPECULAR, l->Specular ); + ctx->Driver.Lightfv( ctx, p, GL_POSITION, 0 ); + ctx->Driver.Lightfv( ctx, p, GL_SPOT_DIRECTION, 0 ); + ctx->Driver.Lightfv( ctx, p, GL_SPOT_EXPONENT, &l->SpotExponent ); + ctx->Driver.Lightfv( ctx, p, GL_SPOT_CUTOFF, &l->SpotCutoff ); + ctx->Driver.Lightfv( ctx, p, GL_CONSTANT_ATTENUATION, + &l->ConstantAttenuation ); + ctx->Driver.Lightfv( ctx, p, GL_LINEAR_ATTENUATION, + &l->LinearAttenuation ); + ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION, + &l->QuadraticAttenuation ); + } + + ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT, + ctx->Light.Model.Ambient ); + + TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx ); + + for (i = 0 ; i < 6; i++) { + ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, NULL ); + } + + ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); + ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); + ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); + ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); + ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); + ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, 0 ); + + + /* Set up vector and scalar state commands: + */ +/* upload_matrix( rmesa, ctx->ModelView.m, MODEL ); */ +/* upload_matrix_t( rmesa, ctx->ModelView.inv, MODEL_IT ); */ +/* upload_matrix( rmesa, ctx->TextureMatrix[0].m, TEXMAT_0 ); */ +/* upload_matrix( rmesa, ctx->TextureMatrix[1].m, TEXMAT_1 ); */ +/* upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, TEXMAT_2 ); */ + + rmesa->hw.grd.cmd[GRD_VERT_GUARD_CLIP_ADJ] = IEEE_ONE; + rmesa->hw.grd.cmd[GRD_VERT_GUARD_DISCARD_ADJ] = IEEE_ONE; + rmesa->hw.grd.cmd[GRD_HORZ_GUARD_CLIP_ADJ] = IEEE_ONE; + rmesa->hw.grd.cmd[GRD_HORZ_GUARD_DISCARD_ADJ] = IEEE_ONE; + + rmesa->hw.eye.cmd[EYE_X] = 0; + rmesa->hw.eye.cmd[EYE_Y] = 0; + rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE; + rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c new file mode 100644 index 000000000..2194add40 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c @@ -0,0 +1,1189 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c,v 1.4 2003/02/15 22:18:48 dawes Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "enums.h" +#include "mem.h" +#include "mmath.h" +#include "macros.h" + +#include "swrast_setup/swrast_setup.h" +#include "math/m_translate.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_swtcl.h" +#include "radeon_tcl.h" + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + + +#define RADEON_XYZW_BIT 0x01 +#define RADEON_RGBA_BIT 0x02 +#define RADEON_SPEC_BIT 0x04 +#define RADEON_TEX0_BIT 0x08 +#define RADEON_TEX1_BIT 0x10 +#define RADEON_PTEX_BIT 0x20 +#define RADEON_MAX_SETUP 0x40 + +static void flush_last_swtcl_prim( radeonContextPtr rmesa ); +static void flush_last_swtcl_prim_compat( radeonContextPtr rmesa ); + +static struct { + void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint ); + interp_func interp; + copy_pv_func copy_pv; + GLboolean (*check_tex_sizes)( GLcontext *ctx ); + GLuint vertex_size; + GLuint vertex_stride_shift; + GLuint vertex_format; +} setup_tab[RADEON_MAX_SETUP]; + + +#define TINY_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_PKCOLOR) + +#define NOTEX_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC) + +#define TEX0_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0) + +#define TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0 | \ + RADEON_CP_VC_FRMT_ST1) + +#define PROJ_TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0 | \ + RADEON_CP_VC_FRMT_Q0 | \ + RADEON_CP_VC_FRMT_ST1 | \ + RADEON_CP_VC_FRMT_Q1) + +#define TEX2_VERTEX_FORMAT 0 +#define TEX3_VERTEX_FORMAT 0 +#define PROJ_TEX3_VERTEX_FORMAT 0 + +#define DO_XYZW (IND & RADEON_XYZW_BIT) +#define DO_RGBA (IND & RADEON_RGBA_BIT) +#define DO_SPEC (IND & RADEON_SPEC_BIT) +#define DO_FOG (IND & RADEON_SPEC_BIT) +#define DO_TEX0 (IND & RADEON_TEX0_BIT) +#define DO_TEX1 (IND & RADEON_TEX1_BIT) +#define DO_TEX2 0 +#define DO_TEX3 0 +#define DO_PTEX (IND & RADEON_PTEX_BIT) + +#define VERTEX radeonVertex +#define VERTEX_COLOR radeon_color_t +#define GET_VIEWPORT_MAT() 0 +#define GET_TEXSOURCE(n) n +#define GET_VERTEX_FORMAT() RADEON_CONTEXT(ctx)->swtcl.vertex_format +#define GET_VERTEX_STORE() RADEON_CONTEXT(ctx)->swtcl.verts +#define GET_VERTEX_STRIDE_SHIFT() RADEON_CONTEXT(ctx)->swtcl.vertex_stride_shift +#define GET_UBYTE_COLOR_STORE() &RADEON_CONTEXT(ctx)->UbyteColor +#define GET_UBYTE_SPEC_COLOR_STORE() &RADEON_CONTEXT(ctx)->UbyteSecondaryColor + +#define HAVE_HW_VIEWPORT 1 +/* Tiny vertices don't seem to work atm - haven't looked into why. + */ +#define HAVE_HW_DIVIDE (IND & ~(RADEON_XYZW_BIT|RADEON_RGBA_BIT)) +#define HAVE_TINY_VERTICES 1 +#define HAVE_RGBA_COLOR 1 +#define HAVE_NOTEX_VERTICES 1 +#define HAVE_TEX0_VERTICES 1 +#define HAVE_TEX1_VERTICES 1 +#define HAVE_TEX2_VERTICES 0 +#define HAVE_TEX3_VERTICES 0 +#define HAVE_PTEX_VERTICES 1 + +#define CHECK_HW_DIVIDE (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE| \ + DD_TRI_UNFILLED))) + +#define IMPORT_QUALIFIER +#define IMPORT_FLOAT_COLORS radeon_import_float_colors +#define IMPORT_FLOAT_SPEC_COLORS radeon_import_float_spec_colors + +#define INTERP_VERTEX setup_tab[RADEON_CONTEXT(ctx)->swtcl.SetupIndex].interp +#define COPY_PV_VERTEX setup_tab[RADEON_CONTEXT(ctx)->swtcl.SetupIndex].copy_pv + + +/*********************************************************************** + * Generate pv-copying and translation functions * + ***********************************************************************/ + +#define TAG(x) radeon_##x +#define IND ~0 +#include "tnl_dd/t_dd_vb.c" +#undef IND + + +/*********************************************************************** + * Generate vertex emit and interp functions * + ***********************************************************************/ + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT) +#define TAG(x) x##_wg +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT|\ + RADEON_PTEX_BIT) +#define TAG(x) x##_wgpt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|\ + RADEON_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|\ + RADEON_TEX0_BIT|RADEON_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|\ + RADEON_TEX0_BIT|RADEON_TEX1_BIT) +#define TAG(x) x##_wgfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|\ + RADEON_TEX0_BIT|RADEON_TEX1_BIT|RADEON_PTEX_BIT) +#define TAG(x) x##_wgfspt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static void init_setup_tab( void ) +{ + init_wg(); + init_wgt0(); + init_wgpt0(); + init_wgt0t1(); + init_wgpt0t1(); + init_wgfs(); + init_wgfst0(); + init_wgfspt0(); + init_wgfst0t1(); + init_wgfspt0t1(); +} + + + +void radeonPrintSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & RADEON_XYZW_BIT) ? " xyzw," : "", + (flags & RADEON_RGBA_BIT) ? " rgba," : "", + (flags & RADEON_SPEC_BIT) ? " spec/fog," : "", + (flags & RADEON_TEX0_BIT) ? " tex-0," : "", + (flags & RADEON_TEX1_BIT) ? " tex-1," : "", + (flags & RADEON_PTEX_BIT) ? " proj-tex," : ""); +} + + +static void radeonRenderStart( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + + if (!setup_tab[rmesa->swtcl.SetupIndex].check_tex_sizes(ctx)) { + GLuint ind = rmesa->swtcl.SetupIndex |= (RADEON_PTEX_BIT|RADEON_RGBA_BIT); + + /* Radeon handles projective textures nicely; just have to change + * up to the new vertex format. + */ + if (setup_tab[ind].vertex_format != rmesa->swtcl.vertex_format) { + RADEON_NEWPRIM(rmesa); + rmesa->swtcl.vertex_format = setup_tab[ind].vertex_format; + rmesa->swtcl.vertex_size = setup_tab[ind].vertex_size; + rmesa->swtcl.vertex_stride_shift = setup_tab[ind].vertex_stride_shift; + } + + if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + tnl->Driver.Render.Interp = setup_tab[rmesa->swtcl.SetupIndex].interp; + tnl->Driver.Render.CopyPV = setup_tab[rmesa->swtcl.SetupIndex].copy_pv; + } + } + + if (rmesa->dma.flush != 0 && + rmesa->dma.flush != flush_last_swtcl_prim && + rmesa->dma.flush != flush_last_swtcl_prim_compat) + rmesa->dma.flush( rmesa ); +} + + +void radeonBuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + GLubyte *v = ((GLubyte *)rmesa->swtcl.verts + + (start << rmesa->swtcl.vertex_stride_shift)); + GLuint stride = 1 << rmesa->swtcl.vertex_stride_shift; + + newinputs |= rmesa->swtcl.SetupNewInputs; + rmesa->swtcl.SetupNewInputs = 0; + + if (!newinputs) + return; + + setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, v, stride ); +} + +void radeonChooseVertexState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint ind = (RADEON_XYZW_BIT | RADEON_RGBA_BIT); + + if (!rmesa->TclFallback || rmesa->Fallback) + return; + + if (ctx->Fog.Enabled || (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)) + ind |= RADEON_SPEC_BIT; + + if (ctx->Texture._ReallyEnabled & TEXTURE1_ANY) + ind |= RADEON_TEX0_BIT|RADEON_TEX1_BIT; + else if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY) + ind |= RADEON_TEX0_BIT; + + rmesa->swtcl.SetupIndex = ind; + + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = radeon_interp_extras; + tnl->Driver.Render.CopyPV = radeon_copy_pv_extras; + } + else { + tnl->Driver.Render.Interp = setup_tab[ind].interp; + tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv; + } + + if (setup_tab[ind].vertex_format != rmesa->swtcl.vertex_format) { + RADEON_NEWPRIM(rmesa); + rmesa->swtcl.vertex_format = setup_tab[ind].vertex_format; + rmesa->swtcl.vertex_size = setup_tab[ind].vertex_size; + rmesa->swtcl.vertex_stride_shift = setup_tab[ind].vertex_stride_shift; + } + + { + GLuint se_coord_fmt, needproj; + + /* HW perspective divide is a win, but tiny vertex formats are a + * bigger one. + */ + if (setup_tab[ind].vertex_format == TINY_VERTEX_FORMAT || + (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + needproj = GL_TRUE; + se_coord_fmt = (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_VTX_Z_PRE_MULT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_Q1); + } + else { + needproj = GL_FALSE; + se_coord_fmt = (RADEON_VTX_W0_IS_NOT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_Q1); + } + + if ( se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT] ) { + RADEON_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt; + } + _tnl_need_projected_coords( ctx, needproj ); + } +} + + +/* Flush vertices in the current dma region. + */ +static void flush_last_swtcl_prim( radeonContextPtr rmesa ) +{ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->dma.current.buf) { + struct radeon_dma_region *current = &rmesa->dma.current; + GLuint current_offset = (rmesa->radeonScreen->agp_buffer_offset + + current->buf->buf->idx * RADEON_BUFFER_SIZE + + current->start); + + assert (!(rmesa->swtcl.hw_primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); + + assert (current->start + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + current->ptr); + + if (rmesa->dma.current.start != rmesa->dma.current.ptr) { + radeonEmitVertexAOS( rmesa, + rmesa->swtcl.vertex_size, + current_offset); + + radeonEmitVbufPrim( rmesa, + rmesa->swtcl.vertex_format, + rmesa->swtcl.hw_primitive, + rmesa->swtcl.numverts); + } + + rmesa->swtcl.numverts = 0; + current->start = current->ptr; + + rmesa->dma.flush = 0; + } +} + + +static void flush_last_swtcl_prim_compat( radeonContextPtr rmesa ) +{ + struct radeon_dma_region *current = &rmesa->dma.current; + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s buf %p start %d ptr %d\n", + __FUNCTION__, + current->buf, + current->start, + current->ptr); + + assert (!(rmesa->swtcl.hw_primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); + assert (current->start + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + current->ptr); + assert (current->start == 0); + + if (current->ptr && current->buf) { + assert (current->buf->refcount == 1); + + radeonCompatEmitPrimitive( rmesa, + rmesa->swtcl.vertex_format, + rmesa->swtcl.hw_primitive, + rmesa->swtcl.numverts); + + /* The buffer has been released: + */ + FREE(current->buf); + current->buf = 0; + current->start = 0; + current->ptr = current->end; + + } + + rmesa->swtcl.numverts = 0; + rmesa->dma.flush = 0; +} + + +/* Alloc space in the current dma region. + */ +static __inline void *radeonAllocDmaLowVerts( radeonContextPtr rmesa, + int nverts, int vsize ) +{ + GLuint bytes = vsize * nverts; + + if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) + radeonRefillCurrentDmaRegion( rmesa ); + + if (!rmesa->dma.flush) { + if (rmesa->dri.drmMinor == 1) + rmesa->dma.flush = flush_last_swtcl_prim_compat; + else + rmesa->dma.flush = flush_last_swtcl_prim; + } + + assert( vsize == rmesa->swtcl.vertex_size * 4 ); + assert( rmesa->dma.flush == flush_last_swtcl_prim || + rmesa->dma.flush == flush_last_swtcl_prim_compat); + assert (rmesa->dma.current.start + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + rmesa->dma.current.ptr); + + + { + GLubyte *head = rmesa->dma.current.address + rmesa->dma.current.ptr; + rmesa->dma.current.ptr += bytes; + rmesa->swtcl.numverts += nverts; + return head; + } + +} + + + + +void radeon_emit_contiguous_verts( GLcontext *ctx, GLuint start, GLuint count ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint vertex_size = rmesa->swtcl.vertex_size * 4; + CARD32 *dest = radeonAllocDmaLowVerts( rmesa, count-start, vertex_size ); + setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, dest, + vertex_size ); +} + + + +void radeon_emit_indexed_verts( GLcontext *ctx, GLuint start, GLuint count ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + radeonAllocDmaRegionVerts( rmesa, + &rmesa->swtcl.indexed_verts, + count - start, + rmesa->swtcl.vertex_size * 4, + 64); + + setup_tab[rmesa->swtcl.SetupIndex].emit( + ctx, start, count, + rmesa->swtcl.indexed_verts.address + rmesa->swtcl.indexed_verts.start, + rmesa->swtcl.vertex_size * 4 ); +} + + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Try to simulate missing primitives with indexed vertices. + */ +#define HAVE_POINTS 1 +#define HAVE_LINES 1 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 +#define HAVE_TRI_FANS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 +#define HAVE_POLYGONS 0 +#define HAVE_ELTS 1 + +static const GLuint hw_prim[GL_POLYGON+1] = { + RADEON_CP_VC_CNTL_PRIM_TYPE_POINT, + RADEON_CP_VC_CNTL_PRIM_TYPE_LINE, + 0, + RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP, + RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, + RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP, + RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN, + 0, + 0, + 0 +}; + +static __inline void radeonDmaPrimitive( radeonContextPtr rmesa, GLenum prim ) +{ + RADEON_NEWPRIM( rmesa ); + rmesa->swtcl.hw_primitive = hw_prim[prim]; + assert(rmesa->dma.current.ptr == rmesa->dma.current.start); +} + +static __inline void radeonEltPrimitive( radeonContextPtr rmesa, GLenum prim ) +{ + RADEON_NEWPRIM( rmesa ); + rmesa->swtcl.hw_primitive = hw_prim[prim] | RADEON_CP_VC_CNTL_PRIM_WALK_IND; +} + + +static void VERT_FALLBACK( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK ); + tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 ); + tnl->Driver.Render.PrimTabVerts[flags&PRIM_MODE_MASK]( ctx, start, count, flags ); + RADEON_CONTEXT(ctx)->swtcl.SetupNewInputs = VERT_CLIP; +} + +static void ELT_FALLBACK( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK ); + tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 ); + tnl->Driver.Render.PrimTabElts[flags&PRIM_MODE_MASK]( ctx, start, count, flags ); + RADEON_CONTEXT(ctx)->swtcl.SetupNewInputs = VERT_CLIP; +} + + +#define LOCAL_VARS radeonContextPtr rmesa = RADEON_CONTEXT(ctx) +#define ELTS_VARS GLushort *dest +#define INIT( prim ) radeonDmaPrimitive( rmesa, prim ) +#define ELT_INIT(prim) radeonEltPrimitive( rmesa, prim ) +#define NEW_PRIMITIVE() RADEON_NEWPRIM( rmesa ) +#define NEW_BUFFER() radeonRefillCurrentDmaRegion( rmesa ) +#define GET_CURRENT_VB_MAX_VERTS() \ + (((int)rmesa->dma.current.end - (int)rmesa->dma.current.ptr) / (rmesa->swtcl.vertex_size*4)) +#define GET_SUBSEQUENT_VB_MAX_VERTS() \ + ((RADEON_BUFFER_SIZE) / (rmesa->swtcl.vertex_size*4)) + +#if RADEON_OLD_PACKETS +# define GET_CURRENT_VB_MAX_ELTS() \ + ((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 24)) / 2) +#else +# define GET_CURRENT_VB_MAX_ELTS() \ + ((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2) +#endif +#define GET_SUBSEQUENT_VB_MAX_ELTS() \ + ((RADEON_CMD_BUF_SZ - 1024) / 2) + + + +/* How do you extend an existing primitive? + */ +#define ALLOC_ELTS(nr) \ +do { \ + if (rmesa->dma.flush == radeonFlushElts && \ + rmesa->store.cmd_used + nr*2 < RADEON_CMD_BUF_SZ) { \ + \ + dest = (GLushort *)(rmesa->store.cmd_buf + \ + rmesa->store.cmd_used); \ + rmesa->store.cmd_used += nr*2; \ + } \ + else { \ + if (rmesa->dma.flush) { \ + rmesa->dma.flush( rmesa ); \ + } \ + \ + radeonEmitVertexAOS( rmesa, \ + rmesa->swtcl.vertex_size, \ + (rmesa->radeonScreen->agp_buffer_offset + \ + rmesa->swtcl.indexed_verts.buf->buf->idx * \ + RADEON_BUFFER_SIZE + \ + rmesa->swtcl.indexed_verts.start)); \ + \ + dest = radeonAllocEltsOpenEnded( rmesa, \ + rmesa->swtcl.vertex_format, \ + rmesa->swtcl.hw_primitive, \ + nr ); \ + } \ +} while (0) + +#define ALLOC_ELTS_NEW_PRIMITIVE(nr) ALLOC_ELTS( nr ) + +#ifdef MESA_BIG_ENDIAN +/* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */ +#define EMIT_ELT(offset, x) do { \ + int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \ + GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \ + (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0) +#else +#define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x) +#endif +#define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x); +#define INCR_ELTS( nr ) dest += nr +#define RELEASE_ELT_VERTS() \ + radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ ) +#define EMIT_VERTS( ctx, j, nr ) \ + radeon_emit_contiguous_verts(ctx, j, (j)+(nr)) +#define EMIT_INDEXED_VERTS( ctx, start, count ) \ + radeon_emit_indexed_verts( ctx, start, count ) + + +#define TAG(x) radeon_dma_##x +#include "tnl_dd/t_dd_dmatmp.h" + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + +static GLboolean radeon_run_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i, length, flags = 0; + render_func *tab = TAG(render_tab_verts); + + if (rmesa->swtcl.indexed_verts.buf && (!VB->Elts || stage->changed_inputs)) + RELEASE_ELT_VERTS(); + + if (VB->ClipOrMask || /* No clipping */ + rmesa->swtcl.RenderIndex != 0 || /* No per-vertex manipulations */ + ctx->Line.StippleFlag) /* GH: THIS IS A HACK!!! */ + return GL_TRUE; + + if (rmesa->dri.drmMinor < 3) { + /* drm 1.1 doesn't support vertex primitives starting in the + * middle of a buffer. It doesn't support sane indexed vertices + * either. drm 1.2 fixes both of these problems, but we don't have a + * compatibility layer to that version yet. + */ + return GL_TRUE; + } + + tnl->Driver.Render.Start( ctx ); + + if (VB->Elts) { + tab = TAG(render_tab_elts); + if (!rmesa->swtcl.indexed_verts.buf) + if (!TAG(emit_elt_verts)(ctx, 0, VB->Count)) + return GL_TRUE; /* too many vertices */ + } + + for (i = 0 ; !(flags & PRIM_LAST) ; i += length) + { + flags = VB->Primitive[i]; + length = VB->PrimitiveLength[i]; + + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "radeon_render.c: prim %s %d..%d\n", + _mesa_lookup_enum_by_nr(flags & PRIM_MODE_MASK), + i, i+length); + + if (length) + tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); + } + + tnl->Driver.Render.Finish( ctx ); + + return GL_FALSE; /* finished the pipe */ +} + + + +static void radeon_check_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + GLuint inputs = VERT_OBJ|VERT_CLIP|VERT_RGBA; + + if (ctx->RenderMode == GL_RENDER) { + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + inputs |= VERT_SPEC_RGB; + + if (ctx->Texture.Unit[0]._ReallyEnabled) + inputs |= VERT_TEX(0); + + if (ctx->Texture.Unit[1]._ReallyEnabled) + inputs |= VERT_TEX(1); + + if (ctx->Fog.Enabled) + inputs |= VERT_FOG_COORD; + } + + stage->inputs = inputs; +} + + +static void dtr( struct gl_pipeline_stage *stage ) +{ + (void)stage; +} + + +const struct gl_pipeline_stage _radeon_render_stage = +{ + "radeon render", + (_DD_NEW_SEPARATE_SPECULAR | + _NEW_TEXTURE| + _NEW_FOG| + _NEW_RENDERMODE), /* re-check (new inputs) */ + 0, /* re-run (always runs) */ + GL_TRUE, /* active */ + 0, 0, /* inputs (set in check_render), outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + radeon_check_render, /* check - initially set to alloc data */ + radeon_run_render /* run */ +}; + + + +/**************************************************************************/ + + +static const GLuint reduced_hw_prim[GL_POLYGON+1] = { + RADEON_CP_VC_CNTL_PRIM_TYPE_POINT, + RADEON_CP_VC_CNTL_PRIM_TYPE_LINE, + RADEON_CP_VC_CNTL_PRIM_TYPE_LINE, + RADEON_CP_VC_CNTL_PRIM_TYPE_LINE, + RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, + RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, + RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, + RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, + RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST, + RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST +}; + +static void radeonRasterPrimitive( GLcontext *ctx, GLuint hwprim ); +static void radeonRenderPrimitive( GLcontext *ctx, GLenum prim ); +static void radeonResetLineStipple( GLcontext *ctx ); + + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#define CTX_ARG radeonContextPtr rmesa +#define CTX_ARG2 rmesa +#define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size +#define ALLOC_VERTS( n, size ) radeonAllocDmaLowVerts( rmesa, n, size * 4 ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + const GLuint shift = rmesa->swtcl.vertex_stride_shift; \ + const char *radeonverts = (char *)rmesa->swtcl.verts; +#define VERT(x) (radeonVertex *)(radeonverts + (x << shift)) +#define VERTEX radeonVertex +#undef TAG +#define TAG(x) radeon_##x +#include "tnl_dd/t_dd_triemit.h" + + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define QUAD( a, b, c, d ) radeon_quad( rmesa, a, b, c, d ) +#define TRI( a, b, c ) radeon_triangle( rmesa, a, b, c ) +#define LINE( a, b ) radeon_line( rmesa, a, b ) +#define POINT( a ) radeon_point( rmesa, a ) + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define RADEON_TWOSIDE_BIT 0x01 +#define RADEON_UNFILLED_BIT 0x02 +#define RADEON_OFFSET_BIT 0x04 /* drmMinor == 1 */ +#define RADEON_MAX_TRIFUNC 0x08 + + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[RADEON_MAX_TRIFUNC]; + + +#define DO_FALLBACK 0 +#define DO_OFFSET (IND & RADEON_OFFSET_BIT) +#define DO_UNFILLED (IND & RADEON_UNFILLED_BIT) +#define DO_TWOSIDE (IND & RADEON_TWOSIDE_BIT) +#define DO_FLAT 0 +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_INDEX 0 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define TAB rast_tab + +#define DEPTH_SCALE 1.0 +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a < 0) +#define GET_VERTEX(e) (rmesa->swtcl.verts + (e<<rmesa->swtcl.vertex_stride_shift)) + +#define VERT_SET_RGBA( v, c ) v->ui[coloroffset] = LE32_TO_CPU(*(GLuint *)c) +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA( idx ) color[idx] = CPU_TO_LE32(v[idx]->ui[coloroffset]) +#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = LE32_TO_CPU(color[idx]) + +#define VERT_SET_SPEC( v0, c ) if (havespec) { \ + v0->v.specular.red = (c)[0]; \ + v0->v.specular.green = (c)[1]; \ + v0->v.specular.blue = (c)[2]; } +#define VERT_COPY_SPEC( v0, v1 ) if (havespec) { \ + v0->v.specular.red = v1->v.specular.red; \ + v0->v.specular.green = v1->v.specular.green; \ + v0->v.specular.blue = v1->v.specular.blue; } +#define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = CPU_TO_LE32(v[idx]->ui[5]) +#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = LE32_TO_CPU(spec[idx]) + +#undef LOCAL_VARS +#define LOCAL_VARS(n) \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = (rmesa->swtcl.vertex_size == 4 ? 3 : 4); \ + GLboolean havespec = (rmesa->swtcl.vertex_size > 4); \ + (void) color; (void) spec; (void) coloroffset; (void) havespec; + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) radeonRasterPrimitive( ctx, reduced_hw_prim[x] ) +#define RENDER_PRIMITIVE rmesa->swtcl.render_primitive +#undef TAG +#define TAG(x) x +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (RADEON_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT|RADEON_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (RADEON_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT|RADEON_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (RADEON_UNFILLED_BIT|RADEON_OFFSET_BIT) +#define TAG(x) x##_unfilled_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT|RADEON_UNFILLED_BIT|RADEON_OFFSET_BIT) +#define TAG(x) x##_twoside_unfilled_offset +#include "tnl_dd/t_dd_tritmp.h" + + +static void init_rast_tab( void ) +{ + init(); + init_twoside(); + init_unfilled(); + init_twoside_unfilled(); + init_offset(); + init_twoside_offset(); + init_unfilled_offset(); + init_twoside_unfilled_offset(); +} + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define VERT(x) (radeonVertex *)(radeonverts + (x << shift)) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + radeon_point( rmesa, VERT(start) ) +#define RENDER_LINE( v0, v1 ) \ + radeon_line( rmesa, VERT(v0), VERT(v1) ) +#define RENDER_TRI( v0, v1, v2 ) \ + radeon_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) \ + radeon_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) +#undef INIT +#define INIT(x) do { \ + radeonRenderPrimitive( ctx, x ); \ +} while (0) +#undef LOCAL_VARS +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + const GLuint shift = rmesa->swtcl.vertex_stride_shift; \ + const char *radeonverts = (char *)rmesa->swtcl.verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) elt; (void) stipple; +#define RESET_STIPPLE if ( stipple ) radeonResetLineStipple( ctx ); +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) (x) +#define TAG(x) radeon_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) radeon_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + +void radeonChooseRenderState( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint index = 0; + GLuint flags = ctx->_TriangleCaps; + + if (!rmesa->TclFallback || rmesa->Fallback) + return; + + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= RADEON_TWOSIDE_BIT; + if (flags & DD_TRI_UNFILLED) index |= RADEON_UNFILLED_BIT; + if ((flags & DD_TRI_OFFSET) && + rmesa->dri.drmMinor == 1) index |= RADEON_OFFSET_BIT; + + if (index != rmesa->swtcl.RenderIndex) { + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = radeon_render_tab_verts; + tnl->Driver.Render.PrimTabElts = radeon_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = radeon_fast_clipped_poly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + } + + rmesa->swtcl.RenderIndex = index; + } +} + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void radeonRasterPrimitive( GLcontext *ctx, GLuint hwprim ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (rmesa->swtcl.hw_primitive != hwprim) { + RADEON_NEWPRIM( rmesa ); + rmesa->swtcl.hw_primitive = hwprim; + } +} + +static void radeonRenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + rmesa->swtcl.render_primitive = prim; + if (prim < GL_TRIANGLES || !(ctx->_TriangleCaps & DD_TRI_UNFILLED)) + radeonRasterPrimitive( ctx, reduced_hw_prim[prim] ); +} + +static void radeonRenderFinish( GLcontext *ctx ) +{ +} + +static void radeonResetLineStipple( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + RADEON_STATECHANGE( rmesa, lin ); +} + + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + +static char *fallbackStrings[] = { + "Texture mode", + "glDrawBuffer(GL_FRONT_AND_BACK)", + "glEnable(GL_STENCIL) without hw stencil buffer", + "glRenderMode(selection or feedback)", + "glBlendEquation", + "glBlendFunc(mode != ADD)" + "RADEON_NO_RAST" +}; + + +static char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + + +void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = rmesa->Fallback; + + if (mode) { + rmesa->Fallback |= bit; + if (oldfallback == 0) { + RADEON_FIREVERTICES( rmesa ); + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_TRUE ); + _swsetup_Wakeup( ctx ); + _tnl_need_projected_coords( ctx, GL_TRUE ); + rmesa->swtcl.RenderIndex = ~0; + if (RADEON_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "Radeon begin rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } + } + } + else { + rmesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + tnl->Driver.Render.Start = radeonRenderStart; + tnl->Driver.Render.PrimitiveNotify = radeonRenderPrimitive; + tnl->Driver.Render.Finish = radeonRenderFinish; + tnl->Driver.Render.BuildVertices = radeonBuildVertices; + tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple; + TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_FALSE ); + if (rmesa->TclFallback) { + /* These are already done if rmesa->TclFallback goes to + * zero above. But not if it doesn't (RADEON_NO_TCL for + * example?) + */ + radeonChooseVertexState( ctx ); + radeonChooseRenderState( ctx ); + } + if (RADEON_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "Radeon end rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } + } + } +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void radeonInitSwtcl( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + init_setup_tab(); + firsttime = 0; + } + + tnl->Driver.Render.Start = radeonRenderStart; + tnl->Driver.Render.Finish = radeonRenderFinish; + tnl->Driver.Render.PrimitiveNotify = radeonRenderPrimitive; + tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple; + tnl->Driver.Render.BuildVertices = radeonBuildVertices; + + rmesa->swtcl.verts = (char *)ALIGN_MALLOC( size * 16 * 4, 32 ); + rmesa->swtcl.RenderIndex = ~0; + rmesa->swtcl.render_primitive = GL_TRIANGLES; + rmesa->swtcl.hw_primitive = 0; +} + + +void radeonDestroySwtcl( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (rmesa->swtcl.indexed_verts.buf) + radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, + __FUNCTION__ ); + + if (rmesa->swtcl.verts) { + ALIGN_FREE(rmesa->swtcl.verts); + rmesa->swtcl.verts = 0; + } + + if (rmesa->UbyteSecondaryColor.Ptr) { + ALIGN_FREE(rmesa->UbyteSecondaryColor.Ptr); + rmesa->UbyteSecondaryColor.Ptr = 0; + } + + if (rmesa->UbyteColor.Ptr) { + ALIGN_FREE(rmesa->UbyteColor.Ptr); + rmesa->UbyteColor.Ptr = 0; + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.h new file mode 100644 index 000000000..fe874cd7b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.h @@ -0,0 +1,76 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.h,v 1.1 2002/10/30 12:51:57 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#ifndef __RADEON_TRIS_H__ +#define __RADEON_TRIS_H__ + +#include "mtypes.h" +#include "swrast/swrast.h" +#include "radeon_context.h" + +extern void radeonInitSwtcl( GLcontext *ctx ); +extern void radeonDestroySwtcl( GLcontext *ctx ); + +extern void radeonChooseRenderState( GLcontext *ctx ); +extern void radeonChooseVertexState( GLcontext *ctx ); + +extern void radeonCheckTexSizes( GLcontext *ctx ); + +extern void radeonBuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ); + +extern void radeonPrintSetupFlags(char *msg, GLuint flags ); + + +extern void radeon_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count ); + +extern void radeon_emit_indexed_verts( GLcontext *ctx, + GLuint start, + GLuint count ); + +extern void radeon_translate_vertex( GLcontext *ctx, + const radeonVertex *src, + SWvertex *dst ); + +extern void radeon_print_vertex( GLcontext *ctx, const radeonVertex *v ); + +extern void radeon_import_float_colors( GLcontext *ctx ); +extern void radeon_import_float_spec_colors( GLcontext *ctx ); + + + +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.c new file mode 100644 index 000000000..c8fc07474 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.c @@ -0,0 +1,545 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.c,v 1.1 2002/10/30 12:51:57 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc., Austin, 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_tex.h" +#include "radeon_tcl.h" +#include "radeon_swtcl.h" +#include "radeon_maos.h" + +#include "mmath.h" +#include "mtypes.h" +#include "enums.h" +#include "colormac.h" +#include "light.h" + +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" + + + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Try to simulate missing primitives with indexed vertices. + */ +#define HAVE_POINTS 1 +#define HAVE_LINES 1 +#define HAVE_LINE_LOOP 0 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 +#define HAVE_TRI_FANS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 +#define HAVE_POLYGONS 1 +#define HAVE_ELTS 1 + + +#define HW_POINTS RADEON_CP_VC_CNTL_PRIM_TYPE_POINT +#define HW_LINES RADEON_CP_VC_CNTL_PRIM_TYPE_LINE +#define HW_LINE_LOOP 0 +#define HW_LINE_STRIP RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP +#define HW_TRIANGLES RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST +#define HW_TRIANGLE_STRIP_0 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP +#define HW_TRIANGLE_STRIP_1 0 +#define HW_TRIANGLE_FAN RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN +#define HW_QUADS 0 +#define HW_QUAD_STRIP 0 +#define HW_POLYGON RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN + + +static GLboolean discreet_prim[0x10] = { + 0, /* none */ + 1, /* points */ + 1, /* lines */ + 0, /* line_strip */ + 1, /* tri_list */ + 0, /* tri_fan */ + 0, /* tri_type_2 */ + 1, /* rect list (unused) */ + 1, /* 3 vert point */ + 1, /* 3 vert line */ + 0, + 0, + 0, + 0, + 0, +}; + + +#define LOCAL_VARS radeonContextPtr rmesa = RADEON_CONTEXT(ctx) +#define ELTS_VARS GLushort *dest + +#define ELT_INIT(prim, hw_prim) \ + radeonTclPrimitive( ctx, prim, hw_prim | RADEON_CP_VC_CNTL_PRIM_WALK_IND ) + +#define GET_ELTS() rmesa->tcl.Elts + + +#define NEW_PRIMITIVE() RADEON_NEWPRIM( rmesa ) +#define NEW_BUFFER() radeonRefillCurrentDmaRegion( rmesa ) + +/* Don't really know how many elts will fit in what's left of cmdbuf, + * as there is state to emit, etc: + */ + +#if 0 +#define GET_CURRENT_VB_MAX_ELTS() \ + ((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2) +#define GET_SUBSEQUENT_VB_MAX_ELTS() ((RADEON_CMD_BUF_SZ - 16) / 2) +#else +/* Testing on isosurf shows a maximum around here. Don't know if it's + * the card or driver or kernel module that is causing the behaviour. + */ +#define GET_CURRENT_VB_MAX_ELTS() 300 +#define GET_SUBSEQUENT_VB_MAX_ELTS() 300 +#endif + +#define RESET_STIPPLE() do { \ + RADEON_STATECHANGE( rmesa, lin ); \ + radeonEmitState( rmesa ); \ +} while (0) + +#define AUTO_STIPPLE( mode ) do { \ + RADEON_STATECHANGE( rmesa, lin ); \ + if (mode) \ + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] |= \ + RADEON_LINE_PATTERN_AUTO_RESET; \ + else \ + rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \ + ~RADEON_LINE_PATTERN_AUTO_RESET; \ + radeonEmitState( rmesa ); \ +} while (0) + + +/* How do you extend an existing primitive? + */ +#define ALLOC_ELTS(nr) \ +do { \ + if (rmesa->dma.flush == radeonFlushElts && \ + rmesa->store.cmd_used + nr*2 < RADEON_CMD_BUF_SZ) { \ + \ + dest = (GLushort *)(rmesa->store.cmd_buf + \ + rmesa->store.cmd_used); \ + rmesa->store.cmd_used += nr*2; \ + } \ + else { \ + if (rmesa->dma.flush) \ + rmesa->dma.flush( rmesa ); \ + \ + radeonEmitAOS( rmesa, \ + rmesa->tcl.aos_components, \ + rmesa->tcl.nr_aos_components, \ + 0 ); \ + \ + dest = radeonAllocEltsOpenEnded( rmesa, \ + rmesa->tcl.vertex_format, \ + rmesa->tcl.hw_primitive, \ + nr ); \ + } \ +} while (0) + + + +/* TODO: Try to extend existing primitive if both are identical, + * discreet and there are no intervening state changes. (Somewhat + * duplicates changes to DrawArrays code) + */ +static void EMIT_PRIM( GLcontext *ctx, + GLenum prim, + GLuint hwprim, + GLuint start, + GLuint count) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + radeonTclPrimitive( ctx, prim, hwprim ); + + radeonEmitAOS( rmesa, + rmesa->tcl.aos_components, + rmesa->tcl.nr_aos_components, + start ); + + /* Why couldn't this packet have taken an offset param? + */ + radeonEmitVbufPrim( rmesa, + rmesa->tcl.vertex_format, + rmesa->tcl.hw_primitive, + count - start ); +} + + + +/* Try & join small primitives + */ +#if 0 +#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) 0 +#else +#define PREFER_DISCRETE_ELT_PRIM( NR, PRIM ) \ + ((NR) < 20 || \ + ((NR) < 40 && \ + rmesa->tcl.hw_primitive == (PRIM| \ + RADEON_CP_VC_CNTL_PRIM_WALK_IND| \ + RADEON_CP_VC_CNTL_TCL_ENABLE))) +#endif + +#ifdef MESA_BIG_ENDIAN +/* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */ +#define EMIT_ELT(offset, x) do { \ + int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \ + GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \ + (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0) +#else +#define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x) +#endif +#define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x); +#define INCR_ELTS( nr ) dest += nr +#define RELEASE_ELT_VERTS() \ + radeonReleaseArrays( ctx, ~0 ) + + + +#define TAG(x) tcl_##x +#include "tnl_dd/t_dd_dmatmp2.h" + +/**********************************************************************/ +/* External entrypoints */ +/**********************************************************************/ + +void radeonEmitPrimitive( GLcontext *ctx, + GLuint first, + GLuint last, + GLuint flags ) +{ + tcl_render_tab_verts[flags&PRIM_MODE_MASK]( ctx, first, last, flags ); +} + +void radeonEmitEltPrimitive( GLcontext *ctx, + GLuint first, + GLuint last, + GLuint flags ) +{ + tcl_render_tab_elts[flags&PRIM_MODE_MASK]( ctx, first, last, flags ); +} + +void radeonTclPrimitive( GLcontext *ctx, + GLenum prim, + int hw_prim ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint se_cntl; + GLuint newprim = hw_prim | RADEON_CP_VC_CNTL_TCL_ENABLE; + + if (newprim != rmesa->tcl.hw_primitive || + !discreet_prim[hw_prim&0xf]) { + RADEON_NEWPRIM( rmesa ); + rmesa->tcl.hw_primitive = newprim; + } + + se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL]; + se_cntl &= ~RADEON_FLAT_SHADE_VTX_LAST; + + if (prim == GL_POLYGON && (ctx->_TriangleCaps & DD_FLATSHADE)) + se_cntl |= RADEON_FLAT_SHADE_VTX_0; + else + se_cntl |= RADEON_FLAT_SHADE_VTX_LAST; + + if (se_cntl != rmesa->hw.set.cmd[SET_SE_CNTL]) { + RADEON_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_CNTL] = se_cntl; + } +} + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + +/* TCL render. + */ +static GLboolean radeon_run_tcl_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i,flags = 0,length; + + /* TODO: separate this from the swtnl pipeline + */ + if (rmesa->TclFallback) + return GL_TRUE; /* fallback to software t&l */ + + if (VB->Count == 0) + return GL_FALSE; + + radeonReleaseArrays( ctx, stage->changed_inputs ); + radeonEmitArrays( ctx, stage->inputs ); + + rmesa->tcl.Elts = VB->Elts; + + for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length) + { + flags = VB->Primitive[i]; + length = VB->PrimitiveLength[i]; + + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s: prim %s %d..%d\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(flags & PRIM_MODE_MASK), + i, i+length); + + if (!length) + continue; + + if (rmesa->tcl.Elts) + radeonEmitEltPrimitive( ctx, i, i+length, flags ); + else + radeonEmitPrimitive( ctx, i, i+length, flags ); + } + + return GL_FALSE; /* finished the pipe */ +} + + + +static void radeon_check_tcl_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint inputs = VERT_OBJ; + + if (ctx->RenderMode == GL_RENDER) { + /* Make all this event-driven: + */ + if (ctx->Light.Enabled) { + inputs |= VERT_NORM; + + if (ctx->Light.ColorMaterialEnabled) { + inputs |= VERT_RGBA; + } + } + else { + inputs |= VERT_RGBA; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { + inputs |= VERT_SPEC_RGB; + } + } + + if (ctx->Texture.Unit[0]._ReallyEnabled) { + if (ctx->Texture.Unit[0].TexGenEnabled) { + if (rmesa->TexGenNeedNormals[0]) { + inputs |= VERT_NORM; + } + } else { + inputs |= VERT_TEX(0); + } + } + + if (ctx->Texture.Unit[1]._ReallyEnabled) { + if (ctx->Texture.Unit[1].TexGenEnabled) { + if (rmesa->TexGenNeedNormals[1]) { + inputs |= VERT_NORM; + } + } else { + inputs |= VERT_TEX(1); + } + } + + stage->inputs = inputs; + stage->active = 1; + } + else + stage->active = 0; +} + +static void radeon_init_tcl_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + stage->check = radeon_check_tcl_render; + stage->check( ctx, stage ); +} + +static void dtr( struct gl_pipeline_stage *stage ) +{ + (void)stage; +} + + +/* Initial state for tcl stage. + */ +const struct gl_pipeline_stage _radeon_tcl_stage = +{ + "radeon render", + (_DD_NEW_SEPARATE_SPECULAR | + _NEW_LIGHT| + _NEW_TEXTURE| + _NEW_FOG| + _NEW_RENDERMODE), /* re-check (new inputs) */ + 0, /* re-run (always runs) */ + GL_TRUE, /* active */ + 0, 0, /* inputs (set in check_render), outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + radeon_init_tcl_render, /* check - initially set to alloc data */ + radeon_run_tcl_render /* run */ +}; + + + +/**********************************************************************/ +/* Validate state at pipeline start */ +/**********************************************************************/ + + +/*----------------------------------------------------------------------- + * Manage TCL fallbacks + */ + + +static void transition_to_swtnl( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint se_cntl; + + RADEON_NEWPRIM( rmesa ); + rmesa->swtcl.vertex_format = 0; + + radeonChooseVertexState( ctx ); + radeonChooseRenderState( ctx ); + + _mesa_validate_all_lighting_tables( ctx ); + + tnl->Driver.NotifyMaterialChange = + _mesa_validate_all_lighting_tables; + + radeonReleaseArrays( ctx, ~0 ); + + se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL]; + se_cntl |= RADEON_FLAT_SHADE_VTX_LAST; + + if (se_cntl != rmesa->hw.set.cmd[SET_SE_CNTL]) { + RADEON_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_CNTL] = se_cntl; + } +} + + +static void transition_to_hwtnl( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint se_coord_fmt = (RADEON_VTX_W0_IS_NOT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_Q1); + + if ( se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT] ) { + RADEON_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt; + _tnl_need_projected_coords( ctx, GL_FALSE ); + } + + radeonUpdateMaterial( ctx ); + + tnl->Driver.NotifyMaterialChange = radeonUpdateMaterial; + + if ( rmesa->dma.flush ) + rmesa->dma.flush( rmesa ); + + rmesa->dma.flush = 0; + rmesa->swtcl.vertex_format = 0; + + if (rmesa->swtcl.indexed_verts.buf) + radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, + __FUNCTION__ ); + + if (RADEON_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "Radeon end tcl fallback\n"); +} + +static char *fallbackStrings[] = { + "Rasterization fallback", + "Unfilled triangles", + "Twosided lighting, differing materials", + "Materials in VB (maybe between begin/end)", + "Texgen unit 0", + "Texgen unit 1", + "Texgen unit 2", + "User disable" +}; + + +static char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + + + +void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint oldfallback = rmesa->TclFallback; + + if (mode) { + rmesa->TclFallback |= bit; + if (oldfallback == 0) { + if (RADEON_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "Radeon begin tcl fallback %s\n", + getFallbackString( bit )); + transition_to_swtnl( ctx ); + } + } + else { + rmesa->TclFallback &= ~bit; + if (oldfallback == bit) { + if (RADEON_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "Radeon end tcl fallback %s\n", + getFallbackString( bit )); + transition_to_hwtnl( ctx ); + } + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h new file mode 100644 index 000000000..c35916c6a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h @@ -0,0 +1,66 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h,v 1.2 2003/02/08 21:26:45 dawes Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + Tungsten Grahpics Inc., Austin, 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAHPICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#ifndef __RADEON_TCL_H__ +#define __RADEON_TCL_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_context.h" + +extern void radeonTclPrimitive( GLcontext *ctx, GLenum prim, int hw_prim ); +extern void radeonEmitEltPrimitive( GLcontext *ctx, GLuint first, GLuint last, + GLuint flags ); +extern void radeonEmitPrimitive( GLcontext *ctx, GLuint first, GLuint last, + GLuint flags ); + +extern void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); + +#define RADEON_TCL_FALLBACK_RASTER 0x1 /* rasterization */ +#define RADEON_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */ +#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */ +#define RADEON_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */ +#define RADEON_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */ +#define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */ +#define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */ +#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */ + +#define RADEON_MAX_TCL_VERTSIZE (15*4) + +#define TCL_FALLBACK( ctx, bit, mode ) radeonTclFallback( ctx, bit, mode ) + + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c index 701cd6f25..c804f48e2 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c,v 1.6 2002/09/16 18:05:20 eich Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c,v 1.9 2002/12/16 16:18:59 dawes Exp $ */ /* * Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and * VA Linux Systems Inc., Fremont, California. @@ -32,7 +32,7 @@ #include "radeon_context.h" #include "radeon_state.h" #include "radeon_ioctl.h" -#include "radeon_vb.h" +#include "radeon_swtcl.h" #include "radeon_tex.h" #include "colormac.h" @@ -40,11 +40,9 @@ #include "enums.h" #include "image.h" #include "mem.h" -#include "mmath.h" #include "simple_list.h" #include "texformat.h" #include "texstore.h" -#include "texutil.h" /* ============================================================= @@ -65,6 +63,18 @@ static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap ) case GL_CLAMP_TO_EDGE: t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; break; + case GL_CLAMP_TO_BORDER: + t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_BORDER; + break; + case GL_MIRRORED_REPEAT: + t->pp_txfilter |= RADEON_CLAMP_S_MIRROR; + break; + case GL_MIRROR_CLAMP_ATI: + t->pp_txfilter |= RADEON_CLAMP_S_MIRROR_CLAMP_BORDER; + break; + case GL_MIRROR_CLAMP_TO_EDGE_ATI: + t->pp_txfilter |= RADEON_CLAMP_S_MIRROR_CLAMP_LAST; + break; } switch ( twrap ) { @@ -77,6 +87,18 @@ static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap ) case GL_CLAMP_TO_EDGE: t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; break; + case GL_CLAMP_TO_BORDER: + t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_BORDER; + break; + case GL_MIRRORED_REPEAT: + t->pp_txfilter |= RADEON_CLAMP_T_MIRROR; + break; + case GL_MIRROR_CLAMP_ATI: + t->pp_txfilter |= RADEON_CLAMP_T_MIRROR_CLAMP_BORDER; + break; + case GL_MIRROR_CLAMP_TO_EDGE_ATI: + t->pp_txfilter |= RADEON_CLAMP_T_MIRROR_CLAMP_LAST; + break; } } @@ -167,27 +189,19 @@ static radeonTexObjPtr radeonAllocTexObj( struct gl_texture_object *texObj ) if (!t) return NULL; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %p )\n",__FUNCTION__, (void*)texObj, (void*)t ); + if ( RADEON_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t ); } - /* Initialize non-image-dependent parts of the state: - */ t->tObj = texObj; -#if 0 - t->dirty_images = ~0; -#endif - t->pp_txfilter = RADEON_BORDER_MODE_OGL; - t->pp_txformat = (RADEON_TXFORMAT_ENDIAN_NO_SWAP | - RADEON_TXFORMAT_PERSPECTIVE_ENABLE); - make_empty_list( t ); + /* Initialize non-image-dependent parts of the state: + */ radeonSetTexWrap( t, texObj->WrapS, texObj->WrapT ); radeonSetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); radeonSetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); radeonSetTexBorderColor( t, texObj->BorderColor ); - return t; } @@ -202,6 +216,7 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, switch ( internalFormat ) { case 4: case GL_RGBA: + case GL_COMPRESSED_RGBA: if ( format == GL_BGRA ) { if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { return &_mesa_texformat_argb8888; @@ -217,6 +232,7 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case 3: case GL_RGB: + case GL_COMPRESSED_RGB: if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { return &_mesa_texformat_rgb565; } @@ -251,6 +267,7 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: return &_mesa_texformat_al88; case 1: @@ -259,6 +276,7 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_LUMINANCE8: case GL_LUMINANCE12: case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: return &_mesa_texformat_al88; case 2: @@ -269,6 +287,7 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_LUMINANCE12_ALPHA4: case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: return &_mesa_texformat_al88; case GL_INTENSITY: @@ -276,6 +295,7 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_INTENSITY8: case GL_INTENSITY12: case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: return &_mesa_texformat_i8; default: @@ -316,13 +336,6 @@ static void radeonTexImage1D( GLcontext *ctx, GLenum target, GLint level, &ctx->Unpack, texObj, texImage); t->dirty_images |= (1 << level); - - if ( t == rmesa->state.texture.unit[0].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - } - if ( t == rmesa->state.texture.unit[1].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); - } } @@ -357,13 +370,6 @@ static void radeonTexSubImage1D( GLcontext *ctx, GLenum target, GLint level, texImage); t->dirty_images |= (1 << level); - - if ( t == rmesa->state.texture.unit[0].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - } - if ( t == rmesa->state.texture.unit[1].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); - } } @@ -378,6 +384,8 @@ static void radeonTexImage2D( GLcontext *ctx, GLenum target, GLint level, radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + if ( t ) { radeonSwapOutTexObj( rmesa, t ); } @@ -396,13 +404,6 @@ static void radeonTexImage2D( GLcontext *ctx, GLenum target, GLint level, &ctx->Unpack, texObj, texImage); t->dirty_images |= (1 << level); - - if ( t == rmesa->state.texture.unit[0].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - } - if ( t == rmesa->state.texture.unit[1].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); - } } @@ -418,10 +419,11 @@ static void radeonTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + assert( t ); /* this _should_ be true */ if ( t ) { radeonSwapOutTexObj( rmesa, t ); - t->dirty_images |= (1 << level); } else { t = radeonAllocTexObj(texObj); @@ -437,88 +439,12 @@ static void radeonTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, texImage); t->dirty_images |= (1 << level); - - if ( t == rmesa->state.texture.unit[0].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - } - if ( t == rmesa->state.texture.unit[1].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); - } -} - -#if 0 -static void radeonTexImage3D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; - - if ( t ) { - radeonSwapOutTexObj( rmesa, t ); - } - else { - t = radeonAllocTexObj( texObj ); - if (!t) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - return; - } - texObj->DriverData = t; - } - - /* Note, this will call radeonChooseTextureFormat */ - _mesa_store_teximage3d(ctx, target, level, internalFormat, - width, height, depth, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); - - t->dirty_images |= (1 << level); - - if ( t == rmesa->state.texture.unit[0].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - } - if ( t == rmesa->state.texture.unit[1].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); - } } -static void radeonTexSubImage3D( GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLint depth, - GLenum format, GLenum type, - const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; - - assert( t ); /* this _should_ be true */ - - _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset, - width, height, depth, format, type, pixels, - packing, texObj, texImage); - - t->dirty_images |= (1 << level); - - if ( t == rmesa->state.texture.unit[0].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - } - if ( t == rmesa->state.texture.unit[1].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); - } -} -#endif - #define SCALED_FLOAT_TO_BYTE( x, scale ) \ - ((((GLint)((256.0F / scale) * (x))) - 1) / 2) + (((GLuint)((255.0F / scale) * (x))) / 2) static void radeonTexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) @@ -527,7 +453,7 @@ static void radeonTexEnv( GLcontext *ctx, GLenum target, GLuint unit = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + if ( RADEON_DEBUG & DEBUG_STATE ) { fprintf( stderr, "%s( %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) ); } @@ -538,11 +464,9 @@ static void radeonTexEnv( GLcontext *ctx, GLenum target, GLuint envColor; UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor ); envColor = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); - if ( rmesa->state.hw.texture[unit].pp_tfactor != envColor ) { - if ( rmesa->state.texture.unit[unit].texobj ) { - RADEON_STATECHANGE( rmesa, (RADEON_UPLOAD_TEX0 << unit) ); - } - rmesa->state.hw.texture[unit].pp_tfactor = envColor; + if ( rmesa->hw.tex[unit].cmd[TEX_PP_TFACTOR] != envColor ) { + RADEON_STATECHANGE( rmesa, tex[unit] ); + rmesa->hw.tex[unit].cmd[TEX_PP_TFACTOR] = envColor; } break; } @@ -560,14 +484,14 @@ static void radeonTexEnv( GLcontext *ctx, GLenum target, if ( bias == 0 ) { b = 0; } else if ( bias > 0 ) { - b = ((GLuint)SCALED_FLOAT_TO_BYTE( bias, 4.0 )) << 8; + b = ((GLuint)SCALED_FLOAT_TO_BYTE( bias, 4.0 )) << RADEON_LOD_BIAS_SHIFT; } else { - b = ((GLuint)SCALED_FLOAT_TO_BYTE( bias, 1.0 )) << 8; + b = ((GLuint)SCALED_FLOAT_TO_BYTE( bias, 1.0 )) << RADEON_LOD_BIAS_SHIFT; } - if ( rmesa->state.hw.texture[unit].pp_txfilter != b ) { - if ( rmesa->state.texture.unit[unit].texobj ) - RADEON_STATECHANGE( rmesa, (RADEON_UPLOAD_TEX0 << unit) ); - rmesa->state.hw.texture[unit].pp_txfilter = b; + if ( (rmesa->hw.tex[unit].cmd[TEX_PP_TXFILTER] & RADEON_LOD_BIAS_MASK) != b ) { + RADEON_STATECHANGE( rmesa, tex[unit] ); + rmesa->hw.tex[unit].cmd[TEX_PP_TXFILTER] &= ~RADEON_LOD_BIAS_MASK; + rmesa->hw.tex[unit].cmd[TEX_PP_TXFILTER] |= (b & RADEON_LOD_BIAS_MASK); } break; } @@ -584,8 +508,8 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target, radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %s )\n",__FUNCTION__, + if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { + fprintf( stderr, "%s( %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) ); } @@ -596,6 +520,8 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target, switch ( pname ) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + radeonSetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); radeonSetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); break; @@ -608,10 +534,6 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target, radeonSetTexBorderColor( t, texObj->BorderColor ); break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - radeonSetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); - break; - case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MIN_LOD: @@ -628,12 +550,9 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target, return; } - if ( t == rmesa->state.texture.unit[0].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - } - if ( t == rmesa->state.texture.unit[1].texobj ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); - } + /* Mark this texobj as dirty (one bit per tex unit) + */ + t->dirty_state = TEX_ALL; } @@ -644,8 +563,8 @@ static void radeonBindTexture( GLcontext *ctx, GLenum target, radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; GLuint unit = ctx->Texture.CurrentUnit; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p ) unit=%d\n",__FUNCTION__, (void*)texObj, unit ); + if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { + fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, texObj, unit ); } if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) { @@ -662,8 +581,8 @@ static void radeonDeleteTexture( GLcontext *ctx, radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p )\n",__FUNCTION__, (void*)texObj ); + if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { + fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj ); } if ( t ) { @@ -717,6 +636,27 @@ static void radeonInitTextureObjects( GLcontext *ctx ) ctx->Texture.CurrentUnit = tmp; } +/* Need: + * - Same GEN_MODE for all active bits + * - Same EyePlane/ObjPlane for all active bits when using Eye/Obj + * - STRQ presumably all supported (matrix means incoming R values + * can end up in STQ, this has implications for vertex support, + * presumably ok if maos is used, though?) + * + * Basically impossible to do this on the fly - just collect some + * basic info & do the checks from ValidateState(). + */ +static void radeonTexGen( GLcontext *ctx, + GLenum coord, + GLenum pname, + const GLfloat *params ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint unit = ctx->Texture.CurrentUnit; + rmesa->recheck_texgen[unit] = GL_TRUE; +} + + void radeonInitTextureFuncs( GLcontext *ctx ) { ctx->Driver.ChooseTextureFormat = radeonChooseTextureFormat; @@ -730,7 +670,7 @@ void radeonInitTextureFuncs( GLcontext *ctx ) ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; - ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; ctx->Driver.BindTexture = radeonBindTexture; @@ -743,6 +683,7 @@ void radeonInitTextureFuncs( GLcontext *ctx ) ctx->Driver.TexEnv = radeonTexEnv; ctx->Driver.TexParameter = radeonTexParameter; + ctx->Driver.TexGen = radeonTexGen; radeonInitTextureObjects( ctx ); } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c index efa1fa26a..f87853b35 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c,v 1.4 2002/09/16 18:05:20 eich Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c,v 1.7 2002/12/16 16:18:59 dawes Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -35,17 +35,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "radeon_context.h" -#include "radeon_state.h" -#include "radeon_ioctl.h" -#include "radeon_vb.h" #include "radeon_tex.h" #include "context.h" -#include "colormac.h" -#include "mmath.h" -#include "macros.h" #include "simple_list.h" -#include "enums.h" #include "mem.h" @@ -57,8 +50,8 @@ void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) if ( !t ) return; - if ( RADEON_DEBUG & DEBUG_VERBOSE_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n",__FUNCTION__, (void*)t, (void*)t->tObj ); + if ( RADEON_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); } if ( t->memBlock ) { @@ -75,12 +68,14 @@ void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) if ( t == rmesa->state.texture.unit[0].texobj ) { rmesa->state.texture.unit[0].texobj = NULL; - rmesa->state.hw.dirty &= ~RADEON_UPLOAD_TEX0; + remove_from_list( &rmesa->hw.tex[0] ); + make_empty_list( &rmesa->hw.tex[0] ); } if ( t == rmesa->state.texture.unit[1].texobj ) { rmesa->state.texture.unit[1].texobj = NULL; - rmesa->state.hw.dirty &= ~RADEON_UPLOAD_TEX1; + remove_from_list( &rmesa->hw.tex[1] ); + make_empty_list( &rmesa->hw.tex[1] ); } } @@ -88,12 +83,13 @@ void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) FREE( t ); } + /* Keep track of swapped out texture objects. */ void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) { - if ( RADEON_DEBUG & DEBUG_VERBOSE_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n",__FUNCTION__, (void*)t, (void*)t->tObj ); + if ( RADEON_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); } /* Bump the performace counter */ @@ -124,8 +120,7 @@ void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ) t->memBlock->ofs, t->memBlock->size ); } else { - fprintf( stderr, "Texture (bound %d) at 0x%x sz 0x%x\n", - t->bound, + fprintf( stderr, "Texture at 0x%x sz 0x%x\n", t->memBlock->ofs, t->memBlock->size ); } @@ -139,7 +134,7 @@ void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ) radeon_tex_region_t *list = rmesa->sarea->texList[heap]; int i, j; - fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, (void*)list ); + fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) { fprintf( stderr, "list[%d] age %d next %d prev %d\n", @@ -329,9 +324,11 @@ static void radeonUploadSubImage( radeonContextPtr rmesa, GLuint format, pitch, offset; GLint imageWidth, imageHeight; GLint ret; + drmRadeonTexture tex; + drmRadeonTexImage tmp; - if ( RADEON_DEBUG & DEBUG_VERBOSE_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n",__FUNCTION__, (void*)t, (void*)t->tObj ); + if ( RADEON_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); } /* Ensure we have a valid texture to upload */ @@ -343,13 +340,13 @@ static void radeonUploadSubImage( radeonContextPtr rmesa, texImage = t->tObj->Image[level]; if ( !texImage ) { - if ( RADEON_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, "%s: texImage %d is NULL!\n",__FUNCTION__, level ); + if ( RADEON_DEBUG & DEBUG_TEXTURE ) + fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level ); return; } if ( !texImage->Data ) { - if ( RADEON_DEBUG & DEBUG_VERBOSE_TEXTURE ) - fprintf( stderr, "%s: image data is NULL!\n",__FUNCTION__ ); + if ( RADEON_DEBUG & DEBUG_TEXTURE ) + fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ ); return; } @@ -380,7 +377,7 @@ static void radeonUploadSubImage( radeonContextPtr rmesa, rmesa->c_textureBytes += (dwords << 2); #endif - if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { GLint imageX = 0; GLint imageY = 0; GLint blitX = t->image[level].x; @@ -397,12 +394,24 @@ static void radeonUploadSubImage( radeonContextPtr rmesa, } t->image[level].data = texImage->Data; - ret = drmRadeonLoadTexture( rmesa->dri.fd, offset, pitch, format, - imageWidth, imageHeight, &t->image[level] ); + + tex.offset = offset; + tex.pitch = pitch; + tex.format = format; + tex.width = imageWidth; + tex.height = imageHeight; + tex.image = &tmp; + + memcpy( &tmp, &t->image[level], sizeof(drmRadeonTexImage) ); + + do { + ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE, + &tex, sizeof(drmRadeonTexture) ); + } while ( ret && errno == EAGAIN ); if ( ret ) { UNLOCK_HARDWARE( rmesa ); - fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret ); + fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret ); fprintf( stderr, " offset=0x%08x pitch=0x%x format=%d\n", offset, pitch, format ); fprintf( stderr, " image width=%d height=%d\n", @@ -412,8 +421,6 @@ static void radeonUploadSubImage( radeonContextPtr rmesa, t->image[level].data ); exit( 1 ); } - - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS ); } /* Upload the texture images associated with texture `t'. This might @@ -425,10 +432,12 @@ int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ) const int numLevels = t->lastLevel - t->firstLevel + 1; int i; int heap; + radeonTexObjPtr t0 = rmesa->state.texture.unit[0].texobj; + radeonTexObjPtr t1 = rmesa->state.texture.unit[1].texobj; - if ( RADEON_DEBUG & DEBUG_VERBOSE_TEXTURE ) { - fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n",__FUNCTION__, - (void*)rmesa->glCtx, (void*)t->tObj, t->totalSize, + if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { + fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, + rmesa->glCtx, t->tObj, t->totalSize, t->firstLevel, t->lastLevel ); } @@ -465,7 +474,8 @@ int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ) /* Kick out textures until the requested texture fits */ while ( !t->memBlock ) { - if ( rmesa->texture.objects[heap].prev->bound ) { + if ( rmesa->texture.objects[heap].prev == t0 || + rmesa->texture.objects[heap].prev == t1 ) { fprintf( stderr, "radeonUploadTexImages: ran into bound texture\n" ); UNLOCK_HARDWARE( rmesa ); @@ -512,11 +522,9 @@ int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ) } #endif - if ( t == rmesa->state.texture.unit[0].texobj ) - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX0 ); - - if ( t == rmesa->state.texture.unit[1].texobj ) - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_TEX1 ); + /* Mark this texobj as dirty on all units: + */ + t->dirty_state = TEX_ALL; } /* Let the world know we've used this memory recently */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c index f66f589cd..943074514 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.3 2002/09/16 18:05:21 eich Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.6 2002/12/16 16:18:59 dawes Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -37,16 +37,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #include "radeon_state.h" #include "radeon_ioctl.h" -#include "radeon_vb.h" +#include "radeon_swtcl.h" #include "radeon_tex.h" +#include "radeon_tcl.h" -#include "colormac.h" #include "context.h" #include "enums.h" -#include "macros.h" #include "mem.h" -#include "mmath.h" -#include "simple_list.h" #include "texformat.h" @@ -228,6 +225,8 @@ static void radeonSetTexImages( radeonContextPtr rmesa, t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) | (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT)); + t->dirty_state = TEX_ALL; + radeonUploadTexImages( rmesa, t ); } @@ -723,7 +722,7 @@ do { \ * Texture unit state management */ -static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) +static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; @@ -733,9 +732,9 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) GLuint color_arg[3], alpha_arg[3]; GLuint i, numColorArgs = 0, numAlphaArgs = 0; - if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %d ) format=%s\n",__FUNCTION__, - (void*)ctx, unit, _mesa_lookup_enum_by_nr( format ) ); + if ( RADEON_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %d ) format=%s\n", __FUNCTION__, + ctx, unit, _mesa_lookup_enum_by_nr( format ) ); } /* Set the texture environment state. Isn't this nice and clean? @@ -764,7 +763,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -787,7 +786,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -807,7 +806,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -830,7 +829,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -853,7 +852,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -872,16 +871,19 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_MODULATE: case GL_ADD: - case GL_ADD_SIGNED_EXT: + case GL_ADD_SIGNED: + case GL_SUBTRACT: + case GL_DOT3_RGB: + case GL_DOT3_RGBA: case GL_DOT3_RGB_EXT: case GL_DOT3_RGBA_EXT: numColorArgs = 2; break; - case GL_INTERPOLATE_EXT: + case GL_INTERPOLATE: numColorArgs = 3; break; default: - return; + return GL_FALSE; } switch ( texUnit->CombineModeA ) { @@ -890,14 +892,15 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_MODULATE: case GL_ADD: - case GL_ADD_SIGNED_EXT: + case GL_ADD_SIGNED: + case GL_SUBTRACT: numAlphaArgs = 2; break; - case GL_INTERPOLATE_EXT: + case GL_INTERPOLATE: numAlphaArgs = 3; break; default: - return; + return GL_FALSE; } /* Step 1: @@ -911,17 +914,17 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) case GL_TEXTURE: color_arg[i] = radeon_texture_color[op][unit]; break; - case GL_CONSTANT_EXT: + case GL_CONSTANT: color_arg[i] = radeon_tfactor_color[op]; break; - case GL_PRIMARY_COLOR_EXT: + case GL_PRIMARY_COLOR: color_arg[i] = radeon_primary_color[op]; break; - case GL_PREVIOUS_EXT: + case GL_PREVIOUS: color_arg[i] = radeon_previous_color[op]; break; default: - return; + return GL_FALSE; } } @@ -933,17 +936,17 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) case GL_TEXTURE: alpha_arg[i] = radeon_texture_alpha[op][unit]; break; - case GL_CONSTANT_EXT: + case GL_CONSTANT: alpha_arg[i] = radeon_tfactor_alpha[op]; break; - case GL_PRIMARY_COLOR_EXT: + case GL_PRIMARY_COLOR: alpha_arg[i] = radeon_primary_alpha[op]; break; - case GL_PREVIOUS_EXT: + case GL_PREVIOUS: alpha_arg[i] = radeon_previous_alpha[op]; break; default: - return; + return GL_FALSE; } } @@ -973,7 +976,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, C ); break; - case GL_ADD_SIGNED_EXT: + case GL_ADD_SIGNED: color_combine = (RADEON_COLOR_ARG_B_ZERO | RADEON_COMP_ARG_B | RADEON_BLEND_CTL_ADDSIGNED | @@ -981,13 +984,31 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, C ); break; - case GL_INTERPOLATE_EXT: + case GL_SUBTRACT: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_SUBTRACT | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + break; + case GL_INTERPOLATE: color_combine = (RADEON_BLEND_CTL_BLEND | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, B ); RADEON_COLOR_ARG( 1, A ); RADEON_COLOR_ARG( 2, C ); break; + + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + if ( texUnit->CombineScaleShiftRGB + != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) + { + return GL_FALSE; + } + /* FALLTHROUGH */ + case GL_DOT3_RGB_EXT: case GL_DOT3_RGBA_EXT: color_combine = (RADEON_COLOR_ARG_C_ZERO | @@ -997,7 +1018,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) RADEON_COLOR_ARG( 1, B ); break; default: - return; + return GL_FALSE; } switch ( texUnit->CombineModeA ) { @@ -1023,7 +1044,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) RADEON_ALPHA_ARG( 0, A ); RADEON_ALPHA_ARG( 1, C ); break; - case GL_ADD_SIGNED_EXT: + case GL_ADD_SIGNED: alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | RADEON_COMP_ARG_B | RADEON_BLEND_CTL_ADDSIGNED | @@ -1031,7 +1052,15 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) RADEON_ALPHA_ARG( 0, A ); RADEON_ALPHA_ARG( 1, C ); break; - case GL_INTERPOLATE_EXT: + case GL_SUBTRACT: + alpha_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_SUBTRACT | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_INTERPOLATE: alpha_combine = (RADEON_BLEND_CTL_BLEND | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, B ); @@ -1039,23 +1068,26 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) RADEON_ALPHA_ARG( 2, C ); break; default: - return; + return GL_FALSE; } - if ( texUnit->CombineModeRGB == GL_DOT3_RGB_EXT ) { + if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT) + || (texUnit->CombineModeRGB == GL_DOT3_RGB_ARB) ) { alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE; } /* Step 3: - * Apply the scale factor. The EXT extension has a somewhat - * unnecessary restriction that the scale must be 4x. The ARB - * extension will likely drop this and we can just apply the - * scale factors regardless. + * Apply the scale factor. The EXT version of the DOT3 extension does + * not support the scale factor, but the ARB version (and the version in + * OpenGL 1.3) does. The catch is that the Radeon only supports a 1X + * multiplier in hardware w/the ARB version. */ if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT && - texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT ) { - color_combine |= (texUnit->CombineScaleShiftRGB << 21); - alpha_combine |= (texUnit->CombineScaleShiftA << 21); + texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT && + texUnit->CombineModeRGB != GL_DOT3_RGB && + texUnit->CombineModeRGB != GL_DOT3_RGBA ) { + color_combine |= (texUnit->CombineScaleShiftRGB << RADEON_SCALE_SHIFT); + alpha_combine |= (texUnit->CombineScaleShiftA << RADEON_SCALE_SHIFT); } else { @@ -1068,57 +1100,227 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) break; default: - return; + return GL_FALSE; + } + + if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine || + rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) { + RADEON_STATECHANGE( rmesa, tex[unit] ); + rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine; + rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine; + } + + return GL_TRUE; +} + +#define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \ + RADEON_MIN_FILTER_MASK | \ + RADEON_MAG_FILTER_MASK | \ + RADEON_MAX_ANISO_MASK | \ + RADEON_CLAMP_S_MASK | \ + RADEON_CLAMP_T_MASK) + +#define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \ + RADEON_TXFORMAT_HEIGHT_MASK | \ + RADEON_TXFORMAT_FORMAT_MASK | \ + RADEON_TXFORMAT_ALPHA_IN_MAP) + + +static void import_tex_obj_state( radeonContextPtr rmesa, + int unit, + radeonTexObjPtr texobj ) +{ + GLuint *cmd = RADEON_DB_STATE( tex[unit] ); + + cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; + cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; + cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; + cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; + cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset; + cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; + texobj->dirty_state &= ~(1<<unit); + + RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] ); +} + + + + +static void set_texgen_matrix( radeonContextPtr rmesa, + GLuint unit, + GLfloat *s_plane, + GLfloat *t_plane ) +{ + static const GLfloat scale_identity[4] = { 1,1,1,1 }; + + if (!TEST_EQ_4V( s_plane, scale_identity) || + !(TEST_EQ_4V( t_plane, scale_identity))) { + rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<<unit; + rmesa->TexGenMatrix[unit].m[0] = s_plane[0]; + rmesa->TexGenMatrix[unit].m[4] = s_plane[1]; + rmesa->TexGenMatrix[unit].m[8] = s_plane[2]; + rmesa->TexGenMatrix[unit].m[12] = s_plane[3]; + + rmesa->TexGenMatrix[unit].m[1] = t_plane[0]; + rmesa->TexGenMatrix[unit].m[5] = t_plane[1]; + rmesa->TexGenMatrix[unit].m[9] = t_plane[2]; + rmesa->TexGenMatrix[unit].m[13] = t_plane[3]; + rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + } +} + +/* Ignoring the Q texcoord for now. + * + * Returns GL_FALSE if fallback required. + */ +static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4; + GLuint tmp = rmesa->TexGenEnabled; + + rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit); + rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit); + rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift); + rmesa->TexGenNeedNormals[unit] = 0; + + if (0) + fprintf(stderr, "%s unit %d cleared texgenEnabled %x\n", __FUNCTION__, + unit, rmesa->TexGenEnabled); + + if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) { + /* Disabled, no fallback: + */ + rmesa->TexGenEnabled |= + (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; + return GL_TRUE; + } + else if (texUnit->TexGenEnabled & Q_BIT) { + /* Very easy to do this, in fact would remove a fallback case + * elsewhere, but I haven't done it yet... Fallback: + */ + fprintf(stderr, "fallback Q_BIT\n"); + return GL_FALSE; + } + else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) || + texUnit->GenModeS != texUnit->GenModeT) { + /* Mixed modes, fallback: + */ +/* fprintf(stderr, "fallback mixed texgen\n"); */ + return GL_FALSE; + } + else + rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit; + + switch (texUnit->GenModeS) { + case GL_OBJECT_LINEAR: + rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift; + set_texgen_matrix( rmesa, unit, + texUnit->ObjectPlaneS, + texUnit->ObjectPlaneT); + break; + + case GL_EYE_LINEAR: + rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift; + set_texgen_matrix( rmesa, unit, + texUnit->EyePlaneS, + texUnit->EyePlaneT); + break; + + case GL_REFLECTION_MAP_NV: + rmesa->TexGenNeedNormals[unit] = GL_TRUE; + rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT<<inputshift; + break; + + case GL_NORMAL_MAP_NV: + rmesa->TexGenNeedNormals[unit] = GL_TRUE; + rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL<<inputshift; + break; + + case GL_SPHERE_MAP: + default: + /* Unsupported mode, fallback: + */ + /* fprintf(stderr, "fallback unsupported texgen\n"); */ + return GL_FALSE; } - if ( rmesa->state.hw.texture[unit].pp_txcblend != color_combine || - rmesa->state.hw.texture[unit].pp_txablend != alpha_combine ) { - RADEON_STATECHANGE( rmesa, (RADEON_UPLOAD_TEX0 << unit) ); - rmesa->state.hw.texture[unit].pp_txcblend = color_combine; - rmesa->state.hw.texture[unit].pp_txablend = alpha_combine; + if (tmp != rmesa->TexGenEnabled) { + rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; } + +/* fprintf(stderr, "%s unit %d texgenEnabled %x\n", __FUNCTION__, */ +/* unit, rmesa->TexGenEnabled); */ + return GL_TRUE; } -static void radeonUpdateTextureUnit( GLcontext *ctx, int unit ) + + + +static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + if ( texUnit->_ReallyEnabled & (TEXTURE0_1D|TEXTURE0_2D) ) { struct gl_texture_object *tObj = texUnit->_Current; radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; - GLuint flag = RADEON_UPLOAD_TEX0 << unit; GLenum format; /* Fallback if there's a texture border */ - if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) { - FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE ); - return; - } + if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) + return GL_FALSE; /* Upload teximages (not pipelined) */ if ( t->dirty_images ) { RADEON_FIREVERTICES( rmesa ); radeonSetTexImages( rmesa, tObj ); - if ( !t->memBlock ) { - FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE ); - return; - } + /* Fallback if we can't upload: + */ + if ( !t->memBlock ) + return GL_FALSE; } /* Update state if this is a different texture object to last * time. */ if ( rmesa->state.texture.unit[unit].texobj != t ) { - if ( rmesa->state.texture.unit[unit].texobj == NULL ) { - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - rmesa->state.hw.context.pp_cntl |= (RADEON_TEX_0_ENABLE | - RADEON_TEX_BLEND_0_ENABLE)<<unit; - } - RADEON_STATECHANGE( rmesa, flag ); rmesa->state.texture.unit[unit].texobj = t; - radeonUpdateTexLRU( rmesa, t ); /* done too often */ + t->dirty_state |= 1<<unit; + radeonUpdateTexLRU( rmesa, t ); /* XXX: should be locked! */ + } + + + /* Newly enabled? + */ + if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) { + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= + (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit; + + RADEON_STATECHANGE( rmesa, tcl ); + + if (unit == 0) + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0; + else + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST1; + + rmesa->recheck_texgen[unit] = GL_TRUE; + } + + if (t->dirty_state & (1<<unit)) { + import_tex_obj_state( rmesa, unit, t ); + } + + if (rmesa->recheck_texgen[unit]) { + GLboolean fallback = !radeon_validate_texgen( ctx, unit ); + TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback); + rmesa->recheck_texgen[unit] = 0; + rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; } format = tObj->Image[tObj->BaseLevel]->Format; @@ -1126,27 +1328,76 @@ static void radeonUpdateTextureUnit( GLcontext *ctx, int unit ) rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) { rmesa->state.texture.unit[unit].format = format; rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode; - radeonUpdateTextureEnv( ctx, unit ); + if ( ! radeonUpdateTextureEnv( ctx, unit ) ) { + return GL_FALSE; + } } } else if ( texUnit->_ReallyEnabled ) { - FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE ); - return; + /* 3d textures, etc: + */ + return GL_FALSE; } - else { + else if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) { /* Texture unit disabled */ rmesa->state.texture.unit[unit].texobj = 0; - rmesa->state.hw.dirty &= ~(RADEON_UPLOAD_TEX0 << unit); - RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT ); - rmesa->state.hw.context.pp_cntl &= ~((RADEON_TEX_0_ENABLE | - RADEON_TEX_BLEND_0_ENABLE) << unit); + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= + ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit); + + RADEON_STATECHANGE( rmesa, tcl ); + switch (unit) { + case 0: + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST0 | + RADEON_TCL_VTX_Q0); + break; + case 1: + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST1 | + RADEON_TCL_VTX_Q1); + break; + default: + break; + } + + + if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) { + TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE); + rmesa->recheck_texgen[unit] = GL_TRUE; + } + + + + { + GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4; + GLuint tmp = rmesa->TexGenEnabled; + + rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit); + rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit); + rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift); + rmesa->TexGenNeedNormals[unit] = 0; + rmesa->TexGenEnabled |= + (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; + + if (tmp != rmesa->TexGenEnabled) { + rmesa->recheck_texgen[unit] = GL_TRUE; + rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + } + } } + + return GL_TRUE; } void radeonUpdateTextureState( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, GL_FALSE ); - radeonUpdateTextureUnit( ctx, 0 ); - radeonUpdateTextureUnit( ctx, 1 ); + GLboolean ok; + + ok = (radeonUpdateTextureUnit( ctx, 0 ) && + radeonUpdateTextureUnit( ctx, 1 )); + + FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok ); + + if (rmesa->TclFallback) + radeonChooseVertexState( ctx ); } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c index 6b06a33c2..3da333549 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c @@ -1,607 +1,979 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c,v 1.2 2002/09/10 00:39:39 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c,v 1.5 2002/12/16 16:18:59 dawes Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + /* - * Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * * Authors: - * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> + * */ - - #include "glheader.h" +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_tex.h" +#include "radeon_tcl.h" +#include "radeon_vtxfmt.h" + #include "api_noop.h" -#include "colormac.h" +#include "api_arrayelt.h" #include "context.h" -#include "light.h" -#include "macros.h" #include "mem.h" #include "mmath.h" #include "mtypes.h" -#include "simple_list.h" +#include "enums.h" +#include "glapi.h" +#include "colormac.h" +#include "light.h" +#include "state.h" #include "vtxfmt.h" -#include "math/m_xform.h" #include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_array_api.h" -#include "radeon_context.h" -#include "radeon_ioctl.h" -#include "radeon_vb.h" -#include "radeon_vtxfmt.h" - +struct radeon_vb vb; -#define VERTEX radeonVertex -#define TNL_VERTEX radeonTnlVertex +static void radeonFlushVertices( GLcontext *, GLuint ); +static void count_func( const char *name, struct dynfn *l ) +{ + int i = 0; + struct dynfn *f; + foreach (f, l) i++; + if (i) fprintf(stderr, "%s: %d\n", name, i ); +} -#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A))) - -#define INTERP_RGBA( t, out, a, b ) \ -do { \ - GLint i; \ - for ( i = 0 ; i < 4 ; i++ ) { \ - GLfloat fa = UBYTE_TO_FLOAT( a[i] ); \ - GLfloat fb = UBYTE_TO_FLOAT( b[i] ); \ - GLfloat fo = LINTERP( t, fa, fb ); \ - UNCLAMPED_FLOAT_TO_UBYTE( out[i], fo ); \ - } \ -} while (0) - +static void count_funcs( radeonContextPtr rmesa ) +{ + count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f ); + count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv ); + count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f ); + count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv ); + count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub ); + count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv ); + count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub ); + count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv ); + count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f ); + count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv ); + count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f ); + count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv ); + count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); + count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); + count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); + count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); + count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f ); + count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv ); + count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f ); + count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv ); + count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f ); + count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv ); + count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); + count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); +} +void radeon_copy_to_current( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); -/* ================================================================ - * Color functions: Always update ctx->Current.* - */ + assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT); + assert(vb.context == ctx); -/* ================================================================ - * Material functions: - */ + if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_N0) { + ctx->Current.Normal[0] = vb.normalptr[0]; + ctx->Current.Normal[1] = vb.normalptr[1]; + ctx->Current.Normal[2] = vb.normalptr[2]; + } -static __inline void radeon_recalc_base_color( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct gl_light *light; + if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKCOLOR) { + ctx->Current.Color[0] = UBYTE_TO_FLOAT( vb.colorptr->red ); + ctx->Current.Color[1] = UBYTE_TO_FLOAT( vb.colorptr->green ); + ctx->Current.Color[2] = UBYTE_TO_FLOAT( vb.colorptr->blue ); + ctx->Current.Color[3] = UBYTE_TO_FLOAT( vb.colorptr->alpha ); + } + + if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPCOLOR) { + ctx->Current.Color[0] = vb.floatcolorptr[0]; + ctx->Current.Color[1] = vb.floatcolorptr[1]; + ctx->Current.Color[2] = vb.floatcolorptr[2]; + } - COPY_3V( rmesa->state.light.base_color, ctx->Light._BaseColor[0] ); - foreach ( light, &ctx->Light.EnabledList ) { - ACC_3V( rmesa->state.light.base_color, light->_MatAmbient[0] ); + if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPALPHA) + ctx->Current.Color[3] = vb.floatcolorptr[3]; + + if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKSPEC) { + ctx->Current.SecondaryColor[0] = UBYTE_TO_FLOAT( vb.specptr->red ); + ctx->Current.SecondaryColor[1] = UBYTE_TO_FLOAT( vb.specptr->green ); + ctx->Current.SecondaryColor[2] = UBYTE_TO_FLOAT( vb.specptr->blue ); + } + + if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_ST0) { + ctx->Current.Texcoord[0][0] = vb.texcoordptr[0][0]; + ctx->Current.Texcoord[0][1] = vb.texcoordptr[0][1]; + ctx->Current.Texcoord[0][2] = 0.0F; + ctx->Current.Texcoord[0][3] = 1.0F; } - - UNCLAMPED_FLOAT_TO_UBYTE( rmesa->state.light.base_alpha, - ctx->Light.Material[0].Diffuse[3] ); -} + if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_ST1) { + ctx->Current.Texcoord[1][0] = vb.texcoordptr[1][0]; + ctx->Current.Texcoord[1][1] = vb.texcoordptr[1][1]; + ctx->Current.Texcoord[1][2] = 0.0F; + ctx->Current.Texcoord[1][3] = 1.0F; + } -/* ================================================================ - * Normal functions: - */ + ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; +} -struct radeon_norm_tab { - void (*normal3f_multi)( GLfloat x, GLfloat y, GLfloat z ); - void (*normal3fv_multi)( const GLfloat *v ); - void (*normal3f_single)( GLfloat x, GLfloat y, GLfloat z ); - void (*normal3fv_single)( const GLfloat *v ); +static GLboolean discreet_gl_prim[GL_POLYGON+1] = { + 1, /* 0 points */ + 1, /* 1 lines */ + 0, /* 2 line_strip */ + 0, /* 3 line_loop */ + 1, /* 4 tris */ + 0, /* 5 tri_fan */ + 0, /* 6 tri_strip */ + 1, /* 7 quads */ + 0, /* 8 quadstrip */ + 0, /* 9 poly */ }; -static struct radeon_norm_tab norm_tab[0x4]; - +static void flush_prims( radeonContextPtr rmesa ) +{ + int i,j; + struct radeon_dma_region tmp = rmesa->dma.current; + + tmp.buf->refcount++; + tmp.aos_size = vb.vertex_size; + tmp.aos_stride = vb.vertex_size; + tmp.aos_start = GET_START(&tmp); + + rmesa->dma.current.ptr = rmesa->dma.current.start += + (vb.initial_counter - vb.counter) * vb.vertex_size * 4; + + rmesa->tcl.vertex_format = rmesa->vb.vertex_format; + rmesa->tcl.aos_components[0] = &tmp; + rmesa->tcl.nr_aos_components = 1; + rmesa->dma.flush = 0; + + /* Optimize the primitive list: + */ + if (rmesa->vb.nrprims > 1) { + for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) { + int pj = rmesa->vb.primlist[j].prim & 0xf; + int pi = rmesa->vb.primlist[i].prim & 0xf; + + if (pj == pi && discreet_gl_prim[pj] && + rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) { + rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end; + } + else { + j++; + if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i]; + } + } + rmesa->vb.nrprims = j+1; + } -#define HAVE_HW_LIGHTING 0 + for (i = 0 ; i < rmesa->vb.nrprims; i++) { + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i, + _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim & + PRIM_MODE_MASK ), + rmesa->vb.primlist[i].start, + rmesa->vb.primlist[i].end); + + radeonEmitPrimitive( vb.context, + rmesa->vb.primlist[i].start, + rmesa->vb.primlist[i].end, + rmesa->vb.primlist[i].prim ); + } -#define GET_CURRENT_VERTEX \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - radeonTnlVertexPtr v = rmesa->imm.v0 + rmesa->vb.nrprims = 0; + radeonReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ ); +} -#define CURRENT_NORMAL rmesa->state.current.normal -#define BASE_COLOR rmesa->state.light.base_color -#define BASE_ALPHA rmesa->state.light.base_alpha -#define VERT_COLOR( COMP ) v->color[COMP] +static void start_prim( radeonContextPtr rmesa, GLuint mode ) +{ + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s %d\n", __FUNCTION__, vb.initial_counter - vb.counter); + rmesa->vb.primlist[rmesa->vb.nrprims].start = vb.initial_counter - vb.counter; + rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode; +} -#define IND (0) -#define TAG(x) radeon_##x -#define PRESERVE_NORMAL_DEFS -#include "tnl_dd/t_dd_imm_napi.h" +static void note_last_prim( radeonContextPtr rmesa, GLuint flags ) +{ + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s %d\n", __FUNCTION__, vb.initial_counter - vb.counter); -#define IND (NORM_RESCALE) -#define TAG(x) radeon_##x##_rescale -#define PRESERVE_NORMAL_DEFS -#include "tnl_dd/t_dd_imm_napi.h" + if (rmesa->vb.prim[0] != GL_POLYGON+1) { + rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags; + rmesa->vb.primlist[rmesa->vb.nrprims].end = vb.initial_counter - vb.counter; -#define IND (NORM_NORMALIZE) -#define TAG(x) radeon_##x##_normalize -#include "tnl_dd/t_dd_imm_napi.h" + if (++(rmesa->vb.nrprims) == RADEON_MAX_PRIMS) + flush_prims( rmesa ); + } +} -static void radeon_init_norm_funcs( void ) +static void copy_vertex( radeonContextPtr rmesa, GLuint n, GLfloat *dst ) { - radeon_init_norm(); - radeon_init_norm_rescale(); - radeon_init_norm_normalize(); -} + GLuint i; + GLfloat *src = (GLfloat *)(rmesa->dma.current.address + + rmesa->dma.current.ptr + + (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) * + vb.vertex_size * 4); -static void radeon_choose_Normal3f( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint index; + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n); - if ( ctx->Light.Enabled ) { - if ( ctx->Transform.Normalize ) { - index = NORM_NORMALIZE; - } - else if ( !ctx->Transform.RescaleNormals && - ctx->_ModelViewInvScale != 1.0 ) { - index = NORM_RESCALE; - } - else { - index = 0; - } + for (i = 0 ; i < vb.vertex_size; i++) { + dst[i] = src[i]; + } +} - if ( ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev ) { - ctx->Exec->Normal3f = norm_tab[index].normal3f_single; +/* NOTE: This actually reads the copied vertices back from uncached + * memory. Could also use the counter/notify mechanism to populate + * tmp on the fly as vertices are generated. + */ +static GLuint copy_dma_verts( radeonContextPtr rmesa, GLfloat (*tmp)[15] ) +{ + GLuint ovf, i; + GLuint nr = (vb.initial_counter - vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start; + + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr); + + switch( rmesa->vb.prim[0] ) + { + case GL_POINTS: + return 0; + case GL_LINES: + ovf = nr&1; + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + case GL_TRIANGLES: + ovf = nr%3; + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + case GL_QUADS: + ovf = nr&3; + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + case GL_LINE_STRIP: + if (nr == 0) + return 0; + copy_vertex( rmesa, nr-1, tmp[0] ); + return 1; + case GL_LINE_LOOP: + case GL_TRIANGLE_FAN: + case GL_POLYGON: + if (nr == 0) + return 0; + else if (nr == 1) { + copy_vertex( rmesa, 0, tmp[0] ); + return 1; } else { - ctx->Exec->Normal3f = norm_tab[index].normal3f_multi; + copy_vertex( rmesa, 0, tmp[0] ); + copy_vertex( rmesa, nr-1, tmp[1] ); + return 2; } - } else { - ctx->Exec->Normal3f = _mesa_noop_Normal3f; + case GL_TRIANGLE_STRIP: + ovf = MIN2( nr-1, 2 ); + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + case GL_QUAD_STRIP: + ovf = MIN2( nr-1, 2 ); + if (nr > 2) ovf += nr&1; + for (i = 0 ; i < ovf ; i++) + copy_vertex( rmesa, nr-ovf+i, tmp[i] ); + return i; + default: + assert(0); + return 0; } - - glNormal3f( x, y, z ); } -static void radeon_choose_Normal3fv( const GLfloat *v ) +static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) { - GET_CURRENT_CONTEXT(ctx); - GLuint index; + GLcontext *ctx = vb.context; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if ( ctx->Light.Enabled ) { - if ( ctx->Transform.Normalize ) { - index = NORM_NORMALIZE; - } - else if ( !ctx->Transform.RescaleNormals && - ctx->_ModelViewInvScale != 1.0 ) { - index = NORM_RESCALE; - } - else { - index = 0; - } + if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) + fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - if ( ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev ) { - ctx->Exec->Normal3fv = norm_tab[index].normal3fv_single; - } else { - ctx->Exec->Normal3fv = norm_tab[index].normal3fv_multi; - } - } else { - ctx->Exec->Normal3fv = _mesa_noop_Normal3fv; - } + if (ctx->Driver.NeedFlush) + radeonFlushVertices( ctx, ctx->Driver.NeedFlush ); + + if (ctx->NewState) + _mesa_update_state( ctx ); /* clear state so fell_back sticks */ + + _tnl_wakeup_exec( ctx ); - glNormal3fv( v ); + assert( rmesa->dma.flush == 0 ); + rmesa->vb.fell_back = GL_TRUE; + rmesa->vb.installed = GL_FALSE; + vb.context = 0; } +static void VFMT_FALLBACK( const char *caller ) +{ + GLcontext *ctx = vb.context; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLfloat tmp[3][15]; + GLuint i, prim; + GLuint ind = rmesa->vb.vertex_format; + GLuint nrverts; + GLfloat alpha = 1.0; + if (RADEON_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT)) + fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); -/* ================================================================ - * Texture functions: - */ + if (rmesa->vb.prim[0] == GL_POLYGON+1) { + VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); + return; + } -#define GET_CURRENT \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx) + /* Copy vertices out of dma: + */ + nrverts = copy_dma_verts( rmesa, tmp ); -#define NUM_TEXTURE_UNITS RADEON_MAX_TEXTURE_UNITS -#define DO_PROJ_TEX + /* Finish the prim at this point: + */ + note_last_prim( rmesa, 0 ); + flush_prims( rmesa ); -#define CURRENT_TEXTURE( unit ) rmesa->state.current.texture[unit] + /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl. + */ + prim = rmesa->vb.prim[0]; + ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; + _tnl_wakeup_exec( ctx ); -#define TAG(x) radeon_##x -#include "tnl_dd/t_dd_imm_tapi.h" + assert(rmesa->dma.flush == 0); + rmesa->vb.fell_back = GL_TRUE; + rmesa->vb.installed = GL_FALSE; + vb.context = 0; + glBegin( prim ); + + if (rmesa->vb.installed_color_3f_sz == 4) + alpha = ctx->Current.Color[3]; + /* Replay saved vertices + */ + for (i = 0 ; i < nrverts; i++) { + GLuint offset = 3; + if (ind & RADEON_CP_VC_FRMT_N0) { + glNormal3fv( &tmp[i][offset] ); + offset += 3; + } + if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { + radeon_color_t *col = (radeon_color_t *)&tmp[i][offset]; + glColor4ub( col->red, col->green, col->blue, col->alpha ); + offset++; + } + else if (ind & RADEON_CP_VC_FRMT_FPALPHA) { + glColor4fv( &tmp[i][offset] ); + offset+=4; + } + else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { + glColor3fv( &tmp[i][offset] ); + offset+=3; + } -/* ================================================================ - * Vertex functions: - */ + if (ind & RADEON_CP_VC_FRMT_PKSPEC) { + radeon_color_t *spec = (radeon_color_t *)&tmp[i][offset]; + _glapi_Dispatch->SecondaryColor3ubEXT( spec->red, spec->green, spec->blue ); + offset++; + } -#define GET_CURRENT_VERTEX \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - radeonTnlVertexPtr v = rmesa->imm.v0 + if (ind & RADEON_CP_VC_FRMT_ST0) { + glTexCoord2fv( &tmp[i][offset] ); + offset += 2; + } -#define CURRENT_VERTEX v->obj -#define SAVE_VERTEX rmesa->imm.save_vertex( ctx, v ) + if (ind & RADEON_CP_VC_FRMT_ST1) { + glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, &tmp[i][offset] ); + offset += 2; + } + glVertex3fv( &tmp[i][0] ); + } -#define TAG(x) radeon_##x -#include "tnl_dd/t_dd_imm_vapi.h" + /* Replay current vertex + */ + if (ind & RADEON_CP_VC_FRMT_N0) + glNormal3fv( vb.normalptr ); + + if (ind & RADEON_CP_VC_FRMT_PKCOLOR) + glColor4ub( vb.colorptr->red, vb.colorptr->green, vb.colorptr->blue, vb.colorptr->alpha ); + else if (ind & RADEON_CP_VC_FRMT_FPALPHA) + glColor4fv( vb.floatcolorptr ); + else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { + if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) + glColor4f( vb.floatcolorptr[0], + vb.floatcolorptr[1], + vb.floatcolorptr[2], + alpha ); + else + glColor3fv( vb.floatcolorptr ); + } + if (ind & RADEON_CP_VC_FRMT_PKSPEC) + _glapi_Dispatch->SecondaryColor3ubEXT( vb.specptr->red, vb.specptr->green, vb.specptr->blue ); + if (ind & RADEON_CP_VC_FRMT_ST0) + glTexCoord2fv( vb.texcoordptr[0] ); + if (ind & RADEON_CP_VC_FRMT_ST1) + glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, vb.texcoordptr[1] ); +} -struct radeon_vert_tab { - void (*save_vertex)( GLcontext *ctx, radeonTnlVertexPtr v ); - void (*interpolate_vertex)( GLfloat t, - radeonTnlVertex *O, - const radeonTnlVertex *I, - const radeonTnlVertex *J ); -}; -static struct radeon_vert_tab vert_tab[0xf]; -#define VTX_NORMAL 0x0 -#define VTX_RGBA 0x1 -#define VTX_SPEC 0x2 -#define VTX_TEX0 0x4 -#define VTX_TEX1 0x8 +static void wrap_buffer( void ) +{ + GLcontext *ctx = vb.context; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLfloat tmp[3][15]; + GLuint i, nrverts; -#define LOCAL_VARS \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx) + if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS)) + fprintf(stderr, "%s %d\n", __FUNCTION__, vb.initial_counter - vb.counter); -#define CURRENT_COLOR rmesa->state.current.color -#define CURRENT_SPECULAR rmesa->state.current.specular + /* Don't deal with parity. + */ + if ((((vb.initial_counter - vb.counter) - + rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) { + vb.counter++; + vb.initial_counter++; + return; + } -#define CURRENT_NORMAL( COMP ) rmesa->state.current.normal[COMP] -#define CURRENT_TEXTURE( U, COMP ) rmesa->state.current.texture[U][COMP] + /* Copy vertices out of dma: + */ + if (rmesa->vb.prim[0] == GL_POLYGON+1) + nrverts = 0; + else { + nrverts = copy_dma_verts( rmesa, tmp ); + + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%d vertices to copy\n", nrverts); + + /* Finish the prim at this point: + */ + note_last_prim( rmesa, 0 ); + } -#define FLUSH_VERTEX rmesa->imm.flush_vertex( ctx, v ); + /* Fire any buffered primitives + */ + flush_prims( rmesa ); + /* Get new buffer + */ + radeonRefillCurrentDmaRegion( rmesa ); -#define IND (VTX_NORMAL) -#define TAG(x) radeon_##x##_NORMAL -#define PRESERVE_VERTEX_DEFS -#include "tnl_dd/t_dd_imm_vertex.h" + /* Reset counter, dmaptr + */ + vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address); + vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / + (vb.vertex_size * 4); + vb.counter--; + vb.initial_counter = vb.counter; + vb.notify = wrap_buffer; -#define IND (VTX_NORMAL|VTX_TEX0) -#define TAG(x) radeon_##x##_NORMAL_TEX0 -#define PRESERVE_VERTEX_DEFS -#include "tnl_dd/t_dd_imm_vertex.h" + rmesa->dma.flush = flush_prims; -#define IND (VTX_NORMAL|VTX_TEX0|VTX_TEX1) -#define TAG(x) radeon_##x##_NORMAL_TEX0_TEX1 -#define PRESERVE_VERTEX_DEFS -#include "tnl_dd/t_dd_imm_vertex.h" + /* Restart wrapped primitive: + */ + if (rmesa->vb.prim[0] != GL_POLYGON+1) + start_prim( rmesa, rmesa->vb.prim[0] ); -#define IND (VTX_RGBA) -#define TAG(x) radeon_##x##_RGBA -#define PRESERVE_VERTEX_DEFS -#include "tnl_dd/t_dd_imm_vertex.h" + /* Reemit saved vertices + */ + for (i = 0 ; i < nrverts; i++) { + if (RADEON_DEBUG & DEBUG_VERTS) { + int j; + fprintf(stderr, "re-emit vertex %d to %p\n", i, vb.dmaptr); + if (RADEON_DEBUG & DEBUG_VERBOSE) + for (j = 0 ; j < vb.vertex_size; j++) + fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]); + } -#define IND (VTX_RGBA|VTX_TEX0) -#define TAG(x) radeon_##x##_RGBA_TEX0 -#define PRESERVE_VERTEX_DEFS -#include "tnl_dd/t_dd_imm_vertex.h" + memcpy( vb.dmaptr, tmp[i], vb.vertex_size * 4 ); + vb.dmaptr += vb.vertex_size; + vb.counter--; + } +} -#define IND (VTX_RGBA|VTX_TEX1) -#define TAG(x) radeon_##x##_RGBA_TEX0_TEX1 -#include "tnl_dd/t_dd_imm_vertex.h" -static void radeon_init_vert_funcs( void ) +static GLboolean check_vtx_fmt( GLcontext *ctx ) { - radeon_init_vert_NORMAL(); - radeon_init_vert_NORMAL_TEX0(); - radeon_init_vert_NORMAL_TEX0_TEX1(); - radeon_init_vert_RGBA(); - radeon_init_vert_RGBA_TEX0(); - radeon_init_vert_RGBA_TEX0_TEX1(); -} + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint ind = RADEON_CP_VC_FRMT_Z; + if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag) + return GL_FALSE; + if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) + ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); + + /* Make all this event-driven: + */ + if (ctx->Light.Enabled) { + ind |= RADEON_CP_VC_FRMT_N0; + + /* TODO: make this data driven: If we receive only ubytes, send + * color as ubytes. Also check if converting (with free + * checking for overflow) is cheaper than sending floats + * directly. + */ + if (ctx->Light.ColorMaterialEnabled) { + ind |= RADEON_CP_VC_FRMT_FPCOLOR; + if (ctx->Color.AlphaEnabled) { + ind |= RADEON_CP_VC_FRMT_FPALPHA; + } + } + } + else { + /* TODO: make this data driven? + */ + ind |= RADEON_CP_VC_FRMT_PKCOLOR; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { + ind |= RADEON_CP_VC_FRMT_PKSPEC; + } + } + if (ctx->Texture.Unit[0]._ReallyEnabled) { + if (ctx->Texture.Unit[0].TexGenEnabled) { + if (rmesa->TexGenNeedNormals[0]) { + ind |= RADEON_CP_VC_FRMT_N0; + } + } else { + if (ctx->Current.Texcoord[0][2] != 0.0F || + ctx->Current.Texcoord[0][3] != 1.0) { + if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) + fprintf(stderr, "%s: rq0\n", __FUNCTION__); + return GL_FALSE; + } + ind |= RADEON_CP_VC_FRMT_ST0; + } + } + if (ctx->Texture.Unit[1]._ReallyEnabled) { + if (ctx->Texture.Unit[1].TexGenEnabled) { + if (rmesa->TexGenNeedNormals[1]) { + ind |= RADEON_CP_VC_FRMT_N0; + } + } else { + if (ctx->Current.Texcoord[1][2] != 0.0F || + ctx->Current.Texcoord[1][3] != 1.0) { + if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) + fprintf(stderr, "%s: rq1\n", __FUNCTION__); + return GL_FALSE; + } + ind |= RADEON_CP_VC_FRMT_ST1; + } + } + if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) + fprintf(stderr, "%s: format: 0x%x\n", __FUNCTION__, ind ); + RADEON_NEWPRIM(rmesa); + rmesa->vb.vertex_format = ind; + vb.vertex_size = 3; + rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; -#define LOCAL_VARS \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx) + vb.normalptr = ctx->Current.Normal; + vb.colorptr = NULL; + vb.floatcolorptr = ctx->Current.Color; + vb.specptr = NULL; + vb.floatspecptr = ctx->Current.SecondaryColor; + vb.texcoordptr[0] = ctx->Current.Texcoord[0]; + vb.texcoordptr[1] = ctx->Current.Texcoord[1]; -#define FLUSH_VERTEX rmesa->imm.flush_vertex + /* Run through and initialize the vertex components in the order + * the hardware understands: + */ + if (ind & RADEON_CP_VC_FRMT_N0) { + vb.normalptr = &vb.vertex[vb.vertex_size].f; + vb.vertex_size += 3; + vb.normalptr[0] = ctx->Current.Normal[0]; + vb.normalptr[1] = ctx->Current.Normal[1]; + vb.normalptr[2] = ctx->Current.Normal[2]; + } -#define IMM_VERTEX( V ) rmesa->imm.V -#define IMM_VERTICES( n ) rmesa->imm.vertices[n] + if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { + vb.colorptr = &vb.vertex[vb.vertex_size].color; + vb.vertex_size += 1; + UNCLAMPED_FLOAT_TO_CHAN( vb.colorptr->red, ctx->Current.Color[0] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.colorptr->green, ctx->Current.Color[1] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.colorptr->blue, ctx->Current.Color[2] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.colorptr->alpha, ctx->Current.Color[3] ); + } + if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { + assert(!(ind & RADEON_CP_VC_FRMT_PKCOLOR)); + vb.floatcolorptr = &vb.vertex[vb.vertex_size].f; + vb.vertex_size += 3; + vb.floatcolorptr[0] = ctx->Current.Color[0]; + vb.floatcolorptr[1] = ctx->Current.Color[1]; + vb.floatcolorptr[2] = ctx->Current.Color[2]; + + if (ind & RADEON_CP_VC_FRMT_FPALPHA) { + vb.vertex_size += 1; + vb.floatcolorptr[3] = ctx->Current.Color[3]; + } + } + + if (ind & RADEON_CP_VC_FRMT_PKSPEC) { + vb.specptr = &vb.vertex[vb.vertex_size].color; + vb.vertex_size += 1; + UNCLAMPED_FLOAT_TO_CHAN( vb.specptr->red, ctx->Current.SecondaryColor[0] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.specptr->green, ctx->Current.SecondaryColor[1] ); + UNCLAMPED_FLOAT_TO_CHAN( vb.specptr->blue, ctx->Current.SecondaryColor[2] ); + } -/* TINY_VERTEX_FORMAT: - */ -#define GET_VERTEX_SPACE( n ) radeonAllocDmaLow( rmesa, n * 16, __FUNCTION__ ) - -#define EMIT_VERTEX( vb, v ) \ -do { \ - vb[0] = *(GLuint *)&(v->clip[0]); \ - vb[1] = *(GLuint *)&(v->clip[1]); \ - vb[2] = *(GLuint *)&(v->clip[2]); \ - vb[3] = *(GLuint *)&(v->color); \ - vb += 4; \ -} while (0) -#define TAG(x) radeon_##x##_tiny -#define PRESERVE_PRIM_DEFS -#include "tnl_dd/t_dd_imm_primtmp.h" + if (ind & RADEON_CP_VC_FRMT_ST0) { + vb.texcoordptr[0] = &vb.vertex[vb.vertex_size].f; + vb.vertex_size += 2; + vb.texcoordptr[0][0] = ctx->Current.Texcoord[0][0]; + vb.texcoordptr[0][1] = ctx->Current.Texcoord[0][1]; + } + + if (ind & RADEON_CP_VC_FRMT_ST1) { + vb.texcoordptr[1] = &vb.vertex[vb.vertex_size].f; + vb.vertex_size += 2; + vb.texcoordptr[1][0] = ctx->Current.Texcoord[1][0]; + vb.texcoordptr[1][1] = ctx->Current.Texcoord[1][1]; + } + + if (rmesa->vb.installed_vertex_format != rmesa->vb.vertex_format) { + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "reinstall on vertex_format change\n"); + _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); + rmesa->vb.installed_vertex_format = rmesa->vb.vertex_format; + } + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s -- success\n", __FUNCTION__); + + return GL_TRUE; +} -/* NOTEX_VERTEX_FORMAT: - */ -#define GET_VERTEX_SPACE( n ) radeonAllocDmaLow( rmesa, n * 24, __FUNCTION__ ) - -#define EMIT_VERTEX( vb, v ) \ -do { \ - vb[0] = *(GLuint *)&(v->clip[0]); \ - vb[1] = *(GLuint *)&(v->clip[1]); \ - vb[2] = *(GLuint *)&(v->clip[2]); \ - vb[3] = *(GLuint *)&(v->clip[3]); \ - vb[4] = *(GLuint *)&(v->color); \ - vb[5] = *(GLuint *)&(v->specular); \ - vb += 6; \ -} while (0) -#define TAG(x) radeon_##x##_notex -#define PRESERVE_PRIM_DEFS -#include "tnl_dd/t_dd_imm_primtmp.h" +void radeonVtxfmtInvalidate( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + rmesa->vb.recheck = GL_TRUE; + rmesa->vb.fell_back = GL_FALSE; +} -/* TEX0_VERTEX_FORMAT: - */ -#define GET_VERTEX_SPACE( n ) radeonAllocDmaLow( rmesa, n * 32, __FUNCTION__ ) - -#define EMIT_VERTEX( vb, v ) \ -do { \ - vb[0] = *(GLuint *)&(v->clip[0]); \ - vb[1] = *(GLuint *)&(v->clip[1]); \ - vb[2] = *(GLuint *)&(v->clip[2]); \ - vb[3] = *(GLuint *)&(v->clip[3]); \ - vb[4] = *(GLuint *)&(v->color); \ - vb[5] = *(GLuint *)&(v->specular); \ - vb[6] = *(GLuint *)&(v->texture[0][0]); \ - vb[7] = *(GLuint *)&(v->texture[0][1]); \ - vb += 8; \ -} while (0) -#define TAG(x) radeon_##x##_tex0 -#define PRESERVE_PRIM_DEFS -#include "tnl_dd/t_dd_imm_primtmp.h" +static void radeonNewList( GLcontext *ctx, GLuint list, GLenum mode ) +{ + VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); +} -/* TEX1_VERTEX_FORMAT: - */ -#define GET_VERTEX_SPACE( n ) radeonAllocDmaLow( rmesa, n * 40, __FUNCTION__ ) - -#define EMIT_VERTEX( vb, v ) \ -do { \ - vb[0] = *(GLuint *)&(v->clip[0]); \ - vb[1] = *(GLuint *)&(v->clip[1]); \ - vb[2] = *(GLuint *)&(v->clip[2]); \ - vb[3] = *(GLuint *)&(v->clip[3]); \ - vb[4] = *(GLuint *)&(v->color); \ - vb[5] = *(GLuint *)&(v->specular); \ - vb[6] = *(GLuint *)&(v->texture[0][0]); \ - vb[7] = *(GLuint *)&(v->texture[0][1]); \ - vb[8] = *(GLuint *)&(v->texture[1][0]); \ - vb[9] = *(GLuint *)&(v->texture[1][1]); \ - vb += 10; \ -} while (0) +static void radeonVtxfmtValidate( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); -#define TAG(x) radeon_##x##_tex1 -#define PRESERVE_PRIM_DEFS -#include "tnl_dd/t_dd_imm_primtmp.h" + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); + if (ctx->Driver.NeedFlush) + ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); + rmesa->vb.recheck = GL_FALSE; + if (check_vtx_fmt( ctx )) { + if (!rmesa->vb.installed) { + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "reinstall (new install)\n"); + _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); + ctx->Driver.FlushVertices = radeonFlushVertices; + ctx->Driver.NewList = radeonNewList; + rmesa->vb.installed = GL_TRUE; + vb.context = ctx; + } + else if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s: already installed", __FUNCTION__); + } + else { + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s: failed\n", __FUNCTION__); + + if (rmesa->vb.installed) { + if (rmesa->dma.flush) + rmesa->dma.flush( rmesa ); + _tnl_wakeup_exec( ctx ); + rmesa->vb.installed = GL_FALSE; + vb.context = 0; + } + } +} -/* Bzzt: Material changes are lost on fallback. +/* Materials: */ -static void radeon_Materialfv( GLenum face, GLenum pname, +static void radeon_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) { - GET_CURRENT_CONTEXT(ctx); + GLcontext *ctx = vb.context; + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); + if (rmesa->vb.prim[0] != GL_POLYGON+1) { + VFMT_FALLBACK( __FUNCTION__ ); + glMaterialfv( face, pname, params ); + return; + } _mesa_noop_Materialfv( face, pname, params ); - radeon_recalc_base_color( ctx ); + radeonUpdateMaterial( vb.context ); } - - - -/* ================================================================ - * Fallback functions: +/* Begin/End */ - -static void radeon_do_fallback( GLcontext *ctx ) +static void radeon_Begin( GLenum mode ) { + GLcontext *ctx = vb.context; radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct radeon_current_state *current = &rmesa->state.current; + + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); - /* Tell tnl to restore its exec vtxfmt, rehook its driver callbacks - * and revive internal state that depended on those callbacks: - */ - _tnl_wakeup_exec( ctx ); + if (mode > GL_POLYGON) { + _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); + return; + } - /* Replay enough vertices that the current primitive is continued - * correctly: - */ - if ( rmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END ) { - glBegin( rmesa->imm.prim ); - /*rmesa->fire_on_fallback( ctx );*/ + if (rmesa->vb.prim[0] != GL_POLYGON+1) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); + return; } + + if (ctx->NewState) + _mesa_update_state( ctx ); - /* Replay the current, partially complete vertex: - */ - if ( current->texture[0][3] == 1.0 ) { - glMultiTexCoord3fvARB( GL_TEXTURE0_ARB, current->texture[0] ); - } else { - glMultiTexCoord4fvARB( GL_TEXTURE0_ARB, current->texture[0] ); + if (rmesa->NewGLState) + radeonValidateState( ctx ); + + if (rmesa->vb.recheck) + radeonVtxfmtValidate( ctx ); + + if (!rmesa->vb.installed) { + glBegin( mode ); + return; } - if ( current->texture[1][3] == 1.0 ) { - glMultiTexCoord3fvARB( GL_TEXTURE1_ARB, current->texture[1] ); - } else { - glMultiTexCoord4fvARB( GL_TEXTURE1_ARB, current->texture[1] ); + + if (rmesa->dma.flush && vb.counter < 12) { + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__); + flush_prims( rmesa ); } - /* FIXME: Secondary color, fog coord... + /* Need to arrange to save vertices here? Or always copy from dma (yuk)? */ + if (!rmesa->dma.flush) { + if (rmesa->dma.current.ptr + 12*vb.vertex_size*4 > + rmesa->dma.current.end) { + RADEON_NEWPRIM( rmesa ); + radeonRefillCurrentDmaRegion( rmesa ); + } - if ( ctx->Light.Enabled ) { - glColor4fv( ctx->Current.Color ); /* Catch ColorMaterial */ - glNormal3fv( current->normal ); - } else { - glColor4ubv( current->color ); + vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr); + vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / + (vb.vertex_size * 4); + vb.counter--; + vb.initial_counter = vb.counter; + vb.notify = wrap_buffer; + rmesa->dma.flush = flush_prims; + vb.context->Driver.NeedFlush |= FLUSH_STORED_VERTICES; } + + + rmesa->vb.prim[0] = mode; + start_prim( rmesa, mode | PRIM_BEGIN ); } -#define PRE_LOOPBACK( FUNC ) do { \ - GET_CURRENT_CONTEXT(ctx); \ - radeon_do_fallback( ctx ); \ -} while (0) -#define TAG(x) radeon_fallback_##x -#include "vtxfmt_tmp.h" +static void radeon_End( void ) +{ + GLcontext *ctx = vb.context; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->vb.prim[0] == GL_POLYGON+1) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); + return; + } + + note_last_prim( rmesa, PRIM_END ); + rmesa->vb.prim[0] = GL_POLYGON+1; +} +/* Fallback on difficult entrypoints: + */ +#define PRE_LOOPBACK( FUNC ) \ +do { \ + if (RADEON_DEBUG & DEBUG_VFMT) \ + fprintf(stderr, "%s\n", __FUNCTION__); \ + VFMT_FALLBACK( __FUNCTION__ ); \ +} while (0) +#define TAG(x) radeon_fallback_##x +#include "vtxfmt_tmp.h" -static void radeon_Begin( GLenum prim ) +static GLboolean radeonNotifyBegin( GLcontext *ctx, GLenum p ) { - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); - if ( prim > GL_POLYGON ) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - if ( rmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END ) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } + assert(!rmesa->vb.installed); - ctx->Driver.NeedFlush |= (FLUSH_STORED_VERTICES | - FLUSH_UPDATE_CURRENT); + if (ctx->NewState) + _mesa_update_state( ctx ); + if (rmesa->NewGLState) + radeonValidateState( ctx ); - radeonChooseVertexState( ctx ); + if (ctx->Driver.NeedFlush) + ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); + if (rmesa->vb.recheck) + radeonVtxfmtValidate( ctx ); - rmesa->imm.prim = prim; - rmesa->imm.v0 = &rmesa->imm.vertices[0]; + if (!rmesa->vb.installed) { + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s -- failed\n", __FUNCTION__); + return GL_FALSE; + } - rmesa->imm.save_vertex = radeon_save_vertex_RGBA; - rmesa->imm.flush_vertex = rmesa->imm.flush_tab[prim]; + radeon_Begin( p ); + return GL_TRUE; } -static void radeon_End( void ) +static void radeonFlushVertices( GLcontext *ctx, GLuint flags ) { - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - if ( rmesa->imm.prim == PRIM_OUTSIDE_BEGIN_END ) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - return; - } + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "%s\n", __FUNCTION__); - rmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END; + assert(rmesa->vb.installed); + assert(vb.context == ctx); - ctx->Driver.NeedFlush &= ~(FLUSH_STORED_VERTICES | - FLUSH_UPDATE_CURRENT); -} + if (flags & FLUSH_UPDATE_CURRENT) { + radeon_copy_to_current( ctx ); + if (RADEON_DEBUG & DEBUG_VFMT) + fprintf(stderr, "reinstall on update_current\n"); + _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); + ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; + } + if (flags & FLUSH_STORED_VERTICES) { + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + assert (rmesa->dma.flush == 0 || + rmesa->dma.flush == flush_prims); + if (rmesa->dma.flush == flush_prims) + flush_prims( RADEON_CONTEXT( ctx ) ); + ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; + } +} +/* At this point, don't expect very many versions of each function to + * be generated, so not concerned about freeing them? + */ -void radeonInitTnlModule( GLcontext *ctx ) +void radeonVtxfmtInit( GLcontext *ctx ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLvertexformat *vfmt = &(rmesa->imm.vtxfmt); - - return; - - radeon_init_norm_funcs(); - radeon_init_vert_funcs(); + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + GLvertexformat *vfmt = &(rmesa->vb.vtxfmt); MEMSET( vfmt, 0, sizeof(GLvertexformat) ); - /* Handled fully in supported states: + /* Hook in chooser functions for codegen, etc: */ - vfmt->ArrayElement = NULL; /* FIXME: ... */ - vfmt->Color3f = radeon_choose_Color3f; - vfmt->Color3fv = radeon_choose_Color3fv; - vfmt->Color3ub = radeon_choose_Color3ub; - vfmt->Color3ubv = radeon_choose_Color3ubv; - vfmt->Color4f = radeon_choose_Color4f; - vfmt->Color4fv = radeon_choose_Color4fv; - vfmt->Color4ub = radeon_choose_Color4ub; - vfmt->Color4ubv = radeon_choose_Color4ubv; - vfmt->FogCoordfvEXT = radeon_FogCoordfvEXT; - vfmt->FogCoordfEXT = radeon_FogCoordfEXT; - vfmt->Materialfv = radeon_Materialfv; - vfmt->MultiTexCoord1fARB = radeon_MultiTexCoord1fARB; - vfmt->MultiTexCoord1fvARB = radeon_MultiTexCoord1fvARB; - vfmt->MultiTexCoord2fARB = radeon_MultiTexCoord2fARB; - vfmt->MultiTexCoord2fvARB = radeon_MultiTexCoord2fvARB; - vfmt->MultiTexCoord3fARB = radeon_MultiTexCoord3fARB; - vfmt->MultiTexCoord3fvARB = radeon_MultiTexCoord3fvARB; - vfmt->MultiTexCoord4fARB = radeon_MultiTexCoord4fARB; - vfmt->MultiTexCoord4fvARB = radeon_MultiTexCoord4fvARB; - vfmt->Normal3f = radeon_choose_Normal3f; - vfmt->Normal3fv = radeon_choose_Normal3fv; - vfmt->SecondaryColor3ubEXT = radeon_SecondaryColor3ubEXT; - vfmt->SecondaryColor3ubvEXT = radeon_SecondaryColor3ubvEXT; - vfmt->SecondaryColor3fEXT = radeon_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = radeon_SecondaryColor3fvEXT; - vfmt->TexCoord1f = radeon_TexCoord1f; - vfmt->TexCoord1fv = radeon_TexCoord1fv; - vfmt->TexCoord2f = radeon_TexCoord2f; - vfmt->TexCoord2fv = radeon_TexCoord2fv; - vfmt->TexCoord3f = radeon_TexCoord3f; - vfmt->TexCoord3fv = radeon_TexCoord3fv; - vfmt->TexCoord4f = radeon_TexCoord4f; - vfmt->TexCoord4fv = radeon_TexCoord4fv; - vfmt->Vertex2f = radeon_Vertex2f; - vfmt->Vertex2fv = radeon_Vertex2fv; - vfmt->Vertex3f = radeon_Vertex3f; - vfmt->Vertex3fv = radeon_Vertex3fv; - vfmt->Vertex4f = radeon_Vertex4f; - vfmt->Vertex4fv = radeon_Vertex4fv; + radeonVtxfmtInitChoosers( vfmt ); + /* Handled fully in supported states, but no codegen: + */ + vfmt->Materialfv = radeon_Materialfv; + vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ + vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */ vfmt->Begin = radeon_Begin; vfmt->End = radeon_End; - vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */ - - vfmt->DrawArrays = NULL; - vfmt->DrawElements = NULL; - vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements; /* discard range */ + /* Fallback for performance reasons: (Fix with cva/elt path here and + * dmatmp2.h style primitive-merging) + * + * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow + * a driver-hook. + */ + vfmt->DrawArrays = radeon_fallback_DrawArrays; + vfmt->DrawElements = radeon_fallback_DrawElements; + vfmt->DrawRangeElements = radeon_fallback_DrawRangeElements; /* Not active in supported states; just keep ctx->Current uptodate: */ + vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT; + vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT; vfmt->EdgeFlag = _mesa_noop_EdgeFlag; vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv; vfmt->Indexi = _mesa_noop_Indexi; @@ -609,10 +981,6 @@ void radeonInitTnlModule( GLcontext *ctx ) /* Active but unsupported -- fallback if we receive these: - * - * All of these fallbacks can be fixed with additional code, except - * CallList, unless we build a play_immediate_noop() command which - * turns an immediate back into glBegin/glEnd commands... */ vfmt->CallList = radeon_fallback_CallList; vfmt->EvalCoord1f = radeon_fallback_EvalCoord1f; @@ -623,132 +991,137 @@ void radeonInitTnlModule( GLcontext *ctx ) vfmt->EvalMesh2 = radeon_fallback_EvalMesh2; vfmt->EvalPoint1 = radeon_fallback_EvalPoint1; vfmt->EvalPoint2 = radeon_fallback_EvalPoint2; - - - rmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END; - - /* THIS IS A HACK! - */ - _mesa_install_exec_vtxfmt( ctx, vfmt ); + vfmt->TexCoord3f = radeon_fallback_TexCoord3f; + vfmt->TexCoord3fv = radeon_fallback_TexCoord3fv; + vfmt->TexCoord4f = radeon_fallback_TexCoord4f; + vfmt->TexCoord4fv = radeon_fallback_TexCoord4fv; + vfmt->MultiTexCoord3fARB = radeon_fallback_MultiTexCoord3fARB; + vfmt->MultiTexCoord3fvARB = radeon_fallback_MultiTexCoord3fvARB; + vfmt->MultiTexCoord4fARB = radeon_fallback_MultiTexCoord4fARB; + vfmt->MultiTexCoord4fvARB = radeon_fallback_MultiTexCoord4fvARB; + vfmt->Vertex4f = radeon_fallback_Vertex4f; + vfmt->Vertex4fv = radeon_fallback_Vertex4fv; + + (void)radeon_fallback_vtxfmt; + + TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin; + + vb.context = ctx; + rmesa->vb.enabled = 1; + rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; + rmesa->vb.primflags = 0; + + make_empty_list( &rmesa->vb.dfn_cache.Vertex2f ); + make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv ); + make_empty_list( &rmesa->vb.dfn_cache.Vertex3f ); + make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv ); + make_empty_list( &rmesa->vb.dfn_cache.Color4ub ); + make_empty_list( &rmesa->vb.dfn_cache.Color4ubv ); + make_empty_list( &rmesa->vb.dfn_cache.Color3ub ); + make_empty_list( &rmesa->vb.dfn_cache.Color3ubv ); + make_empty_list( &rmesa->vb.dfn_cache.Color4f ); + make_empty_list( &rmesa->vb.dfn_cache.Color4fv ); + make_empty_list( &rmesa->vb.dfn_cache.Color3f ); + make_empty_list( &rmesa->vb.dfn_cache.Color3fv ); + make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); + make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); + make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); + make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); + make_empty_list( &rmesa->vb.dfn_cache.Normal3f ); + make_empty_list( &rmesa->vb.dfn_cache.Normal3fv ); + make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f ); + make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv ); + make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f ); + make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv ); + make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); + make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); + + radeonInitCodegen( &rmesa->vb.codegen ); } - - - - - -#if 0 - - - -static void radeon_Begin( GLenum prim ) +static void free_funcs( struct dynfn *l ) { - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_prim *tab = &radeon_prim_tab[(int)prim]; - - if ( prim > GL_POLYGON ) { - gl_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if ( rmesa->prim != PRIM_OUTSIDE_BEGIN_END ) { - gl_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - if ( tab->fire_on_vertex ) { - rmesa->fire_on_vertex = tab->fire_on_vertex; - rmesa->fire_on_end = tab->fire_on_end; - rmesa->fire_on_fallback = tab->fire_on_fallback; - rmesa->vert = &(rmesa->cache[0]); - rmesa->prim = prim; - ctx->Driver.NeedFlush |= (FLUSH_INSIDE_BEGIN_END | - FLUSH_STORED_VERTICES); - } else { - radeon_fallback_vtxfmt( ctx ); + struct dynfn *f, *tmp; + foreach_s (f, tmp, l) { + remove_from_list( f ); + ALIGN_FREE( f->code ); + FREE( f ); } } -static void radeon_End( void ) +void radeonVtxfmtUnbindContext( GLcontext *ctx ) { - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if ( rmesa->prim == PRIM_OUTSIDE_BEGIN_END ) { - gl_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - return; + if (RADEON_CONTEXT(ctx)->vb.installed) { + assert(vb.context == ctx); + VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); } - rmesa->fire_on_end( ctx ); - rmesa->prim = PRIM_OUTSIDE_BEGIN_END; - - ctx->Exec->Vertex3fv = radeon_noop_Vertex3fv; - ctx->Exec->Vertex3f = radeon_noop_Vertex3f; - ctx->Exec->Vertex2f = radeon_noop_Vertex2f; - - ctx->Driver.NeedFlush &= ~(FLUSH_INSIDE_BEGIN_END | - FLUSH_STORED_VERTICES); + TNL_CONTEXT(ctx)->Driver.NotifyBegin = 0; } - - -static GLboolean radeon_flush_vtxfmt( GLcontext *ctx, GLuint flags ) +void radeonVtxfmtMakeCurrent( GLcontext *ctx ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if ( fxMesa->prim != PRIM_OUTSIDE_BEGIN_END ) - return GL_FALSE; - - /* Outside begin/end. All vertices will already be flushed, just - * update ctx->Current. - */ - if ( flags & FLUSH_UPDATE_CURRENT ) { - radeonClipVertexPtr v = &(RADEON_CONTEXT(ctx)->Current); - COPY_2FV( ctx->Current.Texcoord[0], v->texcoord[0] ); - COPY_2FV( ctx->Current.Texcoord[1], v->texcoord[1] ); - if ( rmesa->accel_light == ACCEL_LIGHT ) { - COPY_3FV( ctx->Current.Normal, v->normal ); - } else { - ctx->Current.Color[RCOMP] = UBYTE_TO_CHAN( v->v.color.red ); - ctx->Current.Color[GCOMP] = UBYTE_TO_CHAN( v->v.color.green ); - ctx->Current.Color[BCOMP] = UBYTE_TO_CHAN( v->v.color.blue ); - ctx->Current.Color[ACOMP] = UBYTE_TO_CHAN( v->v.color.alpha ); + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + +#if defined(THREADS) + static GLboolean ThreadSafe = GL_FALSE; /* In thread-safe mode? */ + if (!ThreadSafe) { + static unsigned long knownID; + static GLboolean firstCall = GL_TRUE; + if (firstCall) { + knownID = _glthread_GetID(); + firstCall = GL_FALSE; + } + else if (knownID != _glthread_GetID()) { + ThreadSafe = GL_TRUE; - if ( ctx->Light.ColorMaterialEnabled ) - _mesa_update_color_material( ctx, ctx->Current.Color ); + if (RADEON_DEBUG & (DEBUG_DRI|DEBUG_VFMT)) + fprintf(stderr, "**** Multithread situation!\n"); } } + if (ThreadSafe) + return; +#endif - /* Could clear this flag and set it from each 'choose' function, - * maybe, but there isn't much of a penalty for leaving it set: - */ - ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT; - return GL_TRUE; + if (rmesa->vb.enabled) { + TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin; + } } -void radeon_update_lighting( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if ( !ctx->Light.Enabled ) { - rmesa->accel_light = ACCEL_NO_LIGHT; - } - else if ( !ctx->Light._NeedVertices && !ctx->Light.Model.TwoSide ) { - rmesa->accel_light = ACCEL_LIGHT; - radeon_recalc_basecolor( ctx ); - } - else { - radeon->accel_light = 0; - } +void radeonVtxfmtDestroy( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + + count_funcs( rmesa ); + free_funcs( &rmesa->vb.dfn_cache.Vertex2f ); + free_funcs( &rmesa->vb.dfn_cache.Vertex2fv ); + free_funcs( &rmesa->vb.dfn_cache.Vertex3f ); + free_funcs( &rmesa->vb.dfn_cache.Vertex3fv ); + free_funcs( &rmesa->vb.dfn_cache.Color4ub ); + free_funcs( &rmesa->vb.dfn_cache.Color4ubv ); + free_funcs( &rmesa->vb.dfn_cache.Color3ub ); + free_funcs( &rmesa->vb.dfn_cache.Color3ubv ); + free_funcs( &rmesa->vb.dfn_cache.Color4f ); + free_funcs( &rmesa->vb.dfn_cache.Color4fv ); + free_funcs( &rmesa->vb.dfn_cache.Color3f ); + free_funcs( &rmesa->vb.dfn_cache.Color3fv ); + free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); + free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); + free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); + free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); + free_funcs( &rmesa->vb.dfn_cache.Normal3f ); + free_funcs( &rmesa->vb.dfn_cache.Normal3fv ); + free_funcs( &rmesa->vb.dfn_cache.TexCoord2f ); + free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv ); + free_funcs( &rmesa->vb.dfn_cache.TexCoord1f ); + free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv ); + free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); + free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); } - -/* How to fallback: - * - install default vertex format - * - call glBegin - * - revive stalled vertices (may be reordered). - * - re-issue call that caused fallback. - */ -#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h index b388d7364..9b82756be 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h @@ -1,30 +1,36 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h,v 1.1 2002/02/22 21:45:01 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h,v 1.3 2002/12/21 17:02:16 dawes Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + /* - * Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * * Authors: - * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> + * */ #ifndef __RADEON_VTXFMT_H__ @@ -34,13 +40,89 @@ #include "radeon_context.h" -extern void radeonInitTnlModule( GLcontext *ctx ); -extern radeon_flush_func radeon_flush_tab_tiny[GL_POLYGON+1]; -extern radeon_flush_func radeon_flush_tab_notex[GL_POLYGON+1]; -extern radeon_flush_func radeon_flush_tab_tex0[GL_POLYGON+1]; -extern radeon_flush_func radeon_flush_tab_tex1[GL_POLYGON+1]; +extern struct radeon_vb vb; + + +extern void radeonVtxfmtUpdate( GLcontext *ctx ); +extern void radeonVtxfmtInit( GLcontext *ctx ); +extern void radeonVtxfmtInvalidate( GLcontext *ctx ); +extern void radeonVtxfmtDestroy( GLcontext *ctx ); +extern void radeonVtxfmtInitChoosers( GLvertexformat *vfmt ); + +extern void radeonVtxfmtMakeCurrent( GLcontext *ctx ); +extern void radeonVtxfmtUnbindContext( GLcontext *ctx ); + +extern void radeon_copy_to_current( GLcontext *ctx ); + +#define DFN( FUNC, CACHE) \ +do { \ + char *start = (char *)&FUNC; \ + char *end = (char *)&FUNC##_end; \ + insert_at_head( &CACHE, dfn ); \ + dfn->key = key; \ + dfn->code = ALIGN_MALLOC( end - start, 16 ); \ + memcpy (dfn->code, start, end - start); \ +} \ +while ( 0 ) + +#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \ +do { \ + int *icode = (int *)(CODE+OFFSET); \ + assert (*icode == CHECKVAL); \ + *icode = (int)NEWVAL; \ +} while (0) + + +/* Useful for figuring out the offsets: + */ +#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ +do { \ + while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ + /* fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__, */ \ +/* __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL)); */ \ + *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ + OFFSET += 4; \ +} while (0) + +/* + */ +void radeonInitCodegen( struct dfn_generators *gen ); +void radeonInitX86Codegen( struct dfn_generators *gen ); +void radeonInitSSECodegen( struct dfn_generators *gen ); + + + +/* Defined in radeon_vtxfmt_x86.c + */ +struct dynfn *radeon_makeX86Vertex2f( GLcontext *, int ); +struct dynfn *radeon_makeX86Vertex2fv( GLcontext *, int ); +struct dynfn *radeon_makeX86Vertex3f( GLcontext *, int ); +struct dynfn *radeon_makeX86Vertex3fv( GLcontext *, int ); +struct dynfn *radeon_makeX86Color4ub( GLcontext *, int ); +struct dynfn *radeon_makeX86Color4ubv( GLcontext *, int ); +struct dynfn *radeon_makeX86Color3ub( GLcontext *, int ); +struct dynfn *radeon_makeX86Color3ubv( GLcontext *, int ); +struct dynfn *radeon_makeX86Color4f( GLcontext *, int ); +struct dynfn *radeon_makeX86Color4fv( GLcontext *, int ); +struct dynfn *radeon_makeX86Color3f( GLcontext *, int ); +struct dynfn *radeon_makeX86Color3fv( GLcontext *, int ); +struct dynfn *radeon_makeX86SecondaryColor3ubEXT( GLcontext *, int ); +struct dynfn *radeon_makeX86SecondaryColor3ubvEXT( GLcontext *, int ); +struct dynfn *radeon_makeX86SecondaryColor3fEXT( GLcontext *, int ); +struct dynfn *radeon_makeX86SecondaryColor3fvEXT( GLcontext *, int ); +struct dynfn *radeon_makeX86Normal3f( GLcontext *, int ); +struct dynfn *radeon_makeX86Normal3fv( GLcontext *, int ); +struct dynfn *radeon_makeX86TexCoord2f( GLcontext *, int ); +struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *, int ); +struct dynfn *radeon_makeX86TexCoord1f( GLcontext *, int ); +struct dynfn *radeon_makeX86TexCoord1fv( GLcontext *, int ); +struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *, int ); +struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *, int ); +struct dynfn *radeon_makeX86MultiTexCoord1fARB( GLcontext *, int ); +struct dynfn *radeon_makeX86MultiTexCoord1fvARB( GLcontext *, int ); + #endif #endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c new file mode 100644 index 000000000..fadfc3077 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c @@ -0,0 +1,801 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c,v 1.2 2002/12/16 16:18:59 dawes Exp $ */ +/************************************************************************** + +Copyright 2002 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ +#include "mtypes.h" +#include "colormac.h" +#include "simple_list.h" +#include "api_noop.h" +#include "vtxfmt.h" + +#include "radeon_vtxfmt.h" + +/* Fallback versions of all the entrypoints for situations where + * codegen isn't available. This is still a lot faster than the + * vb/pipeline implementation in Mesa. + */ +static void radeon_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) +{ + int i; + + *vb.dmaptr++ = *(int *)&x; + *vb.dmaptr++ = *(int *)&y; + *vb.dmaptr++ = *(int *)&z; + + for (i = 3; i < vb.vertex_size; i++) + *vb.dmaptr++ = vb.vertex[i].i; + + if (--vb.counter == 0) + vb.notify(); +} + + +static void radeon_Vertex3fv( const GLfloat *v ) +{ + int i; + + *vb.dmaptr++ = *(int *)&v[0]; + *vb.dmaptr++ = *(int *)&v[1]; + *vb.dmaptr++ = *(int *)&v[2]; + + for (i = 3; i < vb.vertex_size; i++) + *vb.dmaptr++ = vb.vertex[i].i; + + if (--vb.counter == 0) + vb.notify(); +} + + +static void radeon_Vertex2f( GLfloat x, GLfloat y ) +{ + int i; + + *vb.dmaptr++ = *(int *)&x; + *vb.dmaptr++ = *(int *)&y; + *vb.dmaptr++ = 0; + + for (i = 3; i < vb.vertex_size; i++) + *vb.dmaptr++ = *(int *)&vb.vertex[i]; + + if (--vb.counter == 0) + vb.notify(); +} + + +static void radeon_Vertex2fv( const GLfloat *v ) +{ + int i; + + *vb.dmaptr++ = *(int *)&v[0]; + *vb.dmaptr++ = *(int *)&v[1]; + *vb.dmaptr++ = 0; + + for (i = 3; i < vb.vertex_size; i++) + *vb.dmaptr++ = vb.vertex[i].i; + + if (--vb.counter == 0) + vb.notify(); +} + + + +/* Color for ubyte (packed) color formats: + */ +static void radeon_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b ) +{ + radeon_color_t *dest = vb.colorptr; + dest->red = r; + dest->green = g; + dest->blue = b; + dest->alpha = 0xff; +} + +static void radeon_Color3ubv_ub( const GLubyte *v ) +{ + radeon_color_t *dest = vb.colorptr; + dest->red = v[0]; + dest->green = v[1]; + dest->blue = v[2]; + dest->alpha = 0xff; +} + +static void radeon_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + radeon_color_t *dest = vb.colorptr; + dest->red = r; + dest->green = g; + dest->blue = b; + dest->alpha = a; +} + +static void radeon_Color4ubv_ub( const GLubyte *v ) +{ + *(GLuint *)vb.colorptr = LE32_TO_CPU(*(GLuint *)v); +} + + +static void radeon_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) +{ + radeon_color_t *dest = vb.colorptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); + dest->alpha = 255; +} + +static void radeon_Color3fv_ub( const GLfloat *v ) +{ + radeon_color_t *dest = vb.colorptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); + dest->alpha = 255; +} + +static void radeon_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) +{ + radeon_color_t *dest = vb.colorptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); +} + +static void radeon_Color4fv_ub( const GLfloat *v ) +{ + radeon_color_t *dest = vb.colorptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); +} + + +/* Color for float color+alpha formats: + */ +static void radeon_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); + dest[3] = 1.0; +} + +static void radeon_Color3ubv_4f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); + dest[3] = 1.0; +} + +static void radeon_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); + dest[3] = UBYTE_TO_FLOAT(a); +} + +static void radeon_Color4ubv_4f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); + dest[3] = UBYTE_TO_FLOAT(v[3]); +} + + +static void radeon_Color3f_4f( GLfloat r, GLfloat g, GLfloat b ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; + dest[3] = 1.0; +} + +static void radeon_Color3fv_4f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; + dest[3] = 1.0; +} + +static void radeon_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; + dest[3] = a; +} + +static void radeon_Color4fv_4f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; + dest[3] = v[3]; +} + + +/* Color for float color formats: + */ +static void radeon_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); +} + +static void radeon_Color3ubv_3f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); +} + +static void radeon_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); + vb.context->Current.Color[3] = UBYTE_TO_FLOAT(a); +} + +static void radeon_Color4ubv_3f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); + vb.context->Current.Color[3] = UBYTE_TO_FLOAT(v[3]); +} + + +static void radeon_Color3f_3f( GLfloat r, GLfloat g, GLfloat b ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; +} + +static void radeon_Color3fv_3f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; +} + +static void radeon_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; + vb.context->Current.Color[3] = a; +} + +static void radeon_Color4fv_3f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatcolorptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; + vb.context->Current.Color[3] = v[3]; +} + + +/* Secondary Color: + */ +static void radeon_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b ) +{ + radeon_color_t *dest = vb.specptr; + dest->red = r; + dest->green = g; + dest->blue = b; + dest->alpha = 0xff; +} + +static void radeon_SecondaryColor3ubvEXT_ub( const GLubyte *v ) +{ + radeon_color_t *dest = vb.specptr; + dest->red = v[0]; + dest->green = v[1]; + dest->blue = v[2]; + dest->alpha = 0xff; +} + +static void radeon_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) +{ + radeon_color_t *dest = vb.specptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); + dest->alpha = 255; +} + +static void radeon_SecondaryColor3fvEXT_ub( const GLfloat *v ) +{ + radeon_color_t *dest = vb.specptr; + UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); + dest->alpha = 255; +} + +static void radeon_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b ) +{ + GLfloat *dest = vb.floatspecptr; + dest[0] = UBYTE_TO_FLOAT(r); + dest[1] = UBYTE_TO_FLOAT(g); + dest[2] = UBYTE_TO_FLOAT(b); + dest[3] = 1.0; +} + +static void radeon_SecondaryColor3ubvEXT_3f( const GLubyte *v ) +{ + GLfloat *dest = vb.floatspecptr; + dest[0] = UBYTE_TO_FLOAT(v[0]); + dest[1] = UBYTE_TO_FLOAT(v[1]); + dest[2] = UBYTE_TO_FLOAT(v[2]); + dest[3] = 1.0; +} + +static void radeon_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b ) +{ + GLfloat *dest = vb.floatspecptr; + dest[0] = r; + dest[1] = g; + dest[2] = b; + dest[3] = 1.0; +} + +static void radeon_SecondaryColor3fvEXT_3f( const GLfloat *v ) +{ + GLfloat *dest = vb.floatspecptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; + dest[3] = 1.0; +} + + +/* Normal + */ +static void radeon_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 ) +{ + GLfloat *dest = vb.normalptr; + dest[0] = n0; + dest[1] = n1; + dest[2] = n2; +} + +static void radeon_Normal3fv( const GLfloat *v ) +{ + GLfloat *dest = vb.normalptr; + dest[0] = v[0]; + dest[1] = v[1]; + dest[2] = v[2]; +} + + +/* TexCoord + */ +static void radeon_TexCoord1f( GLfloat s ) +{ + GLfloat *dest = vb.texcoordptr[0]; + dest[0] = s; + dest[1] = 0; +} + +static void radeon_TexCoord1fv( const GLfloat *v ) +{ + GLfloat *dest = vb.texcoordptr[0]; + dest[0] = v[0]; + dest[1] = 0; +} + +static void radeon_TexCoord2f( GLfloat s, GLfloat t ) +{ + GLfloat *dest = vb.texcoordptr[0]; + dest[0] = s; + dest[1] = t; +} + +static void radeon_TexCoord2fv( const GLfloat *v ) +{ + GLfloat *dest = vb.texcoordptr[0]; + dest[0] = v[0]; + dest[1] = v[1]; +} + + +/* MultiTexcoord + */ +static void radeon_MultiTexCoord1fARB( GLenum target, GLfloat s ) +{ + GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + dest[0] = s; + dest[1] = 0; +} + +static void radeon_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) +{ + GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + dest[0] = v[0]; + dest[1] = 0; +} + +static void radeon_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) +{ + GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + dest[0] = s; + dest[1] = t; +} + +static void radeon_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) +{ + GLfloat *dest = vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + dest[0] = v[0]; + dest[1] = v[1]; +} + +static struct dynfn *lookup( struct dynfn *l, int key ) +{ + struct dynfn *f; + + foreach( f, l ) { + if (f->key == key) + return f; + } + + return 0; +} + +/* Can't use the loopback template for this: + */ + +#define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \ +static void choose_##FN ARGS1 \ +{ \ + radeonContextPtr rmesa = RADEON_CONTEXT(vb.context); \ + int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ + struct dynfn *dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ + \ + if (dfn == 0) \ + dfn = rmesa->vb.codegen.FN( vb.context, key ); \ + else if (RADEON_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \ + \ + if (dfn) \ + vb.context->Exec->FN = (FNTYPE)(dfn->code); \ + else { \ + if (RADEON_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ + vb.context->Exec->FN = radeon_##FN; \ + } \ + \ + vb.context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ + vb.context->Exec->FN ARGS2; \ +} + + + +/* For the _3f case, only allow one color function to be hooked in at + * a time. Eventually, use a similar mechanism to allow selecting the + * color component of the vertex format based on client behaviour. + * + * Note: Perform these actions even if there is a codegen or cached + * codegen version of the chosen function. + */ +#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK, ACTIVE, ARGS1, ARGS2 ) \ +static void choose_##FN ARGS1 \ +{ \ + GLcontext *ctx = vb.context; \ + radeonContextPtr rmesa = RADEON_CONTEXT(vb.context); \ + int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ + struct dynfn *dfn; \ + \ + if (rmesa->vb.vertex_format & ACTIVE_PKCOLOR) { \ + ctx->Exec->FN = radeon_##FN##_ub; \ + } \ + else if ((rmesa->vb.vertex_format & \ + (ACTIVE_FPCOLOR|ACTIVE_FPALPHA)) == ACTIVE_FPCOLOR) { \ + \ + if (rmesa->vb.installed_color_3f_sz != NR) { \ + rmesa->vb.installed_color_3f_sz = NR; \ + if (NR == 3) ctx->Current.Color[3] = 1.0; \ + if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \ + radeon_copy_to_current( ctx ); \ + _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \ + ctx->Exec->FN ARGS2; \ + return; \ + } \ + } \ + \ + ctx->Exec->FN = radeon_##FN##_3f; \ + } \ + else { \ + ctx->Exec->FN = radeon_##FN##_4f; \ + } \ + \ + \ + dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ + if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \ + \ + if (dfn) { \ + if (RADEON_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \ + ctx->Exec->FN = (FNTYPE)dfn->code; \ + } \ + else if (RADEON_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \ + \ + ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ + ctx->Exec->FN ARGS2; \ +} + + + +/* Right now there are both _ub and _3f versions of the secondary color + * functions. Currently, we only set-up the hardware to use the _ub versions. + * The _3f versions are needed for the cases where secondary color isn't used + * in the vertex format, but it still needs to be stored in the context + * state vector. + */ +#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \ +static void choose_##FN ARGS1 \ +{ \ + GLcontext *ctx = vb.context; \ + radeonContextPtr rmesa = RADEON_CONTEXT(vb.context); \ + int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ + struct dynfn *dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ + \ + if (dfn == 0) \ + dfn = rmesa->vb.codegen.FN( vb.context, key ); \ + else if (RADEON_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \ + \ + if (dfn) \ + vb.context->Exec->FN = (FNTYPE)(dfn->code); \ + else { \ + if (RADEON_DEBUG & DEBUG_CODEGEN) \ + fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ + vb.context->Exec->FN = ((rmesa->vb.vertex_format & ACTIVE_PKSPEC) != 0) \ + ? radeon_##FN##_ub : radeon_##FN##_3f; \ + } \ + \ + ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ + ctx->Exec->FN ARGS2; \ +} + + + + + +/* Shorthands + */ +#define ACTIVE_XYZW (RADEON_CP_VC_FRMT_W0|RADEON_CP_VC_FRMT_Z) +#define ACTIVE_NORM RADEON_CP_VC_FRMT_N0 + +#define ACTIVE_PKCOLOR RADEON_CP_VC_FRMT_PKCOLOR +#define ACTIVE_FPCOLOR RADEON_CP_VC_FRMT_FPCOLOR +#define ACTIVE_FPALPHA RADEON_CP_VC_FRMT_FPALPHA +#define ACTIVE_COLOR (ACTIVE_FPCOLOR|ACTIVE_PKCOLOR) + +#define ACTIVE_PKSPEC RADEON_CP_VC_FRMT_PKSPEC +#define ACTIVE_FPSPEC RADEON_CP_VC_FRMT_FPSPEC +#define ACTIVE_SPEC (ACTIVE_FPSPEC|ACTIVE_PKSPEC) + +#define ACTIVE_ST0 RADEON_CP_VC_FRMT_ST0 +#define ACTIVE_ST1 RADEON_CP_VC_FRMT_ST1 +#define ACTIVE_ST_ALL (RADEON_CP_VC_FRMT_ST1|RADEON_CP_VC_FRMT_ST0) + +/* Each codegen function should be able to be fully specified by a + * subsetted version of rmesa->vb.vertex_format. + */ +#define MASK_NORM (ACTIVE_XYZW) +#define MASK_COLOR (MASK_NORM|ACTIVE_NORM) +#define MASK_SPEC (MASK_COLOR|ACTIVE_COLOR) +#define MASK_ST0 (MASK_SPEC|ACTIVE_SPEC) +#define MASK_ST1 (MASK_ST0|ACTIVE_ST0) +#define MASK_ST_ALL (MASK_ST1|ACTIVE_ST1) +#define MASK_VERTEX (MASK_ST_ALL|ACTIVE_FPALPHA) + + +typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat ); +typedef void (*p3f)( GLfloat, GLfloat, GLfloat ); +typedef void (*p2f)( GLfloat, GLfloat ); +typedef void (*p1f)( GLfloat ); +typedef void (*pe2f)( GLenum, GLfloat, GLfloat ); +typedef void (*pe1f)( GLenum, GLfloat ); +typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte ); +typedef void (*p3ub)( GLubyte, GLubyte, GLubyte ); +typedef void (*pfv)( const GLfloat * ); +typedef void (*pefv)( GLenum, const GLfloat * ); +typedef void (*pubv)( const GLubyte * ); + + +CHOOSE(Normal3f, p3f, MASK_NORM, ACTIVE_NORM, + (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) +CHOOSE(Normal3fv, pfv, MASK_NORM, ACTIVE_NORM, + (const GLfloat *v), (v)) + +CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, ACTIVE_COLOR, + (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d)) +CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, ACTIVE_COLOR, + (const GLubyte *v), (v)) +CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, ACTIVE_COLOR, + (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) +CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, ACTIVE_COLOR, + (const GLubyte *v), (v)) + +CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, ACTIVE_COLOR, + (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d)) +CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, ACTIVE_COLOR, + (const GLfloat *v), (v)) +CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, ACTIVE_COLOR, + (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) +CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, ACTIVE_COLOR, + (const GLfloat *v), (v)) + + +CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, ACTIVE_SPEC, + (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) +CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, ACTIVE_SPEC, + (const GLubyte *v), (v)) +CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, ACTIVE_SPEC, + (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) +CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, ACTIVE_SPEC, + (const GLfloat *v), (v)) + +CHOOSE(TexCoord2f, p2f, MASK_ST0, ACTIVE_ST0, + (GLfloat a,GLfloat b), (a,b)) +CHOOSE(TexCoord2fv, pfv, MASK_ST0, ACTIVE_ST0, + (const GLfloat *v), (v)) +CHOOSE(TexCoord1f, p1f, MASK_ST0, ACTIVE_ST0, + (GLfloat a), (a)) +CHOOSE(TexCoord1fv, pfv, MASK_ST0, ACTIVE_ST0, + (const GLfloat *v), (v)) + +CHOOSE(MultiTexCoord2fARB, pe2f, MASK_ST_ALL, ACTIVE_ST_ALL, + (GLenum u,GLfloat a,GLfloat b), (u,a,b)) +CHOOSE(MultiTexCoord2fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL, + (GLenum u,const GLfloat *v), (u,v)) +CHOOSE(MultiTexCoord1fARB, pe1f, MASK_ST_ALL, ACTIVE_ST_ALL, + (GLenum u,GLfloat a), (u,a)) +CHOOSE(MultiTexCoord1fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL, + (GLenum u,const GLfloat *v), (u,v)) + +CHOOSE(Vertex3f, p3f, MASK_VERTEX, MASK_VERTEX, + (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) +CHOOSE(Vertex3fv, pfv, MASK_VERTEX, MASK_VERTEX, + (const GLfloat *v), (v)) +CHOOSE(Vertex2f, p2f, MASK_VERTEX, MASK_VERTEX, + (GLfloat a,GLfloat b), (a,b)) +CHOOSE(Vertex2fv, pfv, MASK_VERTEX, MASK_VERTEX, + (const GLfloat *v), (v)) + + + + + +void radeonVtxfmtInitChoosers( GLvertexformat *vfmt ) +{ + vfmt->Color3f = choose_Color3f; + vfmt->Color3fv = choose_Color3fv; + vfmt->Color3ub = choose_Color3ub; + vfmt->Color3ubv = choose_Color3ubv; + vfmt->Color4f = choose_Color4f; + vfmt->Color4fv = choose_Color4fv; + vfmt->Color4ub = choose_Color4ub; + vfmt->Color4ubv = choose_Color4ubv; + vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT; + vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; + vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; + vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; + vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; + vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; + vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; + vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; + vfmt->Normal3f = choose_Normal3f; + vfmt->Normal3fv = choose_Normal3fv; + vfmt->TexCoord1f = choose_TexCoord1f; + vfmt->TexCoord1fv = choose_TexCoord1fv; + vfmt->TexCoord2f = choose_TexCoord2f; + vfmt->TexCoord2fv = choose_TexCoord2fv; + vfmt->Vertex2f = choose_Vertex2f; + vfmt->Vertex2fv = choose_Vertex2fv; + vfmt->Vertex3f = choose_Vertex3f; + vfmt->Vertex3fv = choose_Vertex3fv; +} + + +static struct dynfn *codegen_noop( GLcontext *ctx, int key ) +{ + (void) ctx; (void) key; + return 0; +} + +void radeonInitCodegen( struct dfn_generators *gen ) +{ + gen->Vertex3f = codegen_noop; + gen->Vertex3fv = codegen_noop; + gen->Color4ub = codegen_noop; + gen->Color4ubv = codegen_noop; + gen->Normal3f = codegen_noop; + gen->Normal3fv = codegen_noop; + gen->TexCoord2f = codegen_noop; + gen->TexCoord2fv = codegen_noop; + gen->MultiTexCoord2fARB = codegen_noop; + gen->MultiTexCoord2fvARB = codegen_noop; + gen->Vertex2f = codegen_noop; + gen->Vertex2fv = codegen_noop; + gen->Color3ub = codegen_noop; + gen->Color3ubv = codegen_noop; + gen->Color4f = codegen_noop; + gen->Color4fv = codegen_noop; + gen->Color3f = codegen_noop; + gen->Color3fv = codegen_noop; + gen->SecondaryColor3fEXT = codegen_noop; + gen->SecondaryColor3fvEXT = codegen_noop; + gen->SecondaryColor3ubEXT = codegen_noop; + gen->SecondaryColor3ubvEXT = codegen_noop; + gen->TexCoord1f = codegen_noop; + gen->TexCoord1fv = codegen_noop; + gen->MultiTexCoord1fARB = codegen_noop; + gen->MultiTexCoord1fvARB = codegen_noop; + + if (!getenv("RADEON_NO_CODEGEN")) { +#if defined(USE_X86_ASM) + radeonInitX86Codegen( gen ); +#endif + +#if defined(USE_SSE_ASM) + radeonInitSSECodegen( gen ); +#endif + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c new file mode 100644 index 000000000..0df3062be --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c @@ -0,0 +1,88 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:58 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include <stdio.h> +#include <assert.h> +#include "mem.h" +#include "simple_list.h" +#include "radeon_vtxfmt.h" + +#if defined(USE_SSE_ASM) +#include "X86/common_x86_asm.h" + +/* Build specialized versions of the immediate calls on the fly for + * the current state. ???P4 SSE2 versions??? + */ + + +static struct dynfn *makeSSENormal3fv( GLcontext *ctx, int key ) +{ + /* Requires P4 (sse2?) + */ + static unsigned char temp[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $0x12345678,%edx */ + 0xf3, 0x0f, 0x7e, 0x00, /* movq (%eax),%xmm0 */ + 0x66, 0x0f, 0x6e, 0x48, 0x08, /* movd 0x8(%eax),%xmm1 */ + 0x66, 0x0f, 0xd6, 0x42, 0x0c, /* movq %xmm0,0xc(%edx) */ + 0x66, 0x0f, 0x7e, 0x4a, 0x14, /* movd %xmm1,0x14(%edx) */ + 0xc3, /* ret */ + }; + + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + insert_at_head( &rmesa->vb.dfn_cache.Normal3fv, dfn ); + dfn->key = key; + + dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 5, 0x0, (int)vb.normalptr); + return dfn; +} + +void radeonInitSSECodegen( struct dfn_generators *gen ) +{ + if ( cpu_has_xmm && cpu_has_xmm2 ) + /*gen->Normal3fv = */ (void)makeSSENormal3fv; +} + +#else + +void radeonInitSSECodegen( struct dfn_generators *gen ) +{ + (void) gen; +} + +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c new file mode 100644 index 000000000..ad7d9308e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c @@ -0,0 +1,463 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c,v 1.2 2002/12/21 17:02:16 dawes Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include <stdio.h> +#include <assert.h> +#include "mem.h" +#include "mmath.h" +#include "simple_list.h" +#include "radeon_vtxfmt.h" + +#if defined(USE_X86_ASM) + +#define EXTERN( FUNC ) \ +extern const char *FUNC; \ +extern const char *FUNC##_end + +EXTERN ( _x86_Normal3fv ); +EXTERN ( _x86_Normal3f ); +EXTERN ( _x86_Vertex3fv_6 ); +EXTERN ( _x86_Vertex3fv_8 ); +EXTERN ( _x86_Vertex3fv ); +EXTERN ( _x86_Vertex3f_4 ); +EXTERN ( _x86_Vertex3f_6 ); +EXTERN ( _x86_Vertex3f ); +EXTERN ( _x86_Color4ubv_ub ); +EXTERN ( _x86_Color4ubv_4f ); +EXTERN ( _x86_Color4ub_ub ); +EXTERN ( _x86_Color3fv_3f ); +EXTERN ( _x86_Color3f_3f ); +EXTERN ( _x86_TexCoord2fv ); +EXTERN ( _x86_TexCoord2f ); +EXTERN ( _x86_MultiTexCoord2fvARB ); +EXTERN ( _x86_MultiTexCoord2fvARB_2 ); +EXTERN ( _x86_MultiTexCoord2fARB ); +EXTERN ( _x86_MultiTexCoord2fARB_2 ); + + +/* Build specialized versions of the immediate calls on the fly for + * the current state. Generic x86 versions. + */ + +struct dynfn *radeon_makeX86Vertex3f( GLcontext *ctx, int key ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, vb.vertex_size ); + + switch (vb.vertex_size) { + case 4: { + + DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f ); + FIXUP(dfn->code, 2, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 25, 0x0, (int)&vb.vertex[3]); + FIXUP(dfn->code, 36, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 46, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 51, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 60, 0x0, (int)&vb.notify); + break; + } + case 6: { + + DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f ); + FIXUP(dfn->code, 3, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 28, 0x0, (int)&vb.vertex[3]); + FIXUP(dfn->code, 34, 0x0, (int)&vb.vertex[4]); + FIXUP(dfn->code, 40, 0x0, (int)&vb.vertex[5]); + FIXUP(dfn->code, 57, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 63, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 70, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 79, 0x0, (int)&vb.notify); + break; + } + default: { + + DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f ); + FIXUP(dfn->code, 3, 0x0, (int)&vb.vertex[3]); + FIXUP(dfn->code, 9, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 37, 0x0, vb.vertex_size-3); + FIXUP(dfn->code, 44, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 50, 0x0, (int)&vb.dmaptr); + FIXUP(dfn->code, 56, 0x0, (int)&vb.counter); + FIXUP(dfn->code, 67, 0x0, (int)&vb.notify); + break; + } + } + + return dfn; +} + + + +struct dynfn *radeon_makeX86Vertex3fv( GLcontext *ctx, int key ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, vb.vertex_size ); + + switch (vb.vertex_size) { + case 6: { + + DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv ); + FIXUP(dfn->code, 1, 0x00000000, (int)&vb.dmaptr); + FIXUP(dfn->code, 27, 0x0000001c, (int)&vb.vertex[3]); + FIXUP(dfn->code, 33, 0x00000020, (int)&vb.vertex[4]); + FIXUP(dfn->code, 45, 0x00000024, (int)&vb.vertex[5]); + FIXUP(dfn->code, 56, 0x00000000, (int)&vb.dmaptr); + FIXUP(dfn->code, 61, 0x00000004, (int)&vb.counter); + FIXUP(dfn->code, 67, 0x00000004, (int)&vb.counter); + FIXUP(dfn->code, 76, 0x00000008, (int)&vb.notify); + break; + } + + + case 8: { + + DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv ); + FIXUP(dfn->code, 1, 0x00000000, (int)&vb.dmaptr); + FIXUP(dfn->code, 27, 0x0000001c, (int)&vb.vertex[3]); + FIXUP(dfn->code, 33, 0x00000020, (int)&vb.vertex[4]); + FIXUP(dfn->code, 45, 0x0000001c, (int)&vb.vertex[5]); + FIXUP(dfn->code, 51, 0x00000020, (int)&vb.vertex[6]); + FIXUP(dfn->code, 63, 0x00000024, (int)&vb.vertex[7]); + FIXUP(dfn->code, 74, 0x00000000, (int)&vb.dmaptr); + FIXUP(dfn->code, 79, 0x00000004, (int)&vb.counter); + FIXUP(dfn->code, 85, 0x00000004, (int)&vb.counter); + FIXUP(dfn->code, 94, 0x00000008, (int)&vb.notify); + break; + } + + + + default: { + + DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv ); + FIXUP(dfn->code, 8, 0x01010101, (int)&vb.dmaptr); + FIXUP(dfn->code, 32, 0x00000006, vb.vertex_size-3); + FIXUP(dfn->code, 37, 0x00000058, (int)&vb.vertex[3]); + FIXUP(dfn->code, 45, 0x01010101, (int)&vb.dmaptr); + FIXUP(dfn->code, 50, 0x02020202, (int)&vb.counter); + FIXUP(dfn->code, 58, 0x02020202, (int)&vb.counter); + FIXUP(dfn->code, 67, 0x0, (int)&vb.notify); + break; + } + } + + return dfn; +} + +struct dynfn *radeon_makeX86Normal3fv( GLcontext *ctx, int key ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int i = 0; + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + DFN ( _x86_Normal3fv, rmesa->vb.dfn_cache.Normal3fv ); + + FIXUP2(dfn->code, i, 0x0, (int)vb.normalptr); + FIXUP2(dfn->code, i, 0x4, 4+(int)vb.normalptr); + FIXUP2(dfn->code, i, 0x8, 8+(int)vb.normalptr); + /* fprintf(stderr, "%s done\n", __FUNCTION__); */ + return dfn; +} + +struct dynfn *radeon_makeX86Normal3f( GLcontext *ctx, int key ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + DFN ( _x86_Normal3f, rmesa->vb.dfn_cache.Normal3f ); + FIXUP(dfn->code, 1, 0x12345678, (int)vb.normalptr); + return dfn; +} + +struct dynfn *radeon_makeX86Color4ubv( GLcontext *ctx, int key ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + if (key & RADEON_CP_VC_FRMT_PKCOLOR) { + DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); + FIXUP(dfn->code, 5, 0x12345678, (int)vb.colorptr); + return dfn; + } + else { + + DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); + FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); + FIXUP(dfn->code, 27, 0xdeadbeaf, (int)vb.floatcolorptr); + FIXUP(dfn->code, 33, 0xdeadbeaf, (int)vb.floatcolorptr+4); + FIXUP(dfn->code, 55, 0xdeadbeaf, (int)vb.floatcolorptr+8); + FIXUP(dfn->code, 61, 0xdeadbeaf, (int)vb.floatcolorptr+12); + return dfn; + } +} + +struct dynfn *radeon_makeX86Color4ub( GLcontext *ctx, int key ) +{ + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + if (key & RADEON_CP_VC_FRMT_PKCOLOR) { + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); + FIXUP(dfn->code, 18, 0x0, (int)vb.colorptr); + FIXUP(dfn->code, 24, 0x0, (int)vb.colorptr+1); + FIXUP(dfn->code, 30, 0x0, (int)vb.colorptr+2); + FIXUP(dfn->code, 36, 0x0, (int)vb.colorptr+3); + return dfn; + } + else + return 0; +} + + +struct dynfn *radeon_makeX86Color3fv( GLcontext *ctx, int key ) +{ + if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) + return 0; + else + { + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + DFN ( _x86_Color3fv_3f, rmesa->vb.dfn_cache.Color3fv ); + FIXUP(dfn->code, 5, 0x0, (int)vb.floatcolorptr); + return dfn; + } +} + +struct dynfn *radeon_makeX86Color3f( GLcontext *ctx, int key ) +{ + if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) + return 0; + else + { + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + DFN ( _x86_Color3f_3f, rmesa->vb.dfn_cache.Color3f ); + FIXUP(dfn->code, 1, 0x12345678, (int)vb.floatcolorptr); + return dfn; + } +} + + + +struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *ctx, int key ) +{ + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + DFN ( _x86_TexCoord2fv, rmesa->vb.dfn_cache.TexCoord2fv ); + FIXUP(dfn->code, 5, 0x12345678, (int)vb.texcoordptr[0]); + return dfn; +} + +struct dynfn *radeon_makeX86TexCoord2f( GLcontext *ctx, int key ) +{ + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + DFN ( _x86_TexCoord2f, rmesa->vb.dfn_cache.TexCoord2f ); + FIXUP(dfn->code, 1, 0x12345678, (int)vb.texcoordptr[0]); + return dfn; +} + +struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *ctx, int key ) +{ +#if 0 + static char temp[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ + 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ + 0x83, 0xe0, 0x01, /* and $0x1,%eax */ + 0x8b, 0x11, /* mov (%ecx),%edx */ + 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ + 0x8b, 0x49, 0x04, /* mov 0x4(%ecx),%ecx */ + 0x89, 0x90, 0, 0, 0, 0,/* mov %edx,DEST(%eax) */ + 0x89, 0x88, 0, 0, 0, 0,/* mov %ecx,DEST+8(%eax) */ + 0xc3, /* ret */ + }; + static char temp2[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ + 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ + 0x83, 0xe0, 0x01, /* and $0x1,%eax */ + 0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%edx */ + 0x8b, 0x01, /* mov (%ecx),%eax */ + 0x89, 0x02, /* mov %eax,(%edx) */ + 0x8b, 0x41, 0x04, /* mov 0x4(%ecx),%eax */ + 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ + 0xc3, /* ret */ + }; +#endif + + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == + (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { + DFN ( _x86_MultiTexCoord2fvARB, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 26, 0xdeadbeef, (int)vb.texcoordptr[0]); + FIXUP(dfn->code, 32, 0xdeadbeef, (int)vb.texcoordptr[0]+4); + } else { + DFN ( _x86_MultiTexCoord2fvARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 19, 0x0, (int)vb.texcoordptr); + } + return dfn; +} + +struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *ctx, + int key ) +{ +#if 0 + static char temp[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ + 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ + 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ + 0x83, 0xe0, 0x01, /* and $0x1,%eax */ + 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ + 0x89, 0x90, 0, 0, 0, 0, /* mov %edx,DEST(%eax) */ + 0x89, 0x88, 0, 0, 0, 0, /* mov %ecx,DEST+8(%eax) */ + 0xc3, /* ret */ + }; + + static char temp2[] = { + 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ + 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ + 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ + 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ + 0x83, 0xe0, 0x01, /* and $0x1,%eax */ + 0x8b, 0x04, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%eax */ + 0x89, 0x10, /* mov %edx,(%eax) */ + 0x89, 0x48, 0x04, /* mov %ecx,0x4(%eax) */ + 0xc3, /* ret */ + }; +#endif + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == + (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { + DFN ( _x86_MultiTexCoord2fARB, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 25, 0xdeadbeef, (int)vb.texcoordptr[0]); + FIXUP(dfn->code, 31, 0xdeadbeef, (int)vb.texcoordptr[0]+4); + } + else { + /* Note: this might get generated multiple times, even though the + * actual emitted code is the same. + */ + DFN ( _x86_MultiTexCoord2fARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 23, 0x0, (int)vb.texcoordptr); + } + return dfn; +} + + +void radeonInitX86Codegen( struct dfn_generators *gen ) +{ + gen->Vertex3f = radeon_makeX86Vertex3f; + gen->Vertex3fv = radeon_makeX86Vertex3fv; + gen->Color4ub = radeon_makeX86Color4ub; /* PKCOLOR only */ + gen->Color4ubv = radeon_makeX86Color4ubv; /* PKCOLOR only */ + gen->Normal3f = radeon_makeX86Normal3f; + gen->Normal3fv = radeon_makeX86Normal3fv; + gen->TexCoord2f = radeon_makeX86TexCoord2f; + gen->TexCoord2fv = radeon_makeX86TexCoord2fv; + gen->MultiTexCoord2fARB = radeon_makeX86MultiTexCoord2fARB; + gen->MultiTexCoord2fvARB = radeon_makeX86MultiTexCoord2fvARB; + gen->Color3f = radeon_makeX86Color3f; + gen->Color3fv = radeon_makeX86Color3fv; + + /* Not done: + */ +/* gen->Vertex2f = radeon_makeX86Vertex2f; */ +/* gen->Vertex2fv = radeon_makeX86Vertex2fv; */ +/* gen->Color3ub = radeon_makeX86Color3ub; */ +/* gen->Color3ubv = radeon_makeX86Color3ubv; */ +/* gen->Color4f = radeon_makeX86Color4f; */ +/* gen->Color4fv = radeon_makeX86Color4fv; */ +/* gen->TexCoord1f = radeon_makeX86TexCoord1f; */ +/* gen->TexCoord1fv = radeon_makeX86TexCoord1fv; */ +/* gen->MultiTexCoord1fARB = radeon_makeX86MultiTexCoord1fARB; */ +/* gen->MultiTexCoord1fvARB = radeon_makeX86MultiTexCoord1fvARB; */ +} + + +#else + +void radeonInitX86Codegen( struct dfn_generators *gen ) +{ + (void) gen; +} + +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S new file mode 100644 index 000000000..b9b1594a3 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S @@ -0,0 +1,410 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S,v 1.2 2002/11/07 18:32:00 tsi Exp $ */ +/************************************************************************** + +Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#define GLOBL( x ) \ +.globl x; \ +x##: + +.data +.align 4 +GLOBL( _x86_Normal3fv) + movl 4(%esp), %eax /* load 'v' off stack */ + movl (%eax), %ecx /* load v[0] */ + movl 4(%eax), %edx /* load v[1] */ + movl 8(%eax), %eax /* load v[2] */ + movl %ecx, 0 /* store v[0] to current vertex */ + movl %edx, 4 /* store v[1] to current vertex */ + movl %eax, 8 /* store v[2] to current vertex */ + ret +GLOBL ( _x86_Normal3fv_end ) + +/* + vertex 3f vertex size 4 +*/ + +GLOBL ( _x86_Vertex3f_4 ) + movl (0), %ecx + movl 4(%esp), %eax + movl 8(%esp), %edx + movl %eax, (%ecx) + movl %edx, 4(%ecx) + movl 12(%esp), %eax + movl (0), %edx + movl %eax, 8(%ecx) + movl %edx, 12(%ecx) + movl (0), %eax + addl $16, %ecx + dec %eax + movl %ecx, (0) + movl %eax, (0) + je .1 + ret +.1: jmp *0 + +GLOBL ( _x86_Vertex3f_4_end ) + +/* + vertex 3f vertex size 6 +*/ +GLOBL ( _x86_Vertex3f_6 ) + push %edi + movl (0), %edi + movl 8(%esp), %eax + movl 12(%esp), %edx + movl 16(%esp), %ecx + movl %eax, (%edi) + movl %edx, 4(%edi) + movl %ecx, 8(%edi) + movl (0), %eax + movl (0), %edx + movl (0), %ecx + movl %eax, 12(%edi) + movl %edx, 16(%edi) + movl %ecx, 20(%edi) + addl $24, %edi + movl (0), %eax + movl %edi, (0) + dec %eax + pop %edi + movl %eax, (0) + je .2 + ret +.2: jmp *0 +GLOBL ( _x86_Vertex3f_6_end ) +/* + vertex 3f generic size +*/ +GLOBL ( _x86_Vertex3f ) + push %edi + push %esi + movl $0, %esi + movl (0), %edi + movl 12(%esp), %eax + movl 16(%esp), %edx + movl 20(%esp), %ecx + movl %eax, (%edi) + movl %edx, 4(%edi) + movl %ecx, 8(%edi) + addl $12, %edi + movl $0, %ecx + repz + movsl %ds:(%esi), %es:(%edi) + movl (0), %eax + movl %edi, (0) + dec %eax + movl %eax, (0) + pop %esi + pop %edi + je .3 + ret +.3: jmp *0 + +GLOBL ( _x86_Vertex3f_end ) + +/* + Vertex 3fv vertex size 6 +*/ +GLOBL ( _x86_Vertex3fv_6 ) + movl (0), %eax + movl 4(%esp), %ecx + movl (%ecx), %edx + movl %edx, (%eax) + movl 4(%ecx), %edx + movl 8(%ecx), %ecx + movl %edx, 4(%eax) + movl %ecx, 8(%eax) + movl (28), %edx + movl (32), %ecx + movl %edx, 12(%eax) + movl %ecx, 16(%eax) + movl (36), %edx + movl %edx, 20(%eax) + addl $24, %eax + movl %eax, 0 + movl 4, %eax + dec %eax + movl %eax, 4 + je .4 + ret +.4: jmp *8 + +GLOBL ( _x86_Vertex3fv_6_end ) + +/* + Vertex 3fv vertex size 8 +*/ +GLOBL ( _x86_Vertex3fv_8 ) + movl (0), %eax + movl 4(%esp), %ecx + movl (%ecx), %edx + movl %edx ,(%eax) + movl 4(%ecx) ,%edx + movl 8(%ecx) ,%ecx + movl %edx, 4(%eax) + movl %ecx, 8(%eax) + movl (28), %edx + movl (32), %ecx + movl %edx, 12(%eax) + movl %ecx, 16(%eax) + movl (28), %edx + movl (32), %ecx + movl %edx, 20(%eax) + movl %ecx, 24(%eax) + movl (36), %edx + movl %edx, 28(%eax) + addl $32, %eax + movl %eax, (0) + movl 4, %eax + dec %eax + movl %eax, (4) + je .5 + ret +.5: jmp *8 + +GLOBL ( _x86_Vertex3fv_8_end ) + +/* + Vertex 3fv generic vertex size +*/ +GLOBL ( _x86_Vertex3fv ) + movl 4(%esp), %edx + push %edi + push %esi + movl (0x1010101), %edi + movl (%edx), %eax + movl 4(%edx), %ecx + movl 8(%edx), %esi + movl %eax, (%edi) + movl %ecx, 4(%edi) + movl %esi, 8(%edi) + addl $12, %edi + movl $6, %ecx + movl $0x58, %esi + repz + movsl %ds:(%esi), %es:(%edi) + movl %edi, (0x1010101) + movl (0x2020202), %eax + pop %esi + pop %edi + dec %eax + movl %eax, (0x2020202) + je .6 + ret +.6: jmp *0 +GLOBL ( _x86_Vertex3fv_end ) + +/* + Normal 3f +*/ +GLOBL ( _x86_Normal3f ) + movl $0x12345678, %edx + movl 4(%esp), %eax + movl %eax, (%edx) + movl 8(%esp), %eax + movl %eax, 4(%edx) + movl 12(%esp), %eax + movl %eax, 8(%edx) + ret +GLOBL ( _x86_Normal3f_end ) + +/* + Color 4ubv_ub +*/ +GLOBL ( _x86_Color4ubv_ub ) + movl 4(%esp), %eax + movl $0x12345678, %edx + movl (%eax), %eax + movl %eax, (%edx) + ret +GLOBL ( _x86_Color4ubv_ub_end ) + +/* + Color 4ubv 4f +*/ +GLOBL ( _x86_Color4ubv_4f ) + push %ebx + movl $0, %edx + xor %eax, %eax + xor %ecx, %ecx + movl 8(%esp), %ebx + movl (%ebx), %ebx + mov %bl, %al + mov %bh, %cl + movl (%edx,%eax,4),%eax + movl (%edx,%ecx,4),%ecx + movl %eax, (0xdeadbeaf) + movl %ecx, (0xdeadbeaf) + xor %eax, %eax + xor %ecx, %ecx + shr $16, %ebx + mov %bl, %al + mov %bh, %cl + movl (%edx,%eax,4), %eax + movl (%edx,%ecx,4), %ecx + movl %eax, (0xdeadbeaf) + movl %ecx, (0xdeadbeaf) + pop %ebx + ret +GLOBL ( _x86_Color4ubv_4f_end ) + +/* + + Color4ub_ub +*/ +GLOBL( _x86_Color4ub_ub ) + push %ebx + movl 8(%esp), %eax + movl 12(%esp), %edx + movl 16(%esp), %ecx + movl 20(%esp), %ebx + mov %al, (0) + mov %dl, (0) + mov %cl, (0) + mov %bl, (0) + pop %ebx + ret +GLOBL( _x86_Color4ub_ub_end ) + +/* + Color3fv_3f +*/ +GLOBL( _x86_Color3fv_3f ) + movl 4(%esp), %eax + movl $0, %edx + movl (%eax), %ecx + movl %ecx, (%edx) + movl 4(%eax), %ecx + movl %ecx, 4(%edx) + movl 8(%eax), %ecx + movl %ecx, 8(%edx) + ret +GLOBL( _x86_Color3fv_3f_end ) + +/* + Color3f_3f +*/ +GLOBL( _x86_Color3f_3f ) + movl $0x12345678, %edx + movl 4(%esp), %eax + movl %eax, (%edx) + movl 8(%esp,1), %eax + movl %eax, 4(%edx) + movl 12(%esp), %eax + movl %eax, 8(%edx) + ret +GLOBL( _x86_Color3f_3f_end ) + +/* + TexCoord2fv +*/ + +GLOBL( _x86_TexCoord2fv ) + movl 4(%esp), %eax + movl $0x12345678, %edx + movl (%eax), %ecx + movl 4(%eax), %eax + movl %ecx, (%edx) + movl %eax, 4(%edx) + ret + +GLOBL( _x86_TexCoord2fv_end ) +/* + TexCoord2f +*/ +GLOBL( _x86_TexCoord2f ) + movl $0x12345678, %edx + movl 4(%esp), %eax + movl 8(%esp), %ecx + movl %eax, (%edx) + movl %ecx, 4(%edx) + ret +GLOBL( _x86_TexCoord2f_end ) + +/* + MultiTexCoord2fvARB st0/st1 +*/ +GLOBL( _x86_MultiTexCoord2fvARB ) + + movl 4(%esp), %eax + movl 8(%esp), %ecx + sub $0x84c0, %eax + and $1, %eax + movl (%ecx), %edx + shl $3, %eax + movl 4(%ecx), %ecx + movl %edx, 0xdeadbeef(%eax) + movl %ecx, 0xdeadbeef(%eax) + ret +GLOBL( _x86_MultiTexCoord2fvARB_end ) +/* + MultiTexCoord2fvARB +*/ + +GLOBL( _x86_MultiTexCoord2fvARB_2 ) + movl 4(%esp,1), %eax + movl 8(%esp,1), %ecx + sub $0x84c0, %eax + and $0x1, %eax + movl 0(,%eax,4), %edx + movl (%ecx), %eax + movl %eax, (%edx) + movl 4(%ecx), %eax + movl %eax, 4(%edx) + ret + +GLOBL( _x86_MultiTexCoord2fvARB_2_end ) + +/* + MultiTexCoord2fARB st0/st1 +*/ +GLOBL( _x86_MultiTexCoord2fARB ) + movl 4(%esp), %eax + movl 8(%esp), %edx + sub $0x84c0, %eax + movl 12(%esp), %ecx + and $1, %eax + shl $3, %eax + movl %edx, 0xdeadbeef(%eax) + movl %ecx, 0xdeadbeef(%eax) + ret +GLOBL( _x86_MultiTexCoord2fARB_end ) + +/* + MultiTexCoord2fARB +*/ +GLOBL( _x86_MultiTexCoord2fARB_2 ) + movl 4(%esp), %eax + movl 8(%esp), %edx + sub $0x84c0, %eax + movl 12(%esp,1), %ecx + and $1,%eax + movl 0(,%eax,4), %eax + movl %edx, (%eax) + movl %ecx, 4(%eax) + ret +GLOBL( _x86_MultiTexCoord2fARB_2_end ) diff --git a/xc/lib/GL/mesa/src/drv/sis/Imakefile b/xc/lib/GL/mesa/src/drv/sis/Imakefile index 653d687c1..23697f935 100644 --- a/xc/lib/GL/mesa/src/drv/sis/Imakefile +++ b/xc/lib/GL/mesa/src/drv/sis/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/sis/Imakefile,v 1.20 2002/02/27 21:09:33 tsi Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/sis/Imakefile,v 1.22 2002/11/25 14:04:52 eich Exp $ #include <Threads.tmpl> @@ -25,7 +25,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/sis/Imakefile,v 1.20 2002/02/27 21:09:33 #include "../../tnl/Imakefile.inc" #include "../../tnl_dd/Imakefile.inc" #include "../../Imakefile.inc" -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #include "../../X86/Imakefile.inc" #endif #ifdef SparcArchitecture @@ -62,7 +62,7 @@ XCOMM DEBUG_DEFINES = -DSIS_DEBUG OBJS = $(DRIOBJS) $(DRMOBJS) $(COREMESAOBJS) \ $(MESA_ASM_OBJS) $(SISOBJS) $(HIOBJS) -REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) +REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) $(XONLYLIB) #include <Library.tmpl> diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_mesa.c b/xc/lib/GL/mesa/src/drv/sis/sis_mesa.c index a631000e6..4f1db4f88 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_mesa.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_mesa.c @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_mesa.c,v 1.6 2001/10/31 22:50:25 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_mesa.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */ /* * Authors: @@ -1404,8 +1404,9 @@ sis_update_drawable_state (GLcontext * ctx) } void -sis_GetBufferSize (GLcontext * ctx, GLuint * width, GLuint * height) +sis_GetBufferSize (GLframebuffer *buffer, GLuint * width, GLuint * height) { + GET_CURRENT_CONTEXT(ctx); XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; __GLSiScontext *hwcx = (__GLSiScontext *) xmesa->private; diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_mesa.h b/xc/lib/GL/mesa/src/drv/sis/sis_mesa.h index 309a1ba8f..88a57bb0b 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_mesa.h +++ b/xc/lib/GL/mesa/src/drv/sis/sis_mesa.h @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_mesa.h,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_mesa.h,v 1.4 2002/10/30 12:52:00 alanh Exp $ */ /* * Authors: @@ -44,7 +44,7 @@ GLbitfield sis_Clear (GLcontext * ctx, GLbitfield mask, GLboolean all, GLboolean sis_SetDrawBuffer (GLcontext * ctx, GLenum mode); void sis_SetReadBuffer (GLcontext *ctx, GLframebuffer *colorBuffer, GLenum buffer); -void sis_GetBufferSize (GLcontext * ctx, GLuint * width, GLuint * height); +void sis_GetBufferSize (GLframebuffer * buffer, GLuint * width, GLuint * height); const char *sis_ExtensionString (GLcontext * ctx); const GLubyte *sis_GetString (GLcontext * ctx, GLenum name); void sis_Finish (GLcontext * ctx); diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile index 19eb8c613..fa905838a 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile +++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.30 2002/02/23 00:45:51 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.32 2002/11/25 14:04:52 eich Exp $ #include <Threads.tmpl> @@ -25,7 +25,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.30 2002/02/23 00:45:51 #include "../../tnl/Imakefile.inc" #include "../../tnl_dd/Imakefile.inc" #include "../../Imakefile.inc" -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm #include "../../X86/Imakefile.inc" #endif #ifdef SparcArchitecture @@ -54,7 +54,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.30 2002/02/23 00:45:51 OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(COREMESAOBJS) \ $(MESA_ASM_OBJS) $(TDFXOBJS) $(HIOBJS) -REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) +REQUIREDLIBS = MathLibrary $(LDPRELIB) $(GLXLIB) $(XONLYLIB) #include <Library.tmpl> diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c index 8c75dee7e..b1fc19b2d 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c,v 1.9 2002/08/08 08:18:01 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c,v 1.11 2003/01/15 04:16:39 dawes Exp $ */ /* * Original rewrite: @@ -755,118 +755,116 @@ GLboolean tdfxInitGlide(tdfxContextPtr tmesa) } } -#define GET_FUNCTION(PTR, NAME, CHECK) \ - *((void **)&(tmesa->Glide.PTR)) = dlsym(libHandle, NAME); \ - if (CHECK && !tmesa->Glide.PTR) { \ +#define GET_FUNCTION(PTR, NAME) \ + tmesa->Glide.PTR = dlsym(libHandle, NAME); \ + if (!tmesa->Glide.PTR) { \ __driUtilMessage("couldn't find Glide function %s in %s.", \ NAME, libName); \ } - GET_FUNCTION(grDrawPoint, "grDrawPoint", GL_TRUE); - GET_FUNCTION(grDrawLine, "grDrawLine", GL_TRUE); - GET_FUNCTION(grDrawTriangle, "grDrawTriangle", GL_TRUE); - GET_FUNCTION(grVertexLayout, "grVertexLayout", GL_TRUE); - GET_FUNCTION(grDrawVertexArray, "grDrawVertexArray", GL_TRUE); - GET_FUNCTION(grDrawVertexArrayContiguous, "grDrawVertexArrayContiguous", GL_TRUE); - GET_FUNCTION(grBufferClear, "grBufferClear", GL_TRUE); + GET_FUNCTION(grDrawPoint, "grDrawPoint"); + GET_FUNCTION(grDrawLine, "grDrawLine"); + GET_FUNCTION(grDrawTriangle, "grDrawTriangle"); + GET_FUNCTION(grVertexLayout, "grVertexLayout"); + GET_FUNCTION(grDrawVertexArray, "grDrawVertexArray"); + GET_FUNCTION(grDrawVertexArrayContiguous, "grDrawVertexArrayContiguous"); + GET_FUNCTION(grBufferClear, "grBufferClear"); /*GET_FUNCTION(grBufferSwap, "grBufferSwap");*/ - GET_FUNCTION(grRenderBuffer, "grRenderBuffer", GL_TRUE); - GET_FUNCTION(grErrorSetCallback, "grErrorSetCallback", GL_TRUE); - GET_FUNCTION(grFinish, "grFinish", GL_TRUE); - GET_FUNCTION(grFlush, "grFlush", GL_TRUE); - GET_FUNCTION(grSstWinOpen, "grSstWinOpen", GL_TRUE); - GET_FUNCTION(grSstWinClose, "grSstWinClose", GL_TRUE); + GET_FUNCTION(grRenderBuffer, "grRenderBuffer"); + GET_FUNCTION(grErrorSetCallback, "grErrorSetCallback"); + GET_FUNCTION(grFinish, "grFinish"); + GET_FUNCTION(grFlush, "grFlush"); + GET_FUNCTION(grSstWinOpen, "grSstWinOpen"); + GET_FUNCTION(grSstWinClose, "grSstWinClose"); #if 0 /* Not in V3 lib, and not used anyway. */ - GET_FUNCTION(grSetNumPendingBuffers, "grSetNumPendingBuffers", GL_TRUE); + GET_FUNCTION(grSetNumPendingBuffers, "grSetNumPendingBuffers"); #endif - GET_FUNCTION(grSelectContext, "grSelectContext", GL_TRUE); - GET_FUNCTION(grSstOrigin, "grSstOrigin", GL_TRUE); - GET_FUNCTION(grSstSelect, "grSstSelect", GL_TRUE); - GET_FUNCTION(grAlphaBlendFunction, "grAlphaBlendFunction", GL_TRUE); - GET_FUNCTION(grAlphaCombine, "grAlphaCombine", GL_TRUE); - GET_FUNCTION(grAlphaControlsITRGBLighting, "grAlphaControlsITRGBLighting", GL_TRUE); - GET_FUNCTION(grAlphaTestFunction, "grAlphaTestFunction", GL_TRUE); - GET_FUNCTION(grAlphaTestReferenceValue, "grAlphaTestReferenceValue", GL_TRUE); - GET_FUNCTION(grChromakeyMode, "grChromakeyMode", GL_TRUE); - GET_FUNCTION(grChromakeyValue, "grChromakeyValue", GL_TRUE); - GET_FUNCTION(grClipWindow, "grClipWindow", GL_TRUE); - GET_FUNCTION(grColorCombine, "grColorCombine", GL_TRUE); - GET_FUNCTION(grColorMask, "grColorMask", GL_TRUE); - GET_FUNCTION(grCullMode, "grCullMode", GL_TRUE); - GET_FUNCTION(grConstantColorValue, "grConstantColorValue", GL_TRUE); - GET_FUNCTION(grDepthBiasLevel, "grDepthBiasLevel", GL_TRUE); - GET_FUNCTION(grDepthBufferFunction, "grDepthBufferFunction", GL_TRUE); - GET_FUNCTION(grDepthBufferMode, "grDepthBufferMode", GL_TRUE); - GET_FUNCTION(grDepthMask, "grDepthMask", GL_TRUE); - GET_FUNCTION(grDisableAllEffects, "grDisableAllEffects", GL_TRUE); - GET_FUNCTION(grDitherMode, "grDitherMode", GL_TRUE); - GET_FUNCTION(grFogColorValue, "grFogColorValue", GL_TRUE); - GET_FUNCTION(grFogMode, "grFogMode", GL_TRUE); - GET_FUNCTION(grFogTable, "grFogTable", GL_TRUE); - GET_FUNCTION(grLoadGammaTable, "grLoadGammaTable", GL_TRUE); - GET_FUNCTION(grSplash, "grSplash", GL_TRUE); - GET_FUNCTION(grGet, "grGet", GL_TRUE); - GET_FUNCTION(grGetString, "grGetString", GL_TRUE); - GET_FUNCTION(grQueryResolutions, "grQueryResolutions", GL_TRUE); - GET_FUNCTION(grReset, "grReset", GL_TRUE); - GET_FUNCTION(grGetProcAddress, "grGetProcAddress", GL_TRUE); - GET_FUNCTION(grEnable, "grEnable", GL_TRUE); - GET_FUNCTION(grDisable, "grDisable", GL_TRUE); - GET_FUNCTION(grCoordinateSpace, "grCoordinateSpace", GL_TRUE); - GET_FUNCTION(grDepthRange, "grDepthRange", GL_TRUE); -#ifdef __linux__ - GET_FUNCTION(grStippleMode, "grStippleMode", GL_TRUE); - GET_FUNCTION(grStipplePattern, "grStipplePattern", GL_TRUE); -#endif /* __linux__ */ - GET_FUNCTION(grViewport, "grViewport", GL_TRUE); - GET_FUNCTION(grTexCalcMemRequired, "grTexCalcMemRequired", GL_TRUE); - GET_FUNCTION(grTexTextureMemRequired, "grTexTextureMemRequired", GL_TRUE); - GET_FUNCTION(grTexMinAddress, "grTexMinAddress", GL_TRUE); - GET_FUNCTION(grTexMaxAddress, "grTexMaxAddress", GL_TRUE); - GET_FUNCTION(grTexNCCTable, "grTexNCCTable", GL_TRUE); - GET_FUNCTION(grTexSource, "grTexSource", GL_TRUE); - GET_FUNCTION(grTexClampMode, "grTexClampMode", GL_TRUE); - GET_FUNCTION(grTexCombine, "grTexCombine", GL_TRUE); - GET_FUNCTION(grTexDetailControl, "grTexDetailControl", GL_TRUE); - GET_FUNCTION(grTexFilterMode, "grTexFilterMode", GL_TRUE); - GET_FUNCTION(grTexLodBiasValue, "grTexLodBiasValue", GL_TRUE); - GET_FUNCTION(grTexDownloadMipMap, "grTexDownloadMipMap", GL_TRUE); - GET_FUNCTION(grTexDownloadMipMapLevel, "grTexDownloadMipMapLevel", GL_TRUE); - GET_FUNCTION(grTexDownloadMipMapLevelPartial, "grTexDownloadMipMapLevelPartial", GL_TRUE); - GET_FUNCTION(grTexDownloadTable, "grTexDownloadTable", GL_TRUE); - GET_FUNCTION(grTexDownloadTablePartial, "grTexDownloadTablePartial", GL_TRUE); - GET_FUNCTION(grTexMipMapMode, "grTexMipMapMode", GL_TRUE); - GET_FUNCTION(grTexMultibase, "grTexMultibase", GL_TRUE); - GET_FUNCTION(grTexMultibaseAddress, "grTexMultibaseAddress", GL_TRUE); - GET_FUNCTION(grLfbLock, "grLfbLock", GL_TRUE); - GET_FUNCTION(grLfbUnlock, "grLfbUnlock", GL_TRUE); - GET_FUNCTION(grLfbConstantAlpha, "grLfbConstantAlpha", GL_TRUE); - GET_FUNCTION(grLfbConstantDepth, "grLfbConstantDepth", GL_TRUE); - GET_FUNCTION(grLfbWriteColorSwizzle, "grLfbWriteColorSwizzle", GL_TRUE); - GET_FUNCTION(grLfbWriteColorFormat, "grLfbWriteColorFormat", GL_TRUE); - GET_FUNCTION(grLfbWriteRegion, "grLfbWriteRegion", GL_TRUE); - GET_FUNCTION(grLfbReadRegion, "grLfbReadRegion", GL_TRUE); - GET_FUNCTION(grGlideInit, "grGlideInit", GL_TRUE); - GET_FUNCTION(grGlideShutdown, "grGlideShutdown", GL_TRUE); - GET_FUNCTION(grGlideGetState, "grGlideGetState", GL_TRUE); - GET_FUNCTION(grGlideSetState, "grGlideSetState", GL_TRUE); - GET_FUNCTION(grGlideGetVertexLayout, "grGlideGetVertexLayout", GL_TRUE); - GET_FUNCTION(grGlideSetVertexLayout, "grGlideSetVertexLayout", GL_TRUE); + GET_FUNCTION(grSelectContext, "grSelectContext"); + GET_FUNCTION(grSstOrigin, "grSstOrigin"); + GET_FUNCTION(grSstSelect, "grSstSelect"); + GET_FUNCTION(grAlphaBlendFunction, "grAlphaBlendFunction"); + GET_FUNCTION(grAlphaCombine, "grAlphaCombine"); + GET_FUNCTION(grAlphaControlsITRGBLighting, "grAlphaControlsITRGBLighting"); + GET_FUNCTION(grAlphaTestFunction, "grAlphaTestFunction"); + GET_FUNCTION(grAlphaTestReferenceValue, "grAlphaTestReferenceValue"); + GET_FUNCTION(grChromakeyMode, "grChromakeyMode"); + GET_FUNCTION(grChromakeyValue, "grChromakeyValue"); + GET_FUNCTION(grClipWindow, "grClipWindow"); + GET_FUNCTION(grColorCombine, "grColorCombine"); + GET_FUNCTION(grColorMask, "grColorMask"); + GET_FUNCTION(grCullMode, "grCullMode"); + GET_FUNCTION(grConstantColorValue, "grConstantColorValue"); + GET_FUNCTION(grDepthBiasLevel, "grDepthBiasLevel"); + GET_FUNCTION(grDepthBufferFunction, "grDepthBufferFunction"); + GET_FUNCTION(grDepthBufferMode, "grDepthBufferMode"); + GET_FUNCTION(grDepthMask, "grDepthMask"); + GET_FUNCTION(grDisableAllEffects, "grDisableAllEffects"); + GET_FUNCTION(grDitherMode, "grDitherMode"); + GET_FUNCTION(grFogColorValue, "grFogColorValue"); + GET_FUNCTION(grFogMode, "grFogMode"); + GET_FUNCTION(grFogTable, "grFogTable"); + GET_FUNCTION(grLoadGammaTable, "grLoadGammaTable"); + GET_FUNCTION(grSplash, "grSplash"); + GET_FUNCTION(grGet, "grGet"); + GET_FUNCTION(grGetString, "grGetString"); + GET_FUNCTION(grQueryResolutions, "grQueryResolutions"); + GET_FUNCTION(grReset, "grReset"); + GET_FUNCTION(grGetProcAddress, "grGetProcAddress"); + GET_FUNCTION(grEnable, "grEnable"); + GET_FUNCTION(grDisable, "grDisable"); + GET_FUNCTION(grCoordinateSpace, "grCoordinateSpace"); + GET_FUNCTION(grDepthRange, "grDepthRange"); + GET_FUNCTION(grStippleMode, "grStippleMode"); + GET_FUNCTION(grStipplePattern, "grStipplePattern"); + GET_FUNCTION(grViewport, "grViewport"); + GET_FUNCTION(grTexCalcMemRequired, "grTexCalcMemRequired"); + GET_FUNCTION(grTexTextureMemRequired, "grTexTextureMemRequired"); + GET_FUNCTION(grTexMinAddress, "grTexMinAddress"); + GET_FUNCTION(grTexMaxAddress, "grTexMaxAddress"); + GET_FUNCTION(grTexNCCTable, "grTexNCCTable"); + GET_FUNCTION(grTexSource, "grTexSource"); + GET_FUNCTION(grTexClampMode, "grTexClampMode"); + GET_FUNCTION(grTexCombine, "grTexCombine"); + GET_FUNCTION(grTexDetailControl, "grTexDetailControl"); + GET_FUNCTION(grTexFilterMode, "grTexFilterMode"); + GET_FUNCTION(grTexLodBiasValue, "grTexLodBiasValue"); + GET_FUNCTION(grTexDownloadMipMap, "grTexDownloadMipMap"); + GET_FUNCTION(grTexDownloadMipMapLevel, "grTexDownloadMipMapLevel"); + GET_FUNCTION(grTexDownloadMipMapLevelPartial, "grTexDownloadMipMapLevelPartial"); + GET_FUNCTION(grTexDownloadTable, "grTexDownloadTable"); + GET_FUNCTION(grTexDownloadTablePartial, "grTexDownloadTablePartial"); + GET_FUNCTION(grTexMipMapMode, "grTexMipMapMode"); + GET_FUNCTION(grTexMultibase, "grTexMultibase"); + GET_FUNCTION(grTexMultibaseAddress, "grTexMultibaseAddress"); + GET_FUNCTION(grLfbLock, "grLfbLock"); + GET_FUNCTION(grLfbUnlock, "grLfbUnlock"); + GET_FUNCTION(grLfbConstantAlpha, "grLfbConstantAlpha"); + GET_FUNCTION(grLfbConstantDepth, "grLfbConstantDepth"); + GET_FUNCTION(grLfbWriteColorSwizzle, "grLfbWriteColorSwizzle"); + GET_FUNCTION(grLfbWriteColorFormat, "grLfbWriteColorFormat"); + GET_FUNCTION(grLfbWriteRegion, "grLfbWriteRegion"); + GET_FUNCTION(grLfbReadRegion, "grLfbReadRegion"); + GET_FUNCTION(grGlideInit, "grGlideInit"); + GET_FUNCTION(grGlideShutdown, "grGlideShutdown"); + GET_FUNCTION(grGlideGetState, "grGlideGetState"); + GET_FUNCTION(grGlideSetState, "grGlideSetState"); + GET_FUNCTION(grGlideGetVertexLayout, "grGlideGetVertexLayout"); + GET_FUNCTION(grGlideSetVertexLayout, "grGlideSetVertexLayout"); /* Glide utility functions */ - GET_FUNCTION(guFogGenerateExp, "guFogGenerateExp", GL_TRUE); - GET_FUNCTION(guFogGenerateExp2, "guFogGenerateExp2", GL_TRUE); - GET_FUNCTION(guFogGenerateLinear, "guFogGenerateLinear", GL_TRUE); + GET_FUNCTION(guFogGenerateExp, "guFogGenerateExp"); + GET_FUNCTION(guFogGenerateExp2, "guFogGenerateExp2"); + GET_FUNCTION(guFogGenerateLinear, "guFogGenerateLinear"); /* DRI functions */ - GET_FUNCTION(grDRIOpen, "grDRIOpen", GL_TRUE); - GET_FUNCTION(grDRIPosition, "grDRIPosition", GL_TRUE); + GET_FUNCTION(grDRIOpen, "grDRIOpen"); + GET_FUNCTION(grDRIPosition, "grDRIPosition"); /*GET_FUNCTION(grDRILostContext, "grDRILostContext");*/ - GET_FUNCTION(grDRIImportFifo, "grDRIImportFifo", GL_TRUE); - GET_FUNCTION(grDRIInvalidateAll, "grDRIInvalidateAll", GL_TRUE); - GET_FUNCTION(grDRIResetSAREA, "grDRIResetSAREA", GL_TRUE); - GET_FUNCTION(grDRIBufferSwap, "grDRIBufferSwap", GL_TRUE); + GET_FUNCTION(grDRIImportFifo, "grDRIImportFifo"); + GET_FUNCTION(grDRIInvalidateAll, "grDRIInvalidateAll"); + GET_FUNCTION(grDRIResetSAREA, "grDRIResetSAREA"); + GET_FUNCTION(grDRIBufferSwap, "grDRIBufferSwap"); /* * Extension functions: @@ -874,22 +872,22 @@ GLboolean tdfxInitGlide(tdfxContextPtr tmesa) * not found. */ /* PIXEXT extension */ - GET_FUNCTION(grStencilFunc, "grStencilFunc", GL_FALSE); - GET_FUNCTION(grStencilMask, "grStencilMask", GL_FALSE); - GET_FUNCTION(grStencilOp, "grStencilOp", GL_FALSE); - GET_FUNCTION(grBufferClearExt, "grBufferClearExt", GL_FALSE); - GET_FUNCTION(grColorMaskExt, "grColorMaskExt", GL_FALSE); + tmesa->Glide.grStencilFunc = dlsym(libHandle, "grStencilFunc"); + tmesa->Glide.grStencilMask = dlsym(libHandle, "grStencilMask"); + tmesa->Glide.grStencilOp = dlsym(libHandle, "grStencilOp"); + tmesa->Glide.grBufferClearExt = dlsym(libHandle, "grBufferClearExt"); + tmesa->Glide.grColorMaskExt = dlsym(libHandle, "grColorMaskExt"); /* COMBINE extension */ - GET_FUNCTION(grColorCombineExt, "grColorCombineExt", GL_FALSE); - GET_FUNCTION(grTexColorCombineExt, "grTexColorCombineExt", GL_FALSE); - GET_FUNCTION(grAlphaCombineExt, "grAlphaCombineExt", GL_FALSE); - GET_FUNCTION(grTexAlphaCombineExt, "grTexAlphaCombineExt", GL_FALSE); - GET_FUNCTION(grAlphaBlendFunctionExt, "grAlphaBlendFunctionExt", GL_FALSE); - GET_FUNCTION(grConstantColorValueExt, "grConstantColorValueExt", GL_FALSE); + tmesa->Glide.grColorCombineExt = dlsym(libHandle, "grColorCombineExt"); + tmesa->Glide.grTexColorCombineExt = dlsym(libHandle, "grTexColorCombineExt"); + tmesa->Glide.grAlphaCombineExt = dlsym(libHandle, "grAlphaCombineExt"); + tmesa->Glide.grTexAlphaCombineExt = dlsym(libHandle, "grTexAlphaCombineExt"); + tmesa->Glide.grAlphaBlendFunctionExt = dlsym(libHandle, "grAlphaBlendFunctionExt"); + tmesa->Glide.grConstantColorValueExt = dlsym(libHandle, "grConstantColorValueExt"); /* Texus 2 */ - GET_FUNCTION(txImgQuantize, "txImgQuantize", GL_FALSE); - GET_FUNCTION(txImgDequantizeFXT1, "_txImgDequantizeFXT1", GL_FALSE); - GET_FUNCTION(txErrorSetCallback, "txErrorSetCallback", GL_FALSE); + tmesa->Glide.txImgQuantize = dlsym(libHandle, "txImgQuantize"); + tmesa->Glide.txImgDequantizeFXT1 = dlsym(libHandle, "_txImgDequantizeFXT1"); + tmesa->Glide.txErrorSetCallback = dlsym(libHandle, "txErrorSetCallback"); #ifdef DEBUG_TRAP /* wrap the drawing functions so we can trap them */ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c index 976958ca1..826ebdc60 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c,v 1.9 2002/09/10 00:39:39 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c,v 1.10 2002/10/30 12:52:00 alanh Exp $ */ /* * Original rewrite: @@ -256,6 +256,7 @@ void tdfxDDInitDriverFuncs( GLcontext *ctx ) ctx->Driver.GetString = tdfxDDGetString; ctx->Driver.GetBufferSize = tdfxDDGetBufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; ctx->Driver.Error = NULL; /* Pixel path fallbacks. @@ -265,7 +266,6 @@ void tdfxDDInitDriverFuncs( GLcontext *ctx ) ctx->Driver.CopyPixels = _swrast_CopyPixels; ctx->Driver.DrawPixels = _swrast_DrawPixels; ctx->Driver.ReadPixels = _swrast_ReadPixels; - ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; /* Accelerated paths */ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c index 2790caa15..450b1626a 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c,v 1.4 2002/02/22 21:45:03 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c,v 1.5 2002/12/16 16:19:00 dawes Exp $ */ /* * Original rewrite: @@ -49,7 +49,7 @@ void tdfxGetLock( tdfxContextPtr fxMesa ) __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) + fxMesa->fxScreen->sarea_priv_offset); - int stamp = dPriv->lastStamp; + unsigned int stamp = dPriv->lastStamp; drmGetLock( fxMesa->driFd, fxMesa->hHWContext, 0 ); diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c index 8af85a608..721d9098a 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c,v 1.6 2002/04/12 21:58:36 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */ /* * Original rewrite: @@ -32,7 +32,7 @@ * Authors: * Gareth Hughes <gareth@valinux.com> * Brian Paul <brianp@valinux.com> - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ @@ -572,30 +572,28 @@ GetFbParams(tdfxContextPtr fxMesa, * * Recall that x and y are screen coordinates. */ +#define GET_FB_DATA(ReadParamsp, type, x, y) \ + (((x) < (ReadParamsp)->firstWrappedX) \ + ? (((type *)((ReadParamsp)->lfbPtr)) \ + [(y) * ((ReadParamsp)->LFBStrideInElts) \ + + (x)]) \ + : (((type *)((ReadParamsp)->lfbWrapPtr)) \ + [((y)) * ((ReadParamsp)->LFBStrideInElts) \ + + ((x) - (ReadParamsp)->firstWrappedX)])) #define GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \ - ((*(type **)(&(ReadParamsp)->lfbPtr)) \ + (((type *)((ReadParamsp)->lfbPtr)) \ [(y) * ((ReadParamsp)->LFBStrideInElts) \ + (x)]) #define GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) \ - ((*(type **)(&(ReadParamsp)->lfbWrapPtr)) \ - [(y) * ((ReadParamsp)->LFBStrideInElts) \ + (((type *)((ReadParamsp)->lfbWrapPtr)) \ + [((y)) * ((ReadParamsp)->LFBStrideInElts) \ + ((x) - (ReadParamsp)->firstWrappedX)]) -#define GET_FB_DATA(ReadParamsp, type, x, y) \ - (((x) < (ReadParamsp)->firstWrappedX) ? \ - GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) : \ - GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y)) - -#define PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value) \ +#define PUT_FB_DATA(ReadParamsp, type, x, y, value) \ + (GET_FB_DATA(ReadParamsp, type, x, y) = (type)(value)) +#define PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value) \ (GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) = (type)(value)) -#define PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value) \ +#define PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value) \ (GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) = (type)(value)) -#define PUT_FB_DATA(ReadParamsp, type, x, y, value) \ - do { \ - if ((x) < (ReadParamsp)->firstWrappedX) \ - PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value); \ - else \ - PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value); \ - } while(0) static void tdfxDDWriteDepthSpan(GLcontext * ctx, diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c index f5fca6a66..2a3532cca 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c,v 1.6 2002/09/11 19:49:08 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */ /* * Original rewrite: @@ -32,7 +32,7 @@ * Authors: * Gareth Hughes <gareth@valinux.com> * Brian Paul <brianp@valinux.com> - * Keith Whitwell <keithw@valinux.com> (port to 3.5) + * Keith Whitwell <keith@tungstengraphics.com> (port to 3.5) * */ @@ -1008,25 +1008,25 @@ static void tdfxDDSetDrawBuffer( GLcontext *ctx, GLenum mode ) switch( mode) { case GL_FRONT_LEFT: - fxMesa->DrawBuffer = GR_BUFFER_FRONTBUFFER; + fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_FRONTBUFFER; fxMesa->new_state |= TDFX_NEW_RENDER; FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE ); - return; + break; case GL_BACK_LEFT: - fxMesa->DrawBuffer = GR_BUFFER_BACKBUFFER; + fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_BACKBUFFER; fxMesa->new_state |= TDFX_NEW_RENDER; FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE ); - return; + break; case GL_NONE: FX_grColorMaskv( ctx, false4 ); FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE ); - return; + break; default: FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; + break; } } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c index d9236533f..bffee9606 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c @@ -23,7 +23,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c,v 1.5 2002/02/26 23:37:36 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c,v 1.7 2002/11/05 17:46:10 tsi Exp $ */ /* * Original rewrite: @@ -565,12 +565,12 @@ tdfxDDTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj) /**** NEW TEXTURE IMAGE FUNCTIONS ****/ /**********************************************************************/ -#define TX_DITHER_NONE 0x00000000 - #if 000 static FxBool TexusFatalError = FXFALSE; static FxBool TexusError = FXFALSE; +#define TX_DITHER_NONE 0x00000000 + static void fxTexusError(const char *string, FxBool fatal) { @@ -975,7 +975,7 @@ tdfxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level, 0, /* dstImageStride */ format, type, pixels, packing); assert(!texImage->Data); - texImage->Data = MALLOC(mml->width * mml->height * texelBytes); + texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); FREE(tempImage); @@ -991,7 +991,7 @@ tdfxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level, else { /* no rescaling needed */ assert(!texImage->Data); - texImage->Data = MALLOC(mml->width * mml->height * texelBytes); + texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c index 4c28b2d2d..44b4c32de 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c @@ -23,10 +23,10 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c,v 1.3 2002/02/22 21:45:04 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c,v 1.4 2002/10/30 12:52:01 alanh Exp $ */ /* Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #include <stdio.h> @@ -901,7 +901,7 @@ static void tdfxFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, int i; for (i = 2 ; i < n ; i++) { - fxMesa->Glide.grDrawTriangle( start, VERT(elts[i-1]), VERT(elts[i]) ); + fxMesa->Glide.grDrawTriangle( VERT(elts[i-1]), VERT(elts[i]), start ); } } @@ -1167,24 +1167,6 @@ static void tdfxRenderFinish( GLcontext *ctx ) } - -/* - * These functions are used when we're software rendering, and - * lock/unlock the hardware (for span reading/writing). - */ -static void tdfxSwSetupStart( GLcontext *ctx ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - LOCK_HARDWARE(fxMesa); -} - -static void tdfxSwSetupFinish( GLcontext *ctx ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - UNLOCK_HARDWARE(fxMesa); -} - - /**********************************************************************/ /* Manage total rasterization fallbacks */ /**********************************************************************/ @@ -1257,7 +1239,6 @@ void tdfxFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) void tdfxDDInitTriFuncs( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - SScontext *swsetup = SWSETUP_CONTEXT(ctx); tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); static int firsttime = 1; @@ -1276,9 +1257,5 @@ void tdfxDDInitTriFuncs( GLcontext *ctx ) tnl->Driver.Render.BuildVertices = tdfxBuildVertices; tnl->Driver.Render.Multipass = NULL; - - swsetup->Driver.Start = tdfxSwSetupStart; - swsetup->Driver.Finish = tdfxSwSetupFinish; - (void) tdfx_print_vertex; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h index 6f9216627..57e5d9b0a 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h @@ -26,10 +26,10 @@ /* * Authors: - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h,v 1.4 2002/02/27 00:51:15 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.h,v 1.5 2002/10/30 12:52:01 alanh Exp $ */ #ifndef TDFX_TRIS_INC #define TDFX_TRIS_INC diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c index 492d41d06..5f8fb5fd7 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c @@ -22,7 +22,7 @@ * * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c,v 1.2 2002/02/22 21:45:04 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c,v 1.3 2002/10/30 12:52:01 alanh Exp $ */ #include "glheader.h" #include "mtypes.h" @@ -303,9 +303,9 @@ void tdfxChooseVertexState( GLcontext *ctx ) tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); GLuint ind = TDFX_XYZ_BIT|TDFX_RGBA_BIT; - if (ctx->Texture._ReallyEnabled & 0xf0) + if (ctx->Texture._ReallyEnabled & TEXTURE1_ANY) ind |= TDFX_W_BIT|TDFX_TEX1_BIT|TDFX_TEX0_BIT; - else if (ctx->Texture._ReallyEnabled & 0xf) + else if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY) ind |= TDFX_W_BIT|TDFX_TEX0_BIT; else if (ctx->Fog.Enabled) ind |= TDFX_W_BIT; diff --git a/xc/lib/GL/mesa/src/math/Imakefile b/xc/lib/GL/mesa/src/math/Imakefile index 83dd51e0c..c4e8b21f6 100644 --- a/xc/lib/GL/mesa/src/math/Imakefile +++ b/xc/lib/GL/mesa/src/math/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/math/Imakefile,v 1.5 2002/02/28 17:52:16 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/math/Imakefile,v 1.9 2002/11/25 14:04:52 eich Exp $ #include <Threads.tmpl> @@ -12,7 +12,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/math/Imakefile,v 1.5 2002/02/28 17:52:16 dawe * driver modules. */ -#if GlxDriverUsesMesa || GlxBuiltInXMesa || BuildOSMesaLib +#if BuildOSMesaLib || (BuildXF86DRI && (GlxDriverUsesMesa || GlxBuiltInXMesa)) #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) #define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) #define DoExtraLib SharedLibGlx @@ -42,7 +42,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL -I$(INCLUDESRC)/GL -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri #endif -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm ASM_DIR = X86 ASM_SRCS = ASM_OBJS = diff --git a/xc/lib/GL/mesa/src/math/Imakefile.inc b/xc/lib/GL/mesa/src/math/Imakefile.inc index 75104fbe0..73bd3312b 100644 --- a/xc/lib/GL/mesa/src/math/Imakefile.inc +++ b/xc/lib/GL/mesa/src/math/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/math/Imakefile.inc,v 1.1 2002/02/23 00:45:52 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/math/Imakefile.inc,v 1.2 2002/11/14 21:01:17 tsi Exp $ #ifndef MesaMathBuildDir #define MesaMathBuildDir $(GLXLIBSRC)/mesa/src/math/ @@ -41,7 +41,7 @@ LinkSourceFile(m_xform.c, $(MESASRCDIR)/src/math) $(MESAMATHBUILDDIR)m_vertices.o \ $(MESAMATHBUILDDIR)m_xform.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_MATH_UOBJS = $(MESAMATHBUILDDIR)unshared/m_debug_clip.o \ $(MESAMATHBUILDDIR)unshared/m_debug_norm.o \ $(MESAMATHBUILDDIR)unshared/m_debug_xform.o \ diff --git a/xc/lib/GL/mesa/src/swrast/Imakefile b/xc/lib/GL/mesa/src/swrast/Imakefile index aca5cbc57..15caa185a 100644 --- a/xc/lib/GL/mesa/src/swrast/Imakefile +++ b/xc/lib/GL/mesa/src/swrast/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/swrast/Imakefile,v 1.5 2002/02/28 17:52:17 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/swrast/Imakefile,v 1.9 2002/11/25 14:04:52 eich Exp $ #include <Threads.tmpl> @@ -12,7 +12,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/swrast/Imakefile,v 1.5 2002/02/28 17:52:17 da * driver modules. */ -#if GlxDriverUsesMesa || GlxBuiltInXMesa || BuildOSMesaLib +#if BuildOSMesaLib || (BuildXF86DRI && (GlxDriverUsesMesa || GlxBuiltInXMesa)) #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) #define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) #define DoExtraLib SharedLibGlx @@ -42,7 +42,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL -I$(INCLUDESRC)/GL -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri #endif -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm ASM_DIR = X86 ASM_SRCS = ASM_OBJS = diff --git a/xc/lib/GL/mesa/src/swrast/Imakefile.inc b/xc/lib/GL/mesa/src/swrast/Imakefile.inc index 6ea372416..49c489a80 100644 --- a/xc/lib/GL/mesa/src/swrast/Imakefile.inc +++ b/xc/lib/GL/mesa/src/swrast/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/swrast/Imakefile.inc,v 1.1 2002/02/23 00:45:52 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/swrast/Imakefile.inc,v 1.2 2002/11/14 21:01:17 tsi Exp $ #ifndef MesaSwrastBuildDir #define MesaSwrastBuildDir $(GLXLIBSRC)/mesa/src/swrast/ @@ -101,7 +101,7 @@ LinkSourceFile(s_zoom.c, $(MESASRCDIR)/src/swrast) $(MESASWRASTBUILDDIR)s_triangle.o \ $(MESASWRASTBUILDDIR)s_zoom.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_SWRAST_UOBJS = $(MESASWRASTBUILDDIR)unshared/s_aaline.o \ $(MESASWRASTBUILDDIR)unshared/s_aatriangle.o \ $(MESASWRASTBUILDDIR)unshared/s_accum.o \ diff --git a/xc/lib/GL/mesa/src/swrast_setup/Imakefile b/xc/lib/GL/mesa/src/swrast_setup/Imakefile index 9fe6c3886..d77cea578 100644 --- a/xc/lib/GL/mesa/src/swrast_setup/Imakefile +++ b/xc/lib/GL/mesa/src/swrast_setup/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/swrast_setup/Imakefile,v 1.5 2002/02/28 17:52:17 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/swrast_setup/Imakefile,v 1.9 2002/11/25 14:04:52 eich Exp $ #include <Threads.tmpl> @@ -12,7 +12,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/swrast_setup/Imakefile,v 1.5 2002/02/28 17:52 * driver modules. */ -#if GlxDriverUsesMesa || GlxBuiltInXMesa || BuildOSMesaLib +#if BuildOSMesaLib || (BuildXF86DRI && (GlxDriverUsesMesa || GlxBuiltInXMesa)) #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) #define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) #define DoExtraLib SharedLibGlx @@ -41,7 +41,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL -I$(INCLUDESRC)/GL -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri #endif -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm ASM_DIR = X86 ASM_SRCS = ASM_OBJS = diff --git a/xc/lib/GL/mesa/src/swrast_setup/Imakefile.inc b/xc/lib/GL/mesa/src/swrast_setup/Imakefile.inc index f1bab9061..ac68c55cc 100644 --- a/xc/lib/GL/mesa/src/swrast_setup/Imakefile.inc +++ b/xc/lib/GL/mesa/src/swrast_setup/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/swrast_setup/Imakefile.inc,v 1.1 2002/02/23 00:45:52 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/swrast_setup/Imakefile.inc,v 1.2 2002/11/14 21:01:17 tsi Exp $ #ifndef MesaSwrastSetupBuildDir #define MesaSwrastSetupBuildDir $(GLXLIBSRC)/mesa/src/swrast_setup/ @@ -20,7 +20,7 @@ LinkSourceFile(ss_vb.c, $(MESASRCDIR)/src/swrast_setup) $(MESASWRSETUPDIR)ss_triangle.o \ $(MESASWRSETUPDIR)ss_vb.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_SWR_SETUP_UOBJS = $(MESASWRSETUPDIR)unshared/ss_context.o \ $(MESASWRSETUPDIR)unshared/ss_triangle.o \ $(MESASWRSETUPDIR)unshared/ss_vb.o diff --git a/xc/lib/GL/mesa/src/tnl/Imakefile b/xc/lib/GL/mesa/src/tnl/Imakefile index f3cd2ca48..15e76f4b1 100644 --- a/xc/lib/GL/mesa/src/tnl/Imakefile +++ b/xc/lib/GL/mesa/src/tnl/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/tnl/Imakefile,v 1.5 2002/02/28 17:52:17 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/tnl/Imakefile,v 1.9 2002/11/25 14:04:52 eich Exp $ #include <Threads.tmpl> @@ -12,7 +12,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/tnl/Imakefile,v 1.5 2002/02/28 17:52:17 dawes * driver modules. */ -#if GlxDriverUsesMesa || GlxBuiltInXMesa || BuildOSMesaLib +#if BuildOSMesaLib || (BuildXF86DRI && (GlxDriverUsesMesa || GlxBuiltInXMesa)) #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) #define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) #define DoExtraLib SharedLibGlx @@ -42,7 +42,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL -I$(INCLUDESRC)/GL -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri #endif -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm ASM_DIR = X86 ASM_SRCS = ASM_OBJS = diff --git a/xc/lib/GL/mesa/src/tnl/Imakefile.inc b/xc/lib/GL/mesa/src/tnl/Imakefile.inc index 87b6dafcf..9331da0a2 100644 --- a/xc/lib/GL/mesa/src/tnl/Imakefile.inc +++ b/xc/lib/GL/mesa/src/tnl/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/tnl/Imakefile.inc,v 1.1 2002/02/23 00:45:53 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/tnl/Imakefile.inc,v 1.2 2002/11/14 21:01:17 tsi Exp $ #ifndef MesaTnlBuildDir #define MesaTnlBuildDir $(GLXLIBSRC)/mesa/src/tnl/ @@ -74,7 +74,7 @@ LinkSourceFile(t_vb_vertex.c, $(MESASRCDIR)/src/tnl) $(MESATNLBUILDDIR)t_vb_texmat.o \ $(MESATNLBUILDDIR)t_vb_vertex.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_TNL_UOBJS = $(MESATNLBUILDDIR)unshared/t_array_api.o \ $(MESATNLBUILDDIR)unshared/t_array_import.o \ $(MESATNLBUILDDIR)unshared/t_context.o \ diff --git a/xc/lib/GL/mesa/src/tnl_dd/Imakefile b/xc/lib/GL/mesa/src/tnl_dd/Imakefile index b0143b3a7..1fb94f9c8 100644 --- a/xc/lib/GL/mesa/src/tnl_dd/Imakefile +++ b/xc/lib/GL/mesa/src/tnl_dd/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/tnl_dd/Imakefile,v 1.4 2002/02/28 17:52:17 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/tnl_dd/Imakefile,v 1.7 2002/11/25 14:04:53 eich Exp $ #include <Threads.tmpl> @@ -52,7 +52,7 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src \ SRCS = $(MESA_TNL_DD_SRCS) OBJS = $(MESA_TNL_DD_OBJS) -#ifdef i386Architecture +#if defined(i386Architecture) && MesaUseX86Asm ASM_SRCS = ASM_OBJS = #if MesaUseMMX diff --git a/xc/lib/GL/mesa/src/tnl_dd/Imakefile.inc b/xc/lib/GL/mesa/src/tnl_dd/Imakefile.inc index e6af80713..c55dd846e 100644 --- a/xc/lib/GL/mesa/src/tnl_dd/Imakefile.inc +++ b/xc/lib/GL/mesa/src/tnl_dd/Imakefile.inc @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/tnl_dd/Imakefile.inc,v 1.1 2002/02/23 00:45:53 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/tnl_dd/Imakefile.inc,v 1.2 2002/11/14 21:01:18 tsi Exp $ #ifndef MesaTnlDdBuildDir #define MesaTnlDdBuildDir $(GLXLIBSRC)/mesa/src/tnl_dd/ @@ -20,7 +20,7 @@ LinkSourceFile(t_dd_vb.c, $(MESASRCDIR)/src/tnl_dd) $(MESATNLDDBUILDDIR)t_dd.o \ $(MESATNLDDBUILDDIR)t_dd_vb.o -#if DoSharedLib +#if defined(DoSharedLib) && DoSharedLib MESA_TNL_DD_UOBJS = $(MESATNLDDBUILDDIR)unshared/t_array_api.o \ $(MESATNLDDBUILDDIR)unshared/t_dd.o \ $(MESATNLDDBUILDDIR)unshared/t_dd_vb.o |