diff options
155 files changed, 12965 insertions, 9747 deletions
diff --git a/xc/config/cf/host.def b/xc/config/cf/host.def index ef72a80d4..67b924bbf 100644 --- a/xc/config/cf/host.def +++ b/xc/config/cf/host.def @@ -1,13 +1,26 @@ +#define ProjectRoot /mnt/src/XF40 #define DefaultGcc2i386Opt -O2 #define LibraryCDebugFlags -O2 #define BuildServersOnly YES -#define XF86CardDrivers vga i810 tdfx +#define XF86CardDrivers vga tdfx i810 mga #define LinuxDistribution LinuxRedHat -#define DefaultCCOptions -ansi GccWarningOptions -pipe +#define GccWarningOptions -Wall -Wpointer-arith -Wstrict-prototypes \ + -Wmissing-prototypes -Wmissing-declarations \ + -Wnested-externs +#define DefaultCCOptions -ansi GccWarningOptions -pipe -g +#define NormalLibGlx NO + #define BuildXF86DRI YES #define HasGlide3 YES + /* Optionally turn these on for debugging */ /* #define GlxBuiltInTdfx YES */ +/* #define GlxBuiltInI810 YES */ +/* #define GlxBuiltInMga YES */ /* #define DoLoadableServer NO */ #define SharedLibFont NO + +#define XnestServer NO +#define XVirtualFramebufferServer NO +#define XprtServer NO diff --git a/xc/extras/Mesa/src/dlist.c b/xc/extras/Mesa/src/dlist.c index cdb1a5ac3..b2cc13787 100644 --- a/xc/extras/Mesa/src/dlist.c +++ b/xc/extras/Mesa/src/dlist.c @@ -4808,6 +4808,7 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list ) case OPCODE_END_OF_LIST: fprintf(f,"END-LIST %u\n", list); done = GL_TRUE; + gl_print_cassette( (struct immediate *) n[1].data ); break; default: if (opcode < 0 || opcode > OPCODE_END_OF_LIST) { diff --git a/xc/extras/Mesa/src/fog.c b/xc/extras/Mesa/src/fog.c index bac41cb1d..e35906c8f 100644 --- a/xc/extras/Mesa/src/fog.c +++ b/xc/extras/Mesa/src/fog.c @@ -35,6 +35,7 @@ #include "types.h" #include "xform.h" #endif +#include "xform.h" diff --git a/xc/extras/Mesa/src/fog.h b/xc/extras/Mesa/src/fog.h index 9a58f54a1..59d84517b 100644 --- a/xc/extras/Mesa/src/fog.h +++ b/xc/extras/Mesa/src/fog.h @@ -65,4 +65,6 @@ extern void _mesa_init_fog( void ); +extern struct gl_pipeline_stage gl_fog_coord_stage; + #endif diff --git a/xc/extras/Mesa/src/mmath.h b/xc/extras/Mesa/src/mmath.h index 6048eb186..30a300cdb 100644 --- a/xc/extras/Mesa/src/mmath.h +++ b/xc/extras/Mesa/src/mmath.h @@ -22,7 +22,7 @@ * 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. */ - +/* $XFree86: xc/extras/Mesa/src/mmath.h,v 1.4 2000/03/03 18:30:08 tsi Exp $ */ /* * Faster arithmetic functions. If the FAST_MATH preprocessor symbol is @@ -47,7 +47,10 @@ * In the worst case, we force the compiler to use a memory access to * truncate the float, by specifying the 'volatile' keyword. */ -#if defined(__linux__) && defined(__i386__) +#if defined(__linux__) && defined(__i386__) && !defined(IN_MODULE) +/* + * A libc interface is needed for this... + */ #include <fpu_control.h> #if !defined(_FPU_SETCW) diff --git a/xc/extras/Mesa/src/types.h b/xc/extras/Mesa/src/types.h index dc1b5e103..e96740e78 100644 --- a/xc/extras/Mesa/src/types.h +++ b/xc/extras/Mesa/src/types.h @@ -1345,8 +1345,6 @@ struct gl_extensions { #define DD_STENCIL 0x1000000 #define DD_CLIP_FOG_COORD 0x2000000 - - #define DD_SW_SETUP (DD_TRI_CULL| \ DD_TRI_CULL_FRONT_BACK| \ DD_TRI_OFFSET| \ diff --git a/xc/extras/Mesa/src/varray.c b/xc/extras/Mesa/src/varray.c index dc758594a..786793da7 100644 --- a/xc/extras/Mesa/src/varray.c +++ b/xc/extras/Mesa/src/varray.c @@ -682,6 +682,7 @@ _mesa_DrawArrays(GLenum mode, GLint start, GLsizei count) VB->Primitive[VB->CopyStart] = mode; ctx->Array.Flag[count] |= VERT_END_VB; + ctx->Array.Flag[count] |= VERT_END_VB; /* Transform and render. */ gl_run_pipeline( VB ); diff --git a/xc/include/GL/glx.h b/xc/include/GL/glx.h index 367ce0a51..0254b6064 100644 --- a/xc/include/GL/glx.h +++ b/xc/include/GL/glx.h @@ -101,7 +101,7 @@ extern GLXDrawable glXGetCurrentDrawableEXT (void); extern GLXContext glXImportContextEXT (Display *dpy, GLXContextID contextID); extern void glXFreeContextEXT (Display *dpy, GLXContext ctx); extern int glXQueryContextInfoEXT (Display *dpy, GLXContext ctx, int attribute, int *value); -extern void (*glXGetProcAddressARB(const GLubyte *procName))(); +extern void (*glXGetProcAddressARB(const GLubyte *procName))( void ); diff --git a/xc/lib/GL/Imakefile b/xc/lib/GL/Imakefile index a185089e4..c3dfb015d 100644 --- a/xc/lib/GL/Imakefile +++ b/xc/lib/GL/Imakefile @@ -27,6 +27,14 @@ DependSubdirs($(SUBDIRS)) LIBNAME = GL SOREV = $(SOGLREV) +#if 0 + LOWSRC = lowpc.c + LOWOBJ = lowpc.o + + HISRC = highpc.c + HIOBJ = highpc.o +#endif + GLXOBJS = glx/?*.o GLXUOBJS = glx/unshared/?*.o GLXDOBJS = glx/debugger/?*.o @@ -98,6 +106,87 @@ DRIMESADONES = mesa/dri/DONE DRVDONES = $(TDFXDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) REQUIREDLIBS += -lglide3x + +#elif GlxBuiltInI810 + + DRMOBJS = dri/drm/?*.o + DRMUOBJS = dri/drm/unshared/?*.o + DRMDOBJS = dri/drm/debugger/?*.o + DRMPOBJS = dri/drm/profiled/?*.o + DRMDONES = dri/drm/DONE + + I810OBJS = mesa/src/drv/i810/?*.o + I810UOBJS = mesa/src/drv/i810/unshared/?*.o + I810DOBJS = mesa/src/drv/i810/debugger/?*.o + I810POBJS = mesa/src/drv/i810/profiled/?*.o + I810DONES = mesa/src/drv/i810/DONE + + COMMONOBJS = mesa/src/drv/common/?*.o + COMMONUOBJS = mesa/src/drv/common/unshared/?*.o + COMMONDOBJS = mesa/src/drv/common/debugger/?*.o + COMMONPOBJS = mesa/src/drv/common/profiled/?*.o + COMMONDONES = mesa/src/drv/common/DONE + + MESAOBJS = mesa/src/?*.o mesa/src/X86/?*.o + MESAUOBJS = mesa/src/unshared/?*.o mesa/src/X86/unshared/?*.o + MESADOBJS = mesa/src/debugger/?*.o mesa/src/X86/debugger/?*.o + MESAPOBJS = mesa/src/profiled/?*.o mesa/src/X86/profiled/?*.o + MESADONES = mesa/src/DONE mesa/src/X86/DONE + + DRIMESAOBJS = mesa/dri/?*.o +DRIMESAUOBJS = mesa/dri/unshared/?*.o +DRIMESADOBJS = mesa/dri/debugger/?*.o +DRIMESAPOBJS = mesa/dri/profiled/?*.o +DRIMESADONES = mesa/dri/DONE + + DRVOBJS = $(I810OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVUOBJS = $(I810UOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) + DRVDOBJS = $(I810DOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) + DRVPOBJS = $(I810POBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) + DRVDONES = $(I810DONES) $(COMMONDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) + + + + +#elif GlxBuiltInMga + + DRMOBJS = dri/drm/?*.o + DRMUOBJS = dri/drm/unshared/?*.o + DRMDOBJS = dri/drm/debugger/?*.o + DRMPOBJS = dri/drm/profiled/?*.o + DRMDONES = dri/drm/DONE + + MGAOBJS = mesa/src/drv/mga/?*.o + MGAUOBJS = mesa/src/drv/mga/unshared/?*.o + MGADOBJS = mesa/src/drv/mga/debugger/?*.o + MGAPOBJS = mesa/src/drv/mga/profiled/?*.o + MGADONES = mesa/src/drv/mga/DONE + + COMMONOBJS = mesa/src/drv/common/?*.o + COMMONUOBJS = mesa/src/drv/common/unshared/?*.o + COMMONDOBJS = mesa/src/drv/common/debugger/?*.o + COMMONPOBJS = mesa/src/drv/common/profiled/?*.o + COMMONDONES = mesa/src/drv/common/DONE + + MESAOBJS = mesa/src/?*.o mesa/src/X86/?*.o + MESAUOBJS = mesa/src/unshared/?*.o mesa/src/X86/unshared/?*.o + MESADOBJS = mesa/src/debugger/?*.o mesa/src/X86/debugger/?*.o + MESAPOBJS = mesa/src/profiled/?*.o mesa/src/X86/profiled/?*.o + MESADONES = mesa/src/DONE mesa/src/X86/DONE + + DRIMESAOBJS = mesa/dri/?*.o +DRIMESAUOBJS = mesa/dri/unshared/?*.o +DRIMESADOBJS = mesa/dri/debugger/?*.o +DRIMESAPOBJS = mesa/dri/profiled/?*.o +DRIMESADONES = mesa/dri/DONE + + DRVOBJS = $(MGAOBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVUOBJS = $(MGAUOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) + DRVDOBJS = $(MGADOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) + DRVPOBJS = $(MGAPOBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) + DRVDONES = $(MGADONES) $(COMMONDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) + + #elif GlxBuiltInMesa #ifndef GlxDriverUsesMesa DRVOBJS = mesa/src/?*.o mesa/src/X/?*.o @@ -113,17 +202,26 @@ DRIMESADONES = mesa/dri/DONE #ifdef OS2Architecture OBJS = $(LIBNAME).a #else - OBJS = $(GLXOBJS) $(DRIOBJS) $(DRVOBJS) + OBJS = $(LOWOBJ) $(GLXOBJS) $(DRIOBJS) $(DRVOBJS) $(HIOBJ) #endif #if HasSharedLibraries +#if 1 UOBJS = $(GLXUOBJS) $(DRIUOBJS) $(DRVUOBJS) #else UOBJS = $(OBJS) #endif +#else + UOBJS = $(OBJS) +#endif DOBJS = $(GLXDOBJS) $(DRIDOBJS) $(DRVDOBJS) POBJS = $(GLXPOBJS) $(DRIPOBJS) $(DRVPOBJS) DONES = $(GLXDONES) $(DRIDONES) $(DRVDONES) +#if 0 +SubdirLibraryRule(highpc.o lowpc.o) +NormalLintTarget(highpc.c lowpc.c) +#endif + #if LocalThreads THREADOBJS = $(THREADS_LIBS) #endif diff --git a/xc/lib/GL/dri/XF86dri.c b/xc/lib/GL/dri/XF86dri.c index 77654ac76..cd485680b 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.2 1999/06/27 14:07:22 dawes Exp $ */ +/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.5 2000/02/23 04:46:33 martin Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -31,7 +31,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Kevin E. Martin <kevin@precisioninsight.com> * Jens Owen <jens@precisioninsight.com> * - * $PI: xc/lib/GL/dri/XF86dri.c,v 1.14 1999/06/16 20:08:33 faith Exp $ */ /* THIS IS NOT AN X CONSORTIUM STANDARD */ @@ -385,7 +384,11 @@ Bool XF86DRIDestroyDrawable(dpy, screen, drawable) } Bool XF86DRIGetDrawableInfo(dpy, screen, drawable, - index, stamp, X, Y, W, H, numClipRects, pClipRects) + index, stamp, X, Y, W, H, + numClipRects, pClipRects, + backX, backY, + numBackClipRects, pBackClipRects + ) Display* dpy; int screen; Drawable drawable; @@ -397,10 +400,15 @@ Bool XF86DRIGetDrawableInfo(dpy, screen, drawable, int* H; int* numClipRects; XF86DRIClipRectPtr* pClipRects; + int* backX; + int* backY; + int* numBackClipRects; + XF86DRIClipRectPtr* pBackClipRects; { XExtDisplayInfo *info = find_display (dpy); xXF86DRIGetDrawableInfoReply rep; xXF86DRIGetDrawableInfoReq *req; + int total_rects; XF86DRICheckExtension (dpy, info, False); @@ -410,7 +418,9 @@ Bool XF86DRIGetDrawableInfo(dpy, screen, drawable, req->driReqType = X_XF86DRIGetDrawableInfo; req->screen = screen; req->drawable = drawable; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + + if (!_XReply(dpy, (xReply *)&rep, 1, xFalse)) + { UnlockDisplay(dpy); SyncHandle(); return False; @@ -422,16 +432,41 @@ Bool XF86DRIGetDrawableInfo(dpy, screen, drawable, *W = (int)rep.drawableWidth; *H = (int)rep.drawableHeight; *numClipRects = rep.numClipRects; + total_rects = *numClipRects; + + *backX = rep.backX; + *backY = rep.backY; + *numBackClipRects = rep.numBackClipRects; + total_rects += *numBackClipRects; + + if (rep.length != (SIZEOF(xXF86DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply) + + total_rects * sizeof(XF86DRIClipRectRec))) { + _XEatData(dpy, rep.length); + return False; + } + - if (rep.length) { - if (!(*pClipRects = (XF86DRIClipRectPtr)Xcalloc(rep.length, 1))) { - _XEatData(dpy, rep.length); - return False; - } - _XRead32(dpy, *pClipRects, rep.length); + if (*numClipRects) { + int len = sizeof(XF86DRIClipRectRec) * (*numClipRects); + + *pClipRects = (XF86DRIClipRectPtr)Xcalloc(len, 1); + if (*pClipRects) + _XRead32(dpy, *pClipRects, len); } else { *pClipRects = NULL; } + + if (*numBackClipRects) { + int len = sizeof(XF86DRIClipRectRec) * (*numBackClipRects); + + *pBackClipRects = (XF86DRIClipRectPtr)Xcalloc(len, 1); + if (*pBackClipRects) + _XRead32(dpy, *pBackClipRects, len); + } else { + *pBackClipRects = NULL; + } + UnlockDisplay(dpy); SyncHandle(); return True; diff --git a/xc/lib/GL/dri/drm/Imakefile b/xc/lib/GL/dri/drm/Imakefile index 18619461b..4fd493e1d 100644 --- a/xc/lib/GL/dri/drm/Imakefile +++ b/xc/lib/GL/dri/drm/Imakefile @@ -25,6 +25,8 @@ LinkSourceFile(xf86drmRandom.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) LinkSourceFile(xf86drmSL.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) LinkSourceFile(xf86drm.h,$(XF86OSSRC)) LinkSourceFile(drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel) +LinkSourceFile(mga_drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel) +LinkSourceFile(i810_drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel) #include <Library.tmpl> diff --git a/xc/lib/GL/dri/xf86dri.h b/xc/lib/GL/dri/xf86dri.h index 8e234fcb2..8b7cd3aa2 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.2 1999/06/27 14:07:24 dawes Exp $ */ +/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.5 2000/02/23 04:46:34 martin Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -32,7 +32,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Jens Owen <jens@precisioninsight.com> * Rickard E. Faith <faith@precisioninsight.com> * - * $PI: xc/lib/GL/dri/xf86dri.h,v 1.12 1999/06/16 20:08:34 faith Exp $ */ #ifndef _XF86DRI_H_ @@ -60,6 +59,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define XF86DRIOperationNotSupported 1 #define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) +/* Warning : Do not change XF86DRIClipRect without changing the kernel + * structure! */ typedef struct _XF86DRIClipRect { unsigned short x1; /* Upper left: inclusive */ unsigned short y1; @@ -178,7 +179,11 @@ Bool XF86DRIGetDrawableInfo( int* /* W */, int* /* H */, int* /* numClipRects */, - XF86DRIClipRectPtr* /* pClipRects */ + XF86DRIClipRectPtr*,/* pClipRects */ + int* /* backX */, + int* /* backY */, + int* /* numBackClipRects */, + XF86DRIClipRectPtr* /* pBackClipRects */ #endif ); diff --git a/xc/lib/GL/dri/xf86dristr.h b/xc/lib/GL/dri/xf86dristr.h index 32969834c..dd246bac8 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.2 1999/06/27 14:07:24 dawes Exp $ */ +/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.5 2000/02/23 04:46:34 martin Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -31,7 +31,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Kevin E. Martin <kevin@precisioninsight.com> * Jens Owen <jens@precisioninsight.com> * - * $PI: xc/lib/GL/dri/xf86dristr.h,v 1.11 1999/06/22 03:09:44 jens Exp $ */ #ifndef _XF86DRISTR_H_ @@ -41,7 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define XF86DRINAME "XFree86-DRI" -#define XF86DRI_MAJOR_VERSION 1 /* current version numbers */ +#define XF86DRI_MAJOR_VERSION 2 /* current version numbers */ #define XF86DRI_MINOR_VERSION 0 #define XF86DRI_PATCH_VERSION 0 @@ -239,9 +238,13 @@ typedef struct { INT16 drawableWidth B16; INT16 drawableHeight B16; CARD32 numClipRects B32; - CARD32 pad6 B32; + INT16 backX B16; + INT16 backY B16; + CARD32 numBackClipRects B32; } xXF86DRIGetDrawableInfoReply; -#define sz_xXF86DRIGetDrawableInfoReply 32 + +#define sz_xXF86DRIGetDrawableInfoReply 36 + typedef struct _XF86DRIGetDeviceInfo { CARD8 reqType; /* always DRIReqCode */ diff --git a/xc/lib/GL/highpc.c b/xc/lib/GL/highpc.c new file mode 100644 index 000000000..c9218d02a --- /dev/null +++ b/xc/lib/GL/highpc.c @@ -0,0 +1,75 @@ +#include <stdio.h> +#include <stdlib.h> + + +/* Mesa shared lib profiling code by Josh Vanderhoof. Adapted + * (trivially) to the DRI by Keith Whitwell. + */ + +/* + * This is the highest address in libGL.so + */ +void glx_highpc(void) { } + +#if defined(__GNUC__) && defined(__linux__) + +void monstartup( char *lowpc, char *highpc ); +void _mcleanup( void ); +void glx_lowpc( void ); + +static int profile = 0; + + +/* + * Start profiling + */ +void __attribute__ ((constructor)) +glx_init_prof( void ) +{ + FILE *fp; + char *s = getenv("GLX_SO_MON"); + + fprintf(stderr, "\n\n\nIn glx_init_prof\n\n\n"); + + if (!s) return; + + profile = 1; + monstartup( (char *)glx_lowpc, (char *)glx_highpc ); + + fprintf(stderr, "Starting profiling, %x %x\n", + (unsigned int)glx_lowpc, + (unsigned int)glx_highpc); + + if ((fp = fopen( "glx_lowpc", "w" )) != NULL) { + fprintf( fp, "0x%08x ", (unsigned int)glx_lowpc ); + fclose( fp ); + } +} + + + +/* + * Finish profiling + */ +void __attribute__ ((destructor)) +glx_fini_prof( void ) +{ + fprintf(stderr, "in glx_fini_prof\n"); + + if (profile) { + _mcleanup(); + profile = 0; + fprintf(stderr, "Finished profiling\n"); + } +} + + + + +#else + +void force_init_prof( void ) +{ +} + +#endif diff --git a/xc/lib/GL/lowpc.c b/xc/lib/GL/lowpc.c new file mode 100644 index 000000000..7c580a02c --- /dev/null +++ b/xc/lib/GL/lowpc.c @@ -0,0 +1,4 @@ +/* + * This is the lowest address in Mesa + */ +void glx_lowpc(void) { } diff --git a/xc/lib/GL/makeprofile.sh b/xc/lib/GL/makeprofile.sh new file mode 100755 index 000000000..05d1b221a --- /dev/null +++ b/xc/lib/GL/makeprofile.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +RUNDIR=$1 + +[ -f ${RUNDIR}/glx_lowpc ] || { echo "no file ${RUNDIR}/glx_lowpc" ; exit 1 } +[ -f ${RUNDIR}/gmon.out ] || { echo "no file ${RUNDIR}/gmon.out" ; exit 1 } + +rm -f glx_lowpc gmon.out glxsyms profile +ln -s ${RUNDIR}/glx_lowpc . || exit 1 +ln -s ${RUNDIR}/gmon.out . || exit 1 + +ld -o glxsyms -noinhibit-exec --whole-archive -Ttext=`cat glx_lowpc` libGL.a 2> /dev/null && \ +gprof glxsyms < gmon.out > profile diff --git a/xc/lib/GL/mesa/dri/dri_mesa.c b/xc/lib/GL/mesa/dri/dri_mesa.c index 08f3dfcfd..b2ee7e3e0 100644 --- a/xc/lib/GL/mesa/dri/dri_mesa.c +++ b/xc/lib/GL/mesa/dri/dri_mesa.c @@ -307,14 +307,26 @@ void driMesaUpdateDrawableInfo(Display *dpy, int scrn, Xfree(pdp->pClipRects); } + if (pdp->pBackClipRects) { + Xfree(pdp->pBackClipRects); + } + + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); if (!XF86DRIGetDrawableInfo(dpy, scrn, pdp->draw, &pdp->index, &pdp->lastStamp, &pdp->x, &pdp->y, &pdp->w, &pdp->h, - &pdp->numClipRects, &pdp->pClipRects)) { + &pdp->numClipRects, &pdp->pClipRects, + &pdp->backX, + &pdp->backY, + &pdp->numBackClipRects, + &pdp->pBackClipRects + )) { pdp->numClipRects = 0; pdp->pClipRects = NULL; + pdp->numBackClipRects = 0; + pdp->pBackClipRects = 0; /* ERROR!!! */ } @@ -354,7 +366,9 @@ static void *driMesaCreateDrawable(Display *dpy, int scrn, GLXDrawable draw, pdp->w = 0; pdp->h = 0; pdp->numClipRects = 0; + pdp->numBackClipRects = 0; pdp->pClipRects = NULL; + pdp->pBackClipRects = NULL; pDRIScreen = __glXFindDRIScreen(dpy, scrn); pdp->driScreenPriv = psp = (__DRIscreenPrivate *)pDRIScreen->private; diff --git a/xc/lib/GL/mesa/dri/dri_mesaint.h b/xc/lib/GL/mesa/dri/dri_mesaint.h index 6b64114d0..16c483f01 100644 --- a/xc/lib/GL/mesa/dri/dri_mesaint.h +++ b/xc/lib/GL/mesa/dri/dri_mesaint.h @@ -104,6 +104,16 @@ struct __DRIdrawablePrivateRec { XF86DRIClipRectPtr pClipRects; /* + ** Information about the back and depthbuffer where different + ** from above. + */ + int backX; + int backY; + int backClipRectType; + int numBackClipRects; + XF86DRIClipRectPtr pBackClipRects; + + /* ** Pointer to context to which this drawable is currently bound. */ __DRIcontextPrivate *driContextPriv; diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile index fadb29bb2..306bf16dc 100644 --- a/xc/lib/GL/mesa/src/drv/Imakefile +++ b/xc/lib/GL/mesa/src/drv/Imakefile @@ -16,6 +16,12 @@ DRIVER += gamma #if GlxBuiltInTdfx DRIVER += tdfx #endif +#if GlxBuiltInMga +DRIVER += common mga +#endif +#if GlxBuiltInI810 +DRIVER += common i810 +#endif SUBDIRS = $(DRIVER) #else @@ -23,6 +29,9 @@ SUBDIRS += gamma #if HasGlide3 SUBDIRS += tdfx #endif +SUBDIRS += common +SUBDIRS += mga +SUBDIRS += i810 #endif MakeSubdirs($(SUBDIRS)) diff --git a/xc/lib/GL/mesa/src/drv/common/Imakefile b/xc/lib/GL/mesa/src/drv/common/Imakefile index 5c3d40dd7..e96291842 100644 --- a/xc/lib/GL/mesa/src/drv/common/Imakefile +++ b/xc/lib/GL/mesa/src/drv/common/Imakefile @@ -22,8 +22,7 @@ MESA_INCLUDES = -I. -I.. -I../../include DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) - INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \ - -I/usr/include/glide + INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) DRISRCS = hwlog.c mm.c DRIOBJS = hwlog.o mm.o @@ -44,7 +43,8 @@ LibraryObjectRule() SubdirLibraryRule($(OBJS)) NormalLintTarget($(SRCS)) -#if !GlxUseBuiltInDRIDriver +XCOMM #if !GlxUseBuiltInDRIDriver +#if 0 LIBNAME = i810_dri.so ALL_OBJS = $(OBJS) ALL_DEPS = DONE diff --git a/xc/lib/GL/mesa/src/drv/common/depthtmp.h b/xc/lib/GL/mesa/src/drv/common/depthtmp.h new file mode 100644 index 000000000..3aa307904 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/depthtmp.h @@ -0,0 +1,133 @@ +#ifndef DBG +#define DBG 0 +#endif + + + +static void TAG(WriteDepthSpan)( GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLdepth *depth, + const GLubyte mask[] ) +{ + HW_LOCK() + { + GLint x1; + GLint n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP(y); + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteDepthSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;i<n1;i++,x1++) + if (mask[i]) + WRITE_DEPTH( x1, y, depth[i] ); + } + else + { + for (;i<n1;i++,x1++) + WRITE_DEPTH( x1, y, depth[i] ); + } + } + HW_ENDCLIPLOOP(); + } + HW_UNLOCK(); +} + + +static void TAG(WriteDepthPixels)( GLcontext *ctx, + GLuint n, + const GLint x[], + const GLint y[], + const GLdepth depth[], + const GLubyte mask[] ) +{ + HW_LOCK() + { + GLint i; + LOCAL_DEPTH_VARS; + + if (DBG) fprintf(stderr, "WriteDepthPixels\n"); + + HW_CLIPLOOP() + { + for (i=0;i<n;i++) + { + if (mask[i]) { + const int fy = Y_FLIP(y[i]); + if (CLIPPIXEL(x[i],fy)) + WRITE_DEPTH( x[i], fy, depth[i] ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_UNLOCK(); +} + + + + +/* Read depth spans and pixels + */ +static void TAG(ReadDepthSpan)( GLcontext *ctx, + GLuint n, GLint x, GLint y, + GLdepth depth[]) +{ + HW_LOCK() + { + GLint x1,n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP(y); + + if (DBG) fprintf(stderr, "ReadDepthSpan\n"); + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + for (;i<n1;i++) + READ_DEPTH( depth[i], (x1+i), y ); + } + HW_ENDCLIPLOOP(); + } + HW_UNLOCK(); +} + +static void TAG(ReadDepthPixels)( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLdepth depth[] ) +{ + HW_LOCK() + { + GLint i; + LOCAL_DEPTH_VARS; + + if (DBG) fprintf(stderr, "ReadDepthPixels\n"); + + HW_CLIPLOOP() + { + for (i=0;i<n;i++) { + int fy = Y_FLIP( y[i] ); + if (CLIPPIXEL( x[i], fy )) + READ_DEPTH( depth[i], x[i], fy ); + } + } + HW_ENDCLIPLOOP(); + } + HW_UNLOCK(); +} + + +#undef WRITE_DEPTH +#undef READ_DEPTH +#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.c b/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.c new file mode 100644 index 000000000..2fd80eb3e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.c @@ -0,0 +1,88 @@ +#include <stdio.h> +#include "shared_texture_lru.h" + +/* (Re)initialize the global circular LRU list. The last element + * in the array (heap->nrRegions) is the sentinal. Keeping it + * at the end of the array allows the other elements of the array + * to be addressed rationally when looking up objects at a + * particular location in texture memory. + */ +static void resetGlobalLRU( driHeapPtr heap ) +{ + driTexRegion *list = heap->shared->list; + int sz = 1 << heap->logGranularity; + int i; + + heap->localAge = ++heap->shared->texAge; + + for (i = 0 ; (i+1) * sz <= heap->size ; i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = heap->shared->texAge; + } + + i--; + list[0].prev = heap->nrRegions; + list[i].prev = i-1; + list[i].next = heap->nrRegions; + list[heap->nrRegions].prev = i; + list[heap->nrRegions].next = 0; +} + +/* Called by the client whenever it touches a local texture. + */ +void driUpdateHeap( driHeapPtr heap, int start, int end ) +{ + driTexRegion *list = heap->shared->list; + int i; + + heap->localAge = ++heap->shared->globalAge; + + for (i = start ; i <= end ; i++) + { + list[i].in_use = 1; + list[i].age = heap->localAge; + + /* remove_from_list(i) + */ + list[(unsigned)list[i].next].prev = list[i].prev; + list[(unsigned)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) + */ + list[i].prev = heap->nrRegions; + list[i].next = list[heap->nrRegions].next; + list[(unsigned)list[heap->nrRegions].next].prev = i; + list[heap->nrRegions].next = i; + } +} + + +/* Called by the client on lock contention to determine whether + * textures have been stolen + */ +void driAgeTextures( driHeapPtr heap ) +{ + driTexRegion *list = heap->shared->list; + int sz = 1 << (heap->logGranularity); + int i, nr = 0; + + /* Have to go right round from the back to ensure stuff ends up + * LRU in the local list... Fix with a cursor pointer. + */ + for (i = list[heap->nrRegions].prev ; + i != heap->nrRegions && nr < heap->nrRegions ; + i = list[i].prev, nr++) + { + if (list[i].age > heap->localAge) + heap->texturesGone( heap->driverContext, heap->heapId, i * sz, sz, 1); + } + + /* Loop or uninitialized heap detected. Reset. + */ + if (nr == heap->nrRegions) { + heap->texturesGone( heap->driverContext, heap->heapId, 0, heap->size, 0); + resetGlobalLRU( heap ); + } +} + diff --git a/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.h b/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.h new file mode 100644 index 000000000..e6cee567d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.h @@ -0,0 +1,76 @@ +#ifndef DRI_TEX_HEAP_H +#define DRI_TEX_HEAP_H + + +/* Private struct. + */ +typedef struct { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} driTexRegion; + + +/* This is the global part of the shared texture mechanism. + * + * Do not use this struct directly - declare an equivalent one with a + * larger list[] array, tuned to suit your application. + * + * Your expanded struct should be placed in the driver-specific + * portion of the sarea. + */ +struct { + int globalAge; + driTexRegion list[1]; /* drivers will want to define a larger list */ +} driGlobalList; + + +/* This is the client-private part of the mechanism. + * + * Clients will place one or more of these structs in their driver + * context struct to manage one or more global texture heaps. All + * fields except print_local_lru must be filled in. + */ +struct dri_tex_heap_t { + + int heapId; /* client-supplied identifier */ + void *driverContext; /* pointer to the client's context private */ + int size; /* heap size in bytes */ + int logGranularity; /* log base 2 of size of single heap region */ + int nrRegions; /* number of elements in global list */ + driGlobalList *shared; /* pointer to sarea driGlobalList struct */ + int localAge; /* initialize to zero */ + + /* Callback to the client to let it know a region of texture + * space has changed age. The client must integrate this + * information with its local texture knowledge, in particular + * checking whether any of its own textures have been + * invalidated. + */ + void (*textures_gone)( void *driverContext, + int heapId, + int offset, + int size, + int inUse ); + + /* Optional hook for debugging. + */ + void (*print_local_lru)( void *driverContext, + int heapId ); +} driTexHeap; + + +#define DRI_AGE_TEXTURES( heap ) \ + if ((heap)->localAge > (heap)->shared->globalAge) \ + driAgeTextures( heap ); + + +/* This should be called whenever there has been contention on the + * hardware lock. Clients can shortcircuit this slightly by using + * DRI_AGE_TEXTURES, above. + */ +void driAgeTextures( driTexHeap *heap ); + +#endif + + diff --git a/xc/lib/GL/mesa/src/drv/common/spantmp.h b/xc/lib/GL/mesa/src/drv/common/spantmp.h index e10dca1a2..b475c6b18 100644 --- a/xc/lib/GL/mesa/src/drv/common/spantmp.h +++ b/xc/lib/GL/mesa/src/drv/common/spantmp.h @@ -1,37 +1,48 @@ +#ifndef DBG +#define DBG 0 +#endif static void TAG(WriteRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] ) { - GLuint x1,n1; - LOCAL_VARS; - - y = Y_FLIP(y); - - if (DBG) fprintf(stderr, "WriteRGBASpan\n"); - - HW_CLIPLOOP() + HW_LOCK() { - GLuint i = 0; - CLIPSPAN(x,y,n,x1,n1,i); - if (mask) - { - for (i=0;i<n1;i++,x1++) - if (mask[i]) - WRITE_RGBA( x1, y, - rgba[i][0], rgba[i][1], - rgba[i][2], rgba[i][3] ); - } - else - { - for (i=0;i<n1;i++,x1++) - WRITE_RGBA( x1, y, - rgba[i][0], rgba[i][1], - rgba[i][2], rgba[i][3] ); - } + GLint x1; + GLint n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteRGBASpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;i<n1;i++,x1++) + if (mask[i]) + WRITE_RGBA( x1, y, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + else + { + for (;i<n1;i++,x1++) + WRITE_RGBA( x1, y, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + } + HW_ENDCLIPLOOP(); } - HW_ENDCLIPLOOP(); + HW_UNLOCK(); } static void TAG(WriteRGBSpan)( const GLcontext *ctx, @@ -39,32 +50,37 @@ static void TAG(WriteRGBSpan)( const GLcontext *ctx, const GLubyte rgb[][3], const GLubyte mask[] ) { - GLuint x1,n1; - LOCAL_VARS; - - y = Y_FLIP(y); - - - if (DBG) fprintf(stderr, "WriteRGBSpan\n"); - - HW_CLIPLOOP() + HW_LOCK() { - GLuint i = 0; - CLIPSPAN(x,y,n,x1,n1,i); - - if (mask) - { - for (;i<n1;i++,x1++) - if (mask[i]) - WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 ); - } - else - { - for (;i<n1;i++,x1++) - WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 ); - } + GLint x1; + GLint n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteRGBSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;i<n1;i++,x1++) + if (mask[i]) + WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 ); + } + else + { + for (;i<n1;i++,x1++) + WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 ); + } + } + HW_ENDCLIPLOOP(); } - HW_ENDCLIPLOOP(); + HW_UNLOCK(); } static void TAG(WriteRGBAPixels)( const GLcontext *ctx, @@ -74,25 +90,29 @@ static void TAG(WriteRGBAPixels)( const GLcontext *ctx, const GLubyte rgba[][4], const GLubyte mask[] ) { - GLuint i; - LOCAL_VARS; - - if (DBG) fprintf(stderr, "WriteRGBAPixels\n"); - - HW_CLIPLOOP() + HW_LOCK() { - for (i=0;i<n;i++) - { - if (mask[i]) { - const int fy = Y_FLIP(y[i]); - if (CLIPPIXEL(x[i],fy)) - WRITE_RGBA( x[i], fy, - rgba[i][0], rgba[i][1], - rgba[i][2], rgba[i][3] ); + GLint i; + LOCAL_VARS; + + if (DBG) fprintf(stderr, "WriteRGBAPixels\n"); + + HW_CLIPLOOP() + { + for (i=0;i<n;i++) + { + if (mask[i]) { + const int fy = Y_FLIP(y[i]); + if (CLIPPIXEL(x[i],fy)) + WRITE_RGBA( x[i], fy, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + } } - } + HW_ENDCLIPLOOP(); } - HW_ENDCLIPLOOP(); + HW_UNLOCK(); } @@ -100,23 +120,28 @@ static void TAG(WriteMonoRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] ) { - GLuint x1,n1; - LOCAL_VARS; - INIT_MONO_PIXEL(p); - - y = Y_FLIP( y ); - - if (DBG) fprintf(stderr, "WriteMonoRGBASpan\n"); - - HW_CLIPLOOP() + HW_LOCK() { - GLuint i = 0; - CLIPSPAN(x,y,n,x1,n1,i); - for (;i<n1;i++,x1++) - if (mask[i]) - WRITE_PIXEL( x1, y, p ); + GLint x1; + GLint n1; + LOCAL_VARS; + INIT_MONO_PIXEL(p); + + y = Y_FLIP( y ); + + if (DBG) fprintf(stderr, "WriteMonoRGBASpan\n"); + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + for (;i<n1;i++,x1++) + if (mask[i]) + WRITE_PIXEL( x1, y, p ); + } + HW_ENDCLIPLOOP(); } - HW_ENDCLIPLOOP(); + HW_UNLOCK(); } @@ -125,22 +150,26 @@ static void TAG(WriteMonoRGBAPixels)( const GLcontext *ctx, const GLint x[], const GLint y[], const GLubyte mask[] ) { - GLuint i; - LOCAL_VARS; - INIT_MONO_PIXEL(p); - - if (DBG) fprintf(stderr, "WriteMonoRGBAPixels\n"); - - HW_CLIPLOOP() + HW_LOCK() { - for (i=0;i<n;i++) - if (mask[i]) { - int fy = Y_FLIP(y[i]); - if (CLIPPIXEL( x[i], fy )) - WRITE_PIXEL( x[i], fy, p ); + GLint i; + LOCAL_VARS; + INIT_MONO_PIXEL(p); + + if (DBG) fprintf(stderr, "WriteMonoRGBAPixels\n"); + + HW_CLIPLOOP() + { + for (i=0;i<n;i++) + if (mask[i]) { + int fy = Y_FLIP(y[i]); + if (CLIPPIXEL( x[i], fy )) + WRITE_PIXEL( x[i], fy, p ); + } } - } - HW_ENDCLIPLOOP(); + HW_ENDCLIPLOOP(); + } + HW_UNLOCK(); } @@ -152,42 +181,50 @@ static void TAG(ReadRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4]) { - GLuint x1,n1; - LOCAL_VARS; + HW_LOCK() + { + GLint x1,n1; + LOCAL_VARS; - y = Y_FLIP(y); + y = Y_FLIP(y); - if (DBG) fprintf(stderr, "ReadRGBASpan\n"); + if (DBG) fprintf(stderr, "ReadRGBASpan\n"); - HW_CLIPLOOP() - { - GLuint i = 0; - CLIPSPAN(x,y,n,x1,n1,i); - for (;i<n1;i++) - READ_RGBA( rgba[i], x1+i, y ); + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + for (;i<n1;i++) + READ_RGBA( rgba[i], (x1+i), y ); + } + HW_ENDCLIPLOOP(); } - HW_ENDCLIPLOOP(); + HW_UNLOCK(); } static void TAG(ReadRGBAPixels)( const GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] ) { - GLuint i; - LOCAL_VARS; + HW_LOCK() + { + GLint i; + LOCAL_VARS; - if (DBG) fprintf(stderr, "ReadRGBAPixels\n"); + if (DBG) fprintf(stderr, "ReadRGBAPixels\n"); - HW_CLIPLOOP() - { - for (i=0;i<n;i++) - if (mask[i]) { - int fy = Y_FLIP( y[i] ); - if (CLIPPIXEL( x[i], fy )) - READ_RGBA( rgba[i], x[i], fy ); + HW_CLIPLOOP() + { + for (i=0;i<n;i++) + if (mask[i]) { + int fy = Y_FLIP( y[i] ); + if (CLIPPIXEL( x[i], fy )) + READ_RGBA( rgba[i], x[i], fy ); + } } + HW_ENDCLIPLOOP(); } - HW_ENDCLIPLOOP(); + HW_UNLOCK(); } diff --git a/xc/lib/GL/mesa/src/drv/i810/Imakefile b/xc/lib/GL/mesa/src/drv/i810/Imakefile index 5f1d93072..5c6a33796 100644 --- a/xc/lib/GL/mesa/src/drv/i810/Imakefile +++ b/xc/lib/GL/mesa/src/drv/i810/Imakefile @@ -1,4 +1,6 @@ +#include <Threads.tmpl> + #define DoNormalLib NormalLibGlx #define DoSharedLib SharedLibGlx #define DoExtraLib SharedLibGlx @@ -10,12 +12,14 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif #if BuildXF86DRI - DRI_DEFINES = GlxDefines -DFX -DFX_GLIDE3 -DGLIDE3 -DDRIVERTS + DRI_DEFINES = GlxDefines -DDRIVERTS DRI_INCLUDES = -I../../../../dri -I../../../../glx \ + -I../../../dri \ -I$(TOP)/include -I$(TOP)/include/GL \ -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \ - -I$(XF86DRIVERSRC)/i810 \ - -I../../../include -I../.. -I../../X + -I$(XF86DRIVERSRC)/i810 \ + -I../../../include -I../.. -I../common -I../../X \ + -I$(XF86OSSRC)/linux/drm/kernel #endif MESA_INCLUDES = -I. -I.. -I../../include @@ -23,20 +27,234 @@ MESA_INCLUDES = -I. -I.. -I../../include DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) - INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \ - -I/usr/include/glide - DRISRCS = i810_init.c i810_inithw.c i810_xmesa.c i810clear.c \ - i810context.c i810dd.c i810depth.c i810dma.c \ + INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) + + DRISRCS = ../../../dri/dri_mesa.c \ + ../../../../dri/dri_tmm.c + + DRIOBJS = ../../../dri/dri_mesa.o \ + ../../../../dri/dri_tmm.o + + DRMSRCS = ../../../../dri/drm/xf86drm.c \ + ../../../../dri/drm/xf86drmHash.c \ + ../../../../dri/drm/xf86drmRandom.c \ + ../../../../dri/drm/xf86drmSL.c + + DRMOBJS = ../../../../dri/drm/xf86drm.o \ + ../../../../dri/drm/xf86drmHash.o \ + ../../../../dri/drm/xf86drmRandom.o \ + ../../../../dri/drm/xf86drmSL.o + + + I810SRCS = i810_xmesa.c i810clear.c \ + i810dd.c \ i810pipeline.c i810span.c i810state.c i810swap.c \ - i810tex.c i810tris.c i810vb.c + i810tex.c i810tris.c i810vb.c i810fastpath.c i810ioctl.c - DRIOBJS = i810_init.o i810_inithw.o i810_xmesa.o i810clear.o \ - i810context.o i810dd.o i810depth.o i810dma.o \ + I810OBJS = i810_xmesa.o i810clear.o \ + i810dd.o \ i810pipeline.o i810span.o i810state.o i810swap.o \ - i810tex.o i810tris.o i810vb.o + i810tex.o i810tris.o i810vb.o i810fastpath.o i810ioctl.o + + MESASRCS = ../../accum.c \ + ../../alpha.c \ + ../../alphabuf.c \ + ../../attrib.c \ + ../../bbox.c \ + ../../bitmap.c \ + ../../blend.c \ + ../../buffers.c \ + ../../clip.c \ + ../../colortab.c \ + ../../config.c \ + ../../context.c \ + ../../copypix.c \ + ../../cva.c \ + ../../debug_xform.c \ + ../../depth.c \ + ../../dlist.c \ + ../../drawpix.c \ + ../../enable.c \ + ../../enums.c \ + ../../eval.c \ + ../../extensions.c \ + ../../feedback.c \ + ../../fog.c \ + ../../get.c \ + ../../glapi.c \ + ../../glapinoop.c \ + ../../glthread.c \ + ../../hash.c \ + ../../image.c \ + ../../imaging.o \ + ../../light.c \ + ../../lines.c \ + ../../logic.c \ + ../../masking.c \ + ../../matrix.c \ + ../../mem.c \ + ../../mmath.c \ + ../../pb.c \ + ../../pipeline.c \ + ../../pixel.c \ + ../../points.c \ + ../../polygon.c \ + ../../quads.c \ + ../../rastpos.c \ + ../../readpix.c \ + ../../rect.c \ + ../../scissor.c \ + ../../shade.c \ + ../../span.c \ + ../../stages.c \ + ../../state.c \ + ../../stencil.c \ + ../../teximage.c \ + ../../texobj.c \ + ../../texstate.c \ + ../../texture.c \ + ../../translate.c \ + ../../triangle.c \ + ../../varray.c \ + ../../vb.c \ + ../../vbcull.c \ + ../../vbfill.c \ + ../../vbindirect.c \ + ../../vbrender.c \ + ../../vbxform.c \ + ../../vector.c \ + ../../vertices.c \ + ../../winpos.c \ + ../../xform.c \ + ../../zoom.c \ + ../../X86/common_x86.c + + MESAOBJS = ../../accum.o \ + ../../alpha.o \ + ../../alphabuf.o \ + ../../attrib.o \ + ../../bbox.o \ + ../../bitmap.o \ + ../../blend.o \ + ../../buffers.o \ + ../../clip.o \ + ../../colortab.o \ + ../../config.o \ + ../../context.o \ + ../../copypix.o \ + ../../cva.o \ + ../../debug_xform.o \ + ../../depth.o \ + ../../dlist.o \ + ../../drawpix.o \ + ../../enable.o \ + ../../enums.o \ + ../../eval.o \ + ../../extensions.o \ + ../../feedback.o \ + ../../fog.o \ + ../../get.o \ + ../../hash.o \ + ../../hint.o \ + ../../image.o \ + ../../imaging.o \ + ../../light.o \ + ../../lines.o \ + ../../logic.o \ + ../../masking.o \ + ../../matrix.o \ + ../../mem.o \ + ../../mmath.o \ + ../../pb.o \ + ../../pipeline.o \ + ../../pixel.o \ + ../../points.o \ + ../../polygon.o \ + ../../quads.o \ + ../../rastpos.o \ + ../../readpix.o \ + ../../rect.o \ + ../../scissor.o \ + ../../shade.o \ + ../../span.o \ + ../../stages.o \ + ../../state.o \ + ../../stencil.o \ + ../../teximage.o \ + ../../texobj.o \ + ../../texstate.o \ + ../../texture.o \ + ../../translate.o \ + ../../triangle.o \ + ../../varray.o \ + ../../vb.o \ + ../../vbcull.o \ + ../../vbfill.o \ + ../../vbindirect.o \ + ../../vbrender.o \ + ../../vbxform.o \ + ../../vector.o \ + ../../vertices.o \ + ../../winpos.o \ + ../../xform.o \ + ../../zoom.o + +#ifdef i386Architecture + X86_SRCS = ../../X86/x86.c \ + ../../X86/x86a.S \ + ../../X86/common_x86.c \ + ../../X86/common_x86asm.S \ + ../../X86/vertex.S + + X86_OBJS = ../../X86/x86.o \ + ../../X86/x86a.o \ + ../../X86/common_x86.o \ + ../../X86/common_x86asm.o \ + ../../X86/vertex.o + + MMX_SRCS = ../../X86/mmx_blend.S + + MMX_OBJS = ../../X86/mmx_blend.o + +XCOMM Disabling 3Dnow code for the time being. +#if 0 + 3DNOW_SRCS = ../../X86/3dnow.c \ + ../../X86/3dnow_norm_raw.S \ + ../../X86/3dnow_xform_masked1.S \ + ../../X86/3dnow_xform_masked2.S \ + ../../X86/3dnow_xform_masked3.S \ + ../../X86/3dnow_xform_masked4.S \ + ../../X86/3dnow_xform_raw1.S \ + ../../X86/3dnow_xform_raw2.S \ + ../../X86/3dnow_xform_raw3.S \ + ../../X86/3dnow_xform_raw4.S \ + ../../X86/vertex_3dnow.S + + 3DNOW_OBJS = ../../X86/3dnow.o \ + ../../X86/3dnow_norm_raw.o \ + ../../X86/3dnow_xform_masked1.o \ + ../../X86/3dnow_xform_masked2.o \ + ../../X86/3dnow_xform_masked3.o \ + ../../X86/3dnow_xform_masked4.o \ + ../../X86/3dnow_xform_raw1.o \ + ../../X86/3dnow_xform_raw2.o \ + ../../X86/3dnow_xform_raw3.o \ + ../../X86/3dnow_xform_raw4.o \ + ../../X86/vertex_3dnow.o +#endif + +#endif + + ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) + ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) + + COMMONSRCS = ../common/mm.c ../common/hwlog.c + COMMONOBJS = ../common/mm.o ../common/hwlog.o + + SRCS = $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) $(COMMONSRCS) $(I810SRCS) + OBJS = $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) $(COMMONOBJS) $(I810OBJS) - SRCS = $(DRISRCS) - OBJS = $(DRIOBJS) +REQUIREDLIBS += -lm #if !GlxUseBuiltInDRIDriver #undef DoNormalLib NormalLibGlx @@ -57,7 +275,7 @@ LIBNAME = i810_dri.so ALL_OBJS = $(OBJS) ALL_DEPS = DONE SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) -InstallDynamicModule($(LIBNAME),$(MODULEDIR),.) +InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.) #endif DependTarget() diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h index 677a35222..e4e274e9a 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h @@ -75,7 +75,8 @@ * 4: DR4_* */ #define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) -#define DR1_RECT_CLIP_ENABLE (0x1<<31) +#define DR1_RECT_CLIP_ENABLE (0x0<<31) +#define DR1_RECT_CLIP_DISABLE (0x1<<31) #define DR1_X_DITHER_BIAS_MASK (0x3<<26) #define DR1_X_DITHER_BIAS_SHIFT 26 #define DR1_Y_DITHER_BIAS_MASK (0x3<<24) @@ -107,6 +108,8 @@ #define LCS_UPDATE_LINEWIDTH (0x1<<15) #define LCS_LINEWIDTH_MASK (0x7<<12) #define LCS_LINEWIDTH_SHIFT 12 +#define LCS_LINEWIDTH_0_5 (0x1<<12) +#define LCS_LINEWIDTH_1_0 (0x2<<12) #define LCS_UPDATE_ALPHA_INTERP (0x1<<11) #define LCS_ALPHA_FLAT (0x0<<10) #define LCS_ALPHA_INTERP (0x1<<10) @@ -238,18 +241,6 @@ #define SDM_DST_BOTH_SRC_ALPHA (0xc<<0) #define SDM_DST_BOTH_INV_SRC_ALPHA (0xd<<0) -/* GFXRENDERSTATE_COLOR_CHROMA_KEY, p135 - */ -#define GFX_OP_COLOR_CHROMA_KEY ((0x3<<29)|(0x1d<<24)|(0x2<<16)|0x1) -#define CC1_UPDATE_CC_TEST_ENABLE (1<<28) -#define CC1_CC_TEST_ENABLE (1<<27) -#define CC1_UPDATE_CI_VALUE (1<<26) -#define CC1_UPDATE_CK_LOW_VALUE (1<<25) -#define CC1_UPDATE_CK_HI_VALUE (1<<24) -#define CC1_CK_LOW_VALUE_MASK ((1<<24)-1) -#define CC2_CI_VALUE_MASK (0xff<<24) -#define CC2_CI_VALUE_SHIFT 24 -#define CC2_CK_HIGH_VALUE_MASK ((1<<24)-1) /* GFXRENDERSTATE_COLOR_FACTOR, p134 * @@ -628,13 +619,43 @@ typedef struct { #define DV_PF_565 (0x2<<8) + + +#define GFX_OP_ANTIALIAS ((0x3<<29)|(0x6<<24)) +#define AA_UPDATE_EDGEFLAG (1<<13) +#define AA_ENABLE_EDGEFLAG (1<<12) +#define AA_UPDATE_POLYWIDTH (1<<11) +#define AA_POLYWIDTH_05 (1<<9) +#define AA_POLYWIDTH_10 (2<<9) +#define AA_POLYWIDTH_20 (3<<9) +#define AA_POLYWIDTH_40 (4<<9) +#define AA_UPDATE_LINEWIDTH (1<<8) +#define AA_LINEWIDTH_05 (1<<6) +#define AA_LINEWIDTH_10 (2<<6) +#define AA_LINEWIDTH_20 (3<<6) +#define AA_LINEWIDTH_40 (4<<6) +#define AA_UPDATE_BB_EXPANSION (1<<5) +#define AA_BB_EXPANSION_SHIFT 2 +#define AA_UPDATE_AA_ENABLE (1<<1) +#define AA_ENABLE (1<<0) + +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + + /* Indices into buf.Setup where various bits of state are mirrored per * context and per buffer. These can be fired at the card as a unit, * or in a piecewise fashion as required. */ -/* Destbuffer state (includes zbuffer). Drawrect is the only thing - * that needs to be restored for 2d??? +/* Destbuffer state + * - backbuffer linear offset and pitch -- invarient in the current dri + * - zbuffer linear offset and pitch -- also invarient + * - drawing origin in back and depth buffers. + * + * Keep the depth/back buffer state here to acommodate private buffers + * in the future. */ #define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */ #define I810_DESTREG_DI1 1 @@ -667,14 +688,24 @@ typedef struct { #define I810_CTXREG_B1 12 /* GFX_OP_BOOL_1 */ #define I810_CTXREG_B2 13 /* GFX_OP_BOOL_2 */ #define I810_CTXREG_LCS 14 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */ -#define I810_CTXREG_SCI0 15 /* GFX_OP_SCISSOR_INFO (3 dwords) */ -#define I810_CTXREG_SCI1 16 -#define I810_CTXREG_SCI2 17 -#define I810_CTXREG_SC 18 /* GFX_OP_SCISSOR */ -#define I810_CTXREG_PV 19 /* GFX_OP_PV_RULE -- Invarient! */ -#define I810_CTXREG_ZA 20 /* GFX_OP_ZBIAS_ALPHAFUNC */ - -#define I810_CTX_SETUP_SIZE (21+1) /* pad to qword */ +#define I810_CTXREG_PV 15 /* GFX_OP_PV_RULE -- Invarient! */ +#define I810_CTXREG_ZA 16 /* GFX_OP_ZBIAS_ALPHAFUNC */ +#define I810_CTXREG_ST0 17 /* GFX_OP_STIPPLE */ +#define I810_CTXREG_ST1 18 +#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */ +#define I810_CTX_SETUP_SIZE (20) /* pad to qword */ + + +/* Cliprect state - keep seperate from context as it is used for + * drawing triangles to the shared backbuffer, and + * changes more frequently than the 'normal' context. + */ +#define I810_CLIPREG_SCI0 0 /* GFX_OP_SCISSOR_INFO (3 dwords) */ +#define I810_CLIPREG_SCI1 1 +#define I810_CLIPREG_SCI2 2 +#define I810_CLIPREG_SC 3 /* GFX_OP_SCISSOR */ + +#define I810_CLIP_SETUP_SIZE 4 /* Texture state (per tex_buffer) */ diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_init.c b/xc/lib/GL/mesa/src/drv/i810/i810_init.c deleted file mode 100644 index 5f37cd769..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810_init.c +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************** - -Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <keithw@precisioninsight.com> - * - * based on tdfx driver by - * Daryll Strauss <daryll@precisioninsight.com> - * - * $PI: # - */ - -#ifdef GLX_DIRECT_RENDERING - -#include <X11/Xlibint.h> -#include "xf86dri.h" -#include "i810_dri.h" -#include "i810_init.h" - -#ifdef DEBUG_LOCKING -char *prevLockFile=0; -int prevLockLine=0; -#endif - -static void performMagic(__DRIscreenPrivate *driScrnPriv) -{ - i810ScreenPrivate *gPriv = (i810ScreenPrivate *)driScrnPriv->private; - I810DRIPtr gDRIPriv = (I810DRIPtr)driScrnPriv->pDevPriv; - - gPriv->regs.handle=gDRIPriv->regs; - gPriv->regs.size=gDRIPriv->regsSize; - gPriv->deviceID=gDRIPriv->deviceID; - gPriv->width=gDRIPriv->width; - gPriv->height=gDRIPriv->height; - gPriv->mem=gDRIPriv->mem; - gPriv->cpp=gDRIPriv->cpp; - gPriv->stride=gDRIPriv->stride; - gPriv->fbOffset=gDRIPriv->fbOffset; - gPriv->backOffset=gDRIPriv->backOffset; - gPriv->depthOffset=gDRIPriv->depthOffset; - gPriv->textureOffset=gDRIPriv->textureOffset; - gPriv->textureSize=gDRIPriv->textureSize; -} - -GLboolean i810MapAllRegions(__DRIscreenPrivate *driScrnPriv) -{ - i810ScreenPrivate *gPriv = (i810ScreenPrivate *)driScrnPriv->private; - - /* First, pick apart pDevPriv & friends */ - performMagic(driScrnPriv); - - if (drmMap(driScrnPriv->fd, gPriv->regs.handle, gPriv->regs.size, - &gPriv->regs.map)) { - return GL_FALSE; - } - - return GL_TRUE; -} - -void i810UnmapAllRegions(__DRIscreenPrivate *driScrnPriv) -{ - i810ScreenPrivate *gPriv = (i810ScreenPrivate *)driScrnPriv->private; - - drmUnmap(gPriv->regs.map, gPriv->regs.size); -} - -/* - * Shutdown hardware - nothing to do... - */ -void i810CloseHardware(void) -{ -} - -#endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_init.h b/xc/lib/GL/mesa/src/drv/i810/i810_init.h index c7af9c443..804f66889 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_init.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810_init.h @@ -27,7 +27,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> * */ @@ -37,7 +37,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING #include <sys/time.h> -#include <glide.h> #include "dri_tmm.h" #include "dri_mesaint.h" #include "dri_mesa.h" @@ -45,148 +44,88 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xmesaP.h" typedef struct { - drmHandle handle; - drmSize size; - drmAddress map; + drmHandle handle; + drmSize size; + char *map; } i810Region, *i810RegionPtr; typedef struct { - i810Region regs; - int deviceID; - int width; - int height; - int mem; - int cpp; - int stride; - int fbOffset; - int backOffset; - int depthOffset; - int textureOffset; - int textureSize; - __DRIscreenPrivate *driScrnPriv; -} i810ScreenPrivate; + i810Region front; + i810Region back; + i810Region depth; + i810Region tex; -typedef struct { - volatile int *fifoPtr; - volatile int *fifoRead; - volatile int fifoOwner; - volatile int ctxOwner; - volatile int texOwner; -} I810SAREAPriv; + int deviceID; + int width; + int height; + int mem; + + int cpp; /* for front and back buffers */ + int bitsPerPixel; + + int fbFormat; + int fbOffset; + int fbStride; + + int backOffset; + int depthOffset; + + int backPitch; + int backPitchBits; + int textureOffset; + int textureSize; + int logTextureGranularity; + __DRIscreenPrivate *driScrnPriv; + drmBufMapPtr bufs; + +} i810ScreenPrivate; #include "i810context.h" -extern GLboolean i810MapAllRegions(__DRIscreenPrivate *driScrnPriv); -extern void i810UnmapAllRegions(__DRIscreenPrivate *driScrnPriv); -extern GLboolean i810InitHW(XMesaContext c); - -extern void XMesaWindowMoved(XMesaContext *c); -extern void XMesaUpdateState(XMesaContext *c, int windowMoved); -extern void XMesaSetSAREA(XMesaContext *c); - -extern XMesaContext gCC; -extern i810ContextPtr i810Ctx; - -/* -You can turn this on to find locking conflicts. -#define DEBUG_LOCKING -*/ - -#ifdef 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 +extern void i810GetLock( i810ContextPtr imesa, GLuint flags ); +extern void i810EmitHwStateLocked( i810ContextPtr imesa ); +extern void i810EmitScissorValues( i810ContextPtr imesa, int box_nr, int emit ); +extern void i810EmitDrawingRectangle( i810ContextPtr imesa ); +extern void i810XMesaSetBackClipRects( i810ContextPtr imesa ); +extern void i810XMesaSetFrontClipRects( i810ContextPtr imesa ); -/* !!! 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 !!! */ - -#define DRM_LIGHT_LOCK_RETURN(fd,lock,context,__ret) \ - do { \ - DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ - if (__ret) drmGetLock(fd,context,0); \ - } while(0) - -/* Lock the hardware using the global current context */ -#define LOCK_HARDWARE() \ - do { \ - int stamp; \ - char __ret=0; \ - __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \ - __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; \ - DEBUG_CHECK_LOCK(); \ - DRM_LIGHT_LOCK_RETURN(sPriv->fd, &sPriv->pSAREA->lock, \ - dPriv->driContextPriv->hHWContext, __ret); \ - if (__ret) __ret=1; \ - stamp=dPriv->lastStamp; \ - XMESA_VALIDATE_DRAWABLE_INFO(gCC->display, sPriv, dPriv); \ - if (*(dPriv->pStamp)!=stamp) __ret=2; \ - if (__ret) XMesaUpdateState(gCC, __ret==2); \ - DEBUG_LOCK(); \ - } while (0) -/* Unlock the hardware using the global current context */ -#define UNLOCK_HARDWARE() \ - do { \ - __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \ - __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; \ - XMesaSetSAREA(gCC); \ - DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, \ - dPriv->driContextPriv->hHWContext); \ - DEBUG_RESET(); \ - } while (0) +#define GET_DISPATCH_AGE( imesa ) imesa->sarea->last_dispatch +#define GET_ENQUEUE_AGE( imesa ) imesa->sarea->last_enqueue -#define BEGIN_BOARD_LOCK() LOCK_HARDWARE() -#define END_BOARD_LOCK() UNLOCK_HARDWARE() -/* - This pair of macros makes a loop over the drawing operations - so it is not self contained and doesn't have the nice single - statement semantics of most macros -*/ -#define BEGIN_CLIP_LOOP() \ - do { \ - __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \ - int _nc = dPriv->numClipRects; \ - LOCK_HARDWARE(); \ - while (_nc--) { \ - if (i810Ctx->needClip) { \ - i810Ctx->clipMinX=dPriv->pClipRects[_nc].x1; \ - i810Ctx->clipMaxX=dPriv->pClipRects[_nc].x2; \ - i810Ctx->clipMinY=dPriv->pClipRects[_nc].y1; \ - i810Ctx->clipMaxY=dPriv->pClipRects[_nc].y2; \ - i810SetScissorValues(i810Ctx->glCtx); \ - } - -#define END_CLIP_LOOP() \ - } \ - UNLOCK_HARDWARE(); \ +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( imesa ) \ + do { \ + char __ret=0; \ + DRM_CAS(imesa->driHwLock, imesa->hHWContext, \ + (DRM_LOCK_HELD|imesa->hHWContext), __ret); \ + if (__ret) \ + i810GetLock( imesa, 0 ); \ } while (0) + + +/* Unlock the hardware using the global current context + */ +#define UNLOCK_HARDWARE(imesa) \ + DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext); + + +/* 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, + * this is 3 ioctls. The best solution probably only gets me down + * to 2 ioctls in the worst case. + */ +#define LOCK_HARDWARE_QUIESCENT( imesa ) do { \ + LOCK_HARDWARE( imesa ); \ + i810RegetLockQuiescent( imesa ); \ +} while(0) + + #endif #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_inithw.c b/xc/lib/GL/mesa/src/drv/i810/i810_inithw.c deleted file mode 100644 index 6bcae44c7..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810_inithw.c +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************** - -Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Daryll Strauss <daryll@precisioninsight.com> - * - * $PI: $ - */ - -#ifdef GLX_DIRECT_RENDERING - -#include "i810_init.h" -#include <glide.h> - -GLboolean i810InitHW(XMesaContext c) -{ - /* KW: Would be nice to make one of these a member of the other. - */ - i810ContextPtr cPriv = (i810ContextPtr)c->private; - __DRIdrawablePrivate *driDrawPriv = c->driContextPriv->driDrawablePriv; - __DRIscreenPrivate *driScrnPriv = driDrawPriv->driScreenPriv; - i810ScreenPrivate *sPriv = (i810ScreenPrivate*)driScrnPriv->private; - -#ifdef DEBUG_LOCKING - fprintf(stderr, "Debug locking enabled\n"); -#endif - - if (cPriv->initDone) return GL_TRUE; - - cPriv->width=driDrawPriv->w; - cPriv->height=driDrawPriv->h; - - DRM_LIGHT_LOCK(driScrnPriv->fd, &driScrnPriv->pSAREA->lock, - driDrawPriv->driContextPriv->hHWContext); - FX_grGlideInit_NoLock(); - - - if (sPriv->deviceID==0x3) - cPriv->haveTwoTMUs=GL_FALSE; - else - cPriv->haveTwoTMUs=GL_TRUE; - - /* !!! We are forcing these !!! */ - cPriv->haveDoubleBuffer=GL_TRUE; - cPriv->haveAlphaBuffer=GL_FALSE; - cPriv->haveZBuffer=GL_TRUE; - cPriv->haveGlobalPaletteTexture=GL_FALSE; - - cPriv->glideContext = FX_grSstWinOpen_NoLock((FxU32)-1, GR_RESOLUTION_NONE, - GR_REFRESH_NONE, - GR_COLORFORMAT_ARGB, - GR_ORIGIN_LOWER_LEFT, 2, 1); - - - grDRIResetSAREA(); - - DRM_UNLOCK(driScrnPriv->fd, &driScrnPriv->pSAREA->lock, - driDrawPriv->driContextPriv->hHWContext); - - cPriv->needClip=1; - - if (!fxDDInitFxMesaContext( fxMesa )) - return GL_FALSE; - - cPriv->initDone=GL_TRUE; - return GL_TRUE; - -} - -#endif - - - - diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c index d4b540507..7716b4634 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c @@ -27,21 +27,54 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> * */ #ifdef GLX_DIRECT_RENDERING #include <X11/Xlibint.h> -#include <glide.h> +#include <stdio.h> + #include "i810_init.h" #include "context.h" #include "vbxform.h" #include "matrix.h" +#include "simple_list.h" + +#include "i810dd.h" +#include "i810state.h" +#include "i810tex.h" +#include "i810span.h" +#include "i810tris.h" +#include "i810swap.h" +#include "i810pipeline.h" +#include "i810ioctl.h" + +#include "i810_dri.h" + + + +#ifndef I810_DEBUG +int I810_DEBUG = (0 +/* | DEBUG_ALWAYS_SYNC */ +/* | DEBUG_VERBOSE_RING */ +/* | DEBUG_VERBOSE_OUTREG */ +/* | DEBUG_VERBOSE_MSG */ +/* | DEBUG_NO_OUTRING */ +/* | DEBUG_NO_OUTREG */ +/* | DEBUG_VERBOSE_API */ +/* | DEBUG_VERBOSE_2D */ +/* | DEBUG_VERBOSE_DRI */ +/* | DEBUG_VALIDATE_RING */ +/* | DEBUG_VERBOSE_IOCTL */ + ); +#endif + + +static i810ContextPtr i810Ctx = 0; -XMesaContext gCC = 0; -i810ContextPtr *i810Ctx = 0; +i810Glx_t i810glx; static int count_bits(unsigned int n) { @@ -76,32 +109,106 @@ static int count_bits(unsigned int n) */ -GLboolean XMesaInitDriver(__DRIscreenPrivate *driScrnPriv) +GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { - i810ScreenPrivate *gsp; + i810ScreenPrivate *i810Screen; + I810DRIPtr gDRIPriv = (I810DRIPtr)sPriv->pDevPriv; /* Allocate the private area */ - gsp = (i810ScreenPrivate *)Xmalloc(sizeof(i810ScreenPrivate)); - if (!gsp) return GL_FALSE; + i810Screen = (i810ScreenPrivate *)Xmalloc(sizeof(i810ScreenPrivate)); + if (!i810Screen) return GL_FALSE; + + i810Screen->driScrnPriv = sPriv; + sPriv->private = (void *)i810Screen; + + i810Screen->deviceID=gDRIPriv->deviceID; + i810Screen->width=gDRIPriv->width; + i810Screen->height=gDRIPriv->height; + i810Screen->mem=gDRIPriv->mem; + i810Screen->cpp=gDRIPriv->cpp; + i810Screen->fbStride=gDRIPriv->fbStride; + i810Screen->fbOffset=gDRIPriv->fbOffset; + + if (gDRIPriv->bitsPerPixel == 15) + i810Screen->fbFormat = DV_PF_555; + else + i810Screen->fbFormat = DV_PF_565; + + i810Screen->backOffset=gDRIPriv->backOffset; + i810Screen->depthOffset=gDRIPriv->depthOffset; + i810Screen->backPitch = gDRIPriv->auxPitch; + i810Screen->backPitchBits = gDRIPriv->auxPitchBits; + i810Screen->textureOffset=gDRIPriv->textureOffset; + i810Screen->textureSize=gDRIPriv->textureSize; + i810Screen->logTextureGranularity = gDRIPriv->logTextureGranularity; + + if (1) + fprintf(stderr, "Tex heap size %x, granularity %x bytes\n", + i810Screen->textureSize, 1<<(i810Screen->logTextureGranularity)); + + i810Screen->bufs = drmMapBufs(sPriv->fd); + + + i810Screen->back.handle = gDRIPriv->backbuffer; + i810Screen->back.size = gDRIPriv->backbufferSize; + + if (drmMap(sPriv->fd, + i810Screen->back.handle, + i810Screen->back.size, + (drmAddress *)&i810Screen->back.map) != 0) + { + Xfree(i810Screen); + return GL_FALSE; + } + + i810Screen->depth.handle = gDRIPriv->depthbuffer; + i810Screen->depth.size = gDRIPriv->depthbufferSize; - gsp->driScrnPriv = driScrnPriv; + if (drmMap(sPriv->fd, + i810Screen->depth.handle, + i810Screen->depth.size, + (drmAddress *)&i810Screen->depth.map) != 0) + { + Xfree(i810Screen); + return GL_FALSE; + } - driScrnPriv->private = (void *)gsp; + i810Screen->tex.handle = gDRIPriv->textures; + i810Screen->tex.size = gDRIPriv->textureSize; - if (!i810MapAllRegions(driScrnPriv)) { - Xfree(driScrnPriv->private); + if (drmMap(sPriv->fd, + i810Screen->tex.handle, + i810Screen->tex.size, + (drmAddress *)&i810Screen->tex.map) != 0) + { + Xfree(i810Screen); return GL_FALSE; } + + /* Ditch i810glx in favor of i810Screen? + */ + memset(&i810glx, 0, sizeof(i810glx)); + i810glx.texVirtual = i810Screen->tex.map; + + i810DDFastPathInit(); + i810DDTrifuncInit(); + i810DDSetupInit(); + return GL_TRUE; } /* Accessed by dlsym from dri_mesa_init.c */ -void XMesaResetDriver(__DRIscreenPrivate *driScrnPriv) +void XMesaResetDriver(__DRIscreenPrivate *sPriv) { - i810UnmapAllRegions(driScrnPriv); /* in i810_init.c */ - Xfree(driScrnPriv->private); + i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private; + + /* Need to unmap all the bufs and maps here: + */ + + + Xfree(i810Screen); } /* Accessed by dlsym from dri_mesa_init.c @@ -135,27 +242,18 @@ XMesaVisual XMesaCreateVisual(XMesaDisplay *display, v->display = display; v->level = level; - - v->gl_visual = (GLvisual *)Xmalloc(sizeof(GLvisual)); + v->gl_visual = gl_create_visual(rgb_flag, GL_FALSE, db_flag, stereo_flag, + depth_size, stencil_size, accum_size, 0, + count_bits(visinfo->red_mask), + count_bits(visinfo->green_mask), + count_bits(visinfo->blue_mask), + GL_FALSE); if (!v->gl_visual) { Xfree(v->visinfo); - XFree(v); - return 0; + Xfree(v); + return NULL; } - - v->gl_visual->RGBAflag = rgb_flag; - v->gl_visual->DBflag = db_flag; - v->gl_visual->StereoFlag = stereo_flag; - - v->gl_visual->RedBits = count_bits(visinfo->red_mask); - v->gl_visual->GreenBits = count_bits(visinfo->green_mask); - v->gl_visual->BlueBits = count_bits(visinfo->blue_mask); - v->gl_visual->AlphaBits = 0; /* Not currently supported */ - - v->gl_visual->AccumBits = accum_size; - v->gl_visual->DepthBits = depth_size; - v->gl_visual->StencilBits = stencil_size; - + return v; } @@ -169,71 +267,143 @@ void XMesaDestroyVisual(XMesaVisual v) XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, __DRIcontextPrivate *driContextPriv) { + GLcontext *ctx; XMesaContext c; - i810ContextPtr cPriv; - __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; - i810ScreenPrivate *sPriv = (i810ScreenPrivate *)driScrnPriv->private; - I810SAREAPriv *saPriv; - GLcontext *shareCtx; -/* int **fifoPtr; */ + i810ContextPtr imesa; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private; + drm_i810_sarea_t *saPriv=(drm_i810_sarea_t *)(((char*)sPriv->pSAREA)+ + sizeof(XF86DRISAREARec)); + + GLcontext *shareCtx = 0; c = (XMesaContext)Xmalloc(sizeof(struct xmesa_context)); - if (!c) return 0; + if (!c) { + return 0; + } + + imesa = (i810ContextPtr)Xcalloc(sizeof(i810Context), 1); + if (!imesa) { + Xfree(c); + return 0; + } c->driContextPriv = driContextPriv; c->xm_visual = v; c->xm_buffer = 0; /* Set by MakeCurrent */ c->display = v->display; + c->private = (void *)imesa; - cPriv = (i810ContextPtr)Xmalloc(sizeof(i810Context)); - if (!cPriv) { - Xfree(c); - return NULL; - } + if (share_list) + shareCtx=((i810ContextPtr)(share_list->private))->glCtx; - cPriv->hHWContext = driContextPriv->hHWContext; - cPriv->i810ScrnPriv = sPriv; - c->private = (void *)cPriv; + ctx = imesa->glCtx = gl_create_context(v->gl_visual, shareCtx, + (void*)imesa, GL_TRUE); - cPriv->glVis=v->gl_visual; - cPriv->glBuffer=gl_create_framebuffer(v->gl_visual); - cPriv->screen_width=sPriv->width; - cPriv->screen_height=sPriv->height; - cPriv->new_state = ~0; + /* Set the maximum texture size small enough that we can guarentee + * that both texture units can bind a maximal texture and have them + * in memory at once. + */ + if (i810Screen->textureSize < 2*1024*1024) { + ctx->Const.MaxTextureLevels = 8; + ctx->Const.MaxTextureSize = 1<<8; + } else if (i810Screen->textureSize < 8*1024*1024) { + ctx->Const.MaxTextureLevels = 9; + ctx->Const.MaxTextureSize = 1<<9; + } else { + ctx->Const.MaxTextureLevels = 10; + ctx->Const.MaxTextureSize = 1<<10; + } - if (share_list) - shareCtx=((i810ContextPtr)(share_list->private))->glCtx; - else - shareCtx=0; - cPriv->glCtx=gl_create_context(v->gl_visual, shareCtx, (void*)cPriv, GL_TRUE); - cPriv->initDone=GL_FALSE; - saPriv=(I810SAREAPriv*)((void*)driScrnPriv->pSAREA+sizeof(XF86DRISAREARec)); + /* Dri stuff + */ + imesa->display = v->display; + imesa->hHWContext = driContextPriv->hHWContext; + imesa->driFd = sPriv->fd; + imesa->driHwLock = &sPriv->pSAREA->lock; + imesa->i810Screen = i810Screen; + imesa->driScreen = sPriv; + imesa->sarea = saPriv; - fprintf(stderr, "would call grDRIOpen here\n"); + imesa->glBuffer = gl_create_framebuffer(v->gl_visual, + GL_FALSE, + v->gl_visual->StencilBits > 0, + v->gl_visual->AccumBits > 0, + v->gl_visual->AlphaBits > 0); -/* - grDRIOpen(driScrnPriv->pFB, sPriv->regs.map, sPriv->deviceID, - sPriv->width, sPriv->height, sPriv->mem, sPriv->cpp, sPriv->stride, - sPriv->fifoOffset, sPriv->fifoSize, sPriv->fbOffset, - sPriv->backOffset, sPriv->depthOffset, sPriv->textureOffset, - sPriv->textureSize, &saPriv->fifoPtr, &saPriv->fifoRead); -*/ + imesa->texHeap = mmInit( 0, i810Screen->textureSize ); + + + /* Utah stuff + */ + imesa->renderindex = -1; /* impossible value */ + imesa->new_state = ~0; + imesa->dirty = ~0; + + make_empty_list(&imesa->TexObjList); + make_empty_list(&imesa->SwappedOut); + + imesa->TextureMode = ctx->Texture.Unit[0].EnvMode; + imesa->CurrentTexObj[0] = 0; + imesa->CurrentTexObj[1] = 0; + + i810DDExtensionsInit( ctx ); + + i810DDInitStateFuncs( ctx ); + i810DDInitTextureFuncs( ctx ); + i810DDInitSpanFuncs( ctx ); + i810DDInitDriverFuncs( ctx ); + i810DDInitIoctlFuncs( ctx ); + + ctx->Driver.TriangleCaps = (DD_TRI_CULL| + DD_TRI_LIGHT_TWOSIDE| + DD_TRI_STIPPLE| + DD_TRI_OFFSET); + + /* Ask mesa to clip fog coordinates for us. + */ + ctx->TriangleCaps |= DD_CLIP_FOG_COORD; + + ctx->Shared->DefaultD[2][0].DriverData = 0; + ctx->Shared->DefaultD[2][1].DriverData = 0; + + if (ctx->VB) + i810DDRegisterVB( ctx->VB ); + + if (ctx->NrPipelineStages) + ctx->NrPipelineStages = + i810DDRegisterPipelineStages(ctx->PipelineStage, + ctx->PipelineStage, + ctx->NrPipelineStages); + + i810DDInitState( imesa ); return c; } void XMesaDestroyContext(XMesaContext c) { - i810ContextPtr cPriv; + i810ContextPtr imesa = (i810ContextPtr) c->private; + + if (imesa) { + i810TextureObjectPtr next_t, t; - cPriv=(i810ContextPtr)c->private; - if (cPriv) { - gl_destroy_context(cPriv->glCtx); - gl_destroy_framebuffer(cPriv->glBuffer); + gl_destroy_context(imesa->glCtx); + gl_destroy_framebuffer(imesa->glBuffer); + + foreach_s (t, next_t, &(imesa->TexObjList)) + i810DestroyTexObj(imesa, t); + + foreach_s (t, next_t, &(imesa->SwappedOut)) + i810DestroyTexObj(imesa, t); + + Xfree(imesa); + + c->private = 0; } } @@ -254,137 +424,232 @@ void XMesaDestroyBuffer(XMesaBuffer b) { } -void XMesaSwapBuffers(XMesaBuffer b) +void XMesaSwapBuffers(XMesaBuffer bogus) { - FxI32 result; - XMesaContext *xmc = b->xm_context; - i810ContextPtr imesa; - - if (!xmc || !xmc->private) return; + i810ContextPtr imesa = i810Ctx; - imesa = (i810ContextPtr) xmc->private; + FLUSH_VB( imesa->glCtx, "swap buffers" ); + i810SwapBuffers(imesa); +} + +static void i810InitClipRects( i810ContextPtr imesa ) +{ + switch (imesa->numClipRects) { + case 0: + imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR | + SC_UPDATE_SCISSOR ); + imesa->ClipSetup[I810_CLIPREG_SCI1] = 0; + imesa->ClipSetup[I810_CLIPREG_SCI2] = 0; + break; + case 1: + break; + default: + break; + } + imesa->dirty |= I810_EMIT_CLIPRECT; +} - fprintf(stderr, "imesa %x i810Ctx %x\n", imesa, i810Ctx ); - FLUSH_VB( imesa->glCtx, "swap buffers" ); - if (imesa->haveDoubleBuffer) { - i810BackToFront(imesa); - i810Ctx->stats.swapBuffer++; +void i810XMesaSetFrontClipRects( i810ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + imesa->numClipRects = dPriv->numClipRects; + imesa->pClipRects = dPriv->pClipRects; + imesa->drawX = dPriv->x; + imesa->drawY = dPriv->y; + + imesa->drawMap = imesa->driScreen->pFB; + i810EmitDrawingRectangle( imesa ); + i810InitClipRects( imesa ); +} + + +void i810XMesaSetBackClipRects( i810ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + int i; + + if (dPriv->numBackClipRects == 0) + { + if (I810_DEBUG & DEBUG_VERBOSE_DRI) + fprintf(stderr, "FRONT_CLIPRECTS, %d rects\n", + dPriv->numClipRects); + + imesa->numClipRects = dPriv->numClipRects; + imesa->pClipRects = dPriv->pClipRects; + imesa->drawX = dPriv->x; + imesa->drawY = dPriv->y; } else { - fprintf(stderr, "No double buffer\n"); + if (I810_DEBUG & DEBUG_VERBOSE_DRI) + fprintf(stderr, "BACK_RECTS, %d rects\n", + dPriv->numBackClipRects); + + imesa->numClipRects = dPriv->numBackClipRects; + imesa->pClipRects = dPriv->pBackClipRects; + imesa->drawX = dPriv->backX; + imesa->drawY = dPriv->backY; } + + imesa->drawMap = imesa->i810Screen->back.map; + i810EmitDrawingRectangle( imesa ); + i810InitClipRects( imesa ); + + if (I810_DEBUG & DEBUG_VERBOSE_DRI) + for (i = 0 ; i < imesa->numClipRects ; i++) + fprintf(stderr, "cliprect %d: %d,%d - %d,%d\n", + i, + imesa->pClipRects[i].x1, + imesa->pClipRects[i].y1, + imesa->pClipRects[i].x2, + imesa->pClipRects[i].y2); +} + + +static void i810XMesaWindowMoved( i810ContextPtr imesa ) +{ + if (0) + fprintf(stderr, "i810XMesaWindowMoved\n\n"); + + switch (imesa->glCtx->Color.DriverDrawBuffer) { + case GL_FRONT_LEFT: + i810XMesaSetFrontClipRects( imesa ); + break; + case GL_BACK_LEFT: + i810XMesaSetBackClipRects( imesa ); + break; + default: + fprintf(stderr, "fallback buffer\n"); + break; + } +} + + +GLboolean XMesaUnbindContext(XMesaContext c) +{ + if (c->private) + ((i810ContextPtr)c->private)->dirty = ~0; + + return GL_TRUE; } -/* This looks buggy to me: + +/* This looks buggy to me - the 'b' variable isn't used anywhere... + * Hmm - It seems that the drawable is already hooked in to + * driDrawablePriv. */ GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b) { - __DRIdrawablePrivate *driDrawPriv; + + if (c->private==(void *)i810Ctx) return GL_TRUE; if (c) { - if (c==gCC) return GL_TRUE; - gCC = c; - i810Ctx = (i810ContextPtr)c->private; + __DRIdrawablePrivate *dPriv = c->driContextPriv->driDrawablePriv; - fprintf(stderr, "Make current\n"); - driDrawPriv = c->driContextPriv->driDrawablePriv; - if (!i810Ctx->initDone) { - i810Ctx->width=driDrawPriv->w; - i810Ctx->height=driDrawPriv->h; - if (!i810InitHW(c)) return GL_FALSE; - /* Zap the width to force XMesaWindowMoved to execute */ - i810Ctx->width=0; - } - FX_grSstSelect(i810Ctx->board); - XMesaWindowMoved(); + i810Ctx = (i810ContextPtr)c->private; - FX_grGlideSetState((GrState*)i810Ctx->state); gl_make_current(i810Ctx->glCtx, i810Ctx->glBuffer); - fxSetupDDPointers(i810Ctx->glCtx); + + i810Ctx->driDrawable = dPriv; + i810Ctx->dirty = ~0; + + i810XMesaWindowMoved( i810Ctx ); + if (!i810Ctx->glCtx->Viewport.Width) - gl_Viewport(i810Ctx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h); + gl_Viewport(i810Ctx->glCtx, 0, 0, dPriv->w, dPriv->h); + } else { gl_make_current(0,0); - gCC = NULL; i810Ctx = NULL; } return GL_TRUE; } -void i810XMesaWindowMoved( XMesaContext xmc ) + +void i810GetLock( i810ContextPtr imesa, GLuint flags ) { - i810ContextPtr imesa = (i810ContextPtr) xmc->private; - __DRIdrawablePrivate *dPriv = xmc->driContextPriv->driDrawablePriv; - GLcontext *ctx=imesa->glCtx; - -/* grDRIPosition(dPriv->x, dPriv->y, dPriv->w, dPriv->h, */ -/* dPriv->numClipRects, dPriv->pClipRects); */ - - - imesa->numClipRects=dPriv->numClipRects; - imesa->pClipRects=dPriv->pClipRects; - if (dPriv->x!=imesa->x_offset || dPriv->y!=imesa->y_offset || - dPriv->w!=imesa->width || dPriv->h!=imesa->height) { - imesa->x_offset=dPriv->x; - imesa->y_offset=dPriv->y; - imesa->width=dPriv->w; - imesa->height=dPriv->h; - imesa->y_delta=imesa->screen_height-imesa->y_offset-imesa->height; + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + __DRIscreenPrivate *sPriv = imesa->driScreen; + drm_i810_sarea_t *sarea = imesa->sarea; + int me = imesa->hHWContext; + int stamp = dPriv->lastStamp; + + + if (0) fprintf(stderr, ".\n"); + + /* We know there has been contention. + */ + drmGetLock(imesa->driFd, imesa->hHWContext, flags); + + + /* Note contention for throttling hint + */ + imesa->any_contend = 1; + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + XMESA_VALIDATE_DRAWABLE_INFO(imesa->display, sPriv, dPriv); + + + if (0) + fprintf(stderr, "i810GetLock, last enque: %d last dispatch: %d\n", + sarea->last_enqueue, + sarea->last_dispatch); + + /* If we lost context, need to dump all registers to hardware. + * Note that we don't care about 2d contexts, even if they perform + * accelerated commands, so the DRI locking in the X server is even + * more broken than usual. + */ + if (sarea->ctxOwner != me) { + i810glx.c_ctxlost++; + imesa->dirty |= I810_UPLOAD_CTX; + imesa->dirty |= I810_EMIT_CLIPRECT; + imesa->dirty |= I810_UPLOAD_BUFFERS; + sarea->ctxOwner = me; } - switch (dPriv->numClipRects) { - case 0: - imesa->clipMinX=dPriv->x; - imesa->clipMaxX=dPriv->x+dPriv->w; - imesa->clipMinY=dPriv->y; - imesa->clipMaxY=dPriv->y+dPriv->h; - fxSetScissorValues(ctx); - imesa->needClip=0; - break; - case 1: - imesa->clipMinX=dPriv->pClipRects[0].x1; - imesa->clipMaxX=dPriv->pClipRects[0].x2; - imesa->clipMinY=dPriv->pClipRects[0].y1; - imesa->clipMaxY=dPriv->pClipRects[0].y2; - fxSetScissorValues(ctx); - imesa->needClip=0; - break; - default: - imesa->needClip=1; - } -} -void i810XMesaUpdateState(XMesaContext *xmc, int windowMoved) { - __DRIdrawablePrivate *dPriv = xmc->driContextPriv->driDrawablePriv; - __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; - I810SAREAPriv *saPriv=(I810SAREAPriv*)(((char*)sPriv->pSAREA)+sizeof(XF86DRISAREARec)); - - /* fprintf(stderr, "In FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */ - if (saPriv->fifoOwner!=dPriv->driContextPriv->hHWContext) { - grDRIImportFifo(saPriv->fifoPtr, saPriv->fifoRead); - } - if (saPriv->ctxOwner!=dPriv->driContextPriv->hHWContext) { - grDRIInvalidateAll(); - /* This shouldn't be needed if the state is reset by Glide */ - /* FX_grConstantColorValue_NoLock(FXCOLOR4(&i810Ctx->constColor)); */ - } - if (saPriv->texOwner!=dPriv->driContextPriv->hHWContext) { - fxTMRestoreTextures(i810Ctx); - } - if (windowMoved) - XMesaWindowMoved( xmc ); -} + /* Shared texture managment - if another client has played with + * texture space, figure out which if any of our textures have been + * ejected, and update our global LRU. + */ + if (sarea->texAge != imesa->texAge) { + int sz = 1 << (imesa->i810Screen->logTextureGranularity); + int idx, nr = 0; + + /* Have to go right round from the back to ensure stuff ends up + * LRU in our local list... + */ + for (idx = sarea->texList[I810_NR_TEX_REGIONS].prev ; + idx != I810_NR_TEX_REGIONS && nr < I810_NR_TEX_REGIONS ; + idx = sarea->texList[idx].prev, nr++) + { + if (sarea->texList[idx].age > imesa->texAge) + i810TexturesGone(imesa, idx * sz, sz, sarea->texList[idx].in_use); + } -void i810XMesaSetSAREA( XMesaContext *xmc ) { - __DRIdrawablePrivate *dPriv = xmc->driContextPriv->driDrawablePriv; - __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; - I810SAREAPriv *saPriv=(I810SAREAPriv*)(((char*)sPriv->pSAREA)+sizeof(XF86DRISAREARec)); + if (nr == I810_NR_TEX_REGIONS) { + i810TexturesGone(imesa, 0, imesa->i810Screen->textureSize, 0); + i810ResetGlobalLRU( imesa ); + } + + if (0) fprintf(stderr, "imesa %d sarea %d\n", imesa->texAge, sarea->texAge); + imesa->dirty |= I810_UPLOAD_TEX0IMAGE; + imesa->dirty |= I810_UPLOAD_TEX1IMAGE; + imesa->texAge = sarea->texAge; + } - saPriv->fifoOwner=dPriv->driContextPriv->hHWContext; - saPriv->ctxOwner=dPriv->driContextPriv->hHWContext; - saPriv->texOwner=dPriv->driContextPriv->hHWContext; - grDRIResetSAREA(); - /* fprintf(stderr, "Out FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */ + + if (dPriv->lastStamp != stamp) + i810XMesaWindowMoved( imesa ); + + + sarea->last_quiescent = -1; /* just kill it for now */ } + #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810buf.h b/xc/lib/GL/mesa/src/drv/i810/i810buf.h deleted file mode 100644 index e72b0f225..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810buf.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * GLX Hardware Device Driver for Intel 810 - * Copyright (C) 1999 Keith Whitwell - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Keith Whitwell <keithw@precisioninsight.com> - * - * based on matrox driver by - * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> - * and others. - */ - -#ifndef I810BUF_INC -#define I810BUF_INC - -#include "i810common.h" -#include "i810_3d_reg.h" -#include "types.h" -#include "mm.h" - -#define VALID_I810_BUFFER(b) (b) - - -struct i810_dest_buffer -{ - int refcount; - PMemBlock MemBlock; - GLuint Setup[I810_DEST_SETUP_SIZE]; - - int Format; - int Width; /* in pixels */ - int Height; - int Pitch; - int BytesPerPixel; - int Size; - int Drawable; - char *BufAddr; - struct i810_z_buffer *ZBuffer; -}; - -struct i810_z_buffer -{ - int refcount; - PMemBlock MemBlock; - - int Format; - char *BufAddr; - - int Pitch; -}; - - - -/* Don't bother trying to hide the differences between these types of - * buffer. - */ -struct i810_dest_buffer *i810CreateDestBuffer(int Format, - int Width, - int Height); -void i810DestroyDestBuffer(struct i810_dest_buffer *buf); - - - -/* Parent is a dest-buffer, supplies geometry info. - */ -struct i810_z_buffer *i810CreateZBuffer( struct i810_dest_buffer *parent ); -void i810FreeZBuffer(struct i810_z_buffer *buf); - - - - - -#endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.c b/xc/lib/GL/mesa/src/drv/i810/i810clear.c index 3749b9659..f6e74beb8 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810clear.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810clear.c @@ -1,144 +1,145 @@ -#include "xsmesaP.h" -#include "mesaglx/types.h" +#include "types.h" #include "vbrender.h" -#include "glx_log.h" - -#include "vga.h" -#include "vgaPCI.h" +#include "i810log.h" #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include "mm.h" #include "i810lib.h" #include "i810dd.h" -#include "i810glx.h" #include "i810clear.h" #include "i810state.h" #include "i810tris.h" +#include "i810ioctl.h" + +#define DEPTH_SCALE 65535.0F + +static void i810_clear_buffer( GLcontext *ctx, + GLboolean all, + GLint cx, GLint cy, + GLint cwidth, + GLint cheight, + GLushort value, + GLuint offset ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + i810ScreenPrivate *i810Screen = imesa->i810Screen; + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + int _nc = imesa->numClipRects; + XF86DRIClipRectPtr box = imesa->pClipRects; + + cy = dPriv->h-cy-cheight; + cx += imesa->drawX; + cy += imesa->drawY; + + while (_nc--) { + GLint x = box[_nc].x1; + GLint y = box[_nc].y1; + GLint width = box[_nc].x2 - x; + GLint height = box[_nc].y2 - y; + + if (!all) { + if (x < cx) width -= cx - x, x = cx; + if (y < cy) height -= cy - y, y = cy; + if (x + width > cx + cwidth) width = cx + cwidth - x; + if (y + height > cy + cheight) height = cy + cheight - y; + if (width <= 0) continue; + if (height <= 0) continue; + } + + if (I810_DEBUG&DEBUG_VERBOSE_2D) + fprintf(stderr, "clear color rect %d,%d %dx%d\n", + (int) x, (int) y, (int) width, (int) height); + + + { + int start = (offset + + y * i810Screen->backPitch + + x * i810Screen->cpp); + + BEGIN_BATCH( imesa, 6 ); + + OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); + OUT_BATCH( BR13_SOLID_PATTERN | + (0xF0 << 16) | + i810Screen->backPitch ); + OUT_BATCH( (height << 16) | (width * i810Screen->cpp)); + OUT_BATCH( start ); + OUT_BATCH( value ); + OUT_BATCH( 0 ); + + ADVANCE_BATCH(); + } + } +} + /* * i810Clear - * perform hardware accelerated clearing of the color and/or depth - * buffer. Software may still clear stencil buffers. - * If all==GL_TRUE, clear whole buffer, else just clear region defined - * by x,y,width,height + * + * Clear the color and/or depth buffers. If 'all' is GL_TRUE, clear + * whole buffer, otherwise clear the region defined by the remaining + * parameters. */ - - GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) + GLint cx, GLint cy, GLint cwidth, GLint cheight ) { - XSMesaContext xsmesa = (XSMesaContext) ctx->DriverCtx; - GLubyte *c; - GLuint zval; + i810ContextPtr imesa = I810_CONTEXT( ctx ); + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); - i810Msg(10, "i810Clear( %i, %i, %i, %i, %i )\n", - mask, x, y, width, height ); + if (I810_DEBUG&DEBUG_VERBOSE_API) + fprintf(stderr, "i810Clear( %d, %d, %d, %d, %d )\n", + (int)mask, (int)cx, (int)cy, (int)cwidth, (int)cheight ); - CHECK_CONTEXT( return mask; ); - - if (all == GL_TRUE) { - x = 0; - y = 0; - width = i810DB->Width; - height = i810DB->Height; - } - - if ( y + height > i810DB->Height ) { - height = i810DB->Height - y; - } - if ( x + width > i810DB->Width ) { - width = i810DB->Width - x; - } - if ( x < 0 ) { - width += x; - x = 0; - } - if ( y < 0 ) { - height += y; - y = 0; - } - if ( x >= i810DB->Width || y >= i810DB->Height || width < 1 || height < 1 ) { - return 0; - } - - /* flip top to bottom */ - y = i810DB->Height-y-height; - c = xsmesa->clearcolor; - zval = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE); - - i810FinishPrimitive(); + FLUSH_BATCH(imesa); + + LOCK_HARDWARE(imesa); + i810GetGeneralDmaBufferLocked( imesa ); - if (1) { - BEGIN_BATCH(2); + BEGIN_BATCH( imesa, 2 ); OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH ); - OUT_BATCH( 0 ); /* pad to quadword */ + OUT_BATCH( 0 ); ADVANCE_BATCH(); } - /* color buffer */ - if (mask & GL_COLOR_BUFFER_BIT) - { - int start = (i810DB->MemBlock->ofs + - y * i810DB->Pitch + - x * vgaBytesPerPixel); - - BEGIN_BATCH(6); - - OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); - OUT_BATCH( BR13_SOLID_PATTERN | - (0xF0 << 16) | - i810DB->Pitch ); - OUT_BATCH( (height << 16) | (width * vgaBytesPerPixel)); - OUT_BATCH( start ); - OUT_BATCH( i810PackColor( i810DB->Format, c[0], c[1], c[2], c[3] ) ); - OUT_BATCH( 0 ); - - ADVANCE_BATCH(); - - mask &= ~GL_COLOR_BUFFER_BIT; + if ( (mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) { + i810_clear_buffer( ctx, all, cx, cy, cwidth, cheight, + imesa->ClearColor, + imesa->i810Screen->fbOffset); + mask &= ~DD_FRONT_LEFT_BIT; } - /* depth buffer */ - if ( (mask & GL_DEPTH_BUFFER_BIT) && - i810DB->ZBuffer && - ctx->Depth.Mask ) - { - int start = (i810DB->ZBuffer->MemBlock->ofs + - y * i810DB->ZBuffer->Pitch + - x * 2); - - BEGIN_BATCH(6); - - OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); - OUT_BATCH( BR13_SOLID_PATTERN | - (0xF0 << 16) | - i810DB->ZBuffer->Pitch ); - OUT_BATCH( (height << 16) | (width * 2)); - OUT_BATCH( start ); - OUT_BATCH( zval ); - OUT_BATCH( 0 ); - - ADVANCE_BATCH(); - - mask &= ~GL_DEPTH_BUFFER_BIT; + if ( (mask & DD_BACK_LEFT_BIT) && colorMask == ~0) { + i810_clear_buffer( ctx, all, cx, cy, cwidth, cheight, + imesa->ClearColor, + imesa->i810Screen->backOffset); + mask &= ~DD_BACK_LEFT_BIT; } - if (1) + if ( (mask & DD_DEPTH_BIT) && ctx->Depth.Mask ) { + i810_clear_buffer( ctx, all, cx, cy, cwidth, cheight, + ctx->Depth.Clear * DEPTH_SCALE, + imesa->i810Screen->depthOffset); + mask &= ~DD_DEPTH_BIT; + } + { - BEGIN_BATCH(2); + BEGIN_BATCH( imesa, 2 ); OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH ); - OUT_BATCH( 0 ); /* pad to quadword */ + OUT_BATCH( 0 ); ADVANCE_BATCH(); } + i810FlushGeneralLocked(imesa); + UNLOCK_HARDWARE( imesa ); return mask; } - diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.c b/xc/lib/GL/mesa/src/drv/i810/i810context.c deleted file mode 100644 index a9bd855d5..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810context.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * GLX Hardware Device Driver for Intel i810 - * Copyright (C) 1999 Keith Whitwell - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "xsmesaP.h" -#include <stdlib.h> -#include <stdio.h> -#include <time.h> -#include <GL/gl.h> - -#include "i810context.h" -#include "i810lib.h" -#include "i810log.h" -#include "i810dd.h" -#include "i810pipeline.h" -/* #include "i810render.h" */ -#include "i810state.h" -#include "i810tris.h" -#include "simple_list.h" - - - -i810ContextPtr i810CreateContext(GLcontext *ctx) -{ - i810ContextPtr c; - - c = (i810ContextPtr) calloc(1,sizeof(i810Context)); - if (!c) - return NULL; - - c->gl_ctx = ctx; - - c->renderindex = -1; /* impossible value */ - c->new_state = ~0; - c->reg_dirty = ~0; - - make_empty_list(&c->SwappedOut); - make_empty_list(&c->TexObjList); - - c->TextureMode = ctx->Texture.Unit[0].EnvMode; - - c->CurrentTex0Obj = 0; - c->CurrentTex1Obj = 0; - ctx->Shared->DefaultD[2][0].DriverData = 0; - ctx->Shared->DefaultD[2][1].DriverData = 0; - - if (ctx->VB) - i810DDRegisterVB( ctx->VB ); - - if (ctx->NrPipelineStages) - ctx->NrPipelineStages = - i810DDRegisterPipelineStages(ctx->PipelineStage, - ctx->PipelineStage, - ctx->NrPipelineStages); - - - /* Ask mesa to clip fog coordinates for us. - */ - ctx->TriangleCaps |= DD_CLIP_FOG_COORD; - - -#if 0 - if (!getenv("I810_NO_FAST_PATH")) - ctx->Driver.BuildPrecalcPipeline = i810DDBuildPrecalcPipeline; - - i810DDRenderInit(); - i810DDFastPathInit(); -#endif - - - i810DDTrifuncInit(); - i810DDSetupInit(); - i810DDExtensionsInit( ctx ); - - i810_setup_DD_pointers( ctx ); - i810DDInitState( c ); - - if (MESA_VERBOSE&VERBOSE_DRIVER) - fprintf(stderr,"i810CreateContext(): successful.\n"); - - return c; -} - -int i810DestroyContext(i810ContextPtr ctx) -{ - i810TextureObjectPtr next_t, t; - - if (!ctx) - return 0; - - if (--(ctx->refcount) > 0) - return 0; - - foreach_s (t, next_t, &(ctx->TexObjList)) - i810DestroyTexObj(ctx, t); - - foreach_s (t, next_t, &(ctx->SwappedOut)) - i810DestroyTexObj(ctx, t); - - free(ctx); - - if (MESA_VERBOSE&VERBOSE_DRIVER) - fprintf(stderr,"i810DestroyContext(): successfully destroyed.\n"); - - return 0; -} diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.h b/xc/lib/GL/mesa/src/drv/i810/i810context.h index 754a0e3f1..6a7ffa968 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810context.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810context.h @@ -26,60 +26,82 @@ #ifndef I810CONTEXT_INC #define I810CONTEXT_INC +typedef struct i810_context_t i810Context; +typedef struct i810_context_t *i810ContextPtr; + +#include <X11/Xlibint.h> +#include "dri_tmm.h" +#include "dri_mesaint.h" +#include "dri_mesa.h" +#include "xmesaP.h" -#include "mesaglx/types.h" +#include "types.h" +#include "i810_init.h" +#include "drm.h" -#include "i810common.h" -#include "i810buf.h" #include "i810tex.h" #include "i810vb.h" -#include "xsmesaP.h" -/* Hmmm */ -#define FALLBACK_TEXTURE 1 + +#define I810_FALLBACK_TEXTURE 0x1 +#define I810_FALLBACK_DRAW_BUFFER 0x2 +#define I810_FALLBACK_READ_BUFFER 0x4 +#define I810_FALLBACK_COLORMASK 0x8 +#define I810_FALLBACK_STIPPLE 0x10 +#define I810_FALLBACK_SPECULAR 0x20 + +/* for i810ctx.new_state - manage GL->driver state changes + */ +#define I810_NEW_TEXTURE 0x1 + +/* for i810ctx.dirty - manage driver->hw state changes, including + * lost contexts. + */ +#define I810_WAIT_AGE 0x1 +#define I810_UPLOAD_TEX0IMAGE 0x2 +#define I810_UPLOAD_TEX1IMAGE 0x4 +#define I810_UPLOAD_CTX 0x8 +#define I810_UPLOAD_BUFFERS 0x10 +#define I810_REFRESH_RING 0x20 +#define I810_EMIT_CLIPRECT 0x40 -#define I810_NEW_TEXTURE 0x20 -#define I810_NEW_CONTEXT 0x100 +typedef void (*i810_interp_func)( GLfloat t, + GLfloat *result, + const GLfloat *in, + const GLfloat *out ); + struct i810_context_t { GLint refcount; - struct i810_dest_buffer *DB; - GLcontext *gl_ctx; + GLcontext *glCtx; - i810TextureObjectPtr CurrentTex0Obj; - i810TextureObjectPtr CurrentTex1Obj; + i810TextureObjectPtr CurrentTexObj[2]; - struct i810_texture_object_t TexObjList, SwappedOut; + struct i810_texture_object_t TexObjList; + struct i810_texture_object_t SwappedOut; int TextureMode; - /* flags - */ - int GlobalPaletteUpdated:1; - - /* Hardware state */ GLuint Setup[I810_CTX_SETUP_SIZE]; + GLuint BufferSetup[I810_DEST_SETUP_SIZE]; + GLuint ClipSetup[I810_CLIP_SETUP_SIZE]; - /* Context hardware state mirrors. - */ - GLushort GlobalPalette[256]; - /* Support for CVA and the fast paths. */ GLuint setupdone; GLuint setupindex; GLuint renderindex; GLuint using_fast_path; -/* gl_vertex_interp_func interp; */ + i810_interp_func interp; /* Shortcircuit some state changes. */ @@ -90,39 +112,98 @@ struct i810_context_t { /* Manage our own state */ GLuint new_state; - GLuint reg_dirty; - + + /* Manage hardware state */ + GLuint dirty; + memHeap_t *texHeap; + /* One of the few bits of hardware state that can't be calculated * completely on the fly: */ GLuint LcsCullMode; - /* For mono span and pixel funcs. + /* Funny mesa mirrors */ - GLushort CurrentColor; + GLushort MonoColor; + GLushort ClearColor; /* DRI stuff */ - GLuint needClip; - GLuint clipMinX; - GLuint clipMaxX; - GLuint clipMinY; - GLuint clipMaxY; + drmBufPtr dma_buffer; + drmBufPtr vertex_dma_buffer; + + GLframebuffer *glBuffer; + /* Two flags to keep track of fallbacks. + */ + GLuint IndirectTriangles; + GLuint Fallback; - drmContext hHWContext; - int numClipRects; + + GLuint needClip; + + /* These refer to the current draw (front vs. back) buffer: + */ + char *drawMap; /* draw buffer address in virtual mem */ + char *readMap; + int drawX; /* origin of drawable in draw buffer */ + int drawY; + GLuint numClipRects; /* cliprects for that buffer */ XF86DRIClipRectPtr pClipRects; - i810ScreenPrivate *i810ScrnPriv; + + int lastSwap; + int secondLastSwap; + int texAge; + int ctxAge; + int dirtyAge; + int any_contend; /* throttle me harder */ + + int scissor; + + int lines_are_tris; /* not used */ + int horiz_line_stipple; + int vert_line_stipple; + + int poly_stipple; + + drm_clip_rect_t draw_rect; + drm_clip_rect_t scissor_rect; + + drmContext hHWContext; + drmLock *driHwLock; + int driFd; + Display *display; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + i810ScreenPrivate *i810Screen; + drm_i810_sarea_t *sarea; }; -typedef struct i810_context_t i810Context; -typedef struct i810_context_t *i810ContextPtr; + +/* To remove all debugging, make sure I810_DEBUG is defined as a + * preprocessor symbol, and equal to zero. + */ +#define I810_DEBUG 0 +#ifndef I810_DEBUG +#warning "Debugging enabled - expect reduced performance" +extern int I810_DEBUG; +#endif + +#define DEBUG_VERBOSE_2D 0x1 +#define DEBUG_VERBOSE_RING 0x8 +#define DEBUG_VERBOSE_OUTREG 0x10 +#define DEBUG_ALWAYS_SYNC 0x40 +#define DEBUG_VERBOSE_MSG 0x80 +#define DEBUG_NO_OUTRING 0x100 +#define DEBUG_NO_OUTREG 0x200 +#define DEBUG_VERBOSE_API 0x400 +#define DEBUG_VALIDATE_RING 0x800 +#define DEBUG_VERBOSE_LRU 0x1000 +#define DEBUG_VERBOSE_DRI 0x2000 +#define DEBUG_VERBOSE_IOCTL 0x4000 -i810ContextPtr i810CreateContext(GLcontext *ctx); /* Do I need visual info? */ -int i810DestroyContext(i810ContextPtr ctx); -int i810BindBuffer(i810ContextPtr ctx, struct i810_dest_buffer *buf); extern GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out, const struct gl_pipeline_stage *in, diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.c b/xc/lib/GL/mesa/src/drv/i810/i810dd.c index 7a762ce9b..954f60a79 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810dd.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.c @@ -30,17 +30,15 @@ #include "mm.h" #include "i810lib.h" -#include "i810glx.h" #include "i810clear.h" #include "i810dd.h" -#include "i810direct.h" -#include "i810depth.h" #include "i810log.h" #include "i810state.h" #include "i810span.h" #include "i810tex.h" #include "i810tris.h" #include "i810vb.h" +#include "i810pipeline.h" #include "extensions.h" #include "vb.h" #include "dd.h" @@ -54,18 +52,39 @@ extern int xf86VTSema; ***************************************/ -const GLubyte *i810DDGetString( GLcontext *ctx, GLenum name ) +static const GLubyte *i810DDGetString( GLcontext *ctx, GLenum name ) { switch (name) { case GL_VENDOR: return "Keith Whitwell, Precision Insight Inc."; case GL_RENDERER: - return "GLX-I810"; + return "DRI-I810"; default: return 0; } } +static GLint i810GetParameteri(const GLcontext *ctx, GLint param) +{ + switch (param) { + case DD_HAVE_HARDWARE_FOG: + return 1; + default: + return 0; + } +} + + + +static void i810BufferSize(GLcontext *ctx, GLuint *width, GLuint *height) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + *width = imesa->driDrawable->w; + *height = imesa->driDrawable->h; +} + + + void i810DDExtensionsInit( GLcontext *ctx ) { @@ -86,77 +105,26 @@ void i810DDExtensionsInit( GLcontext *ctx ) gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); + if (0) gl_extensions_disable( ctx, "GL_ARB_multitexture" ); + + /* We do support tex_env_add, however */ gl_extensions_enable( ctx, "GL_EXT_texture_env_add" ); } -static GLint i810GetParameteri(const GLcontext *ctx, GLint param) -{ - switch (param) { - case DD_HAVE_HARDWARE_FOG: - return 1; - default: - return 0; - } -} -GLboolean i810IsTextureResident( GLcontext *ctx, struct gl_texture_object *t ) +void i810DDInitDriverFuncs( GLcontext *ctx ) { - i810TextureObjectPtr mt = (i810TextureObjectPtr)t->DriverData; - return mt && mt->MemBlock; -} - - - - -void i810_setup_DD_pointers( GLcontext *ctx ) -{ - i810DDInitStatePointers(ctx); - + ctx->Driver.GetBufferSize = i810BufferSize; ctx->Driver.GetString = i810DDGetString; - ctx->Driver.UpdateState = i810DDUpdateState; + ctx->Driver.GetParameteri = i810GetParameteri; ctx->Driver.RegisterVB = i810DDRegisterVB; ctx->Driver.UnregisterVB = i810DDUnregisterVB; ctx->Driver.Clear = i810Clear; - ctx->Driver.GetParameteri = i810GetParameteri; - ctx->Driver.TexEnv = i810TexEnv; - ctx->Driver.TexImage = i810TexImage; - ctx->Driver.TexSubImage = i810TexSubImage; - ctx->Driver.BindTexture = i810BindTexture; - ctx->Driver.DeleteTexture = i810DeleteTexture; - ctx->Driver.TexParameter = i810TexParameter; - ctx->Driver.UpdateTexturePalette = i810UpdateTexturePalette; - ctx->Driver.IsTextureResident = i810IsTextureResident; - - ctx->Driver.TriangleCaps = (DD_TRI_CULL| - DD_TRI_LIGHT_TWOSIDE| - DD_TRI_OFFSET); - - i810DDInitSpans( ctx ); - - ctx->Driver.ReadDepthSpanFloat = i810_read_depth_span_float; - ctx->Driver.ReadDepthSpanInt = i810_read_depth_span_int; - if (ctx->Depth.Test) { - switch (ctx->Depth.Func) { - case GL_LESS: - ctx->Driver.DepthTestSpan = i810_depth_test_span_less; - ctx->Driver.DepthTestPixels = i810_depth_test_pixels_less; - break; - case GL_GREATER: - ctx->Driver.DepthTestSpan = i810_depth_test_span_greater; - ctx->Driver.DepthTestPixels = i810_depth_test_pixels_greater; - break; - default: - ctx->Driver.DepthTestSpan = i810_depth_test_span_generic; - ctx->Driver.DepthTestPixels = i810_depth_test_pixels_generic; - break; - } - } - /* Also do the normal GL state-change checks. - */ - i810DDUpdateState( ctx ); + + ctx->Driver.BuildPrecalcPipeline = i810DDBuildPrecalcPipeline; } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.h b/xc/lib/GL/mesa/src/drv/i810/i810dd.h index 1274e66e2..86a8618d0 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810dd.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.h @@ -25,23 +25,9 @@ #ifndef I810DD_INC #define I810DD_INC -#include "mesaglx/context.h" +#include "context.h" -#include "i810buf.h" - -void i810_setup_DD_pointers( GLcontext *ctx ); -void i810DDRegisterVB( struct vertex_buffer *VB ); - -void i810DDFastPath( struct vertex_buffer *VB ); -void i810DDImmediateFastPath( struct vertex_buffer *VB ); -void i810DDFastPathInit(); void i810DDExtensionsInit( GLcontext *ctx ); - -void i810_setup_DD_pointers_no_accel( GLcontext *ctx ); -/* void i810FinishPrimitive( void ); */ - -#define i810FinishPrimitive() - - +void i810DDInitDriverFuncs( GLcontext *ctx ); #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810depth.c b/xc/lib/GL/mesa/src/drv/i810/i810depth.c deleted file mode 100644 index 9b089f7de..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810depth.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 3.1 - * - * Copyright (C) 1999 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * This file has been modified by Wittawat Yamwong for GLX module. - */ - -/* - * Depth buffer functions - */ - - -#ifdef PC_HEADER -#include "all.h" -#else -#include <stdlib.h> -#include <string.h> -#include "mesaglx/context.h" -#include "i810depth.h" -#include "mesaglx/types.h" -#include "mm.h" -#include "i810lib.h" -#endif - - - -/* - * Return the address of the Z-buffer value for window coordinate (x,y): - */ -#define Z_SETUP \ - GLdepth *zbstart = (GLdepth *)i810DB->ZBuffer->BufAddr; \ - GLint zbpitch = i810DB->ZBuffer->Pitch; -#define Z_ADDRESS( X, Y ) \ - (zbstart + zbpitch * (Y) + (X)) - - -/**********************************************************************/ -/***** Depth Testing Functions *****/ -/**********************************************************************/ - - -/* - * Depth test horizontal spans of fragments. These functions are called - * via ctx->Driver.depth_test_span only. - * - * Input: n - number of pixels in the span - * x, y - location of leftmost pixel in span in window coords - * z - array [n] of integer depth values - * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw) - * Return: number of pixels which passed depth test - */ - - -/* - * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ). - */ -GLuint i810_depth_test_span_generic( GLcontext* ctx, - GLuint n, GLint x, GLint y, - const GLdepth z[], - GLubyte mask[] ) -{ - Z_SETUP - GLdepth *zptr = Z_ADDRESS( x, y ); - GLubyte *m = mask; - GLuint i; - GLuint passed = 0; - - i810WaitDrawingEngine(); - - /* switch cases ordered from most frequent to less frequent */ - switch (ctx->Depth.Func) { - case GL_LESS: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0; i<n; i++,zptr++,m++) { - if (*m) { - if (z[i] < *zptr) { - /* pass */ - *zptr = z[i]; - passed++; - } - else { - /* fail */ - *m = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0; i<n; i++,zptr++,m++) { - if (*m) { - if (z[i] < *zptr) { - /* pass */ - passed++; - } - else { - *m = 0; - } - } - } - } - break; - case GL_LEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] <= *zptr) { - *zptr = z[i]; - passed++; - } - else { - *m = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] <= *zptr) { - /* pass */ - passed++; - } - else { - *m = 0; - } - } - } - } - break; - case GL_GEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] >= *zptr) { - *zptr = z[i]; - passed++; - } - else { - *m = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] >= *zptr) { - /* pass */ - passed++; - } - else { - *m = 0; - } - } - } - } - break; - case GL_GREATER: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] > *zptr) { - *zptr = z[i]; - passed++; - } - else { - *m = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] > *zptr) { - /* pass */ - passed++; - } - else { - *m = 0; - } - } - } - } - break; - case GL_NOTEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] != *zptr) { - *zptr = z[i]; - passed++; - } - else { - *m = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] != *zptr) { - /* pass */ - passed++; - } - else { - *m = 0; - } - } - } - } - break; - case GL_EQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] == *zptr) { - *zptr = z[i]; - passed++; - } - else { - *m =0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - if (z[i] == *zptr) { - /* pass */ - passed++; - } - else { - *m =0; - } - } - } - } - break; - case GL_ALWAYS: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0;i<n;i++,zptr++,m++) { - if (*m) { - *zptr = z[i]; - passed++; - } - } - } - else { - /* Don't update Z buffer or mask */ - passed = n; - } - break; - case GL_NEVER: - for (i=0;i<n;i++) { - mask[i] = 0; - } - break; - default: - gl_problem(ctx, "Bad depth func in gl_depth_test_span_generic"); - } /*switch*/ - - return passed; -} - - - -/* - * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE). - */ -GLuint i810_depth_test_span_less( GLcontext* ctx, - GLuint n, GLint x, GLint y, const GLdepth z[], - GLubyte mask[] ) -{ - Z_SETUP - GLdepth *zptr = Z_ADDRESS( x, y ); - GLuint i; - GLuint passed = 0; - - i810WaitDrawingEngine(); - - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] < zptr[i]) { - /* pass */ - zptr[i] = z[i]; - passed++; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - return passed; -} - - -/* - * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE). - */ -GLuint i810_depth_test_span_greater( GLcontext* ctx, - GLuint n, GLint x, GLint y, - const GLdepth z[], - GLubyte mask[] ) -{ - Z_SETUP - GLdepth *zptr = Z_ADDRESS( x, y ); - GLuint i; - GLuint passed = 0; - - i810WaitDrawingEngine(); - - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] > zptr[i]) { - /* pass */ - zptr[i] = z[i]; - passed++; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - return passed; -} - - - -/* - * Depth test an array of randomly positioned fragments. - */ - -/* - * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ). - */ -void i810_depth_test_pixels_generic( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) -{ - Z_SETUP - register GLdepth *zptr; - register GLuint i; - - i810WaitDrawingEngine(); - - /* switch cases ordered from most frequent to less frequent */ - switch (ctx->Depth.Func) { - case GL_LESS: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] < *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] < *zptr) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_LEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] <= *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] <= *zptr) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_GEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] >= *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] >= *zptr) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_GREATER: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] > *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] > *zptr) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_NOTEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] != *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] != *zptr) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_EQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] == *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] == *zptr) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_ALWAYS: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - *zptr = z[i]; - } - } - } - else { - /* Don't update Z buffer or mask */ - } - break; - case GL_NEVER: - /* depth test never passes */ - for (i=0;i<n;i++) { - mask[i] = 0; - } - break; - default: - gl_problem(ctx, "Bad depth func in gl_depth_test_pixels_generic"); - } /*switch*/ -} - - - -/* - * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ). - */ -void i810_depth_test_pixels_less( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) -{ - Z_SETUP - GLdepth *zptr; - GLuint i; - - i810WaitDrawingEngine(); - - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] < *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } -} - - -/* - * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ). - */ -void i810_depth_test_pixels_greater( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) -{ - Z_SETUP - GLdepth *zptr; - GLuint i; - - i810WaitDrawingEngine(); - - for (i=0; i<n; i++) { - if (mask[i]) { - zptr = Z_ADDRESS(x[i],y[i]); - if (z[i] > *zptr) { - /* pass */ - *zptr = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } -} - - - - -/**********************************************************************/ -/***** Read Depth Buffer *****/ -/**********************************************************************/ - - -/* - * Return a span of depth values from the depth buffer as floats in [0,1]. - * This function is only called through Driver.read_depth_span_float() - * Input: n - how many pixels - * x,y - location of first pixel - * Output: depth - the array of depth values - */ -void i810_read_depth_span_float( GLcontext* ctx, - GLuint n, GLint x, GLint y, GLfloat depth[] ) -{ - Z_SETUP - GLdepth *zptr; - GLfloat scale; - GLuint i; - - i810WaitDrawingEngine(); - - scale = 1.0F / DEPTH_SCALE; - - if (ctx->Buffer->Depth) { - zptr = Z_ADDRESS( x, y ); - for (i=0;i<n;i++) { - depth[i] = (GLfloat) zptr[i] * scale; - } - } - else { - for (i=0;i<n;i++) { - depth[i] = 0.0F; - } - } -} - - -/* - * Return a span of depth values from the depth buffer as integers in - * [0,MAX_DEPTH]. - * This function is only called through Driver.read_depth_span_int() - * Input: n - how many pixels - * x,y - location of first pixel - * Output: depth - the array of depth values - */ -void i810_read_depth_span_int( GLcontext* ctx, - GLuint n, GLint x, GLint y, GLdepth depth[] ) -{ - Z_SETUP - - i810WaitDrawingEngine(); - - if (ctx->Buffer->Depth) { - GLdepth *zptr = Z_ADDRESS( x, y ); - MEMCPY( depth, zptr, n * sizeof(GLdepth) ); - } - else { - GLuint i; - for (i=0;i<n;i++) { - depth[i] = 0; - } - } -} diff --git a/xc/lib/GL/mesa/src/drv/i810/i810depth.h b/xc/lib/GL/mesa/src/drv/i810/i810depth.h deleted file mode 100644 index 878fbefe8..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810depth.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 3.1 - * - * Copyright (C) 1999 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * This file has been modified by Wittawat Yamwong for GLX module. - */ - - -#ifndef I810DEPTH_INC -#define I810DEPTH_INC - - -#include "mesaglx/types.h" - - - - - -extern GLuint -i810_depth_test_span_generic( GLcontext* ctx, GLuint n, GLint x, GLint y, - const GLdepth z[], GLubyte mask[] ); - -extern GLuint -i810_depth_test_span_less( GLcontext* ctx, GLuint n, GLint x, GLint y, - const GLdepth z[], GLubyte mask[] ); - -extern GLuint -i810_depth_test_span_greater( GLcontext* ctx, GLuint n, GLint x, GLint y, - const GLdepth z[], GLubyte mask[] ); - - - -extern void -i810_depth_test_pixels_generic( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ); - -extern void -i810_depth_test_pixels_less( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ); - -extern void -i810_depth_test_pixels_greater( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ); - - -extern void i810_read_depth_span_float( GLcontext* ctx, - GLuint n, GLint x, GLint y, - GLfloat depth[] ); - - -extern void i810_read_depth_span_int( GLcontext* ctx, GLuint n, GLint x, GLint y, - GLdepth depth[] ); - - - -#endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.c b/xc/lib/GL/mesa/src/drv/i810/i810dma.c deleted file mode 100644 index f745d272f..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810dma.c +++ /dev/null @@ -1,363 +0,0 @@ -/* -*- mode: C; c-basic-offset:8 -*- */ -/* - * GLX Hardware Device Driver for Intel i810 - * Copyright (C) 1999 Keith Whitwell - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * based on the original mgadma.c by Jeff Hartmann <slicer@ionet.net> - * as rewritten by John Carmack <johnc@idsoftware.com> - */ - -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <sys/mman.h> -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> - -#include "mm.h" -#include "i810buf.h" -#include "i810dd.h" -#include "i810lib.h" -#include "i810log.h" -#include "i810tris.h" -#include "i810direct.h" -#include "i810state.h" - -#include "pb.h" - -/* X server include: - */ -#include "i810.h" - - - -/* This will be overwritten from the default values when glx.so is - * loaded on the client. - */ -void i810ServerDmaFlush( int wait ); -GLuint i810ActiveDmaBuffer = 0; - - - -#ifndef I810_DEBUG -int I810_DEBUG = (0 -/* | DEBUG_ALWAYS_SYNC */ -/* | DEBUG_VERBOSE_ACCEL */ -/* | DEBUG_VERBOSE_SYNC */ -/* | DEBUG_VERBOSE_VGA */ -/* | DEBUG_VERBOSE_RING */ -/* | DEBUG_VERBOSE_OUTREG */ -/* | DEBUG_VERBOSE_MEMORY */ -/* | DEBUG_ALWAYS_SYNC */ -/* | DEBUG_VERBOSE_MSG */ - ); -#endif - - - -static void delay( void ) { -} - - - -int i810WaitForDmaCompletion( void ) -{ - int start, end; - - if (I810LpRing.head == I810LpRing.tail && I810LpRing.space) - return 0; - - start = i810_usec(); - I810LpRing.head = INREG(I810LpRing.base_reg + RING_HEAD); - end = i810_usec(); - - if (0 && start + 100 < end) - fprintf(stderr, "INREG in WaitForDma: %d usec\n", end - start); - - I810LpRing.head &= HEAD_ADDR; - I810LpRing.space = I810LpRing.head - (I810LpRing.tail + 8); - if (I810LpRing.space < 0) - I810LpRing.space += I810LpRing.mem.Size; - - if (I810LpRing.head == I810LpRing.tail) - return 0; - - start = i810_usec(); - I810Sync(); - end = i810_usec(); - - return 1; -} - - - -/* - * i810DmaResetBuffer - */ -void i810DmaResetBuffer( void ) { - - i810glx.dma_buffer = dmaBuffers[ i810ActiveDmaBuffer ]; - i810glx.dma_buffer->head = 0; - i810glx.dma_buffer->space = 0; - i810glx.dma_buffer->additional_space = - i810glx.dma_buffer->mem.Size - 256; - - i810DmaOverflow( 0 ); - - if (i810glx.dma_buffer_age < i810glx.dma_buffer->texture_age) - i810glx.dma_buffer_age = i810glx.dma_buffer->texture_age; -} - - - - -/* - * i810FlushRealDma - */ -void i810FlushRealDma( void ) { - - GLuint start; - - if (MESA_VERBOSE&VERBOSE_DRIVER) - fprintf(stderr, "i810FlushRealDma()\n" ); - - - if ( i810glx.skipDma || !I810_USE_BATCH ) - return; - - - if (i810glx.dma_buffer->head & 0x4) { - FatalError( "Misaligned batch buffer\n" ); - } - - if ( (I810_DEBUG&DEBUG_VERBOSE_OUTREG) && 0) - { - int i; - for (i = 0 ; i <= i810glx.dma_buffer->head ; i+=4) - fprintf(stderr, - " 0x%05x : 0x%08x\n", - i/4, - *(GLuint *)(i810glx.dma_buffer->virtual_start + - i)); - } - - - /* fire the batch buffer */ - for (start = 0 ; start < i810glx.dma_buffer->head ; start += MAX_BATCH) - { - GLuint ofs = i810glx.dma_buffer->mem.Start; - GLuint end = MIN2(start + MAX_BATCH, i810glx.dma_buffer->head); - - BEGIN_LP_RING(4); - OUT_RING( CMD_OP_BATCH_BUFFER ); - OUT_RING( (ofs + start) | BB1_PROTECTED ); - OUT_RING( (ofs + end) - 4 ); - OUT_RING( 0 ); - ADVANCE_LP_RING(); - } - - { - BEGIN_LP_RING(2); - OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | - INST_FLUSH_MAP_CACHE ); - OUT_RING( 0 ); - } -} - -/* - * i810DmaFlush - * Send all pending commands off to the hardware. - * If we are running async, the hardware will be drawing - * while we return to do other things. - */ -void i810ServerDmaFlush( int wait ) { - int start, end; - - if (I810_DEBUG) - fprintf(stderr, - "i810ServerDmaFlush, buffer %d, head %x space %x\n", - i810ActiveDmaBuffer, - i810glx.dma_buffer->head, - i810glx.dma_buffer->space); - - if ( i810glx.dma_buffer->head == 0 ) - { - if (wait && !i810WaitForDmaCompletion()) - i810glx.hardwareWentIdle = 1; - - return; - } - - i810glx.c_dmaFlush++; - - /* wait for the last buffer to complete */ - if ( !i810WaitForDmaCompletion() ) - i810glx.hardwareWentIdle = 1; - - - /* collect timing information if we are going syncronously */ - if ( i810glx.dmaDriver != 3 ) { - start = i810_usec(); - } else { - start = end = 0; - } - - i810FlushRealDma(); - - if ( i810glx.dmaDriver == 2 ) { - /* wait until the dma completes */ - i810WaitForDmaCompletion(); - } - - if ( i810glx.dmaDriver != 3 ) { - end = i810_usec(); - } - - i810Msg(10, "flushmode %i, buffer %i: prim dwords:%i usec:%i\n", - i810glx.dmaDriver, i810ActiveDmaBuffer, - i810glx.dma_buffer->head / 4, - end - start ); - - /* swap to using the other buffer */ - i810ActiveDmaBuffer ^= 1; - i810DmaResetBuffer(); - - if ( wait ) - i810WaitForDmaCompletion(); -} - - -/* - * i810DmaFlush - */ -void i810DmaFlush( void ) { - i810FinishPrimitive(); - i810glx.dma_buffer->texture_age = ++i810glx.current_texture_age; - - if ( i810Ctx && i810Ctx->CurrentTex0Obj ) - i810Ctx->CurrentTex0Obj->age = ++i810glx.current_texture_age; - - if ( i810Ctx && i810Ctx->CurrentTex1Obj ) - i810Ctx->CurrentTex1Obj->age = ++i810glx.current_texture_age; - - i810ServerDmaFlush( 0 ); -} - - -/* - * i810DmaFinish - */ -void i810DmaFinish( void ) { - i810FinishPrimitive(); - i810ServerDmaFlush( 1 ); - - i810glx.dma_buffer_age = ++i810glx.current_texture_age; - - if ( i810Ctx && i810Ctx->CurrentTex0Obj ) - i810Ctx->CurrentTex0Obj->age = ++i810glx.current_texture_age; - - if ( i810Ctx && i810Ctx->CurrentTex1Obj ) - i810Ctx->CurrentTex1Obj->age = ++i810glx.current_texture_age; -} - - -/* - * i810DmaOverflow - * This is called when I810DMAGETPTR is at the end of the buffer - */ -void i810DmaOverflow( int newDwords ) { - - if (i810glx.dma_buffer->additional_space) { - GLuint incr = MAX_BATCH; - - if (i810glx.dma_buffer->additional_space < incr) - incr = i810glx.dma_buffer->additional_space; - - while (i810glx.dma_buffer->head & (MAX_BATCH - 1)) { - GLuint outbatch = i810glx.dma_buffer->head; - GLubyte *virt = i810glx.dma_buffer->virtual_start; - - *(volatile unsigned int *)(virt + outbatch) = 0; - i810glx.dma_buffer->head += 4; - } - - i810glx.dma_buffer->space += incr; - i810glx.dma_buffer->additional_space -= incr; - - if (0) - fprintf(stderr, "overflow, head %x space %x\n", - i810glx.dma_buffer->head, - i810glx.dma_buffer->space); - return; - } - - i810Msg( 9, "i810DmaOverflow(%i)\n", newDwords ); - - /* flush all the current commands so we will have another - empty buffer */ - i810DmaFlush(); - - i810glx.c_overflows++; - - if ( newDwords > i810glx.dma_buffer->space ) - FatalError("i810DmaOverflow > maxPrimaryDwords"); -} - - -/* - * i810WaitDrawingEngine - * This will not return until the drawing engine has completed - * drawing pixels and it is safe to read or write the framebuffer - * for software rendering. - */ -int i810WaitDrawingEngine( void ) { - /* note this for the performance block display */ - i810glx.c_drawWaits++; - - /* make sure all pending dma has completed */ - i810DmaFinish(); - return 0; -} - - -/* - * i810DmaExecute - * Add a block of data to the dma buffer - */ -void i810DmaExecute( GLuint *code, int dwords ) -{ - int i; - BEGIN_BATCH(dwords); - - if (dwords & 1) - FatalError( "Misaligned buffer in i810DmaExecute\n" ); - - for ( i = 0 ; i < dwords ; i++ ) - OUT_BATCH( code[i] ); - ADVANCE_BATCH(); -} - - - diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.h b/xc/lib/GL/mesa/src/drv/i810/i810dma.h index 55adbcddd..3fd995cb3 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810dma.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810dma.h @@ -1,138 +1,44 @@ -/* - GLX Hardware Device Driver for Intel i810 - Copyright (C) 1999 Keith Whitwell <keithw@precisioninsight.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - original by Jeff Hartmann <slicer@ionet.net> - 6/16/99: rewrite by John Carmack <johnc@idsoftware.com> - Oct 99: port to i180 by Keith Whitwell <keithw@precisioninsight.com> -*/ #ifndef I810DMA_H #define I810DMA_H -#include "i810common.h" #include "i810lib.h" -#include "i810.h" +#include "i810_init.h" #include "mm.h" -/* the main initialization of the entire i810 hardware driver */ -GLboolean i810InitGLX( void ); -/* a flush command will guarantee that all data added to the dma buffer -is on its way to the card, and will eventually complete with no more -intervention. -*/ -void i810DmaFlush(void); - -/* the overflow function is called when a block can't be allocated -in the current dma buffer. It flushes the current buffer and -records some information */ -void i810DmaOverflow(int newDwords); - -/* a finish command will guarantee that all dma commands have actually -been consumed by the card. Note that there may still be a couple primitives -that have not yet been executed out of the internal FIFO, so this does not -guarantee that the drawing engine is idle. */ -void i810DmaFinish( void ); - -/* a i810WaitDrawingEngine command will guarantee that the framebuffer -is safe to read or write for software rendering */ -int i810WaitDrawingEngine( void ); - - - - - -typedef struct { - I810MemRange mem; - char *virtual_start; - int head; - int space; - int additional_space; - int texture_age; -} i810BatchBuffer; - - - -#define I810_USE_BATCH 1 -#if I810_USE_BATCH - -#define BEGIN_BATCH(n) \ +/* Vertex data does not use these macros. + */ +#define BEGIN_BATCH( imesa, n ) \ unsigned int outbatch; \ volatile char *virt; \ if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - fprintf(stderr, \ - "BEGIN_BATCH(%d) in %s\n" \ - "(spc left %d/%d, head %x vstart %x start %x)\n", \ - n, __FUNCTION__, i810glx.dma_buffer->space, \ - i810glx.dma_buffer->mem.Size - i810glx.dma_buffer->head, \ - i810glx.dma_buffer->head, \ - i810glx.dma_buffer->virtual_start, \ - i810glx.dma_buffer->mem.Start ); \ - if (i810glx.dma_buffer->space < n*4) \ - i810DmaOverflow(n); \ - outbatch = i810glx.dma_buffer->head; \ - virt = i810glx.dma_buffer->virtual_start; - - -#define OUT_BATCH(val) { \ - *(volatile unsigned int *)(virt + outbatch) = val; \ - if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - fprintf(stderr, "OUT_BATCH %x: %x\n", outbatch/4, val); \ - outbatch += 4; \ -} + fprintf(stderr, "BEGIN_BATCH(%d) in %s\n", n, __FUNCTION__); \ + if (imesa->dma_buffer->total - imesa->dma_buffer->used < n*4) { \ + i810FlushGeneralLocked( imesa ); \ + i810GetGeneralDmaBufferLocked( imesa ); \ + } \ + outbatch = imesa->dma_buffer->used; \ + virt = imesa->dma_buffer->address; + + +#define OUT_BATCH(val) do { \ + *(volatile unsigned int *)(virt + outbatch) = val; \ + if (I810_DEBUG & DEBUG_VERBOSE_RING) \ + fprintf(stderr, "OUT_BATCH %x: %x\n", \ + (int)(outbatch/4), (int)(val)); \ + outbatch += 4; \ +} while (0) -#define ADVANCE_BATCH() { \ - if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - fprintf(stderr, "ADVANCE_BATCH(%f) in %s\n", \ - (outbatch - i810glx.dma_buffer->head) / 4.0, \ - __FUNCTION__); \ - i810glx.dma_buffer->space -= outbatch - i810glx.dma_buffer->head; \ - i810glx.dma_buffer->head = outbatch; \ -} +#define ADVANCE_BATCH() do { \ + if (I810_DEBUG & DEBUG_VERBOSE_RING) \ + fprintf(stderr, "ADVANCE_BATCH(%.1f) in %s\n", \ + (outbatch - imesa->dma_buffer->used) / 4.0, \ + __FUNCTION__); \ + imesa->dma_buffer->used = outbatch; \ +} while(0) #define FINISH_PRIM() -#else - -/* Need some work to be able to do primitives this way. - */ -#define BEGIN_BATCH(n) BEGIN_LP_RING(n) -#define ADVANCE_BATCH() ADVANCE_LP_RING() -#define OUT_BATCH(val) OUT_RING(val) -#define FINISH_PRIM() OUTREG(I810LpRing.base_reg + RING_TAIL, I810LpRing.tail) - -#endif - - -/* These are only required by i810direct.c: - */ -extern GLuint i810ActiveDmaBuffer; -extern void (*i810DoDmaFlush)( int ); -extern i810BatchBuffer *dmaBuffers[2]; - -extern int i810WaitForDmaCompletion( void ); -extern void i810DmaResetBuffer( void ); - -extern void i810DmaExecute( GLuint *code, int dwords ); - -extern void I810Sync( void ) ; -extern void I810WaitLpRing( int n ); - - #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dmainit.c b/xc/lib/GL/mesa/src/drv/i810/i810dmainit.c deleted file mode 100644 index 335c4a612..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810dmainit.c +++ /dev/null @@ -1,389 +0,0 @@ - -/* -*- mode: C; c-basic-offset:8 -*- */ -/* - * GLX Hardware Device Driver for Intel i810 - * Copyright (C) 1999 Keith Whitwell - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * based on the original by Jeff Hartmann <slicer@ionet.net> - * as rewritten by John Carmack <johnc@idsoftware.com> - */ - -/* - -This file is only entered at startup. After i810GlxInit completes, -nothing here will be executed again. - -*/ - -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <sys/mman.h> -#include <stdio.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <signal.h> - -#include "context.h" -#include "depth.h" -#include "macros.h" -#include "texstate.h" -#include "triangle.h" -#include "vb.h" -#include "types.h" - -#include "xsmesaP.h" -#include "glx_log.h" -#include "mesaglx/context.h" -#include "mesaglx/matrix.h" -#include "mesaglx/types.h" - -#define GC XXGC -#include "gcstruct.h" -#include "pixmapstr.h" -#include "servermd.h" /* PixmapBytePad */ -#include "scrnintstr.h" -#include "regionstr.h" -#include "windowstr.h" -#undef GC - -#include "vga.h" -#include "vgaPCI.h" -#include "i810.h" -#include "xaa/xf86xaa.h" - -#include "mm.h" -#include "i810buf.h" -#include "i810dd.h" -#include "i810lib.h" -#include "i810log.h" -#include "i810direct.h" -#include "i810glx.h" - -#include <agpgart.h> - -/* private vars */ -i810BatchBuffer *dmaBuffers[2]; -static I810MemRange I810SysMem2; - - -static const char *getenvSafe(const char *name ) { - const char *r; - - r = getenv( name ); - if ( !r ) { - return ""; - } - return r; -} - - -static void AllocateCommandBuffers( void ) -{ - PMemBlock block; - GLuint bufferBytes = i810glx.cmdSize; - GLuint start, i; - - if ( 1 || !bufferBytes ) { - fprintf(stderr,"temporarily hardwiring GLX_I810_CMDSIZE = 1\n" ); - bufferBytes = 1; - } - - bufferBytes *= 0x100000; - - block = mmAllocMem( i810glx.sysmemHeap, bufferBytes, 8, 0 ); - - if ( !block ) { - fprintf(stderr, - "failed to allocate 0x%x bytes from " - "sysmemHeap for command buffers.\n", - bufferBytes ); - - FatalError("Couldn't get dma buffer\n"); - } - - start = block->ofs; - - /* setup the two buffers that will be ping-ponged - */ - for (i = 0 ; i < 2 ; i++) { - dmaBuffers[i] = calloc(1,sizeof(i810BatchBuffer)); - dmaBuffers[i]->virtual_start = i810glx.sysmemVirtual + start; - dmaBuffers[i]->mem.Start = start; - dmaBuffers[i]->mem.Size = bufferBytes / 2; - dmaBuffers[i]->mem.End = (start += bufferBytes / 2); - } - - i810DmaResetBuffer(); -} - - -/* Another bit of duplication caused by 'static' code in the X server. - */ -static int gartfd; -static struct gart_info gartinf; -static char *gart_buf; - -static int AllocateGARTMemory( int size ) -{ - int i, pages = size / 4096; - int start = vga256InfoRec.videoRam / 4; /* a crock! */ - struct stat sb; - - if (stat("/dev/agpgart", &sb) != 0) { - ErrorF("Stat failed on /dev/agpgart: %s\n", - sys_errlist[errno]); - return -1; - } - - gartfd = open("/dev/agpgart", O_RDWR); - if (gartfd == -1) { - ErrorF("unable to open /dev/agpgart: %s\n", - sys_errlist[errno]); - FatalError("Aborting"); - } - - if (ioctl(gartfd, GARTIOCINFO, &gartinf) != 0) { - ErrorF("error doing ioctl(GARTIOCINFO): %s\n", - sys_errlist[errno]); - FatalError("Aborting"); - } - - /* Treat the gart like video memory - we assume we own all that is - * there, so ignore EBUSY errors. Don't try to remove it on - * failure, either. - */ - for (i = start; i < start+pages; i++) - if (ioctl(gartfd, GARTIOCINSERT, &i) != 0) { - if (errno != EBUSY) - { - perror("gart insert"); - ErrorF("GART: allocation of %d pages failed at page %d\n", - pages, i); - FatalError("Aborting"); - } - } - - ErrorF("GART: allocated %dK system ram\n", pages * 4); - - I810SysMem2.Start = start * 4096; - I810SysMem2.End = (start + pages) * 4096; - I810SysMem2.Size = pages * 4096; - - gart_buf = mmap( 0, - gartinf.size * 0x100000, - PROT_READ | PROT_WRITE, - MAP_SHARED, - gartfd, - 0 ); - - if ((unsigned int)gart_buf == ~0) { - perror("/dev/agpgart"); - FatalError("Couldn't mmap /dev/agpgart - aborting"); - } - - return 0; -} - - -/* - * AllocateSystemMemory - * Looks at environment variables to determine if a block - * of physical memory has been left for graphics after the - * memory available to the kernel. - * System memory can be used for dma command buffers or - * textures. - */ -static void AllocateSystemMemory( void ) -{ - GLuint sysmemBytes = i810glx.dmaSize; - - if ( !sysmemBytes ) - sysmemBytes = 8; - - sysmemBytes *= 0x100000; - - if (AllocateGARTMemory(sysmemBytes) != 0) - FatalError( "AllocateGARTMemory failed.\n" ); - - - i810glx.sysmemVirtual = (unsigned char *)gart_buf; - - /* Suck in any leftover memory from the 2d server. - - i810glx.sysmemHeap = mmInit( I810SysMem.Start, - I810SysMem.Size ); - */ - - /* Add our new memory. - */ - i810glx.sysmemHeap = -/* mmAddRange( i810glx.sysmemHeap, */ - mmInit( - I810SysMem2.Start, - I810SysMem2.Size ); - - - /* Manage dcache mem via. a seperate heap. - */ - i810glx.cardHeap = mmInit( I810DcacheMem.Start, - I810DcacheMem.Size ); - - i810Msg( 1, "sysmemSize: 0x%x\n", sysmemBytes ); - i810Msg( 1, "cardSize: 0x%lx\n", I810DcacheMem.Size ); -} - - - -/* - * i810DmaInit - * -*/ -void i810DmaInit(void) { - - /* Server init - queries environment variables. The client - * gets these values from the sever and initializes them in - * i810direct.c - */ - if (__glx_is_server) { - i810glx.dmaDriver = atoi( getenvSafe("GLX_I810_DMA") ); - i810glx.dmaSize = atoi( getenvSafe("GLX_I810_DMASIZE") ); - i810glx.cmdSize = atoi( getenvSafe("GLX_I810_CMDSIZE") ); - - if (i810glx.dmaDriver != 3) - FatalError("GLX_I810_DMA not set\n"); - } - - /* get some system memory and make it write combining if we can */ - AllocateSystemMemory(); - - /* read the command environment variable */ - i810Msg(1,"i810DmaInit: GLX_I810_DMA = %i\n", i810glx.dmaDriver ); - - /* setup the two command buffers in the apropriate memory space */ - AllocateCommandBuffers(); - - /* prepare the first buffer for use */ - i810DmaResetBuffer(); -} - - -/* - * This function should only verify that the current hardware is supported. - * It should do no setup. - */ -static GLboolean i810_detect_hw( void ) -{ - if (I810Chipset == -1) - return GL_FALSE; - - if (vga256InfoRec.depth != 15 && - vga256InfoRec.depth != 16) - { - i810Error("Unsupported depth: %d, only 15 and 16d bpp " - "are supported right now\n", - vga256InfoRec.depth); - return GL_FALSE; - } - - return GL_TRUE; -} - -/* - * i810InitLogging - * - */ -void i810InitLogging( void ) -{ - i810glx.logLevel = 100; -} - - - -/* - * i810InitGLX - * This is the initial entry point for the i810 hardware driver, - * called at X server module load time, or libGL direct rendering - * init time. - */ -GLboolean i810InitGLX( void ) { - - fprintf(stderr, "\n\n\n\ni810InitGLX\n"); - - i810InitLogging(); - - i810Msg(1,"virtual (x, y) (%d, %d)\n", vga256InfoRec.virtualX, - vga256InfoRec.virtualY); - i810Msg(1,"width: %d\n", vga256InfoRec.displayWidth); - i810Msg(1,"depth: %d\n", vga256InfoRec.depth); - i810Msg(1,"memBase: %p\n", vgaLinearBase); - i810Msg(1,"videoRam: 0x%08x\n", vga256InfoRec.videoRam); - - if (!i810_detect_hw()) { - ErrorF("Couldn't find i810 hardware\n\n\n"); - return GL_FALSE; - } - - /* init the dma system */ - i810DmaInit(); - - /* Register as a glx driver */ - GLXProcs.CreateContext = i810GLXCreateContext; - GLXProcs.DestroyContext = i810GLXDestroyContext; - GLXProcs.SwapBuffers = i810GLXSwapBuffers; - GLXProcs.CreateImage = i810GLXCreateImage; - GLXProcs.DestroyImage = i810GLXDestroyImage; - GLXProcs.CreateDepthBuffer = i810GLXCreateDepthBuffer; - GLXProcs.MakeCurrent = i810GLXMakeCurrent; - GLXProcs.BindBuffer = i810GLXBindBuffer; - GLXProcs.SwapBuffers = i810GLXSwapBuffers; - GLXProcs.VendorPrivate = i810GLXVendorPrivate; - GLXProcs.AllowDirect = i810GLXAllowDirect; - - if (!__glx_is_server) { - GLXProcs.ValidateFrontBuffer = i810ClientGetGeometry; - } - - /* these vars can be changed between invocations of direct clients */ - if (getenv("GLX_I810_NULLPRIMS") ) { - i810Msg( 1, "enabling GLX_I810_NULLPRIMS\n" ); - i810glx.nullprims = 1; - } - if (getenv("GLX_I810_SKIPDMA") ) { - i810Msg( 1, "enabling GLX_I810_SKIPDMA\n" ); - i810glx.skipDma = 1; - } - if (getenv("GLX_I810_BOXES") ) { - i810Msg( 1, "enabling GLX_I810_BOXES\n" ); - i810glx.boxes = 1; - } - if (getenv("GLX_I810_NOFALLBACK") ) { - i810Msg( 1, "enabling GLX_I810_NOFALLBACK\n" ); - i810glx.noFallback = 1; - } - - i810Error("i810InitGLX completed\n"); - return GL_TRUE; -} - - diff --git a/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c b/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c index 9223060e7..3e4887619 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c @@ -116,14 +116,10 @@ static void i810_render_elements_direct( struct vertex_buffer *VB ) if (imesa->new_state) i810DDUpdateHwState( ctx ); - BEGIN_CLIP_LOOP(imesa) - { - do { - func( VB, 0, nr, 0 ); - } while (ctx->Driver.MultipassFunc && - ctx->Driver.MultipassFunc( VB, ++p )); - } - END_CLIP_LOOP(imesa); + do { + func( VB, 0, nr, 0 ); + } while (ctx->Driver.MultipassFunc && + ctx->Driver.MultipassFunc( VB, ++p )); } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810glx.h b/xc/lib/GL/mesa/src/drv/i810/i810glx.h deleted file mode 100644 index df5c08674..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810glx.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * GLX Hardware Device Driver for Intel i810 - * Copyright (C) 1999 Wittawat Yamwong - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - */ - -#ifndef I810GLX_INC -#define I810GLX_INC - -void i810DumpDB(struct i810_dest_buffer *buf); -void i810GLXCreateDepthBuffer(GLcontext* ctx); -void i810GLXDestroyImage(GLXImage* image); -GLXImage* i810GLXCreateImage(WindowPtr pwindow, int depth, int width, int height); -GLboolean i810GLXMakeCurrent( XSMesaContext c ); -GLboolean i810GLXBindBuffer( XSMesaContext c, XSMesaBuffer b ); -XSMesaContext i810GLXCreateContext( XSMesaVisual v, - XSMesaContext share_list ); -void i810GLXDestroyContext( XSMesaContext c ); - -extern int i810BackToFront(DrawablePtr drawable, struct i810_dest_buffer *buf); -extern void (*i810GLXSwapBuffers)(XSMesaBuffer b); -extern void i810PerformanceBoxes( int is_direct ); - - -#endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c new file mode 100644 index 000000000..93e2f4492 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c @@ -0,0 +1,436 @@ +#include <stdio.h> + + +#include "types.h" +#include "pb.h" +#include "dd.h" + +#include "mm.h" +#include "i810context.h" +#include "i810log.h" +#include "i810ioctl.h" + +#include "drm.h" +#include <sys/ioctl.h> + +static int _tot_used, _tot_size; + +void i810FlushGeneralLocked( i810ContextPtr imesa ) +{ + int retcode; + drm_i810_general_t dma; + drmBufPtr buf = imesa->dma_buffer; + + if (!buf) { + fprintf(stderr, "i810FlushGeneralLocked: no buffer\n"); + return; + } + + _tot_used += buf->used; + _tot_size += buf->total; + + dma.idx = buf->idx; + dma.used = buf->used; + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "DRM_IOCTL_I810_DMA idx %d used %d\n", + dma.idx, dma.used); + + if ((retcode = ioctl(imesa->driFd, DRM_IOCTL_I810_DMA, &dma))) { + printf("send dma retcode = %d\n", retcode); + exit(1); + } + + imesa->dma_buffer = 0; + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "finished general dma put\n"); +} + +static drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa ) +{ + int idx = 0; + int size = 0; + drmDMAReq dma; + int retcode; + drmBufPtr buf; + int cnt = 0; + + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "Getting dma buffer\n"); + + dma.context = imesa->hHWContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + dma.request_size = I810_DMA_BUF_SZ; + dma.request_list = &idx; + dma.request_sizes = &size; + dma.granted_count = 0; + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n", + dma.context, dma.request_count, + dma.request_size); + + while (1) { + retcode = drmDMA(imesa->driFd, &dma); + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "retcode %d sz %d idx %d count %d\n", + retcode, + dma.request_sizes[0], + dma.request_list[0], + dma.granted_count); + + if (retcode == 0 && + dma.request_list[0] && + dma.request_sizes[0] && + dma.granted_count) + break; + + if (++cnt > 1000) { + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) { + fprintf(stderr, "\n\nflush retcode %d idx %d sz %d count %d\n", + retcode, dma.request_list[0], + dma.request_sizes[0], dma.granted_count); + + fprintf(stderr, "used %d size %d (ratio %.3f)\n", + _tot_used, _tot_size, (float)_tot_size / (float)_tot_used); + } + + ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH); + } + } + + + + buf = &(imesa->i810Screen->bufs->list[idx]); + buf->used = 0; + + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, + "drmDMA (get) returns size[0] 0x%x idx[0] %d\n" + "dma_buffer now: buf idx: %d size: %d used: %d\n", + dma.request_sizes[0], dma.request_list[0], + buf->idx, buf->total, + buf->used); + + return buf; +} + + + +void i810GetGeneralDmaBufferLocked( i810ContextPtr imesa ) +{ + if (imesa->dma_buffer) { + fprintf(stderr, "i810GetGeneralDmaBufferLocked - dma_buffer not zero\n"); + exit(1); + } + + imesa->dma_buffer = i810_get_buffer_ioctl( imesa ); +} + + + +/* This waits for *everybody* to finish rendering -- overkill. + */ +void i810DmaFinish( i810ContextPtr imesa ) +{ + FLUSH_BATCH( imesa ); + + if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) { + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "i810DmaFinish\n"); + + LOCK_HARDWARE( imesa ); + i810RegetLockQuiescent( imesa ); + UNLOCK_HARDWARE( imesa ); + imesa->sarea->last_quiescent = imesa->sarea->last_enqueue; + } +} + + +void i810RegetLockQuiescent( i810ContextPtr imesa ) +{ + if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) { + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "i810RegetLockQuiescent\n"); + + drmUnlock(imesa->driFd, imesa->hHWContext); + i810GetLock( imesa, DRM_LOCK_QUIESCENT ); + imesa->sarea->last_quiescent = imesa->sarea->last_enqueue; + } +} + +void i810WaitAgeLocked( i810ContextPtr imesa, int age ) +{ + int i = 0; + + if (0) fprintf(stderr, "waitagelocked\n"); + + while (++i < 500000 && GET_DISPATCH_AGE(imesa) < age) { + ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE); + } + + if (GET_DISPATCH_AGE(imesa) < age) { + if (0) + fprintf(stderr, "wait locked %d %d\n", age, GET_DISPATCH_AGE(imesa)); + ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH); + } +} + + +void i810WaitAge( i810ContextPtr imesa, int age ) +{ + int i = 0; + + while (++i < 500000 && GET_DISPATCH_AGE(imesa) < age) { + ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE); + } + + if (GET_DISPATCH_AGE(imesa) >= age) + return; + + i = 0; + while (++i < 1000 && GET_DISPATCH_AGE(imesa) < age) { + ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE); + usleep(1000); + } + + /* To be effective at letting other clients at the hardware, + * particularly the X server which regularly needs quiescence to + * touch the framebuffer, we really need to sleep *beyond* the + * point where our last buffer clears the hardware. + */ + if (imesa->any_contend) { + usleep(3000); + } + + imesa->any_contend = 0; + + if (GET_DISPATCH_AGE(imesa) < age) { + LOCK_HARDWARE(imesa); + if (GET_DISPATCH_AGE(imesa) < age) + ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH); + UNLOCK_HARDWARE(imesa); + } +} + + + +void i810FlushVertices( i810ContextPtr imesa ) +{ + if (!imesa->vertex_dma_buffer) return; + + LOCK_HARDWARE( imesa ); + i810FlushVerticesLocked( imesa ); + UNLOCK_HARDWARE( imesa ); +} + + +static int intersect_rect( drm_clip_rect_t *out, + drm_clip_rect_t *a, + drm_clip_rect_t *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 0; + if (out->y1 >= out->y2) return 0; + return 1; +} + + +static void age_imesa( i810ContextPtr imesa, int age ) +{ + if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->age = age; + if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->age = age; +} + +void i810FlushVerticesLocked( i810ContextPtr imesa ) +{ + drm_clip_rect_t *pbox = (drm_clip_rect_t *)imesa->pClipRects; + int nbox = imesa->numClipRects; + drmBufPtr buffer = imesa->vertex_dma_buffer; + drm_i810_vertex_t vertex; + int i; + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "i810FlushVerticesLocked, buf %p\n", buffer); + + if (!buffer) + return; + + if (imesa->dirty & ~I810_EMIT_CLIPRECT) + i810EmitHwStateLocked( imesa ); + + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "i810FlushVerticesLocked, used %d\n", + buffer->used); + + _tot_used += buffer->used; + _tot_size += buffer->total; + + imesa->vertex_dma_buffer = 0; + + vertex.idx = buffer->idx; + vertex.used = buffer->used; + vertex.discard = 0; + + if (!nbox) + vertex.used = 0; + + if (nbox > I810_NR_SAREA_CLIPRECTS) + imesa->dirty |= I810_EMIT_CLIPRECT; + + if (!vertex.used || !(imesa->dirty & I810_EMIT_CLIPRECT)) + { + if (nbox == 1) + imesa->sarea->nbox = 0; + else + imesa->sarea->nbox = nbox; + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "DRM_IOCTL_I810_VERTEX CASE1 nbox %d used %d\n", + nbox, vertex.used); + + vertex.discard = 1; + ioctl(imesa->driFd, DRM_IOCTL_I810_VERTEX, &vertex); + age_imesa(imesa, imesa->sarea->last_enqueue); + } + else + { + for (i = 0 ; i < nbox ; ) + { + int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, nbox); + drm_clip_rect_t *b = imesa->sarea->boxes; + + if (imesa->scissor) { + imesa->sarea->nbox = 0; + + for ( ; i < nr ; i++) { + b->x1 = pbox[i].x1 - imesa->drawX; + b->y1 = pbox[i].y1 - imesa->drawY; + b->x2 = pbox[i].x2 - imesa->drawX; + b->y2 = pbox[i].y2 - imesa->drawY; + + if (intersect_rect(b, b, &imesa->scissor_rect)) { + imesa->sarea->nbox++; + b++; + } + } + + /* Culled? + */ + if (!imesa->sarea->nbox) { + if (nr < nbox) continue; + vertex.used = 0; + } + } else { + imesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++, b++) { + b->x1 = pbox[i].x1 - imesa->drawX; + b->y1 = pbox[i].y1 - imesa->drawY; + b->x2 = pbox[i].x2 - imesa->drawX; + b->y2 = pbox[i].y2 - imesa->drawY; + } + } + + /* Finished with the buffer? + */ + if (nr == nbox) + vertex.discard = 1; + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "DRM_IOCTL_I810_VERTEX nbox %d used %d\n", + nbox, vertex.used); + + ioctl(imesa->driFd, DRM_IOCTL_I810_VERTEX, &vertex); + age_imesa(imesa, imesa->sarea->last_enqueue); + } + } + + imesa->dirty = 0; + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "finished i810FlushVerticesLocked\n"); +} + + +GLuint *i810AllocDwords( i810ContextPtr imesa, int dwords ) +{ + GLuint orig_dwords = dwords; + GLuint *start; + + dwords++; + dwords&=~1; + + if (!imesa->vertex_dma_buffer) + { + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "i810AllocPrimitiveVerts -- get buf\n"); + LOCK_HARDWARE(imesa); + imesa->vertex_dma_buffer = i810_get_buffer_ioctl( imesa ); + UNLOCK_HARDWARE(imesa); + } + else if (imesa->vertex_dma_buffer->used + dwords * 4 > + imesa->vertex_dma_buffer->total) + { + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "i810AllocPrimitiveVerts -- flush\n"); + i810FlushVertices( imesa ); + LOCK_HARDWARE(imesa); + imesa->vertex_dma_buffer = i810_get_buffer_ioctl( imesa ); + UNLOCK_HARDWARE(imesa); + } + + if (0) + fprintf(stderr, "i810AllocPrimitiveVerts %d, buf %d, used %d\n", + dwords, imesa->vertex_dma_buffer->idx, + imesa->vertex_dma_buffer->used); + + + start = (GLuint *)((char *)imesa->vertex_dma_buffer->address + + imesa->vertex_dma_buffer->used); + + imesa->vertex_dma_buffer->used += dwords * 4; + + if (orig_dwords & 1) + *start++ = 0; + + return start; +} + + + + + + +static void i810DDFlush( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + FLUSH_BATCH( imesa ); +} + + +static void i810DDFinish( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + i810DmaFinish( imesa ); +} + + +void i810DDInitIoctlFuncs( GLcontext *ctx ) +{ + ctx->Driver.Flush = i810DDFlush; + ctx->Driver.Finish = i810DDFinish; +} diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h new file mode 100644 index 000000000..ac213bf1e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h @@ -0,0 +1,32 @@ +#ifndef MGA_IOCTL_H +#define MGA_IOCTL_H + +#include "i810context.h" + + +GLuint *i810AllocDwords( i810ContextPtr imesa, int dwords ); + +void i810GetGeneralDmaBufferLocked( i810ContextPtr mmesa ); + +void i810FlushVertices( i810ContextPtr mmesa ); +void i810FlushVerticesLocked( i810ContextPtr mmesa ); + +void i810FlushGeneralLocked( i810ContextPtr imesa ); +void i810WaitAgeLocked( i810ContextPtr imesa, int age ); +void i810WaitAge( i810ContextPtr imesa, int age ); + +void i810DmaFinish( i810ContextPtr imesa ); + +void i810RegetLockQuiescent( i810ContextPtr imesa ); + +void i810DDInitIoctlFuncs( GLcontext *ctx ); + + +#define FLUSH_BATCH(imesa) do { \ + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) \ + fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \ + if (imesa->vertex_dma_buffer) i810FlushVertices(imesa); \ +} while (0) + + +#endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810lib.h b/xc/lib/GL/mesa/src/drv/i810/i810lib.h index ec07995a0..ad80674f0 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810lib.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810lib.h @@ -28,29 +28,34 @@ #include <stdio.h> -#include "i810common.h" -#include "i810buf.h" #include "i810context.h" #include "mm.h" #include "i810log.h" -#include "i810dma.h" -#ifndef MESA31 -#error "The I810 driver now requires Mesa 3.1 or higher" -#endif +struct i810_mem_range { + unsigned long Start; + unsigned long End; + unsigned long Size; +}; + +struct i810_batch_buffer; + +struct i810_ring_buffer { + int tail_mask; + struct i810_mem_range mem; + char *virtual_start; + int head; + int tail; + int space; + int synced; +}; typedef struct { /* logging stuff */ GLuint logLevel; FILE *logFile; - /* dma stuff */ - GLuint dmaDriver; - GLuint dmaSize; - GLuint dmaAdr; - GLuint cmdSize; - /* bookkeeping for texture swaps */ GLuint dma_buffer_age; GLuint current_texture_age; @@ -68,37 +73,28 @@ typedef struct { GLuint c_lines; GLuint c_drawWaits; GLuint c_textureSwaps; - GLuint c_signals; GLuint c_dmaFlush; GLuint c_overflows; + + GLuint c_ringlost; + GLuint c_texlost; + GLuint c_ctxlost; GLuint hardwareWentIdle; /* cleared each swapbuffers, set if a waitfordmacompletion ever exited without having to wait */ - /* Primitive managment (like warpSerie) */ - GLuint prim_start; - GLuint prim_dwords; - - /* card == dcache - * sysmem == normal gart memory - */ - memHeap_t *cardHeap; - memHeap_t *sysmemHeap; - unsigned char *sysmemVirtual; + unsigned char *texVirtual; - i810BatchBuffer *dma_buffer; + + struct i810_batch_buffer *dma_buffer; + struct i810_ring_buffer LpRing; + unsigned char *MMIOBase; } i810Glx_t; extern i810Glx_t i810glx; -int i810_usec( void ); -void i810LibInit(); -void i810SoftReset(); - -int i810MakeCurrent(i810ContextPtr ctx, struct i810_dest_buffer *buf); -void i810LoadTexturePalette(unsigned short *pal, int start, int len); #define I810PACKCOLOR1555(r,g,b,a) \ ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ @@ -123,6 +119,7 @@ static __inline__ GLuint i810PackColor(GLuint format, case DV_PF_565: return I810PACKCOLOR565(r,g,b); default: + fprintf(stderr, "unknown format %d\n", (int)format); return 0; } } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c index 2cd53b42e..06269a818 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c @@ -1,15 +1,16 @@ /* #include "i810pipeline.h" */ #include <stdio.h> -#include "xsmesaP.h" + +#include "types.h" +#include "fog.h" + #include "i810vb.h" #include "i810dd.h" #include "i810lib.h" #include "i810tris.h" +#include "i810pipeline.h" -#include "fog.h" - -#if 0 static struct gl_pipeline_stage i810_fast_stage = { "I810 fast path", @@ -68,11 +69,6 @@ GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx ) } -#endif - - - - GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out, const struct gl_pipeline_stage *in, @@ -83,7 +79,6 @@ GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out, for (i = o = 0 ; i < nr ; i++) { switch (in[i].ops) { -#if 0 case PIPE_OP_RAST_SETUP_0: out[o] = in[i]; out[o].cva_state_change = NEW_LIGHTING|NEW_TEXTURING|NEW_RASTER_OPS; @@ -98,7 +93,6 @@ GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out, out[o].run = i810DDDoRasterSetup; o++; break; -#endif /* Completely replace Mesa's fog processing to generate fog * coordinates instead of messing with colors. diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h index 350f23431..87b95455d 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h @@ -7,4 +7,8 @@ extern GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out, extern GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx ); +extern void i810DDFastPath( struct vertex_buffer *VB ); +extern void i810DDFastPathInit( void ); + + #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ring.c b/xc/lib/GL/mesa/src/drv/i810/i810ring.c deleted file mode 100644 index 2e5909e9f..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810ring.c +++ /dev/null @@ -1,162 +0,0 @@ -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <sys/mman.h> -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> - -#include "mm.h" -#include "i810dd.h" -#include "i810lib.h" -#include "i810state.h" - - -#include "i810dma.h" - -static void -I810PrintErrorState( void ) -{ - fprintf(stderr, "pgetbl_ctl: 0x%x pgetbl_err: 0x%x\n", - INREG(PGETBL_CTL), - INREG(PGE_ERR)); - - fprintf(stderr, "ipeir: %x iphdr: %x\n", - INREG(IPEIR), - INREG(IPEHR)); - - fprintf(stderr, "LP ring tail: %x head: %x len: %x start %x\n", - INREG(LP_RING + RING_TAIL), - INREG(LP_RING + RING_HEAD) & HEAD_ADDR, - INREG(LP_RING + RING_LEN), - INREG(LP_RING + RING_START)); - - fprintf(stderr, "eir: %x esr: %x emr: %x\n", - INREG16(EIR), - INREG16(ESR), - INREG16(EMR)); - - fprintf(stderr, "instdone: %x instpm: %x\n", - INREG16(INST_DONE), - INREG8(INST_PM)); - - fprintf(stderr, "memmode: %x instps: %x\n", - INREG(MEMMODE), - INREG(INST_PS)); - - fprintf(stderr, "hwstam: %x ier: %x imr: %x iir: %x\n", - INREG16(HWSTAM), - INREG16(IER), - INREG16(IMR), - INREG16(IIR)); -} - - - - -static int -I810USec( void ) -{ - struct timeval tv; - struct timezone tz; - gettimeofday( &tv, &tz ); - return (tv.tv_sec & 2047) * 1000000 + tv.tv_usec; -} - - - -void -_I810RefreshLpRing( i810ContextPtr imesa, int update ) -{ - struct i810_ring_buffer *ring = &(i810glx.LpRing); - - ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = INREG(LP_RING + RING_TAIL); - ring->space = ring->head - (ring->tail+8); - - if (ring->space < 0) { - ring->space += ring->mem.Size; - if (update) - imesa->sarea->lastWrap = ++imesa->sarea->ringAge; - } -} - -int -_I810WaitLpRing( i810ContextPtr imesa, int n, int timeout_usec ) -{ - struct i810_ring_buffer *ring = &(i810glx.LpRing); - int iters = 0; - int startTime = 0; - int curTime = 0; - - if (timeout_usec == 0) - timeout_usec = 15000000; - - if (I810_DEBUG & DEBUG_VERBOSE_API) - fprintf(stderr, "I810WaitLpRing %d\n", n); - - while (ring->space < n) - { - int i; - - ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->space = ring->head - (ring->tail+8); - - if (ring->space < 0) { - imesa->sarea->lastWrap = ++imesa->sarea->ringAge; - ring->space += ring->mem.Size; - } - - iters++; - curTime = I810USec(); - if ( startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if ( curTime - startTime > timeout_usec ) { - I810PrintErrorState(); - fprintf(stderr, "space: %d wanted %d\n", - ring->space, n ); - UNLOCK_HARDWARE(imesa); - exit(1); - } - - for (i = 0 ; i < 2000 ; i++) - ; - } - - return iters; -} - -int -_I810Sync( i810ContextPtr imesa ) -{ - int rv; - - if (I810_DEBUG & DEBUG_VERBOSE_API) - fprintf(stderr, "I810Sync\n"); - - /* Send a flush instruction and then wait till the ring is empty. - * This is stronger than waiting for the blitter to finish as it also - * flushes the internal graphics caches. - */ - { - BEGIN_LP_RING( imesa, 2 ); - OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH ); - OUT_RING( 0 ); /* pad to quadword */ - ADVANCE_LP_RING(); - } - - - i810glx.LpRing.synced = 1; /* ?? */ - - rv = _I810WaitLpRing( imesa, i810glx.LpRing.mem.Size - 8, 0 ); - imesa->sarea->lastSync = ++imesa->sarea->ringAge; - - return rv; -} - - - - diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c index ce55c6f70..c47bf2f40 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810span.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810span.c @@ -1,149 +1,174 @@ #include "types.h" -#include "i810buf.h" #include "i810dd.h" #include "i810lib.h" #include "i810dma.h" #include "i810log.h" +#include "i810span.h" +#include "i810ioctl.h" -static void (*xsmWriteRGBASpan)( const GLcontext *ctx, - GLuint n, GLint x, GLint y, - CONST GLubyte rgba[][4], - const GLubyte mask[] ); -static void (*xsmWriteRGBSpan)( const GLcontext *ctx, - GLuint n, GLint x, GLint y, - CONST GLubyte rgb[][3], const GLubyte mask[] ); -static void (*xsmWriteMonoRGBASpan)(const GLcontext *ctx, GLuint n, - GLint x, GLint y,const GLubyte mask[] ); -static void (*xsmWriteRGBAPixels)(const GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - CONST GLubyte rgba[][4], - const GLubyte mask[] ); -static void (*xsmWriteMonoRGBAPixels)(const GLcontext *ctx,GLuint n, - const GLint x[], const GLint y[], - const GLubyte mask[] ); -static void (*xsmReadRGBASpan)(const GLcontext *ctx, GLuint n, - GLint x, GLint y,GLubyte rgba[][4] ); -static void (*xsmReadRGBAPixels)(const GLcontext *ctx,GLuint n, - const GLint x[], const GLint y[], - GLubyte rgba[][4], const GLubyte mask[] ); - -/* Wrapper functions */ - -static void WriteRGBASpan( const GLcontext *ctx, - GLuint n, GLint x, GLint y, - CONST GLubyte rgba[][4], - const GLubyte mask[] ) -{ - i810Msg(12,__FUNCTION__ "\n"); - i810WaitDrawingEngine(); - (*xsmWriteRGBASpan)(ctx,n,x,y,rgba,mask); -} -static void WriteRGBSpan( const GLcontext *ctx, - GLuint n, GLint x, GLint y, - CONST GLubyte rgb[][3], const GLubyte mask[] ) -{ - i810Msg(12,__FUNCTION__ "\n"); - i810WaitDrawingEngine(); - (*xsmWriteRGBSpan)(ctx,n,x,y,rgb,mask); -} +#define DBG 0 -static void WriteMonoRGBASpan(const GLcontext *ctx, GLuint n, - GLint x, GLint y,const GLubyte mask[] ) -{ - i810Msg(12,__FUNCTION__ "\n"); - i810WaitDrawingEngine(); - (*xsmWriteMonoRGBASpan)(ctx,n,x,y,mask); -} +#define LOCAL_VARS \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ + i810ScreenPrivate *i810Screen = imesa->i810Screen; \ + GLuint pitch = i810Screen->backPitch; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(imesa->drawMap + \ + dPriv->x * 2 + \ + dPriv->y * pitch); \ + char *read_buf = (char *)(imesa->readMap + \ + dPriv->x * 2 + \ + dPriv->y * pitch); \ + GLushort p = I810_CONTEXT( ctx )->MonoColor; \ + (void) read_buf; (void) buf; (void) p -static void WriteRGBAPixels(const GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - CONST GLubyte rgba[][4], - const GLubyte mask[] ) -{ - i810Msg(12,__FUNCTION__ "\n"); - i810WaitDrawingEngine(); - (*xsmWriteRGBAPixels)(ctx,n,x,y,rgba,mask); -} +#define LOCAL_DEPTH_VARS \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ + i810ScreenPrivate *i810Screen = imesa->i810Screen; \ + GLuint pitch = i810Screen->backPitch; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(i810Screen->depth.map + \ + dPriv->x * 2 + \ + dPriv->y * pitch) -static void WriteMonoRGBAPixels(const GLcontext *ctx,GLuint n, - const GLint x[], const GLint y[], - const GLubyte mask[] ) -{ - i810Msg(12,__FUNCTION__ "\n"); - i810WaitDrawingEngine(); - (*xsmWriteMonoRGBAPixels)(ctx,n,x,y,mask); -} +#define INIT_MONO_PIXEL(p) -static void ReadRGBASpan(const GLcontext *ctx, GLuint n, - GLint x, GLint y,GLubyte rgba[][4] ) -{ - i810Msg(12,__FUNCTION__ "\n"); - i810WaitDrawingEngine(); - (*xsmReadRGBASpan)(ctx,n,x,y,rgba); -} +#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \ + _y >= miny && _y < maxy) -static void ReadRGBAPixels(const GLcontext *ctx,GLuint n, - const GLint x[], const GLint y[], - GLubyte rgba[][4], const GLubyte mask[] ) -{ - i810Msg(12,__FUNCTION__ "\n"); - i810WaitDrawingEngine(); - (*xsmReadRGBAPixels)(ctx,n,x,y,rgba,mask); -} -#define WRAP(x) \ - xsm ## x = ctx->Driver.x; \ - ctx->Driver.x = x +#define CLIPSPAN(_x,_y,_n,_x1,_n1,_i) \ + if (_y < miny || _y >= maxy) _n1 = 0, _x1 = x; \ + else { \ + _n1 = _n; \ + _x1 = _x; \ + if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \ + if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \ + } -void i810DDInitSpans( GLcontext *ctx ) -{ - /* Need another hook from mesa to synchronize hardware before - * write-pixels and read-spans/pixels. - */ - WRAP(WriteRGBASpan); - WRAP(WriteRGBSpan); - WRAP(WriteMonoRGBASpan); - WRAP(WriteRGBAPixels); - WRAP(WriteMonoRGBAPixels); - WRAP(ReadRGBASpan); - WRAP(ReadRGBAPixels); -} +#define Y_FLIP(_y) (height - _y - 1) +#define HW_LOCK() \ + i810ContextPtr imesa = I810_CONTEXT(ctx); \ + LOCK_HARDWARE_QUIESCENT(imesa); +#define HW_CLIPLOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ + 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() \ + UNLOCK_HARDWARE(imesa); -void fxUpdateDDSpanPointers(GLcontext *ctx) -{ - ctx->Driver.DepthTestSpan=fxDDDepthTestSpanGeneric; - ctx->Driver.DepthTestPixels=fxDDDepthTestPixelsGeneric; - ctx->Driver.ReadDepthSpanFloat=fxDDReadDepthSpanFloat; - ctx->Driver.ReadDepthSpanInt=fxDDReadDepthSpanInt; -} +/* 16 bit, 565 rgb color spanline and pixel functions + */ +#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; \ + rgba[1] = (p >> 3) & 0xfc; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = 0; /* or 255? */ \ +} while(0) + +#define TAG(x) i810##x##_565 +#include "spantmp.h" + + + + +/* 15 bit, 555 rgb color spanline and pixel functions + */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \ + ((g & 0xf8) << 3) | \ + ((b & 0xf8) >> 3)) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (p >> 7) & 0xf8; \ + rgba[1] = (p >> 3) & 0xf8; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = 0; /* or 255? */ \ +} while(0) + +#define TAG(x) i810##x##_555 +#include "spantmp.h" + + + + +/* 16 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLdepth *)(buf + _x*2 + _y*pitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLdepth *)(buf + _x*2 + _y*pitch); + +/* d = 0xffff; */ + +#define TAG(x) i810##x##_16 +#include "depthtmp.h" + + -void fxSetupDDSpanPointers(GLcontext *ctx) +void i810DDInitSpanFuncs( GLcontext *ctx ) { - ctx->Driver.WriteRGBASpan =fxDDWriteRGBASpan; - ctx->Driver.WriteRGBSpan =fxDDWriteRGBSpan; - ctx->Driver.WriteMonoRGBASpan =fxDDWriteMonoRGBASpan; - ctx->Driver.WriteRGBAPixels =fxDDWriteRGBAPixels; - ctx->Driver.WriteMonoRGBAPixels =fxDDWriteMonoRGBAPixels; - - ctx->Driver.WriteCI8Span =NULL; - ctx->Driver.WriteCI32Span =NULL; - ctx->Driver.WriteMonoCISpan =NULL; - ctx->Driver.WriteCI32Pixels =NULL; - ctx->Driver.WriteMonoCIPixels =NULL; - - ctx->Driver.ReadRGBASpan =fxDDReadRGBASpan; - ctx->Driver.ReadRGBAPixels =fxDDReadRGBAPixels; - - ctx->Driver.ReadCI32Span =NULL; - ctx->Driver.ReadCI32Pixels =NULL; + if (1) { + ctx->Driver.WriteRGBASpan = i810WriteRGBASpan_565; + ctx->Driver.WriteRGBSpan = i810WriteRGBSpan_565; + ctx->Driver.WriteMonoRGBASpan = i810WriteMonoRGBASpan_565; + ctx->Driver.WriteRGBAPixels = i810WriteRGBAPixels_565; + ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_565; + ctx->Driver.ReadRGBASpan = i810ReadRGBASpan_565; + ctx->Driver.ReadRGBAPixels = i810ReadRGBAPixels_565; + } else { + ctx->Driver.WriteRGBASpan = i810WriteRGBASpan_555; + ctx->Driver.WriteRGBSpan = i810WriteRGBSpan_555; + ctx->Driver.WriteMonoRGBASpan = i810WriteMonoRGBASpan_555; + ctx->Driver.WriteRGBAPixels = i810WriteRGBAPixels_555; + ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_555; + ctx->Driver.ReadRGBASpan = i810ReadRGBASpan_555; + ctx->Driver.ReadRGBAPixels = i810ReadRGBAPixels_555; + } + + ctx->Driver.ReadDepthSpan = i810ReadDepthSpan_16; + ctx->Driver.WriteDepthSpan = i810WriteDepthSpan_16; + ctx->Driver.ReadDepthPixels = i810ReadDepthPixels_16; + ctx->Driver.WriteDepthPixels = i810WriteDepthPixels_16; + + ctx->Driver.WriteCI8Span =NULL; + ctx->Driver.WriteCI32Span =NULL; + ctx->Driver.WriteMonoCISpan =NULL; + ctx->Driver.WriteCI32Pixels =NULL; + ctx->Driver.WriteMonoCIPixels =NULL; + ctx->Driver.ReadCI32Span =NULL; + ctx->Driver.ReadCI32Pixels =NULL; } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.h b/xc/lib/GL/mesa/src/drv/i810/i810span.h index 07276cd86..17a52085b 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810span.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810span.h @@ -1,6 +1,6 @@ #ifndef _I810_SPAN_H #define _I810_SPAN_H -extern void i810DDInitSpans( GLcontext *ctx ); +extern void i810DDInitSpanFuncs( GLcontext *ctx ); #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.c b/xc/lib/GL/mesa/src/drv/i810/i810state.c index e4a77efc1..caf9fafd6 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810state.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810state.c @@ -1,33 +1,33 @@ #include <stdio.h> -#include "xsmesaP.h" - #include "types.h" +#include "enums.h" #include "pb.h" #include "dd.h" -#include "glx_log.h" #include "mm.h" #include "i810lib.h" -#include "i810glx.h" #include "i810dd.h" #include "i810context.h" #include "i810state.h" -#include "i810depth.h" #include "i810tex.h" #include "i810log.h" #include "i810vb.h" #include "i810tris.h" +#include "i810ioctl.h" + + static void i810DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref) { i810ContextPtr imesa = I810_CONTEXT(ctx); - CARD32 a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF); + FLUSH_BATCH(imesa); + switch (ctx->Color.AlphaFunc) { case GL_NEVER: a |= ZA_ALPHA_NEVER; break; case GL_LESS: a |= ZA_ALPHA_LESS; break; @@ -42,21 +42,17 @@ static void i810DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref) a |= ctx->Color.AlphaRef << ZA_ALPHAREF_SHIFT; - imesa->reg_dirty |= (1<<I810_CTXREG_ZA); + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK); imesa->Setup[I810_CTXREG_ZA] |= a; } -/* This shouldn't get called, as the extension is disabled. However, - * there are internal Mesa calls, and rouge use of the api which must be - * caught. - */ static void i810DDBlendEquation(GLcontext *ctx, GLenum mode) { if (mode != GL_FUNC_ADD_EXT) { ctx->Color.BlendEquation = GL_FUNC_ADD_EXT; - FatalError("Unsupported blend equation"); - gl_error( ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)"); + i810Error("Unsupported blend equation"); + exit(1); } } @@ -65,6 +61,9 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint a; + FLUSH_BATCH(imesa); + + a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND; switch (ctx->Color.BlendSrcRGB) { @@ -80,7 +79,8 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) a |= SDM_SRC_SRC_ALPHA; /* use GFXRENDERSTATE_COLOR_FACTOR ??? */ break; default: - FatalError("unknown blend source func"); + i810Error("unknown blend source func"); + exit(1); return; } @@ -94,11 +94,12 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) case GL_DST_ALPHA: a |= SDM_DST_ONE; break; case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break; default: - FatalError("unknown blend dst func"); + i810Error( "unknown blend dst func"); + exit(1); return; } - imesa->reg_dirty |= (1<<I810_CTXREG_SDM); + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK); imesa->Setup[I810_CTXREG_SDM] |= a; } @@ -124,6 +125,8 @@ static void i810DDDepthFunc(GLcontext *ctx, GLenum func) i810ContextPtr imesa = I810_CONTEXT(ctx); int zmode; + FLUSH_BATCH(imesa); + switch(func) { case GL_NEVER: zmode = LCS_Z_NEVER; break; case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break; @@ -135,43 +138,161 @@ static void i810DDDepthFunc(GLcontext *ctx, GLenum func) case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break; default: return; } - - /* Could just fire it off now... - */ + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK; imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_ZMODE | zmode; - imesa->reg_dirty |= (1<<I810_CTXREG_LCS); + + imesa->dirty |= I810_UPLOAD_CTX; } static void i810DDDepthMask(GLcontext *ctx, GLboolean flag) { i810ContextPtr imesa = I810_CONTEXT(ctx); - imesa->reg_dirty |= (1<<I810_CTXREG_B2); + FLUSH_BATCH(imesa); + + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE; - imesa->Setup[I810_CTXREG_B2] |= B2_UPDATE_ZB_WRITE_ENABLE; if (flag) imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE; +} -/* - Possible technique to reduce the amount of checking for small state - changes. Large ones detect wrap on update_count & just send the - whole state... - { - imesa->Update[imesa->update_count & MAX_UPDATE] = - ( imesa->Setup[I810_CTXREG_B2] & - (B1_ZB_WRITE_ENABLE | B1_UPDATE_ZB_WRITE_ENABLE | GFX_OP_BOOL_1) - ); - imesa->update_count++; - } -*/ +/* ============================================================= + * Polygon stipple + * + * The i810 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. Could + * also consider using a multitexturing mechanism for this, but + * that has real issues, too. + */ +static void i810DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i,j,k; + int active = (ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON); + + FLUSH_BATCH(imesa); + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + + if (active) { + imesa->dirty |= I810_UPLOAD_CTX; + imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[0] & 0xf; p[0] |= p[0] << 4; + p[1] = mask[4] & 0xf; p[1] |= p[1] << 4; + p[2] = mask[8] & 0xf; p[2] |= p[2] << 4; + p[3] = mask[12] & 0xf; p[3] |= p[3] << 4; + + for (k = 0 ; k < 8 ; k++) + for (j = 0 ; j < 4; j++) + for (i = 0 ; i < 4 ; i++) + if (*m++ != p[j]) { + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + return; + } + + + + imesa->poly_stipple = ( ((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | + ((p[3] & 0xf) << 12) ); + + if (1) { + imesa->Setup[I810_CTXREG_ST1] &= ~0xffff; + imesa->Setup[I810_CTXREG_ST1] |= ( ((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | + ((p[3] & 0xf) << 12) ); + } + + if (active) + imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; } +/* ============================================================ + * Line stipple -- not completed + * - need to cope with stipplecounter + */ +#if 0 +static void i810DDLineStipple( GLcontext *ctx, GLint factor, GLushort pattern ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLushort p, h, test; + + FLUSH_BATCH(imesa); + ctx->Driver.TriangleCaps |= DD_LINE_STIPPLE; + + if (ctx->Line.StippleFlag) { + imesa->lines_are_tris |= I810_LINE_STIPPLE; + + if (ctx->PB->primitive == GL_LINE) { + imesa->dirty |= I810_UPLOAD_CTX; + imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; + } + } + + switch (factor) { + case 1: + p = pattern & 0xf; + p |= p << 4; + p |= p << 8; + test = p; + break; + case 2: + p = pattern & 1; + p |= (pattern & 2) << 2; + p |= p << 1; + p |= p << 4; + p |= p << 8; + test = pattern & 3; + test |= test << 2; + test |= test << 4; + test |= test << 8; + break; + default: + p = 0; + if (pattern) + p = 0xffff; + test = p; + break; + } + + if (pattern != test) { + ctx->Driver.TriangleCaps &= ~DD_LINE_STIPPLE; + imesa->lines_are_tris &= ~I810_LINE_STIPPLE; + return; + } + + h = (((p & 1) << 0) | + ((p & 2) << 4) | + ((p & 3) << 8) | + ((p & 4) << 12)); + + h |= h << 1; + h |= h << 2; + + imesa->vert_line_stipple = p; + imesa->horiz_line_stipple = h; + + if (ctx->Line.Stipple && ctx->PB->primitive == GL_LINE) + imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; +} +#endif + +/* ============================================================ + * Antialiased lines and triangles + */ +/* Nothing to do... + */ @@ -184,36 +305,105 @@ static void i810DDDepthMask(GLcontext *ctx, GLboolean flag) static void i810DDScissor( GLcontext *ctx, GLint x, GLint y, - GLsizei w, GLsizei h ) + GLsizei w, GLsizei h ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + FLUSH_BATCH(imesa); + imesa->scissor_rect.x1 = x; + imesa->scissor_rect.y1 = imesa->driDrawable->h - (y+h); + imesa->scissor_rect.x2 = x+w; + imesa->scissor_rect.y2 = imesa->driDrawable->h - y; + + + if (I810_DEBUG&DEBUG_VERBOSE_2D) + fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n", + imesa->scissor_rect.x1, + imesa->scissor_rect.y1, + imesa->scissor_rect.x2, + imesa->scissor_rect.y2); + + + imesa->dirty |= I810_EMIT_CLIPRECT; +} + + +static void i810DDDither(GLcontext *ctx, GLboolean enable) +{ +} + + +static GLboolean i810DDSetDrawBuffer(GLcontext *ctx, GLenum mode ) { i810ContextPtr imesa = I810_CONTEXT(ctx); - int x1,x2,y1,y2; - x1 = ctx->Scissor.X; - x2 = ctx->Scissor.X + ctx->Scissor.Width - 1; - y1 = i810DB->Height - ctx->Scissor.Y - ctx->Scissor.Height; - y2 = i810DB->Height - ctx->Scissor.Y - 1; - - if (x1 < 0) x1 = 0; - if (y1 < 0) y1 = 0; - if (x2 >= i810DB->Width) x2 = i810DB->Width-1; - if (y2 >= i810DB->Height) y2 = i810DB->Height-1; - - if (x1 > x2 || y1 > y2) { - x1 = 0; x2 = 0; - y2 = 0; y1 = 1; + FLUSH_BATCH(imesa); + + imesa->Fallback &= ~I810_FALLBACK_DRAW_BUFFER; + + if (mode == GL_FRONT_LEFT) + { + imesa->drawMap = imesa->driScreen->pFB; + imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset | + imesa->i810Screen->backPitchBits); + imesa->dirty |= I810_UPLOAD_BUFFERS; + i810XMesaSetFrontClipRects( imesa ); + return GL_TRUE; + } + else if (mode == GL_BACK_LEFT) + { + imesa->drawMap = imesa->i810Screen->back.map; + imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset | + imesa->i810Screen->backPitchBits); + imesa->dirty |= I810_UPLOAD_BUFFERS; + i810XMesaSetBackClipRects( imesa ); + return GL_TRUE; } - /* Turn it off if full screen? - */ - imesa->Setup[I810_CTXREG_SCI0] = GFX_OP_SCISSOR_INFO; - imesa->Setup[I810_CTXREG_SCI1] = (y1<<16)|x1; - imesa->Setup[I810_CTXREG_SCI2] = (y2<<16)|x2; + imesa->Fallback |= I810_FALLBACK_DRAW_BUFFER; + return GL_FALSE; +} +static void i810DDSetReadBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, + GLenum mode ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); - imesa->reg_dirty |= ((1<<I810_CTXREG_SCI0) | - (1<<I810_CTXREG_SCI1) | - (1<<I810_CTXREG_SCI2)); + if (mode == GL_FRONT_LEFT) + { + imesa->readMap = imesa->driScreen->pFB; + imesa->Fallback &= ~I810_FALLBACK_READ_BUFFER; + } + else if (mode == GL_BACK_LEFT) + { + imesa->readMap = imesa->i810Screen->back.map; + imesa->Fallback &= ~I810_FALLBACK_READ_BUFFER; + } + else + imesa->Fallback |= I810_FALLBACK_READ_BUFFER; +} + + + +static void i810DDSetColor(GLcontext *ctx, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + imesa->MonoColor = i810PackColor( imesa->i810Screen->fbFormat, + r, g, b, a ); +} + + +static void i810DDClearColor(GLcontext *ctx, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat, + r, g, b, a ); } @@ -226,6 +416,8 @@ static void i810DDCullFaceFrontFace(GLcontext *ctx, GLenum unused) i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint mode = LCS_CULL_BOTH; + FLUSH_BATCH(imesa); + if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { mode = LCS_CULL_CW; if (ctx->Polygon.CullFaceMode == GL_FRONT) @@ -238,25 +430,55 @@ static void i810DDCullFaceFrontFace(GLcontext *ctx, GLenum unused) if (ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON) { - imesa->reg_dirty |= (1<<I810_CTXREG_LCS); + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK; - imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode); + imesa->Setup[I810_CTXREG_LCS] |= mode; } } static void i810DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) { - if (ctx->Polygon.CullFlag) { - i810ContextPtr imesa = I810_CONTEXT(ctx); - GLuint mode = imesa->LcsCullMode; - - if (ctx->PB->primitive != GL_POLYGON) - mode = LCS_CULL_DISABLE; - - imesa->reg_dirty |= (1<<I810_CTXREG_LCS); - imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK; - imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode); + i810ContextPtr imesa = I810_CONTEXT(ctx); + FLUSH_BATCH(imesa); + + imesa->dirty |= I810_UPLOAD_CTX; + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK; + imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + + switch (ctx->PB->primitive) { + case GL_POLYGON: + if (ctx->Polygon.StippleFlag && + (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE)) + imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; + if (ctx->Polygon.CullFlag) + imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode; + else + imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE; + if (ctx->Polygon.SmoothFlag) + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + break; + case GL_LINES: +#if 0 + if (ctx->Line.StippleFlag && (ctx->Driver.TriangleCaps & DD_LINE_STIPPLE)) + imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; +#endif + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5; + if (ctx->Line.SmoothFlag) { + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5; + } + imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE; + break; + case GL_POINTS: + if (ctx->Point.SmoothFlag) + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE; + break; + default: + imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE; + break; } } @@ -266,15 +488,36 @@ static void i810DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) * Color masks */ -/* Mesa calls this from the wrong place. +/* Mesa calls this from the wrong place - it is called a very large + * number of redundant times. * - * Its a fallback... + * Colormask can be simulated by multipass or multitexture techniques. */ static GLboolean i810DDColorMask(GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a ) { - return 1; + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLuint tmp = 0; + GLuint rv = 1; + + imesa->Fallback &= ~I810_FALLBACK_COLORMASK; + + if (r && g && b) { + tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE; + } else if (!r && !g && !b) { + tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE; + } else { + rv = 0; + imesa->Fallback |= I810_FALLBACK_COLORMASK; + } + + if (tmp != imesa->Setup[I810_CTXREG_B2]) { + FLUSH_BATCH(imesa); + imesa->Setup[I810_CTXREG_B2] = tmp; + } + + return rv; } /* Seperate specular not fully implemented in hardware... Needs @@ -284,7 +527,16 @@ static GLboolean i810DDColorMask(GLcontext *ctx, static void i810DDLightModelfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { - if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) + { + i810ContextPtr imesa = I810_CONTEXT( ctx ); + FLUSH_BATCH(imesa); + + imesa->Fallback &= ~I810_FALLBACK_SPECULAR; + + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + imesa->Fallback |= I810_FALLBACK_SPECULAR; + I810_CONTEXT(ctx)->new_state |= I810_NEW_TEXTURE; } } @@ -295,7 +547,7 @@ static void i810DDLightModelfv(GLcontext *ctx, GLenum pname, * Fog */ -void i810DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) +static void i810DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { i810ContextPtr imesa = I810_CONTEXT(ctx); @@ -304,7 +556,7 @@ void i810DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0)); - imesa->reg_dirty |= (1<<I810_CTXREG_FOG); + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_FOG] = ((GFX_OP_FOG_COLOR | color) & ~FOG_RESERVED_MASK); } @@ -320,66 +572,126 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) switch(cap) { case GL_ALPHA_TEST: - imesa->reg_dirty |= (1<<I810_CTXREG_B1); + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE; - imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_ALPHA_TEST_ENABLE; if (state) imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE; break; case GL_BLEND: - imesa->reg_dirty |= (1<<I810_CTXREG_B1); + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE; - imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_BLEND_ENABLE; if (state) imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE; break; case GL_DEPTH_TEST: - imesa->reg_dirty |= (1<<I810_CTXREG_B1); + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE; - imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_Z_TEST_ENABLE; if (state) imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE; break; case GL_SCISSOR_TEST: - imesa->reg_dirty |= (1<<I810_CTXREG_SC); - imesa->Setup[I810_CTXREG_SC] &= ~SC_ENABLE_MASK; - imesa->Setup[I810_CTXREG_SC] |= SC_UPDATE_SCISSOR; - if (state) - imesa->Setup[I810_CTXREG_SC] |= SC_ENABLE; + FLUSH_BATCH(imesa); + imesa->scissor = state; + imesa->dirty |= I810_EMIT_CLIPRECT; + break; + case GL_POLYGON_STIPPLE: + if ((ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) && + ctx->PB->primitive == GL_POLYGON) + { + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; + imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; + } + break; + case GL_LINE_STIPPLE: +#if 0 + if (ctx->Driver.TriangleCaps & DD_LINE_STIPPLE) + { + imesa->lines_are_tris &= ~I810_LINE_STIPPLE; + if (state) + imesa->lines_are_tris |= I810_LINE_STIPPLE; + + if (ctx->PB->primitive == GL_LINE) { + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; + imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; + } + } +#endif + break; + case GL_LINE_SMOOTH: + if (ctx->PB->primitive == GL_LINE) { + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5; + if (state) { + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5; + } + } + break; + case GL_POINT_SMOOTH: + if (ctx->PB->primitive == GL_POINT) { + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + } + break; + case GL_POLYGON_SMOOTH: + if (ctx->PB->primitive == GL_POLYGON) { + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + } break; case GL_FOG: - imesa->reg_dirty |= (1<<I810_CTXREG_B1); + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE; - imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_FOG_ENABLE; if (state) imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE; break; case GL_CULL_FACE: if (ctx->PB->primitive == GL_POLYGON) { - imesa->reg_dirty |= (1<<I810_CTXREG_LCS); + FLUSH_BATCH(imesa); + imesa->dirty |= I810_UPLOAD_CTX; imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK; - imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_CULL_MODE; if (state) imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode; else imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE; } break; + case GL_TEXTURE_1D: + case GL_TEXTURE_3D: + FLUSH_BATCH(imesa); + imesa->new_state |= I810_NEW_TEXTURE; + break; case GL_TEXTURE_2D: - imesa->reg_dirty |= (1<<I810_CTXREG_MT); + FLUSH_BATCH(imesa); + imesa->new_state |= I810_NEW_TEXTURE; + imesa->dirty |= I810_UPLOAD_CTX; if (ctx->Texture.CurrentUnit == 0) { imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE; - imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL0_STATE; if (state) imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE; } else { imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE; - imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL1_STATE; if (state) imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE; } - - I810_CONTEXT(ctx)->new_state |= I810_NEW_TEXTURE; break; default: ; @@ -387,26 +699,6 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) } -/* Don't use the regs parm yet. - */ -static void i810UpdateRegs( GLcontext *ctx, GLuint regs ) -{ - i810ContextPtr imesa = I810_CONTEXT(ctx); - int i; - - { - BEGIN_BATCH( I810_CTX_SETUP_SIZE ); - - for (i = 0 ; i < I810_CTX_SETUP_SIZE ; i++) { - OUT_BATCH( imesa->Setup[i] ); - } - - ADVANCE_BATCH(); - } - - imesa->reg_dirty = 0; -} - /* ============================================================= */ @@ -417,50 +709,158 @@ void i810DDPrintState( const char *msg, GLuint state ) { fprintf(stderr, "%s (0x%x): %s\n", msg, - state, + (unsigned int) state, (state & I810_NEW_TEXTURE) ? "texture, " : ""); } + + void i810DDUpdateHwState( GLcontext *ctx ) { i810ContextPtr imesa = I810_CONTEXT(ctx); - if (imesa->new_state & I810_NEW_TEXTURE) + if (imesa->new_state & I810_NEW_TEXTURE) { + FLUSH_BATCH(imesa); i810UpdateTextureState( ctx ); + } imesa->new_state = 0; +} + - if (imesa->reg_dirty) { - i810FinishPrimitive(); - i810UpdateRegs( ctx, imesa->reg_dirty ); + +/* + * i810DmaExecute + * Add a block of data to the dma buffer + * + * -- In ring buffer mode, must be called with lock held, and translates to + * OUT_RING rather than outbatch + * + * -- In dma mode, probably won't be used because state updates will have + * to be done via the kernel for security... + */ +static void i810DmaExecute( i810ContextPtr imesa, + GLuint *code, int dwords, const char *where ) +{ + if (I810_DEBUG & DEBUG_VERBOSE_RING) + fprintf(stderr, "i810DmaExecute (%s)\n", where); + + if (dwords & 1) { + i810Error( "Misaligned buffer in i810DmaExecute\n" ); + exit(1); + } + + { + int i; + BEGIN_BATCH( imesa, dwords); + + for ( i = 0 ; i < dwords ; i++ ) { + OUT_BATCH( code[i] ); + } + + ADVANCE_BATCH(); } } -void i810DDInitStatePointers(GLcontext *ctx) + +void i810EmitDrawingRectangle( i810ContextPtr imesa ) { - ctx->Driver.Enable = i810DDEnable; - ctx->Driver.LightModelfv = i810DDLightModelfv; - ctx->Driver.AlphaFunc = i810DDAlphaFunc; - ctx->Driver.BlendEquation = i810DDBlendEquation; - ctx->Driver.BlendFunc = i810DDBlendFunc; - ctx->Driver.BlendFuncSeparate = i810DDBlendFuncSeparate; - ctx->Driver.DepthFunc = i810DDDepthFunc; - ctx->Driver.DepthMask = i810DDDepthMask; - ctx->Driver.Fogfv = i810DDFogfv; - ctx->Driver.Scissor = i810DDScissor; - ctx->Driver.CullFace = i810DDCullFaceFrontFace; - ctx->Driver.FrontFace = i810DDCullFaceFrontFace; - ctx->Driver.ColorMask = i810DDColorMask; - ctx->Driver.ReducedPrimitiveChange = i810DDReducedPrimitiveChange; - ctx->Driver.RenderStart = i810DDUpdateHwState; - ctx->Driver.RenderFinish = 0; + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i810ScreenPrivate *i810Screen = imesa->i810Screen; + + int x0 = imesa->drawX; + int y0 = imesa->drawY; + int x1 = x0 + dPriv->w; + int y1 = y0 + dPriv->h; + + + /* Coordinate origin of the window - may be offscreen. + */ + imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) | + (((unsigned)x0)&0xFFFF)); + + /* Clip to screen. + */ + if (x0 < 0) x0 = 0; + if (y0 < 0) y0 = 0; + if (x1 > i810Screen->width-1) x1 = i810Screen->width-1; + if (y1 > i810Screen->height-1) y1 = i810Screen->height-1; + + + /* Onscreen drawing rectangle. + */ + imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0); + imesa->BufferSetup[I810_DESTREG_DR3] = (((y1+1)<<16) | (x1+1)); + imesa->dirty |= I810_UPLOAD_BUFFERS; +} + + +static void i810DDPrintDirty( const char *msg, GLuint state ) +{ + fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n", + msg, + (unsigned int) state, + (state & I810_REFRESH_RING) ? "read-lp-ring, " : "", + (state & I810_WAIT_AGE) ? "wait-age, " : "", + (state & I810_UPLOAD_TEX0IMAGE) ? "upload-tex0, " : "", + (state & I810_UPLOAD_TEX1IMAGE) ? "upload-tex1, " : "", + (state & I810_UPLOAD_CTX) ? "upload-ctx, " : "", + (state & I810_UPLOAD_BUFFERS) ? "upload-bufs, " : "", + (state & I810_EMIT_CLIPRECT) ? "emit-single-cliprect, " : "" + ); } +/* Spew the state onto the ring/batch buffer and/or texture memory. + */ +void i810EmitHwStateLocked( i810ContextPtr imesa ) +{ + if (I810_DEBUG & DEBUG_VERBOSE_API) + i810DDPrintDirty( "\n\n\ni810EmitHwStateLocked", imesa->dirty ); + + if (imesa->dirty & ~(I810_WAIT_AGE|I810_EMIT_CLIPRECT)) + { + i810GetGeneralDmaBufferLocked( imesa ); + + if ((imesa->dirty & I810_UPLOAD_TEX0IMAGE) && imesa->CurrentTexObj[0]) + i810UploadTexImages(imesa, imesa->CurrentTexObj[0]); + + if ((imesa->dirty & I810_UPLOAD_TEX1IMAGE) && imesa->CurrentTexObj[1]) + i810UploadTexImages(imesa, imesa->CurrentTexObj[1]); + + if ((imesa->dirty & I810_UPLOAD_CTX)) { + i810DmaExecute( imesa, imesa->Setup, I810_CTX_SETUP_SIZE, "context" ); + + if (imesa->CurrentTexObj[0]) + i810DmaExecute( imesa, imesa->CurrentTexObj[0]->Setup, + I810_TEX_SETUP_SIZE, "tex-0"); + + if (imesa->CurrentTexObj[1]) + i810DmaExecute( imesa, imesa->CurrentTexObj[1]->Setup, + I810_TEX_SETUP_SIZE, "tex-1"); + } + + if (imesa->dirty & I810_UPLOAD_BUFFERS) + i810DmaExecute( imesa, imesa->BufferSetup, + I810_DEST_SETUP_SIZE, "buffers" ); + + i810FlushGeneralLocked( imesa ); + } + + /* Clear everything but the cliprect dirty flag: + */ + imesa->dirty &= (I810_EMIT_CLIPRECT|I810_WAIT_AGE); +} + + + void i810DDInitState( i810ContextPtr imesa ) { + i810ScreenPrivate *i810Screen = imesa->i810Screen; + + memset(imesa->Setup, 0, sizeof(imesa->Setup)); imesa->Setup[I810_CTXREG_VF] = (GFX_OP_VERTEX_FMT | VF_TEXCOORD_COUNT_2 | @@ -562,6 +962,8 @@ void i810DDInitState( i810ContextPtr imesa ) imesa->Setup[I810_CTXREG_SDM] = ( GFX_OP_SRC_DEST_MONO | + SDM_UPDATE_MONO_ENABLE | + 0 | SDM_UPDATE_SRC_BLEND | SDM_SRC_ONE | SDM_UPDATE_DST_BLEND | @@ -627,7 +1029,7 @@ void i810DDInitState( i810ContextPtr imesa ) LCS_UPDATE_ZMODE | LCS_Z_LESS | LCS_UPDATE_LINEWIDTH | - (0x2<<LCS_LINEWIDTH_SHIFT) | + LCS_LINEWIDTH_1_0 | LCS_UPDATE_ALPHA_INTERP | LCS_ALPHA_INTERP | LCS_UPDATE_FOG_INTERP | @@ -641,14 +1043,6 @@ void i810DDInitState( i810ContextPtr imesa ) imesa->LcsCullMode = LCS_CULL_CW; - imesa->Setup[I810_CTXREG_SCI0] = GFX_OP_SCISSOR_INFO; - imesa->Setup[I810_CTXREG_SCI1] = 0; - imesa->Setup[I810_CTXREG_SCI2] = 0; - - imesa->Setup[I810_CTXREG_SC] = ( GFX_OP_SCISSOR | - SC_UPDATE_SCISSOR | - 0 ); - imesa->Setup[I810_CTXREG_PV] = ( GFX_OP_PV_RULE | PV_UPDATE_PIXRULE | PV_PIXRULE_ENABLE | @@ -659,8 +1053,59 @@ void i810DDInitState( i810ContextPtr imesa ) PV_UPDATE_TRISTRIP | PV_TRISTRIP_PV0 ); -} + imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE; + imesa->Setup[I810_CTXREG_ST1] = 0; + + + + imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS | + AA_UPDATE_EDGEFLAG | + AA_ENABLE_EDGEFLAG | /* ? */ + AA_UPDATE_POLYWIDTH | + AA_POLYWIDTH_05 | + AA_UPDATE_LINEWIDTH | + AA_LINEWIDTH_05 | + AA_UPDATE_BB_EXPANSION | + 0 | + AA_UPDATE_AA_ENABLE | + 0 ); + + + + /* This stuff is all invarient as long as we are using + * shared back and depth buffers. + */ + memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup)); + imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO; + + if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT) { + imesa->drawMap = i810Screen->back.map; + imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset | + i810Screen->backPitchBits); + } else { + imesa->drawMap = imesa->driScreen->pFB; + imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset | + i810Screen->backPitchBits); + } + + if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT) { + imesa->readMap = i810Screen->back.map; + } else { + imesa->readMap = imesa->driScreen->pFB; + } + + imesa->BufferSetup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS; + imesa->BufferSetup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL | + DV_VORG_BIAS_OGL | + i810Screen->fbFormat); + imesa->BufferSetup[I810_DESTREG_ZB0] = CMD_OP_Z_BUFFER_INFO; + imesa->BufferSetup[I810_DESTREG_ZB1] = (i810Screen->depthOffset | + i810Screen->backPitchBits); + + imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO; + imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE; +} #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\ @@ -672,16 +1117,66 @@ void i810DDUpdateState( GLcontext *ctx ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); + /* Have to do this here to detect texture fallbacks in time: + */ + if (I810_CONTEXT(ctx)->new_state & I810_NEW_TEXTURE) + i810DDUpdateHwState( ctx ); + + if (ctx->NewState & INTERESTED) { - i810FinishPrimitive(); i810DDChooseRenderState(ctx); i810ChooseRasterSetupFunc(ctx); } + + if (0) + fprintf(stderr, "IndirectTriangles %x Fallback %x\n", + imesa->IndirectTriangles, imesa->Fallback); - /* TODO: stop mesa from clobbering these. - */ - ctx->Driver.PointsFunc=imesa->PointsFunc; - ctx->Driver.LineFunc=imesa->LineFunc; - ctx->Driver.TriangleFunc=imesa->TriangleFunc; - ctx->Driver.QuadFunc=imesa->QuadFunc; + if (!imesa->Fallback) + { + ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + ctx->IndirectTriangles |= imesa->IndirectTriangles; + + ctx->Driver.PointsFunc=imesa->PointsFunc; + ctx->Driver.LineFunc=imesa->LineFunc; + ctx->Driver.TriangleFunc=imesa->TriangleFunc; + ctx->Driver.QuadFunc=imesa->QuadFunc; + } +} + + +void i810DDInitStateFuncs(GLcontext *ctx) +{ + ctx->Driver.UpdateState = i810DDUpdateState; + ctx->Driver.Enable = i810DDEnable; + ctx->Driver.LightModelfv = i810DDLightModelfv; + ctx->Driver.AlphaFunc = i810DDAlphaFunc; + ctx->Driver.BlendEquation = i810DDBlendEquation; + ctx->Driver.BlendFunc = i810DDBlendFunc; + ctx->Driver.BlendFuncSeparate = i810DDBlendFuncSeparate; + ctx->Driver.DepthFunc = i810DDDepthFunc; + ctx->Driver.DepthMask = i810DDDepthMask; + ctx->Driver.Fogfv = i810DDFogfv; + ctx->Driver.Scissor = i810DDScissor; + ctx->Driver.CullFace = i810DDCullFaceFrontFace; + ctx->Driver.FrontFace = i810DDCullFaceFrontFace; + ctx->Driver.ColorMask = i810DDColorMask; + ctx->Driver.ReducedPrimitiveChange = i810DDReducedPrimitiveChange; + ctx->Driver.RenderStart = i810DDUpdateHwState; + ctx->Driver.RenderFinish = 0; + + ctx->Driver.PolygonStipple = i810DDPolygonStipple; + ctx->Driver.LineStipple = 0; + + ctx->Driver.SetReadBuffer = i810DDSetReadBuffer; + ctx->Driver.SetDrawBuffer = i810DDSetDrawBuffer; + + ctx->Driver.Color = i810DDSetColor; + ctx->Driver.ClearColor = i810DDClearColor; + ctx->Driver.Dither = i810DDDither; + + ctx->Driver.Index = 0; + ctx->Driver.ClearIndex = 0; + ctx->Driver.IndexMask = 0; } + diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.h b/xc/lib/GL/mesa/src/drv/i810/i810state.h index 1cccb44bb..d0551631e 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810state.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810state.h @@ -2,10 +2,12 @@ #define _I810_STATE_H -extern void i810DDInitStatePointers(GLcontext *ctx); extern void i810DDUpdateHwState( GLcontext *ctx ); extern void i810DDUpdateState( GLcontext *ctx ); extern void i810DDInitState( i810ContextPtr imesa ); +extern void i810DDInitStateFuncs( GLcontext *ctx ); + +extern void i810DDPrintState( const char *msg, GLuint state ); #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810swap.c b/xc/lib/GL/mesa/src/drv/i810/i810swap.c index 3c78921e3..a0f6d8938 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810swap.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810swap.c @@ -1,66 +1,71 @@ + +#include "types.h" +#include "vbrender.h" +#include "i810log.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "mm.h" +#include "i810lib.h" +#include "i810dd.h" +#include "i810dma.h" +#include "i810state.h" +#include "i810swap.h" +#include "i810dma.h" +#include "i810ioctl.h" + /* * i810BackToFront * - * Blit the visible rectangles from the back buffer to the screen - * Can't really do this from a direct context - don't have the clip - * info, and getting it would be a lot slower than just sending a - * request to the server to do the blit there. - * - * drawable -- front buffer - * buf -- back buffer + * Blit the visible rectangles from the back buffer to the screen. + * Respects the frontbuffer cliprects, and applies the offset + * necessary if the backbuffer is positioned elsewhere in the screen. */ -int i810BackToFront(DrawablePtr drawable, - struct i810_dest_buffer *buf) +static int i810BackToFront( i810ContextPtr imesa ) { - RegionPtr prgnClip; - BoxPtr pbox; - int i,nbox; - int ofs, xorg, yorg, pitch; - - if ( !xf86VTSema ) { - i810Error("BackToFront(): !xf86VTSema\n"); - return BadMatch; /* Is this really an error? */ - } - - if ( drawable->width != buf->Width || - drawable->height != buf->Height || - drawable->type != DRAWABLE_WINDOW ) { - i810Error("BackToFront(): bad drawable\n"); - return BadMatch; - } + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i810ScreenPrivate *i810Screen = imesa->i810Screen; - prgnClip = &((WindowPtr)drawable)->clipList; - pbox = REGION_RECTS(prgnClip); - nbox = REGION_NUM_RECTS(prgnClip); - if( !nbox ) return Success; - xorg = drawable->x; - yorg = drawable->y; - pitch = buf->Pitch; - ofs = buf->MemBlock->ofs; + /* Use the frontbuffer cliprects: + */ + XF86DRIClipRectPtr pbox = dPriv->pClipRects; + int nbox = dPriv->numClipRects; + if( nbox ) { - unsigned int BR13 = ((vga256InfoRec.displayWidth * vgaBytesPerPixel) | + int i; + int pitch = i810Screen->backPitch; + + int dx = dPriv->backX - dPriv->x; + int dy = dPriv->backY - dPriv->y; + int ofs = ( i810Screen->backOffset + + dy * i810Screen->backPitch + + dx * i810Screen->cpp); + + unsigned int BR13 = ((i810Screen->fbStride) | (0xCC << 16)); for (i=0; i < nbox; i++, pbox++) { - int x = pbox->x1 - xorg; - int y = pbox->y1 - yorg; int w = pbox->x2 - pbox->x1; int h = pbox->y2 - pbox->y1; - int start = ofs + x*vgaBytesPerPixel + y*pitch; - int dst = ((pbox->x1 + pbox->y1 * vga256InfoRec.displayWidth) * - vgaBytesPerPixel); + int start = ofs + pbox->x1*i810Screen->cpp + pbox->y1*pitch; + int dst = pbox->x1*i810Screen->cpp + pbox->y1*i810Screen->fbStride; + + if (I810_DEBUG&DEBUG_VERBOSE_2D) + fprintf(stderr, "i810BackToFront %d,%d-%dx%d\n", + pbox->x1,pbox->y1,w,h); { - BEGIN_BATCH( 6 ); + BEGIN_BATCH( imesa, 6 ); OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); OUT_BATCH( BR13 ); /* dest pitch, rop */ - OUT_BATCH( (h << 16) | (w * vgaBytesPerPixel)); + OUT_BATCH( (h << 16) | (w * i810Screen->cpp)); OUT_BATCH( dst ); OUT_BATCH( pitch ); /* src pitch */ @@ -76,33 +81,70 @@ int i810BackToFront(DrawablePtr drawable, /* * ClearBox - * Add hardware commands to draw a filled box for the - * debugging display. + * + * Add hardware commands to draw a filled box for the debugging + * display. These are drawn into the current drawbuffer, so should + * work with both front and backbuffer rendering. (However, it + * is only ever called on swapbuffer - ie backbuffer rendering). */ -static void ClearBox( int x, int y, int w, int h, int r, int g, int b ) +static void ClearBox( i810ContextPtr imesa, + int cx, int cy, int cw, int ch, + int r, int g, int b ) { - int start = (i810DB->MemBlock->ofs + - y * i810DB->Pitch + - x * vgaBytesPerPixel); - - BEGIN_BATCH(6); - - OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); - OUT_BATCH( BR13_SOLID_PATTERN | - (0xF0 << 16) | - i810DB->Pitch ); - OUT_BATCH( (h << 16) | (w * vgaBytesPerPixel)); - OUT_BATCH( start ); - OUT_BATCH( i810PackColor( i810DB->Format, r, g, b, 0 ) ); - OUT_BATCH( 0 ); + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i810ScreenPrivate *i810Screen = imesa->i810Screen; + + int _nc = imesa->numClipRects; + + while (_nc--) { + int x1 = cx + dPriv->x; + int y1 = cy + dPriv->y; + int x2 = x1 + cw; + int y2 = y1 + ch; + + { + int rx1 = imesa->pClipRects[_nc].x1; + int ry1 = imesa->pClipRects[_nc].y1; + int rx2 = imesa->pClipRects[_nc].x2; + int ry2 = imesa->pClipRects[_nc].y2; + + + if (x2 < rx1) continue; + if (y2 < ry1) continue; + if (x1 > rx2) continue; + if (y1 > ry2) continue; + if (x1 < rx1) x1 = rx1; + if (y1 < ry1) y1 = ry1; + if (x2 > rx2) x2 = rx2; + if (y2 > ry2) y2 = ry2; + } - if (0) - fprintf(stderr, "box %d,%x %dx%d col %x (%d,%d,%d)\n", x,y,w,h, - i810PackColor( i810DB->Format, r, g, b, 0 ), r, g, b); - ADVANCE_BATCH(); + { + int start = (0 + + y1 * i810Screen->backPitch + + x1 * i810Screen->cpp); + BEGIN_BATCH( imesa, 6 ); + OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); + OUT_BATCH( BR13_SOLID_PATTERN | + (0xF0 << 16) | + i810Screen->backPitch ); + OUT_BATCH( ((y2-y1) << 16) | ((x2-x1) * i810Screen->cpp)); + OUT_BATCH( start ); + OUT_BATCH( i810PackColor( i810Screen->fbFormat, r, g, b, 0 ) ); + OUT_BATCH( 0 ); + + if (I810_DEBUG&DEBUG_VERBOSE_2D) + fprintf(stderr, "box %d,%x %d,%d col %x (%d,%d,%d)\n", + (int)x1,(int)y1, (int)x2,(int)y2, + (int)i810PackColor( i810Screen->fbFormat, r, g, b, 0 ), + (int)r, (int)g, (int)b); + + ADVANCE_BATCH(); + } + } } @@ -111,143 +153,110 @@ static void ClearBox( int x, int y, int w, int h, int r, int g, int b ) * Draw some small boxesin the corner of the buffer * based on some performance information */ -void i810PerformanceBoxes( int is_direct ) { - int w, t; +static void i810PerformanceBoxes( i810ContextPtr imesa ) { - if ( !i810glx.boxes ) - return; - - - /* draw a box to show we are active, so if it is't seen - it means that it is completely software based rendering */ - /* draw a purple box if we are direct rendering */ - if ( is_direct ) { /* purple = direct (client dma) rendering */ - ClearBox( 4, 4, 8, 8, 255, 0, 255 ); - } else if ( i810glx.dmaDriver ) { /* white = server dma rendering */ - ClearBox( 4, 4, 8, 8, 255, 255, 255 ); - } else { /* grey = servery PDMA */ - ClearBox( 4, 4, 8, 8, 128, 128, 128 ); - } + + /* draw a box to show we are active, so if it is't seen it means + that it is completely software based. Purple is traditional for + direct rendering */ + ClearBox( imesa, 4, 4, 8, 8, 255, 0, 255 ); /* draw a red box if we had to wait for drawing to complete (software render or texture swap) */ if ( i810glx.c_drawWaits ) { - ClearBox( 16, 4, 8, 8, 255, 0, 0 ); + ClearBox( imesa, 16, 4, 8, 8, 255, 0, 0 ); i810glx.c_drawWaits = 0; } - /* draw a blue box if the register protection signal was hit */ - if ( i810glx.c_signals ) { - ClearBox( 28, 4, 8, 8, 0, 0, 255 ); - i810glx.c_signals = 0; + /* draw a blue box if the 3d context was lost + */ + if ( i810glx.c_ctxlost ) { + ClearBox( imesa, 28, 4, 8, 8, 0, 0, 255 ); + i810glx.c_ctxlost = 0; } + /* draw an orange box if texture state was stomped */ + if ( i810glx.c_texlost ) { + ClearBox( imesa, 40, 4, 8, 8, 255, 128, 0 ); + i810glx.c_texlost = 0; + } + /* draw a yellow box if textures were swapped */ if ( i810glx.c_textureSwaps ) { - ClearBox( 40, 4, 8, 8, 255, 255, 0 ); + ClearBox( imesa, 56, 4, 8, 8, 255, 255, 0 ); i810glx.c_textureSwaps = 0; } - - + /* draw a green box if we had to wait for dma to complete (full utilization) on the previous frame */ if ( !i810glx.hardwareWentIdle ) { - ClearBox( 64, 4, 8, 8, 0, 255, 0 ); + ClearBox( imesa, 72, 4, 8, 8, 0, 255, 0 ); } i810glx.hardwareWentIdle = 0; +#if 0 /* show buffer utilization */ if ( i810glx.c_dmaFlush > 1 ) { /* draw a solid bar if we flushed more than one buffer */ - ClearBox( 4, 16, 252, 4, 255, 32, 32 ); + ClearBox( imesa, 4, 16, 252, 4, 255, 32, 32 ); } else { - /* draw bars to represent the utilization of primary and secondary buffers */ - ClearBox( 4, 16, 252, 4, 32, 32, 32 ); + /* draw bars to represent the utilization of primary and + secondary buffers */ + ClearBox( imesa, 4, 16, 252, 4, 32, 32, 32 ); t = i810glx.dma_buffer->mem.Size; w = 252 * i810glx.dma_buffer->head / t; if ( w < 1 ) { w = 1; } - ClearBox( 4, 16, w, 4, 196, 128, 128 ); + ClearBox( imesa, 4, 16, w, 4, 196, 128, 128 ); } +#endif + i810glx.c_dmaFlush = 0; } -static void i810SendDmaFlush( void ) + +static void i810EmitFlush( i810ContextPtr imesa ) { - BEGIN_BATCH(2); + BEGIN_BATCH( imesa, 2 ); OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH ); OUT_BATCH( 0 ); ADVANCE_BATCH(); } - -/* - * Copy the back buffer to the front buffer. If there's no back buffer - * this is a no-op. Only called in indirect contexts. - */ -static void i810ServerSwapBuffers( XSMesaBuffer b ) +void i810SwapBuffers( i810ContextPtr imesa ) { - /* make sure mesa gives us everything */ - if (i810Ctx && i810Ctx->gl_ctx) - glFlush(); + int tmp; - if ( !b->db_state ) { - /* not double buffered, so do nothing */ - } else { - ValidateGC(b->frontbuffer, b->cleargc); - if ( b->backimage ) { - - struct i810_dest_buffer *buf = - (struct i810_dest_buffer *)b->backimage->devPriv; + if (I810_DEBUG & DEBUG_VERBOSE_API) + fprintf(stderr, "i810SwapBuffers()\n"); - if ( buf && buf->Drawable ) { + FLUSH_BATCH( imesa ); + LOCK_HARDWARE( imesa ); + + i810GetGeneralDmaBufferLocked( imesa ); + i810EmitFlush( imesa ); - /* flush the last primitive */ - i810FinishPrimitive(); + if ( i810glx.boxes ) + i810PerformanceBoxes( imesa ); - /* Drop a flush op into the dma stream */ - i810SendDmaFlush(); + i810BackToFront( imesa ); + i810EmitFlush( imesa ); + i810FlushGeneralLocked( imesa ); - /* diagnostic drawing tools */ - i810PerformanceBoxes( 0 ); + /* Throttle app if the last swap hasn't dispatched yet + */ + if (0) + fprintf(stderr, "dispatch age: %d last swap: %d\n", + GET_DISPATCH_AGE(imesa), imesa->lastSwap); + + tmp = GET_ENQUEUE_AGE(imesa); - /* hardware accelerated back to front blit */ - i810BackToFront( (DrawablePtr)b->frontbuffer,buf ); + UNLOCK_HARDWARE( imesa ); - /* make sure all dma is going to get executed if - * everything has gone well, this will be the only flush - * each frame - */ - i810DmaFlush(); + if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) + i810WaitAge(imesa, imesa->lastSwap); - } else { - /* Use backimage's dimension (not buffer's) */ - (*b->cleargc->ops->PutImage)((DrawablePtr)b->frontbuffer, - b->cleargc, - b->frontbuffer->depth, - 0, 0, - b->backimage->width, - b->backimage->height, - 0, ZPixmap, b->backimage->data); - } - } else { - /* Copy pixmap to window on server */ - (*b->cleargc->ops->CopyArea)((DrawablePtr)b->backpixmap, - b->frontbuffer, - b->cleargc, - 0, 0, b->width, b->height, - 0, 0); - } - } - - /* report performance counters */ - i810Msg(10, "swapBuffers: c_triangles:%i c_lines:%i c_points:%i c_setup:%i c_textures:%i\n", - i810glx.c_triangles, i810glx.c_lines, i810glx.c_points, i810glx.c_setupPointers, - i810glx.c_textureSwaps ); - i810glx.c_triangles = 0; - i810glx.c_lines = 0; - i810glx.c_points = 0; - i810glx.c_setupPointers = 0; - i810Msg(10, "---------------------------------------------------------\n" ); + imesa->secondLastSwap = imesa->lastSwap; + imesa->lastSwap = tmp; } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c index 5b1d00398..35c395296 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tex.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c @@ -22,7 +22,6 @@ * */ -#include "xsmesaP.h" #include <stdlib.h> #include <stdio.h> @@ -32,6 +31,7 @@ #include "i810lib.h" #include "i810tex.h" #include "i810log.h" +#include "i810ioctl.h" #include "simple_list.h" #include "enums.h" @@ -49,7 +49,6 @@ static void i810SetTexWrapping(i810TextureObjectPtr tex, GLenum s, GLenum t) val ^= (MCS_V_WRAP^MCS_V_CLAMP); tex->Setup[I810_TEXREG_MCS] = val; - tex->reg_dirty |= (1 << I810_TEXREG_MCS); } static void i810SetTexFilter(i810TextureObjectPtr t, GLenum minf, GLenum magf) @@ -136,10 +135,6 @@ static void i810SetTexFilter(i810TextureObjectPtr t, GLenum minf, GLenum magf) MLC_LOD_BIAS_MASK, 0x0); } - - t->reg_dirty |= ((1<<I810_TEXREG_MLC) | - (1<<I810_TEXREG_MLL) | - (1<<I810_TEXREG_MF)); } @@ -161,8 +156,8 @@ static void ReplicateMesaTexState(i810TextureObjectPtr t, i810SetTexBorderColor(t,mesatex->BorderColor); } -i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx, - struct gl_texture_object *tObj) +static i810TextureObjectPtr i810CreateTexObj(i810ContextPtr imesa, + struct gl_texture_object *tObj) { i810TextureObjectPtr t; GLuint height, width, pitch, i, textureFormat, log_pitch; @@ -194,7 +189,6 @@ i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx, case GL_COLOR_INDEX: textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444; t->texelBytes = 1; - t->UsePalette = 1; break; default: i810Error( "i810CreateTexObj: bad image->Format\n" ); @@ -211,6 +205,7 @@ i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx, log_pitch++; t->dirty_images = 0; + t->bound = 0; for ( height = i = 0 ; i < I810_TEX_MAXLEVELS && tObj->Image[i] ; i++ ) { t->image[i].image = tObj->Image[i]; @@ -226,7 +221,6 @@ i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx, t->min_level = 0; t->globj = tObj; t->age = 0; - t->reg_dirty = ~0; t->Setup[I810_TEXREG_MI0] = GFX_OP_MAP_INFO; @@ -279,89 +273,72 @@ i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx, ReplicateMesaTexState(t,tObj); tObj->DriverData = t; - insert_at_head(&ctx->SwappedOut, t); + imesa->dirty |= I810_UPLOAD_CTX; + make_empty_list( t ); return t; } -int i810DestroyTexObj(i810ContextPtr ctx, i810TextureObjectPtr t) +void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t) { - if (t) { - if (t->age > i810glx.dma_buffer_age) - i810WaitDrawingEngine(); + if (!t) return; + /* This is sad - need to sync *in case* we upload a texture + * to this newly free memory... + */ + if (t->MemBlock) { mmFreeMem(t->MemBlock); - t->MemBlock = 0; - remove_from_list(t); - free(t); + t->MemBlock = 0; + + if (t->age > imesa->dirtyAge) + imesa->dirtyAge = t->age; } - return 0; + + if (t->globj) + t->globj->DriverData = 0; + + if (t->bound) + imesa->CurrentTexObj[t->bound - 1] = 0; + + remove_from_list(t); + free(t); } -/* Card memory management - */ -static void i810SwapOutOldestTexObj( i810ContextPtr ctx ) +static void i810SwapOutTexObj(i810ContextPtr imesa, i810TextureObjectPtr t) { - i810TextureObjectPtr t = ctx->TexObjList.prev; - - fprintf(stderr, "swap out oldest, age %d, dma age %d\n", - t->age, i810glx.dma_buffer_age); + if (t->MemBlock) { + mmFreeMem(t->MemBlock); + t->MemBlock = 0; - if (t->age > i810glx.dma_buffer_age) - i810WaitDrawingEngine(); + if (t->age > imesa->dirtyAge) + imesa->dirtyAge = t->age; + } - mmFreeMem( t->MemBlock ); - t->MemBlock = 0; t->dirty_images = ~0; - move_to_tail(&ctx->SwappedOut, t); + move_to_tail(&(imesa->SwappedOut), t); } -/* Just allocates the memory - doesn't do the upload. - */ -static int i810SwapInTexObj( i810ContextPtr ctx, i810TextureObjectPtr t) -{ - i810Msg(10," Swapping in texture.\n"); - i810glx.c_textureSwaps++; - - /* Try to allocate textureHeap memory, swapping out stuff until we - * can. - */ - while (1) - { - t->MemBlock = mmAllocMem( i810glx.sysmemHeap, t->totalSize, 12, 0 ); - - if (t->MemBlock) - break; - if (is_empty_list(&ctx->TexObjList)) - return -1; - - i810SwapOutOldestTexObj( ctx ); - } - - t->Setup[I810_TEXREG_MI3] = t->MemBlock->ofs; - t->BufAddr = i810glx.sysmemVirtual + t->MemBlock->ofs; - t->reg_dirty |= ((1<<I810_TEXREG_MI0) | - (1<<I810_TEXREG_MI1) | - (1<<I810_TEXREG_MI2) | - (1<<I810_TEXREG_MI3)); - return 0; -} /* Upload an image from mesa's internal copy. */ -static int i810UploadTexLevel( i810TextureObjectPtr t, int level ) +static void i810UploadTexLevel( i810TextureObjectPtr t, int level ) { const struct gl_texture_image *image = t->image[level].image; int i,j; - i810Msg(10,"CopyImage():\n"); + if (I810_DEBUG & DEBUG_VERBOSE_LRU) + fprintf(stderr, "i810UploadTexLevel %d, BufAddr %p offset %x\n", + level, t->BufAddr, t->image[level].offset); /* Need triangle (rather than pixel) fallbacks to simulate this using * normal textured triangles. - */ + * + * DO THIS IN DRIVER STATE MANAGMENT, not hardware state. + * if (image->Border != 0) - i810Error("Not supported texture border %d.\n",image->Border); + i810Error("Not supported texture border %d.\n", (int) image->Border); + */ switch (t->image[level].internalFormat) { case GL_RGB: @@ -440,6 +417,8 @@ static int i810UploadTexLevel( i810TextureObjectPtr t, int level ) } break; + /* TODO: Translate color indices *now*: + */ case GL_COLOR_INDEX: { GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset); @@ -452,38 +431,221 @@ static int i810UploadTexLevel( i810TextureObjectPtr t, int level ) src += 1; } } - - t->UsePalette = I810_USE_PALETTE; } break; default: - i810Error("Not supported texture format %d\n",image->Format); - FatalError("bummer"); - return -1; + i810Error("Not supported texture format %d\n",(int)image->Format); + exit(1); } +} - return 0; + + +void i810PrintLocalLRU( i810ContextPtr imesa ) +{ + i810TextureObjectPtr t; + int sz = 1 << (imesa->i810Screen->logTextureGranularity); + + foreach( t, &imesa->TexObjList ) { + if (!t->globj) + fprintf(stderr, "Placeholder %d at %x sz %x\n", + t->MemBlock->ofs / sz, + t->MemBlock->ofs, + t->MemBlock->size); + else + fprintf(stderr, "Texture (bound %d) at %x sz %x\n", + t->bound, + t->MemBlock->ofs, + t->MemBlock->size); + + } +} + +void i810PrintGlobalLRU( i810ContextPtr imesa ) +{ + int i, j; + drm_i810_tex_region_t *list = imesa->sarea->texList; + + for (i = 0, j = I810_NR_TEX_REGIONS ; i < I810_NR_TEX_REGIONS ; i++) { + fprintf(stderr, "list[%d] age %d next %d prev %d\n", + j, list[j].age, list[j].next, list[j].prev); + j = list[j].next; + if (j == I810_NR_TEX_REGIONS) break; + } + + if (j != I810_NR_TEX_REGIONS) + fprintf(stderr, "Loop detected in global LRU\n"); +} + + +void i810ResetGlobalLRU( i810ContextPtr imesa ) +{ + drm_i810_tex_region_t *list = imesa->sarea->texList; + int sz = 1 << imesa->i810Screen->logTextureGranularity; + int i; + + /* (Re)initialize the global circular LRU list. The last element + * in the array (I810_NR_TEX_REGIONS) is the sentinal. Keeping it + * at the end of the array allows it to be addressed rationally + * when looking up objects at a particular location in texture + * memory. + */ + for (i = 0 ; (i+1) * sz <= imesa->i810Screen->textureSize ; i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = I810_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = I810_NR_TEX_REGIONS; + list[I810_NR_TEX_REGIONS].prev = i; + list[I810_NR_TEX_REGIONS].next = 0; + imesa->sarea->texAge = 0; } +static void i810UpdateTexLRU( i810ContextPtr imesa, i810TextureObjectPtr t ) +{ + int i; + int logsz = imesa->i810Screen->logTextureGranularity; + int start = t->MemBlock->ofs >> logsz; + int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; + drm_i810_tex_region_t *list = imesa->sarea->texList; + + imesa->texAge = ++imesa->sarea->texAge; + + /* Update our local LRU + */ + move_to_head( &(imesa->TexObjList), t ); + + /* Update the global LRU + */ + for (i = start ; i <= end ; i++) { + + list[i].in_use = 1; + list[i].age = imesa->texAge; + + /* remove_from_list(i) + */ + list[(unsigned)list[i].next].prev = list[i].prev; + list[(unsigned)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) + */ + list[i].prev = I810_NR_TEX_REGIONS; + list[i].next = list[I810_NR_TEX_REGIONS].next; + list[(unsigned)list[I810_NR_TEX_REGIONS].next].prev = i; + list[I810_NR_TEX_REGIONS].next = i; + } +} + -static int i810UploadTexImages( i810ContextPtr ctx, i810TextureObjectPtr t ) +/* Called for every shared texture region which has increased in age + * since we last held the lock. + * + * Figures out which of our textures have been ejected by other clients, + * and pushes a placeholder texture onto the LRU list to represent + * the other client's textures. + */ +void i810TexturesGone( i810ContextPtr imesa, + GLuint offset, + GLuint size, + GLuint in_use ) +{ + i810TextureObjectPtr t, tmp; + + foreach_s ( t, tmp, &imesa->TexObjList ) { + + if (t->MemBlock->ofs >= offset + size || + t->MemBlock->ofs + t->MemBlock->size <= offset) + continue; + + /* It overlaps - kick it off. Need to hold onto the currently bound + * objects, however. + */ + if (t->bound) + i810SwapOutTexObj( imesa, t ); + else + i810DestroyTexObj( imesa, t ); + } + + + if (in_use) { + t = (i810TextureObjectPtr) calloc(1,sizeof(*t)); + if (!t) return; + + t->MemBlock = mmAllocMem( imesa->texHeap, size, 0, offset); + insert_at_head( &imesa->TexObjList, t ); + } +} + + + + + +/* This is called with the lock held. May have to eject our own and/or + * other client's texture objects to make room for the upload. + */ +int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t ) { int i; + int ofs; i810glx.c_textureSwaps++; - if (!t->MemBlock) - i810SwapInTexObj( ctx, t ); + /* Do we need to eject LRU texture objects? + */ + if (!t->MemBlock) { + while (1) + { + t->MemBlock = mmAllocMem( imesa->texHeap, t->totalSize, 12, 0 ); + if (t->MemBlock) + break; - if (t->age > i810glx.dma_buffer_age) - i810WaitDrawingEngine(); + if (imesa->TexObjList.prev->bound) { + fprintf(stderr, "Hit bound texture in upload\n"); + i810PrintLocalLRU( imesa ); + return -1; + } - for (i = t->min_level ; i <= t->max_level ; i++) - if (t->dirty_images & (1<<i)) { - if (i810UploadTexLevel( t, i ) != 0) + if (imesa->TexObjList.prev == &(imesa->TexObjList)) { + fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); + mmDumpMemInfo( imesa->texHeap ); return -1; + } + + i810DestroyTexObj( imesa, imesa->TexObjList.prev ); } + + ofs = t->MemBlock->ofs; + t->Setup[I810_TEXREG_MI3] = imesa->i810Screen->textureOffset + ofs; + t->BufAddr = i810glx.texVirtual + ofs; + imesa->dirty |= I810_UPLOAD_CTX; + } + + /* Let the world know we've used this memory recently. + */ + i810UpdateTexLRU( imesa, t ); + + if (I810_DEBUG & DEBUG_VERBOSE_LRU) + fprintf(stderr, "dispatch age: %d age freed memory: %d\n", + GET_DISPATCH_AGE(imesa), imesa->dirtyAge); + + if (imesa->dirtyAge >= GET_DISPATCH_AGE(imesa)) + i810WaitAgeLocked( imesa, imesa->dirtyAge ); + + + if (t->dirty_images) { + if (I810_DEBUG & DEBUG_VERBOSE_LRU) + fprintf(stderr, "*"); + + for (i = t->min_level ; i <= t->max_level ; i++) + if (t->dirty_images & (1<<i)) + i810UploadTexLevel( t, i ); + } + t->dirty_images = 0; return 0; @@ -499,7 +661,6 @@ static void i810TexSetUnit( i810TextureObjectPtr t, GLuint unit ) t->Setup[I810_TEXREG_MCS] ^= (MCS_COORD_0 ^ MCS_COORD_1); t->Setup[I810_TEXREG_MF] ^= (MF_MAP_0 ^ MF_MAP_1); - t->reg_dirty = ~0; t->current_unit = unit; } @@ -519,30 +680,29 @@ static void i810UpdateTex0State( GLcontext *ctx ) if ( tObj != ctx->Texture.Unit[0].CurrentD[2] ) tObj = 0; - if (!(ctx->Texture.Enabled & 0xf) || !tObj || !tObj->Complete) { - - imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_ITERATED_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_ARG1 ); - imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_ARG1 ); + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ITERATED_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_ARG1 ); + + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ); - imesa->reg_dirty |= ((1<<I810_CTXREG_MA0) | - (1<<I810_CTXREG_MC0)); + + if (!(ctx->Texture.Enabled & 0xf) || !tObj || !tObj->Complete) { return; } @@ -557,30 +717,13 @@ static void i810UpdateTex0State( GLcontext *ctx ) i810TexSetUnit( t, 0 ); if (t->dirty_images) - i810UploadTexImages(imesa, t); - - t->age = ++i810glx.current_texture_age; - move_to_head(&imesa->TexObjList, t); - - imesa->CurrentTex0Obj = t; - - if (0) - if (t->UsePalette == I810_USE_PALETTE) { - if (ctx->Texture.SharedPalette) { - if (imesa->GlobalPaletteUpdated) - i810LoadTexturePalette(imesa->GlobalPalette,0,256); - imesa->GlobalPaletteUpdated = 0; - } - else { - i810LoadTexturePalette(t->Palette,0,256); - imesa->GlobalPaletteUpdated = 1; - } - } - - - if (t->reg_dirty) - i810DmaExecute(t->Setup,I810_TEX_SETUP_SIZE); + imesa->dirty |= I810_UPLOAD_TEX0IMAGE; + + imesa->CurrentTexObj[0] = t; + t->bound = 1; + if (t->MemBlock) + i810UpdateTexLRU( imesa, t ); switch (ctx->Texture.Unit[0].EnvMode) { case GL_REPLACE: @@ -730,15 +873,10 @@ static void i810UpdateTex0State( GLcontext *ctx ) break; default: - FatalError("unkown tex env mode"); + fprintf(stderr, "unknown tex env mode"); + exit(1); break; } - - - - imesa->reg_dirty |= ((1<<I810_CTXREG_MA0) | - (1<<I810_CTXREG_MC0)); - } @@ -756,36 +894,34 @@ static void i810UpdateTex1State( GLcontext *ctx ) if ( tObj != ctx->Texture.Unit[1].CurrentD[2] ) tObj = 0; - if (!(ctx->Texture.Enabled & 0xf0) || !tObj || !tObj->Complete) { - imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_ONE | - MC_ARG1_DONT_REPLICATE_ALPHA | - MC_ARG1_DONT_INVERT | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_ARG2_DONT_REPLICATE_ALPHA | - MC_ARG2_DONT_INVERT | - MC_UPDATE_OP | - MC_OP_DISABLE ); + imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ONE | + MC_ARG1_DONT_REPLICATE_ALPHA | + MC_ARG1_DONT_INVERT | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_ARG2_DONT_REPLICATE_ALPHA | + MC_ARG2_DONT_INVERT | + MC_UPDATE_OP | + MC_OP_DISABLE ); + + imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_ARG1_DONT_INVERT | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_ARG2_DONT_INVERT | + MA_UPDATE_OP | + MA_OP_ARG1 ); - imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_ARG1_DONT_INVERT | - MA_UPDATE_ARG2 | - MA_ARG2_CURRENT_ALPHA | - MA_ARG2_DONT_INVERT | - MA_UPDATE_OP | - MA_OP_ARG1 ); - - imesa->reg_dirty |= ((1<<I810_CTXREG_MA1) | - (1<<I810_CTXREG_MC1)); + if (!(ctx->Texture.Enabled & 0xf0) || !tObj || !tObj->Complete) { return; } @@ -796,35 +932,18 @@ static void i810UpdateTex1State( GLcontext *ctx ) if (!t) return; } - if (t->dirty_images) - i810UploadTexImages(imesa, t); - if (t->current_unit != 1) i810TexSetUnit( t, 1 ); - t->age = ++i810glx.current_texture_age; - move_to_head(&imesa->TexObjList, t); - imesa->CurrentTex1Obj = t; - - if (0) - if (t->UsePalette == I810_USE_PALETTE) { - if (ctx->Texture.SharedPalette) { - if (imesa->GlobalPaletteUpdated) - i810LoadTexturePalette(imesa->GlobalPalette,0,256); - imesa->GlobalPaletteUpdated = 0; - } - else { - i810LoadTexturePalette(t->Palette,0,256); - imesa->GlobalPaletteUpdated = 1; - } - } - + if (t->dirty_images) + imesa->dirty |= I810_UPLOAD_TEX1IMAGE; - if (t->reg_dirty) - i810DmaExecute(t->Setup,I810_TEX_SETUP_SIZE); + imesa->CurrentTexObj[1] = t; + t->bound = 2; + if (t->MemBlock) + i810UpdateTexLRU( imesa, t ); - switch (ctx->Texture.Unit[1].EnvMode) { case GL_REPLACE: imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | @@ -980,64 +1099,70 @@ static void i810UpdateTex1State( GLcontext *ctx ) break; default: - FatalError("unkown tex 1 env mode"); + fprintf(stderr, "unkown tex 1 env mode\n"); + exit(1); break; } - - imesa->reg_dirty |= ((1<<I810_CTXREG_MA1) | - (1<<I810_CTXREG_MC1)); } void i810UpdateTextureState( GLcontext *ctx ) { + i810ContextPtr imesa = I810_CONTEXT(ctx); + if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound = 0; + if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound = 0; + imesa->CurrentTexObj[0] = 0; + imesa->CurrentTexObj[1] = 0; i810UpdateTex0State( ctx ); i810UpdateTex1State( ctx ); + I810_CONTEXT( ctx )->dirty |= I810_UPLOAD_CTX; } /***************************************** - * Driver functions + * DRIVER functions *****************************************/ -void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param ) +static void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); if (pname == GL_TEXTURE_ENV_MODE) { + FLUSH_BATCH(imesa); imesa->new_state |= I810_NEW_TEXTURE; } else if (pname == GL_TEXTURE_ENV_COLOR) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - GLubyte c[4]; + GLfloat *fc = texUnit->EnvColor; GLuint col; - FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c); - col = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]); + col = ((((GLubyte)fc[3])<<24) | + (((GLubyte)fc[0])<<16) | + (((GLubyte)fc[1])<<8) | + (((GLubyte)fc[2])<<0)); if (imesa->Setup[I810_CTXREG_CF1] != col) { + FLUSH_BATCH(imesa); imesa->Setup[I810_CTXREG_CF1] = col; - imesa->reg_dirty |= (1<<I810_CTXREG_CF1); + imesa->dirty |= I810_UPLOAD_CTX; } } } -void i810TexImage( GLcontext *ctx, - GLenum target, - struct gl_texture_object *tObj, - GLint level, - GLint internalFormat, - const struct gl_texture_image *image ) +static void i810TexImage( GLcontext *ctx, + GLenum target, + struct gl_texture_object *tObj, + GLint level, + GLint internalFormat, + const struct gl_texture_image *image ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); i810TextureObjectPtr t; - CHECK_CONTEXT( return; ); - i810Msg(10,"i810TexImage(%d): level %d internalFormat %x\n", tObj->Name, level, internalFormat); @@ -1049,6 +1174,7 @@ void i810TexImage( GLcontext *ctx, t = (i810TextureObjectPtr) tObj->DriverData; if (t) { + if (t->bound) FLUSH_BATCH(imesa); /* if this is the current object, it will force an update */ i810DestroyTexObj( imesa, t ); tObj->DriverData = 0; @@ -1056,12 +1182,12 @@ void i810TexImage( GLcontext *ctx, } } -void i810TexSubImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLint internalFormat, - const struct gl_texture_image *image ) +static void i810TexSubImage( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLint internalFormat, + const struct gl_texture_image *image ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); i810TextureObjectPtr t; @@ -1070,13 +1196,12 @@ void i810TexSubImage( GLcontext *ctx, GLenum target, width, height, image->Width,image->Height, level); - CHECK_CONTEXT( return; ); - if ( target != GL_TEXTURE_2D ) return; t = (i810TextureObjectPtr) tObj->DriverData; if (t) { + if (t->bound) FLUSH_BATCH( imesa ); i810DestroyTexObj( imesa, t ); tObj->DriverData = 0; imesa->new_state |= I810_NEW_TEXTURE; @@ -1084,9 +1209,9 @@ void i810TexSubImage( GLcontext *ctx, GLenum target, } } -void i810TexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) +static void i810TexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) { i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData; i810ContextPtr imesa = I810_CONTEXT( ctx ); @@ -1097,97 +1222,82 @@ void i810TexParameter( GLcontext *ctx, GLenum target, switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: + if (t->bound) FLUSH_BATCH( imesa ); i810SetTexFilter(t,tObj->MinFilter,tObj->MagFilter); break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: + if (t->bound) FLUSH_BATCH( imesa ); i810SetTexWrapping(t,tObj->WrapS,tObj->WrapT); break; case GL_TEXTURE_BORDER_COLOR: + if (t->bound) FLUSH_BATCH( imesa ); i810SetTexBorderColor(t,tObj->BorderColor); break; default: return; } + imesa->new_state |= I810_NEW_TEXTURE; } -void i810BindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj ) +static void i810BindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); + + FLUSH_BATCH(imesa); - if (target != GL_TEXTURE_2D) - return; + if (imesa->CurrentTexObj[ctx->Texture.CurrentUnit]) { + imesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0; + imesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0; + } imesa->new_state |= I810_NEW_TEXTURE; } -void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) +static void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData; i810ContextPtr imesa = I810_CONTEXT( ctx ); - i810DestroyTexObj(imesa,t); - tObj->DriverData=0; -} - -void i810UpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj ) -{ - i810ContextPtr imesa = I810_CONTEXT( ctx ); - i810TextureObjectPtr t; - GLushort *dst; - GLubyte *src; - int i, size, next; - GLenum format; + if (t) { + if (t->bound) { + FLUSH_BATCH(imesa); + imesa->CurrentTexObj[t->bound-1] = 0; + imesa->new_state |= I810_NEW_TEXTURE; + } - return; + i810DestroyTexObj(imesa,t); + tObj->DriverData=0; + } +} - if (tObj) - { - i810Msg(8,"i810UpdateTexturePalette(): size %d\n", tObj->PaletteSize); - t = (i810TextureObjectPtr) tObj->DriverData;; - if (!t) return; - size = tObj->PaletteSize; - format = tObj->PaletteFormat; - dst = t->Palette; - src = (GLubyte *) tObj->Palette; - } - else - { - /* shared palette */ - imesa->GlobalPaletteUpdated = 1; - size = ctx->Texture.PaletteSize; - format = ctx->Texture.PaletteFormat; - dst = imesa->GlobalPalette; - src = (GLubyte *) ctx->Texture.Palette; - - i810Msg(8, "i810UpdateTexturePalette(): size %d intFormat %x format %x\n", - size, ctx->Texture.PaletteIntFormat, ctx->Texture.PaletteFormat); - } +static GLboolean i810IsTextureResident( GLcontext *ctx, + struct gl_texture_object *t ) +{ + i810TextureObjectPtr mt; - if (size > 256) { - i810Error("i810UpdateTexturePalette(): palette > 256 entries!\n"); - return; - } +/* LOCK_HARDWARE; */ + mt = (i810TextureObjectPtr)t->DriverData; +/* UNLOCK_HARDWARE; */ - switch (format) - { - case GL_RGB: next = 3; break; - case GL_RGBA:next = 4; break; - default : - i810Error("i810UpdateTexturePalette(): unsupported palette format %x\n"); - next = 4; - } + return mt && mt->MemBlock; +} - for (i=0; i < size; i++) { - *dst = I810PACKCOLOR565(src[RCOMP],src[GCOMP],src[BCOMP]); - dst++; - src += next; - } +void i810DDInitTextureFuncs( GLcontext *ctx ) +{ + ctx->Driver.TexEnv = i810TexEnv; + ctx->Driver.TexImage = i810TexImage; + ctx->Driver.TexSubImage = i810TexSubImage; + ctx->Driver.BindTexture = i810BindTexture; + ctx->Driver.DeleteTexture = i810DeleteTexture; + ctx->Driver.TexParameter = i810TexParameter; + ctx->Driver.UpdateTexturePalette = 0; + ctx->Driver.IsTextureResident = i810IsTextureResident; } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.h b/xc/lib/GL/mesa/src/drv/i810/i810tex.h index ed9875be8..5261d0b1b 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tex.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.h @@ -26,16 +26,31 @@ #ifndef I810TEX_INC #define I810TEX_INC -#include "mesaglx/types.h" +#include "types.h" #include "mmath.h" +#include "mm.h" -#include "i810common.h" -#include "i810buf.h" +#include "i810context.h" +#include "i810_3d_reg.h" #define VALID_I810_TEXTURE_OBJECT(tobj) (tobj) #define I810_TEX_MAXLEVELS 10 + + +/* For shared texture space managment, these texture objects may also + * be used as proxies for regions of texture memory containing other + * client's textures. Such proxy textures (not to be confused with GL + * proxy textures) are subject to the same LRU aging we use for our + * own private textures, and thus we have a mechanism where we can + * fairly decide between kicking out our own textures and those of + * other clients. + * + * Non-local texture objects have a valid MemBlock to describe the + * region managed by the other client, and can be identified by + * 't->globj == 0' + */ struct i810_texture_object_t { struct i810_texture_object_t *next, *prev; @@ -46,11 +61,11 @@ struct i810_texture_object_t { int Height; int texelBytes; int totalSize; + int bound; - PMemBlock MemBlock; - + PMemBlock MemBlock; char *BufAddr; - + GLuint min_level; GLuint max_level; GLuint dirty_images; @@ -64,13 +79,8 @@ struct i810_texture_object_t { /* Support for multitexture. */ - GLuint current_unit; - + GLuint current_unit; GLuint Setup[I810_TEX_SETUP_SIZE]; - GLuint reg_dirty; - - GLushort Palette[256]; - int UsePalette; }; #define I810_NO_PALETTE 0x0 @@ -80,38 +90,20 @@ struct i810_texture_object_t { typedef struct i810_texture_object_t *i810TextureObjectPtr; -i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx, - struct gl_texture_object *tObj); -int i810DestroyTexObj(i810ContextPtr ctx, i810TextureObjectPtr t); -void i810UpdateTextureState(GLcontext *ctx); - - -/* Driver functions */ - -void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param ); - -void i810TexImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint internalFormat, - const struct gl_texture_image *image ); +void i810UpdateTextureState( GLcontext *ctx ); +void i810DDInitTextureFuncs( GLcontext *ctx ); -void i810TexSubImage( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLint internalFormat, - const struct gl_texture_image *image ); +void i810DestroyTexObj( i810ContextPtr imesa, i810TextureObjectPtr t); +int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t ); -void i810TexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ); +void i810ResetGlobalLRU( i810ContextPtr imesa ); +void i810TexturesGone( i810ContextPtr imesa, + GLuint start, GLuint end, + GLuint in_use ); -void i810BindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj ); +void i810PrintLocalLRU( i810ContextPtr imesa ); +void i810PrintGlobalLRU( i810ContextPtr imesa ); -void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ); -void i810UpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj ); -void i810UseGlobalTexturePalette( GLcontext *ctx, GLboolean state ); #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.c b/xc/lib/GL/mesa/src/drv/i810/i810tris.c index 1c81b9549..d970e3a36 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.c @@ -26,6 +26,7 @@ #include <stdio.h> #include <math.h> +#include "types.h" #include "vb.h" #include "pipeline.h" @@ -34,28 +35,9 @@ #include "i810tris.h" #include "i810vb.h" #include "i810log.h" -#include "xsmesaP.h" - - -static void i810_null_quad( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint v3, GLuint pv ) -{ -} - -static void i810_null_triangle( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint pv ) -{ -} - -static void i810_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) -{ -} - -static void i810_null_points( GLcontext *ctx, GLuint first, GLuint last ) -{ -} - +/* Used in i810tritmp.h + */ #define I810_COLOR(to, from) { \ (to)[0] = (from)[2]; \ (to)[1] = (from)[1]; \ @@ -70,17 +52,6 @@ static quad_func quad_tab[0x20]; static line_func line_tab[0x20]; static points_func points_tab[0x20]; -void i810PrintRenderState( const char *msg, GLuint state ) -{ - fprintf(stderr, "%s: (%x) %s%s%s%s%s%s\n", - msg, state, - (state & I810_FLAT_BIT) ? "flat, " : "", - (state & I810_OFFSET_BIT) ? "offset, " : "", - (state & I810_TWOSIDE_BIT) ? "twoside, " : "", - (state & I810_ANTIALIAS_BIT) ? "antialias, " : "", - (state & I810_NODRAW_BIT) ? "no-draw, " : "", - (state & I810_FALLBACK_BIT) ? "fallback" : ""); -} #define IND (0) #define TAG(x) x @@ -90,33 +61,32 @@ void i810PrintRenderState( const char *msg, GLuint state ) #define TAG(x) x##_flat #include "i810tritmp.h" -#define IND (I810_OFFSET_BIT) +#define IND (I810_OFFSET_BIT) /* wide */ #define TAG(x) x##_offset #include "i810tritmp.h" -#define IND (I810_OFFSET_BIT|I810_FLAT_BIT) +#define IND (I810_OFFSET_BIT|I810_FLAT_BIT) /* wide|flat */ #define TAG(x) x##_offset_flat #include "i810tritmp.h" -#define IND (I810_TWOSIDE_BIT) +#define IND (I810_TWOSIDE_BIT) /* stipple */ #define TAG(x) x##_twoside #include "i810tritmp.h" -#define IND (I810_TWOSIDE_BIT|I810_FLAT_BIT) +#define IND (I810_TWOSIDE_BIT|I810_FLAT_BIT) /* stipple|flat */ #define TAG(x) x##_twoside_flat #include "i810tritmp.h" -#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT) +#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT) /* stipple|wide */ #define TAG(x) x##_twoside_offset #include "i810tritmp.h" -#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FLAT_BIT) +#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FLAT_BIT) /* stip|wide|flat*/ #define TAG(x) x##_twoside_offset_flat #include "i810tritmp.h" void i810DDTrifuncInit() { - int i; init(); init_flat(); init_offset(); @@ -125,113 +95,9 @@ void i810DDTrifuncInit() init_twoside_flat(); init_twoside_offset(); init_twoside_offset_flat(); - - /* Hmmm... - */ - for (i = 0 ; i < 0x20 ; i++) { - if (i & ~I810_FLAT_BIT) { - points_tab[i] = points_tab[i&I810_FLAT_BIT]; - line_tab[i] = line_tab[i&I810_FLAT_BIT]; - } - } - - for (i = 0 ; i < 0x20 ; i++) - if ((i & (I810_NODRAW_BIT|I810_FALLBACK_BIT)) == I810_NODRAW_BIT || - i810glx.nullprims) - { - quad_tab[i] = i810_null_quad; - tri_tab[i] = i810_null_triangle; - line_tab[i] = i810_null_line; - points_tab[i] = i810_null_points; - } - - if (i810glx.noFallback) { - for (i = 0 ; i < 0x10 ; i++) { - points_tab[i|I810_FALLBACK_BIT] = points_tab[i]; - line_tab[i|I810_FALLBACK_BIT] = line_tab[i]; - tri_tab[i|I810_FALLBACK_BIT] = tri_tab[i]; - quad_tab[i|I810_FALLBACK_BIT] = quad_tab[i]; - } - } - } -/* Everything is done via single triangle instructiopns at the moment; - * this can change fairly easily. - */ -#if I810_USE_BATCH - -GLuint *i810AllocPrimitiveVerts( int dwords ) -{ - GLuint orig_dwords = dwords; - - dwords+=2; - dwords&=~1; - - while (1) { - if (i810glx.dma_buffer->space < dwords * 4) - { - if (I810_DEBUG & DEBUG_VERBOSE_RING) - fprintf(stderr, "i810AllocPrimitiveVerts: dma buffer overflow\n"); - i810DmaOverflow( dwords ); - } - else - { - GLuint start = i810glx.dma_buffer->head; - i810glx.dma_buffer->head += dwords * 4; - i810glx.dma_buffer->space -= dwords * 4; - - if ((orig_dwords & 1) == 0) { - *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) = 0; - start += 4; - } - - *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) = - GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1); - - return (GLuint *)(i810glx.dma_buffer->virtual_start + start + 4); - } - } -} - -#else -GLuint *i810AllocPrimitiveVerts( int dwords ) -{ - GLuint orig_dwords = dwords; - - dwords+=2; - dwords&=~1; - - while (1) - { - BEGIN_LP_RING( dwords ); - - if (outring + dwords * 4 != ((outring + dwords * 4) & ringmask)) - { - int i; - - if (I810_DEBUG & DEBUG_VERBOSE_RING) - fprintf(stderr, "\n\nwrap case in i810AllocPrimitiveVerts\n\n"); - - for (i = 0 ; i < dwords ; i++) - OUT_RING( 0 ); - ADVANCE_LP_RING(); - } - else - { - I810LpRing.tail = outring + dwords * 4; - - if ((orig_dwords & 1) == 0) - OUT_RING(0); - - OUT_RING( GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1) ); - return (GLuint *)(virt + outring); - } - } -} -#endif - void i810DDChooseRenderState( GLcontext *ctx ) @@ -239,50 +105,41 @@ void i810DDChooseRenderState( GLcontext *ctx ) i810ContextPtr imesa = I810_CONTEXT( ctx ); GLuint flags = ctx->TriangleCaps; - ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + imesa->IndirectTriangles = 0; if (flags) { GLuint ind = 0; GLuint shared = 0; - GLuint setup = imesa->setupindex; - GLuint fallback = I810_FALLBACK_BIT; - - if (i810glx.noFallback) fallback = 0; - if ((flags & DD_FLATSHADE) && (setup & I810_RGBA_BIT)) shared |= I810_FLAT_BIT; - if (flags & DD_MULTIDRAW) shared |= fallback; + if (flags & DD_FLATSHADE) shared |= I810_FLAT_BIT; + if (flags & DD_MULTIDRAW) shared |= I810_FALLBACK_BIT; if (flags & DD_SELECT) shared |= I810_FALLBACK_BIT; if (flags & DD_FEEDBACK) shared |= I810_FALLBACK_BIT; - ind = shared; - if (flags & DD_POINT_SMOOTH) ind |= I810_ANTIALIAS_BIT; - if (flags & DD_POINT_ATTEN) ind |= fallback; - - imesa->renderindex = ind; - imesa->PointsFunc = points_tab[ind]; - if (ind & I810_FALLBACK_BIT) - ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + imesa->renderindex = shared; + imesa->PointsFunc = points_tab[shared]; ind = shared; - if (flags & DD_LINE_SMOOTH) ind |= I810_ANTIALIAS_BIT; - if (flags & DD_LINE_STIPPLE) ind |= fallback; + if (flags & DD_LINE_WIDTH) ind |= I810_WIDE_LINE_BIT; + if (flags & DD_LINE_STIPPLE) ind |= I810_FALLBACK_BIT; imesa->renderindex |= ind; imesa->LineFunc = line_tab[ind]; if (ind & I810_FALLBACK_BIT) - ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE; + imesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE; ind = shared; - if (flags & DD_TRI_SMOOTH) ind |= I810_ANTIALIAS_BIT; if (flags & DD_TRI_OFFSET) ind |= I810_OFFSET_BIT; if (flags & DD_TRI_LIGHT_TWOSIDE) ind |= I810_TWOSIDE_BIT; - if (flags & (DD_TRI_UNFILLED|DD_TRI_STIPPLE)) ind |= fallback; + if (flags & DD_TRI_UNFILLED) ind |= I810_FALLBACK_BIT; + if ((flags & DD_TRI_STIPPLE) && + (ctx->IndirectTriangles & DD_TRI_STIPPLE)) ind |= I810_FALLBACK_BIT; imesa->renderindex |= ind; imesa->TriangleFunc = tri_tab[ind]; imesa->QuadFunc = quad_tab[ind]; if (ind & I810_FALLBACK_BIT) - ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE); + imesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE); } else if (imesa->renderindex) { @@ -293,9 +150,9 @@ void i810DDChooseRenderState( GLcontext *ctx ) imesa->QuadFunc = quad_tab[0]; } - if (MESA_VERBOSE&VERBOSE_DRIVER) { + + if (I810_DEBUG&DEBUG_VERBOSE_API) { gl_print_tri_caps("tricaps", ctx->TriangleCaps); - i810PrintRenderState("i810: Render state", imesa->renderindex); } } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h index 12e0ec7fd..5b73b7676 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h @@ -23,107 +23,76 @@ * */ -#ifndef I810TIS_INC -#define I810TIS_INC +#ifndef I810TRIS_INC +#define I810TRIS_INC -#include "mesaglx/types.h" +#include "types.h" +#include "i810dma.h" +#include "i810ioctl.h" +extern void i810PrintRenderState( const char *msg, GLuint state ); extern void i810DDChooseRenderState(GLcontext *ctx); -extern void i810DDTrifuncInit(); +extern void i810DDTrifuncInit( void ); -/* extern void i810FinishPrimitive( void ); */ -extern void i810NaughtyFinishPrimitive( void ); -extern GLuint *i810AllocPrimitiveVerts( int dwords ); +/* shared */ +#define I810_FLAT_BIT 0x1 +/* triangle */ +#define I810_OFFSET_BIT 0x2 +#define I810_TWOSIDE_BIT 0x4 -/* Todo: - * - multidraw, ... - * - Antialiasing (?) - * - line and polygon stipple - * - select and feedback - * - stencil - * - point parameters - * - - */ -#define I810_ANTIALIAS_BIT 0 /* ignored for now, no fallback */ -#define I810_FLAT_BIT 0x1 -#define I810_OFFSET_BIT 0x2 /* 3.1 only */ -#define I810_TWOSIDE_BIT 0x4 /* 3.1 only */ -#define I810_NODRAW_BIT 0x8 -#define I810_FALLBACK_BIT 0x10 - -/* Not in use: - */ -#define I810_FEEDBACK_BIT 0x20 -#define I810_SELECT_BIT 0x40 -#define I810_POINT_PARAM_BIT 0x80 /* not needed? */ +/* line */ +#define I810_WIDE_LINE_BIT 0x2 +#define I810_STIPPLE_LINE_BIT 0x4 +/* shared */ +#define I810_FALLBACK_BIT 0x8 -static inline void i810_draw_triangle( i810_vertex *v0, - i810_vertex *v1, - i810_vertex *v2 ) -{ -#if 0 - fprintf(stderr, "i810_draw_triangle( %p, %p, %p )\n", v0, v1, v2); -#endif +static i810_vertex __inline__ *i810AllocTriangles( i810ContextPtr imesa, int nr) +{ + GLuint *start = i810AllocDwords( imesa, 30*nr+1 ); + *start++ = GFX_OP_PRIMITIVE | PR_TRIANGLES | (30*nr-1); + return (i810_vertex *)start; +} -#if 0 -#define WID 640 -#define HI 480 - { - GLuint print = 1, draw = 1; - GLfloat area = ((v0->x - v2->x) * (v1->y - v2->y) - - (v0->y - v2->y) * (v1->x - v2->x)); - - if (v0->x < -.501 || v0->x > WID || v0->y < -.501 || v0->y > HI || - v1->x < -.501 || v1->x > WID || v1->y < -.501 || v1->y > HI || - v2->x < -.501 || v2->x > WID || v2->y < -.501 || v2->y > HI) { - fprintf(stderr, "not clipped\n"); - print = 1; - } - - if (area == 0 && ((v0 == v1) || (v1 == v2))) { - fprintf(stderr, "zero area %p %p %p\n", v0, v1, v2); - draw = 0; - } - - if (print) { - fprintf(stderr," v0: %f %f %f %f tex: %f %f\n", - v0->x, v0->y, v0->z, v0->oow, v0->tu0, v0->tv0); - fprintf(stderr," v1: %f %f %f %f tex: %f %f\n", - v1->x, v1->y, v1->z, v1->oow, v1->tu0, v1->tv0); - fprintf(stderr," v2: %f %f %f %f tex: %f %f\n", - v2->x, v2->y, v2->z, v2->oow, v2->tu0, v2->tv0); - return; - } - - if (!draw) return; - } -#endif +static i810_vertex __inline__ *i810AllocLine( i810ContextPtr imesa ) +{ + GLuint *start = i810AllocDwords( imesa, 21 ); + *start++ = GFX_OP_PRIMITIVE | PR_LINESTRIP | (20-1); + return (i810_vertex *)start; +} - { - i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( 3 * 10 ); - wv[0] = *v0; - wv[1] = *v1; - wv[2] = *v2; - FINISH_PRIM(); - } +static i810_vertex __inline__ *i810AllocRect( i810ContextPtr imesa ) +{ + GLuint *start = i810AllocDwords( imesa, 31 ); + *start++ = GFX_OP_PRIMITIVE | PR_RECTS | (30-1); + return (i810_vertex *)start; } +static void __inline__ i810_draw_triangle( i810ContextPtr imesa, + i810_vertex *v0, + i810_vertex *v1, + i810_vertex *v2 ) +{ + i810_vertex *wv = i810AllocTriangles( imesa, 1 ); + wv[0] = *v0; + wv[1] = *v1; + wv[2] = *v2; + FINISH_PRIM(); +} -/* These can go soon, but for the meantime we're using triangles for - * everything. - */ -static inline void i810_draw_point( i810_vertex *tmp, float sz ) + +static __inline__ void i810_draw_point( i810ContextPtr imesa, + i810_vertex *tmp, float sz ) { - i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts(6*10); + i810_vertex *wv = i810AllocTriangles( imesa, 2 ); wv[0] = *tmp; wv[0].x = tmp->x - sz; @@ -153,11 +122,23 @@ static inline void i810_draw_point( i810_vertex *tmp, float sz ) } -static inline void i810_draw_line( i810_vertex *tmp0, - i810_vertex *tmp1, - float width ) +static __inline__ void i810_draw_line_line( i810ContextPtr imesa, + i810_vertex *tmp0, + i810_vertex *tmp1 ) +{ + i810_vertex *wv = i810AllocLine( imesa ); + wv[0] = *tmp0; + wv[1] = *tmp1; + FINISH_PRIM(); +} + +static __inline__ void i810_draw_tri_line( i810ContextPtr imesa, + i810_vertex *tmp0, + i810_vertex *tmp1, + float width ) { - i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( 6 * 10 ); + i810_vertex *wv = i810AllocTriangles( imesa, 2 ); + float dx, dy, ix, iy; dx = tmp0->x - tmp1->x; @@ -168,15 +149,6 @@ static inline void i810_draw_line( i810_vertex *tmp0, iy = ix; ix = 0; } -#if 0 - fprintf(stderr,"tmp0: %f %f %f %f col: %x tex: %f %f\n", - tmp0->x, tmp0->y, tmp0->z, tmp0->oow, *(GLuint*)&tmp0->color, tmp0->tu0, tmp0->tv0); - fprintf(stderr,"tmp1: %f %f %f %f col: %x tex: %f %f\n", - tmp1->x, tmp1->y, tmp1->z, tmp1->oow, *(GLuint*)&tmp1->color, tmp1->tu0, tmp1->tv0); - fprintf(stderr, "ix: %f, iy: %f\n", ix, iy); -#endif - - wv[0] = *tmp0; wv[0].x = tmp0->x - ix; wv[0].y = tmp0->y - iy; @@ -200,8 +172,16 @@ static inline void i810_draw_line( i810_vertex *tmp0, wv[5] = *tmp1; wv[5].x = tmp1->x + ix; wv[5].y = tmp1->y + iy; - FINISH_PRIM(); } + +static __inline__ void i810_draw_line( i810ContextPtr imesa, + i810_vertex *tmp0, + i810_vertex *tmp1, + float width ) +{ + i810_draw_line_line( imesa, tmp0, tmp1 ); +} + #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h index c8ec01d49..ebe1ef5ea 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h @@ -1,19 +1,20 @@ -static inline void TAG(triangle)( GLcontext *ctx, GLuint e0, - GLuint e1, GLuint e2, GLuint pv ) +static __inline__ void TAG(triangle)( GLcontext *ctx, GLuint e0, + GLuint e1, GLuint e2, GLuint pv ) { + i810ContextPtr imesa = I810_CONTEXT(ctx); struct vertex_buffer *VB = ctx->VB; i810VertexPtr i810VB = I810_DRIVER_DATA(VB)->verts; - const i810_vertex *v0 = &i810VB[e0].v.v; - const i810_vertex *v1 = &i810VB[e1].v.v; - const i810_vertex *v2 = &i810VB[e2].v.v; + const i810_vertex *v0 = &i810VB[e0].v; + const i810_vertex *v1 = &i810VB[e1].v; + const i810_vertex *v2 = &i810VB[e2].v; #if (IND & I810_OFFSET_BIT) GLfloat offset = ctx->Polygon.OffsetUnits * 1.0/0x10000; #endif #if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT)) - int c0 = *(int *)&i810VB[pv].v.v.color; + int c0 = *(int *)&i810VB[pv].v.color; int c1 = c0; int c2 = c0; #endif @@ -64,78 +65,39 @@ static inline void TAG(triangle)( GLcontext *ctx, GLuint e0, i810glx.c_triangles++; -#if 0 -#define WID 512 -#define HI 384 - { - GLuint print = 0, draw = 1; - GLfloat area = ((v0->x - v2->x) * (v1->y - v2->y) - - (v0->y - v2->y) * (v1->x - v2->x)); - - if (v0->x < -.501 || v0->x > WID || v0->y < -.501 || v0->y > HI || - v1->x < -.501 || v1->x > WID || v1->y < -.501 || v1->y > HI || - v2->x < -.501 || v2->x > WID || v2->y < -.501 || v2->y > HI) { - fprintf(stderr, "not clipped\n"); - print = 1; - } - - if (area == 0 && ((v0 == v1) || (v1 == v2))) { - fprintf(stderr, "zero area %p %p %p\n", v0, v1, v2); - draw = 0; - } - - if (print) { - fprintf(stderr,"v0: %f %f %f %f col: %x tex: %f %f\n", - v0->x, v0->y, v0->z, v0->oow, - *(GLuint*)&v0->color, v0->tu0, v0->tv0); - fprintf(stderr,"v1: %f %f %f %f col: %x tex: %f %f\n", - v1->x, v1->y, v1->z, v1->oow, - *(GLuint*)&v1->color, v1->tu0, v1->tv0); - fprintf(stderr,"v2: %f %f %f %f col: %x tex: %f %f\n", - v2->x, v2->y, v2->z, v2->oow, - *(GLuint*)&v2->color, v2->tu0, v2->tv0); -/* return; */ - } - - if (!draw) return; - } -#endif - BEGIN_CLIP_LOOP() - { - i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( 3 * 10 ); - wv[0] = *v0; + { + i810_vertex *wv = i810AllocTriangles( imesa, 1 ); + wv[0] = *v0; #if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT)) - *((int *)(&wv[0].color)) = c0; + *((int *)(&wv[0].color)) = c0; #endif #if (IND & I810_OFFSET_BIT) - wv[0].z = v0->z + offset; + wv[0].z = v0->z + offset; #endif - wv[1] = *v1; + wv[1] = *v1; #if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT)) - *((int *)(&wv[1].color)) = c1; + *((int *)(&wv[1].color)) = c1; #endif #if (IND & I810_OFFSET_BIT) - wv[1].z = v1->z + offset; + wv[1].z = v1->z + offset; #endif - wv[2] = *v2; + wv[2] = *v2; #if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT)) - *((int *)(&wv[2].color)) = c2; + *((int *)(&wv[2].color)) = c2; #endif #if (IND & I810_OFFSET_BIT) - wv[2].z = v2->z + offset; + wv[2].z = v2->z + offset; #endif - FINISH_PRIM(); - } - END_CLIP_LOOP(); + FINISH_PRIM(); + } } - static void TAG(quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, GLuint pv ) @@ -144,60 +106,66 @@ static void TAG(quad)( GLcontext *ctx, GLuint v0, TAG(triangle)( ctx, v1, v2, v3, pv ); } - -#if ((IND & ~I810_FLAT_BIT) == 0) - static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) { + i810ContextPtr imesa = I810_CONTEXT( ctx ); i810VertexPtr i810VB = I810_DRIVER_DATA(ctx->VB)->verts; - i810_vertex tmp0 = i810VB[v0].v.v; - i810_vertex tmp1 = i810VB[v1].v.v; - float width = ctx->Line.Width; + int tmp0, tmp1; + (void) tmp0; (void) tmp1; + if (IND & I810_FLAT_BIT) { - *(int *)&tmp1.color = *(int *)&tmp0.color = - *(int *)&i810VB[pv].v.v.color; - } + tmp0 = *(int *)&i810VB[v0].v.color; + tmp1 = *(int *)&i810VB[v1].v.color; + i810VB[v0].v.color = i810VB[pv].v.color; + i810VB[v1].v.color = i810VB[pv].v.color; + } - BEGIN_CLIP_LOOP() - i810_draw_line( &tmp0, &tmp1, width ); - END_CLIP_LOOP(); + if (IND & I810_WIDE_LINE_BIT) + { + i810_draw_tri_line( imesa, &i810VB[v0].v, &i810VB[v1].v, + ctx->Line.Width ); + } + else + { + i810_draw_line_line( imesa, &i810VB[v0].v, &i810VB[v1].v ); + } + + if (IND & I810_FLAT_BIT) { + *(int *)&i810VB[v0].v.color = tmp0; + *(int *)&i810VB[v1].v.color = tmp1; + } } static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) { - int i; + i810ContextPtr imesa = I810_CONTEXT( ctx ); struct vertex_buffer *VB = ctx->VB; i810VertexPtr i810VB = I810_DRIVER_DATA(VB)->verts; GLfloat sz = ctx->Point.Size * .5; + int i; /* Culling is disabled automatically via. the * ctx->Driver.ReducedPrimitiveChange() callback. */ - + for(i=first;i<=last;i++) { if(VB->ClipMask[i]==0) { - i810_vertex *tmp = &i810VB[i].v.v; - BEGIN_CLIP_LOOP() - i810_draw_point( tmp, sz ); - END_CLIP_LOOP(); + i810_vertex *tmp = &i810VB[i].v; + i810_draw_point( imesa, tmp, sz ); } } } -#endif -static void TAG(init)() +static void TAG(init)( void ) { tri_tab[IND] = TAG(triangle); quad_tab[IND] = TAG(quad); - -#if ((IND & ~I810_FLAT_BIT) == 0) line_tab[IND] = TAG(line); points_tab[IND] = TAG(points); -#endif } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c index b41ad0960..6ba7eb9a5 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810vb.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c @@ -28,46 +28,43 @@ #include "i810vb.h" #include "i810log.h" #include "i810dma.h" -#include "xsmesaP.h" -#include "xsmesa.h" #include "stages.h" -#include "os.h" #include <stdio.h> #include <stdlib.h> #define TEX0 { \ - v->v.v.tu0 = tc0[i][0]; \ - v->v.v.tv0 = tc0[i][1]; \ + v->v.tu0 = tc0[i][0]; \ + v->v.tv0 = tc0[i][1]; \ } #define TEX1 { \ - v->v.v.tu1 = tc1[i][0]; \ - v->v.v.tv1 = tc1[i][1]; \ + v->v.tu1 = tc1[i][0]; \ + v->v.tv1 = tc1[i][1]; \ } /* Doesn't seem to work very well (golly). */ #define SPC { \ GLubyte *spec = &(VB->Spec[0][i][0]); \ - v->v.v.specular.red = spec[0]; \ - v->v.v.specular.green = spec[1]; \ - v->v.v.specular.blue = spec[2]; \ + v->v.specular.red = spec[0]; \ + v->v.specular.green = spec[1]; \ + v->v.specular.blue = spec[2]; \ } #define FOG { \ GLubyte *spec = &(VB->Spec[0][i][0]); \ - v->v.v.specular.alpha = spec[3]; \ + v->v.specular.alpha = spec[3]; \ } #define COL { \ GLubyte *col = &(VB->Color[0]->data[i][0]); \ - v->v.v.color.blue = col[2]; \ - v->v.v.color.green = col[1]; \ - v->v.v.color.red = col[0]; \ - v->v.v.color.alpha = col[3]; \ + v->v.color.blue = col[2]; \ + v->v.color.green = col[1]; \ + v->v.color.red = col[0]; \ + v->v.color.alpha = col[3]; \ } /* The vertex formats we have don't seem to support projective texturing @@ -82,19 +79,19 @@ imesa->setupdone &= ~I810_WIN_BIT; \ for (i=start; i < end; i++, v++) { \ float oow = 1.0 / tc[i][3]; \ - v->v.v.oow *= tc[i][3]; \ - v->v.v.tu0 *= oow; \ - v->v.v.tv0 *= oow; \ + v->v.oow *= tc[i][3]; \ + v->v.tu0 *= oow; \ + v->v.tv0 *= oow; \ } \ } #define COORD \ GLfloat *win = VB->Win.data[i]; \ - v->v.v.x = win[0]; \ - v->v.v.y = i810height - win[1]; \ - v->v.v.z = (1.0/0x10000) * win[2]; \ - v->v.v.oow = win[3]; + v->v.x = win[0]; \ + v->v.y = i810height - win[1]; \ + v->v.z = (1.0/0x10000) * win[2]; \ + v->v.oow = win[3]; @@ -104,15 +101,15 @@ #define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,spec,fog) \ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ { \ - i810ContextPtr imesa = I810_CONTEXT( ctx ); \ + i810ContextPtr imesa = I810_CONTEXT( VB->ctx ); \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ i810VertexPtr v; \ GLfloat (*tc0)[4]; \ GLfloat (*tc1)[4]; \ - GLfloat i810height = i810DB->Height; \ + GLfloat i810height = dPriv->h; \ int i; \ - (void) i810height; \ + (void) i810height; (void) imesa; \ \ - CHECK_CONTEXT( return; ); \ \ gl_import_client_data( VB, VB->ctx->RenderFlags, \ (VB->ClipOrMask \ @@ -143,7 +140,7 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ tex1; \ } \ col; \ - } \ + } \ tex0_4; \ } @@ -155,11 +152,13 @@ SETUPFUNC(rs_wt0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,NOP) SETUPFUNC(rs_wft0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,FOG) SETUPFUNC(rs_wft0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,FOG) SETUPFUNC(rs_wg, COORD,COL,NOP,NOP,NOP,NOP,NOP) +SETUPFUNC(rs_wgs, COORD,COL,NOP,NOP,NOP,SPC,NOP) SETUPFUNC(rs_wgt0, COORD,COL,TEX0,NOP,TEX0_4,NOP,NOP) SETUPFUNC(rs_wgt0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,NOP) SETUPFUNC(rs_wgst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,NOP) SETUPFUNC(rs_wgst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,NOP) SETUPFUNC(rs_wgf, COORD,COL,NOP,NOP,NOP,NOP,FOG) +SETUPFUNC(rs_wgfs, COORD,COL,NOP,NOP,NOP,SPC,FOG) SETUPFUNC(rs_wgft0, COORD,COL,TEX0,NOP,TEX0_4,NOP,FOG) SETUPFUNC(rs_wgft0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,FOG) SETUPFUNC(rs_wgfst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,FOG) @@ -171,11 +170,13 @@ SETUPFUNC(rs_f, NOP,NOP,NOP,NOP,NOP,NOP,FOG) SETUPFUNC(rs_ft0, NOP,NOP,TEX0,NOP,TEX0_4,NOP,FOG) SETUPFUNC(rs_ft0t1, NOP,NOP,TEX0,TEX1,TEX0_4,NOP,FOG) SETUPFUNC(rs_g, NOP,COL,NOP,NOP,NOP,NOP,NOP) +SETUPFUNC(rs_gs, NOP,COL,NOP,NOP,NOP,SPC,NOP) SETUPFUNC(rs_gt0, NOP,COL,TEX0,NOP,TEX0_4,NOP,NOP) SETUPFUNC(rs_gt0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,NOP) SETUPFUNC(rs_gst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,NOP) SETUPFUNC(rs_gst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,NOP) SETUPFUNC(rs_gf, NOP,COL,NOP,NOP,NOP,NOP,FOG) +SETUPFUNC(rs_gfs, NOP,COL,NOP,NOP,NOP,SPC,FOG) SETUPFUNC(rs_gft0, NOP,COL,TEX0,NOP,TEX0_4,NOP,FOG) SETUPFUNC(rs_gft0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,FOG) SETUPFUNC(rs_gfst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,FOG) @@ -206,11 +207,13 @@ void i810DDSetupInit( void ) setup_func[I810_WIN_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_wft0; setup_func[I810_WIN_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wft0t1; setup_func[I810_WIN_BIT|I810_RGBA_BIT] = rs_wg; + setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT] = rs_wgs; setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_TEX0_BIT] = rs_wgt0; setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgt0t1; setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_wgst0; setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgst0t1; setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT] = rs_wgf; + setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT] = rs_wgfs; setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_wgft0; setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgft0t1; setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_wgfst0; @@ -223,11 +226,13 @@ void i810DDSetupInit( void ) setup_func[I810_FOG_BIT|I810_TEX0_BIT] = rs_ft0; setup_func[I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_ft0t1; setup_func[I810_RGBA_BIT] = rs_g; + setup_func[I810_RGBA_BIT|I810_SPEC_BIT] = rs_gs; setup_func[I810_RGBA_BIT|I810_TEX0_BIT] = rs_gt0; setup_func[I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gt0t1; setup_func[I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_gst0; setup_func[I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gst0t1; setup_func[I810_RGBA_BIT|I810_FOG_BIT] = rs_gf; + setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT] = rs_gfs; setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_gft0; setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gft0t1; setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_gfst0; @@ -240,7 +245,7 @@ void i810PrintSetupFlags(char *msg, GLuint flags ) { fprintf(stderr, "%s: %d %s%s%s%s%s%s%s\n", msg, - flags, + (int)flags, (flags & I810_WIN_BIT) ? " xyzw," : "", (flags & I810_RGBA_BIT) ? " rgba," : "", (flags & I810_SPEC_BIT) ? " spec," : "", @@ -274,7 +279,7 @@ void i810ChooseRasterSetupFunc(GLcontext *ctx) if (ctx->FogMode == FOG_FRAGMENT) funcindex |= I810_FOG_BIT; - if (MESA_VERBOSE || I810_DEBUG) + if (MESA_VERBOSE) i810PrintSetupFlags("xsmesa: full setup function", funcindex); imesa->setupindex = funcindex; @@ -312,6 +317,7 @@ void i810DDCheckPartialRasterSetup( GLcontext *ctx, */ void i810DDPartialRasterSetup( struct vertex_buffer *VB ) { + i810ContextPtr imesa = I810_CONTEXT( VB->ctx ); GLuint new = VB->pipeline->new_outputs; GLuint available = VB->pipeline->outputs; GLuint ind = 0; @@ -337,7 +343,7 @@ void i810DDPartialRasterSetup( struct vertex_buffer *VB ) ind &= imesa->setupindex; imesa->setupdone |= ind; - i810PrintSetupFlags("xsmesa: partial setup function", ind); + if (0) i810PrintSetupFlags("xsmesa: partial setup function", ind); if (ind) setup_func[ind&~I810_ALPHA_BIT]( VB, VB->Start, VB->Count ); @@ -366,28 +372,37 @@ void i810DDResizeVB( struct vertex_buffer *VB, GLuint size ) free( mvb->vert_store ); mvb->vert_store = malloc( sizeof(i810Vertex) * mvb->size + 31); - if (!mvb->vert_store) - FatalError("i810-glx: out of memory !\n"); + if (!mvb->vert_store) { + fprintf(stderr, "i810-glx: out of memory !\n"); + exit(1); + } mvb->verts = (i810VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31); gl_vector1ui_free( &mvb->clipped_elements ); gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 ); - if (!mvb->clipped_elements.start) - FatalError("i810-glx: out of memory !\n"); + if (!mvb->clipped_elements.start) { + fprintf(stderr, "i810-glx: out of memory !\n"); + exit(1); + } free( VB->ClipMask ); VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size); - if (!VB->ClipMask) - FatalError("i810-glx: out of memory !\n"); + if (!VB->ClipMask) { + fprintf(stderr, "i810-glx: out of memory !\n"); + exit(1); + } + if (VB->Type == VB_IMMEDIATE) { free( mvb->primitive ); free( mvb->next_primitive ); mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); - if (!mvb->primitive || !mvb->next_primitive) - FatalError("i810-glx: out of memory!"); + if (!mvb->primitive || !mvb->next_primitive) { + fprintf(stderr, "i810-glx: out of memory !\n"); + exit(1); + } } } @@ -398,31 +413,35 @@ void i810DDRegisterVB( struct vertex_buffer *VB ) mvb = (i810VertexBufferPtr)calloc( 1, sizeof(*mvb) ); - /* This looks like it allocates a lot of memory, but it basically - * just sets an upper limit on how much can be used - nothing like - * this amount will ever be turned into 'real' memory. - */ - mvb->size = VB->Size * 5; + mvb->size = VB->Size * 2; mvb->vert_store = malloc( sizeof(i810Vertex) * mvb->size + 31); - if (!mvb->vert_store) - FatalError("i810-glx: out of memory !\n"); + if (!mvb->vert_store) { + fprintf(stderr, "i810-glx: out of memory !\n"); + exit(1); + } mvb->verts = (i810VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31); gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 ); - if (!mvb->clipped_elements.start) - FatalError("i810-glx: out of memory !\n"); - + if (!mvb->clipped_elements.start) { + fprintf(stderr, "i810-glx: out of memory !\n"); + exit(1); + } + free( VB->ClipMask ); VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size); - if (!VB->ClipMask) - FatalError("i810-glx: out of memory !\n"); + if (!VB->ClipMask) { + fprintf(stderr, "i810-glx: out of memory !\n"); + exit(1); + } mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size ); - if (!mvb->primitive || !mvb->next_primitive) - FatalError("i810-glx: out of memory!"); - + if (!mvb->primitive || !mvb->next_primitive) { + fprintf(stderr, "i810-glx: out of memory !\n"); + exit(1); + } + VB->driver_data = mvb; } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.h b/xc/lib/GL/mesa/src/drv/i810/i810vb.h index 640afa678..23685f106 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810vb.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.h @@ -26,7 +26,8 @@ #ifndef I810VB_INC #define I810VB_INC -#include "mesaglx/vb.h" +#include "vb.h" +#include "types.h" /* * color type for the vertex data @@ -56,15 +57,13 @@ typedef struct { /* Unfortunately only have assembly for 16-stride vertices. */ -struct i810_vertex_t { - union { - i810_vertex v; - float f[16]; - } v; +union i810_vertex_t { + i810_vertex v; + float f[16]; }; -typedef struct i810_vertex_t i810Vertex; -typedef struct i810_vertex_t *i810VertexPtr; +typedef union i810_vertex_t i810Vertex; +typedef union i810_vertex_t *i810VertexPtr; struct i810_vertex_buffer_t { GLvector1ui clipped_elements; @@ -79,7 +78,7 @@ struct i810_vertex_buffer_t { typedef struct i810_vertex_buffer_t *i810VertexBufferPtr; -#define I810_CONTEXT(ctx) ((i810ContextPtr)(((XSMesaContext)(ctx)->DriverCtx)->hw_ctx)) +#define I810_CONTEXT(ctx) ((i810ContextPtr)(ctx->DriverCtx)) #define I810_DRIVER_DATA(vb) ((i810VertexBufferPtr)((vb)->driver_data)) @@ -97,7 +96,7 @@ extern void i810PrintSetupFlags(char *msg, GLuint flags ); extern void i810DDDoRasterSetup( struct vertex_buffer *VB ); extern void i810DDPartialRasterSetup( struct vertex_buffer *VB ); extern void i810DDCheckPartialRasterSetup( GLcontext *ctx, - struct gl_pipeline_stage *d ); + struct gl_pipeline_stage *d ); extern void i810DDViewport( GLcontext *ctx, GLint x, GLint y, diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile index e4e39b747..1ca3bde8a 100644 --- a/xc/lib/GL/mesa/src/drv/mga/Imakefile +++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile @@ -1,4 +1,6 @@ +#include <Threads.tmpl> + #define DoNormalLib NormalLibGlx #define DoSharedLib SharedLibGlx #define DoExtraLib SharedLibGlx @@ -12,6 +14,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #if BuildXF86DRI DRI_DEFINES = GlxDefines -DDRIVERTS DRI_INCLUDES = -I../../../../dri -I../../../../glx \ + -I../../../dri \ -I$(TOP)/include -I$(TOP)/include/GL \ -I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \ -I$(XF86DRIVERSRC)/mga \ @@ -24,23 +27,244 @@ MESA_INCLUDES = -I. -I.. -I../../include DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) - INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \ - -I/usr/include/glide - DRISRCS = mgaclear.c mgacnvtex.c mgadd.c mgadepth.c \ + INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) + +#if 0 + LOSRC = ../../../../lowpc.c + LOOBJ = ../../../../lowpc.o + + HISRC = ../../../../highpc.c + HIOBJ = ../../../../highpc.o +#endif + + DRISRCS = ../../../dri/dri_mesa.c \ + ../../../../dri/dri_tmm.c + + DRIOBJS = ../../../dri/dri_mesa.o \ + ../../../../dri/dri_tmm.o + + DRMSRCS = ../../../../dri/drm/xf86drm.c \ + ../../../../dri/drm/xf86drmHash.c \ + ../../../../dri/drm/xf86drmRandom.c \ + ../../../../dri/drm/xf86drmSL.c + + DRMOBJS = ../../../../dri/drm/xf86drm.o \ + ../../../../dri/drm/xf86drmHash.o \ + ../../../../dri/drm/xf86drmRandom.o \ + ../../../../dri/drm/xf86drmSL.o + + + MGASRCS = mgaclear.c mgacnvtex.c mgadd.c \ mgafastpath.c \ mgapipeline.c \ mgaspan.c mgastate.c mgatex.c \ - mgatris.c mgavb.c mgaioctl.c mga_xmesa.c + mgatris.c mgavb.c mgaioctl.c mga_xmesa.c mgabuffers.c - DRIOBJS = mgaclear.o mgacnvtex.o mgadd.o mgadepth.o \ + MGAOBJS = mgaclear.o mgacnvtex.o mgadd.o \ mgafastpath.o \ mgapipeline.o \ mgaspan.o mgastate.o mgatex.o \ - mgatris.o mgavb.o mgaioctl.o mga_xmesa.o + mgatris.o mgavb.o mgaioctl.o mga_xmesa.o mgabuffers.o + + MESASRCS = ../../accum.c \ + ../../alpha.c \ + ../../alphabuf.c \ + ../../attrib.c \ + ../../bbox.c \ + ../../bitmap.c \ + ../../blend.c \ + ../../buffers.c \ + ../../clip.c \ + ../../colortab.c \ + ../../config.c \ + ../../context.c \ + ../../copypix.c \ + ../../cva.c \ + ../../debug_xform.c \ + ../../depth.c \ + ../../dlist.c \ + ../../drawpix.c \ + ../../enable.c \ + ../../enums.c \ + ../../eval.c \ + ../../extensions.c \ + ../../feedback.c \ + ../../fog.c \ + ../../get.c \ + ../../glapi.c \ + ../../glapinoop.c \ + ../../glthread.c \ + ../../hash.c \ + ../../image.c \ + ../../imaging.o \ + ../../light.c \ + ../../lines.c \ + ../../logic.c \ + ../../masking.c \ + ../../matrix.c \ + ../../mem.c \ + ../../mmath.c \ + ../../pb.c \ + ../../pipeline.c \ + ../../pixel.c \ + ../../points.c \ + ../../polygon.c \ + ../../quads.c \ + ../../rastpos.c \ + ../../readpix.c \ + ../../rect.c \ + ../../scissor.c \ + ../../shade.c \ + ../../span.c \ + ../../stages.c \ + ../../state.c \ + ../../stencil.c \ + ../../teximage.c \ + ../../texobj.c \ + ../../texstate.c \ + ../../texture.c \ + ../../translate.c \ + ../../triangle.c \ + ../../varray.c \ + ../../vb.c \ + ../../vbcull.c \ + ../../vbfill.c \ + ../../vbindirect.c \ + ../../vbrender.c \ + ../../vbxform.c \ + ../../vector.c \ + ../../vertices.c \ + ../../winpos.c \ + ../../xform.c \ + ../../zoom.c \ + ../../X86/common_x86.c + + MESAOBJS = ../../accum.o \ + ../../alpha.o \ + ../../alphabuf.o \ + ../../attrib.o \ + ../../bbox.o \ + ../../bitmap.o \ + ../../blend.o \ + ../../buffers.o \ + ../../clip.o \ + ../../colortab.o \ + ../../config.o \ + ../../context.o \ + ../../copypix.o \ + ../../cva.o \ + ../../debug_xform.o \ + ../../depth.o \ + ../../dlist.o \ + ../../drawpix.o \ + ../../enable.o \ + ../../enums.o \ + ../../eval.o \ + ../../extensions.o \ + ../../feedback.o \ + ../../fog.o \ + ../../get.o \ + ../../hash.o \ + ../../hint.o \ + ../../image.o \ + ../../imaging.o \ + ../../light.o \ + ../../lines.o \ + ../../logic.o \ + ../../masking.o \ + ../../matrix.o \ + ../../mem.o \ + ../../mmath.o \ + ../../pb.o \ + ../../pipeline.o \ + ../../pixel.o \ + ../../points.o \ + ../../polygon.o \ + ../../quads.o \ + ../../rastpos.o \ + ../../readpix.o \ + ../../rect.o \ + ../../scissor.o \ + ../../shade.o \ + ../../span.o \ + ../../stages.o \ + ../../state.o \ + ../../stencil.o \ + ../../teximage.o \ + ../../texobj.o \ + ../../texstate.o \ + ../../texture.o \ + ../../translate.o \ + ../../triangle.o \ + ../../varray.o \ + ../../vb.o \ + ../../vbcull.o \ + ../../vbfill.o \ + ../../vbindirect.o \ + ../../vbrender.o \ + ../../vbxform.o \ + ../../vector.o \ + ../../vertices.o \ + ../../winpos.o \ + ../../xform.o \ + ../../zoom.o + +#ifdef i386Architecture + X86_SRCS = ../../X86/x86.c \ + ../../X86/x86a.S \ + ../../X86/common_x86.c \ + ../../X86/common_x86asm.S \ + ../../X86/vertex.S + + X86_OBJS = ../../X86/x86.o \ + ../../X86/x86a.o \ + ../../X86/common_x86.o \ + ../../X86/common_x86asm.o \ + ../../X86/vertex.o + + MMX_SRCS = ../../X86/mmx_blend.S + + MMX_OBJS = ../../X86/mmx_blend.o + +XCOMM Disabling 3Dnow code for the time being. +#if 0 + 3DNOW_SRCS = ../../X86/3dnow.c \ + ../../X86/3dnow_norm_raw.S \ + ../../X86/3dnow_xform_masked1.S \ + ../../X86/3dnow_xform_masked2.S \ + ../../X86/3dnow_xform_masked3.S \ + ../../X86/3dnow_xform_masked4.S \ + ../../X86/3dnow_xform_raw1.S \ + ../../X86/3dnow_xform_raw2.S \ + ../../X86/3dnow_xform_raw3.S \ + ../../X86/3dnow_xform_raw4.S \ + ../../X86/vertex_3dnow.S + + 3DNOW_OBJS = ../../X86/3dnow.o \ + ../../X86/3dnow_norm_raw.o \ + ../../X86/3dnow_xform_masked1.o \ + ../../X86/3dnow_xform_masked2.o \ + ../../X86/3dnow_xform_masked3.o \ + ../../X86/3dnow_xform_masked4.o \ + ../../X86/3dnow_xform_raw1.o \ + ../../X86/3dnow_xform_raw2.o \ + ../../X86/3dnow_xform_raw3.o \ + ../../X86/3dnow_xform_raw4.o \ + ../../X86/vertex_3dnow.o +#endif + +#endif + + ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) + ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) + + COMMONSRCS = ../common/mm.c ../common/hwlog.c + COMMONOBJS = ../common/mm.o ../common/hwlog.o + SRCS = $(LOWSRC) $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) $(COMMONSRCS) $(MGASRCS) $(HISRC) + OBJS = $(LOWOBJ) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) $(COMMONOBJS) $(MGAOBJS) $(HIOBJ) - SRCS = $(DRISRCS) - OBJS = $(DRIOBJS) +REQUIREDLIBS += -lm #if !GlxUseBuiltInDRIDriver #undef DoNormalLib NormalLibGlx @@ -61,7 +285,7 @@ LIBNAME = mga_dri.so ALL_OBJS = $(OBJS) ALL_DEPS = DONE SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) -InstallDynamicModule($(LIBNAME),$(MODULEDIR),.) +InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.) #endif DependTarget() diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c index 496c29a05..996dc3819 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c @@ -27,7 +27,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> * */ @@ -36,6 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <X11/Xlibint.h> #include <stdio.h> +#include "drm.h" #include "mga_xmesa.h" #include "context.h" #include "vbxform.h" @@ -49,20 +50,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mgadepth.h" #include "mgatris.h" #include "mgapipeline.h" +#include "mgabuffers.h" #include "xf86dri.h" -#include "mga_dri.h" -#include "mga_drm_public.h" #include "mga_xmesa.h" +#include "mga_dri.h" + #ifndef MGA_DEBUG int MGA_DEBUG = (0 -/* | MGA_DEBUG_ALWAYS_SYNC */ -/* | MGA_DEBUG_VERBOSE_MSG */ +/* | DEBUG_ALWAYS_SYNC */ +/* | DEBUG_VERBOSE_MSG */ +/* | DEBUG_VERBOSE_LRU */ +/* | DEBUG_VERBOSE_DRI */ +/* | DEBUG_VERBOSE_IOCTL */ +/* | DEBUG_VERBOSE_2D */ ); #endif @@ -107,7 +113,10 @@ static int count_bits(unsigned int n) GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { mgaScreenPrivate *mgaScreen; - MGADRIPtr gDRIPriv = (MGADRIPtr)sPriv->pDevPriv; + MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv; + + + fprintf(stderr, "XMesaInitDriver\n"); /* Allocate the private area */ mgaScreen = (mgaScreenPrivate *)Xmalloc(sizeof(mgaScreenPrivate)); @@ -116,20 +125,68 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) mgaScreen->sPriv = sPriv; sPriv->private = (void *)mgaScreen; - mgaScreen->chipset=gDRIPriv->chipset; - mgaScreen->width=gDRIPriv->width; - mgaScreen->height=gDRIPriv->height; - mgaScreen->mem=gDRIPriv->mem; - mgaScreen->cpp=gDRIPriv->cpp; - mgaScreen->frontPitch=gDRIPriv->frontPitch; - mgaScreen->frontOffset=gDRIPriv->frontOffset; - mgaScreen->backOffset=gDRIPriv->backOffset; - mgaScreen->backPitch = gDRIPriv->backPitch; - mgaScreen->depthOffset=gDRIPriv->depthOffset; - mgaScreen->depthPitch = gDRIPriv->depthPitch; - mgaScreen->textureOffset=gDRIPriv->textureOffset; - mgaScreen->textureSize=gDRIPriv->textureSize; - mgaScreen->logTextureGranularity = gDRIPriv->logTextureGranularity; + fprintf(stderr, "serverInfo->chipset: %d\n", serverInfo->chipset); + + if (serverInfo->chipset != MGA_CARD_TYPE_G200 && + serverInfo->chipset != MGA_CARD_TYPE_G400) + return GL_FALSE; + + mgaScreen->chipset = serverInfo->chipset; + mgaScreen->width = serverInfo->width; + mgaScreen->height = serverInfo->height; + mgaScreen->mem = serverInfo->mem; + mgaScreen->cpp = serverInfo->cpp; + mgaScreen->frontPitch = serverInfo->frontPitch; + mgaScreen->frontOffset = serverInfo->frontOffset; + mgaScreen->backOffset = serverInfo->backOffset; + mgaScreen->backPitch = serverInfo->backPitch; + mgaScreen->depthOffset = serverInfo->depthOffset; + mgaScreen->depthPitch = serverInfo->depthPitch; + + + mgaScreen->agp_tex.handle = serverInfo->agp; + mgaScreen->agp_tex.size = serverInfo->agpSize; + + if (drmMap(sPriv->fd, + mgaScreen->agp_tex.handle, + mgaScreen->agp_tex.size, + (drmAddress *)&mgaScreen->agp_tex.map) != 0) + { + Xfree(mgaScreen); + return GL_FALSE; + } + + + + mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset; + mgaScreen->textureOffset[MGA_AGP_HEAP] = (mgaScreen->agp_tex.handle | + PDEA_pagpxfer_enable | 1); + + fprintf(stderr, "CARD texture size %x, granul %d --> %x\n", + serverInfo->textureSize, serverInfo->logTextureGranularity, + 1<<serverInfo->logTextureGranularity); + + mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize; + mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize; + + mgaScreen->logTextureGranularity[MGA_CARD_HEAP] = + serverInfo->logTextureGranularity; + mgaScreen->logTextureGranularity[MGA_AGP_HEAP] = + serverInfo->logAgpTextureGranularity; + + mgaScreen->texVirtual[MGA_CARD_HEAP] = (mgaScreen->sPriv->pFB + + mgaScreen->textureOffset[0]); + mgaScreen->texVirtual[MGA_AGP_HEAP] = mgaScreen->agp_tex.map; + + mgaScreen->mAccess = serverInfo->mAccess; + + + fprintf(stderr, "\n\n\nbackOffset: %x pitch %x\n", + mgaScreen->backOffset, + mgaScreen->backPitch); + + + mgaScreen->Attrib = MGA_PF_565; mgaScreen->bufs = drmMapBufs(sPriv->fd); @@ -169,6 +226,8 @@ XMesaVisual XMesaCreateVisual(XMesaDisplay *display, { XMesaVisual v; + fprintf(stderr, "XMesaCreateVisual\n"); + /* Only RGB visuals are supported on the MGA boards */ if (!rgb_flag) return 0; @@ -183,28 +242,19 @@ XMesaVisual XMesaCreateVisual(XMesaDisplay *display, memcpy(v->visinfo, visinfo, sizeof(*visinfo)); v->display = display; - v->level = level; - - v->gl_visual = (GLvisual *)Xmalloc(sizeof(GLvisual)); + v->level = level; + v->gl_visual = gl_create_visual(rgb_flag, GL_FALSE, db_flag, stereo_flag, + depth_size, stencil_size, accum_size, 0, + count_bits(visinfo->red_mask), + count_bits(visinfo->green_mask), + count_bits(visinfo->blue_mask), + GL_FALSE); if (!v->gl_visual) { Xfree(v->visinfo); - XFree(v); - return 0; + Xfree(v); + return NULL; } - v->gl_visual->RGBAflag = rgb_flag; - v->gl_visual->DBflag = db_flag; - v->gl_visual->StereoFlag = stereo_flag; - - v->gl_visual->RedBits = count_bits(visinfo->red_mask); - v->gl_visual->GreenBits = count_bits(visinfo->green_mask); - v->gl_visual->BlueBits = count_bits(visinfo->blue_mask); - v->gl_visual->AlphaBits = 0; /* Not currently supported */ - - v->gl_visual->AccumBits = accum_size; - v->gl_visual->DepthBits = depth_size; - v->gl_visual->StencilBits = stencil_size; - return v; } @@ -218,6 +268,7 @@ void XMesaDestroyVisual(XMesaVisual v) XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, __DRIcontextPrivate *driContextPriv) { + int i; GLcontext *ctx; XMesaContext c; mgaContextPtr mmesa; @@ -227,12 +278,15 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, sizeof(XF86DRISAREARec)); GLcontext *shareCtx = 0; + fprintf(stderr, "XMesaCreateContext\n"); + + c = (XMesaContext)Xmalloc(sizeof(struct xmesa_context)); if (!c) { return 0; } - mmesa = (mgaContextPtr)Xmalloc(sizeof(mgaContext)); + mmesa = (mgaContextPtr)Xcalloc(sizeof(mgaContext), 1); if (!mmesa) { Xfree(c); return 0; @@ -250,8 +304,6 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, ctx = mmesa->glCtx = gl_create_context(v->gl_visual, shareCtx, (void*)mmesa, GL_TRUE); - /* Dri stuff - */ mmesa->display = v->display; mmesa->hHWContext = driContextPriv->hHWContext; mmesa->driFd = sPriv->fd; @@ -261,40 +313,45 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, mmesa->driScreen = sPriv; mmesa->sarea = saPriv; - mmesa->glBuffer=gl_create_framebuffer(v->gl_visual); + mmesa->glBuffer=gl_create_framebuffer(v->gl_visual, + GL_FALSE, /* software depth buffer? */ + v->gl_visual->StencilBits > 0, + v->gl_visual->AccumBits > 0, + v->gl_visual->AlphaBits > 0); + + make_empty_list(&mmesa->SwappedOut); - mmesa->needClip=1; + mmesa->lastTexHeap = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1; - mmesa->texHeap = mmInit( 0, mgaScreen->textureSize ); + for (i = 0 ; i < mmesa->lastTexHeap ; i++) { + mmesa->texHeap[i] = mmInit( 0, mgaScreen->textureSize[i]); + make_empty_list(&mmesa->TexObjList[i]); + } - /* Utah stuff - */ mmesa->renderindex = -1; /* impossible value */ mmesa->new_state = ~0; mmesa->dirty = ~0; - - mmesa->warp_pipe = 0; - - - make_empty_list(&mmesa->SwappedOut); - make_empty_list(&mmesa->TexObjList); - + mmesa->warp_pipe = 0; mmesa->CurrentTexObj[0] = 0; mmesa->CurrentTexObj[1] = 0; + mmesa->texAge[0] = 0; + mmesa->texAge[1] = 0; + + mgaDDExtensionsInit( ctx ); mgaDDInitStateFuncs( ctx ); mgaDDInitTextureFuncs( ctx ); mgaDDInitSpanFuncs( ctx ); - mgaDDInitDepthFuncs( ctx ); mgaDDInitDriverFuncs( ctx ); mgaDDInitIoctlFuncs( ctx ); ctx->Driver.TriangleCaps = (DD_TRI_CULL| DD_TRI_LIGHT_TWOSIDE| + DD_TRI_STIPPLE| DD_TRI_OFFSET); /* Ask mesa to clip fog coordinates for us. @@ -312,6 +369,9 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, mgaDDRegisterPipelineStages(ctx->PipelineStage, ctx->PipelineStage, ctx->NrPipelineStages); + + mgaInitState( mmesa ); + return c; } @@ -364,59 +424,12 @@ void XMesaSwapBuffers(XMesaBuffer bogus_value_do_not_use) - -void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ) +GLboolean XMesaUnbindContext(XMesaContext c) { - __DRIdrawablePrivate *dPriv = mmesa->driDrawable; - - mmesa->numClipRects = dPriv->numClipRects; - mmesa->pClipRects = dPriv->pClipRects; - mmesa->drawX = dPriv->x; - mmesa->drawY = dPriv->y; - - mmesa->drawOffset = mmesa->mgaScreen->frontOffset; -} - - -void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) -{ - __DRIdrawablePrivate *dPriv = mmesa->driDrawable; - - if (dPriv->numAuxClipRects == 0) - { - mmesa->numClipRects = dPriv->numClipRects; - mmesa->pClipRects = dPriv->pClipRects; - mmesa->drawX = dPriv->x; - mmesa->drawY = dPriv->y; - } else { - mmesa->numClipRects = dPriv->numAuxClipRects; - mmesa->pClipRects = dPriv->pAuxClipRects; - mmesa->drawX = dPriv->auxX; - mmesa->drawY = dPriv->auxY; - } - - mmesa->drawOffset = mmesa->mgaScreen->backOffset; -} - - -static void mgaXMesaWindowMoved( mgaContextPtr mmesa ) -{ - /* Clear any contaminated CVA data. - */ - mmesa->setupdone = 0; - - switch (mmesa->glCtx->Color.DriverDrawBuffer) { - case GL_FRONT_LEFT: - mgaXMesaSetFrontClipRects( mmesa ); - break; - case GL_BACK_LEFT: - mgaXMesaSetBackClipRects( mmesa ); - break; - default: - fprintf(stderr, "fallback buffer\n"); - break; - } + if (c->private) + ((mgaContextPtr)c->private)->dirty = ~0; + return GL_TRUE; } @@ -439,9 +452,9 @@ GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b) gl_make_current(mgaCtx->glCtx, mgaCtx->glBuffer); - mgaXMesaWindowMoved( mgaCtx ); mgaCtx->driDrawable = dPriv; mgaCtx->dirty = ~0; + mgaCtx->dirty_cliprects = (MGA_FRONT|MGA_BACK); if (!mgaCtx->glCtx->Viewport.Width) gl_Viewport(mgaCtx->glCtx, 0, 0, dPriv->w, dPriv->h); @@ -455,54 +468,36 @@ GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b) } -void mgaXMesaUpdateState( mgaContextPtr mmesa ) +void mgaGetLock( mgaContextPtr mmesa, GLuint flags ) { __DRIdrawablePrivate *dPriv = mmesa->driDrawable; - __DRIscreenPrivate *sPriv = mmesa->driScreen; drm_mga_sarea_t *sarea = mmesa->sarea; - int me = mmesa->hHWContext; - int stamp = dPriv->lastStamp; + int i; - /* If the window moved, may need to set a new cliprect now. - * - * NOTE: This releases and regains the hw lock, so all state - * checking must be done *after* this call: - */ - XMESA_VALIDATE_DRAWABLE_INFO(mmesa->display, sPriv, dPriv); + drmGetLock(mmesa->driFd, mmesa->hHWContext, flags); - if (sarea->ctxOwner != me) { - mmesa->dirty |= MGA_UPLOAD_CTX; + if (*(dPriv->pStamp) != dPriv->lastStamp) { + mmesa->setupdone = 0; + mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); + mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) ); } - if (sarea->texAge != mmesa->texAge) { - int sz = 1 << (mmesa->mgaScreen->logTextureGranularity); - int idx, nr = 0; - - /* Have to go right round from the back to ensure stuff ends up - * LRU in our local list... - */ - for (idx = sarea->texList[MGA_NR_TEX_REGIONS].prev ; - idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ; - idx = sarea->texList[idx].prev, nr++) - { - if (sarea->texList[idx].age > mmesa->texAge) - mgaTexturesGone(mmesa, idx * sz, sz, 1); - } - - if (nr == MGA_NR_TEX_REGIONS) { - mgaTexturesGone(mmesa, 0, mmesa->mgaScreen->textureSize, 0); - mgaResetGlobalLRU( mmesa ); - } - - mmesa->texAge = sarea->texAge; - mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE; + mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_CLIPRECTS; + + mmesa->sarea->dirty |= MGA_UPLOAD_CTX; + + if (sarea->ctxOwner != me) { + mmesa->dirty |= (MGA_UPLOAD_CTX | MGA_UPLOAD_TEX0 | + MGA_UPLOAD_TEX1 | MGA_UPLOAD_PIPE); + sarea->ctxOwner=me; } - if (dPriv->lastStamp != stamp) - mgaXMesaWindowMoved( mmesa ); + for (i = 0 ; i < mmesa->lastTexHeap ; i++) + if (sarea->texAge[i] != mmesa->texAge[i]) + mgaAgeTextures( mmesa, i ); - sarea->ctxOwner=me; + sarea->last_quiescent = -1; /* just kill it for now */ } 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 d563bd429..1379f48d9 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h @@ -28,7 +28,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Keith Whitwell <keithw@precisioninsight.com> - * Daryll Strauss <daryll@precisioninsight.com> (Origninal tdfx driver). * */ @@ -43,6 +42,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri_mesa.h" #include "types.h" #include "xmesaP.h" +#include "mgaregs.h" + +typedef struct { + drmHandle handle; + drmSize size; + char *map; +} mgaRegion, *mgaRegionPtr; typedef struct { @@ -54,6 +60,7 @@ typedef struct { int cpp; /* for front and back buffers */ int Attrib; + int mAccess; int frontOffset; int frontPitch; @@ -64,43 +71,54 @@ typedef struct { int depthPitch; int depthCpp; - int textureOffset; - int textureSize; - int logTextureGranularity; + int textureOffset[MGA_NR_TEX_HEAPS]; + int textureSize[MGA_NR_TEX_HEAPS]; + int logTextureGranularity[MGA_NR_TEX_HEAPS]; + char *texVirtual[MGA_NR_TEX_HEAPS]; + __DRIscreenPrivate *sPriv; drmBufMapPtr bufs; + mgaRegion agp_tex; + } mgaScreenPrivate; #include "mgalib.h" -extern void mgaXMesaUpdateState( mgaContextPtr mmesa ); +extern void mgaGetLock( mgaContextPtr mmesa, GLuint flags ); extern void mgaEmitHwStateLocked( mgaContextPtr mmesa ); extern void mgaEmitScissorValues( mgaContextPtr mmesa, int box_nr, int emit ); -extern void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ); -extern void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ); + +#define GET_DISPATCH_AGE( mmesa ) mmesa->sarea->last_dispatch +#define GET_ENQUEUE_AGE( mmesa ) mmesa->sarea->last_enqueue /* Lock the hardware and validate our state. */ -#define LOCK_HARDWARE( mmesa ) \ - do { \ - char __ret=0; \ - DRM_CAS(mmesa->driHwLock, mmesa->hHWContext, \ - (DRM_LOCK_HELD|mmesa->hHWContext), __ret); \ - if (__ret) { \ - drmGetLock(mmesa->driFd, mmesa->hHWContext, 0); \ - mgaXMesaUpdateState( mmesa ); \ - } \ +#define LOCK_HARDWARE( mmesa ) \ + do { \ + char __ret=0; \ + DRM_CAS(mmesa->driHwLock, mmesa->hHWContext, \ + (DRM_LOCK_HELD|mmesa->hHWContext), __ret); \ + if (__ret) \ + mgaGetLock( mmesa, 0 ); \ } while (0) +/* + */ +#define LOCK_HARDWARE_QUIESCENT( mmesa ) do { \ + LOCK_HARDWARE( mmesa ); \ + mgaUpdateLock( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH ); \ +} while (0) + + /* Unlock the hardware using the global current context */ -#define UNLOCK_HARDWARE(mmesa) \ +#define UNLOCK_HARDWARE(mmesa) \ DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext); @@ -109,6 +127,8 @@ extern void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ); #define REFRESH_DRAWABLE_INFO( mmesa ) \ do { \ LOCK_HARDWARE( mmesa ); \ + mmesa->lastX = mmesa->drawX; \ + mmesa->lastY = mmesa->drawY; \ UNLOCK_HARDWARE( mmesa ); \ } while (0) diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c new file mode 100644 index 000000000..276c5df85 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c @@ -0,0 +1,315 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@precisioninsight.com> + * + * $PI: $ + */ + +#include <stdio.h> +#include "mgalib.h" +#include "mgabuffers.h" +#include "mgastate.h" + +static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ) +{ + __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + + mmesa->numClipRects = driDrawable->numClipRects; + mmesa->pClipRects = driDrawable->pClipRects; + mmesa->drawX = driDrawable->x; + mmesa->drawY = driDrawable->y; + + mmesa->drawOffset = mmesa->mgaScreen->frontOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->drawOffset; + mmesa->dirty |= MGA_UPLOAD_CTX; + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; +} + + +static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) +{ + __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + + if (driDrawable->numBackClipRects == 0) + { + mmesa->numClipRects = driDrawable->numClipRects; + mmesa->pClipRects = driDrawable->pClipRects; + mmesa->drawX = driDrawable->x; + mmesa->drawY = driDrawable->y; + } else { + mmesa->numClipRects = driDrawable->numBackClipRects; + mmesa->pClipRects = driDrawable->pBackClipRects; + mmesa->drawX = driDrawable->backX; + mmesa->drawY = driDrawable->backY; + } + + mmesa->drawOffset = mmesa->mgaScreen->backOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->drawOffset; + + mmesa->dirty |= MGA_UPLOAD_CTX; + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; +} + + + +static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa ) +{ + __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + __DRIscreenPrivate *driScreen = mmesa->driScreen; + drm_mga_sarea_t *sarea = mmesa->sarea; + int i = 0, top = 0; + + + if (sarea->exported_buffers & MGA_BACK) { + XF86DRIClipRectPtr boxes = + (XF86DRIClipRectPtr)malloc( sarea->exported_nback * sizeof(*boxes) ); + + if (driDrawable->pBackClipRects) + free(driDrawable->pBackClipRects); + + driDrawable->numBackClipRects = sarea->exported_nback; + driDrawable->pBackClipRects = boxes; + + top = sarea->exported_nback; + for (i = 0 ; i < top ; i++) + boxes[i] = *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); + } + + + if (sarea->exported_buffers & MGA_FRONT) + { + int start = top; + XF86DRIClipRectPtr boxes = + (XF86DRIClipRectPtr)malloc( sarea->exported_nfront * sizeof(*boxes) ); + + if (driDrawable->pClipRects) + free(driDrawable->pClipRects); + + driDrawable->numClipRects = sarea->exported_nfront; + driDrawable->pClipRects = boxes; + + top += sarea->exported_nfront; + for ( ; i < top ; i++) + boxes[i-start] = *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); + + } + + + + driDrawable->index = sarea->exported_index; + driDrawable->lastStamp = sarea->exported_stamp; + driDrawable->x = sarea->exported_front_x; + driDrawable->y = sarea->exported_front_y; + driDrawable->backX = sarea->exported_back_x; + driDrawable->backY = sarea->exported_back_y; + driDrawable->w = sarea->exported_w; + driDrawable->h = sarea->exported_h; + driDrawable->pStamp = + &(driScreen->pSAREA->drawableTable[driDrawable->index].stamp); + + mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK) & ~(sarea->exported_buffers); +} + + + +static void printSareaRects( mgaContextPtr mmesa ) +{ + __DRIscreenPrivate *driScreen = mmesa->driScreen; + drm_mga_sarea_t *sarea = mmesa->sarea; + int i; + + fprintf(stderr, "sarea->exported: %d\n", sarea->exported_drawable); + fprintf(stderr, "sarea->exported_index: %d\n", sarea->exported_index); + fprintf(stderr, "sarea->exported_stamp: %d\n", sarea->exported_stamp); + fprintf(stderr, "sarea->exported_front_x: %d\n", sarea->exported_front_x); + fprintf(stderr, "sarea->exported_front_y: %d\n", sarea->exported_front_y); + fprintf(stderr, "sarea->exported_back_x: %d\n", sarea->exported_back_x); + fprintf(stderr, "sarea->exported_back_y: %d\n", sarea->exported_back_y); + fprintf(stderr, "sarea->exported_w: %d\n", sarea->exported_w); + fprintf(stderr, "sarea->exported_h: %d\n", sarea->exported_h); + fprintf(stderr, "sarea->exported_buffers: %d\n", sarea->exported_buffers); + fprintf(stderr, "sarea->exported_nfront: %d\n", sarea->exported_nfront); + fprintf(stderr, "sarea->exported_nback: %d\n", sarea->exported_nback); + + i = 0; + if (sarea->exported_buffers & MGA_BACK) + for ( ; i < sarea->exported_nback ; i++) + fprintf(stderr, "back %d: %d,%d-%d,%d\n", i, + sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1, + sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2); + + if (sarea->exported_buffers & MGA_FRONT) { + int start = i; + int top = i + sarea->exported_nfront; + for ( ; i < top ; i++) + fprintf(stderr, "front %d: %d,%d-%d,%d\n", + i - start, + sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1, + sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2); + } + + fprintf(stderr, "drawableTable[%d].stamp: %d\n", + sarea->exported_index, + driScreen->pSAREA->drawableTable[sarea->exported_index].stamp); +} + +static void printMmesaRects( mgaContextPtr mmesa ) +{ + __DRIscreenPrivate *driScreen = mmesa->driScreen; + __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + int nr = mmesa->numClipRects; + int i; + + fprintf(stderr, "driDrawable->draw: %ld\n", driDrawable->draw); + fprintf(stderr, "driDrawable->index: %d\n", driDrawable->index); + fprintf(stderr, "driDrawable->lastStamp: %d\n", driDrawable->lastStamp); + fprintf(stderr, "mmesa->drawX: %d\n", mmesa->drawX); + fprintf(stderr, "mmesa->drawY: %d\n", mmesa->drawY); + fprintf(stderr, "driDrawable->w: %d\n", driDrawable->w); + fprintf(stderr, "driDrawable->h: %d\n", driDrawable->h); + + for (i = 0 ; i < nr ; i++) + fprintf(stderr, "box %d: %d,%d-%d,%d\n", i, + mmesa->pClipRects[i].x1, mmesa->pClipRects[i].y1, + mmesa->pClipRects[i].x2, mmesa->pClipRects[i].y2); + + fprintf(stderr, "mmesa->draw_buffer: %d\n", mmesa->draw_buffer); + fprintf(stderr, "drawableTable[%d].stamp: %d\n", + driDrawable->index, + driScreen->pSAREA->drawableTable[driDrawable->index].stamp); +} + + + +void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) +{ + __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + drm_mga_sarea_t *sarea = mmesa->sarea; + + /* The MGA X driver will try to push one set of cliprects (back or + * front, the last active) for one drawable (the last used) into + * the sarea. See if that window was ours, else retrieve both back + * and front rects from the X server via a protocol request. + * + * If there isn't room for the cliprects in the sarea, the X server + * clears the drawable value to indicate failure. + */ + if (0) printSareaRects(mmesa); + + if (sarea->exported_drawable == driDrawable->draw && + (sarea->exported_buffers & buffers) == buffers) + { + mgaUpdateRectsFromSarea( mmesa ); + } + else + { + if(MGA_DEBUG & DEBUG_VERBOSE_MSG) + fprintf(stderr, "^"); + driDrawable->lastStamp = 0; + + XMESA_VALIDATE_DRAWABLE_INFO(mmesa->display, + mmesa->driScreen, + driDrawable); + mmesa->dirty_cliprects = 0; + } + + if (mmesa->draw_buffer == MGA_FRONT) + mgaXMesaSetFrontClipRects( mmesa ); + else + mgaXMesaSetBackClipRects( mmesa ); + + + if (0) printMmesaRects(mmesa); + + sarea->req_drawable = driDrawable->draw; + sarea->req_draw_buffer = mmesa->draw_buffer; + + + mgaUpdateClipping( mmesa->glCtx ); + + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; +} + + + +GLboolean mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + FLUSH_BATCH( MGA_CONTEXT(ctx) ); + + mmesa->Fallback &= ~MGA_FALLBACK_BUFFER; + + if (mode == GL_FRONT_LEFT) + { + mmesa->drawOffset = mmesa->mgaScreen->frontOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->frontOffset; + mmesa->dirty |= MGA_UPLOAD_CTX; + mmesa->draw_buffer = MGA_FRONT; + mgaXMesaSetFrontClipRects( mmesa ); + return GL_TRUE; + } + else if (mode == GL_BACK_LEFT) + { + mmesa->drawOffset = mmesa->mgaScreen->backOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->backOffset; + mmesa->draw_buffer = MGA_BACK; + mmesa->dirty |= MGA_UPLOAD_CTX; + mgaXMesaSetBackClipRects( mmesa ); + return GL_TRUE; + } + else + { + mmesa->Fallback |= MGA_FALLBACK_BUFFER; + return GL_FALSE; + } +} + +GLboolean mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + if (mode == GL_FRONT_LEFT) + { + mmesa->readOffset = mmesa->mgaScreen->frontOffset; + mmesa->read_buffer = MGA_FRONT; + return GL_TRUE; + } + else if (mode == GL_BACK_LEFT) + { + mmesa->readOffset = mmesa->mgaScreen->backOffset; + mmesa->read_buffer = MGA_BACK; + return GL_TRUE; + } + else + { + return GL_FALSE; + } +} diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h new file mode 100644 index 000000000..9345fd9c4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h @@ -0,0 +1,9 @@ +#ifndef MGA_BUFFERS_H +#define MGA_BUFFERS_H + +GLboolean mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode ); +GLboolean mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode ); + +void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c b/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c index ae8d95037..428b65d06 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c @@ -46,205 +46,206 @@ */ void mgaConvertTexture( mgaUI32 *destPtr, int texelBytes, struct gl_texture_image *image, - int x, int y, int width, int height ) { + int x, int y, int width, int height ) +{ register int i, j; mgaUI8 *src; int stride; /* FIXME: g400 luminance_alpha internal format */ switch (texelBytes) { - case 1: - switch (image->Format) { - case GL_COLOR_INDEX: - case GL_INTENSITY: - case GL_LUMINANCE: - case GL_ALPHA: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width >> 2 ; j ; j-- ) { + case 1: + switch (image->Format) { + case GL_COLOR_INDEX: + case GL_INTENSITY: + case GL_LUMINANCE: + case GL_ALPHA: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width >> 2 ; j ; j-- ) { - *destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 ); - src += 4; - } - src += stride; - } - break; - default: - goto format_error; - } - break; - case 2: - switch (image->Format) { - case GL_RGB: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 3; - stride = (image->Width - width) * 3; - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { + *destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 ); + src += 4; + } + src += stride; + } + break; + default: + goto format_error; + } + break; + case 2: + switch (image->Format) { + case GL_RGB: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 3; + stride = (image->Width - width) * 3; + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) | - ( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 ); - src += 6; - } - src += stride; - } - break; - case GL_RGBA: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 4; - stride = (image->Width - width) * 4; - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) | + ( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 ); + src += 6; + } + src += stride; + } + break; + case GL_RGBA: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 4; + stride = (image->Width - width) * 4; + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) | - ( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 ); - src += 8; - } - src += stride; - } - break; - case GL_LUMINANCE: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { - /* FIXME: should probably use 555 texture to get true grey */ - *destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) | - ( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 ); - src += 2; - } - src += stride; - } - break; - case GL_INTENSITY: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) | + ( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 ); + src += 8; + } + src += stride; + } + break; + case GL_LUMINANCE: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { + /* FIXME: should probably use 555 texture to get true grey */ + *destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) | + ( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 ); + src += 2; + } + src += stride; + } + break; + case GL_INTENSITY: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) | - ( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 ); - src += 2; - } - src += stride; - } - break; - case GL_ALPHA: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) | + ( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 ); + src += 2; + } + src += stride; + } + break; + case GL_ALPHA: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) | - ( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 ); - src += 2; - } - src += stride; - } - break; - case GL_LUMINANCE_ALPHA: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 2; - stride = (image->Width - width) * 2; - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) | + ( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 ); + src += 2; + } + src += stride; + } + break; + case GL_LUMINANCE_ALPHA: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 2; + stride = (image->Width - width) * 2; + for ( i = height ; i ; i-- ) { + for ( j = width >> 1 ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) | - ( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 ); - src += 4; - } - src += stride; - } - break; - default: - goto format_error; - } - break; - case 4: - switch (image->Format) { - case GL_RGB: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 3; - stride = (image->Width - width) * 3; - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) | + ( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 ); + src += 4; + } + src += stride; + } + break; + default: + goto format_error; + } + break; + case 4: + switch (image->Format) { + case GL_RGB: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 3; + stride = (image->Width - width) * 3; + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255); - src += 3; - } - src += stride; - } - break; - case GL_RGBA: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 4; - stride = (image->Width - width) * 4; - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255); + src += 3; + } + src += stride; + } + break; + case GL_RGBA: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 4; + stride = (image->Width - width) * 4; + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]); - src += 4; - } - src += stride; - } - break; - case GL_LUMINANCE: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]); + src += 4; + } + src += stride; + } + break; + case GL_LUMINANCE: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255); - src += 1; - } - src += stride; - } - break; - case GL_INTENSITY: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255); + src += 1; + } + src += stride; + } + break; + case GL_INTENSITY: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]); - src += 1; - } - src += stride; - } - break; - case GL_ALPHA: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]); + src += 1; + } + src += stride; + } + break; + case GL_ALPHA: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ); + stride = (image->Width - width); + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]); - src += 1; - } - src += stride; - } - break; - case GL_LUMINANCE_ALPHA: - src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 2; - stride = (image->Width - width) * 2; - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { + *destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]); + src += 1; + } + src += stride; + } + break; + case GL_LUMINANCE_ALPHA: + src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 2; + stride = (image->Width - width) * 2; + for ( i = height ; i ; i-- ) { + for ( j = width ; j ; j-- ) { - *destPtr++ = MGAPACKCOLOR8888(src[0],src[0], - src[0],src[1]); - src += 2; - } - src += stride; - } - break; - default: - goto format_error; - } - break; - default: - goto format_error; + *destPtr++ = MGAPACKCOLOR8888(src[0],src[0], + src[0],src[1]); + src += 2; + } + src += stride; + } + break; + default: + goto format_error; + } + break; + default: + goto format_error; } return; -format_error: + format_error: - mgaError( "Unsupported texelBytes %i, image->Format %i\n", - texelBytes, image->Format ); + mgaError( "Unsupported texelBytes %i, image->Format %i\n", + (int)texelBytes, (int)image->Format ); } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.c b/xc/lib/GL/mesa/src/drv/mga/mgadd.c index ad56cbbc3..bdae9a2bf 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadd.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.c @@ -61,11 +61,11 @@ static const GLubyte *mgaDDGetString( GLcontext *ctx, GLenum name ) mgaContextPtr mmesa = MGA_CONTEXT( ctx ); switch (name) { case GL_VENDOR: - return "Utah GLX"; + return "Precision Insight"; case GL_RENDERER: - if (MGA_IS_G200(mmesa)) return "GLX-MGA-G200"; - if (MGA_IS_G400(mmesa)) return "GLX-MGA-G400"; - return "GLX-MGA"; + if (MGA_IS_G200(mmesa)) return "DRI-MGA-G200"; + if (MGA_IS_G400(mmesa)) return "DRI-MGA-G400"; + return "DRI-MGA"; default: return 0; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadepth.c b/xc/lib/GL/mesa/src/drv/mga/mgadepth.c index 0d55137d1..2dfc3e00c 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadepth.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgadepth.c @@ -43,20 +43,24 @@ #include "mgalib.h" #endif - +#define DEPTH_SCALE 65535.0F /* * Return the address of the Z-buffer value for window coordinate (x,y): */ -#define Z_SETUP \ - mgaContextPtr mmesa = MGA_CONTEXT(ctx); \ - __DRIscreenPrivate *sPriv = mmesa->driScreen; \ - mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \ - GLdepth *zbstart = (GLdepth *)(sPriv->pFB + mgaScreen->depthOffset);\ - GLint zbpitch = mgaScreen->depthPitch +#define Z_SETUP \ + __DRIscreenPrivate *sPriv = mmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \ + GLuint height = dPriv->h; \ + mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \ + GLint zbpitch = mgaScreen->depthPitch; \ + char *zbstart = (char *)(sPriv->pFB + \ + mgaScreen->depthOffset + \ + dPriv->x * 2 + \ + dPriv->y * zbpitch) #define Z_ADDRESS( X, Y ) \ - (zbstart + zbpitch * (Y) + (X)) + (GLdepth *)(zbstart + zbpitch * (height - (Y)) + (X) * 2) /**********************************************************************/ @@ -84,16 +88,18 @@ static GLuint mga_depth_test_span_generic( GLcontext* ctx, const GLdepth z[], GLubyte mask[] ) { - Z_SETUP; - GLdepth *zptr = Z_ADDRESS( x, y ); + mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLubyte *m = mask; GLuint i; GLuint passed = 0; - LOCK_HARDWARE(mmesa); + LOCK_HARDWARE_QUIESCENT(mmesa); + { + Z_SETUP; + GLdepth *zptr = Z_ADDRESS( x, y ); - /* switch cases ordered from most frequent to less frequent */ - switch (ctx->Depth.Func) { + /* switch cases ordered from most frequent to less frequent */ + switch (ctx->Depth.Func) { case GL_LESS: if (ctx->Depth.Mask) { /* Update Z buffer */ @@ -297,8 +303,8 @@ static GLuint mga_depth_test_span_generic( GLcontext* ctx, } break; default: + } } - UNLOCK_HARDWARE(mmesa); return passed; @@ -320,14 +326,16 @@ static void mga_depth_test_pixels_generic( GLcontext* ctx, const GLint x[], const GLint y[], const GLdepth z[], GLubyte mask[] ) { - Z_SETUP; - register GLdepth *zptr; - register GLuint i; + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + LOCK_HARDWARE_QUIESCENT(mmesa); + { + Z_SETUP; + register GLdepth *zptr; + register GLuint i; - LOCK_HARDWARE(mmesa); - /* switch cases ordered from most frequent to less frequent */ - switch (ctx->Depth.Func) { + /* switch cases ordered from most frequent to less frequent */ + switch (ctx->Depth.Func) { case GL_LESS: if (ctx->Depth.Mask) { /* Update Z buffer */ @@ -547,8 +555,8 @@ static void mga_depth_test_pixels_generic( GLcontext* ctx, } break; default: - } - + } + } UNLOCK_HARDWARE(mmesa); } @@ -570,27 +578,29 @@ static void mga_read_depth_span_float( GLcontext* ctx, GLuint n, GLint x, GLint y, GLfloat depth[] ) { - Z_SETUP; - GLdepth *zptr; - GLfloat scale; - GLuint i; + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + LOCK_HARDWARE_QUIESCENT(mmesa); + { - LOCK_HARDWARE(mmesa); + Z_SETUP; + GLdepth *zptr; + GLfloat scale; + GLuint i; - scale = 1.0F / DEPTH_SCALE; + scale = 1.0F / DEPTH_SCALE; - if (ctx->Buffer->Depth) { - zptr = Z_ADDRESS( x, y ); - for (i=0;i<n;i++) { - depth[i] = (GLfloat) zptr[i] * scale; + if (ctx->ReadBuffer->Depth) { + zptr = Z_ADDRESS( x, y ); + for (i=0;i<n;i++) { + depth[i] = (GLfloat) zptr[i] * scale; + } } - } - else { - for (i=0;i<n;i++) { - depth[i] = 0.0F; + else { + for (i=0;i<n;i++) { + depth[i] = 0.0F; + } } } - UNLOCK_HARDWARE(mmesa); } @@ -607,30 +617,32 @@ static void mga_read_depth_span_int( GLcontext* ctx, GLuint n, GLint x, GLint y, GLdepth depth[] ) { - Z_SETUP; + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + LOCK_HARDWARE_QUIESCENT(mmesa); + { + Z_SETUP; - LOCK_HARDWARE(mmesa); - if (ctx->Buffer->Depth) { - GLdepth *zptr = Z_ADDRESS( x, y ); - MEMCPY( depth, zptr, n * sizeof(GLdepth) ); - } - else { - GLuint i; - for (i=0;i<n;i++) { - depth[i] = 0; + if (ctx->ReadBuffer->Depth) { + GLdepth *zptr = Z_ADDRESS( x, y ); + MEMCPY( depth, zptr, n * sizeof(GLdepth) ); + } + else { + GLuint i; + for (i=0;i<n;i++) { + depth[i] = 0; + } } } - UNLOCK_HARDWARE(mmesa); } void mgaDDInitDepthFuncs( GLcontext *ctx ) { - ctx->Driver.ReadDepthSpanFloat = mga_read_depth_span_float; - ctx->Driver.ReadDepthSpanInt = mga_read_depth_span_int; - ctx->Driver.DepthTestSpan = mga_depth_test_span_generic; - ctx->Driver.DepthTestPixels = mga_depth_test_pixels_generic; + ctx->Driver.ReadDepthSpan = mga_read_depth_span_float; + ctx->Driver.WriteDepthSpan = mga_read_depth_span_float; + ctx->Driver.ReadDepthPixels mga_read_depth_span_float; + ctx->Driver.WriteDepthPixels = mga_read_depth_span_float; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c index 8017e7f02..5e237bb01 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c @@ -380,6 +380,8 @@ static void mga_project_vertices( struct vertex_buffer *VB ) GLmatrix *mat = &ctx->Viewport.WindowMap; GLfloat m[16]; + REFRESH_DRAWABLE_INFO(mmesa); + m[MAT_SX] = mat->m[MAT_SX]; m[MAT_TX] = mat->m[MAT_TX] + mmesa->drawX - .5; m[MAT_SY] = (- mat->m[MAT_SY]); @@ -401,6 +403,8 @@ static void mga_project_clipped_vertices( struct vertex_buffer *VB ) GLmatrix *mat = &ctx->Viewport.WindowMap; GLfloat m[16]; + REFRESH_DRAWABLE_INFO(mmesa); + m[MAT_SX] = mat->m[MAT_SX]; m[MAT_TX] = mat->m[MAT_TX] + mmesa->drawX - .5; m[MAT_SY] = (- mat->m[MAT_SY]); @@ -507,18 +511,12 @@ void mgaDDFastPath( struct vertex_buffer *VB ) ctx->CVA.elt_mode = gl_reduce_prim[prim]; VB->EltPtr = &(MGA_DRIVER_DATA(VB)->clipped_elements); - LOCK_HARDWARE( mmesa ); mga_project_clipped_vertices( VB ); /* clip->device space */ mga_render_elements_direct( VB ); /* render using new list */ - mgaFlushVerticesLocked( mmesa ); - UNLOCK_HARDWARE( mmesa ); } } else { - LOCK_HARDWARE( mmesa ); mga_project_vertices( VB ); /* clip->device space */ mga_render_elements_direct( VB ); /* render using orig list */ - mgaFlushVerticesLocked( mmesa ); - UNLOCK_HARDWARE( mmesa ); } /* This indicates that there is no cached data to reuse. diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h b/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h index 43caddcac..1fb177694 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h @@ -87,6 +87,8 @@ static void TAG(mga_setup_full)( struct vertex_buffer *VB, GLuint do_cliptest ) STRIDE_F(tex0_data, tex0_stride); } if (TYPE & MGA_TEX1_BIT) { + /* Hits a second cache line. + */ f[CLIP_S1] = tex1_data[0]; f[CLIP_T1] = tex1_data[1]; STRIDE_F(tex1_data, tex1_stride); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c index c1819924d..f9ef24310 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c @@ -14,114 +14,137 @@ #include "mgalog.h" #include "mgavb.h" #include "mgatris.h" +#include "mgabuffers.h" + #include "drm.h" #include <sys/ioctl.h> +#define DEPTH_SCALE 65535.0F + static void mga_iload_dma_ioctl(mgaContextPtr mmesa, - int x1, int y1, int x2, int y2, - unsigned long dest, unsigned int maccess) + unsigned long dest, + int length) { int retcode; drm_mga_iload_t iload; - drmBufPtr buf = mmesa->dma_buffer; + drmBufPtr buf = mmesa->iload_buffer; iload.idx = buf->idx; iload.destOrg = dest; - iload.mAccess = maccess; - iload.texture.x1 = x1; - iload.texture.y1 = y1; - iload.texture.y2 = x2; - iload.texture.x2 = y2; + iload.length = length; + + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n", + iload.idx, iload.destOrg, iload.length); + if ((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_ILOAD, &iload))) { printf("send iload retcode = %d\n", retcode); exit(1); } -} + mmesa->iload_buffer = 0; + + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "finished iload dma put\n"); -static void mga_vertex_dma_ioctl(mgaContextPtr mmesa) +} + +int mgaUpdateLock( mgaContextPtr mmesa, drmLockFlags flags ) { - int retcode; - int size = MGA_DMA_BUF_SZ; - drmDMAReq dma; - drmBufPtr buf = mmesa->dma_buffer; + drm_lock_t lock; + + lock.flags = 0; - dma.context = mmesa->hHWContext; - dma.send_count = 1; - dma.send_list = &buf->idx; - dma.send_sizes = &size; - dma.flags = DRM_DMA_WAIT; - dma.request_count = 0; - dma.request_size = 0; - dma.request_list = 0; - dma.request_sizes = 0; - - if ((retcode = drmDMA(mmesa->driFd, &dma))) { - printf("send iload retcode = %d\n", retcode); - exit(1); + if (mmesa->sarea->last_quiescent != mmesa->sarea->last_enqueue && + flags & DRM_LOCK_QUIESCENT) { + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "mgaLockQuiescent\n"); + 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; + + if (!lock.flags) + return 0; + + if(ioctl(mmesa->driFd, DRM_IOCTL_MGA_FLUSH, &lock)) { + printf("Lockupdate failed\n"); + return -1; } + + if(flags & DRM_LOCK_QUIESCENT) + mmesa->sarea->last_quiescent = mmesa->sarea->last_enqueue; + + return 0; } - -static void mga_get_buffer_ioctl( mgaContextPtr mmesa ) +static drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ) { int idx = 0; int size = 0; drmDMAReq dma; int retcode; + drmBufPtr buf; - fprintf(stderr, "Getting dma buffer\n"); + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "Getting dma buffer\n"); dma.context = mmesa->hHWContext; dma.send_count = 0; dma.send_list = NULL; dma.send_sizes = NULL; - dma.flags = DRM_DMA_WAIT; + dma.flags = 0; dma.request_count = 1; dma.request_size = MGA_DMA_BUF_SZ; dma.request_list = &idx; dma.request_sizes = &size; - - if ((retcode = drmDMA(mmesa->driFd, &dma))) { - fprintf(stderr, "request drmDMA retcode = %d\n", retcode); - exit(1); - } + dma.granted_count = 0; - mmesa->dma_buffer = &mmesa->mgaScreen->bufs->list[idx]; -} -static void mga_swap_ioctl( mgaContextPtr mmesa ) -{ - int retcode; - drm_mga_swap_t swap; - - if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) { - printf("send swap retcode = %d\n", retcode); - exit(1); - } -} + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n", + dma.context, dma.request_count, + dma.request_size); + while (1) { + retcode = drmDMA(mmesa->driFd, &dma); + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "retcode %d sz %d idx %d count %d\n", + retcode, + dma.request_sizes[0], + dma.request_list[0], + dma.granted_count); -static void mga_clear_ioctl( mgaContextPtr mmesa, int flags, int col, int zval ) -{ - int retcode; - drm_mga_clear_t clear; - - clear.flags = flags; - clear.clear_color = col; - clear.clear_depth = zval; - - if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_CLEAR, &clear))) { - printf("send clear retcode = %d\n", retcode); - exit(1); + if (retcode == 0 && + dma.request_sizes[0] && + dma.granted_count) + break; + + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "\n\nflush"); + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); } -} + buf = &(mmesa->mgaScreen->bufs->list[idx]); + buf->used = 0; + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, + "drmDMA (get) returns size[0] 0x%x idx[0] %d\n" + "dma_buffer now: buf idx: %d size: %d used: %d\n", + dma.request_sizes[0], dma.request_list[0], + buf->idx, buf->total, + buf->used); + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "finished getbuffer\n"); + + return buf; +} @@ -130,52 +153,57 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLuint c = mmesa->ClearColor; - mgaUI32 zval = (mgaUI32) (ctx->Depth.Clear * DEPTH_SCALE); __DRIdrawablePrivate *dPriv = mmesa->driDrawable; - int flags = 0; + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + drm_mga_clear_t clear; + int retcode; int i; + static int nrclears; - mgaMsg( 10, "mgaClear( %i, %i, %i, %i, %i )\n", - mask, x, y, width, height ); - - - mgaFlushVertices( mmesa ); + clear.flags = 0; + clear.clear_color = mmesa->ClearColor; + clear.clear_depth = (mgaUI32) (ctx->Depth.Clear * DEPTH_SCALE); + FLUSH_BATCH( mmesa ); + + if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) { + clear.flags |= MGA_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } - if (mask & GL_COLOR_BUFFER_BIT) { - if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT) { - flags |= MGA_CLEAR_FRONT; - mask &= ~GL_COLOR_BUFFER_BIT; - } else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT) { - flags |= MGA_CLEAR_BACK; - mask &= ~GL_COLOR_BUFFER_BIT; - } + if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) { + clear.flags |= MGA_BACK; + mask &= ~DD_BACK_LEFT_BIT; } - if ((flags & GL_DEPTH_BUFFER_BIT) && ctx->Depth.Mask) { - flags |= MGA_CLEAR_DEPTH; - mask &= ~GL_DEPTH_BUFFER_BIT; + if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) { + clear.flags |= MGA_DEPTH; + mask &= ~DD_DEPTH_BIT; } - if (!flags) + if (!clear.flags) return mask; LOCK_HARDWARE( mmesa ); - + + if (mmesa->dirty_cliprects) + mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK)); + /* flip top to bottom */ cy = dPriv->h-cy-ch; cx += mmesa->drawX; cy += mmesa->drawY; - for (i = 0 ; i < dPriv->numClipRects ; ) { + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "Clear, bufs %x nbox %d\n", + (int)clear.flags, (int)mmesa->numClipRects); - /* Use the cliprects for the current draw buffer - */ + for (i = 0 ; i < mmesa->numClipRects ; ) + { int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects); XF86DRIClipRectRec *box = mmesa->pClipRects; - xf86drmClipRectRec *b = mmesa->sarea->boxes; - mmesa->sarea->nbox = nr - i; + drm_clip_rect_t *b = mmesa->sarea->boxes; + int n = 0; if (!all) { for ( ; i < nr ; i++) { @@ -196,16 +224,37 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all, b->x2 = x + w; b->y2 = y + h; b++; + n++; } } else { - for ( ; i < nr ; i++) - *b++ = *(xf86drmClipRectRec *)&box[i]; + for ( ; i < nr ; i++) { + *b++ = *(drm_clip_rect_t *)&box[i]; + n++; + } } - mga_clear_ioctl( mmesa, mask, c, zval ); + + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, + "DRM_IOCTL_MGA_CLEAR flag 0x%x color %x depth %x nbox %d\n", + clear.flags, clear.clear_color, + clear.clear_depth, mmesa->sarea->nbox); + + + mmesa->sarea->nbox = n; + + retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_CLEAR, &clear); + if (retcode) { + printf("send clear retcode = %d\n", retcode); + exit(1); + } + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "finished clear %d\n", ++nrclears); } UNLOCK_HARDWARE( mmesa ); + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; + return mask; } @@ -218,50 +267,62 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all, void mgaSwapBuffers( mgaContextPtr mmesa ) { __DRIdrawablePrivate *dPriv = mmesa->driDrawable; + XF86DRIClipRectPtr pbox; + int nbox; + drm_mga_swap_t swap; + static int nrswaps; + int retcode; int i; + int tmp; - mgaFlushVertices( mmesa ); - LOCK_HARDWARE( mmesa ); - { - /* Use the frontbuffer cliprects - */ - XF86DRIClipRectPtr pbox = dPriv->pClipRects; - int nbox = dPriv->numClipRects; + FLUSH_BATCH( mmesa ); - for (i = 0 ; i < nbox ; ) - { - int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); - XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes; - mmesa->sarea->nbox = nr - i; + LOCK_HARDWARE( mmesa ); + + /* Use the frontbuffer cliprects + */ + if (mmesa->dirty_cliprects & MGA_FRONT) + mgaUpdateRects( mmesa, MGA_FRONT ); + - for ( ; i < nr ; i++) - *b++ = pbox[i]; - - mga_swap_ioctl( mmesa ); - } - } + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "swap, nbox %d\n", nbox); -#if 1 - UNLOCK_HARDWARE(mmesa); -#else + for (i = 0 ; i < nbox ; ) { - last_enqueue = mmesa->sarea->lastEnqueue; - last_dispatch = mmesa->sarea->lastDispatch; - UNLOCK_HARDWARE; + int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); + XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes; + + mmesa->sarea->nbox = nr - i; + + for ( ; i < nr ; i++) + *b++ = pbox[i]; - /* Throttle runaway apps - there should be an easier way to sleep - * on dma without locking out the rest of the system! - */ - if (mmesa->lastSwap > last_dispatch) { - drmGetLock(mmesa->driFd, mmesa->hHWContext, DRM_LOCK_QUIESCENT); - DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext); + if (0) + fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n"); + + if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) { + printf("send swap retcode = %d\n", retcode); + exit(1); } - mmesa->lastSwap = last_enqueue; + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "finished swap %d\n", ++nrswaps); } -#endif + + tmp = GET_ENQUEUE_AGE(mmesa); + + UNLOCK_HARDWARE( mmesa ); + + if (GET_DISPATCH_AGE(mmesa) < mmesa->lastSwap) + mgaWaitAge(mmesa, mmesa->lastSwap); + + mmesa->lastSwap = tmp; + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; } @@ -269,53 +330,243 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) */ void mgaDDFinish( GLcontext *ctx ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - drmGetLock(mmesa->driFd, mmesa->hHWContext, DRM_LOCK_QUIESCENT); - DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext); + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + if (mmesa->sarea->last_quiescent != mmesa->sarea->last_enqueue) { + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "mgaRegetLockQuiescent\n"); + + LOCK_HARDWARE( mmesa ); + mgaUpdateLock( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH); + UNLOCK_HARDWARE( mmesa ); + + mmesa->sarea->last_quiescent = mmesa->sarea->last_enqueue; + } } +void mgaWaitAgeLocked( mgaContextPtr mmesa, int age ) +{ + if (GET_DISPATCH_AGE(mmesa) < age) { + if (0) fprintf(stderr, "\n\n\nmgaWaitAgeLocked\n"); + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); + } +} +void mgaWaitAge( mgaContextPtr mmesa, int age ) +{ + if (GET_DISPATCH_AGE(mmesa) < age) { + LOCK_HARDWARE(mmesa); + if (GET_DISPATCH_AGE(mmesa) < age) { + if (0) fprintf(stderr, "\n\n\nmgaWaitAge\n"); + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); + } + UNLOCK_HARDWARE(mmesa); + } +} -void mgaFlushVertices( mgaContextPtr mmesa ) + +static int intersect_rect( drm_clip_rect_t *out, + drm_clip_rect_t *a, + drm_clip_rect_t *b ) { - LOCK_HARDWARE( mmesa ); - mgaFlushVerticesLocked( mmesa ); - UNLOCK_HARDWARE( mmesa ); + *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 0; + if (out->y1 >= out->y2) return 0; + return 1; } + + +static void age_mmesa( mgaContextPtr mmesa, int age ) +{ + if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->age = age; + if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->age = age; +} + void mgaFlushVerticesLocked( mgaContextPtr mmesa ) { - XF86DRIClipRectPtr pbox = mmesa->pClipRects; + drm_clip_rect_t *pbox = (drm_clip_rect_t *)mmesa->pClipRects; int nbox = mmesa->numClipRects; + drmBufPtr buffer = mmesa->vertex_dma_buffer; + drm_mga_vertex_t vertex; int i; - if (mmesa->dirty) + if (!buffer) + return; + + if (mmesa->dirty_cliprects & mmesa->draw_buffer) + mgaUpdateRects( mmesa, mmesa->draw_buffer ); + + if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS) mgaEmitHwStateLocked( mmesa ); - for (i = 0 ; i < nbox ; ) + /* FIXME: Workaround bug in kernel module. + */ + mmesa->sarea->dirty |= MGA_UPLOAD_CTX; + + /* FIXME: dstorg bug + */ + if (0) + if (mmesa->lastX != mmesa->drawX || mmesa->lastY != mmesa->drawY) + fprintf(stderr, "****** last: %d,%d current: %d,%d\n", + mmesa->lastX, mmesa->lastY, + mmesa->drawX, mmesa->drawY); + + + mmesa->vertex_dma_buffer = 0; + vertex.idx = buffer->idx; + vertex.used = buffer->used; + vertex.discard = 0; + + if (!nbox) + vertex.used = 0; + + if (nbox >= MGA_NR_SAREA_CLIPRECTS) + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; + + if (!vertex.used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS)) { - int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox); - XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes; - mmesa->sarea->nbox = nr - i; + if (nbox == 1) + mmesa->sarea->nbox = 0; + else + mmesa->sarea->nbox = nbox; + + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox); + + vertex.discard = 1; + ioctl(mmesa->driFd, DRM_IOCTL_MGA_VERTEX, &vertex); + age_mmesa(mmesa, mmesa->sarea->last_enqueue); + } + else + { + for (i = 0 ; i < nbox ; ) + { + int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox); + drm_clip_rect_t *b = mmesa->sarea->boxes; + + if (mmesa->scissor) { + mmesa->sarea->nbox = 0; + + for ( ; i < nr ; i++) { + *b = pbox[i]; + if (intersect_rect(b, b, &mmesa->scissor_rect)) { + mmesa->sarea->nbox++; + b++; + } + } + + /* Culled? + */ + if (!mmesa->sarea->nbox) { + if (nr < nbox) continue; + vertex.used = 0; + } + } else { + mmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++) + *b++ = pbox[i]; + } - for ( ; i < nr ; i++) - *b++ = pbox[i]; - - mga_vertex_dma_ioctl( mmesa ); + /* Finished with the buffer? + */ + if (nr == nbox) + vertex.discard = 1; + + mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS; + ioctl(mmesa->driFd, DRM_IOCTL_MGA_VERTEX, &vertex); + age_mmesa(mmesa, mmesa->sarea->last_enqueue); + } + } + + mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS; +} + +void mgaFlushVertices( mgaContextPtr mmesa ) +{ + LOCK_HARDWARE( mmesa ); + mgaFlushVerticesLocked( mmesa ); + UNLOCK_HARDWARE( mmesa ); +} + + +mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ) +{ + int bytes = dwords * 4; + mgaUI32 *head; + + if (!mmesa->vertex_dma_buffer) { + LOCK_HARDWARE( mmesa ); + mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa ); + UNLOCK_HARDWARE( mmesa ); + } else if (mmesa->vertex_dma_buffer->used + bytes > + mmesa->vertex_dma_buffer->total) { + LOCK_HARDWARE( mmesa ); + mgaFlushVerticesLocked( mmesa ); + mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa ); + UNLOCK_HARDWARE( mmesa ); + } + + head = (mgaUI32 *)((char *)mmesa->vertex_dma_buffer->address + + mmesa->vertex_dma_buffer->used); + + mmesa->vertex_dma_buffer->used += bytes; + return head; +} - break; /* fix dma multiple dispatch */ + +void mgaFireILoadLocked( mgaContextPtr mmesa, + GLuint offset, GLuint length ) +{ + if (!mmesa->iload_buffer) { + fprintf(stderr, "mgaFireILoad: no buffer\n"); + return; } - mga_get_buffer_ioctl( mmesa ); + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "mgaFireILoad idx %d ofs 0x%x length %d\n", + mmesa->iload_buffer->idx, (int)offset, (int)length ); + + mga_iload_dma_ioctl( mmesa, offset, length ); } +void mgaGetILoadBufferLocked( mgaContextPtr mmesa ) +{ + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "mgaGetIloadBuffer (buffer now %p)\n", + mmesa->iload_buffer); + + mmesa->iload_buffer = mga_get_buffer_ioctl( mmesa ); +} + + +static void mgaDDFlush( GLcontext *ctx ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + + FLUSH_BATCH( mmesa ); + + /* This may be called redundantly - dispatch_age may trail what + * has actually been sent and processed by the hardware. + */ + if (GET_DISPATCH_AGE( mmesa ) < mmesa->sarea->last_enqueue) { + LOCK_HARDWARE( mmesa ); + if (0) fprintf(stderr, "mgaDDFlush\n"); + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); + UNLOCK_HARDWARE( mmesa ); + } +} void mgaDDInitIoctlFuncs( GLcontext *ctx ) { ctx->Driver.Clear = mgaClear; - ctx->Driver.Flush = 0; + ctx->Driver.Flush = mgaDDFlush; ctx->Driver.Finish = mgaDDFinish; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h index 22ca26e17..13cec59d7 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h @@ -9,6 +9,21 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all, void mgaSwapBuffers( mgaContextPtr mmesa ); + + +mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ); + + +void mgaGetILoadBufferLocked( mgaContextPtr mmesa ); + + +void mgaFireILoadLocked( mgaContextPtr mmesa, + GLuint offset, GLuint length ); + +void mgaWaitAgeLocked( mgaContextPtr mmesa, int age ); +void mgaWaitAge( mgaContextPtr mmesa, int age ); +int mgaUpdateLock( mgaContextPtr mmesa, drmLockFlags flags ); + void mgaFlushVertices( mgaContextPtr mmesa ); void mgaFlushVerticesLocked( mgaContextPtr mmesa ); @@ -19,5 +34,11 @@ void mgaDDFinish( GLcontext *ctx ); void mgaDDInitIoctlFuncs( GLcontext *ctx ); +#define FLUSH_BATCH(mmesa) do { \ + if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) \ + fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \ + if (mmesa->vertex_dma_buffer) mgaFlushVertices(mmesa); \ +} while (0) + #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgalib.h b/xc/lib/GL/mesa/src/drv/mga/mgalib.h index 4600a69a0..176c126bd 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgalib.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgalib.h @@ -36,6 +36,7 @@ #include "types.h" +#include "drm.h" #include "mgacommon.h" #include "mm.h" #include "mgalog.h" @@ -43,7 +44,6 @@ #include "mgatex.h" #include "mgavb.h" -#include "mga_drm_public.h" #include "mga_xmesa.h" @@ -51,11 +51,8 @@ #define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK)) #define MGA_GET_FIELD(field, val) ((val & ~(field ## _MASK)) >> (field ## _SHIFT)) -#define MGA_CHIP_MGAG200 0 -#define MGA_CHIP_MGAG400 1 - -#define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CHIP_MGAG200) -#define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CHIP_MGAG400) +#define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G200) +#define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400) /* SoftwareFallback @@ -65,6 +62,7 @@ */ #define MGA_FALLBACK_TEXTURE 0x1 #define MGA_FALLBACK_BUFFER 0x2 +#define MGA_FALLBACK_STIPPLE 0x3 /* For mgaCtx->new_state. @@ -97,17 +95,30 @@ typedef void (*mga_interp_func)( GLfloat t, #define MGA_PF_8888 (10 << 4) #define MGA_PF_HASALPHA (8 << 4) + + +/* Reasons why the GL_BLEND fallback mightn't work: + */ +#define MGA_BLEND_ENV_COLOR 0x1 +#define MGA_BLEND_MULTITEX 0x2 + + struct mga_context_t { GLcontext *glCtx; - /* Hardware state - moved from mgabuf.h - */ - mgaUI32 Setup[MGA_CTX_SETUP_SIZE]; - /* Variable sized vertices + /* Bookkeeping for texturing */ - mgaUI32 vertsize; + int lastTexHeap; + struct mga_texture_object_s TexObjList[MGA_NR_TEX_HEAPS]; + struct mga_texture_object_s SwappedOut; + struct mga_texture_object_s *CurrentTexObj[2]; + memHeap_t *texHeap[MGA_NR_TEX_HEAPS]; + int c_texupload; + int c_texusage; + int tex_thrash; + /* Map GL texture units onto hardware. */ @@ -116,68 +127,84 @@ struct mga_context_t { mgaUI32 tex_dest[2]; + /* Manage fallbacks + */ + mgaUI32 IndirectTriangles; + int Fallback; - /* bookkeeping for textureing */ - struct mga_texture_object_s TexObjList; - struct mga_texture_object_s SwappedOut; - struct mga_texture_object_s *CurrentTexObj[2]; - - - /* shared texture palette */ - mgaUI16 GlobalPalette[256]; - - int Fallback; /* or'ed values of FALLBACK_* */ - /* Support for CVA and the fast paths */ + /* Support for CVA and the fastpath + */ unsigned int setupdone; unsigned int setupindex; unsigned int renderindex; unsigned int using_fast_path; - unsigned int using_immediate_fast_path; mga_interp_func interp; - /* Shortcircuit some state changes */ + + /* Support for limited GL_BLEND fallback + */ + unsigned int blend_flags; + unsigned int envcolor; + + + /* Shortcircuit some state changes + */ points_func PointsFunc; line_func LineFunc; triangle_func TriangleFunc; quad_func QuadFunc; - /* Manage our own state */ + + /* Manage driver and hardware state + */ GLuint new_state; GLuint dirty; - - GLubyte clearcolor[4]; - GLushort MonoColor; - GLushort ClearColor; + GLuint Setup[MGA_CTX_SETUP_SIZE]; + GLuint warp_pipe; + GLuint vertsize; + GLushort MonoColor; + GLushort ClearColor; + GLuint poly_stipple; - /* DRI stuff + /* Dma buffers */ - drmBufPtr dma_buffer; + drmBufPtr vertex_dma_buffer; + drmBufPtr iload_buffer; - GLframebuffer *glBuffer; - memHeap_t *texHeap; + + /* Drawable, cliprect and scissor information + */ + int dirty_cliprects; /* which sets of cliprects are uptodate? */ + int draw_buffer; /* which buffer are we rendering to */ + int drawOffset; /* draw buffer address in space */ + int read_buffer; + int readOffset; + int drawX, drawY; /* origin of drawable in draw buffer */ + int lastX, lastY; /* detect DSTORG bug */ + GLuint numClipRects; /* cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; + XF86DRIClipRectRec draw_rect; + drm_clip_rect_t scissor_rect; + int scissor; - GLuint needClip; - GLuint warp_pipe; - /* These refer to the current draw (front vs. back) buffer: + /* Texture aging and DMA based aging. */ - int drawOffset; /* draw buffer address in agp space */ - int drawX; /* origin of drawable in draw buffer */ - int drawY; - GLuint numClipRects; /* cliprects for that buffer */ - XF86DRIClipRectPtr pClipRects; + unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */ + int dirtyAge; /* buffer age for synchronization */ + int lastSwap; /* throttling runaway apps */ - int texAge; - XF86DRIClipRectRec draw_rect; + /* Mirrors of some DRI state. + */ + GLframebuffer *glBuffer; drmContext hHWContext; drmLock *driHwLock; int driFd; Display *display; - __DRIdrawablePrivate *driDrawable; __DRIscreenPrivate *driScreen; mgaScreenPrivate *mgaScreen; @@ -191,16 +218,12 @@ typedef struct { /* dma stuff */ mgaUI32 systemTexture; - mgaUI32 noSetupDma; mgaUI32 default32BitTextures; - mgaUI32 swapBuffersCount; /* options */ mgaUI32 nullprims; /* skip all primitive generation */ - mgaUI32 noFallback; /* don't fall back to software, do - best-effort rendering */ - mgaUI32 skipDma; /* don't send anything to the hardware */ + mgaUI32 noFallback; /* performance counters */ mgaUI32 c_textureUtilization; @@ -240,10 +263,12 @@ extern mgaGlx_t mgaglx; extern int MGA_DEBUG; #endif -#define MGA_DEBUG_ALWAYS_SYNC 0x1 -#define MGA_DEBUG_VERBOSE_MSG 0x2 -#define MGA_DEBUG_VERBOSE_LRU 0x4 -#define MGA_DEBUG_VERBOSE_DRI 0x8 +#define DEBUG_ALWAYS_SYNC 0x1 +#define DEBUG_VERBOSE_MSG 0x2 +#define DEBUG_VERBOSE_LRU 0x4 +#define DEBUG_VERBOSE_DRI 0x8 +#define DEBUG_VERBOSE_IOCTL 0x10 +#define DEBUG_VERBOSE_2D 0x20 static __inline__ mgaUI32 mgaPackColor(mgaUI32 format, mgaUI8 r, mgaUI8 g, diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c index 38e3cdde8..9bf62391c 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c @@ -5,70 +5,99 @@ #include "mgalog.h" #include "mgaspan.h" +#define DBG 0 + #define LOCAL_VARS \ - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); \ __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \ - __DRIscreenPrivate *sPriv = mmesa->driScreen; \ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \ - GLuint pitch = mgaScreen->backPitch; \ + __DRIscreenPrivate *sPriv = mmesa->driScreen; \ + GLuint pitch = mgaScreen->frontPitch; \ GLuint height = dPriv->h; \ + char *read_buf = (char *)(sPriv->pFB + \ + mmesa->readOffset + \ + dPriv->x * 2 + \ + dPriv->y * pitch); \ char *buf = (char *)(sPriv->pFB + \ mmesa->drawOffset + \ dPriv->x * 2 + \ + dPriv->y * pitch); \ + GLushort p = MGA_CONTEXT( ctx )->MonoColor; \ + (void) read_buf; (void) buf; (void) p + + + +#define LOCAL_DEPTH_VARS \ + __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \ + mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \ + __DRIscreenPrivate *sPriv = mmesa->driScreen; \ + GLuint pitch = mgaScreen->frontPitch; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(sPriv->pFB + \ + mgaScreen->depthOffset + \ + dPriv->x * 2 + \ dPriv->y * pitch) -#define INIT_MONO_PIXEL(p) \ - GLushort p = MGA_CONTEXT( ctx )->MonoColor; +#define INIT_MONO_PIXEL(p) -#define CLIPPIXEL(_x,_y) (_x >= minx && _x <= maxx && \ - _y >= miny && _y <= maxy) +#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \ + _y >= miny && _y < maxy) -#define CLIPSPAN(_x,_y,_n,_x1,_n1) \ +#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) _n1 -= (minx - _x1), _x1 = minx; \ - if (_x1 + _n1 > maxx) n1 -= (_x1 + n1 - maxx); \ + if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \ + if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \ } - +#define HW_LOCK() \ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); \ + LOCK_HARDWARE_QUIESCENT(mmesa); #define HW_CLIPLOOP() \ do { \ int _nc = mmesa->numClipRects; \ - LOCK_HARDWARE_QUIESCENT(mmesa); \ while (_nc--) { \ - int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX; \ - int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY; \ - int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX; \ + int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX; \ + int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY; \ + int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX; \ int maxy = mmesa->pClipRects[_nc].y2 - mmesa->drawY; - #define HW_ENDCLIPLOOP() \ } \ - UNLOCK_HARDWARE(mmesa); \ } while (0) +#define HW_UNLOCK() \ + UNLOCK_HARDWARE(mmesa); + + + -#define Y_FLIP(_y) (height - _y) + + + +/* 16 bit, 565 rgb color spanline and pixel functions + */ +#define Y_FLIP(_y) (height - _y - 1) #define WRITE_RGBA( _x, _y, r, g, b, a ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = ( ((r & 0x1f) << 11) | \ - ((g & 0x3f) << 5) | \ - ((b & 0x1f))) + *(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \ + (((int)g & 0xfc) << 3) | \ + (((int)b & 0xf8) >> 3)) + #define WRITE_PIXEL( _x, _y, p ) \ *(GLushort *)(buf + _x*2 + _y*pitch) = p #define READ_RGBA( rgba, _x, _y ) \ do { \ - GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 11) & 0x1f; \ - rgba[1] = (p >> 5) & 0x3f; \ - rgba[2] = (p >> 0) & 0x1f; \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (p >> 8) & 0xf8; \ + rgba[1] = (p >> 3) & 0xfc; \ + rgba[2] = (p << 3) & 0xf8; \ rgba[3] = 0; /* or 255? */ \ } while(0) @@ -78,21 +107,21 @@ do { \ - -#define WRITE_RGBA( _x, _y, r, g, b, a ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = ( ((r & 0x1f) << 10) | \ - ((g & 0x1f) << 5) | \ - ((b & 0x1f))) - +/* 15 bit, 555 rgb color spanline and pixel functions + */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \ + ((g & 0xf8) << 3) | \ + ((b & 0xf8) >> 3)) #define WRITE_PIXEL( _x, _y, p ) \ *(GLushort *)(buf + _x*2 + _y*pitch) = p #define READ_RGBA( rgba, _x, _y ) \ do { \ - GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 10) & 0x1f; \ - rgba[1] = (p >> 5) & 0x1f; \ - rgba[2] = (p >> 0) & 0x1f; \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (p >> 7) & 0xf8; \ + rgba[1] = (p >> 3) & 0xf8; \ + rgba[2] = (p << 3) & 0xf8; \ rgba[3] = 0; /* or 255? */ \ } while(0) @@ -101,27 +130,19 @@ do { \ -#if 0 -#define WRITE_RGBA( _x, _y, r, g, b, a ) \ - *(GLuint *)(buf + _x*4 + _y*pitch) = ( ((r) << 16) | \ - ((g) << 8) | \ - ((b))) +/* 16 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLdepth *)(buf + _x*2 + _y*pitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLdepth *)(buf + _x*2 + _y*pitch); + +#define TAG(x) mga##x##_16 +#include "depthtmp.h" -#define WRITE_PIXEL( _x, _y, p ) \ - *(GLuint *)(buf + _x*4 + _y*pitch) = p -#define READ_RGBA( rgba, _x, _y ) \ -do { \ - GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \ - rgba[0] = (p >> 16) & 0xff; \ - rgba[1] = (p >> 8) & 0xff; \ - rgba[2] = (p >> 0) & 0xff; \ - rgba[3] = 0; /* or 255? */ \ -} while(0) -#define TAG(x) mga##x##_888 -#include "spantmp.h" -#endif void mgaDDInitSpanFuncs( GLcontext *ctx ) { @@ -143,6 +164,11 @@ void mgaDDInitSpanFuncs( GLcontext *ctx ) ctx->Driver.ReadRGBAPixels = mgaReadRGBAPixels_555; } + ctx->Driver.ReadDepthSpan = mgaReadDepthSpan_16; + ctx->Driver.WriteDepthSpan = mgaWriteDepthSpan_16; + ctx->Driver.ReadDepthPixels = mgaReadDepthPixels_16; + ctx->Driver.WriteDepthPixels = mgaWriteDepthPixels_16; + ctx->Driver.WriteCI8Span =NULL; ctx->Driver.WriteCI32Span =NULL; ctx->Driver.WriteMonoCISpan =NULL; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c index ff9063e0b..0dacd7646 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c @@ -16,7 +16,7 @@ #include "mgavb.h" #include "mgatris.h" #include "mgaregs.h" -#include "mga_drm_public.h" +#include "mgabuffers.h" static void mgaUpdateZMode(const GLcontext *ctx) { @@ -60,17 +60,20 @@ static void mgaUpdateZMode(const GLcontext *ctx) static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; } static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; } static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; } @@ -78,6 +81,7 @@ static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; } @@ -87,6 +91,7 @@ static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; } } @@ -95,6 +100,7 @@ static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname, static void mgaDDShadeModel(GLcontext *ctx, GLenum mode) { if (1) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; mgaMsg(8, "mgaDDShadeModel: %x\n", mode); } @@ -103,11 +109,13 @@ static void mgaDDShadeModel(GLcontext *ctx, GLenum mode) static void mgaDDDepthFunc(GLcontext *ctx, GLenum func) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; } static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; } @@ -134,6 +142,7 @@ static void mgaUpdateFogAttrib( GLcontext *ctx ) static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_FOG; } @@ -148,10 +157,11 @@ static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) static void mgaUpdateAlphaMode(GLcontext *ctx) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; int a = 0; /* determine source of alpha for blending and testing */ - if ( !ctx->Texture.Enabled || (mmesa->Fallback & MGA_FALLBACK_TEXTURE)) + if ( !ctx->Texture.Enabled ) a |= AC_alphasel_diffused; else { switch (ctx->Texture.Unit[0].EnvMode) { @@ -168,7 +178,7 @@ static void mgaUpdateAlphaMode(GLcontext *ctx) } - /* alpha test control - disabled by default. + /* alpha test control. */ if (ctx->Color.AlphaEnabled) { GLubyte ref = ctx->Color.AlphaRef; @@ -219,13 +229,13 @@ static void mgaUpdateAlphaMode(GLcontext *ctx) case GL_ONE_MINUS_SRC_ALPHA: a |= AC_src_om_src_alpha; break; case GL_DST_ALPHA: - if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/ + if (mgaScreen->Attrib & MGA_PF_HASALPHA) a |= AC_src_dst_alpha; else a |= AC_src_one; break; case GL_ONE_MINUS_DST_ALPHA: - if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/ + if (mgaScreen->Attrib & MGA_PF_HASALPHA) a |= AC_src_om_dst_alpha; else a |= AC_src_zero; @@ -250,13 +260,13 @@ static void mgaUpdateAlphaMode(GLcontext *ctx) case GL_ONE_MINUS_SRC_COLOR: a |= AC_dst_om_src_color; break; case GL_DST_ALPHA: - if (0) /*(mgaDB->Attrib & MGA_PF_HASALPHA)*/ + if (mgaScreen->Attrib & MGA_PF_HASALPHA) a |= AC_dst_dst_alpha; else a |= AC_dst_one; break; case GL_ONE_MINUS_DST_ALPHA: - if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/ + if (mgaScreen->Attrib & MGA_PF_HASALPHA) a |= AC_dst_om_dst_alpha; else a |= AC_dst_zero; @@ -282,50 +292,44 @@ static void mgaUpdateAlphaMode(GLcontext *ctx) * Hardware clipping */ -static void mgaUpdateClipping(const GLcontext *ctx) +void mgaUpdateClipping(const GLcontext *ctx) { -#if 0 - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - __DRIdrawablePrivate *dPriv = mmesa->driDrawable; - int x1,x2,y1,y2; - - if ( ctx->Scissor.Enabled) { - x1 = ctx->Scissor.X; - x2 = ctx->Scissor.X + ctx->Scissor.Width - 1; - y1 = dPriv->Height - ctx->Scissor.Y - ctx->Scissor.Height; - y2 = dPriv->Height - ctx->Scissor.Y - 1; - } else { - x1 = 0; - y1 = 0; - x2 = mgaDB->Width-1; - y2 = mgaDB->Height-1; - } - - if (x1 < 0) x1 = 0; - if (y1 < 0) y1 = 0; - if (x2 >= mgaDB->Width) x2 = mgaDB->Width-1; - if (y2 >= mgaDB->Height) y2 = mgaDB->Height-1; - - if (x1 > x2 || y1 > y2) { - x1 = 0; x2 = 0; - y2 = 0; y1 = 1; - } - - - mmesa->Setup[MGA_CTXREG_CXBNDRY] = (MGA_FIELD(CXB_cxright,x2) | - MGA_FIELD(CXB_cxleft,x1)); - mmesa->Setup[MGA_CTXREG_YTOP] = y1*mgaDB->Pitch; - mmesa->Setup[MGA_CTXREG_YBOT] = y2*mgaDB->Pitch; - + mgaContextPtr mmesa = MGA_CONTEXT(ctx); - mmesa->dirty |= MGA_UPLOAD_CTX; -#endif + if (mmesa->driDrawable) + { + int x1 = mmesa->driDrawable->x + ctx->Scissor.X; + int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h - (ctx->Scissor.Y+ + ctx->Scissor.Height); + int x2 = mmesa->driDrawable->x + ctx->Scissor.X+ctx->Scissor.Width; + int y2 = mmesa->driDrawable->y + mmesa->driDrawable->h - ctx->Scissor.Y; + + if (x1 < 0) x1 = 0; + if (y1 < 0) y1 = 0; + if (x2 < 0) x2 = 0; + if (y2 < 0) y2 = 0; + + mmesa->scissor_rect.x1 = x1; + mmesa->scissor_rect.y1 = y1; + mmesa->scissor_rect.x2 = x2; + mmesa->scissor_rect.y2 = y2; + + if (MGA_DEBUG&DEBUG_VERBOSE_2D) + fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n", + mmesa->scissor_rect.x1, + mmesa->scissor_rect.y1, + mmesa->scissor_rect.x2, + mmesa->scissor_rect.y2); + + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; + } } static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP; } @@ -339,35 +343,6 @@ static void mgaDDDither(GLcontext *ctx, GLboolean enable) } -static GLboolean mgaDDSetBuffer(GLcontext *ctx, GLenum mode ) -{ - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - - mmesa->Fallback &= ~MGA_FALLBACK_BUFFER; - - if (mode == GL_FRONT_LEFT) - { - mmesa->drawOffset = mmesa->mgaScreen->fbOffset; - mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->fbOffset; - mmesa->dirty |= MGA_UPLOAD_CTX; - mgaXMesaSetFrontClipRects( mmesa ); - return GL_TRUE; - } - else if (mode == GL_BACK_LEFT) - { - mmesa->drawOffset = mmesa->mgaScreen->backOffset; - mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->backOffset; - mmesa->dirty |= MGA_UPLOAD_CTX; - mgaXMesaSetBackClipRects( mmesa ); - return GL_TRUE; - } - else - { - mmesa->Fallback |= MGA_FALLBACK_BUFFER; - return GL_FALSE; - } -} - static void mgaDDSetColor(GLcontext *ctx, @@ -376,7 +351,7 @@ static void mgaDDSetColor(GLcontext *ctx, { mgaContextPtr mmesa = MGA_CONTEXT(ctx); - mmesa->MonoColor = mgaPackColor( mmesa->mgaScreen->fbFormat, + mmesa->MonoColor = mgaPackColor( mmesa->mgaScreen->Attrib, r, g, b, a ); } @@ -387,7 +362,7 @@ static void mgaDDClearColor(GLcontext *ctx, { mgaContextPtr mmesa = MGA_CONTEXT(ctx); - mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->fbFormat, + mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->Attrib, r, g, b, a ); } @@ -426,6 +401,7 @@ static void mgaUpdateCull( GLcontext *ctx ) static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum mode) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL; } @@ -461,6 +437,7 @@ static GLboolean mgaDDColorMask(GLcontext *ctx, } if (mmesa->Setup[MGA_CTXREG_PLNWT] != mask) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); mmesa->Setup[MGA_CTXREG_PLNWT] = mask; MGA_CONTEXT(ctx)->new_state |= MGA_NEW_MASK; mmesa->dirty |= MGA_UPLOAD_CTX; @@ -470,6 +447,85 @@ static GLboolean mgaDDColorMask(GLcontext *ctx, } /* ============================================================= + * Polygon stipple + * + * The mga supports a subset of possible 4x4 stipples natively, GL + * wants 32x32. Fortunately stipple is usually a repeating pattern. + * Could also consider using a multitexturing mechanism for this, but + * that has real issues, too. + */ +static int mgaStipples[16] = { + 0xffff, + 0xa5a5, + 0x5a5a, + 0xa0a0, + 0x5050, + 0x0a0a, + 0x0505, + 0x8020, + 0x0401, + 0x1040, + 0x0208, + 0x0802, + 0x4010, + 0x0104, + 0x2080, + 0x0000 +}; + +static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i,j,k; + int active = (ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON); + GLuint stipple; + + FLUSH_BATCH(mmesa); + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + + if (active) { + mmesa->dirty |= MGA_UPLOAD_CTX; + mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20); + } + + p[0] = mask[0] & 0xf; p[0] |= p[0] << 4; + p[1] = mask[4] & 0xf; p[1] |= p[1] << 4; + p[2] = mask[8] & 0xf; p[2] |= p[2] << 4; + p[3] = mask[12] & 0xf; p[3] |= p[3] << 4; + + for (k = 0 ; k < 8 ; k++) + for (j = 0 ; j < 4; j++) + for (i = 0 ; i < 4 ; i++) + if (*m++ != p[j]) { + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + return; + } + + stipple = ( ((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | + ((p[3] & 0xf) << 12) ); + + for (i = 0 ; i < 16 ; i++) + if (mgaStipples[i] == stipple) { + mmesa->poly_stipple = i<<20; + break; + } + + if (i == 16) { + ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE; + return; + } + + if (active) { + mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20); + mmesa->Setup[MGA_CTXREG_DWGCTL] |= mmesa->poly_stipple; + } +} + +/* ============================================================= */ @@ -477,15 +533,16 @@ static GLboolean mgaDDColorMask(GLcontext *ctx, static void mgaDDPrintDirty( 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 & MGA_REQUIRE_QUIESCENT) ? "req-quiescent, " : "", + (state & MGA_WAIT_AGE) ? "wait-age, " : "", (state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img, " : "", (state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img, " : "", (state & MGA_UPLOAD_CTX) ? "upload-ctx, " : "", (state & MGA_UPLOAD_TEX0) ? "upload-tex0, " : "", - (state & MGA_UPLOAD_TEX1) ? "upload-tex1, " : "" + (state & MGA_UPLOAD_TEX1) ? "upload-tex1, " : "", + (state & MGA_UPLOAD_PIPE) ? "upload-pipe, " : "" ); } @@ -494,7 +551,7 @@ static void mgaDDPrintDirty( const char *msg, GLuint state ) */ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) { - if (MGA_DEBUG & MGA_DEBUG_VERBOSE_MSG) + if (MGA_DEBUG & DEBUG_VERBOSE_MSG) mgaDDPrintDirty( "mgaEmitHwStateLocked", mmesa->dirty ); if ((mmesa->dirty & MGA_UPLOAD_TEX0IMAGE) && mmesa->CurrentTexObj[0]) @@ -503,27 +560,28 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) if ((mmesa->dirty & MGA_UPLOAD_TEX1IMAGE) && mmesa->CurrentTexObj[1]) mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[1]); - if (mmesa->dirty & MGA_UPLOAD_CTX) { + if (mmesa->dirty & MGA_UPLOAD_CTX) memcpy( mmesa->sarea->ContextState, mmesa->Setup, sizeof(mmesa->Setup)); - if (mmesa->CurrentTexObj[0]) + if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) memcpy(mmesa->sarea->TexState[0], mmesa->CurrentTexObj[0]->Setup, sizeof(mmesa->sarea->TexState[0])); - if (mmesa->CurrentTexObj[1]) + if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) memcpy(mmesa->sarea->TexState[1], mmesa->CurrentTexObj[1]->Setup, sizeof(mmesa->sarea->TexState[1])); - } - if (mmesa->dirty & MGA_UPLOAD_PIPE) - mmesa->sarea->WarpPipe = mmesa->setupindex & MGA_WARP_T2GZSAF; - + mmesa->sarea->WarpPipe = mmesa->setupindex & MGA_WARP_T2GZSAF; mmesa->sarea->dirty |= mmesa->dirty; - mmesa->dirty = 0; +#if 0 + fprintf(stderr, "in mgaEmitHwStateLocked: dirty now %x\n", + mmesa->sarea->dirty); +#endif + mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE); } @@ -533,29 +591,50 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) { + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + switch(cap) { case GL_ALPHA_TEST: - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; + FLUSH_BATCH( mmesa ); + mmesa->new_state |= MGA_NEW_ALPHA; break; case GL_BLEND: - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; + FLUSH_BATCH( mmesa ); + mmesa->new_state |= MGA_NEW_ALPHA; break; case GL_DEPTH_TEST: - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; + FLUSH_BATCH( mmesa ); + mmesa->new_state |= MGA_NEW_DEPTH; break; case GL_SCISSOR_TEST: - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP; + FLUSH_BATCH( mmesa ); + mmesa->scissor = state; + mmesa->new_state |= MGA_NEW_CLIP; break; case GL_FOG: - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_FOG; + FLUSH_BATCH( mmesa ); + mmesa->new_state |= MGA_NEW_FOG; break; case GL_CULL_FACE: - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL; + FLUSH_BATCH( mmesa ); + mmesa->new_state |= MGA_NEW_CULL; break; case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; + FLUSH_BATCH( mmesa ); + mmesa->new_state |= MGA_NEW_TEXTURE; + break; + case GL_POLYGON_STIPPLE: + if ((ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) && + ctx->PB->primitive == GL_POLYGON) + { + FLUSH_BATCH(mmesa); + mmesa->dirty |= MGA_UPLOAD_CTX; + mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20); + if (state) + mmesa->Setup[MGA_CTXREG_DWGCTL] |= mmesa->poly_stipple; + } break; default: ; @@ -581,6 +660,7 @@ static void mgaWarpUpdateState( GLcontext *ctx ) { mmesa->warp_pipe = index; mmesa->new_state |= MGA_NEW_WARP; + mmesa->dirty |= MGA_UPLOAD_PIPE; } } @@ -611,21 +691,15 @@ void mgaDDUpdateHwState( GLcontext *ctx ) if (new_state) { - mmesa->new_state = 0; + FLUSH_BATCH( mmesa ); - /* Emit any vertices for the current state. This will also - * push the current state into the sarea. - */ -/* mgaFlushVertices( mmesa ); */ + mmesa->new_state = 0; if (MESA_VERBOSE&VERBOSE_DRIVER) mgaDDPrintState("UpdateHwState", new_state); if (new_state & MGA_NEW_DEPTH) - { mgaUpdateZMode(ctx); - mgaDDInitDepthFuncs(ctx); - } if (new_state & MGA_NEW_ALPHA) mgaUpdateAlphaMode(ctx); @@ -641,8 +715,6 @@ void mgaDDUpdateHwState( GLcontext *ctx ) if (new_state & (MGA_NEW_WARP|MGA_NEW_TEXTURE)) mgaUpdateTextureState(ctx); - - mmesa->new_state = 0; /* tex uploads scribble newstate */ } } @@ -654,8 +726,17 @@ void mgaDDUpdateHwState( GLcontext *ctx ) void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) { - mgaFlushVertices( MGA_CONTEXT(ctx) ); - mgaUpdateCull(ctx); + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + FLUSH_BATCH( mmesa ); + mgaUpdateCull(ctx); + + if (ctx->Polygon.StippleFlag && (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE)) + { + mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20); + if (ctx->PB->primitive == GL_POLYGON) + mmesa->Setup[MGA_CTXREG_DWGCTL] |= mmesa->poly_stipple; + } } @@ -677,10 +758,16 @@ void mgaDDUpdateState( GLcontext *ctx ) /* Have to do this here to detect texture fallbacks in time: */ - if (MGA_CONTEXT(ctx)->new_state & MGA_NEW_TEXTURE) + if (mmesa->new_state & MGA_NEW_TEXTURE) mgaDDUpdateHwState( ctx ); - if (!mmesa->Fallback || mgaglx.noFallback) { + if (0) fprintf(stderr, "fallback %x indirect %x\n", mmesa->Fallback, + mmesa->IndirectTriangles); + + if (!mmesa->Fallback) { + ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + ctx->IndirectTriangles |= mmesa->IndirectTriangles; + ctx->Driver.PointsFunc=mmesa->PointsFunc; ctx->Driver.LineFunc=mmesa->LineFunc; ctx->Driver.TriangleFunc=mmesa->TriangleFunc; @@ -689,6 +776,60 @@ void mgaDDUpdateState( GLcontext *ctx ) } + +void mgaInitState( mgaContextPtr mmesa ) +{ + mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; + GLcontext *ctx = mmesa->glCtx; + + if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT) { + mmesa->draw_buffer = MGA_BACK; + mmesa->read_buffer = MGA_BACK; + mmesa->drawOffset = mmesa->mgaScreen->backOffset; + mmesa->readOffset = mmesa->mgaScreen->backOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->backOffset; + } else { + mmesa->drawOffset = mmesa->mgaScreen->frontOffset; + mmesa->readOffset = mmesa->mgaScreen->frontOffset; + mmesa->draw_buffer = MGA_FRONT; + mmesa->read_buffer = MGA_FRONT; + mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->frontOffset; + } + +/* mmesa->Setup[MGA_CTXREG_MACCESS] = mgaScreen->mAccess; */ +/* mmesa->Setup[MGA_CTXREG_DWGCTL] = ( DC_clipdis_disable | */ +/* (0xC << DC_bop_SHIFT) | */ +/* DC_shftzero_enable | */ +/* DC_zmode_nozcmp | */ +/* DC_atype_zi ); */ + + + mmesa->Setup[MGA_CTXREG_MACCESS] = 0x1; + mmesa->Setup[MGA_CTXREG_DWGCTL] = 0xc4074; + + + mmesa->Setup[MGA_CTXREG_PLNWT] = ~0; + mmesa->Setup[MGA_CTXREG_ALPHACTRL] = ( AC_src_one | + AC_dst_zero | + AC_amode_FCOL | + AC_astipple_disable | + AC_aten_disable | + AC_atmode_noacmp | + AC_alphasel_fromtex ); + + mmesa->Setup[MGA_CTXREG_FOGCOLOR] = + MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F), + (GLubyte)(ctx->Fog.Color[1]*255.0F), + (GLubyte)(ctx->Fog.Color[2]*255.0F)); + + mmesa->Setup[MGA_CTXREG_WFLAG] = 0; + mmesa->Setup[MGA_CTXREG_TDUAL0] = 0; + mmesa->Setup[MGA_CTXREG_TDUAL1] = 0; + mmesa->Setup[MGA_CTXREG_FCOL] = 0; + mmesa->new_state = ~0; +} + + void mgaDDInitStateFuncs( GLcontext *ctx ) { ctx->Driver.UpdateState = mgaDDUpdateState; @@ -710,11 +851,14 @@ void mgaDDInitStateFuncs( GLcontext *ctx ) ctx->Driver.RenderStart = mgaDDUpdateHwState; ctx->Driver.RenderFinish = 0; - ctx->Driver.SetBuffer = mgaDDSetBuffer; + ctx->Driver.SetDrawBuffer = mgaDDSetDrawBuffer; + ctx->Driver.SetReadBuffer = mgaDDSetReadBuffer; ctx->Driver.Color = mgaDDSetColor; ctx->Driver.ClearColor = mgaDDClearColor; ctx->Driver.Dither = mgaDDDither; + ctx->Driver.PolygonStipple = mgaDDPolygonStipple; + ctx->Driver.Index = 0; ctx->Driver.ClearIndex = 0; ctx->Driver.IndexMask = 0; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.h b/xc/lib/GL/mesa/src/drv/mga/mgastate.h index 5ada1b23c..ac92cb0c2 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.h @@ -7,9 +7,10 @@ extern void mgaDDUpdateHwState( GLcontext *ctx ); extern void mgaDDUpdateState( GLcontext *ctx ); extern void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ); -/* reprograms the current registers without updating them, used to -reset state after a dma buffer overflow */ -void mgaUpdateRegs( GLuint regs ); +extern void mgaInitState( mgaContextPtr mmesa ); + +extern void mgaUpdateClipping(const GLcontext *ctx); + #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c index be7ad6018..3afb70bad 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c @@ -47,22 +47,25 @@ * to it. */ static void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) { - int i; if ( !t ) return; /* free the texture memory */ - mmFreeMem( t->MemBlock ); + if (t->MemBlock) { + mmFreeMem( t->MemBlock ); + t->MemBlock = 0; + + if (t->age > mmesa->dirtyAge) + mmesa->dirtyAge = t->age; + } /* free mesa's link */ - t->tObj->DriverData = NULL; + if (t->tObj) + t->tObj->DriverData = NULL; /* see if it was the driver's current object */ - for ( i = 0 ; i < 2 ; i++ ) { - if ( mmesa->CurrentTexObj[i] == t ) { - mmesa->CurrentTexObj[i] = NULL; - } - } + if (t->bound) + mmesa->CurrentTexObj[t->bound - 1] = 0; remove_from_list(t); free( t ); @@ -73,6 +76,9 @@ static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t) if (t->MemBlock) { mmFreeMem(t->MemBlock); t->MemBlock = 0; + + if (t->age > mmesa->dirtyAge) + mmesa->dirtyAge = t->age; } t->dirty_images = ~0; @@ -80,22 +86,76 @@ static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t) } -void mgaResetGlobalLRU( mgaContextPtr mmesa ) +static void mgaPrintLocalLRU( mgaContextPtr mmesa, int heap ) +{ + mgaTextureObjectPtr t; + int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); + + fprintf(stderr, "\nLocal LRU, heap %d:\n", heap); + + foreach( t, &(mmesa->TexObjList[heap]) ) { + if (!t->tObj) + fprintf(stderr, "Placeholder %d at %x sz %x\n", + t->MemBlock->ofs / sz, + t->MemBlock->ofs, + t->MemBlock->size); + else + fprintf(stderr, "Texture (bound %d) at %x sz %x\n", + t->bound, + t->MemBlock->ofs, + t->MemBlock->size); + + } + + fprintf(stderr, "\n\n"); +} + +static void mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap ) +{ + int i, j; + drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; + + fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list); + + for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_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 == MGA_NR_TEX_REGIONS) break; + } + + if (j != MGA_NR_TEX_REGIONS) { + fprintf(stderr, "Loop detected in global LRU\n\n\n"); + for (i = 0 ; i < MGA_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\n"); +} + + +static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap ) { - mgaTexRegion *list = mmesa->sarea->texList; - int sz = 1 << mmesa->mgaScreen->logTextureGranularity; + drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; + int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap]; int i; + mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; + + if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap); + /* (Re)initialize the global circular LRU list. The last element * in the array (MGA_NR_TEX_REGIONS) is the sentinal. Keeping it * at the end of the array allows it to be addressed rationally * when looking up objects at a particular location in texture * memory. */ - for (i = 0 ; (i+1) * sz < mmesa->mgaScreen->textureSize ; i++) { + for (i = 0 ; (i+1) * sz <= mmesa->mgaScreen->textureSize[heap] ; i++) { list[i].prev = i-1; list[i].next = i+1; - list[i].age = 0; + list[i].age = mmesa->sarea->texAge[heap]; } i--; @@ -104,30 +164,41 @@ void mgaResetGlobalLRU( mgaContextPtr mmesa ) list[i].next = MGA_NR_TEX_REGIONS; list[MGA_NR_TEX_REGIONS].prev = i; list[MGA_NR_TEX_REGIONS].next = 0; - mmesa->sarea->texAge = 0; + } static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t ) { int i; - int logsz = mmesa->mgaScreen->logTextureGranularity; + int heap = t->heap; + int logsz = mmesa->mgaScreen->logTextureGranularity[heap]; int start = t->MemBlock->ofs >> logsz; int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - mgaTexRegion *list = mmesa->sarea->texList; + drm_mga_tex_region_t *list = mmesa->sarea->texList[heap]; - mmesa->texAge = ++mmesa->sarea->texAge; + mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; + + if (!t->MemBlock) { + fprintf(stderr, "no memblock\n\n"); + return; + } /* Update our local LRU */ - move_to_head( &(mmesa->TexObjList), t ); + move_to_head( &(mmesa->TexObjList[heap]), t ); + + + if (0) + fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list); + /* Update the global LRU */ for (i = start ; i <= end ; i++) { list[i].in_use = 1; - list[i].age = mmesa->texAge; + list[i].age = mmesa->texAge[heap]; /* remove_from_list(i) */ @@ -141,8 +212,12 @@ static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t ) list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i; list[MGA_NR_TEX_REGIONS].next = i; } -} + if (0) { + mgaPrintGlobalLRU(mmesa, t->heap); + mgaPrintLocalLRU(mmesa, t->heap); + } +} /* Called for every shared texture region which has increased in age * since we last held the lock. @@ -151,23 +226,29 @@ static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t ) * and pushes a placeholder texture onto the LRU list to represent * the other client's textures. */ -void mgaTexturesGone( mgaContextPtr mmesa, - GLuint offset, - GLuint size, - GLuint in_use ) +static void mgaTexturesGone( mgaContextPtr mmesa, + GLuint heap, + GLuint offset, + GLuint size, + GLuint in_use ) { mgaTextureObjectPtr t, tmp; - - foreach_s ( t, tmp, &mmesa->TexObjList ) { + + + + foreach_s ( t, tmp, &(mmesa->TexObjList[heap]) ) { if (t->MemBlock->ofs >= offset + size || t->MemBlock->ofs + t->MemBlock->size <= offset) continue; + + + /* It overlaps - kick it off. Need to hold onto the currently bound * objects, however. */ - if (t == mmesa->CurrentTexObj[0] || t == mmesa->CurrentTexObj[1]) + if (t->bound) mgaSwapOutTexObj( mmesa, t ); else mgaDestroyTexObj( mmesa, t ); @@ -178,12 +259,54 @@ void mgaTexturesGone( mgaContextPtr mmesa, t = (mgaTextureObjectPtr) calloc(1,sizeof(*t)); if (!t) return; - t->MemBlock = mmAllocMem( mmesa->texHeap, size, 0, offset); - insert_at_head( &mmesa->TexObjList, t ); + t->heap = heap; + t->MemBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset); + if (!t->MemBlock) { + fprintf(stderr, "Couldn't alloc placeholder sz %x ofs %x\n", + (int)size, (int)offset); + mmDumpMemInfo( mmesa->texHeap[heap]); + return; + } + insert_at_head( &(mmesa->TexObjList[heap]), t ); } } +void mgaAgeTextures( mgaContextPtr mmesa, int heap ) +{ + drm_mga_sarea_t *sarea = mmesa->sarea; + int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); + int idx, nr = 0; + + /* Have to go right round from the back to ensure stuff ends up + * LRU in our local list... Fix with a cursor pointer. + */ + for (idx = sarea->texList[heap][MGA_NR_TEX_REGIONS].prev ; + idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ; + idx = sarea->texList[heap][idx].prev, nr++) + { + if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) { + mgaTexturesGone(mmesa, heap, idx * sz, sz, 1); + } + } + + if (nr == MGA_NR_TEX_REGIONS) { + mgaTexturesGone(mmesa, heap, 0, + mmesa->mgaScreen->textureSize[heap], 0); + mgaResetGlobalLRU( mmesa, heap ); + } + + + if (0) { + mgaPrintGlobalLRU( mmesa, heap ); + mgaPrintLocalLRU( mmesa, heap ); + } + + mmesa->texAge[heap] = sarea->texAge[heap]; + mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE; +} + + /* * mgaSetTexWrappings */ @@ -281,22 +404,22 @@ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) { /* - * mgaUploadSubImage + * mgaUploadSubImageLocked * * Perform an iload based update of a resident buffer. This is used for * both initial loading of the entire image, and texSubImage updates. * * Performed with the hardware lock held. */ -static void mgaUploadSubImage( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int level, - int x, int y, int width, int height ) { +static void mgaUploadSubImageLocked( mgaContextPtr mmesa, + mgaTextureObjectPtr t, + int level, + int x, int y, int width, int height ) { int x2; int dwords; - int dstorg; + int offset; struct gl_texture_image *image; - int texelBytes, texelsPerDword, texelMaccess; + int texelBytes, texelsPerDword, texelMaccess, length; if ( level < 0 || level >= MGA_TEX_MAXLEVELS ) { mgaMsg( 1, "mgaUploadSubImage: bad level: %i\n", level ); @@ -310,15 +433,9 @@ static void mgaUploadSubImage( mgaContextPtr mmesa, } /* find the proper destination offset for this level */ - dstorg = (mmesa->mgaScreen->textureOffset + t->MemBlock->ofs + + offset = (t->MemBlock->ofs + t->offsets[level]); - /* turn on PCI/AGP if needed - if ( textureHeapPhysical ) { - dstorg |= 1 | mgaglx.use_agp; - } - */ - texelBytes = t->texelBytes; switch( texelBytes ) { case 1: @@ -363,7 +480,7 @@ static void mgaUploadSubImage( mgaContextPtr mmesa, x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1); width = x2 - x; } - + /* we may not be able to upload the entire texture in one batch due to register limits or dma buffer limits. Recursively split it up. */ @@ -374,7 +491,8 @@ static void mgaUploadSubImage( mgaContextPtr mmesa, } mgaMsg(10, "mgaUploadSubImage: recursively subdividing\n" ); - mgaUploadSubImage( mmesa, t, level, x, y, width, height >> 1 ); + mgaUploadSubImageLocked( mmesa, t, level, x, y, + width, height >> 1 ); y += ( height >> 1 ); height -= ( height >> 1 ); } @@ -385,31 +503,50 @@ static void mgaUploadSubImage( mgaContextPtr mmesa, /* bump the performance counter */ mgaglx.c_textureSwaps += ( dwords << 2 ); - -#if 0 - - /* fill in the secondary buffer with properly converted texels - from the mesa buffer */ - mgaConvertTexture( dest, texelBytes, image, x, y, width, height ); - - /* send the secondary data */ - mgaSecondaryDma( TT_BLIT, dest, dwords ); -#endif - + length = dwords * 4; + + /* Fill in the secondary buffer with properly converted texels + * from the mesa buffer. */ + if(t->heap == MGA_CARD_HEAP) { + mgaGetILoadBufferLocked( mmesa ); + mgaConvertTexture( (mgaUI32 *)mmesa->iload_buffer->address, + texelBytes, image, x, y, width, height ); + if(length < 64) length = 64; + mgaMsg(10, "TexelBytes : %d, offset: %d, length : %d\n", + texelBytes, + mmesa->mgaScreen->textureOffset[t->heap] + + offset + + y * width * 4/texelsPerDword, + length); + + mgaFireILoadLocked( mmesa, + mmesa->mgaScreen->textureOffset[t->heap] + + offset + + y * width * 4/texelsPerDword, + length); + } else { + /* This works, is slower for uploads to card space and needs + * additional synchronization with the dma stream. + */ + mgaConvertTexture( (mgaUI32 *) + (mmesa->mgaScreen->texVirtual[t->heap] + + offset + + y * width * 4/texelsPerDword), + texelBytes, image, x, y, width, height ); + } } - static void mgaUploadTexLevel( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int l ) + mgaTextureObjectPtr t, + int l ) { - mgaUploadSubImage( mmesa, - t, - l, - 0, 0, - t->tObj->Image[l]->Width, - t->tObj->Image[l]->Height); + mgaUploadSubImageLocked( mmesa, + t, + l, + 0, 0, + t->tObj->Image[l]->Width, + t->tObj->Image[l]->Height); } @@ -527,9 +664,11 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj) /* fill in our mga texture object */ t->tObj = tObj; t->ctx = mmesa; + t->age = 0; + t->bound = 0; - insert_at_tail(&(mmesa->TexObjList), t); + insert_at_tail(&(mmesa->SwappedOut), t); t->MemBlock = 0; @@ -596,34 +735,61 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj) tObj->DriverData = t; } +static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ + /* NOT DONE */ +} -int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t ) { + return 0; +} + +int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ) +{ + int heap; int i; int ofs; mgaglx.c_textureSwaps++; + heap = t->heap = mgaChooseTexHeap( mmesa, t ); + /* Do we need to eject LRU texture objects? */ if (!t->MemBlock) { while (1) { - t->MemBlock = mmAllocMem( mmesa->texHeap, t->totalSize, 12, 0 ); + mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev; + + t->MemBlock = mmAllocMem( mmesa->texHeap[heap], + t->totalSize, + 6, 0 ); if (t->MemBlock) break; - if (mmesa->TexObjList.prev == &(mmesa->TexObjList)) { - fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); - mmDumpMemInfo( mmesa->texHeap ); + if (mmesa->TexObjList[heap].prev->bound) { + fprintf(stderr, + "Hit bound texture in upload\n"); return -1; } - mgaDestroyTexObj( mmesa, mmesa->TexObjList.prev ); + if (mmesa->TexObjList[heap].prev == + &(mmesa->TexObjList[heap])) + { + fprintf(stderr, "Failed to upload texture, " + "sz %d\n", t->totalSize); + mmDumpMemInfo( mmesa->texHeap[heap] ); + return -1; + } + + mgaDestroyTexObj( mmesa, tmp ); } - ofs = t->MemBlock->ofs; + ofs = t->MemBlock->ofs + + mmesa->mgaScreen->textureOffset[heap] + ; t->Setup[MGA_TEXREG_ORG] = ofs; t->Setup[MGA_TEXREG_ORG1] = ofs + t->offsets[1]; @@ -638,8 +804,16 @@ int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ) */ mgaUpdateTexLRU( mmesa, t ); + + if (MGA_DEBUG&DEBUG_VERBOSE_LRU) + fprintf(stderr, "dispatch age: %d age freed memory: %d\n", + GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge); + + if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa)) + mgaWaitAgeLocked( mmesa, mmesa->dirtyAge ); + if (t->dirty_images) { - if (MGA_DEBUG & MGA_DEBUG_VERBOSE_MSG) + if (MGA_DEBUG&DEBUG_VERBOSE_LRU) fprintf(stderr, "*"); for (i = 0 ; i <= t->lastLevel ; i++) @@ -692,12 +866,10 @@ static void mgaUpdateTextureEnvG200( GLcontext *ctx ) } } -/* I don't have the alpha values correct yet: - */ static void mgaUpdateTextureStage( GLcontext *ctx, int unit ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaUI32 *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit]; + GLuint *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit]; GLuint source = mmesa->tmu_source[unit]; struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current; @@ -725,13 +897,13 @@ static void mgaUpdateTextureStage( GLcontext *ctx, int unit ) *reg = ( TD0_color_arg2_diffuse | TD0_color_sel_mul | TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg1); + TD0_alpha_sel_mul); else *reg = ( TD0_color_arg2_prevstage | TD0_color_alpha_prevstage | TD0_color_sel_mul | TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg1); + TD0_alpha_sel_mul); break; case GL_DECAL: *reg = (TD0_color_arg2_fcol | @@ -751,20 +923,49 @@ static void mgaUpdateTextureStage( GLcontext *ctx, int unit ) TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg1); + TD0_alpha_sel_add); else *reg = ( TD0_color_arg2_prevstage | TD0_color_alpha_prevstage | TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg1); + TD0_alpha_sel_add); break; case GL_BLEND: - /* Use a multipass mechanism to do this: + if (0) + fprintf(stderr, "GL_BLEND unit %d flags %x\n", unit, + mmesa->blend_flags); + + if (mmesa->blend_flags) + mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + return; + + /* Do singletexture GL_BLEND with 'all ones' env-color + * by using both texture units. Multitexture gl_blend + * is a fallback. */ - mmesa->Fallback |= MGA_FALLBACK_TEXTURE; + if (unit == 0) { + /* Part 1: R1 = Rf ( 1 - Rt ) + * A1 = Af At + */ + *reg = ( TD0_color_arg2_diffuse | + TD0_color_arg1_inv_enable | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg1); + } else { + /* Part 2: R2 = R1 + Rt + * A2 = A1 + */ + *reg = ( TD0_color_arg2_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2); + } + break; default: } @@ -782,9 +983,8 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) { mgaMsg(15,"mgaUpdateTextureState %d\n", unit); /* disable texturing until it is known to be good */ - mmesa->Setup[MGA_CTXREG_DWGCTL] = - (( mmesa->Setup[MGA_CTXREG_DWGCTL] & DC_opcod_MASK ) | - DC_opcod_trap); + mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK; + mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_trap; enabled = (ctx->Texture.Enabled>>(source*4))&TEXTURE0_ANY; if (enabled != TEXTURE0_2D) { @@ -804,7 +1004,6 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) { if ( !tObj->DriverData ) { /* clear the current pointer so that texture object can be swapped out if necessary to make room */ - mmesa->CurrentTexObj[source] = NULL; mgaCreateTexObj( mmesa, tObj ); if ( !tObj->DriverData ) { @@ -815,9 +1014,8 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) { } /* we definately have a valid texture now */ - mmesa->Setup[MGA_CTXREG_DWGCTL] = - (( mmesa->Setup[MGA_CTXREG_DWGCTL] & DC_opcod_MASK ) | - DC_opcod_texture_trap); + mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK; + mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_texture_trap; t = (mgaTextureObjectPtr)tObj->DriverData; @@ -825,6 +1023,11 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) { mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << unit); mmesa->CurrentTexObj[unit] = t; + t->bound = unit+1; + + if (t->MemBlock) + mgaUpdateTexLRU( mmesa, t ); + t->Setup[MGA_TEXREG_CTL2] &= ~TMC_dualtex_enable; if (ctx->Texture.Enabled == (TEXTURE0_2D|TEXTURE1_2D)) @@ -848,23 +1051,31 @@ void mgaUpdateTextureState( GLcontext *ctx ) mgaContextPtr mmesa = MGA_CONTEXT( ctx ); mmesa->Fallback &= ~MGA_FALLBACK_TEXTURE; + if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->bound = 0; + if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->bound = 0; + mmesa->CurrentTexObj[0] = 0; + mmesa->CurrentTexObj[1] = 0; + if (MGA_IS_G400(mmesa)) { mgaUpdateTextureObject( ctx, 0 ); mgaUpdateTextureStage( ctx, 0 ); - mmesa->Setup[MGA_CTXREG_TDUAL1] = mmesa->Setup[MGA_CTXREG_TDUAL0]; + mmesa->Setup[MGA_CTXREG_TDUAL1] = + mmesa->Setup[MGA_CTXREG_TDUAL0]; if (mmesa->multitex) { mgaUpdateTextureObject( ctx, 1 ); mgaUpdateTextureStage( ctx, 1 ); } + + mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1; } else { mgaUpdateTextureObject( ctx, 0 ); - mgaUpdateTextureEnvG200( ctx ); + mgaUpdateTextureEnvG200( ctx ); } /* schedule the register writes */ - mmesa->dirty |= MGA_UPLOAD_CTX; + mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_TEX0; } @@ -880,14 +1091,57 @@ Driver functions called directly from mesa /* * mgaTexEnv */ -void mgaTexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param ) { +void mgaTexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); mgaMsg( 10, "mgaTexEnv( %i )\n", pname ); + if (pname == GL_TEXTURE_ENV_MODE) { /* force the texture state to be updated */ - MGA_CONTEXT(ctx)->CurrentTexObj[0] = 0; + FLUSH_BATCH( MGA_CONTEXT(ctx) ); MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; } + else if (pname == GL_TEXTURE_ENV_COLOR) + { + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + GLfloat *fc = texUnit->EnvColor; + GLubyte c[4]; + GLuint col; + + + c[0] = fc[0]; + c[1] = fc[1]; + c[2] = fc[2]; + c[3] = fc[3]; + + /* No alpha at 16bpp? + */ + col = mgaPackColor( mmesa->mgaScreen->Attrib, + c[0], c[1], c[2], c[3] ); + + mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]); + + if (mmesa->Setup[MGA_CTXREG_FCOL] != col) { + FLUSH_BATCH(mmesa); + mmesa->Setup[MGA_CTXREG_FCOL] = col; + mmesa->dirty |= MGA_UPLOAD_CTX; + + mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR; + + /* Actually just require all four components to be + * equal. This permits a single-pass GL_BLEND. + * + * More complex multitexture/multipass fallbacks + * for blend can be done later. + */ + if (mmesa->envcolor != 0x0 && + mmesa->envcolor != 0xffffffff) + mmesa->blend_flags |= MGA_BLEND_ENV_COLOR; + } + } + } /* @@ -907,6 +1161,7 @@ void mgaTexImage( GLcontext *ctx, GLenum target, mgaUpdateTextureState time. */ t = (mgaTextureObjectPtr) tObj->DriverData; if ( t ) { + if (t->bound) FLUSH_BATCH(mmesa); /* if this is the current object, it will force an update */ mgaDestroyTexObj( mmesa, t ); mmesa->new_state |= MGA_NEW_TEXTURE; @@ -936,6 +1191,7 @@ void mgaTexSubImage( GLcontext *ctx, GLenum target, mgaUpdateTextureState time. */ t = (mgaTextureObjectPtr) tObj->DriverData; if ( t ) { + if (t->bound) FLUSH_BATCH(mmesa); /* if this is the current object, it will force an update */ mgaDestroyTexObj( mmesa, t ); mmesa->new_state |= MGA_NEW_TEXTURE; @@ -956,7 +1212,9 @@ void mgaTexSubImage( GLcontext *ctx, GLenum target, */ void mgaTexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) { + GLenum pname, const GLfloat *params ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); mgaTextureObjectPtr t; mgaMsg( 10, "mgaTexParameter( %p, %i )\n", tObj, pname ); @@ -973,52 +1231,68 @@ void mgaTexParameter( GLcontext *ctx, GLenum target, switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: + if (t->bound) FLUSH_BATCH(mmesa); mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: + if (t->bound) FLUSH_BATCH(mmesa); mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT); break; case GL_TEXTURE_BORDER_COLOR: + if (t->bound) FLUSH_BATCH(mmesa); mgaSetTexBorderColor(t,tObj->BorderColor); break; default: return; } - /* force the texture state to be updated */ - MGA_CONTEXT(ctx)->CurrentTexObj[0] = NULL; - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; + + mmesa->new_state |= MGA_NEW_TEXTURE; } /* * mgaBindTexture */ void mgaBindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj ) { + struct gl_texture_object *tObj ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); mgaMsg( 10, "mgaBindTexture( %p )\n", tObj ); - + + FLUSH_BATCH(mmesa); + + if (mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]) { + mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0; + mmesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0; + } + /* force the texture state to be updated */ - MGA_CONTEXT(ctx)->CurrentTexObj[0] = NULL; MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; } /* * mgaDeleteTexture */ -void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { +void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData; mgaMsg( 10, "mgaDeleteTexture( %p )\n", tObj ); - /* delete our driver data */ - if ( tObj->DriverData ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaDestroyTexObj( mmesa, - (mgaTextureObjectPtr)(tObj->DriverData) ); + if ( t ) { + if (t->bound) { + FLUSH_BATCH(mmesa); + mmesa->CurrentTexObj[t->bound-1] = 0; + mmesa->new_state |= MGA_NEW_TEXTURE; + } + + mgaDestroyTexObj( mmesa, t ); mmesa->new_state |= MGA_NEW_TEXTURE; } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.h b/xc/lib/GL/mesa/src/drv/mga/mgatex.h index 1e8e7e86f..7873146c0 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.h @@ -28,7 +28,6 @@ #ifndef MGATEX_INC #define MGATEX_INC -#include "mga_drm_public.h" #include "types.h" #include "mgacommon.h" #include "mm.h" @@ -48,7 +47,9 @@ typedef struct mga_texture_object_s { mgaUI32 dirty_images; mgaUI32 totalSize; int texelBytes; - mgaUI32 age; + mgaUI32 age; + int bound; + int heap; /* agp or card */ mgaUI32 Setup[MGA_TEX_SETUP_SIZE]; } mgaTextureObject_t; @@ -96,7 +97,7 @@ void mgaUpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj ); GLboolean mgaIsTextureResident( GLcontext *ctx, struct gl_texture_object *t ); -void mgaConvertTexture( mgaUI32 *destPtr, int texelBytes, +void mgaConvertTexture( mgaUI32 *dest, int texelBytes, struct gl_texture_image *image, int x, int y, int width, int height ); @@ -107,9 +108,7 @@ int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ); -void mgaResetGlobalLRU( mgaContextPtr mmesa ); -void mgaTexturesGone( mgaContextPtr mmesa, GLuint offset, - GLuint size, GLuint in_use ); +void mgaAgeTextures( mgaContextPtr mmesa, int heap ); void mgaDDInitTextureFuncs( GLcontext *ctx ); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c index bd8ef083f..b83aaf2ea 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c @@ -27,6 +27,7 @@ #include <stdio.h> #include <math.h> +#include "types.h" #include "vb.h" #include "pipeline.h" @@ -122,34 +123,14 @@ void mgaDDTrifuncInit() init_twoside_offset(); init_twoside_offset_flat(); - /* Hmmm... - */ - for (i = 0 ; i < 0x20 ; i++) { - if (i & ~MGA_FLAT_BIT) { - points_tab[i] = points_tab[i&MGA_FLAT_BIT]; - line_tab[i] = line_tab[i&MGA_FLAT_BIT]; - } - } - for (i = 0 ; i < 0x20 ; i++) - if ((i & (MGA_NODRAW_BIT|MGA_FALLBACK_BIT)) == MGA_NODRAW_BIT || - mgaglx.nullprims) + if ((i & (MGA_NODRAW_BIT|MGA_FALLBACK_BIT)) == MGA_NODRAW_BIT) { quad_tab[i] = mga_null_quad; tri_tab[i] = mga_null_triangle; line_tab[i] = mga_null_line; points_tab[i] = mga_null_points; } - - if (mgaglx.noFallback) { - for (i = 0 ; i < 0x10 ; i++) { - points_tab[i|MGA_FALLBACK_BIT] = points_tab[i]; - line_tab[i|MGA_FALLBACK_BIT] = line_tab[i]; - tri_tab[i|MGA_FALLBACK_BIT] = tri_tab[i]; - quad_tab[i|MGA_FALLBACK_BIT] = quad_tab[i]; - } - } - } @@ -162,50 +143,53 @@ void mgaDDChooseRenderState( GLcontext *ctx ) mgaContextPtr mmesa = MGA_CONTEXT( ctx ); GLuint flags = ctx->TriangleCaps; - ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + if (mmesa->Fallback) + return; + + mmesa->IndirectTriangles &= ~DD_SW_RASTERIZE; if (flags) { GLuint ind = 0; GLuint shared = 0; - GLuint fallback = MGA_FALLBACK_BIT; - - if (mgaglx.noFallback) fallback = 0; if (flags & DD_Z_NEVER) shared |= MGA_NODRAW_BIT; if (flags & DD_FLATSHADE) shared |= MGA_FLAT_BIT; - if (flags & DD_MULTIDRAW) shared |= fallback; - if (flags & (DD_SELECT|DD_FEEDBACK)) shared |= MGA_FALLBACK_BIT; + if (flags & (DD_MULTIDRAW| + DD_SELECT| + DD_FEEDBACK)) shared |= MGA_FALLBACK_BIT; if (flags & DD_STENCIL) shared |= MGA_FALLBACK_BIT; ind = shared; if (flags & DD_POINT_SMOOTH) ind |= MGA_ANTIALIAS_BIT; - if (flags & DD_POINT_ATTEN) ind |= fallback; mmesa->renderindex = ind; mmesa->PointsFunc = points_tab[ind]; if (ind & MGA_FALLBACK_BIT) - ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + mmesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE; ind = shared; if (flags & DD_LINE_SMOOTH) ind |= MGA_ANTIALIAS_BIT; - if (flags & DD_LINE_STIPPLE) ind |= fallback; + if (flags & DD_LINE_STIPPLE) ind |= MGA_FALLBACK_BIT; mmesa->renderindex |= ind; mmesa->LineFunc = line_tab[ind]; if (ind & MGA_FALLBACK_BIT) - ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE; + mmesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE; ind = shared; if (flags & DD_TRI_SMOOTH) ind |= MGA_ANTIALIAS_BIT; if (flags & DD_TRI_OFFSET) ind |= MGA_OFFSET_BIT; if (flags & DD_TRI_LIGHT_TWOSIDE) ind |= MGA_TWOSIDE_BIT; - if (flags & (DD_TRI_UNFILLED|DD_TRI_STIPPLE)) ind |= fallback; + if (flags & DD_TRI_UNFILLED) ind |= MGA_FALLBACK_BIT; + if ((flags & DD_TRI_STIPPLE) && + (ctx->IndirectTriangles & DD_TRI_STIPPLE)) ind |= MGA_FALLBACK_BIT; mmesa->renderindex |= ind; mmesa->TriangleFunc = tri_tab[ind]; mmesa->QuadFunc = quad_tab[ind]; if (ind & MGA_FALLBACK_BIT) - ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | DD_QUAD_SW_RASTERIZE); + mmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | + DD_QUAD_SW_RASTERIZE); } else if (mmesa->renderindex) { diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.h b/xc/lib/GL/mesa/src/drv/mga/mgatris.h index 3b41900f1..dcf697409 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.h @@ -34,26 +34,16 @@ extern void mgaDDTrifuncInit( void ); /* Todo: - * - multidraw, ... * - Antialiasing (?) * - line and polygon stipple - * - select and feedback * - stencil - * - point parameters - * - */ #define MGA_ANTIALIAS_BIT 0 /* ignored for now, no fallback */ -#define MGA_FLAT_BIT 0x1 -#define MGA_OFFSET_BIT 0x2 /* 3.1 only */ -#define MGA_TWOSIDE_BIT 0x4 /* 3.1 only */ -#define MGA_NODRAW_BIT 0x8 -#define MGA_FALLBACK_BIT 0x10 - -/* Not in use: - */ -#define MGA_FEEDBACK_BIT 0x20 -#define MGA_SELECT_BIT 0x40 -#define MGA_POINT_PARAM_BIT 0x80 /* not needed? */ +#define MGA_FLAT_BIT 0x1 +#define MGA_OFFSET_BIT 0x2 +#define MGA_TWOSIDE_BIT 0x4 +#define MGA_NODRAW_BIT 0x8 +#define MGA_FALLBACK_BIT 0x10 diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h index ac5a545d2..ba2410914 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h @@ -98,8 +98,6 @@ static void TAG(quad)( GLcontext *ctx, GLuint v0, } -#if ((IND & ~MGA_FLAT_BIT) == 0) - static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); @@ -131,7 +129,6 @@ static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) mga_draw_point( mmesa, &mgaVB[i], sz ); } -#endif static void TAG(init)( void ) @@ -139,10 +136,9 @@ static void TAG(init)( void ) tri_tab[IND] = TAG(triangle); quad_tab[IND] = TAG(quad); -#if ((IND & ~MGA_FLAT_BIT) == 0) line_tab[IND] = TAG(line); points_tab[IND] = TAG(points); -#endif + } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c index f78c542c8..0b703a184 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c @@ -260,11 +260,21 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx) mmesa->tex_dest[0] = MGA_TEX0_BIT; mmesa->tex_dest[1] = MGA_TEX1_BIT; mmesa->multitex = 0; + mmesa->blend_flags &= ~MGA_BLEND_MULTITEX; if (ctx->Texture.Enabled & 0xf) { if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE) funcindex &= ~MGA_RGBA_BIT; + if (ctx->Texture.Unit[0].EnvMode == GL_BLEND && + mmesa->envcolor) + { + mmesa->multitex = 1; + mmesa->vertsize = 10; + mmesa->tmu_source[1] = 0; + funcindex |= MGA_TEX1_BIT; + } + funcindex |= MGA_TEX0_BIT; } @@ -272,7 +282,8 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx) if (ctx->Texture.Enabled & 0xf) { mmesa->multitex = 1; mmesa->vertsize = 10; - funcindex |= MGA_TEX1_BIT; + mmesa->blend_flags |= MGA_BLEND_MULTITEX; + funcindex |= MGA_TEX1_BIT; } else { /* Just a funny way of doing single texturing */ @@ -281,11 +292,25 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx) if (ctx->Texture.Unit[1].EnvMode == GL_REPLACE) funcindex &= ~MGA_RGBA_BIT; + + if (ctx->Texture.Unit[0].EnvMode == GL_BLEND && + mmesa->envcolor) + { + mmesa->multitex = 1; + mmesa->vertsize = 10; + mmesa->tmu_source[1] = 1; + funcindex |= MGA_TEX1_BIT; + } funcindex |= MGA_TEX0_BIT; } } + /* Not really a good place to do this - need to make the mga state + * management code more event-driven so this can be calculated for + * free. + */ + if (ctx->Color.BlendEnabled) funcindex |= MGA_ALPHA_BIT; @@ -298,6 +323,7 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx) if (0) mgaPrintSetupFlags("xsmesa: full setup function", funcindex); + mmesa->dirty |= MGA_UPLOAD_PIPE; mmesa->setupindex = funcindex; /* Called by mesa's clip functons: @@ -477,17 +503,3 @@ void mgaDDUnregisterVB( struct vertex_buffer *VB ) } -mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ) -{ - int bytes = dwords * 4; - mgaUI32 *head; - - if (mmesa->dma_buffer->used + bytes > mmesa->dma_buffer->total) - mgaFlushVertices( mmesa ); - - head = (mgaUI32 *)((char *)mmesa->dma_buffer->address + - mmesa->dma_buffer->used); - - mmesa->dma_buffer->used += bytes; - return head; -} diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.h b/xc/lib/GL/mesa/src/drv/mga/mgavb.h index 8d7c65207..675c1779c 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.h @@ -27,6 +27,7 @@ #ifndef MGAVB_INC #define MGAVB_INC +#include "types.h" #include "vb.h" #include "mgacommon.h" @@ -126,7 +127,4 @@ extern void mgaDDResizeVB( struct vertex_buffer *VB, GLuint size ); extern void mgaDDSetupInit( void ); -extern mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ); - - #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile index 982ca93e8..a8fe76fe7 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile +++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile @@ -278,7 +278,7 @@ XCOMM Disabling 3Dnow code for the time being. SRCS = $(DRISRCS) $(DRMSRCS) $(TDFXSRCS) $(MESASRCS) $(ASMSRCS) OBJS = $(DRIOBJS) $(DRMOBJS) $(TDFXOBJS) $(MESAOBJS) $(ASMOBJS) -REQUIREDLIBS += -lglide3x +REQUIREDLIBS += -lglide3x -lm #if !GlxUseBuiltInDRIDriver #undef DoNormalLib NormalLibGlx diff --git a/xc/programs/Xserver/GL/dri/dri.c b/xc/programs/Xserver/GL/dri/dri.c index 68e638f27..22780d753 100644 --- a/xc/programs/Xserver/GL/dri/dri.c +++ b/xc/programs/Xserver/GL/dri/dri.c @@ -120,6 +120,7 @@ DRIScreenInit( pDRIPriv->directRenderingSupport = TRUE; pDRIPriv->pDriverInfo = pDRIInfo; + pDRIPriv->nrWindows = 0; /* setup device independent direct rendering memory maps */ @@ -334,8 +335,9 @@ DRIFinishScreenInit(ScreenPtr pScreen) pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow; pScreen->CopyWindow = pDRIInfo->wrap.CopyWindow; } - miClipNotify(DRIClipNotify); - + if (pDRIInfo->wrap.ClipNotify) + miClipNotify(pDRIInfo->wrap.ClipNotify); + DRIDrvMsg(pScreen->myNum, X_INFO, "[DRI] installation complete\n"); return TRUE; @@ -492,8 +494,6 @@ DRICloseConnection( ScreenPtr pScreen ) { - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - return TRUE; } @@ -652,7 +652,7 @@ DRICreateContext( visual, *pHWContext, *pVisualConfigPriv, - contextStore))) { + (int)contextStore))) { DRIDestroyContextPriv(pDRIContextPriv); return FALSE; } @@ -689,12 +689,72 @@ DRIContextPrivDelete( if (pDRIPriv->pDriverInfo->DestroyContext) { contextStore=DRIGetContextStore(pDRIContextPriv); (pDRIPriv->pDriverInfo->DestroyContext)(pDRIContextPriv->pScreen, - pDRIContextPriv->hwContext, - contextStore); + pDRIContextPriv->hwContext, + (int)contextStore); } return DRIDestroyContextPriv(pDRIContextPriv); } + +/* This walks the drawable timestamp array and invalidates all of them + * in the case of transition from private to shared backbuffers. It's + * not necessary for correctness, because DRIClipNotify gets called in + * time to prevent any conflict, but the transition from + * shared->private is sometimes missed if we don't do this. + */ +static void +DRIClipNotifyAllDrawables( ScreenPtr pScreen ) +{ + int i; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) { + pDRIPriv->pSAREA->drawableTable[i].stamp = DRIDrawableValidationStamp++; + } +} + + +static void +DRITransitionToSharedBuffers( ScreenPtr pScreen ) +{ +/* ErrorF("DRITransitionToSharedBuffers\n"); */ + DRIClipNotifyAllDrawables( pScreen ); +} + + +static void +DRITransitionToPrivateBuffers( ScreenPtr pScreen ) +{ +/* ErrorF("DRITransitionToPrivateBuffers\n"); */ + DRIClipNotifyAllDrawables( pScreen ); +} + + +static void +DRITransitionTo3d( ScreenPtr pScreen ) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo; + +/* ErrorF("DRITransitionTo3d\n"); */ + + if (pDRIInfo->TransitionTo3d) + pDRIInfo->TransitionTo3d( pScreen ); +} + +static void +DRITransitionTo2d( ScreenPtr pScreen ) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo; + +/* ErrorF("DRITransitionTo2d\n"); */ + + if (pDRIInfo->TransitionTo2d) + pDRIInfo->TransitionTo2d( pScreen ); +} + + Bool DRICreateDrawable( ScreenPtr pScreen, @@ -734,6 +794,17 @@ DRICreateDrawable( pWin->devPrivates[DRIWindowPrivIndex].ptr = (pointer)pDRIDrawablePriv; + switch (++pDRIPriv->nrWindows) { + case 1: + DRITransitionTo3d( pScreen ); + break; + case 2: + DRITransitionToSharedBuffers( pScreen ); + break; + default: + break; + } + /* track this in case this window is destroyed */ AddResource(id, DRIDrawablePrivResType, (pointer)pWin); } @@ -756,13 +827,14 @@ DRIDestroyDrawable( DRIDrawablePrivPtr pDRIDrawablePriv; WindowPtr pWin; + if (pDrawable->type == DRAWABLE_WINDOW) { pWin = (WindowPtr)pDrawable; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); pDRIDrawablePriv->refCount--; if (pDRIDrawablePriv->refCount <= 0) { /* This calls back DRIDrawablePrivDelete which frees private area */ - FreeResourceByType(id, DRIDrawablePrivResType, FALSE); + FreeResourceByType(id, DRIDrawablePrivResType, FALSE); } } else { /* pixmap (or for GLX 1.3, a PBuffer) */ @@ -798,6 +870,17 @@ DRIDrawablePrivDelete( } xfree(pDRIDrawablePriv); pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL; + + switch (--pDRIPriv->nrWindows) { + case 0: + DRITransitionTo2d( pDrawable->pScreen ); + break; + case 1: + DRITransitionToPrivateBuffers( pDrawable->pScreen ); + break; + default: + break; + } } else { /* pixmap (or for GLX 1.3, a PBuffer) */ /* NOT_DONE */ @@ -818,7 +901,11 @@ DRIGetDrawableInfo( int* W, int* H, int* numClipRects, - XF86DRIClipRectPtr* pClipRects + XF86DRIClipRectPtr* pClipRects, + int* backX, + int* backY, + int* numBackClipRects, + XF86DRIClipRectPtr* pBackClipRects ) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); @@ -907,6 +994,35 @@ DRIGetDrawableInfo( *H = (int)(pWin->drawable.height); *numClipRects = REGION_NUM_RECTS(&pWin->clipList); *pClipRects = (XF86DRIClipRectPtr)REGION_RECTS(&pWin->clipList); + + *backX = *X; + *backY = *Y; + + if (pDRIPriv->nrWindows == 1 && *numClipRects) { + /* Use a single cliprect. */ + + int x0 = *X; + int y0 = *Y; + int x1 = x0 + *W; + int y1 = y0 + *H; + + if (x0 < 0) x0 = 0; + if (y0 < 0) y0 = 0; + if (x1 > pScreen->width-1) x1 = pScreen->width-1; + if (y1 > pScreen->height-1) y1 = pScreen->height-1; + + pDRIPriv->private_buffer_rect.x1 = x0; + pDRIPriv->private_buffer_rect.y1 = y0; + pDRIPriv->private_buffer_rect.x2 = x1; + pDRIPriv->private_buffer_rect.y2 = y1; + + *numBackClipRects = 1; + *pBackClipRects = &(pDRIPriv->private_buffer_rect); + } else { + /* Use the frontbuffer cliprects for back buffers. */ + *numBackClipRects = 0; + *pBackClipRects = 0; + } } else { /* Not a DRIDrawable */ @@ -961,6 +1077,10 @@ DRICreateInfoRec(void) inforec->wrap.CopyWindow = DRICopyWindow; inforec->wrap.ValidateTree = DRIValidateTree; inforec->wrap.PostValidateTree = DRIPostValidateTree; + inforec->wrap.ClipNotify = DRIClipNotify; + + inforec->TransitionTo2d = 0; + inforec->TransitionTo3d = 0; return inforec; } @@ -972,6 +1092,7 @@ DRIDestroyInfoRec(DRIInfoPtr DRIInfo) xfree((char*)DRIInfo); } + void DRIWakeupHandler( pointer wakeupData, @@ -1502,10 +1623,27 @@ DRIGetDrawableIndex( return index; } +unsigned int +DRIGetDrawableStamp( + ScreenPtr pScreen, + CARD32 drawable_index) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + return pDRIPriv->pSAREA->drawableTable[drawable_index].stamp; +} + + +void DRIPrintDrawableLock(ScreenPtr pScreen, char *msg) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + ErrorF("%s: %d\n", msg, pDRIPriv->pSAREA->drawable_lock.lock); +} + void DRILock(ScreenPtr pScreen, int flags) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - + if (!lockRefCount) DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pSAREA, pDRIPriv->myContext, flags); lockRefCount++; @@ -1532,7 +1670,7 @@ void *DRIGetSAREAPrivate(ScreenPtr pScreen) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); if (!pDRIPriv) return 0; - return ((void*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec); + return (void *)(((char*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec)); } drmContext DRIGetContext(ScreenPtr pScreen) @@ -1542,3 +1680,11 @@ drmContext DRIGetContext(ScreenPtr pScreen) return pDRIPriv->myContext; } +/* This lets get at the unwrapped functions so that they can correctly + * call the lowerlevel functions, and choose whether they will be + * called at every level of recursion (eg in validatetree). + */ +DRIWrappedFuncsRec *DRIGetWrappedFuncs( ScreenPtr pScreen ) +{ + return &(DRI_SCREEN_PRIV(pScreen)->wrap); +} diff --git a/xc/programs/Xserver/GL/dri/dri.h b/xc/programs/Xserver/GL/dri/dri.h index d82ec5359..367351836 100644 --- a/xc/programs/Xserver/GL/dri/dri.h +++ b/xc/programs/Xserver/GL/dri/dri.h @@ -69,6 +69,10 @@ typedef int DRIWindowRequests; #define DRI_3D_WINDOWS_ONLY 1 #define DRI_ALL_WINDOWS 2 + +typedef void (*ClipNotifyPtr)( WindowPtr, int, int ); + + /* * These functions can be wrapped by the DRI. Each of these have * generic default funcs (initialized in DRICreateInfoRec) and can be @@ -82,8 +86,12 @@ typedef struct { CopyWindowProcPtr CopyWindow; ValidateTreeProcPtr ValidateTree; PostValidateTreeProcPtr PostValidateTree; + ClipNotifyPtr ClipNotify; } DRIWrappedFuncsRec, *DRIWrappedFuncsPtr; + + + typedef struct { /* driver call back functions */ Bool (*CreateContext)(ScreenPtr pScreen, @@ -107,6 +115,8 @@ typedef struct { DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index); + void (*TransitionTo3d)(ScreenPtr pScreen); + void (*TransitionTo2d)(ScreenPtr pScreen); /* wrapped functions */ DRIWrappedFuncsRec wrap; @@ -185,7 +195,11 @@ Bool DRIGetDrawableInfo( int* W, int* H, int* numClipRects, - XF86DRIClipRectPtr* pClipRects + XF86DRIClipRectPtr* pClipRects, + int* backX, + int* backY, + int* numBackClipRects, + XF86DRIClipRectPtr* pBackClipRects ); Bool DRIGetDeviceInfo( ScreenPtr pScreen, @@ -199,6 +213,7 @@ Bool DRIGetDeviceInfo( DRIInfoPtr DRICreateInfoRec(void); void DRIDestroyInfoRec(DRIInfoPtr DRIInfo); Bool DRIFinishScreenInit(ScreenPtr pScreen); + void DRIWakeupHandler( pointer wakeupData, int result, @@ -246,7 +261,13 @@ CARD32 DRIGetDrawableIndex( WindowPtr pWin); void DRILock(ScreenPtr pScreen, int flags); void DRIUnlock(ScreenPtr pScreen); + +DRIWrappedFuncsRec *DRIGetWrappedFuncs( ScreenPtr pScreen ); + void *DRIGetSAREAPrivate(ScreenPtr pScreen); + +unsigned int DRIGetDrawableStamp(ScreenPtr pScreen, CARD32 drawable_index); + DRIContextPrivPtr DRICreateContextPriv(ScreenPtr pScreen, drmContextPtr pHWContext, @@ -256,6 +277,7 @@ DRICreateContextPrivFromHandle(ScreenPtr pScreen, drmContext hHWContext, DRIContextFlags flags); Bool DRIDestroyContextPriv(DRIContextPrivPtr pDRIContextPriv); +drmContext DRIGetContext(ScreenPtr pScreen); #define _DRI_H_ diff --git a/xc/programs/Xserver/GL/dri/dristruct.h b/xc/programs/Xserver/GL/dri/dristruct.h index 392be3d97..d576f40af 100644 --- a/xc/programs/Xserver/GL/dri/dristruct.h +++ b/xc/programs/Xserver/GL/dri/dristruct.h @@ -87,6 +87,8 @@ typedef struct _DRIScreenPrivRec void** hiddenContextStore; /* hidden X context */ void** partial3DContextStore; /* parital 3D context */ DRIInfoPtr pDriverInfo; + int nrWindows; + XF86DRIClipRectRec private_buffer_rect; /* management of private buffers */ DRIWrappedFuncsRec wrap; DrawablePtr DRIDrawables[SAREA_MAX_DRAWABLES]; } DRIScreenPrivRec, *DRIScreenPrivPtr; diff --git a/xc/programs/Xserver/GL/dri/xf86dri.c b/xc/programs/Xserver/GL/dri/xf86dri.c index 77f74e0a8..2619fba87 100644 --- a/xc/programs/Xserver/GL/dri/xf86dri.c +++ b/xc/programs/Xserver/GL/dri/xf86dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/GL/dri/xf86dri.c,v 1.2 1999/06/27 14:07:39 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/GL/dri/xf86dri.c,v 1.6 2000/02/23 04:46:52 martin Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -31,7 +31,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Kevin E. Martin <kevin@precisioninsight.com> * Jens Owen <jens@precisioninsight.com> * - * $PI: xc/programs/Xserver/GL/dri/xf86dri.c,v 1.20 1999/06/24 19:10:40 faith Exp $ */ #if XFree86LOADER @@ -389,6 +388,8 @@ ProcXF86DRIGetDrawableInfo( DrawablePtr pDrawable; int X, Y, W, H; XF86DRIClipRectPtr pClipRects; + XF86DRIClipRectPtr pBackClipRects; + int backX, backY; REQUEST(xXF86DRIGetDrawableInfoReq); REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq); @@ -412,7 +413,11 @@ ProcXF86DRIGetDrawableInfo( (int*)&W, (int*)&H, (int*)&rep.numClipRects, - &pClipRects)) { + &pClipRects, + &backX, + &backY, + (int*)&rep.numBackClipRects, + &pBackClipRects)) { return BadValue; } @@ -420,18 +425,32 @@ ProcXF86DRIGetDrawableInfo( rep.drawableY = Y; rep.drawableWidth = W; rep.drawableHeight = H; + rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply)); + + rep.backX = backX; + rep.backY = backY; + + if (rep.numBackClipRects) + rep.length += sizeof(XF86DRIClipRectRec) * rep.numBackClipRects; + + if (rep.numClipRects) + rep.length += sizeof(XF86DRIClipRectRec) * rep.numClipRects; + + WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep); - rep.length = 0; if (rep.numClipRects) { - rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - - SIZEOF(xGenericReply) + - sizeof(XF86DRIClipRectRec) * rep.numClipRects); + WriteToClient(client, + sizeof(XF86DRIClipRectRec) * rep.numClipRects, + (char *)pClipRects); } - WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep); - if (rep.length) { - WriteToClient(client, rep.length, (char *)pClipRects); + if (rep.numBackClipRects) { + WriteToClient(client, + sizeof(XF86DRIClipRectRec) * rep.numBackClipRects, + (char *)pBackClipRects); } + return (client->noClientException); } diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml index 5306e50a9..895ce09a7 100644 --- a/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml +++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml @@ -7,11 +7,11 @@ <article> - <title>DRI User Guide + <title>DRI Users Guide <author><htmlurl url="http://www.precisioninsight.com/" name="Precision Insight, Inc."> - <date>20 March 2000 - + <date>6 March 2000 + <ident> $XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml,v 1.3 2000/03/08 05:38:41 dawes Exp $ </ident> @@ -25,7 +25,7 @@ <bf>Copyright © 2000 by Precision Insight, Inc., Cedar Park, Texas. All Rights Reserved.</bf> -<p> + <p> <bf>Permission is granted to make and distribute verbatim copies of this document provided the copyright notice and this permission notice are preserved on all copies.</bf> @@ -60,13 +60,9 @@ software downloads. <p> This document does not cover compilation or installation of - XFree86 4.0. - It is assumed that you've already installed a Linux distribution which - includes XFree86 4.0 or that you're an experienced Linux developer - who has compiled the DRI for himself. - DRI download, compilation and installation instructions can be found - at <htmlurl url="http://dri.sourceforge.net/DRIcompile.html" - name="http://dri.sourceforge.net/DRIcompile.html"> + XFree86 4.0; + it is assumed that you've already installed a Linux distribution which + includes XFree86 4.0. <sect>Supported Hardware <p> @@ -108,13 +104,8 @@ <p> <itemize> <item>XFree86 4.0 - <item>Linux kernel 2.2.x. - Later kernels will be supported in the near future, and may be - required for some chipsets. - The DRI modules currently in the 2.3.x kernel tree will not - currently work. - DRI updates for the 2.3.x kernel series are under development - at the time of writing. + <item>Linux kernel 2.2.x (later kernels will be supported in + the near future, and may be required for some chipsets) </itemize> <p> Mesa 3.3 (beta) is included with XFree86 4.0; there is no need to @@ -130,8 +121,6 @@ <p> Before starting the X server you must install the correct kernel module for your hardware. - In the future, this should be automatically done by the system. - But until then, it must be installed manually. <p> This can be done by executing the following as root: <verb> @@ -140,17 +129,7 @@ <p> For example, on 3dfx hardware, the kernel module is called tdfx.o so you you would type insmod XXX/tdfx.o - <p> - Replace XXX with the location of DRI modules on your system. - This may vary between distributions or depend on where you - have your DRI build tree if you compiled it yourself. - <p> - If you compiled the XFree86 source tree yourself, the kernel - modules should be in - <tt>$BUILDROOT/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/</tt>. - Another place to look is - <tt>/lib/modules/</tt><em>kernel-version</em><tt>/misc/</tt> or - <tt>/lib/modules/</tt><em>kernel-version</em><tt>/dri/</tt>. + <p> Verify that the kernel module was installed by checking that /proc/dri/0 exists. @@ -269,19 +248,6 @@ The documentation included with your card should have information about maximum screen size when using 3D. - <sect1>Start-up -<p> - Start your X server in the normal way (typically startx). - If the DRM kernel module loaded correctly there will be a - message to indicate so: - <verb> - (0): [DRI] installation complete - </verb> - When the X server is running, you can use <tt>xdpyinfo</tt> to - check that the GLX, SGI-GLX and XFree86-DRI extensions have loaded. - <p> - Go to the troubleshooting section if this fails. - <sect>Using 3D Acceleration <p> @@ -538,13 +504,14 @@ <item> Older Linux OpenGL applications may have been linked against - Mesa's GL library and will not automatically use the new libGL.so. - In some cases, making symbolic links will solve the problem: + Mesa's GL library and will not automatically use libGL.so. + In some cases, making symbolic links from the Mesa GL library + to libGL.so.1 will solve the problem: <verb> ln -s libGL.so.1 libMesaGL.so.3 </verb> In other cases, the application will have to be relinked - against the new libGL.so from XFree86. + against the new XFree86 libGL.so. <P> It is reported that part of the problem is that running <tt/ldconfig/ will silently rewrite symbolic links based @@ -564,42 +531,6 @@ <sect1>3dfx Voodoo3 <p> - <sect2>Configuration -<p> - Your XF86Config file's device section must specify the - <tt>tdfx</tt> device: - <verb> - Section "Device" - Identifier "Voodoo3" - VendorName "3dfx" - Driver "tdfx" - EndSection - </verb> - The Screen section should then reference the Voodoo3 device: - <verb> - Section "Screen" - Identifier "Screen 1" - Device "Voodoo3" - Monitor "High Res Monitor" - DefaultDepth 16 - Subsection "Display" - Depth 16 - Modes "1280x1024" "1024x768" "800x600" "640x480" - ViewPort 0 0 - EndSubsection - EndSection - </verb> - <p> - The kernel module for the Voodoo3 is named <tt>tdfx.o</tt> and - must be installed with: - <verb> - insmod tdfx.o - </verb> - <p> - The DRI 3D driver for the Voodoo3 should be in - <tt>/usr/X11R6/lib/modules/dri/tdfx_dri.so</tt>. - This will be automatically loaded by libGL.so. - <sect2>Troubleshooting <p> <itemize> @@ -608,9 +539,6 @@ bit/pixel screen mode. Use <tt/xdpyinfo/ to verify that all your visuals are depth 16. Edit your XF86Config file if needed. - <item> - The <tt>/dev/3dfx</tt> device is not used for DRI; it's only for - Glide on older 3dfx hardware. </itemize> <sect2>Performance @@ -633,14 +561,10 @@ demo, may become sluggish when falling back to software rendering to render in that mode. </itemize> - <sect2>Known Problems <p> <itemize> <item> - Glide cannot be used directly; only OpenGL-based programs are - supported on the Voodoo3. - <item> SSystem has problems because of poorly set near and far clipping planes. The office.unc Performer model also suffers from this problem. @@ -649,16 +573,10 @@ <sect1>Intel i810 <p> - Information to be added in the future. - <sect1>Matrox G400 <p> - Information to be added in the future. - <sect1>ATI Rage 128 <p> - Information to be added in the future. - <sect1>3DLabs Oxygen GMX 2000 <p> The driver for this hardware was experimental and is no longer being @@ -736,9 +654,6 @@ <item>Visit the <htmlurl url="http://dri.sourceforge.net" name="DRI project on SourceForge.net"> for the latest development news about the DRI and 3D drivers. - <item>The <htmlurl url="http://dri.sourceforge.net/DRIcompile.html" - name="DRI Compilation Guide"> explains how to download, compile - and install the DRI for yourself. </itemize> <sect1>Support @@ -749,8 +664,9 @@ <htmlurl url="http://sourceforge.net/mail/?group_id=387" name="SourceForge"> is a forum for people to discuss DRI problems. <item> - In the future there may be IHV and Linux vendor support resources - for the DRI. + XXX IHV support? + <item> + XXX Linux distro support? </itemize> </article> diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c index 9acce4b54..b90ed5511 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c @@ -510,7 +510,8 @@ GLINTDRIScreenInit(ScreenPtr pScreen) if ((bufs = drmAddBufs(pGlint->drmSubFD, xf86ConfigDRI.bufs[i].count, xf86ConfigDRI.bufs[i].size, - 0 /* flags */)) <= 0) { + 0, /* flags */ + 0 /* offset */)) <= 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] failure adding %d %d byte DMA buffers\n", xf86ConfigDRI.bufs[i].count, @@ -530,7 +531,8 @@ GLINTDRIScreenInit(ScreenPtr pScreen) if ((bufs = drmAddBufs(pGlint->drmSubFD, GLINT_DRI_BUF_COUNT, GLINT_DRI_BUF_SIZE, - 0 /* flags */)) <= 0) { + 0, /* flags */ + 0 /* offset */)) <= 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] failure adding %d %d byte DMA buffers\n", GLINT_DRI_BUF_COUNT, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile index 331396f38..1a960e964 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile @@ -11,8 +11,8 @@ XCOMM # #undef BuildXF86DRI #if BuildXF86DRI -DRISRCS = i810_dri.c i810_drm.c -DRIOBJS = i810_dri.o i810_drm.o +DRISRCS = i810_dri.c +DRIOBJS = i810_dri.o DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \ -I$(XF86OSSRC)/linux/drm/kernel DRIDEFINES = $(GLX_DEFINES) @@ -63,7 +63,6 @@ InstallDriverSDKNonExecFile(i810_cursor.c,$(DRIVERSDKDIR)/drivers/i810) InstallDriverSDKNonExecFile(i810_driver.c,$(DRIVERSDKDIR)/drivers/i810) InstallDriverSDKNonExecFile(i810_dri.c,$(DRIVERSDKDIR)/drivers/i810) InstallDriverSDKNonExecFile(i810_dri.h,$(DRIVERSDKDIR)/drivers/i810) -InstallDriverSDKNonExecFile(i810_dripriv.h,$(DRIVERSDKDIR)/drivers/i810) InstallDriverSDKNonExecFile(i810_io.c,$(DRIVERSDKDIR)/drivers/i810) InstallDriverSDKNonExecFile(i810_memory.c,$(DRIVERSDKDIR)/drivers/i810) InstallDriverSDKNonExecFile(i810_wmark.c,$(DRIVERSDKDIR)/drivers/i810) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h index 6aceea540..6bb176f9f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h @@ -36,7 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _I810_H_ #define _I810_H_ - +#include "compiler.h" #include "xf86PciInfo.h" #include "xf86Pci.h" #include "i810_reg.h" @@ -211,8 +211,8 @@ typedef struct _I810Rec { extern Bool I810DRIScreenInit(ScreenPtr pScreen); extern void I810DRICloseScreen(ScreenPtr pScreen); extern Bool I810DRIFinishScreenInit(ScreenPtr pScreen); -extern Bool I810drmInitDma(ScrnInfoPtr pScrn); -extern Bool I810drmCleanupDma(ScrnInfoPtr pScrn); +extern Bool I810InitDma(ScrnInfoPtr pScrn); +extern Bool I810CleanupDma(ScrnInfoPtr pScrn); #define I810PTR(p) ((I810Ptr)((p)->driverPrivate)) #define I810REGPTR(p) (&(I810PTR(p)->ModeReg)) @@ -312,7 +312,7 @@ extern void I810EmitInvarientState(ScrnInfoPtr pScrn); /* To remove all debugging, make sure I810_DEBUG is defined as a * preprocessor symbol, and equal to zero. */ -#define I810_DEBUG 0 +#define I810_DEBUG 0 #ifndef I810_DEBUG #warning "Debugging enabled - expect reduced performance" extern int I810_DEBUG; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c index 0f67180d2..5c90fc88a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c @@ -301,13 +301,9 @@ I810Sync( ScrnInfoPtr pScrn ) #ifdef XF86DRI /* VT switching tries to do this. */ - if (!pI810->LockHeld) { + if (!pI810->LockHeld && pI810->directRenderingEnabled) { return; } - - -/* if (pI810->directRenderingEnabled) */ -/* DRIUnlockLockQueiscent( pScrn->pScreen ); */ #endif /* Send a flush instruction and then wait till the ring is empty. diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c index 5bb1b3191..48adc170a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c @@ -20,10 +20,6 @@ #include "i810.h" #include "i810_dri.h" -#include "xf86drm.h" -#include "dristruct.h" - - static char I810KernelDriverName[] = "i810"; static char I810ClientDriverName[] = "i810"; @@ -62,6 +58,29 @@ static int i810_pitch_flags[] = { 0 }; +Bool I810CleanupDma(ScrnInfoPtr pScrn) +{ + I810Ptr pI810 = I810PTR(pScrn); + Bool ret_val; + + ret_val = drmI810CleanupDma(pI810->drmSubFD); + if(ret_val == FALSE) ErrorF("I810 Dma Cleanup Failed\n"); + return ret_val; +} + +Bool I810InitDma(ScrnInfoPtr pScrn) +{ + I810Ptr pI810 = I810PTR(pScrn); + I810RingBuffer *ring = &(pI810->LpRing); + Bool ret_val; + + ret_val = drmI810InitDma(pI810->drmSubFD, ring->mem.Start, + ring->mem.End, ring->mem.Size, + 6, 5, sizeof(XF86DRISAREARec)); + if(ret_val == FALSE) ErrorF("I810 Dma Initialization Failed\n"); + return ret_val; +} + static Bool I810InitVisualConfigs(ScreenPtr pScreen) { @@ -260,8 +279,13 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) int width = pScrn->displayWidth * pI810->cpp; int i; - /* ToDo : save agpHandles? */ - +#if XFree86LOADER + /* Check that the GLX, DRI, and DRM modules have been loaded by testing + * for canonical symbols in each module. */ + if (!LoaderSymbol("GlxSetVisualConfigs")) return FALSE; + if (!LoaderSymbol("DRIScreenInit")) return FALSE; + if (!LoaderSymbol("drmAvailable")) return FALSE; +#endif pDRIInfo = DRICreateInfoRec(); if (!pDRIInfo) { @@ -302,7 +326,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) /* For now the mapping works by using a fixed size defined * in the SAREA header */ - if (sizeof(XF86DRISAREARec)+sizeof(drm_i810_sarea_t)>SAREA_MAX) { + if (sizeof(XF86DRISAREARec)+sizeof(I810SAREARec)>SAREA_MAX) { ErrorF("Data does not fit in SAREA\n"); return FALSE; } @@ -378,9 +402,10 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) * under the DRI. */ - dcacheHandle = drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL); + drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, &dcacheHandle); pI810->dcacheHandle = dcacheHandle; + ErrorF("dcacheHandle : %p\n", dcacheHandle); #define Elements(x) sizeof(x)/sizeof(*x) for (pitch_idx = 0 ; pitch_idx < Elements(i810_pitches) ; pitch_idx++) @@ -392,10 +417,12 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) "Couldn't find depth/back buffer pitch"); DRICloseScreen(pScreen); return FALSE; - } - else { - back_size = i810_pitches[pitch_idx] * pScrn->virtualY; + } else { + back_size = i810_pitches[pitch_idx] * (pScrn->virtualY + 4); + ErrorF("back_size: %d\n", back_size); + /* Round to 4k */ back_size = ((back_size + 4096 - 1) / 4096) * 4096; + ErrorF("back_size 2 : %d\n", back_size); } sysmem_size = pScrn->videoRam * 1024; @@ -411,6 +438,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) } else { sysmem_size = sysmem_size - 2*back_size; } + ErrorF("sysmem_size : %d\n", sysmem_size); sysmem_size -= 4096; if(sysmem_size > ((48*1024*1024) - 1) ) { @@ -428,6 +456,8 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) if (dcacheHandle != 0) { /* The Z buffer is always aligned to the 48 mb mark in the aperture */ + ErrorF("dcacheHandle : %p, aligned to : %lx\n", + dcacheHandle, 48*1024*1024); if(drmAgpBind(pI810->drmSubFD, dcacheHandle, 48*1024*1024) == 0) { xf86memset (&pI810->DcacheMem, 0, sizeof(I810MemRange)); @@ -454,11 +484,12 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: no dcache memory found\n"); } - agpHandle = drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL); + drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, &agpHandle); pI810->backHandle = agpHandle; if(agpHandle != 0) { /* The backbuffer is always aligned to the 56 mb mark in the aperture */ + ErrorF("agpHandle : %p, aligned to : %lx\n", agpHandle, 56*1024*1024); if(drmAgpBind(pI810->drmSubFD, agpHandle, 56*1024*1024) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bound backbuffer memory\n"); @@ -481,11 +512,14 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) if(dcacheHandle == 0) { /* The Z buffer is always aligned to the 48 mb mark in the aperture */ - agpHandle = drmAgpAlloc(pI810->drmSubFD, back_size, 0, - NULL); + drmAgpAlloc(pI810->drmSubFD, back_size, 0, + NULL, &agpHandle); pI810->zHandle = agpHandle; if(agpHandle != 0) { + ErrorF("agpHandle : %p, aligned to : %lx\n", dcacheHandle, + 48*1024*1024); + if(drmAgpBind(pI810->drmSubFD, agpHandle, 48*1024*1024) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bound depthbuffer memory\n"); pI810->DepthBuffer.Start = 48*1024*1024; @@ -510,7 +544,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) * regular framebuffer as well as texture memory. */ - agpHandle = drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL); + drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, &agpHandle); if(agpHandle == 0) { ErrorF("drmAgpAlloc failed\n"); DRICloseScreen(pScreen); @@ -524,8 +558,8 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) return FALSE; } - agpHandle = drmAgpAlloc(pI810->drmSubFD, 4096, 2, - (unsigned long *)&pI810->CursorPhysical); + drmAgpAlloc(pI810->drmSubFD, 4096, 2, + (unsigned long *)&pI810->CursorPhysical, &agpHandle); pI810->cursorHandle = agpHandle; if (agpHandle != 0) { @@ -536,6 +570,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) "GART: Allocated 4K for mouse cursor image\n"); pI810->CursorStart = tom; tom += 4096; + ErrorF("tom : %lx\n", tom); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: cursor bind failed\n"); pI810->CursorPhysical = 0; @@ -545,16 +580,19 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) pI810->CursorPhysical = 0; } + ErrorF("i : %d pI810->DepthBuffer %x\n", pitch_idx, pI810->DepthBuffer); I810SetTiledMemory(pScrn, 1, pI810->DepthBuffer.Start, i810_pitches[pitch_idx], 8*1024*1024); + ErrorF("i : %d\n", pitch_idx); I810SetTiledMemory(pScrn, 2, pI810->BackBuffer.Start, i810_pitches[pitch_idx], 8*1024*1024); + ErrorF("i : %d\n", pitch_idx); pI810->auxPitch = i810_pitches[pitch_idx]; pI810->auxPitchBits = i810_pitch_flags[pitch_idx]; @@ -562,6 +600,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) pI810->SavedDcacheMem = pI810->DcacheMem; pI810DRI->backbufferSize = pI810->BackBuffer.Size; + ErrorF("Backbuffer map : %lx\n", pI810->BackBuffer.Start); if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->BackBuffer.Start, pI810->BackBuffer.Size, DRM_AGP, 0, &pI810DRI->backbuffer) < 0) { @@ -570,6 +609,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) return FALSE; } + ErrorF("Depth map : %lx\n", pI810->DepthBuffer.Start); pI810DRI->depthbufferSize = pI810->DepthBuffer.Size; if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->DepthBuffer.Start, pI810->DepthBuffer.Size, DRM_AGP, 0, @@ -586,6 +626,15 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) I810AllocHigh( &(pI810->BufferMem), &(pI810->SysMem), I810_DMA_BUF_NR * I810_DMA_BUF_SZ); + ErrorF("Buffer map : %lx\n", pI810->BufferMem.Start); + + if(pI810->BufferMem.Start == 0 || + pI810->BufferMem.End - pI810->BufferMem.Start > + I810_DMA_BUF_NR * I810_DMA_BUF_SZ) { + ErrorF("Not enough memory for dma buffers\n"); + DRICloseScreen(pScreen); + return FALSE; + } if(drmAddMap(pI810->drmSubFD, (drmHandle)pI810->BufferMem.Start, pI810->BufferMem.Size, DRM_AGP, 0, &pI810->buffer_map) < 0) { @@ -597,6 +646,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) pI810DRI->agp_buffers = pI810->buffer_map; pI810DRI->agp_buf_size = pI810->BufferMem.Size; + ErrorF("Ring map : %lx\n", pI810->LpRing.mem.Start); if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->LpRing.mem.Start, pI810->LpRing.mem.Size, DRM_AGP, 0, &pI810->ring_map) < 0) { @@ -608,6 +658,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) /* Use the rest of memory for textures. */ pI810DRI->textureSize = pI810->SysMem.Size; + ErrorF("INITIAL texsize: %x\n", pI810DRI->textureSize); i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS); @@ -617,6 +668,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) pI810DRI->logTextureGranularity = i; pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i; /* truncate */ + ErrorF("REDUCED texsize: %x (i: %d)\n", pI810DRI->textureSize, i); if(pI810DRI->textureSize < 512*1024) { ErrorF("Less then 512k for textures\n"); @@ -625,8 +677,8 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) I810AllocLow( &(pI810->TexMem), &(pI810->SysMem), pI810DRI->textureSize); - + ErrorF("Texture map : %lx\n", pI810->TexMem.Start); if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->TexMem.Start, pI810->TexMem.Size, DRM_AGP, 0, &pI810DRI->textures) < 0) { @@ -635,6 +687,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) return FALSE; } + ErrorF("pI810->BufferMem.Start : %lx\n", pI810->BufferMem.Start); if((bufs = drmAddBufs(pI810->drmSubFD, I810_DMA_BUF_NR, I810_DMA_BUF_SZ, @@ -650,7 +703,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] added %d %d byte DMA buffers\n", bufs, I810_DMA_BUF_SZ); - I810drmInitDma(pScrn); + I810InitDma(pScrn); /* Okay now initialize the dma engine */ @@ -718,7 +771,7 @@ I810DRICloseScreen(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I810Ptr pI810 = I810PTR(pScrn); - I810drmCleanupDma(pScrn); + I810CleanupDma(pScrn); if(pI810->dcacheHandle) drmAgpFree(pI810->drmSubFD, pI810->dcacheHandle); if(pI810->backHandle) drmAgpFree(pI810->drmSubFD, pI810->backHandle); @@ -768,7 +821,7 @@ I810DestroyContext(ScreenPtr pScreen, drmContext hwContext, Bool I810DRIFinishScreenInit(ScreenPtr pScreen) { - drm_i810_sarea_t *sPriv = (drm_i810_sarea_t *)DRIGetSAREAPrivate(pScreen); + I810SAREARec *sPriv = (I810SAREARec *)DRIGetSAREAPrivate(pScreen); xf86memset( sPriv, 0, sizeof(sPriv) ); return DRIFinishScreenInit(pScreen); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h index e593f36b2..506227222 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h @@ -4,7 +4,7 @@ #define _I810_DRI_ #include <xf86drm.h> -#include "i810_drm_public.h" +#include <xf86drmI810.h> #define I810_MAX_DRAWABLES 256 @@ -53,6 +53,45 @@ typedef struct { } I810DRIRec, *I810DRIPtr; +/* WARNING: Do not change the SAREA structure without changing the kernel + * as well */ + +typedef struct { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} I810TexRegionRec, *I810TexRegionPtr; + +typedef struct { + unsigned int nbox; + XF86DRIClipRectRec boxes[I810_NR_SAREA_CLIPRECTS]; + + /* Maintain an LRU of contiguous regions of texture space. If + * you think you own a region of texture memory, and it has an + * age different to the one you set, then you are mistaken and + * it has been stolen by another client. If global texAge + * hasn't changed, there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained + * texture information of other clients - by maintaining them + * in the same lru which is used to age their own textures, + * clients have an approximate lru for the whole of global + * texture space, and can make informed decisions as to which + * areas to kick out. There is no need to choose whether to + * kick out your own texture or someone else's - simply eject + * them all in LRU order. + */ + I810TexRegionRec texList[I810_NR_TEX_REGIONS+1]; /* Last elt is sentinal */ + + int texAge; /* last time texture was uploaded */ + + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int last_quiescent; /* */ + + int ctxOwner; /* last context to upload state */ +} I810SAREARec, *I810SAREAPtr; + typedef struct { /* Nothing here yet */ int dummy; @@ -63,5 +102,4 @@ typedef struct { int dummy; } I810DRIContextRec, *I810DRIContextPtr; - #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dripriv.h deleted file mode 100644 index b4bbab133..000000000 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dripriv.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dripriv.h,v 1.1 2000/03/02 16:07:50 martin Exp $ */ - -#ifndef _I810_DRIPRIV_H_ -#define _I810_DRIPRIV_H_ - -#define I810_MAX_DRAWABLES 256 - -extern void GlxSetVisualConfigs( - int nconfigs, - __GLXvisualConfig *configs, - void **configprivs -); - -typedef struct { - /* Nothing here yet */ - int dummy; -} I810ConfigPrivRec, *I810ConfigPrivPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I810DRIContextRec, *I810DRIContextPtr; - -#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c index e489d17c9..e43685559 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c @@ -207,31 +207,19 @@ static const char *ramdacSymbols[] = { #ifdef XF86DRI static const char *drmSymbols[] = { + "drmAvailable", "drmAddBufs", "drmAddMap", - "drmAvailable", - "drmCtlAddCommand", "drmCtlInstHandler", "drmGetInterruptFromBusID", - "drmMapBufs", - "drmMarkBufs", - "drmUnmapBufs", "drmAgpAcquire", "drmAgpRelease", "drmAgpEnable", "drmAgpAlloc", "drmAgpFree", "drmAgpBind", - "drmAgpUnbind", - "drmAgpVersionMajor", - "drmAgpVersionMinor", - "drmAgpGetMode", - "drmAgpBase", - "drmAgpSize", - "drmAgpMemoryUsed", - "drmAgpMemoryAvail", - "drmAgpVendorId", - "drmAgpDeviceId", + "drmI810CleanupDma", + "drmI810InitDma", NULL }; @@ -1551,9 +1539,16 @@ I810AllocateFront(ScrnInfoPtr pScrn) { pI810->FbMemBox.y2 * pI810->cpp) + 4095) & ~4095); + fprintf(stderr, "Framebuffer %x, size %x\n", + pI810->FrontBuffer.Start, + pI810->FrontBuffer.Size); + + fprintf(stderr, "DisplayWidth %x, virtualX %x\n", + pScrn->displayWidth, + pScrn->virtualX); + xf86memset( &(pI810->LpRing), 0, sizeof( I810RingBuffer ) ); if(I810AllocLow( &(pI810->LpRing.mem), &(pI810->SysMem), 16*4096 )) { - if (I810_DEBUG & DEBUG_VERBOSE_MEMORY) ErrorF( "ring buffer at local %lx\n", pI810->LpRing.mem.Start); @@ -1607,6 +1602,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { /* Have to init the DRM earlier than in other drivers to get agp * memory. Wonder if this is going to be a problem... */ + #ifdef XF86DRI /* * Setup DRI after visuals have been established, but before cfbScreenInit @@ -1625,7 +1621,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { return FALSE; I810AllocateFront(pScrn); #endif - + if (!I810MapMem(pScrn)) return FALSE; pScrn->memPhysBase = (int)pI810->FbBase; @@ -1729,6 +1725,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { } } #endif + #ifdef XF86DRI if (!pI810->directRenderingEnabled) { pI810->DoneFrontAlloc = FALSE; @@ -1738,6 +1735,14 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { } #endif + ErrorF("InitFB box: %d,%d-%d,%d virt: %d,%d\n", + pI810->FbMemBox.x1, + pI810->FbMemBox.y1, + pI810->FbMemBox.x2, + pI810->FbMemBox.y2, + pScrn->virtualX, + pScrn->virtualY); + if (!xf86InitFBManager(pScreen, &(pI810->FbMemBox))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n"); @@ -1762,7 +1767,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { } } -#if XF86DRI +#ifdef XF86DRI if (pI810->LpRing.mem.Start == 0) { pI810->directRenderingEnabled = 0; I810DRICloseScreen(pScreen); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_sarea.h deleted file mode 100644 index 0f70d3535..000000000 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_sarea.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef I810_SAPRIV_H -#define I810_SAPRIV_H - -#include "i810_drm_public.h" - -#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile index e9a42442d..c11f6a457 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v 1.26 1999/08/21 13:48:34 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v 1.32 2000/02/28 19:53:12 alanh Exp $ XCOMM XCOMM This is an Imakefile for the MGA driver. XCOMM @@ -6,26 +6,37 @@ XCOMM #define IHaveModules #include <Server.tmpl> +#if BuildXF86DRI +DRISRCS = mga_dri.c mga_warp.c mga_wrap.c +DRIOBJS = mga_dri.o mga_warp.o mga_wrap.o +DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \ + -I$(XF86OSSRC)/linux/drm/kernel +DRIDEFINES = $(GLX_DEFINES) +#endif + SRCS = mga_driver.c mga_hwcurs.c /* mga_cmap.c */ mga_dac3026.c mga_dacG.c \ mga_storm8.c mga_storm16.c mga_storm24.c mga_storm32.c mga_arc.c \ - mga_dga.c mga_shadow.c + mga_dga.c mga_shadow.c mga_video.c $(DRISRCS) OBJS = mga_driver.o mga_hwcurs.o /* mga_cmap.o */ mga_dac3026.o mga_dacG.o \ mga_storm8.o mga_storm16.o mga_storm24.o mga_storm32.o mga_arc.o \ - mga_dga.o mga_shadow.o + mga_dga.o mga_shadow.o mga_video.o $(DRIOBJS) #if defined(XF86DriverSDK) INCLUDES = -I. -I../../include #else INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ - -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi -I$(XF86SRC)/int10 \ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa -I$(XF86SRC)/rac \ -I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \ -I$(XF86SRC)/ramdac -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ - -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb -I$(EXTINCSRC) + -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb -I$(EXTINCSRC) \ + -I$(XF86OSSRC)/vbe $(DRIINCLUDES) #endif +DEFINES = $(DRIDEFINES) + #if MakeHasPosixVariableSubstitutions SubdirLibraryRule($(OBJS)) #endif @@ -62,6 +73,7 @@ InstallDriverSDKNonExecFile(mga_map.h,$(DRIVERSDKDIR)/drivers/mga) InstallDriverSDKNonExecFile(mga_reg.h,$(DRIVERSDKDIR)/drivers/mga) InstallDriverSDKNonExecFile(mga_shadow.c,$(DRIVERSDKDIR)/drivers/mga) InstallDriverSDKNonExecFile(mga_storm.c,$(DRIVERSDKDIR)/drivers/mga) +InstallDriverSDKNonExecFile(mga_video.c,$(DRIVERSDKDIR)/drivers/mga) InstallDriverSDKObjectModule(mga,$(DRIVERSDKMODULEDIR),drivers) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h index bc927c8a4..5e0430616 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.47 1999/08/22 05:57:33 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.57 2000/02/27 02:50:47 mvojkovi Exp $ */ /* * MGA Millennium (MGA2064W) functions * @@ -14,21 +14,32 @@ #ifndef MGA_H #define MGA_H +#include "compiler.h" #include "xaa.h" #include "xf86Cursor.h" #include "vgaHW.h" #include "colormapst.h" #include "xf86DDC.h" +#include "xf86xv.h" -#if defined(__alpha__) -#define INREG8(addr) xf86ReadSparse8(pMga->IOBase, (addr)) -#define INREG16(addr) xf86ReadSparse16(pMga->IOBase, (addr)) -#define INREG(addr) xf86ReadSparse32(pMga->IOBase, (addr)) -#define OUTREG8(addr,val) xf86WriteSparse8((val),pMga->IOBase,(addr)) -#define OUTREG16(addr,val) xf86WriteSparse16((val),pMga->IOBase,(addr)) -#define OUTREG(addr, val) xf86WriteSparse32((val),pMga->IOBase,(addr)) -#else /* __alpha__ */ -#if defined(EXTRADEBUG) +#ifdef XF86DRI +#include "xf86drm.h" +#include "sarea.h" +#define _XF86DRI_SERVER_ +#include "xf86dri.h" +#include "dri.h" +#include "GL/glxint.h" +#include "mga_dri.h" +#endif + +#if !defined(EXTRADEBUG) +#define INREG8(addr) MMIO_IN8(pMga->IOBase, addr) +#define INREG16(addr) MMIO_IN16(pMga->IOBase, addr) +#define INREG(addr) MMIO_IN32(pMga->IOBase, addr) +#define OUTREG8(addr, val) MMIO_OUT8(pMga->IOBase, addr, val) +#define OUTREG16(addr, val) MMIO_OUT16(pMga->IOBase, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(pMga->IOBase, addr, val) +#else /* !EXTRADEBUG */ CARD8 dbg_inreg8(ScrnInfoPtr,int,int); CARD16 dbg_inreg16(ScrnInfoPtr,int,int); CARD32 dbg_inreg32(ScrnInfoPtr,int,int); @@ -41,15 +52,7 @@ void dbg_outreg32(ScrnInfoPtr,int,int); #define OUTREG8(addr,val) dbg_outreg8(pScrn,addr,val) #define OUTREG16(addr,val) dbg_outreg16(pScrn,addr,val) #define OUTREG(addr,val) dbg_outreg32(pScrn,addr,val) -#else /* EXTRADEBUG */ -#define INREG8(addr) *(volatile CARD8 *)(pMga->IOBase + (addr)) -#define INREG16(addr) *(volatile CARD16 *)(pMga->IOBase + (addr)) -#define INREG(addr) *(volatile CARD32 *)(pMga->IOBase + (addr)) -#define OUTREG8(addr, val) *(volatile CARD8 *)(pMga->IOBase + (addr)) = (val) -#define OUTREG16(addr, val) *(volatile CARD16 *)(pMga->IOBase + (addr)) = (val) -#define OUTREG(addr, val) *(volatile CARD32 *)(pMga->IOBase + (addr)) = (val) #endif /* EXTRADEBUG */ -#endif /* __alpha__ */ #define PORT_OFFSET (0x1F00 - 0x300) @@ -62,6 +65,7 @@ typedef struct { CARD32 Option3; } MGARegRec, *MGARegPtr; + typedef struct { Bool isHwCursor; int CursorMaxWidth; @@ -93,6 +97,7 @@ typedef struct { int displayWidth; rgb weight; Bool Overlay8Plus24; + DisplayModePtr mode; } MGAFBLayout; @@ -133,9 +138,7 @@ typedef struct { CARD32 BiosAddress; MessageType BiosFrom; unsigned char * IOBase; -#ifdef __alpha__ unsigned char * IOBaseDense; -#endif unsigned char * FbBase; unsigned char * ILOADBase; unsigned char * FbStart; @@ -170,6 +173,8 @@ typedef struct { CARD32 PlaneMask; CARD32 FgColor; CARD32 BgColor; + CARD32 MAccess; + int FifoSize; int StyleLen; XAAInfoRecPtr AccelInfoRec; xf86CursorInfoPtr CursorInfoRec; @@ -185,19 +190,43 @@ typedef struct { Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr); void (*PointerMoved)(int index, int x, int y); CloseScreenProcPtr CloseScreen; + ScreenBlockHandlerProcPtr BlockHandler; unsigned int (*ddc1Read)(ScrnInfoPtr); void (*DDC1SetSpeed)(ScrnInfoPtr, xf86ddcSpeed); Bool (*i2cInit)(ScrnInfoPtr); I2CBusPtr I2C; Bool FBDev; int colorKey; + int videoKey; int fifoCount; int Rotate; MGAFBLayout CurrentLayout; Bool DrawTransparent; int MaxBlitDWORDS; + +#ifdef XF86DRI + Bool directRenderingEnabled; + DRIInfoPtr pDRIInfo; + int drmSubFD; + int numVisualConfigs; + __GLXvisualConfig* pVisualConfigs; + MGAConfigPrivPtr pVisualConfigsPriv; + MGARegRec DRContextRegs; + MGADRIServerPrivatePtr DRIServerInfo; + Bool have_quiescense; +#endif + + XF86VideoAdaptorPtr adaptor; } MGARec, *MGAPtr; +#ifdef XF86DRI +extern void GlxSetVisualConfigs( + int nconfigs, + __GLXvisualConfig *configs, + void **configprivs +); +#endif + extern CARD32 MGAAtype[16]; extern CARD32 MGAAtypeNoBLK[16]; @@ -211,11 +240,17 @@ extern CARD32 MGAAtypeNoBLK[16]; #define MGA_NO_PLANEMASK 0x00000080 #define USE_LINEAR_EXPANSION 0x00000100 #define LARGE_ADDRESSES 0x00000200 - +#define MGAIOMAPSIZE 0x00004000 +#define MGAILOADMAPSIZE 0x00400000 #define TRANSPARENCY_KEY 255 #define KEY_COLOR 0 +#define MGA_FRONT 0x1 +#define MGA_BACK 0x2 +#define MGA_DEPTH 0x4 + + /* Prototypes */ void MGAAdjustFrame(int scrnIndex, int x, int y, int flags); @@ -238,6 +273,18 @@ void MGAPolyArcThinSolid(DrawablePtr, GCPtr, int, xArc*); Bool MGADGAInit(ScreenPtr pScreen); +Bool MGADRIScreenInit(ScreenPtr pScreen); +void MGADRICloseScreen(ScreenPtr pScreen); +Bool MGADRIFinishScreenInit(ScreenPtr pScreen); +void MGASwapContext(ScreenPtr pScreen); +void MGASelectBuffer(ScrnInfoPtr pScrn, int which); +Bool mgaConfigureWarp(ScrnInfoPtr pScrn); +unsigned int mgaInstallMicrocode(ScreenPtr pScreen, int agp_offset); +unsigned int mgaGetMicrocodeSize(ScreenPtr pScreen); +Bool MgaCleanupDma(ScrnInfoPtr pScrn); +Bool MgaInitDma(ScrnInfoPtr pScrn, int prim_size); +Bool MgaLockUpdate(ScrnInfoPtr pScrn, drmLockFlags flags); + void MGARefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); void MGARefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); void MGARefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); @@ -268,4 +315,7 @@ void Mga32SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, void MGAPointerMoved(int index, int x, int y); +void MGAInitVideo(ScreenPtr pScreen); +void MGAResetVideo(ScrnInfoPtr pScrn); + #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c index 2844302ff..993d763a8 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c @@ -69,6 +69,8 @@ MGAZeroArc( Bool do360; DDXPointRec org, orgo; + CHECK_DMA_QUIESCENT( pMga, infoRec->pScrn ); + (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu, pGC->planemask); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c index f9a07ade3..fb7952211 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c,v 1.48 1999/08/21 13:48:35 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c,v 1.52 2000/01/21 01:12:20 dawes Exp $ */ /* * Copyright 1994 by Robin Cutshaw <robin@XFree86.org> * @@ -49,6 +49,7 @@ #include "mga_bios.h" #include "mga_reg.h" +#include "mga_macros.h" #include "mga.h" #include "xf86DDC.h" @@ -85,17 +86,33 @@ const static unsigned char MGADACregs[] = { 0x06 }; +/* note: to fix a cursor hw glitch, register 0x37 (blue color key) needs + to be set to magic numbers, even though they are "never" used because + blue keying disabled in 0x38. + + Matrox sez: + + ...The more precise statement of the software workaround is to insure + that bits 7-5 of register 0x37 (Blue Color Key High) and bits 7-5 of + register 0x38 (HZOOM)are the same... +*/ + +/* also note: the values of the MUX control register 0x19 (index [2]) can be + found in table 2-17 of the 3026 manual. If interlace is set, the values + listed here are incremented by one. +*/ + #define DACREGSIZE sizeof(MGADACregs) /* * initial values of ti3026 registers */ const static unsigned char MGADACbpp8[DACREGSIZE] = { - 0x06, 0x80, 0x48, 0x25, 0x00, 0x00, 0x0C, 0x00, 0x1E, 0xFF, + 0x06, 0x80, 0x4b, 0x25, 0x00, 0x00, 0x0C, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0, 0x00, 0x00 }; const static unsigned char MGADACbpp16[DACREGSIZE] = { - 0x07, 0x45, 0x50, 0x15, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, + 0x07, 0x45, 0x53, 0x15, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00, 0x00 }; @@ -103,18 +120,29 @@ const static unsigned char MGADACbpp16[DACREGSIZE] = { * [0] value was 0x07, but changed to 0x06 by Doug Merrit to fix high res * stripe glitches and clock glitches at 24bpp. */ +/* [0] value is now set inside of MGA3026Init, based on the silicon revision + It is still set to 7 or 6 based on the revision, though, since setting to + 8 as in the documentation makes (some?) revB chips get the colors wrong... + maybe BGR instead of RGB? This only applies to 24bpp, since it is the only + one documented as depending on revision. + */ + const static unsigned char MGADACbpp24[DACREGSIZE] = { - 0x06, 0x56, 0x58, 0x25, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, + 0x06, 0x56, 0x5b, 0x25, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00, 0x00 }; const static unsigned char MGADACbpp32[DACREGSIZE] = { - 0x07, 0x46, 0x58, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, + 0x07, 0x46, 0x5b, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00, 0x00 }; + +/* on at least some 2064Ws, the PSEL line flips at 4MB or so, so PSEL keying + has to be off in register 0x1e -> bit4 clear */ + const static unsigned char MGADACbpp8plus24[DACREGSIZE] = { - 0x07, 0x06, 0x58, 0x05, 0x00, 0x00, 0x3C, 0x00, 0x1E, 0xFF, + 0x07, 0x06, 0x5b, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0x00, 0x00 }; @@ -523,7 +551,31 @@ MGA3026Init(ScrnInfoPtr pScrn, DisplayModePtr mode) && (pLayout->weight.green == 5) && (pLayout->weight.blue == 5) ) { pReg->DacRegs[1] &= ~0x01; } - pReg->DacRegs[2] |= pMga->Interleave? 0x04 : 0x03; + if (pMga->Interleave ) pReg->DacRegs[2] += 1; + + + if ( pLayout->bitsPerPixel == 24 ) { + int silicon_rev; + /* we need to set DacRegs[0] differently based on the silicon + * revision of the 3026 RAMDAC, as per page 2-14 of tvp3026.pdf. + * If we have rev A silicon, we want 0x07; rev B silicon wants + * 0x06. + */ + silicon_rev = inTi3026(TVP3026_SILICON_REV); + +#ifdef DEBUG + ErrorF("TVP3026 revision 0x%x (rev %s)\n", + silicon_rev, (silicon_rev <= 0x20) ? "A" : "B"); +#endif + + if(silicon_rev <= 0x20) { + /* rev A */ + pReg->DacRegs[0] = 0x07; + } else { + /* rev B */ + pReg->DacRegs[0] = 0x06; + } + } /* * This will initialize all of the generic VGA registers. @@ -652,10 +704,9 @@ MGA3026Init(ScrnInfoPtr pScrn, DisplayModePtr mode) else pReg->Option &= ~0x1000; - if(pMga->UsePCIRetry) - pReg->Option &= ~0x20000000; - else - pReg->Option |= 0x20000000; + /* must always have the pci retries on but rely on + polling to keep them from occuring */ + pReg->Option &= ~0x20000000; pVga->MiscOutReg |= 0x0C; /* XXX Need to check the first argument */ @@ -694,6 +745,8 @@ MGA3026Restore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, int i; MGAPtr pMga = MGAPTR(pScrn); + CHECK_DMA_QUIESCENT( pMga, pScrn ); + /* * Code is needed to get things back to bank zero. */ @@ -771,6 +824,8 @@ MGA3026Save(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, int i; MGAPtr pMga = MGAPTR(pScrn); + CHECK_DMA_QUIESCENT( pMga, pScrn ); + /* Allocate the DacRegs space if not done already */ if (mgaReg->DacRegs == NULL) { mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1); @@ -1034,14 +1089,29 @@ MGA3026RamdacInit(ScrnInfoPtr pScrn) break; } /* Set MCLK based on amount of memory */ - if ( pScrn->videoRam < 4096 ) + if(pMga->OverclockMem) { + if ( pScrn->videoRam < 4096 ) + MGAdac->MemoryClock = pMga->Bios.ClkBase * 12; + else if ( pScrn->videoRam < 8192 ) + MGAdac->MemoryClock = pMga->Bios.Clk4MB * 12; + else + MGAdac->MemoryClock = pMga->Bios.Clk8MB * 12; + MGAdac->MemClkFrom = X_CONFIG; + MGAdac->SetMemClk = TRUE; +#if 0 + ErrorF("BIOS Memory clock settings: 2Mb %d, 4Mb %d, 8MB %d\n", + pMga->Bios.ClkBase, pMga->Bios.Clk4MB, pMga->Bios.Clk8MB); +#endif + } else { + if ( pScrn->videoRam < 4096 ) MGAdac->MemoryClock = pMga->Bios.ClkBase * 10; - else if ( pScrn->videoRam < 8192 ) + else if ( pScrn->videoRam < 8192 ) MGAdac->MemoryClock = pMga->Bios.Clk4MB * 10; - else + else MGAdac->MemoryClock = pMga->Bios.Clk8MB * 10; - MGAdac->MemClkFrom = X_PROBED; - MGAdac->SetMemClk = TRUE; + MGAdac->MemClkFrom = X_PROBED; + MGAdac->SetMemClk = TRUE; + } } else { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c index 1cfa03f31..d81d12b3a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c @@ -2,7 +2,7 @@ * MGA-1064, MGA-G100, MGA-G200, MGA-G400 RAMDAC driver */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c,v 1.30 1999/08/22 05:57:33 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c,v 1.33 1999/12/03 04:03:52 mvojkovi Exp $ */ /* * This is a first cut at a non-accelerated version to work with the @@ -24,6 +24,7 @@ #include "mga_bios.h" #include "mga_reg.h" +#include "mga_macros.h" #include "mga.h" #include "xf86DDC.h" @@ -330,24 +331,40 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->Option2 = 0x0000007; break; case PCI_CHIP_MGAG400: - if(pMga->OverclockMem) { - /* 166 Mhz but faster graphics engine clock */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x13; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x7A; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08; - pReg->Option3 = 0x0190a421; + if(pMga->Dac.maxPixelClock == 360000) { /* G400 MAX */ + if(pMga->OverclockMem) { + /* 150/200 */ + pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x05; + pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x42; + pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; + pReg->Option3 = 0x019B8419; + pReg->Option = 0x50574120; + } else { + /* 125/166 */ + pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02; + pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B; + pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; + pReg->Option3 = 0x019B8419; + pReg->Option = 0x5053C120; + } } else { - /* 165 Mhz */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x09; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x3C; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10; - pReg->Option3 = 0x0190a419; - } + if(pMga->OverclockMem) { + /* 125/166 */ + pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02; + pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B; + pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; + pReg->Option3 = 0x019B8419; + pReg->Option = 0x5053C120; + } else { + /* 110/166 */ + pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x13; + pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x7A; + pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08; + pReg->Option3 = 0x0190a421; + pReg->Option = 0x50044120; + } + } pReg->Option2 = 0x01003000; - if(pMga->HasSDRAM) - pReg->Option = 0x50040120; - else - pReg->Option = 0x50044120; break; case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: @@ -371,10 +388,9 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) break; } - if(pMga->UsePCIRetry) - pReg->Option &= ~0x20000000; - else - pReg->Option |= 0x20000000; + /* must always have the pci retries on but rely on + polling to keep them from occuring */ + pReg->Option &= ~0x20000000; switch(pLayout->bitsPerPixel) { @@ -579,6 +595,8 @@ MGAGRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, int i; MGAPtr pMga = MGAPTR(pScrn); + CHECK_DMA_QUIESCENT( pMga, pScrn ); + /* * Code is needed to get things back to bank zero. */ @@ -656,6 +674,8 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, int i; MGAPtr pMga = MGAPTR(pScrn); + CHECK_DMA_QUIESCENT( pMga, pScrn ); + /* Allocate the DacRegs space if not done already */ if (mgaReg->DacRegs == NULL) { mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1); @@ -749,6 +769,9 @@ MGAGSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) x += 64; y += 64; + /* This doesn't require DMA quiescence (what about flush?) + */ + /* cursor update must never occurs during a retrace period (pp 4-160) */ while( INREG( MGAREG_Status ) & 0x08 ); @@ -915,7 +938,12 @@ MGAGRamdacInit(ScrnInfoPtr pScrn) MGAdac->maxPixelClock = 220000; break; case PCI_CHIP_MGAG400: - MGAdac->maxPixelClock = 300000; + /* We don't know the new pins format but we know that + the maxclock / 4 is where the RamdacType was in the + old pins format */ + MGAdac->maxPixelClock = pMga->Bios2.RamdacType * 4000; + if(MGAdac->maxPixelClock < 300000) + MGAdac->maxPixelClock = 300000; break; default: MGAdac->maxPixelClock = 250000; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c index df23db4f6..ca69d37c1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c @@ -22,7 +22,7 @@ #include "mga.h" #include "mga_macros.h" #include "mga_dri.h" -#include "mga_dripriv.h" +#include "mga_wrap.h" static char MGAKernelDriverName[] = "mga"; static char MGAClientDriverName[] = "mga"; @@ -51,172 +51,252 @@ extern void Mga32DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); extern void Mga32DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index); -static Bool -MGAInitVisualConfigs(ScreenPtr pScreen) +Bool MgaCleanupDma(ScrnInfoPtr pScrn) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - MGAPtr pMGA = MGAPTR(pScrn); - int numConfigs = 0; - __GLXvisualConfig *pConfigs = 0; - MGAConfigPrivPtr pMGAConfigs = 0; - MGAConfigPrivPtr *pMGAConfigPtrs = 0; - int i; + MGAPtr pMGA = MGAPTR(pScrn); + Bool ret_val; + + ret_val = drmMgaCleanupDma(pMGA->drmSubFD); + if(ret_val == FALSE) ErrorF("Mga Dma Cleanup Failed\n"); + + return ret_val; +} - switch (pScrn->bitsPerPixel) { - case 8: - case 24: - case 32: - break; - case 16: - numConfigs = 4; +Bool MgaLockUpdate(ScrnInfoPtr pScrn, drmLockFlags flags) +{ + MGAPtr pMGA = MGAPTR(pScrn); + Bool ret_val; + + ret_val = drmMgaLockUpdate(pMGA->drmSubFD, flags); + if(ret_val == FALSE) ErrorF("LockUpdate failed\n"); + + return ret_val; +} - if (!(pConfigs = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), - numConfigs))) { +Bool MgaInitDma(ScrnInfoPtr pScrn, int prim_size) +{ + MGAPtr pMGA = MGAPTR(pScrn); + MGADRIPtr pMGADRI = (MGADRIPtr)pMGA->pDRIInfo->devPrivate; + MGADRIServerPrivatePtr pMGADRIServer = pMGA->DRIServerInfo; + drmMgaInit init; + Bool ret_val; + + memset(&init, 0, sizeof(drmMgaInit)); + init.reserved_map_agpstart = 0; + init.reserved_map_idx = 3; + init.buffer_map_idx = 4; + init.sarea_priv_offset = sizeof(XF86DRISAREARec); + init.primary_size = prim_size; + init.warp_ucode_size = pMGADRIServer->warp_ucode_size; + + switch(pMGA->Chipset) { + case PCI_CHIP_MGAG400: + init.chipset = MGA_CARD_TYPE_G400; + break; + case PCI_CHIP_MGAG200: + init.chipset = MGA_CARD_TYPE_G200; + break; + case PCI_CHIP_MGAG200_PCI: + default: + ErrorF("Direct rendering not supported on this card/chipset\n"); return FALSE; - } - if (!(pMGAConfigs = (MGAConfigPrivPtr)xnfcalloc(sizeof(MGAConfigPrivRec), + } + + init.frontOffset = pMGADRI->frontOffset; + init.backOffset = pMGADRI->backOffset; + init.depthOffset = pMGADRI->depthOffset; + init.textureOffset = pMGADRI->textureOffset; + init.textureSize = pMGADRI->textureSize; + init.agpTextureSize = pMGADRI->agpTextureSize; + init.cpp = pMGADRI->cpp; + init.stride = pMGADRI->frontPitch; + init.mAccess = pMGA->MAccess; + init.sgram = !pMGA->HasSDRAM; + + memcpy(&init.WarpIndex, &pMGADRIServer->WarpIndex, + sizeof(drmMgaWarpIndex) * MGA_MAX_WARP_PIPES); + + ErrorF("Mga Dma Initialization start\n"); + + ret_val = drmMgaInitDma(pMGA->drmSubFD, &init); + if(ret_val == FALSE) ErrorF("Mga Dma Initialization Failed\n"); + else ErrorF("Mga Dma Initialization done\n"); + return ret_val; +} + +static Bool +MGAInitVisualConfigs(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMGA = MGAPTR(pScrn); + int numConfigs = 0; + __GLXvisualConfig *pConfigs = 0; + MGAConfigPrivPtr pMGAConfigs = 0; + MGAConfigPrivPtr *pMGAConfigPtrs = 0; + int i; + + switch (pScrn->bitsPerPixel) { + case 8: + case 24: + case 32: + break; + case 16: + numConfigs = 4; + + if (!(pConfigs = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), numConfigs))) { - xfree(pConfigs); - return FALSE; - } - if (!(pMGAConfigPtrs = (MGAConfigPrivPtr*)xnfcalloc(sizeof(MGAConfigPrivPtr), - numConfigs))) { - xfree(pConfigs); - xfree(pMGAConfigs); - return FALSE; - } - for (i=0; i<numConfigs; i++) - pMGAConfigPtrs[i] = &pMGAConfigs[i]; + return FALSE; + } + if (!(pMGAConfigs = (MGAConfigPrivPtr)xnfcalloc(sizeof(MGAConfigPrivRec), + numConfigs))) { + xfree(pConfigs); + return FALSE; + } + if (!(pMGAConfigPtrs = (MGAConfigPrivPtr*)xnfcalloc(sizeof(MGAConfigPrivPtr), + numConfigs))) { + xfree(pConfigs); + xfree(pMGAConfigs); + return FALSE; + } + for (i=0; i<numConfigs; i++) + pMGAConfigPtrs[i] = &pMGAConfigs[i]; + + /* config 0: db=FALSE, depth=0 + config 1: db=FALSE, depth=16 + config 2: db=TRUE, depth=0; + config 3: db=TRUE, depth=16 + */ + pConfigs[0].vid = -1; + pConfigs[0].class = -1; + pConfigs[0].rgba = TRUE; + pConfigs[0].redSize = 5; + pConfigs[0].greenSize = 6; + pConfigs[0].blueSize = 5; + pConfigs[0].redMask = 0x0000F800; + pConfigs[0].greenMask = 0x000007E0; + pConfigs[0].blueMask = 0x0000001F; + pConfigs[0].alphaMask = 0; + pConfigs[0].accumRedSize = 0; + pConfigs[0].accumGreenSize = 0; + pConfigs[0].accumBlueSize = 0; + pConfigs[0].accumAlphaSize = 0; + pConfigs[0].doubleBuffer = FALSE; + pConfigs[0].stereo = FALSE; + pConfigs[0].bufferSize = 16; + pConfigs[0].depthSize = 16; + pConfigs[0].stencilSize = 0; + pConfigs[0].auxBuffers = 0; + pConfigs[0].level = 0; + pConfigs[0].visualRating = 0; + pConfigs[0].transparentPixel = 0; + pConfigs[0].transparentRed = 0; + pConfigs[0].transparentGreen = 0; + pConfigs[0].transparentBlue = 0; + pConfigs[0].transparentAlpha = 0; + pConfigs[0].transparentIndex = 0; + + pConfigs[1].vid = -1; + pConfigs[1].class = -1; + pConfigs[1].rgba = TRUE; + pConfigs[1].redSize = 5; + pConfigs[1].greenSize = 6; + pConfigs[1].blueSize = 5; + pConfigs[1].redMask = 0x0000F800; + pConfigs[1].greenMask = 0x000007E0; + pConfigs[1].blueMask = 0x0000001F; + pConfigs[1].alphaMask = 0; + pConfigs[1].accumRedSize = 0; + pConfigs[1].accumGreenSize = 0; + pConfigs[1].accumBlueSize = 0; + pConfigs[1].accumAlphaSize = 0; + pConfigs[1].doubleBuffer = FALSE; + pConfigs[1].stereo = FALSE; + pConfigs[1].bufferSize = 16; + pConfigs[1].depthSize = 16; + pConfigs[1].stencilSize = 0; + pConfigs[1].auxBuffers = 0; + pConfigs[1].level = 0; + pConfigs[1].visualRating = 0; + pConfigs[1].transparentPixel = 0; + pConfigs[1].transparentRed = 0; + pConfigs[1].transparentGreen = 0; + pConfigs[1].transparentBlue = 0; + pConfigs[1].transparentAlpha = 0; + pConfigs[1].transparentIndex = 0; + + pConfigs[2].vid = -1; + pConfigs[2].class = -1; + pConfigs[2].rgba = TRUE; + pConfigs[2].redSize = 5; + pConfigs[2].greenSize = 6; + pConfigs[2].blueSize = 5; + pConfigs[2].redMask = 0x0000F800; + pConfigs[2].greenMask = 0x000007E0; + pConfigs[2].blueMask = 0x0000001F; + pConfigs[2].alphaMask = 0; + pConfigs[2].accumRedSize = 0; + pConfigs[2].accumGreenSize = 0; + pConfigs[2].accumBlueSize = 0; + pConfigs[2].accumAlphaSize = 0; + pConfigs[2].doubleBuffer = TRUE; + pConfigs[2].stereo = FALSE; + pConfigs[2].bufferSize = 16; + pConfigs[2].depthSize = 16; + pConfigs[2].stencilSize = 0; + pConfigs[2].auxBuffers = 0; + pConfigs[2].level = 0; + pConfigs[2].visualRating = 0; + pConfigs[2].transparentPixel = 0; + pConfigs[2].transparentRed = 0; + pConfigs[2].transparentGreen = 0; + pConfigs[2].transparentBlue = 0; + pConfigs[2].transparentAlpha = 0; + pConfigs[2].transparentIndex = 0; + + pConfigs[3].vid = -1; + pConfigs[3].class = -1; + pConfigs[3].rgba = TRUE; + pConfigs[3].redSize = 5; + pConfigs[3].greenSize = 6; + pConfigs[3].blueSize = 5; + pConfigs[3].redMask = 0x0000F800; + pConfigs[3].greenMask = 0x000007E0; + pConfigs[3].blueMask = 0x0000001F; + pConfigs[3].alphaMask = 0; + pConfigs[3].accumRedSize = 0; + pConfigs[3].accumGreenSize = 0; + pConfigs[3].accumBlueSize = 0; + pConfigs[3].accumAlphaSize = 0; + pConfigs[3].doubleBuffer = TRUE; + pConfigs[3].stereo = FALSE; + pConfigs[3].bufferSize = 16; + pConfigs[3].depthSize = 16; + pConfigs[3].stencilSize = 0; + pConfigs[3].auxBuffers = 0; + pConfigs[3].level = 0; + pConfigs[3].visualRating = 0; + pConfigs[3].transparentPixel = 0; + pConfigs[3].transparentRed = 0; + pConfigs[3].transparentGreen = 0; + pConfigs[3].transparentBlue = 0; + pConfigs[3].transparentAlpha = 0; + pConfigs[3].transparentIndex = 0; + } + pMGA->numVisualConfigs = numConfigs; + pMGA->pVisualConfigs = pConfigs; + pMGA->pVisualConfigsPriv = pMGAConfigs; + GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pMGAConfigPtrs); + return TRUE; +} - /* config 0: db=FALSE, depth=0 - config 1: db=FALSE, depth=16 - config 2: db=TRUE, depth=0; - config 3: db=TRUE, depth=16 - */ - pConfigs[0].vid = -1; - pConfigs[0].class = -1; - pConfigs[0].rgba = TRUE; - pConfigs[0].redSize = 8; - pConfigs[0].greenSize = 8; - pConfigs[0].blueSize = 8; - pConfigs[0].redMask = 0x00FF0000; - pConfigs[0].greenMask = 0x0000FF00; - pConfigs[0].blueMask = 0x000000FF; - pConfigs[0].alphaMask = 0; - pConfigs[0].accumRedSize = 0; - pConfigs[0].accumGreenSize = 0; - pConfigs[0].accumBlueSize = 0; - pConfigs[0].accumAlphaSize = 0; - pConfigs[0].doubleBuffer = FALSE; - pConfigs[0].stereo = FALSE; - pConfigs[0].bufferSize = 16; - pConfigs[0].depthSize = 0; - pConfigs[0].stencilSize = 0; - pConfigs[0].auxBuffers = 0; - pConfigs[0].level = 0; - pConfigs[0].visualRating = 0; - pConfigs[0].transparentPixel = 0; - pConfigs[0].transparentRed = 0; - pConfigs[0].transparentGreen = 0; - pConfigs[0].transparentBlue = 0; - pConfigs[0].transparentAlpha = 0; - pConfigs[0].transparentIndex = 0; - - pConfigs[1].vid = -1; - pConfigs[1].class = -1; - pConfigs[1].rgba = TRUE; - pConfigs[1].redSize = 8; - pConfigs[1].greenSize = 8; - pConfigs[1].blueSize = 8; - pConfigs[1].redMask = 0x00FF0000; - pConfigs[1].greenMask = 0x0000FF00; - pConfigs[1].blueMask = 0x000000FF; - pConfigs[1].alphaMask = 0; - pConfigs[1].accumRedSize = 0; - pConfigs[1].accumGreenSize = 0; - pConfigs[1].accumBlueSize = 0; - pConfigs[1].accumAlphaSize = 0; - pConfigs[1].doubleBuffer = FALSE; - pConfigs[1].stereo = FALSE; - pConfigs[1].bufferSize = 16; - pConfigs[1].depthSize = 16; - pConfigs[1].stencilSize = 0; - pConfigs[1].auxBuffers = 0; - pConfigs[1].level = 0; - pConfigs[1].visualRating = 0; - pConfigs[1].transparentPixel = 0; - pConfigs[1].transparentRed = 0; - pConfigs[1].transparentGreen = 0; - pConfigs[1].transparentBlue = 0; - pConfigs[1].transparentAlpha = 0; - pConfigs[1].transparentIndex = 0; - - pConfigs[2].vid = -1; - pConfigs[2].class = -1; - pConfigs[2].rgba = TRUE; - pConfigs[2].redSize = 8; - pConfigs[2].greenSize = 8; - pConfigs[2].blueSize = 8; - pConfigs[2].redMask = 0x00FF0000; - pConfigs[2].greenMask = 0x0000FF00; - pConfigs[2].blueMask = 0x000000FF; - pConfigs[2].alphaMask = 0; - pConfigs[2].accumRedSize = 0; - pConfigs[2].accumGreenSize = 0; - pConfigs[2].accumBlueSize = 0; - pConfigs[2].accumAlphaSize = 0; - pConfigs[2].doubleBuffer = TRUE; - pConfigs[2].stereo = FALSE; - pConfigs[2].bufferSize = 16; - pConfigs[2].depthSize = 0; - pConfigs[2].stencilSize = 0; - pConfigs[2].auxBuffers = 0; - pConfigs[2].level = 0; - pConfigs[2].visualRating = 0; - pConfigs[2].transparentPixel = 0; - pConfigs[2].transparentRed = 0; - pConfigs[2].transparentGreen = 0; - pConfigs[2].transparentBlue = 0; - pConfigs[2].transparentAlpha = 0; - pConfigs[2].transparentIndex = 0; - - pConfigs[3].vid = -1; - pConfigs[3].class = -1; - pConfigs[3].rgba = TRUE; - pConfigs[3].redSize = 8; - pConfigs[3].greenSize = 8; - pConfigs[3].blueSize = 8; - pConfigs[3].redMask = 0x00FF0000; - pConfigs[3].greenMask = 0x0000FF00; - pConfigs[3].blueMask = 0x000000FF; - pConfigs[3].alphaMask = 0; - pConfigs[3].accumRedSize = 0; - pConfigs[3].accumGreenSize = 0; - pConfigs[3].accumBlueSize = 0; - pConfigs[3].accumAlphaSize = 0; - pConfigs[3].doubleBuffer = TRUE; - pConfigs[3].stereo = FALSE; - pConfigs[3].bufferSize = 16; - pConfigs[3].depthSize = 16; - pConfigs[3].stencilSize = 0; - pConfigs[3].auxBuffers = 0; - pConfigs[3].level = 0; - pConfigs[3].visualRating = 0; - pConfigs[3].transparentPixel = 0; - pConfigs[3].transparentRed = 0; - pConfigs[3].transparentGreen = 0; - pConfigs[3].transparentBlue = 0; - pConfigs[3].transparentAlpha = 0; - pConfigs[3].transparentIndex = 0; - break; - } - pMGA->numVisualConfigs = numConfigs; - pMGA->pVisualConfigs = pConfigs; - pMGA->pVisualConfigsPriv = pMGAConfigs; - GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pMGAConfigPtrs); - return TRUE; +static unsigned int mylog2(unsigned int n) +{ + unsigned int log2 = 1; + while (n>1) n >>= 1, log2++; + return log2; } + Bool MGADRIScreenInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -224,10 +304,24 @@ Bool MGADRIScreenInit(ScreenPtr pScreen) DRIInfoPtr pDRIInfo; MGADRIPtr pMGADRI; MGADRIServerPrivatePtr pMGADRIServer; - int bufs; - int prim_size; - int init_offset; + int bufs, size; + int prim_size; + int init_offset; + int i; +#if XFree86LOADER + /* Check that the GLX, DRI, and DRM modules have been loaded by testing + * for canonical symbols in each module. */ + if (!LoaderSymbol("GlxSetVisualConfigs")) return FALSE; + if (!LoaderSymbol("DRIScreenInit")) return FALSE; + if (!LoaderSymbol("drmAvailable")) return FALSE; +#endif + + if((pScrn->bitsPerPixel / 8) != 2) { + ErrorF("Direct Rendering only supported in 16 bpp mode\n"); + return FALSE; + } + pDRIInfo = DRICreateInfoRec(); if (!pDRIInfo) return FALSE; pMGA->pDRIInfo = pDRIInfo; @@ -247,28 +341,25 @@ Bool MGADRIScreenInit(ScreenPtr pScreen) pDRIInfo->frameBufferStride = pScrn->displayWidth*(pScrn->bitsPerPixel/8); pDRIInfo->ddxDrawableTableEntry = MGA_MAX_DRAWABLES; + MGADRIWrapFunctions( pScreen, pDRIInfo ); + if (SAREA_MAX_DRAWABLES < MGA_MAX_DRAWABLES) pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; else pDRIInfo->maxDrawableTableEntry = MGA_MAX_DRAWABLES; -#ifdef NOT_DONE - /* FIXME need to extend DRI protocol to pass this size back to client - * for SAREA mapping that includes a device private record - */ - pDRIInfo->SAREASize = - ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ - /* + shared memory device private rec */ -#else /* For now the mapping works by using a fixed size defined * in the SAREA header */ - if (sizeof(XF86DRISAREARec)+sizeof(drm_mga_sarea_t)>SAREA_MAX) { + if (sizeof(XF86DRISAREARec)+sizeof(MGASAREARec)>SAREA_MAX) { ErrorF("Data does not fit in SAREA\n"); return FALSE; } + + ErrorF("\n\n\nSarea %d+%d: %d\n", sizeof(XF86DRISAREARec), + sizeof(MGASAREARec), sizeof(XF86DRISAREARec) + sizeof(MGASAREARec)); + pDRIInfo->SAREASize = SAREA_MAX; -#endif if (!(pMGADRI = (MGADRIPtr)xnfcalloc(sizeof(MGADRIRec),1))) { DRIDestroyInfoRec(pMGA->pDRIInfo); @@ -277,7 +368,7 @@ Bool MGADRIScreenInit(ScreenPtr pScreen) return FALSE; } if (!(pMGADRIServer = (MGADRIServerPrivatePtr) - xnfcalloc(sizeof(MGADRIServerPrivate),1))) { + xnfcalloc(sizeof(MGADRIServerPrivateRec),1))) { xfree(pMGADRI); DRIDestroyInfoRec(pMGA->pDRIInfo); pMGA->pDRIInfo=0; @@ -334,25 +425,44 @@ Bool MGADRIScreenInit(ScreenPtr pScreen) pMGADRIServer->regs); /* Agp Support */ + pMGADRIServer->agpAcquired = FALSE; + pMGADRIServer->agpHandle = 0; + pMGADRIServer->agpSizep = 0; + pMGADRIServer->agp_map = 0; + if(drmAgpAcquire(pMGA->drmSubFD) < 0) { DRICloseScreen(pScreen); ErrorF("drmAgpAcquire failed\n"); return FALSE; } + pMGADRIServer->agpAcquired = TRUE; + pMGADRIServer->warp_ucode_size = mgaGetMicrocodeSize(pScreen); if(pMGADRIServer->warp_ucode_size == 0) { ErrorF("microcodeSize is zero\n"); DRICloseScreen(pScreen); return FALSE; } + + pMGADRIServer->agpMode = drmAgpGetMode(pMGA->drmSubFD); + /* Default to 1X agp mode */ + pMGADRIServer->agpMode &= ~0x00000002; + if (drmAgpEnable(pMGA->drmSubFD, pMGADRIServer->agpMode) < 0) { + ErrorF("drmAgpEnable failed\n"); + DRICloseScreen(pScreen); + return FALSE; + } + ErrorF("drmAgpEnabled succeeded\n"); prim_size = 65536; init_offset = ((prim_size + pMGADRIServer->warp_ucode_size + 4096 - 1) / 4096) * 4096; - pMGADRIServer->agpSizep = drmAgpSize(pMGA->drmSubFD); - pMGADRIServer->agpBase = drmAgpBase(pMGA->drmSubFD); - if (drmAddMap(pMGA->drmSubFD, (drmHandle)pMGADRIServer->agpBase, + pMGADRIServer->agpSizep = init_offset; + pMGADRI->agpSize = (drmAgpSize(pMGA->drmSubFD)) - init_offset; + + pMGADRIServer->agpBase = (drmAddress) drmAgpBase(pMGA->drmSubFD); + if (drmAddMap(pMGA->drmSubFD, 0, init_offset, DRM_AGP, 0, &pMGADRIServer->agp_private) < 0) { DRICloseScreen(pScreen); @@ -370,12 +480,15 @@ Bool MGADRIScreenInit(ScreenPtr pScreen) /* Now allocate and bind a default of 8 megs */ - pMGADRIServer->agpHandle = drmAgpAlloc(pMGA->drmSubFD, 0x00800000, 0, 0); + drmAgpAlloc(pMGA->drmSubFD, 0x00800000, 0, 0, + &pMGADRIServer->agpHandle); + if(pMGADRIServer->agpHandle == 0) { ErrorF("drmAgpAlloc failed\n"); DRICloseScreen(pScreen); return FALSE; } + if(drmAgpBind(pMGA->drmSubFD, pMGADRIServer->agpHandle, 0) < 0) { DRICloseScreen(pScreen); ErrorF("drmAgpBind failed\n"); @@ -384,72 +497,115 @@ Bool MGADRIScreenInit(ScreenPtr pScreen) mgaInstallMicrocode(pScreen, prim_size); - ErrorF("init_offset: %x\n", init_offset); - pMGADRI->agpSize = pMGADRIServer->agpSizep - init_offset; - ErrorF("pMGADRI->agpSize: %x\n", pMGADRI->agpSize); - - if(drmAddMap(pMGA->drmSubFD, (drmHandle)pMGADRIServer->agpBase + init_offset, + if(drmAddMap(pMGA->drmSubFD, (drmHandle)init_offset, pMGADRI->agpSize, DRM_AGP, 0, &pMGADRI->agp) < 0) { ErrorF("Failed to map public agp area\n"); DRICloseScreen(pScreen); return FALSE; } - ErrorF("Mapped public agp area\n"); + + + switch(pMGA->Chipset) { + case PCI_CHIP_MGAG400: + pMGADRI->chipset = MGA_CARD_TYPE_G400; + break; + case PCI_CHIP_MGAG200: +#if 0 + pMGADRI->chipset = MGA_CARD_TYPE_G200; + break; +#endif + case PCI_CHIP_MGAG200_PCI: + default: + ErrorF("Direct rendering not supported on this card/chipset\n"); + return FALSE; + } + + + pMGADRI->width = pScrn->virtualX; + pMGADRI->height = pScrn->virtualY; + pMGADRI->mem = pScrn->videoRam * 1024; + pMGADRI->cpp = pScrn->bitsPerPixel / 8; + pMGADRI->frontPitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8); + + + pMGADRI->frontOffset = 0; /* pMGA->YDstOrg * (pScrn->bitsPerPixel / 8) */ + pMGADRI->backOffset = ((pScrn->virtualY+129) * pScrn->displayWidth * + (pScrn->bitsPerPixel / 8) + 4095) & ~0xFFF; + + + fprintf(stderr, "calced backoffset: 0x%x\n", + pMGADRI->backOffset); + + +#if 0 + size = 2 * pScrn->virtualX * pScrn->virtualY; + pMGADRI->depthOffset = (pMGADRI->backOffset + size + 4095) & ~0xFFF; + pMGADRI->textureOffset = pMGADRI->depthOffset + size; + pMGADRI->textureSize = pMGA->FbUsableSize - pMGADRI->textureOffset; +#else + size = 2 * pScrn->virtualX * pScrn->virtualY; + size += 4095; + size &= ~4095; + pMGADRI->depthOffset = pMGA->FbUsableSize - size; + pMGADRI->depthOffset &= ~4095; + pMGADRI->textureOffset = pMGADRI->backOffset + size; + pMGADRI->textureSize = pMGADRI->depthOffset - pMGADRI->textureOffset; + + if (pMGADRI->depthOffset < pMGADRI->textureOffset + 512*1024) { + ErrorF("Insufficient memory for direct rendering\n"); + DRICloseScreen(pScreen); + return FALSE; + } +#endif + + pMGADRI->mAccess = pMGA->MAccess; + + i = mylog2(pMGADRI->textureSize / MGA_NR_TEX_REGIONS); + if (i < MGA_LOG_MIN_TEX_REGION_SIZE) + i = MGA_LOG_MIN_TEX_REGION_SIZE; + + pMGADRI->logTextureGranularity = i; + pMGADRI->textureSize = (pMGADRI->textureSize >> i) << i; /* truncate */ + + + /* Calculate similar constants for AGP texture space + */ + i = mylog2(pMGADRI->agpSize / MGA_NR_TEX_REGIONS); + if (i < MGA_LOG_MIN_TEX_REGION_SIZE) + i = MGA_LOG_MIN_TEX_REGION_SIZE; + + pMGADRI->logAgpTextureGranularity = i; + pMGADRI->agpTextureSize = (pMGADRI->agpSize >> i) << i; + + /* Here is where we need to do initialization of the dma engine */ - - pMGADRIServer->agpMode = drmAgpGetMode(pMGA->drmSubFD); - /* Default to 1X agp mode */ - pMGADRIServer->agpMode &= ~0x00000002; - if (drmAgpEnable(pMGA->drmSubFD, pMGADRIServer->agpMode) < 0) { - ErrorF("drmAgpEnable failed\n"); - DRICloseScreen(pScreen); - return FALSE; - } - ErrorF("drmAgpEnabled succeeded\n"); - if((bufs = drmAddBufs(pMGA->drmSubFD, - /*63*/ 15, - /* 65536 */ 524288, + if((bufs = drmAddBufs(pMGA->drmSubFD, + MGA_DMA_BUF_NR, + MGA_DMA_BUF_SZ, DRM_AGP_BUFFER, init_offset)) <= 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] failure adding %d %d byte DMA buffers\n", - /* 63 */ 15, - /* 65536 */ 524288); + MGA_DMA_BUF_NR, + MGA_DMA_BUF_SZ); DRICloseScreen(pScreen); return FALSE; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] added %d %d byte DMA buffers\n", - bufs, /* 65536 */ 524288); + bufs, MGA_DMA_BUF_SZ); - if((mgadrmInitDma(pScrn, prim_size)) != TRUE) { + if((MgaInitDma(pScrn, prim_size)) != TRUE) { ErrorF("Failed to initialize dma engine\n"); DRICloseScreen(pScreen); return FALSE; } - - ErrorF("Initialized Dma Engine\n"); + ErrorF("Initialized Dma Engine\n"); - if(drmMarkBufs(pMGA->drmSubFD, 0.133333, 0.266666) != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "[drm] failure marking DMA buffers\n"); - DRICloseScreen(pScreen); - return FALSE; - } - if (!(pMGADRIServer->drmBufs = drmMapBufs(pMGA->drmSubFD))) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "[drm] failure mapping DMA buffers\n"); - DRICloseScreen(pScreen); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] buffers mapped with %p\n", - pMGADRIServer->drmBufs); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] %d DMA buffers mapped\n", - pMGADRIServer->drmBufs->count); if (!pMGADRIServer->irq) { pMGADRIServer->irq = drmGetInterruptFromBusID(pMGA->drmSubFD, ((pciConfigPtr)pMGA->PciInfo @@ -481,16 +637,26 @@ MGADRICloseScreen(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; MGAPtr pMGA = MGAPTR(pScrn); MGADRIServerPrivatePtr pMGADRIServer = pMGA->DRIServerInfo; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "[drm] unmapping %d buffers\n", - pMGADRIServer->drmBufs->count); - if (drmUnmapBufs(pMGADRIServer->drmBufs)) { - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] unable to unmap DMA buffers\n"); + + MgaCleanupDma(pScrn); + + if(pMGADRIServer->agp_map) { + ErrorF("Unmapped agp region\n"); + drmUnmap(pMGADRIServer->agp_map, pMGADRIServer->agpSizep); + pMGADRIServer->agp_map = 0; } - mgadrmCleanupDma(pScrn); - + if(pMGADRIServer->agpHandle) { + ErrorF("Freeing agp memory\n"); + drmAgpFree(pMGA->drmSubFD, pMGADRIServer->agpHandle); + pMGADRIServer->agpHandle = 0; + pMGADRIServer->agpSizep = 0; + } + if(pMGADRIServer->agpAcquired == TRUE) { + ErrorF("releasing agp module\n"); + drmAgpRelease(pMGA->drmSubFD); + pMGADRIServer->agpAcquired = FALSE; + } + DRICloseScreen(pScreen); if (pMGA->pDRIInfo) { @@ -518,9 +684,6 @@ MGACreateContext(ScreenPtr pScreen, VisualPtr visual, drmContext hwContext, void *pVisualConfigPriv, DRIContextType contextStore) { - MGADRIContextPtr ctx; - - ctx = (MGADRIContextPtr)contextStore; return TRUE; } @@ -528,106 +691,120 @@ static void MGADestroyContext(ScreenPtr pScreen, drmContext hwContext, DRIContextType contextStore) { - MGADRIContextPtr ctx; - ctx = (MGADRIContextPtr)contextStore; } Bool MGADRIFinishScreenInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGASAREAPtr sPriv; MGAPtr pMGA = MGAPTR(pScrn); - MGADRIPtr pMGADRI; - int size; + if (!pMGA->pDRIInfo) return FALSE; + + sPriv = (MGASAREAPtr)DRIGetSAREAPrivate(pScreen); pMGA->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; - /* pMGA->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */ - pMGADRI = (MGADRIPtr)pMGA->pDRIInfo->devPrivate; - pMGADRI->deviceID = pMGA->PciInfo->chipType; - pMGADRI->width = pScrn->virtualX; - pMGADRI->height = pScrn->virtualY; - pMGADRI->mem = pScrn->videoRam * 1024; - pMGADRI->cpp = pScrn->bitsPerPixel / 8; - pMGADRI->stride = pScrn->displayWidth * (pScrn->bitsPerPixel / 8); - pMGADRI->backOffset = ((pScrn->virtualY+129) * pScrn->displayWidth * - (pScrn->bitsPerPixel / 8) + 4095) & ~0xFFF; - size = 2 * pScrn->virtualX * pScrn->virtualY; - pMGADRI->depthOffset = (pMGADRI->backOffset + size + 4095) & ~0xFFF; - pMGADRI->textureOffset = pMGADRI->depthOffset + size; - /* - * The rest of the framebuffer is for textures except for the - * memory for the hardware cursor. - */ - pMGADRI->textureSize = pMGA->FbUsableSize - pMGADRI->textureOffset; - pMGADRI->fbOffset = pMGA->YDstOrg * (pScrn->bitsPerPixel / 8); + xf86memset( sPriv, 0, sizeof(MGASAREARec) ); return DRIFinishScreenInit(pScreen); } -void MGASwapContext(ScreenPtr pScreen) + +void mgaGetQuiescence( ScrnInfoPtr pScrn ) { -#if 0 - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - MGAPtr pMga = MGAPTR(pScrn); - MGAFBLayout *pLayout = &pMga->CurrentLayout; - - usleep(500); - ErrorF("Syncing : swap\n"); - MGABUSYWAIT(); - ErrorF("Sync : swap 1\n"); - MGAStormSync(pScrn); - ErrorF("Syncing done\n"); - pMga->AccelInfoRec->NeedToSync = TRUE; - - WAITFIFO(12); - OUTREG(MGAREG_MACCESS, pMga->MAccess); - OUTREG(MGAREG_PITCH, pLayout->displayWidth); - OUTREG(MGAREG_YDSTORG, pMga->YDstOrg); - OUTREG(MGAREG_PLNWT, pMga->PlaneMask); - OUTREG(MGAREG_BCOL, pMga->BgColor); - OUTREG(MGAREG_FCOL, pMga->FgColor); - OUTREG(MGAREG_SRCORG, pMga->SrcOrg); - OUTREG(MGAREG_DSTORG, pMga->DstOrg); - OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT); - OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */ - OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */ - OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */ - pMga->AccelFlags &= ~CLIPPER_ON; -#endif + MGAPtr pMga = MGAPTR(pScrn); + + pMga->have_quiescense = 1; + + if (pMga->directRenderingEnabled) { + MGAFBLayout *pLayout = &pMga->CurrentLayout; + + MgaLockUpdate(pScrn, (DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH)); + + WAITFIFO(12); + OUTREG(MGAREG_MACCESS, pMga->MAccess); + OUTREG(MGAREG_PITCH, pLayout->displayWidth); + OUTREG(MGAREG_YDSTORG, pMga->YDstOrg); + OUTREG(MGAREG_PLNWT, pMga->PlaneMask); + OUTREG(MGAREG_BCOL, pMga->BgColor); + OUTREG(MGAREG_FCOL, pMga->FgColor); + OUTREG(MGAREG_SRCORG, pMga->SrcOrg); + OUTREG(MGAREG_DSTORG, pMga->DstOrg); + OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT); + OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */ + OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */ + OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */ + pMga->AccelFlags &= ~CLIPPER_ON; + } } -void MGALostContext(ScreenPtr pScreen) + + +void MGASwapContext(ScreenPtr pScreen) { -#if 0 - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - MGAPtr pMga = MGAPTR(pScrn); - MGAFBLayout *pLayout = &pMga->CurrentLayout; - - ErrorF("Syncing : lost\n"); - MGAStormSync(pScrn); - ErrorF("Sync : lost 1\n"); - MGABUSYWAIT(); - ErrorF("Syncing done\n"); -#endif + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMga = MGAPTR(pScrn); + + /* Arrange for dma_quiescence and xaa sync to be called as + * appropriate. + */ + pMga->have_quiescense = 0; + pMga->AccelInfoRec->NeedToSync = TRUE; } + + +/* This is really only called from validate/postvalidate as we + * override the dri lock/unlock. Want to remove validate/postvalidate + * processing, but need to remove all client-side use of drawable lock + * first (otherwise there is noone recover when a client dies holding + * the drawable lock). + * + * What does this mean? + * + * - The above code gets executed every time a + * window changes shape or the focus changes, which isn't really + * optimal. + * - The X server therefore believes it needs to do an XAA sync + * *and* a dma quiescense ioctl each time that happens. + * + * We don't wrap wakeuphandler any longer, so at least we can say that + * this doesn't happen *every time the mouse moves*... + */ static void MGADRISwapContext(ScreenPtr pScreen, DRISyncType syncType, DRIContextType oldContextType, void *oldContext, DRIContextType newContextType, void *newContext) { - if ((syncType == DRI_3D_SYNC) && (oldContextType == DRI_2D_CONTEXT) && - (newContextType == DRI_2D_CONTEXT)) { /* Entering from Wakeup */ - MGASwapContext(pScreen); - } - if ((syncType == DRI_2D_SYNC) && (oldContextType == DRI_NO_CONTEXT) && - (newContextType == DRI_2D_CONTEXT)) { /* Exiting from Block Handler */ - MGALostContext(pScreen); - } + if (syncType == DRI_3D_SYNC && + oldContextType == DRI_2D_CONTEXT && + newContextType == DRI_2D_CONTEXT) + { + MGASwapContext(pScreen); + } } -/* Needs to be written */ -void MGASelectBuffer(MGAPtr pMGA, int which) + +void +MGASelectBuffer(ScrnInfoPtr pScrn, int which) { + MGAPtr pMga = MGAPTR(pScrn); + MGADRIPtr pMGADRI = (MGADRIPtr)pMga->pDRIInfo->devPrivate; + + switch (which) { + case MGA_BACK: + OUTREG(MGAREG_DSTORG, pMGADRI->backOffset); + OUTREG(MGAREG_SRCORG, pMGADRI->backOffset); + break; + case MGA_DEPTH: + OUTREG(MGAREG_DSTORG, pMGADRI->depthOffset); + OUTREG(MGAREG_SRCORG, pMGADRI->depthOffset); + break; + default: + case MGA_FRONT: + OUTREG(MGAREG_DSTORG, pMGADRI->frontOffset); + OUTREG(MGAREG_SRCORG, pMGADRI->frontOffset); + break; + } } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h index 7196bc954..2d35a6a89 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h @@ -4,9 +4,11 @@ #define _MGA_DRI_ #include <xf86drm.h> -#include "mga_drm_public.h" +#include <xf86drmMga.h> -typedef struct _mga_dri_server_private { +#define MGA_MAX_DRAWABLES 256 + +typedef struct { int reserved_map_agpstart; int reserved_map_idx; int buffer_map_idx; @@ -17,6 +19,7 @@ typedef struct _mga_dri_server_private { int sgram; unsigned long agpMode; unsigned long agpHandle; + Bool agpAcquired; drmHandle agp_private; drmSize agpSizep; drmAddress agpBase; @@ -24,27 +27,110 @@ typedef struct _mga_dri_server_private { drmHandle regs; drmSize regsSize; drmAddress regsMap; - mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES]; + drmMgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES]; drmBufMapPtr drmBufs; CARD8 *agp_map; -} MGADRIServerPrivate, *MGADRIServerPrivatePtr; +} MGADRIServerPrivateRec, *MGADRIServerPrivatePtr; typedef struct { - int deviceID; - int width; - int height; - int mem; - int cpp; - int stride; - int fbOffset; - int backOffset; - int depthOffset; - int textureOffset; - int textureSize; - drmHandle agp; - drmSize agpSize; + int chipset; + int width; + int height; + int mem; + int cpp; + int frontOffset; + int frontPitch; + + int backOffset; + int backPitch; + + int depthOffset; + int depthPitch; + + int textureOffset; + int textureSize; + int logTextureGranularity; + + int agpTextureSize; + int logAgpTextureGranularity; + + /* Redundant? + */ + unsigned int frontOrg; + unsigned int backOrg; + unsigned int depthOrg; + + unsigned int mAccess; + + drmHandle agp; + drmSize agpSize; } MGADRIRec, *MGADRIPtr; +/* WARNING: Do not change the SAREA structure without changing the kernel + * as well */ +typedef struct { + unsigned char next, prev; + unsigned char in_use; + int age; +} MGATexRegionRec, *MGATexRegionPtr; + +typedef struct { + /* The channel for communication of state information to the kernel + * on firing a vertex dma buffer. + */ + unsigned int ContextState[MGA_CTX_SETUP_SIZE]; + unsigned int ServerState[MGA_2D_SETUP_SIZE]; + unsigned int TexState[2][MGA_TEX_SETUP_SIZE]; + unsigned int WarpPipe; + unsigned int dirty; + + unsigned int nbox; + XF86DRIClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS]; + + /* Information about the most recently used 3d drawable. The + * client fills in the req_* fields, the server fills in the + * exported_ fields and puts the cliprects into boxes, above. + * + * The client clears the exported_drawable field before + * clobbering the boxes data. + */ + unsigned int req_drawable; /* the X drawable id */ + unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */ + + unsigned int exported_drawable; + unsigned int exported_index; + unsigned int exported_stamp; + unsigned int exported_buffers; + unsigned int exported_nfront; + unsigned int exported_nback; + int exported_back_x, exported_front_x, exported_w; + int exported_back_y, exported_front_y, exported_h; + XF86DRIClipRectRec exported_boxes[MGA_NR_SAREA_CLIPRECTS]; + + /* Counters for aging textures and for client-side throttling. + */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int last_quiescent; /* */ + + /* LRU lists for texture memory in agp space and on the card */ + + MGATexRegionRec texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1]; + unsigned int texAge[MGA_NR_TEX_HEAPS]; + /* Mechanism to validate card state. + */ + int ctxOwner; +} MGASAREARec, *MGASAREAPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} MGAConfigPrivRec, *MGAConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} MGADRIContextRec, *MGADRIContextPtr; #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dripriv.h deleted file mode 100644 index 841c17cb9..000000000 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dripriv.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dripriv.h,v 1.1 2000/02/11 17:25:55 dawes Exp $ */ - -#ifndef _MGA_DRIPRIV_H_ -#define _MGA_DRIPRIV_H_ - -#define MGA_MAX_DRAWABLES 256 - -extern void GlxSetVisualConfigs( - int nconfigs, - __GLXvisualConfig *configs, - void **configprivs -); - -typedef struct { - /* Nothing here yet */ - int dummy; -} MGAConfigPrivRec, *MGAConfigPrivPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} MGADRIContextRec, *MGADRIContextPtr; - -#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c index 85a529068..6f95b8d87 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c @@ -15,8 +15,8 @@ * to be based on Radoslaw's original source * * Contributors: - * Andrew Vanderstock, Melbourne, Australia - * vanderaj@mail2.svhm.org.au + * Andrew van der Stock + * ajv@greebo.net * additions, corrections, cleanups * * Dirk Hohndel @@ -43,7 +43,7 @@ * Fixed 32bpp hires 8MB horizontal line glitch at middle right */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.114 1999/08/28 14:32:47 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.149 2000/03/07 01:37:49 dawes Exp $ */ /* * This is a first cut at a non-accelerated version to work with the @@ -76,8 +76,9 @@ #include "micmap.h" #include "xf86DDC.h" - #include "xf86RAC.h" +#include "vbe.h" + /* * If using cfb, cfb.h is required. Select the others for the bpp values @@ -102,8 +103,9 @@ #include "shadowfb.h" #include "fbdevhw.h" -#include "xf86xv.h" -#include "Xv.h" +#ifdef XF86DRI +#include "dri.h" +#endif /* @@ -111,6 +113,7 @@ */ /* Mandatory functions */ +static OptionInfoPtr MGAAvailableOptions(int chipid, int busid); static void MGAIdentify(int flags); static Bool MGAProbe(DriverPtr drv, int flags); static Bool MGAPreInit(ScrnInfoPtr pScrn, int flags); @@ -120,7 +123,7 @@ static Bool MGAEnterVT(int scrnIndex, int flags); static Bool MGAEnterVTFBDev(int scrnIndex, int flags); static void MGALeaveVT(int scrnIndex, int flags); static Bool MGACloseScreen(int scrnIndex, ScreenPtr pScreen); -static Bool MGASaveScreen(ScreenPtr pScreen, Bool unblank); +static Bool MGASaveScreen(ScreenPtr pScreen, int mode); /* This shouldn't be needed since RAC will disable all I/O for MGA cards. */ #ifdef DISABLE_VGA_IO @@ -162,9 +165,13 @@ static Bool MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); DriverRec MGA = { VERSION, + MGA_DRIVER_NAME, +#if 0 "accelerated driver for Matrox Millennium and Mystique cards", +#endif MGAIdentify, MGAProbe, + MGAAvailableOptions, NULL, 0 }; @@ -208,6 +215,7 @@ typedef enum { OPTION_COLOR_KEY, OPTION_SET_MCLK, OPTION_OVERCLOCK_MEM, + OPTION_VIDEO_KEY, OPTION_ROTATE } MGAOpts; @@ -225,6 +233,7 @@ static OptionInfoRec MGAOptions[] = { { OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE }, { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE }, { OPTION_OVERCLOCK_MEM, "OverclockMem", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -287,6 +296,46 @@ static const char *ramdacSymbols[] = { NULL }; +#ifdef XF86DRI +static const char *drmSymbols[] = { + "drmAvailable", + "drmAddBufs", + "drmAddMap", + "drmCtlInstHandler", + "drmGetInterruptFromBusID", + "drmAgpAcquire", + "drmAgpRelease", + "drmAgpEnable", + "drmAgpAlloc", + "drmAgpFree", + "drmAgpBind", + "drmAgpGetMode", + "drmAgpBase", + "drmAgpSize", + "drmMgaCleanupDma", + "drmMgaLockUpdate", + "drmMgaInitDma", + NULL +}; + +static const char *driSymbols[] = { + "DRIGetDrawableIndex", + "DRIFinishScreenInit", + "DRIDestroyInfoRec", + "DRICloseScreen", + "DRIDestroyInfoRec", + "DRIScreenInit", + "DRIDestroyInfoRec", + "DRICreateInfoRec", + "DRILock", + "DRIUnlock", + "DRIGetSAREAPrivate", + "DRIGetContext", + "GlxSetVisualConfigs", + NULL +}; +#endif + #define MGAuseI2C 1 static const char *ddcSymbols[] = { @@ -309,6 +358,12 @@ static const char *shadowSymbols[] = { NULL }; +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + NULL +}; + static const char *fbdevHWSymbols[] = { "fbdevHWInit", "fbdevHWUseBuildinMode", @@ -381,7 +436,12 @@ mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin) LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols, xf8_32bppSymbols, ramdacSymbols, ddcSymbols, i2cSymbols, shadowSymbols, - fbdevHWSymbols, NULL); + fbdevHWSymbols, vbeSymbols, +#ifdef XF86DRI + drmSymbols, driSymbols, +#endif + + NULL); /* * The return value must be non-NULL on success even though there @@ -439,6 +499,12 @@ MGAFreeRec(ScrnInfoPtr pScrn) pScrn->driverPrivate = NULL; } +static +OptionInfoPtr +MGAAvailableOptions(int chipid, int busid) +{ + return MGAOptions; +} /* Mandatory */ static void @@ -453,7 +519,7 @@ static Bool MGAProbe(DriverPtr drv, int flags) { int i; - GDevPtr *devSections; + GDevPtr *devSections = NULL; int *usedChips; int numDevSections; int numUsed; @@ -509,12 +575,15 @@ MGAProbe(DriverPtr drv, int flags) MGAChipsets, MGAPciChipsets, devSections, numDevSections, drv, &usedChips); /* Free it since we don't need that list after this */ - xfree(devSections); + if (devSections) + xfree(devSections); devSections = NULL; if (numUsed <= 0) return FALSE; - for (i = 0; i < numUsed; i++) { + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { ScrnInfoPtr pScrn; #ifdef DISABLE_VGA_IO MgaSavePtr smga; @@ -694,8 +763,6 @@ MGAReadBios(ScrnInfoPtr pScrn) ErrorF("Pins[0x%02x] is 0x%02x\n", i, ((unsigned char *)pBios2)[i]); #endif - ErrorF("0x20 of Pins[0x34] is %s\n", - (pBios2->VidCtrl & 0x20) ? "set" : "cleared"); return; } else { /* Set default MCLK values (scaled by 10 kHz) */ @@ -719,7 +786,7 @@ static void MGASoftReset(ScrnInfoPtr pScrn) { MGAPtr pMga = MGAPTR(pScrn); - int i; +/* int i; */ pMga->FbMapSize = 8192 * 1024; MGAMapMem(pScrn); @@ -733,6 +800,9 @@ MGASoftReset(ScrnInfoPtr pScrn) OUTREG(MGAREG_MACCESS, 1<<15); usleep(10); +#if 0 + /* This will hang if the PLLs aren't on */ + /* wait until drawing engine is ready */ while ( MGAISBUSY() ) usleep(1000); @@ -742,6 +812,7 @@ MGASoftReset(ScrnInfoPtr pScrn) WAITFIFO(i); while ( i-- ) OUTREG(MGAREG_SHIFT, 0); +#endif MGAUnmapMem(pScrn); } @@ -754,86 +825,99 @@ MGASoftReset(ScrnInfoPtr pScrn) static int MGACountRam(ScrnInfoPtr pScrn) { - MGAPtr pMga = MGAPTR(pScrn); - - if (pMga->FbAddress) - { - volatile unsigned char* base; - unsigned char tmp, tmp3, tmp5; - - pMga->FbMapSize = 8192 * 1024; - MGAMapMem(pScrn); - base = pMga->FbBase; - - /* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */ - OUTREG8(0x1FDE, 3); - tmp = INREG8(0x1FDF); - OUTREG8(0x1FDF, tmp | 0x80); - - /* write, read and compare method */ - base[0x500000] = 0x55; - base[0x300000] = 0x33; - base[0x100000] = 0x11; - tmp5 = base[0x500000]; - tmp3 = base[0x300000]; - - /* restore CRTCEXT3 state */ - OUTREG8(0x1FDE, 3); - OUTREG8(0x1FDF, tmp); - - MGAUnmapMem(pScrn); - - if(tmp5 == 0x55) - return 8192; - if(tmp3 == 0x33) - return 4096; - } - return 2048; -} + MGAPtr pMga = MGAPTR(pScrn); + int ProbeSize = 8192; + int SizeFound = 2048; + CARD32 biosInfo = 0; -/* - * GetAccelPitchValues - - * - * This function returns a list of display width (pitch) values that can - * be used in accelerated mode. - */ #if 0 -static int * -GetAccelPitchValues(ScrnInfoPtr pScrn) -{ - int *linePitches = NULL; - int i, n = 0; - MGAPtr pMga = MGAPTR(pScrn); - - /* XXX ajv - 512, 576, and 1536 may not be supported - line pitches. see sdk pp 4-59 for more - details. Why anyone would want less than 640 is - bizarre. (maybe lots of pixels tall?) */ - - /* The only line pitches the accelerator supports */ -#if 0 - int accelWidths[] = { 512, 576, 640, 768, 800, 960, - 1024, 1152, 1280, 1536, 1600, 1920, 2048, 0 }; -#else - int accelWidths[] = { 640, 768, 800, 960, 1024, 1152, 1280, - 1600, 1920, 2048, 0 }; + /* This isn't correct. It looks like this can have arbitrary + data for the memconfig even when the bios has initialized + it. At least, my cards don't advertise the documented + values (my 8 and 16 Meg G200s have the same values) */ + if(pMga->Primary) /* can only trust this for primary cards */ + biosInfo = pciReadLong(pMga->PciTag, PCI_OPTION_REG); #endif - for (i = 0; accelWidths[i] != 0; i++) { - if (accelWidths[i] % pMga->Rounding == 0) { - n++; - linePitches = xnfrealloc(linePitches, n * sizeof(int)); - linePitches[n - 1] = accelWidths[i]; + switch(pMga->Chipset) { + case PCI_CHIP_MGA2164: + case PCI_CHIP_MGA2164_AGP: + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unable to probe memory amount due to hardware bug. " + "Assuming 4096 KB\n"); + return 4096; + case PCI_CHIP_MGAG400: + if(biosInfo) { + switch((biosInfo >> 10) & 0x07) { + case 0: + return (biosInfo & (1 << 14)) ? 32768 : 16384; + case 1: + case 2: + return 16384; + case 3: + case 5: + return 65536; + case 4: + return 32768; + } } + ProbeSize = 32768; + break; + case PCI_CHIP_MGAG200: + case PCI_CHIP_MGAG200_PCI: + if(biosInfo) { + switch((biosInfo >> 11) & 0x03) { + case 0: + return 8192; + default: + return 16384; + } + } + ProbeSize = 16384; + break; + case PCI_CHIP_MGAG100: + if(biosInfo) /* I'm not sure if the docs are correct */ + return (biosInfo & (1 << 12)) ? 16384 : 8192; + case PCI_CHIP_MGA1064: + case PCI_CHIP_MGA2064: + ProbeSize = 8192; + break; + default: + break; } - /* Mark the end of the list */ - if (n > 0) { - linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int)); - linePitches[n] = 0; - } - return linePitches; + + if (pMga->FbAddress) { + volatile unsigned char* base; + unsigned char tmp; + int i; + + pMga->FbMapSize = ProbeSize * 1024; + MGAMapMem(pScrn); + base = pMga->FbBase; + + /* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */ + OUTREG8(0x1FDE, 3); + tmp = INREG8(0x1FDF); + OUTREG8(0x1FDF, tmp | 0x80); + + /* write, read and compare method */ + for(i = ProbeSize; i > 2048; i -= 2048) { + base[(i * 1024) - 1] = 0xAA; + OUTREG8(MGAREG_CRTC_INDEX, 0); /* flush the cache */ + if(base[(i * 1024) - 1] == 0xAA) { + SizeFound = i; + break; + } + } + + /* restore CRTCEXT3 state */ + OUTREG8(0x1FDE, 3); + OUTREG8(0x1FDF, tmp); + + MGAUnmapMem(pScrn); + } + return SizeFound; } -#endif static xf86MonPtr MGAdoDDC(ScrnInfoPtr pScrn) @@ -878,7 +962,6 @@ MGAdoDDC(ScrnInfoPtr pScrn) /* Initialize I2C bus - used by DDC if available */ if (pMga->i2cInit) { pMga->i2cInit(pScrn); -ErrorF("I2C initialized on %p\n",pMga->I2C); } /* Read and output monitor info using DDC2 over I2C bus */ if (pMga->I2C) { @@ -908,6 +991,8 @@ ErrorF("I2C initialized on %p\n",pMga->I2C); vgaHWUnmapMem(pScrn); } + xf86SetDDCproperties(pScrn, MonInfo); + return MonInfo; } @@ -970,6 +1055,18 @@ VgaIOEnable(void *arg) } #endif /* DISABLE_VGA_IO */ +extern xf86MonPtr ConfiguredMonitor; + +void +MGAProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,index); + ConfiguredMonitor = vbeDoEDID(pVbe); + } +} + /* Mandatory */ static Bool MGAPreInit(ScrnInfoPtr pScrn, int flags) @@ -1002,6 +1099,23 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) if (pScrn->numEntities != 1) return FALSE; + /* Allocate the MGARec driverPrivate */ + if (!MGAGetRec(pScrn)) { + return FALSE; + } + + pMga = MGAPTR(pScrn); + + /* Get the entity, and make sure it is PCI. */ + pMga->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (pMga->pEnt->location.type != BUS_PCI) + return FALSE; + + if (flags & PROBE_DETECT) { + MGAProbeDDC(pScrn, pMga->pEnt->index); + return TRUE; + } + /* The vgahw module should be loaded here when needed */ if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; @@ -1014,16 +1128,19 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) if (!vgaHWGetHWRec(pScrn)) return FALSE; - /* Allocate the MGARec driverPrivate */ - if (!MGAGetRec(pScrn)) { - return FALSE; - } - pMga = MGAPTR(pScrn); +#if 0 + /* This is causing problems with restoring the card to it's + original state. If this is to be done, it needs to happen + after we've saved the original state */ + /* Initialize the card through int10 interface if needed */ + if ( xf86LoadSubModule(pScrn, "int10")){ + xf86Int10InfoPtr pInt; - /* Get the entity, and make sure it is PCI. */ - pMga->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - if (pMga->pEnt->location.type != BUS_PCI) - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n"); + pInt = xf86InitInt10(pMga->pEnt->index); + xf86FreeInt10(pInt); + } +#endif /* Find the PCI info for this screen */ pMga->PciInfo = xf86GetPciInfoForEntity(pMga->pEnt->index); @@ -1060,8 +1177,6 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) xf86SetAccessFuncs(pMga->pEnt, &pMga->Access, &pMga->Access, &pMga->Access, NULL); #endif - - pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; /* Set pScrn->monitor */ pScrn->monitor = pScrn->confScreen->monitor; @@ -1120,17 +1235,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) } } - if (!xf86SetDefaultVisual(pScrn, -1)) { + if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; - } else { - /* We don't currently support DirectColor at > 8bpp */ - if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" - " (%s) is not supported at depth %d\n", - xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); - return FALSE; - } - } bytesPerPixel = pScrn->bitsPerPixel / 8; @@ -1144,20 +1250,52 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, MGAOptions); /* Set the bits per RGB for 8bpp mode */ - if (pScrn->depth == 8) { - /* XXX This is here just to test options. */ - /* Default to 8 */ + if (pScrn->depth == 8) pScrn->rgbBits = 8; -#if 0 - if (xf86GetOptValInteger(MGAOptions, OPTION_RGB_BITS, - &pScrn->rgbBits)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n", - pScrn->rgbBits); - } -#endif + + /* + * Set the Chipset and ChipRev, allowing config file entries to + * override. + */ + if (pMga->pEnt->device->chipset && *pMga->pEnt->device->chipset) { + pScrn->chipset = pMga->pEnt->device->chipset; + pMga->Chipset = xf86StringToToken(MGAChipsets, pScrn->chipset); + from = X_CONFIG; + } else if (pMga->pEnt->device->chipID >= 0) { + pMga->Chipset = pMga->pEnt->device->chipID; + pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset); + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", + pMga->Chipset); + } else { + from = X_PROBED; + pMga->Chipset = pMga->PciInfo->chipType; + pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset); + } + if (pMga->pEnt->device->chipRev >= 0) { + pMga->ChipRev = pMga->pEnt->device->chipRev; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + pMga->ChipRev); + } else { + pMga->ChipRev = pMga->PciInfo->chipRev; } + /* + * This shouldn't happen because such problems should be caught in + * MGAProbe(), but check it just in case. + */ + if (pScrn->chipset == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04X is not recognised\n", pMga->Chipset); + return FALSE; + } + if (pMga->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognised\n", pScrn->chipset); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); from = X_DEFAULT; pMga->HWCursor = TRUE; /* @@ -1199,10 +1337,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) } if ((s = xf86GetOptValString(MGAOptions, OPTION_OVERLAY))) { if (!*s || !xf86NameCmp(s, "8,24") || !xf86NameCmp(s, "24,8")) { - if(pMga->Chipset == PCI_CHIP_MGAG100) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Option \"Overlay\" is not supported by the G100\n"); - } else if(pScrn->bitsPerPixel == 32) { + if(pScrn->bitsPerPixel == 32) { pMga->Overlay8Plus24 = TRUE; if(!xf86GetOptValInteger( MGAOptions, OPTION_COLOR_KEY,&(pMga->colorKey))) @@ -1213,13 +1348,21 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) "PseudoColor overlay enabled\n"); } else { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Option \"Overlay\" is not supported in this configuration\n"); + "Option \"Overlay\" is only supported in 32 bits per pixel\n"); } } else { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid value for Option \"Overlay\"\n", s); } - } + } + if(xf86GetOptValInteger(MGAOptions, OPTION_VIDEO_KEY, &(pMga->videoKey))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", + pMga->videoKey); + } else { + pMga->videoKey = (1 << pScrn->offset.red) | + (1 << pScrn->offset.green) | + (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); + } if (xf86ReturnOptValBool(MGAOptions, OPTION_SHADOW_FB, FALSE)) { pMga->ShadowFB = TRUE; pMga->NoAccel = TRUE; @@ -1273,57 +1416,21 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) } } - - /* - * Set the Chipset and ChipRev, allowing config file entries to - * override. - */ - if (pMga->pEnt->device->chipset && *pMga->pEnt->device->chipset) { - pScrn->chipset = pMga->pEnt->device->chipset; - pMga->Chipset = xf86StringToToken(MGAChipsets, pScrn->chipset); - from = X_CONFIG; - } else if (pMga->pEnt->device->chipID >= 0) { - pMga->Chipset = pMga->pEnt->device->chipID; - pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset); - from = X_CONFIG; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", - pMga->Chipset); - } else { - from = X_PROBED; - pMga->Chipset = pMga->PciInfo->chipType; - pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset); - } - if (pMga->pEnt->device->chipRev >= 0) { - pMga->ChipRev = pMga->pEnt->device->chipRev; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", - pMga->ChipRev); - } else { - pMga->ChipRev = pMga->PciInfo->chipRev; - } - - /* - * This shouldn't happen because such problems should be caught in - * MGAProbe(), but check it just in case. - */ - if (pScrn->chipset == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "ChipID 0x%04X is not recognised\n", pMga->Chipset); - return FALSE; - } - if (pMga->Chipset < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Chipset \"%s\" is not recognised\n", pScrn->chipset); - return FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); - - if ((pMga->PciInfo->subsysCard == PCI_CARD_MILL_G200_SD) || + if(pMga->HasSDRAM) { /* don't bother checking */ } + else if ((pMga->PciInfo->subsysCard == PCI_CARD_MILL_G200_SD) || (pMga->PciInfo->subsysCard == PCI_CARD_MARV_G200_SD) || (pMga->PciInfo->subsysCard == PCI_CARD_MYST_G200_SD) || (pMga->PciInfo->subsysCard == PCI_CARD_PROD_G100_SD)) { pMga->HasSDRAM = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n"); + } + else if (pMga->Primary && (pMga->Chipset != PCI_CHIP_MGA2064) && + (pMga->Chipset != PCI_CHIP_MGA2164) && + (pMga->Chipset != PCI_CHIP_MGA2164_AGP)) { + if(!(pciReadLong(pMga->PciTag, PCI_OPTION_REG) & (1 << 14))) { + pMga->HasSDRAM = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n"); + } } switch (pMga->Chipset) { @@ -1464,28 +1571,21 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) /* * Reset card if it isn't primary one */ - if (!pMga->Primary && !pMga->FBDev) + if ( (!pMga->Primary && !pMga->FBDev) || xf86IsPc98() ) MGASoftReset(pScrn); + /* * If the user has specified the amount of memory in the XF86Config * file, we respect that setting. */ + from = X_PROBED; if (pMga->pEnt->device->videoRam != 0) { pScrn->videoRam = pMga->pEnt->device->videoRam; from = X_CONFIG; - } else if((pMga->Chipset == PCI_CHIP_MGA2164) || - (pMga->Chipset == PCI_CHIP_MGA2164_AGP)){ - pScrn->videoRam = 4096; - from = X_DEFAULT; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Skipping memory probe due to hardware bug. Assuming 4096 kBytes\n"); + } else if (pMga->FBDev) { + pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024; } else { - if (pMga->FBDev) { - pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024; - } else { - pScrn->videoRam = MGACountRam(pScrn); - } - from = X_PROBED; + pScrn->videoRam = MGACountRam(pScrn); } xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", pScrn->videoRam); @@ -1847,6 +1947,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) pMga->CurrentLayout.weight.green = pScrn->weight.green; pMga->CurrentLayout.weight.blue = pScrn->weight.blue; pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24; + pMga->CurrentLayout.mode = pScrn->currentMode; return TRUE; } @@ -1860,37 +1961,30 @@ static Bool MGAMapMem(ScrnInfoPtr pScrn) { MGAPtr pMga; - int mmioFlags; pMga = MGAPTR(pScrn); /* * Map IO registers to virtual address space */ -#if !defined(__alpha__) - mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT; -#else /* * For Alpha, we need to map SPARSE memory, since we need - * byte/short access. + * byte/short access. This is taken care of automatically by the + * os-support layer. */ - mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE; -#endif - pMga->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pMga->PciTag, - pMga->IOAddress, 0x4000); + pMga->IOBase = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, + pMga->PciTag, pMga->IOAddress, 0x4000); if (pMga->IOBase == NULL) return FALSE; #ifdef __alpha__ - /* - * for Alpha, we need to map DENSE memory as well, for - * setting CPUToScreenColorExpandBase. - */ - pMga->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pMga->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_MMIO | VIDMEM_MMIO_32BIT, pMga->PciTag, pMga->IOAddress, 0x4000); if (pMga->IOBaseDense == NULL) return FALSE; -#endif /* __alpha__ */ +#endif pMga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, pMga->PciTag, pMga->FbAddress, @@ -1905,7 +1999,8 @@ MGAMapMem(ScrnInfoPtr pScrn) DWORD access on DWORD boundaries to this window */ if (pMga->ILOADAddress) { pMga->ILOADBase = xf86MapPciMem(pScrn->scrnIndex, - VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, + VIDMEM_MMIO | VIDMEM_MMIO_32BIT | + VIDMEM_READSIDEEFFECT, pMga->PciTag, pMga->ILOADAddress, 0x800000); } else pMga->ILOADBase = NULL; @@ -1961,11 +2056,6 @@ MGAUnmapMem(ScrnInfoPtr pScrn) xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBase, 0x4000); pMga->IOBase = NULL; -#ifdef __alpha__ - xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBaseDense, 0x4000); - pMga->IOBaseDense = NULL; -#endif /* __alpha__ */ - xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->FbBase, pMga->FbMapSize); pMga->FbBase = NULL; pMga->FbStart = NULL; @@ -2039,9 +2129,16 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) vgaReg = &hwp->ModeReg; mgaReg = &pMga->ModeReg; +#ifdef XF86DRI + if (pMga->directRenderingEnabled) { + DRILock(screenInfo.screens[pScrn->scrnIndex], 0); +/* MGADRISwapContext(screenInfo.screens[pScrn->scrnIndex]); */ + } +#endif + (*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE); - - MGAStormSync(pScrn); + + MGAStormSync(pScrn); /* JEFF - Check */ MGAStormEngineInit(pScrn); vgaHWProtect(pScrn, FALSE); @@ -2052,6 +2149,13 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) outb(0xfac, 0x02); } + pMga->CurrentLayout.mode = mode; + +#ifdef XF86DRI + if (pMga->directRenderingEnabled) + DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); +#endif + return TRUE; } @@ -2129,7 +2233,6 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000); if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; - MGAStormSync(pScrn); MGAStormEngineInit(pScrn); } else { /* Save the current state */ @@ -2141,7 +2244,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Darken the screen for aesthetic reasons and set the viewport */ - MGASaveScreen(pScreen, FALSE); + MGASaveScreen(pScreen, SCREEN_SAVER_ON); pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); /* @@ -2195,7 +2298,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if(pMga->ShadowFB) { pMga->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); - pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height); + pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height); displayWidth = pMga->ShadowPitch / (pScrn->bitsPerPixel >> 3); FBStart = pMga->ShadowPtr; } else { @@ -2203,6 +2306,19 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) FBStart = pMga->FbStart; } +#ifdef XF86DRI + /* + * Setup DRI after visuals have been established, but before cfbScreenInit + * is called. cfbScreenInit will eventually call into the drivers + * InitGLXVisuals call back. + */ + if (!pMga->NoAccel) + pMga->directRenderingEnabled = MGADRIScreenInit(pScreen); + else + pMga->directRenderingEnabled = FALSE; +#endif + + switch (pScrn->bitsPerPixel) { case 8: ret = cfbScreenInit(pScreen, FBStart, @@ -2276,6 +2392,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); /* Initialize software cursor. Must precede creation of the default colormap */ @@ -2309,9 +2426,11 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) RefreshAreaFuncPtr refreshArea = MGARefreshArea; if(pMga->Rotate) { - pMga->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = MGAPointerMoved; - + if (!pMga->PointerMoved) { + pMga->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = MGAPointerMoved; + } + switch(pScrn->bitsPerPixel) { case 8: refreshArea = MGARefreshArea8; break; case 16: refreshArea = MGARefreshArea16; break; @@ -2326,21 +2445,29 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #ifdef DPMSExtension xf86DPMSInit(pScreen, MGADisplayPowerManagementSet, 0); #endif - + +#ifdef XF86DRI + /* Initialize the Warp engine */ + if (pMga->directRenderingEnabled) { + pMga->directRenderingEnabled = mgaConfigureWarp(pScrn); + } + if (pMga->directRenderingEnabled) { + /* Now that mi, cfb, drm and others have done their thing, + * complete the DRI setup. + */ + pMga->directRenderingEnabled = MGADRIFinishScreenInit(pScreen); + } + if (pMga->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n"); + } +#endif + pScrn->memPhysBase = pMga->FbAddress; pScrn->fbOffset = pMga->YDstOrg * (pScrn->bitsPerPixel / 8); -#ifdef XvExtension - { - XF86VideoAdaptorPtr *ptr; - int n; - - n = xf86XVListGenericAdaptors(&ptr); - if (n) { - xf86XVScreenInit(pScreen, ptr, n); - } - } -#endif + MGAInitVideo(pScreen); pScreen->SaveScreen = MGASaveScreen; @@ -2384,14 +2511,8 @@ MGAAdjustFrame(int scrnIndex, int x, int y, int flags) pLayout = &pMga->CurrentLayout; - if(pMga->ShowCache && y && pScrn->vtSema) { - int lastline = pMga->FbUsableSize / - (pScrn->displayWidth * pScrn->bitsPerPixel/8); - - lastline -= pScrn->currentMode->VDisplay; + if(pMga->ShowCache && y && pScrn->vtSema) y += pScrn->virtualY - 1; - if(y > lastline) y = lastline; - } Base = (y * pLayout->displayWidth + x + pMga->YDstOrg) >> (3 - pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]); @@ -2430,7 +2551,17 @@ static Bool MGAEnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; +#ifdef XF86DRI + ScreenPtr pScreen; + MGAPtr pMGA; + pMGA = MGAPTR(pScrn); + if (pMGA->directRenderingEnabled) { + pScreen = screenInfo.screens[scrnIndex]; + DRIUnlock(pScreen); + } +#endif + if (!MGAModeInit(pScrn, pScrn->currentMode)) return FALSE; MGAAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); @@ -2441,9 +2572,18 @@ static Bool MGAEnterVTFBDev(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; +#ifdef XF86DRI + ScreenPtr pScreen; + MGAPtr pMGA; + + pMGA = MGAPTR(pScrn); + if (pMGA->directRenderingEnabled) { + pScreen = screenInfo.screens[scrnIndex]; + DRIUnlock(pScreen); + } +#endif fbdevHWEnterVT(scrnIndex,flags); - MGAStormSync(pScrn); MGAStormEngineInit(pScrn); return TRUE; } @@ -2461,12 +2601,24 @@ MGALeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; vgaHWPtr hwp = VGAHWPTR(pScrn); +#ifdef XF86DRI + ScreenPtr pScreen; + MGAPtr pMGA; +#endif MGARestore(pScrn); vgaHWLock(hwp); if (xf86IsPc98()) outb(0xfac, 0x00); +#ifdef XF86DRI + pMGA = MGAPTR(pScrn); + if (pMGA->directRenderingEnabled) { + pScreen = screenInfo.screens[scrnIndex]; + DRILock(pScreen, 0); + } +#endif + } @@ -2496,6 +2648,13 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen) vgaHWUnmapMem(pScrn); } } +#ifdef XF86DRI + if (pMga->directRenderingEnabled) { + MGADRICloseScreen(pScreen); + pMga->directRenderingEnabled=FALSE; + } +#endif + if (pMga->AccelInfoRec) XAADestroyInfoRec(pMga->AccelInfoRec); if (pMga->CursorInfoRec) @@ -2504,11 +2663,17 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen) xfree(pMga->ShadowPtr); if (pMga->DGAModes) xfree(pMga->DGAModes); + if (pMga->adaptor) + xfree(pMga->adaptor); + pScrn->vtSema = FALSE; if (xf86IsPc98()) outb(0xfac, 0x00); + if(pMga->BlockHandler) + pScreen->BlockHandler = pMga->BlockHandler; + pScreen->CloseScreen = pMga->CloseScreen; return (*pScreen->CloseScreen)(scrnIndex, pScreen); } @@ -2524,7 +2689,8 @@ MGAFreeScreen(int scrnIndex, int flags) * This only gets called when a screen is being deleted. It does not * get called routinely at the end of a server generation. */ - vgaHWFreeHWRec(xf86Screens[scrnIndex]); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); MGAFreeRec(xf86Screens[scrnIndex]); } @@ -2558,9 +2724,9 @@ MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) /* Mandatory */ static Bool -MGASaveScreen(ScreenPtr pScreen, Bool unblank) +MGASaveScreen(ScreenPtr pScreen, int mode) { - return vgaHWSaveScreen(pScreen, unblank); + return vgaHWSaveScreen(pScreen, mode); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_drm.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_drm.c deleted file mode 100644 index 6dbebb162..000000000 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_drm.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86Resources.h" -#include "xf86_ansic.h" -#include "compiler.h" -#include "xf86PciInfo.h" -#include "xf86Pci.h" -#include "xf86Priv.h" -#include "mga_bios.h" -#include "mga_reg.h" -#include "mga.h" -#include "mga_macros.h" -#include "mga_dri.h" - -#ifndef XFree86LOADER -#include <sys/stat.h> -#include <sys/mman.h> -#endif - -#include "xf86drm.h" -#include "drm.h" -#include "mga_drm_public.h" - -Bool mgadrmCleanupDma(ScrnInfoPtr pScrn) -{ - MGAPtr pMGA = MGAPTR(pScrn); - drm_mga_init_t init; - - memset(&init, 0, sizeof(drm_mga_init_t)); - init.func = MGA_CLEANUP_DMA; - - if(ioctl(pMGA->drmSubFD, DRM_IOCTL_MGA_INIT, &init)) { - ErrorF("Mga Dma Cleanup Failed\n"); - return FALSE; - } - - return TRUE; -} - -int mgadrmInitDma(ScrnInfoPtr pScrn, int prim_size) -{ - MGAPtr pMGA = MGAPTR(pScrn); - MGADRIPtr pMGADRI = (MGADRIPtr)pMGA->pDRIInfo->devPrivate; - MGADRIServerPrivatePtr pMGADRIServer = pMGA->DRIServerInfo; - drm_mga_init_t init; - - memset(&init, 0, sizeof(drm_mga_init_t)); - init.func = MGA_INIT_DMA; - init.reserved_map_agpstart = 0; - init.reserved_map_idx = 3; - init.buffer_map_idx = 4; - init.sarea_priv_offset = sizeof(XF86DRISAREARec); - init.primary_size = prim_size; - init.warp_ucode_size = pMGADRIServer->warp_ucode_size; - - switch(pMGA->Chipset) { - case PCI_CHIP_MGAG400: - init.chipset = MGA_CARD_TYPE_G400; - break; - case PCI_CHIP_MGAG200: - init.chipset = MGA_CARD_TYPE_G200; - break; - case PCI_CHIP_MGAG200_PCI: - default: - ErrorF("Direct rendering not supported on this card/chipset\n"); - return FALSE; - } - - init.fbOffset = pMGADRI->fbOffset; - init.backOffset = pMGADRI->backOffset; - init.depthOffset = pMGADRI->depthOffset; - init.textureOffset = pMGADRI->textureOffset; - init.textureSize = pMGADRI->textureSize; - init.cpp = pMGADRI->cpp; - init.stride = pMGADRI->stride; - - init.frontOrg = pMGA->DstOrg; - init.backOrg = pMGADRI->backOffset; /* */ - init.depthOrg = pMGADRI->textureOffset; - init.mAccess = pMGA->MAccess; - - if (pMGA->HasSDRAM) - init.sgram = 0; - else - init.sgram = 1; - - memcpy(&init.WarpIndex, &pMGADRIServer->WarpIndex, - sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES); - - - - ErrorF("Mga Dma Initialization start\n"); - - if(ioctl(pMGA->drmSubFD, DRM_IOCTL_MGA_INIT, &init)) { - ErrorF("Mga Dma Initialization Failed\n"); - return FALSE; - } - ErrorF("Mga Dma Initialization done\n"); - return TRUE; -} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h index 15d57b287..19b137740 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h,v 1.10 1999/08/14 10:49:48 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h,v 1.12 2000/02/11 17:25:57 dawes Exp $ */ #ifndef _MGA_MACROS_H_ #define _MGA_MACROS_H_ @@ -19,10 +19,23 @@ #define RGBEQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff)) +#ifdef XF86DRI +#define MGAREG_DWGSYNC 0x2c4c +#define MGA_SYNC_XTAG 0x275f4200 + +#define MGABUSYWAIT() do { \ +OUTREG(MGAREG_DWGSYNC, MGA_SYNC_XTAG); \ +while(INREG(MGAREG_DWGSYNC) != MGA_SYNC_XTAG) ; \ +}while(0); + +#endif + #define MGAISBUSY() (INREG8(MGAREG_Status + 2) & 0x01) -#define WAITFIFO(n) \ +#define WAITFIFO(cnt) \ if(!pMga->UsePCIRetry) {\ + register int n = cnt; \ + if(n > pMga->FifoSize) n = pMga->FifoSize; \ while(pMga->fifoCount < (n))\ pMga->fifoCount = INREG8(MGAREG_FIFOSTATUS);\ pMga->fifoCount -= n;\ @@ -71,4 +84,18 @@ WAITFIFO(1); \ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); } + +#ifdef XF86DRI +extern void mgaGetQuiescence( ScrnInfoPtr pScrn ); + +#define CHECK_DMA_QUIESCENT(pMGA, pScrn) { \ + if (!pMGA->have_quiescense) { \ + mgaGetQuiescence( pScrn ); \ + } \ +} +#else +#define CHECK_DMA_QUIESCENT(pMGA, pScrn) +#endif + + #endif /* _MGA_MACROS_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c index e97030796..903f6d279 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.59 1999/08/29 12:21:01 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.64 2000/02/12 20:45:24 dawes Exp $ */ /* All drivers should typically include these */ @@ -22,12 +22,21 @@ #include "miline.h" #include "servermd.h" +#ifdef XF86DRI +#include "cfb.h" +#include "GL/glxtokens.h" +#endif + #include "mga_bios.h" #include "mga.h" #include "mga_reg.h" #include "mga_map.h" #include "mga_macros.h" +#ifdef XF86DRI +#include "mga_dri.h" +#endif + static void MGANAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn, int srcX, int srcY, int dstX, int dstY, int w, int h); @@ -87,6 +96,14 @@ static void MGANAME(SubsequentDashedTwoPointLine)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int flags, int phase); +#ifdef XF86DRI +void MGANAME(DRIInitBuffers)(WindowPtr pWin, + RegionPtr prgn, CARD32 index); +void MGANAME(DRIMoveBuffers)(WindowPtr pParent, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 index); + +#endif + extern void MGAWriteBitmapColorExpand(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int skipleft, int fg, int bg, int rop, @@ -113,6 +130,9 @@ extern void MGAValidatePolyArc(GCPtr, unsigned long, DrawablePtr); extern void MGAValidatePolyPoint(GCPtr, unsigned long, DrawablePtr); extern void MGAFillCacheBltRects(ScrnInfoPtr, int, unsigned int, int, BoxPtr, int, int, XAACacheInfoPtr); +extern void MGATEGlyphRenderer(ScrnInfoPtr, int, int, int, int, int, int, + unsigned int **glyphs, int, int, int, int, + unsigned planemask); Bool MGANAME(AccelInit)(ScreenPtr pScreen) @@ -122,6 +142,9 @@ MGANAME(AccelInit)(ScreenPtr pScreen) MGAPtr pMga = MGAPTR(pScrn); int maxFastBlitMem; BoxRec AvailFBArea; +#ifdef XF86DRI + RegionRec MemRegion; +#endif pMga->AccelInfoRec = infoPtr = XAACreateInfoRec(); if(!infoPtr) return FALSE; @@ -209,12 +232,10 @@ MGANAME(AccelInit)(ScreenPtr pScreen) /* clipping */ infoPtr->SetClippingRectangle = MGASetClippingRectangle; infoPtr->DisableClipping = MGADisableClipping; - infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE | + infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE | HARDWARE_CLIP_DASHED_LINE | - HARDWARE_CLIP_SOLID_FILL | - HARDWARE_CLIP_MONO_8x8_FILL | - HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | - HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND; + HARDWARE_CLIP_SOLID_FILL | + HARDWARE_CLIP_MONO_8x8_FILL; /* dashed lines */ infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED; @@ -247,7 +268,11 @@ MGANAME(AccelInit)(ScreenPtr pScreen) infoPtr->ColorExpandBase = pMga->ILOADBase; } else { infoPtr->ColorExpandRange = 0x1C00; +#ifdef __alpha__ + infoPtr->ColorExpandBase = pMga->IOBaseDense; +#else infoPtr->ColorExpandBase = pMga->IOBase; +#endif } infoPtr->SetupForCPUToScreenColorExpandFill = MGANAME(SetupForCPUToScreenColorExpandFill); @@ -305,6 +330,7 @@ MGANAME(AccelInit)(ScreenPtr pScreen) infoPtr->SubsequentCPUToScreenColorExpandFill) { infoPtr->FillColorExpandRects = MGAFillColorExpandRects; infoPtr->WriteBitmap = MGAWriteBitmapColorExpand; + infoPtr->TEGlyphRenderer = MGATEGlyphRenderer; if(BITMAP_SCANLINE_PAD == 32) infoPtr->NonTEGlyphRenderer = MGANonTEGlyphRenderer; } @@ -343,6 +369,7 @@ MGANAME(AccelInit)(ScreenPtr pScreen) infoPtr->FillSolidSpansFlags |= NO_PLANEMASK; infoPtr->FillMono8x8PatternRectsFlags |= NO_PLANEMASK; infoPtr->NonTEGlyphRendererFlags |= NO_PLANEMASK; + infoPtr->TEGlyphRendererFlags |= NO_PLANEMASK; infoPtr->FillCacheBltRectsFlags |= NO_PLANEMASK; } @@ -355,10 +382,23 @@ MGANAME(AccelInit)(ScreenPtr pScreen) AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = pMga->FbUsableSize / (pScrn->displayWidth * PSZ / 8); + +#ifndef XF86DRI + AvailFBArea.y1 = 0; + AvailFBArea.y2 = (min(pMga->FbUsableSize, 16*1024*1024)) / + (pScrn->displayWidth * PSZ / 8); + xf86InitFBManager(pScreen, &AvailFBArea); +#else + AvailFBArea.y1 = pScrn->virtualY; + AvailFBArea.y2 = pScrn->virtualY+128; + + REGION_INIT(pScreen, &MemRegion, &AvailFBArea, 1); + xf86InitFBManagerRegion(pScreen, &MemRegion); + REGION_UNINIT(pScreen, &MemRegion); +#endif + return(XAAInit(pScreen, infoPtr)); } @@ -414,6 +454,8 @@ void MGAStormSync(ScrnInfoPtr pScrn) { MGAPtr pMga = MGAPTR(pScrn); + + CHECK_DMA_QUIESCENT(pMga, pScrn); while(MGAISBUSY()); /* flush cache before a read (mga-1064g 5.1.6) */ @@ -430,6 +472,8 @@ void MGAStormEngineInit(ScrnInfoPtr pScrn) MGAPtr pMga = MGAPTR(pScrn); MGAFBLayout *pLayout = &pMga->CurrentLayout; + CHECK_DMA_QUIESCENT(pMga, pScrn); + if (pMga->Chipset == PCI_CHIP_MGAG100) maccess = 1 << 14; @@ -451,10 +495,18 @@ void MGAStormEngineInit(ScrnInfoPtr pScrn) pMga->fifoCount = 0; - WAITFIFO(12); + while(MGAISBUSY()); + + if(!pMga->FifoSize) { + pMga->FifoSize = INREG8(MGAREG_FIFOSTATUS); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%i DWORD fifo\n", + pMga->FifoSize); + } + OUTREG(MGAREG_PITCH, pLayout->displayWidth); OUTREG(MGAREG_YDSTORG, pMga->YDstOrg); OUTREG(MGAREG_MACCESS, maccess); + pMga->MAccess = maccess; pMga->PlaneMask = ~0; if(pMga->Chipset != PCI_CHIP_MGAG100) OUTREG(MGAREG_PLNWT, pMga->PlaneMask); @@ -490,6 +542,8 @@ void MGASetClippingRectangle( ){ MGAPtr pMga = MGAPTR(pScrn); + CHECK_DMA_QUIESCENT(pMga, pScrn); + WAITFIFO(3); OUTREG(MGAREG_CXBNDRY,(x2 << 16) | x1); OUTREG(MGAREG_YTOP, (y1 * pScrn->displayWidth) + pMga->YDstOrg); @@ -501,6 +555,8 @@ void MGADisableClipping(ScrnInfoPtr pScrn) { MGAPtr pMga = MGAPTR(pScrn); + CHECK_DMA_QUIESCENT(pMga, pScrn); + WAITFIFO(3); OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */ OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */ @@ -531,6 +587,9 @@ MGANAME(SetupForScreenToScreenCopy)( CARD32 dwgctl = pMga->AtypeNoBLK[rop] | MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL; + CHECK_DMA_QUIESCENT(pMga, pScrn); + + pMga->AccelInfoRec->SubsequentScreenToScreenCopy = MGANAME(SubsequentScreenToScreenCopy); @@ -718,6 +777,8 @@ MGANAME(SetupForSolidFill)( { MGAPtr pMga = MGAPTR(pScrn); + CHECK_DMA_QUIESCENT(pMga, pScrn); + #if PSZ == 24 if(!RGBEQUAL(color)) pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO | @@ -843,6 +904,8 @@ MGANAME(SetupForMono8x8PatternFill)( MGAPtr pMga = MGAPTR(pScrn); XAAInfoRecPtr infoRec = pMga->AccelInfoRec; + CHECK_DMA_QUIESCENT(pMga, pScrn); + pMga->PatternRectCMD = MGADWG_TRAP | MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_BMONOLEF; @@ -957,6 +1020,8 @@ MGANAME(SetupForCPUToScreenColorExpandFill)( CARD32 mgaCMD = MGADWG_ILOAD | MGADWG_LINEAR | MGADWG_SGNZERO | MGADWG_SHIFTZERO | MGADWG_BMONOLEF; + CHECK_DMA_QUIESCENT(pMga, pScrn); + if(bg == -1) { #if PSZ == 24 if(!RGBEQUAL(fg)) @@ -1017,6 +1082,8 @@ static void MGANAME(SetupForImageWrite)( ){ MGAPtr pMga = MGAPTR(pScrn); + CHECK_DMA_QUIESCENT(pMga, pScrn); + WAITFIFO(3); OUTREG(MGAREG_AR5, 0); SET_PLANEMASK(planemask); @@ -1061,6 +1128,8 @@ MGANAME(SetupForDashedLine)( CARD32 NiceDashPattern = DashPattern[0]; int dwords = (length + 31) >> 5; + CHECK_DMA_QUIESCENT(pMga, pScrn); + pMga->DashCMD = MGADWG_BFCOL | pMga->AtypeNoBLK[rop]; pMga->StyleLen = length - 1; @@ -1168,6 +1237,8 @@ MGANAME(SetupForPlanarScreenToScreenColorExpandFill)( CARD32 mgaCMD = pMga->AtypeNoBLK[rop] | MGADWG_BITBLT | MGADWG_SGNZERO | MGADWG_BPLAN; + CHECK_DMA_QUIESCENT(pMga, pScrn); + if(bg == -1) { mgaCMD |= MGADWG_TRANSC; WAITFIFO(4); @@ -1218,6 +1289,8 @@ MGANAME(SetupForScreenToScreenColorExpandFill)( ){ MGAPtr pMga = MGAPTR(pScrn); CARD32 mgaCMD = MGADWG_BITBLT | MGADWG_SGNZERO | MGADWG_SHIFTZERO; + + CHECK_DMA_QUIESCENT(pMga, pScrn); if(bg == -1) { #if PSZ == 24 @@ -1259,32 +1332,35 @@ MGANAME(SubsequentScreenToScreenColorExpandFill)( MGAPtr pMga = MGAPTR(pScrn); int pitch = pScrn->displayWidth * PSZ; int start, end, next, num; - int SrcOrg = 0, DstOrg = 0; + Bool resetDstOrg = FALSE; if (pMga->AccelFlags & LARGE_ADDRESSES) { - DstOrg = ((y & ~1023) * pScrn->displayWidth * PSZ) >> 9; - SrcOrg = ((srcy & ~1023) * pScrn->displayWidth * PSZ) >> 9; + int DstOrg = ((y & ~1023) * pScrn->displayWidth * PSZ) >> 9; + int SrcOrg = ((srcy & ~1023) * pScrn->displayWidth * PSZ) >> 9; + y &= 1023; + srcy &= 1023; WAITFIFO(2); - if(DstOrg) + if(DstOrg) { OUTREG(MGAREG_DSTORG, DstOrg << 6); + resetDstOrg = TRUE; + } if(SrcOrg != pMga->SrcOrg) { pMga->SrcOrg = SrcOrg; OUTREG(MGAREG_SRCORG, SrcOrg << 6); } - SrcOrg <<= 9; } w--; start = (XYADDRESS(srcx, srcy) * PSZ) + skipleft; end = start + w + (pitch * (h - 1)); - /* src cannot split a 2 Meg boundary */ + /* src cannot split a 2 Meg boundary from SrcOrg */ if(!((start ^ end) & 0xff000000)) { WAITFIFO(4); - OUTREG(MGAREG_AR3, start - SrcOrg); - OUTREG(MGAREG_AR0, start + w - SrcOrg); + OUTREG(MGAREG_AR3, start); + OUTREG(MGAREG_AR0, start + w); OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); } else { @@ -1294,13 +1370,13 @@ MGANAME(SubsequentScreenToScreenColorExpandFill)( num = next - start - 1; WAITFIFO(7); - OUTREG(MGAREG_AR3, start - SrcOrg); - OUTREG(MGAREG_AR0, start + num - SrcOrg); + OUTREG(MGAREG_AR3, start); + OUTREG(MGAREG_AR0, start + num); OUTREG(MGAREG_FXBNDRY, ((x + num) << 16) | (x & 0xffff)); - OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); + OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1); - OUTREG(MGAREG_AR3, next - SrcOrg); - OUTREG(MGAREG_AR0, start + w - SrcOrg); + OUTREG(MGAREG_AR3, next); + OUTREG(MGAREG_AR0, start + w ); OUTREG(MGAREG_FXBNDRY + MGAREG_EXEC, ((x + w) << 16) | ((x + num + 1) & 0xffff)); start += pitch; @@ -1310,8 +1386,8 @@ MGANAME(SubsequentScreenToScreenColorExpandFill)( if(num > h) num = h; WAITFIFO(4); - OUTREG(MGAREG_AR3, start - SrcOrg); - OUTREG(MGAREG_AR0, start + w - SrcOrg); + OUTREG(MGAREG_AR3, start); + OUTREG(MGAREG_AR0, start + w); OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | num); @@ -1321,7 +1397,7 @@ MGANAME(SubsequentScreenToScreenColorExpandFill)( } } - if(DstOrg) { + if(resetDstOrg) { WAITFIFO(1); OUTREG(MGAREG_DSTORG, 0); } @@ -1375,6 +1451,8 @@ MGAWriteBitmapColorExpand( CARD32* maxptr; int dwords, maxlines, count; + CHECK_DMA_QUIESCENT(pMga, pScrn); + (*infoRec->SetupForCPUToScreenColorExpandFill)( pScrn, fg, bg, rop, planemask); @@ -1389,6 +1467,7 @@ MGAWriteBitmapColorExpand( (pScrn, x, y, w, maxlines, skipleft); count = maxlines; while(count--) { + WAITFIFO(dwords); destptr = MoveDWORDS(destptr, (CARD32*)src, dwords); src += srcwidth; if(destptr > maxptr) @@ -1402,13 +1481,14 @@ MGAWriteBitmapColorExpand( pScrn, x, y, w, h, skipleft); while(h--) { + WAITFIFO(dwords); destptr = MoveDWORDS(destptr, (CARD32*)src, dwords); src += srcwidth; if(destptr > maxptr) destptr = (CARD32*)infoRec->ColorExpandBase; } - MGAStormSync(infoRec->pScrn); - infoRec->NeedToSync = FALSE; + DISABLE_CLIP(); + SET_SYNC_FLAG(infoRec); } @@ -1441,6 +1521,8 @@ MGAFillColorExpandRects( } else StippleFunc = XAAStippleScanlineFuncLSBFirst[2]; + CHECK_DMA_QUIESCENT(pMga, pScrn); + (*infoRec->SetupForCPUToScreenColorExpandFill)( pScrn, fg, bg, rop, planemask); @@ -1464,6 +1546,7 @@ MGAFillColorExpandRects( pBox->x1, y, pBox->x2 - pBox->x1, maxlines, 0); count = maxlines; while(count--) { + WAITFIFO(dwords); destptr = (*StippleFunc)( destptr, (CARD32*)srcp, srcx, stipplewidth, dwords); if(destptr > maxptr) @@ -1483,6 +1566,7 @@ MGAFillColorExpandRects( pBox->x1, y , pBox->x2 - pBox->x1, h, 0); while(h--) { + WAITFIFO(dwords); destptr = (*StippleFunc)( destptr, (CARD32*)srcp, srcx, stipplewidth, dwords); if(destptr > maxptr) @@ -1497,8 +1581,8 @@ MGAFillColorExpandRects( pBox++; } - MGAStormSync(infoRec->pScrn); - infoRec->NeedToSync = FALSE; + DISABLE_CLIP(); + SET_SYNC_FLAG(infoRec); } @@ -1514,6 +1598,8 @@ MGAFillSolidRectsDMA( XAAInfoRecPtr infoRec = pMga->AccelInfoRec; CARD32 *base = (CARD32*)pMga->ILOADBase; + CHECK_DMA_QUIESCENT(pMga, pScrn); + SET_SYNC_FLAG(infoRec); (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask); @@ -1554,6 +1640,8 @@ MGAFillSolidSpansDMA( XAAInfoRecPtr infoRec = pMga->AccelInfoRec; CARD32 *base = (CARD32*)pMga->ILOADBase; + CHECK_DMA_QUIESCENT(pMga, pScrn); + SET_SYNC_FLAG(infoRec); if(infoRec->ClipBox) { @@ -1614,6 +1702,8 @@ MGAFillMono8x8PatternRectsTwoPass( int nBox, SecondPassColor; BoxPtr pBox; + CHECK_DMA_QUIESCENT(pMga, pScrn); + if((rop == GXcopy) && (bg != -1)) { SecondPassColor = bg; bg = -1; @@ -1662,6 +1752,8 @@ void MGANonTEGlyphRenderer( int x1, x2, y1, y2, i, h, skiptop, dwords, maxlines; unsigned char *src; + CHECK_DMA_QUIESCENT(pMga, pScrn); + (*infoRec->SetupForCPUToScreenColorExpandFill)( pScrn, fg, -1, rop, planemask); WAITFIFO(1); @@ -1697,6 +1789,7 @@ void MGANonTEGlyphRenderer( OUTREG(MGAREG_AR3, 0); OUTREG(MGAREG_FXBNDRY, ((x2 - 1) << 16) | (x1 & 0xFFFF)); OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | h); + WAITFIFO(dwords * maxlines); MoveDWORDS((CARD32*)infoRec->ColorExpandBase, (CARD32*)src, dwords * maxlines); src += dwords * maxlines << 2; @@ -1710,12 +1803,12 @@ void MGANonTEGlyphRenderer( OUTREG(MGAREG_AR3, 0); OUTREG(MGAREG_FXBNDRY, ((x2 - 1) << 16) | (x1 & 0xFFFF)); OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | h); - + WAITFIFO(dwords); MoveDWORDS((CARD32*)infoRec->ColorExpandBase, (CARD32*)src, dwords); } - MGAStormSync(infoRec->pScrn); - infoRec->NeedToSync = FALSE; + DISABLE_CLIP(); + SET_SYNC_FLAG(infoRec); } void @@ -1767,6 +1860,8 @@ MGAPolyPoint ( pbox = REGION_RECTS(pGC->pCompositeClip); + CHECK_DMA_QUIESCENT(pMga, infoRec->pScrn); + (*infoRec->SetClippingRectangle)(infoRec->pScrn, pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1); (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu, @@ -1831,6 +1926,8 @@ MGAFillCacheBltRects( XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h, start; + CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn); + (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask, pCache->trans_color); @@ -1909,14 +2006,223 @@ MGAFillCacheBltRects( SET_SYNC_FLAG(infoRec); } +void +MGATEGlyphRenderer( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, int skipleft, int startline, + unsigned int **glyphs, int glyphWidth, + int fg, int bg, int rop, unsigned planemask +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + GlyphScanlineFuncPtr GlyphFunc = + XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1]; + MGAPtr pMga = MGAPTR(pScrn); + CARD32* base; + int dwords; -#endif + CHECK_DMA_QUIESCENT(pMga, pScrn); + (*infoRec->SetupForCPUToScreenColorExpandFill)( + pScrn, fg, bg, rop, planemask); + w += skipleft; + x -= skipleft; + dwords = (w + 31) >> 5; + (*infoRec->SubsequentCPUToScreenColorExpandFill)( + pScrn, x, y, w, h, skipleft); + base = (CARD32*)infoRec->ColorExpandBase; + if((dwords * h) <= infoRec->ColorExpandRange) + while(h--) { + WAITFIFO(dwords); + base = (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth); + } + else + while(h--) { + WAITFIFO(dwords); + (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth); + } + DISABLE_CLIP(); + SET_SYNC_FLAG(infoRec); +} +#endif +#ifdef XF86DRI +void +MGANAME(DRIInitBuffers)(WindowPtr pWin, RegionPtr prgn, CARD32 index) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMGA = MGAPTR(pScrn); + BoxPtr pbox = REGION_RECTS(prgn); + int nbox = REGION_NUM_RECTS(prgn); + + CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn); + + MGANAME(SetupForSolidFill)(pScrn, 0, GXcopy, -1); + while (nbox--) { + MGASelectBuffer(pScrn, MGA_BACK); + MGANAME(SubsequentSolidFillRect)(pScrn, pbox->x1, pbox->y1, + pbox->x2-pbox->x1, pbox->y2-pbox->y1); + MGASelectBuffer(pScrn, MGA_DEPTH); + MGANAME(SubsequentSolidFillRect)(pScrn, pbox->x1, pbox->y1, + pbox->x2-pbox->x1, pbox->y2-pbox->y1); + pbox++; + } + MGASelectBuffer(pScrn, MGA_FRONT); + + pMGA->AccelInfoRec->NeedToSync = TRUE; +} +/* + This routine is a modified form of XAADoBitBlt with the calls to + ScreenToScreenBitBlt built in. My routine has the prgnSrc as source + instead of destination. My origin is upside down so the ydir cases + are reversed. +*/ + +void +MGANAME(DRIMoveBuffers)(WindowPtr pParent, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 index) +{ + ScreenPtr pScreen = pParent->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMGA = MGAPTR(pScrn); + int nbox; + BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2; + DDXPointPtr pptTmp, pptNew1, pptNew2; + int xdir, ydir; + int dx, dy; + DDXPointPtr pptSrc; + + int screenwidth = pScrn->virtualX; + int screenheight = pScrn->virtualY; + + CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn); + + pbox = REGION_RECTS(prgnSrc); + nbox = REGION_NUM_RECTS(prgnSrc); + pboxNew1 = 0; + pptNew1 = 0; + pboxNew2 = 0; + pboxNew2 = 0; + pptSrc = &ptOldOrg; + + dx = pParent->drawable.x - ptOldOrg.x; + dy = pParent->drawable.y - ptOldOrg.y; + + /* If the copy will overlap in Y, reverse the order */ + if (dy>0) { + ydir = -1; + + if (nbox>1) { + /* Keep ordering in each band, reverse order of bands */ + pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); + if (!pboxNew1) return; + pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); + if (!pptNew1) { + DEALLOCATE_LOCAL(pboxNew1); + return; + } + pboxBase = pboxNext = pbox+nbox-1; + while (pboxBase >= pbox) { + while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) + pboxNext--; + pboxTmp = pboxNext+1; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp <= pboxBase) { + *pboxNew1++ = *pboxTmp++; + *pptNew1++ = *pptTmp++; + } + pboxBase = pboxNext; + } + pboxNew1 -= nbox; + pbox = pboxNew1; + pptNew1 -= nbox; + pptSrc = pptNew1; + } + } else { + /* No changes required */ + ydir = 1; + } + + /* If the regions will overlap in X, reverse the order */ + if (dx>0) { + xdir = -1; + + if (nbox > 1) { + /*reverse orderof rects in each band */ + pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); + pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); + if (!pboxNew2 || !pptNew2) { + if (pptNew2) DEALLOCATE_LOCAL(pptNew2); + if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } + return; + } + pboxBase = pboxNext = pbox; + while (pboxBase < pbox+nbox) { + while ((pboxNext < pbox+nbox) && (pboxNext->y1 == pboxBase->y1)) + pboxNext++; + pboxTmp = pboxNext; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp != pboxBase) { + *pboxNew2++ = *--pboxTmp; + *pptNew2++ = *--pptTmp; + } + pboxBase = pboxNext; + } + pboxNew2 -= nbox; + pbox = pboxNew2; + pptNew2 -= nbox; + pptSrc = pptNew2; + } + } else { + /* No changes are needed */ + xdir = 1; + } + + MGANAME(SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, -1, -1); + for ( ; nbox-- ; pbox++) + { + int x1 = pbox->x1; + int y1 = pbox->y1; + int destx = x1 + dx; + int desty = y1 + dy; + int w = pbox->x2 - x1 + 1; + int h = pbox->y2 - y1 + 1; + + if ( destx < 0 ) x1 -= destx, w += destx, destx = 0; + if ( desty < 0 ) y1 -= desty, h += desty, desty = 0; + if ( destx + w > screenwidth ) w = screenwidth - destx; + if ( desty + h > screenheight ) h = screenheight - desty; + if ( w <= 0 ) continue; + if ( h <= 0 ) continue; + + MGASelectBuffer(pScrn, MGA_BACK); + MGANAME(SubsequentScreenToScreenCopy)(pScrn, x1,y1, destx,desty, w, h); + MGASelectBuffer(pScrn, MGA_DEPTH); + MGANAME(SubsequentScreenToScreenCopy)(pScrn, x1,y1, destx,desty, w, h); + } + MGASelectBuffer(pScrn, MGA_FRONT); + + if (pboxNew2) { + DEALLOCATE_LOCAL(pptNew2); + DEALLOCATE_LOCAL(pboxNew2); + } + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } + + pMGA->AccelInfoRec->NeedToSync = TRUE; +} + +#endif /* XF86DRI */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c index 9bd43318a..f7c81968c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c @@ -18,6 +18,8 @@ Bool mgaConfigureWarp(ScrnInfoPtr pScrn) MGAPtr pMga = MGAPTR(pScrn); int wmisc; + CHECK_DMA_QUIESCENT( pMga, pScrn ); + WAITFIFO(3); switch(pMga->Chipset) { @@ -108,7 +110,7 @@ static unsigned int mgaG400InstallMicrocode(MGAPtr pMGA, int agp_offset) unsigned int microcode_size = 0; memset(pMGADRIServer->WarpIndex, 0, - sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES); + sizeof(drmMgaWarpIndex) * MGA_MAX_WARP_PIPES); microcode_size = mgaG400GetMicrocodeSize(pMGA); mgaWarpInstallCode(tgz, MGA_WARP_TGZ); @@ -150,7 +152,7 @@ static unsigned int mgaG200InstallMicrocode(MGAPtr pMGA, int agp_offset) unsigned int microcode_size = 0; memset(pMGADRIServer->WarpIndex, 0, - sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES); + sizeof(drmMgaWarpIndex) * MGA_MAX_WARP_PIPES); microcode_size = mgaG400GetMicrocodeSize(pMGA); mgaWarpInstallCode(tgz, MGA_WARP_TGZ); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c new file mode 100644 index 000000000..d812149e1 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c @@ -0,0 +1,198 @@ +/* $XFree86: xc/programs/Xserver/GL/dri/dri.c,v 1.4 1999/09/25 14:36:41 dawes Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@precisioninsight.com> + * + */ + + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Priv.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb32.h" + +#include "miline.h" + +#include "GL/glxtokens.h" + +#include "mga_bios.h" +#include "mga_reg.h" +#include "mga.h" +#include "mga_macros.h" +#include "mga_dri.h" +#include "mga_wrap.h" + + + +static void MGAWakeupHandler(int screenNum, + pointer wakeupData, + unsigned long result, + pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[screenNum]; + DRIWrappedFuncsRec *pDRIWrap = DRIGetWrappedFuncs(pScreen); + + if (0) ErrorF("MGAWakeupHandler (in)\n"); + + /* Disabled: Check contention like the 3d clients do before trying + * to restore state. + */ + DRILock(pScreen, 0); + MGASwapContext( pScreen ); + +} + +static void MGABlockHandler(int screenNum, + pointer blockData, + pointer pTimeout, + pointer pReadmask) + +{ + ScreenPtr pScreen = screenInfo.screens[screenNum]; + DRIWrappedFuncsRec *pDRIWrap = DRIGetWrappedFuncs(pScreen); + MGASAREAPtr sa = (MGASAREAPtr)DRIGetSAREAPrivate( pScreen ); + + if (0) ErrorF("MGABlockHandler (out)\n"); + + + /* Examine the cliprects for the most recently used 3d drawable. + * If they've changed, attempt to push the updated values into the + * sarea. + * + * This avoids the protocol round trip in all single-client + * frontbuffer rendering cases providing the cliprects fit into the + * sarea, and in all single-client backbuffer rendering with arbitary + * numbers of cliprects, for all operations except swapbuffers. + * + * Thus the number of round trips in the cases where comparison is + * possible is reduced to no more (and usually fewer) than the number + * Utah requires. + */ + + if (sa->req_drawable != sa->exported_drawable || + sa->exported_stamp != DRIGetDrawableStamp( pScreen, sa->exported_index )) + { + int i; + XF86DRIClipRectPtr frontboxes, backboxes; + XF86DRIClipRectPtr boxes = (XF86DRIClipRectPtr)sa->exported_boxes; + WindowPtr window = LookupIDByType( sa->req_drawable, RT_WINDOW ); + + if (0) + ErrorF("Trying to update req_drawable: %d (exp %d), stamp %d/%d\n", + sa->req_drawable, sa->exported_drawable); + + sa->exported_drawable = 0; + + if (!window) { + if (0) + ErrorF("Couldn't retreive window\n"); + sa->req_drawable = 0; + goto finished; + } + + if (!DRIGetDrawableInfo( pScreen, &(window->drawable), + &sa->exported_index, + &sa->exported_stamp, + &sa->exported_front_x, + &sa->exported_front_y, + &sa->exported_w, + &sa->exported_h, + &sa->exported_nfront, + &frontboxes, + &sa->exported_back_x, + &sa->exported_back_y, + &sa->exported_nback, + &backboxes )) + { + if (0) + ErrorF("Couldn't get DRI info\n"); + sa->req_drawable = 0; + goto finished; + } + + /* If we can't fit both sets of cliprects into the sarea, try to + * fit the current draw buffer. Otherwise return. + */ + + sa->exported_buffers = MGA_FRONT | MGA_BACK; + + if (sa->exported_nback + sa->exported_nfront >= MGA_NR_SAREA_CLIPRECTS) { + if (sa->req_draw_buffer == MGA_FRONT) { + sa->exported_buffers = MGA_FRONT; + if (sa->exported_nfront >= MGA_NR_SAREA_CLIPRECTS) + goto finished; + } else { + sa->exported_buffers = MGA_BACK; + if (sa->exported_nback >= MGA_NR_SAREA_CLIPRECTS) + goto finished; + } + } + + if (sa->exported_buffers & MGA_BACK) { + for (i = 0 ; i < sa->exported_nback ; i++) + *boxes++ = backboxes[i]; + } + + if (sa->exported_buffers & MGA_FRONT) { + for (i = 0 ; i < sa->exported_nfront ; i++) + *boxes++ = frontboxes[i]; + } + + sa->exported_drawable = sa->req_drawable; + } + + finished: + DRIUnlock(pScreen); +} + + + + +/* Just wrap validate tree for now to remove the quiescense hack. + * This is more of a win for the i810 than the mga, but should be useful + * here too. + */ +void MGADRIWrapFunctions(ScreenPtr pScreen, DRIInfoPtr pDRIInfo) +{ + pDRIInfo->wrap.BlockHandler = MGABlockHandler; + pDRIInfo->wrap.WakeupHandler = MGAWakeupHandler; +/* pDRIInfo->wrap.ValidateTree = NULL; */ +/* pDRIInfo->wrap.PostValidateTree = NULL; */ +} + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.h new file mode 100644 index 000000000..df65ad731 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.h @@ -0,0 +1,6 @@ +#ifndef MGA_WRAP_H +#define MGA_WRAP_H + +void MGADRIWrapFunctions(ScreenPtr pScreen, DRIInfoPtr pDRIInfo); + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile index 96388450b..2c0ce97db 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile @@ -13,9 +13,8 @@ MOBJ = drmmodule.o MTRR_DEFINES = -DHAS_MTRR_SUPPORT #endif -SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c $(MSRC) -OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o $(MOBJ) - +SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c xf86drmI810.c xf86drmMga.c $(MSRC) +OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o xf86drmI810.o xf86drmMga.o $(MOBJ) INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \ -I$(XINCLUDESRC) -I$(EXTINCSRC) -I../.. -Ikernel diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel index 44d75c487..2ea6c7215 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel @@ -14,7 +14,8 @@ L_TARGET := libdrm.a L_OBJS := init.o memory.o proc.o auth.o context.o drawable.o bufs.o \ - lists.o lock.o ioctl.o fops.o vm.o dma.o + lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o \ + agpsupport.o M_OBJS := @@ -26,6 +27,14 @@ ifdef CONFIG_DRM_TDFX M_OBJS += tdfx.o endif +ifdef CONFIG_DRM_MGA +M_OBJS += mga.o +endif + +ifdef CONFIG_DRM_R128 +M_OBJS += r128.o +endif + include $(TOPDIR)/Rules.make gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET) @@ -33,3 +42,10 @@ gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET) tdfx.o: tdfx_drv.o tdfx_context.o $(L_TARGET) $(LD) $(LD_RFLAG) -r -o $@ tdfx_drv.o tdfx_context.o -L. -ldrm + +i810.o: i810_drv.o i810_context.o $(L_TARGET) + $(LD) $(LD_RFLAG) -r -o $@ i810_drv.o i810_bufs.o i810_dma.o i810_context.o -L. -ldrm + +mga.o: mga_drv.o mga_context.o mga_dma.o mga_bufs.o $(L_TARGET) + $(LD) $(LD_RFLAG) -r -o $@ mga_drv.o mga_bufs.o mga_dma.o mga_context.o mga_state.o -L. -ldrm + diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux index 8a41f880b..1db7a81fa 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux @@ -31,12 +31,14 @@ # *** Setup +# **** End of SMP/MODVERSIONS detection + MODS= gamma.o tdfx.o LIBS= libdrm.a PROGS= drmstat DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \ - lists.o lock.o ioctl.o fops.o vm.o dma.o + lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o DRMHEADERS= drm.h drmP.h GAMMAOBJS= gamma_drv.o gamma_dma.o @@ -48,6 +50,8 @@ TDFXHEADERS= tdfx_drv.h $(DRMHEADERS) PROGOBJS= drmstat.po xf86drm.po xf86drmHash.po xf86drmRandom.po sigio.po PROGHEADERS= xf86drm.h $(DRMHEADERS) +INC= /usr/include + CFLAGS= -O2 $(WARNINGS) WARNINGS= -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \ -Wstrict-prototypes -Wshadow -Wnested-externs \ @@ -102,7 +106,27 @@ SMP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ | grep -s 'SMP = ' | cut -d' ' -f3) MODVERSIONS := $(shell gcc -E -I $(TREE) picker.c 2>/dev/null \ | grep -s 'MODVERSIONS = ' | cut -d' ' -f3) -all::;@echo KERNEL HEADERS IN $(TREE): SMP=${SMP} MODVERSIONS=${MODVERSIONS} +AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ + | grep -s 'AGP = ' | cut -d' ' -f3) +ifeq ($(AGP),0) +AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ + | grep -s 'AGP_MODULE = ' | cut -d' ' -f3) +endif + +ifeq ($(AGP),1) +MODCFLAGS += -DDRM_AGP +DRMOBJS += agpsupport.o +MODS += mga.o i810.o + +MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_state.o mga_context.o +MGAHEADERS= mga_drv.h $(DRMHEADERS) + +I810OBJS= i810_drv.o i810_dma.o i810_bufs.o i810_context.o +I810HEADERS= i810_drv.h $(DRMHEADERS) +endif + +all::;@echo KERNEL HEADERS IN $(TREE): SMP=${SMP} MODVERSIONS=${MODVERSIONS} \ + AGP=${AGP} all:: $(LIBS) $(MODS) $(PROGS) endif @@ -116,6 +140,7 @@ ifeq ($(MODVERSIONS),1) MODCFLAGS += -DMODVERSIONS -include $(TREE)/linux/modversions.h endif + # **** End of configuration libdrm.a: $(DRMOBJS) @@ -128,6 +153,14 @@ gamma.o: $(GAMMAOBJS) $(LIBS) tdfx.o: $(TDFXOBJS) $(LIBS) $(LD) -r $^ -o $@ +ifeq ($(AGP),1) +mga.o: $(MGAOBJS) $(LIBS) + $(LD) -r $^ -o $@ + +i810.o: $(I810OBJS) $(LIBS) + $(LD) -r $^ -o $@ +endif + drmstat: $(PROGOBJS) $(CC) $(PRGCFLAGS) $^ $(PRGLIBS) -o $@ @@ -149,8 +182,11 @@ ChangeLog: $(DRMOBJS): $(DRMHEADERS) $(GAMMAOBJS): $(GAMMAHEADERS) $(TDFXOBJS): $(TDFXHEADERS) +ifeq ($(AGP),1) +$(MGAOBJS): $(MGAHEADERS) +$(I810OBJS): $(I810HEADERS) +endif $(PROGOBJS): $(PROGHEADERS) clean: - rm -f *.o *.po *~ core $(PROGS) - + rm -f *.o *.a *.po *~ core $(PROGS) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c index fb58154d6..c2da9ec7e 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c @@ -159,6 +159,8 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, -EFAULT); if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) return -ENOMEM; + + memset(entry, 0, sizeof(*entry)); pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; type = (u32) request.type; @@ -254,8 +256,10 @@ int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (entry->bound) drm_unbind_agp(entry->memory); - entry->prev->next = entry->next; - entry->next->prev = entry->prev; + + if (entry->prev) entry->prev->next = entry->next; + else dev->agp->memory = entry->next; + if (entry->next) entry->next->prev = entry->prev; drm_free_agp(entry->memory, entry->pages); drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; @@ -269,15 +273,12 @@ drm_agp_head_t *drm_agp_init(void) for (fill = &drm_agp_fill[0]; fill->name; fill++) { char *n = (char *)fill->name; -#if 0 - *fill->f = (drm_agp_func_u)get_module_symbol(NULL, n); -#endif *fill->f = (drm_agp_func_u)get_module_symbol(NULL, n); - printk("%s resolves to 0x%08lx\n", n, (*fill->f).address); + DRM_DEBUG("%s resolves to 0x%08lx\n", n, (*fill->f).address); if (!(*fill->f).address) agp_available = 0; } - printk("agp_available = %d\n", agp_available); + DRM_DEBUG("agp_available = %d\n", agp_available); if (agp_available) { if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS))) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c index 85244c7dc..7902f0ccf 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c @@ -102,6 +102,11 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd, dev->lock.hw_lock = map->handle; /* Pointer to lock */ } break; +#ifdef DRM_AGP + case _DRM_AGP: + map->offset = map->offset + dev->agp->base; + break; +#endif default: drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; @@ -172,7 +177,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; if (dev->queue_count) return -EBUSY; /* Not while in use */ - alignment = (request.flags & DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size; + alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ctxbitmap.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ctxbitmap.c index f67209d44..781984f11 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ctxbitmap.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ctxbitmap.c @@ -53,7 +53,7 @@ int drm_ctxbitmap_next(drm_device_t *dev) bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP); if (bit < DRM_MAX_CTXBITMAP) { set_bit(bit, dev->ctx_bitmap); - printk("drm_ctxbitmap_next bit : %d\n", bit); + DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit); return bit; } return -1; @@ -64,15 +64,15 @@ int drm_ctxbitmap_init(drm_device_t *dev) int i; int temp; - dev->ctx_bitmap = (unsigned long *) drm_alloc(PAGE_SIZE * 4, + dev->ctx_bitmap = (unsigned long *) drm_alloc(PAGE_SIZE, DRM_MEM_CTXBITMAP); if(dev->ctx_bitmap == NULL) { return -ENOMEM; } - memset((void *) dev->ctx_bitmap, 0, PAGE_SIZE * 4); + memset((void *) dev->ctx_bitmap, 0, PAGE_SIZE); for(i = 0; i < DRM_RESERVED_CONTEXTS; i++) { temp = drm_ctxbitmap_next(dev); - printk("drm_ctxbitmap_init : %d\n", temp); + DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp); } return 0; @@ -80,7 +80,7 @@ int drm_ctxbitmap_init(drm_device_t *dev) void drm_ctxbitmap_cleanup(drm_device_t *dev) { - drm_free((void *)dev->ctx_bitmap, PAGE_SIZE * 4, + drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP); } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c index 8291e52e4..37ab674f8 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c @@ -63,15 +63,24 @@ void drm_dma_takedown(drm_device_t *dev) dma->bufs[i].page_order, DRM_MEM_DMA); } - drm_free(dma->bufs[i].buflist, - dma->buf_count - * sizeof(*dma->bufs[0].buflist), - DRM_MEM_BUFS); drm_free(dma->bufs[i].seglist, - dma->buf_count + dma->bufs[i].seg_count * sizeof(*dma->bufs[0].seglist), DRM_MEM_SEGS); - drm_freelist_destroy(&dma->bufs[i].freelist); + } + if(dma->bufs[i].buf_count) { + for(j = 0; j < dma->bufs[i].buf_count; j++) { + if(dma->bufs[i].buflist[j].dev_private) { + drm_free(dma->bufs[i].buflist[j].dev_private, + dma->bufs[i].buflist[j].dev_priv_size, + DRM_MEM_BUFS); + } + } + drm_free(dma->bufs[i].buflist, + dma->bufs[i].buf_count * + sizeof(*dma->bufs[0].buflist), + DRM_MEM_BUFS); + drm_freelist_destroy(&dma->bufs[i].freelist); } } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h index 7b8e88265..ae4c65ca3 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h @@ -61,6 +61,19 @@ typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; +/* Warning: If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well */ + +typedef struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +} drm_clip_rect_t; + +/* Seperate include files for the i810/mga specific structures */ +#include "mga_drm.h" +#include "i810_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -101,7 +114,8 @@ typedef struct drm_control { typedef enum drm_map_type { _DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */ _DRM_REGISTERS = 1, /* no caching, no core dump */ - _DRM_SHM = 2 /* shared, cached */ + _DRM_SHM = 2, /* shared, cached */ + _DRM_AGP = 3 /* AGP/GART */ } drm_map_type_t; typedef enum drm_map_flags { @@ -165,8 +179,11 @@ typedef struct drm_buf_desc { int low_mark; /* Low water mark */ int high_mark; /* High water mark */ enum { - DRM_PAGE_ALIGN = 0x01 /* Align on page boundaries for DMA */ + _DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */ + _DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */ } flags; + unsigned long agp_start; /* Start address of where the agp buffers + * are in the agp aperture */ } drm_buf_desc_t; typedef struct drm_buf_info { @@ -237,6 +254,38 @@ typedef struct drm_irq_busid { int funcnum; } drm_irq_busid_t; +typedef struct drm_agp_mode { + unsigned long mode; +} drm_agp_mode_t; + + /* For drm_agp_alloc -- allocated a buffer */ +typedef struct drm_agp_buffer { + unsigned long size; /* In bytes -- will round to page boundary */ + unsigned long handle; /* Used for BIND/UNBIND ioctls */ + unsigned long type; /* Type of memory to allocate */ + unsigned long physical; /* Physical used by i810 */ +} drm_agp_buffer_t; + + /* For drm_agp_bind */ +typedef struct drm_agp_binding { + unsigned long handle; /* From drm_agp_buffer */ + unsigned long offset; /* In bytes -- will round to page boundary */ +} drm_agp_binding_t; + +typedef struct drm_agp_info { + int agp_version_major; + int agp_version_minor; + unsigned long mode; + unsigned long aperture_base; /* physical address */ + unsigned long aperture_size; /* bytes */ + unsigned long memory_allowed; /* bytes */ + unsigned long memory_used; + + /* PCI information */ + unsigned short id_vendor; + unsigned short id_device; +} drm_agp_info_t; + #define DRM_IOCTL_BASE 'd' #define DRM_IOCTL_NR(n) _IOC_NR(n) #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) @@ -276,4 +325,28 @@ typedef struct drm_irq_busid { #define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t) #define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t) +#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) +#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) +#define DRM_IOCTL_AGP_ENABLE DRM_IOR( 0x32, drm_agp_mode_t) +#define DRM_IOCTL_AGP_INFO DRM_IOW( 0x33, drm_agp_info_t) +#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) +#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) + +/* Mga specific ioctls */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) + +/* I810 specific ioctls */ +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) + #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h index 312fba36f..f8e78eabd 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h @@ -48,8 +48,12 @@ #ifdef CONFIG_MTRR #include <asm/mtrr.h> #endif +#ifdef DRM_AGP +#include <linux/types.h> +#include <linux/agp_backend.h> +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) -#include <asm/spinlock.h> +#include <linux/tqueue.h> #include <linux/poll.h> #endif #include "drm.h" @@ -69,21 +73,27 @@ #define DRM_FLAG_DEBUG 0x01 #define DRM_FLAG_NOCTX 0x02 -#define DRM_MEM_DMA 0 -#define DRM_MEM_SAREA 1 -#define DRM_MEM_DRIVER 2 -#define DRM_MEM_MAGIC 3 -#define DRM_MEM_IOCTLS 4 -#define DRM_MEM_MAPS 5 -#define DRM_MEM_VMAS 6 -#define DRM_MEM_BUFS 7 -#define DRM_MEM_SEGS 8 -#define DRM_MEM_PAGES 9 -#define DRM_MEM_FILES 10 -#define DRM_MEM_QUEUES 11 -#define DRM_MEM_CMDS 12 -#define DRM_MEM_MAPPINGS 13 -#define DRM_MEM_BUFLISTS 14 +#define DRM_MEM_DMA 0 +#define DRM_MEM_SAREA 1 +#define DRM_MEM_DRIVER 2 +#define DRM_MEM_MAGIC 3 +#define DRM_MEM_IOCTLS 4 +#define DRM_MEM_MAPS 5 +#define DRM_MEM_VMAS 6 +#define DRM_MEM_BUFS 7 +#define DRM_MEM_SEGS 8 +#define DRM_MEM_PAGES 9 +#define DRM_MEM_FILES 10 +#define DRM_MEM_QUEUES 11 +#define DRM_MEM_CMDS 12 +#define DRM_MEM_MAPPINGS 13 +#define DRM_MEM_BUFLISTS 14 +#define DRM_MEM_AGPLISTS 15 +#define DRM_MEM_TOTALAGP 16 +#define DRM_MEM_BOUNDAGP 17 +#define DRM_MEM_CTXBITMAP 18 + +#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) /* Backward compatibility section */ /* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */ @@ -235,6 +245,7 @@ typedef struct drm_buf { int used; /* Amount of buffer in use (for DMA) */ unsigned long offset; /* Byte offset (used internally) */ void *address; /* Address of buffer */ + unsigned long bus_address; /* Bus address of buffer */ struct drm_buf *next; /* Kernel-only: used for free list */ __volatile__ int waiting; /* On kernel DMA queue */ __volatile__ int pending; /* On hardware DMA queue */ @@ -250,6 +261,11 @@ typedef struct drm_buf { DRM_LIST_PRIO = 4, DRM_LIST_RECLAIM = 5 } list; /* Which list we're on */ + + + void *dev_private; + int dev_priv_size; + #if DRM_DMA_HISTOGRAM cycles_t time_queued; /* Queued to kernel DMA queue */ cycles_t time_dispatched; /* Dispatched to hardware */ @@ -376,6 +392,9 @@ typedef struct drm_device_dma { int page_count; unsigned long *pagelist; unsigned long byte_count; + enum { + _DRM_DMA_USE_AGP = 0x01 + } flags; /* DMA support */ drm_buf_t *this_buffer; /* Buffer being sent */ @@ -384,6 +403,41 @@ typedef struct drm_device_dma { wait_queue_head_t waiting; /* Processes waiting on free bufs */ } drm_device_dma_t; +#ifdef DRM_AGP +typedef struct drm_agp_mem { + unsigned long handle; + agp_memory *memory; + unsigned long bound; /* address */ + int pages; + struct drm_agp_mem *prev; + struct drm_agp_mem *next; +} drm_agp_mem_t; + +typedef struct drm_agp_head { + agp_kern_info agp_info; + const char *chipset; + drm_agp_mem_t *memory; + unsigned long mode; + int enabled; + int acquired; + unsigned long base; + int agp_mtrr; +} drm_agp_head_t; + +typedef struct { + void (*free_memory)(agp_memory *); + agp_memory *(*allocate_memory)(size_t, u32); + int (*bind_memory)(agp_memory *, off_t); + int (*unbind_memory)(agp_memory *); + void (*enable)(u32); + int (*acquire)(void); + void (*release)(void); + void (*copy_info)(agp_kern_info *); +} drm_agp_func_t; + +extern drm_agp_func_t drm_agp; +#endif + typedef struct drm_device { const char *name; /* Simple driver name */ char *unique; /* Unique identifier: e.g., busid */ @@ -462,6 +516,12 @@ typedef struct drm_device { struct fasync_struct *buf_async;/* Processes waiting for SIGIO */ wait_queue_head_t buf_readers; /* Processes waiting to read */ wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */ + +#ifdef DRM_AGP + drm_agp_head_t *agp; +#endif + unsigned long *ctx_bitmap; + void *dev_private; } drm_device_t; @@ -533,6 +593,14 @@ extern void drm_free_pages(unsigned long address, int order, extern void *drm_ioremap(unsigned long offset, unsigned long size); extern void drm_ioremapfree(void *pt, unsigned long size); +#ifdef DRM_AGP +extern agp_memory *drm_alloc_agp(int pages, u32 type); +extern int drm_free_agp(agp_memory *handle, int pages); +extern int drm_bind_agp(agp_memory *handle, unsigned int start); +extern int drm_unbind_agp(agp_memory *handle); +#endif + + /* Buffer management support (bufs.c) */ extern int drm_order(unsigned long size); extern int drm_addmap(struct inode *inode, struct file *filp, @@ -642,5 +710,32 @@ extern int drm_flush_unblock(drm_device_t *dev, int context, drm_lock_flags_t flags); extern int drm_flush_block_and_flush(drm_device_t *dev, int context, drm_lock_flags_t flags); + + /* Context Bitmap support (ctxbitmap.c) */ +extern int drm_ctxbitmap_init(drm_device_t *dev); +extern void drm_ctxbitmap_cleanup(drm_device_t *dev); +extern int drm_ctxbitmap_next(drm_device_t *dev); +extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle); + +#ifdef DRM_AGP + /* AGP/GART support (agpsupport.c) */ +extern drm_agp_head_t *drm_agp_init(void); +extern int drm_agp_acquire(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_release(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_enable(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_info(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_alloc(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_free(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_unbind(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_bind(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +#endif #endif #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c index 8fe6f7072..a96a38b26 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c @@ -187,7 +187,7 @@ int main(int argc, char **argv) case 'b': count = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); - if ((r = drmAddBufs(fd, count, size, 0)) < 0) { + if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) { drmError(r, argv[0]); return 1; } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c index ce970835a..a3c2bd4a0 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c @@ -271,6 +271,10 @@ static int gamma_takedown(drm_device_t *dev) - PAGE_SHIFT, DRM_MEM_SAREA); break; + case _DRM_AGP: + /* Do nothing here, because this is all + handled in the AGP/GART driver. */ + break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c index 49455b434..c025e400b 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c @@ -32,152 +32,28 @@ #define __NO_VERSION__ #include "drmP.h" +#include "i810_drv.h" #include "linux/un.h" int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_device_dma_t *dma = dev->dma; - drm_buf_desc_t request; - drm_buf_entry_t *entry; - drm_buf_t *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - - if (!dma) return -EINVAL; - - copy_from_user_ret(&request, - (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); - - count = request.count; - order = drm_order(request.size); - size = 1 << order; - agp_offset = request.agp_start; - alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - byte_count = 0; - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; - if (dev->queue_count) return -EBUSY; /* Not while in use */ - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); - - down(&dev->struct_sem); - entry = &dma->bufs[order]; - if (entry->buf_count) { - up(&dev->struct_sem); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } - - entry->buflist = drm_alloc(count * sizeof(*entry->buflist), - DRM_MEM_BUFS); - if (!entry->buflist) { - up(&dev->struct_sem); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - - entry->buf_size = size; - entry->page_order = page_order; - - while(entry->buf_count < count) { - for(offset = 0; offset + size <= total && entry->buf_count < count; - offset += alignment, ++entry->buf_count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - buf->offset = agp_offset - dev->agp->base + offset;/* ?? */ - buf->bus_address = agp_offset + offset; - buf->address = agp_offset + offset + dev->agp->base; - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->pid = 0; -#if DRM_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; -#endif - DRM_DEBUG("buffer %d @ %p\n", - entry->buf_count, buf->address); - } - byte_count += PAGE_SIZE << page_order; - } - - dma->buflist = drm_realloc(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), - DRM_MEM_BUFS); - for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) - dma->buflist[i] = &entry->buflist[i - dma->buf_count]; - - dma->buf_count += entry->buf_count; - dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); - - drm_freelist_create(&entry->freelist, entry->buf_count); - for (i = 0; i < entry->buf_count; i++) { - drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]); - } - - up(&dev->struct_sem); - - request.count = entry->buf_count; - request.size = size; - - copy_to_user_ret((drm_buf_desc_t *)arg, - &request, - sizeof(request), - -EFAULT); - - atomic_dec(&dev->buf_alloc); - return 0; -} - -int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_device_dma_t *dma = dev->dma; - drm_buf_desc_t request; - int count; - int order; - int size; - int total; - int page_order; - drm_buf_entry_t *entry; - unsigned long page; - drm_buf_t *buf; - int alignment; - unsigned long offset; - int i; - int byte_count; - int page_count; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + drm_buf_desc_t request; + drm_buf_entry_t *entry; + drm_buf_t *buf; + unsigned long offset; + unsigned long agp_offset; + int count; + int order; + int size; + int alignment; + int page_order; + int total; + int byte_count; + int i; if (!dma) return -EINVAL; @@ -186,20 +62,17 @@ int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, sizeof(request), -EFAULT); - count = request.count; - order = drm_order(request.size); - size = 1 << order; - - DRM_DEBUG("count = %d, size = %d (%d), order = %d, queue_count = %d\n", - request.count, request.size, size, order, dev->queue_count); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; - if (dev->queue_count) return -EBUSY; /* Not while in use */ - + count = request.count; + order = drm_order(request.size); + size = 1 << order; + agp_offset = request.agp_start; alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - + total = PAGE_SIZE << page_order; + byte_count = 0; + + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; + if (dev->queue_count) return -EBUSY; /* Not while in use */ spin_lock(&dev->count_lock); if (dev->buf_use) { spin_unlock(&dev->count_lock); @@ -207,15 +80,15 @@ int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, } atomic_inc(&dev->buf_alloc); spin_unlock(&dev->count_lock); - + down(&dev->struct_sem); entry = &dma->bufs[order]; if (entry->buf_count) { up(&dev->struct_sem); atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ + return -ENOMEM; /* May only call once for each order */ } - + entry->buflist = drm_alloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS); if (!entry->buflist) { @@ -224,69 +97,44 @@ int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, return -ENOMEM; } memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - - entry->seglist = drm_alloc(count * sizeof(*entry->seglist), - DRM_MEM_SEGS); - if (!entry->seglist) { - drm_free(entry->buflist, - count * sizeof(*entry->buflist), - DRM_MEM_BUFS); - up(&dev->struct_sem); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->seglist, 0, count * sizeof(*entry->seglist)); - - dma->pagelist = drm_realloc(dma->pagelist, - dma->page_count * sizeof(*dma->pagelist), - (dma->page_count + (count << page_order)) - * sizeof(*dma->pagelist), - DRM_MEM_PAGES); - DRM_DEBUG("pagelist: %d entries\n", - dma->page_count + (count << page_order)); - - - entry->buf_size = size; + + entry->buf_size = size; entry->page_order = page_order; - byte_count = 0; - page_count = 0; - while (entry->buf_count < count) { - if (!(page = drm_alloc_pages(page_order, DRM_MEM_DMA))) break; - entry->seglist[entry->seg_count++] = page; - for (i = 0; i < (1 << page_order); i++) { - DRM_DEBUG("page %d @ 0x%08lx\n", - dma->page_count + page_count, - page + PAGE_SIZE * i); - dma->pagelist[dma->page_count + page_count++] - = page + PAGE_SIZE * i; - } - for (offset = 0; - offset + size <= total && entry->buf_count < count; - offset += alignment, ++entry->buf_count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - buf->offset = (dma->byte_count + byte_count + offset); - buf->address = (void *)(page + offset); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->pid = 0; + offset = 0; + + while(entry->buf_count < count) { + buf = &entry->buflist[entry->buf_count]; + buf->idx = dma->buf_count + entry->buf_count; + buf->total = alignment; + buf->order = order; + buf->used = 0; + buf->offset = offset; + buf->bus_address = dev->agp->base + agp_offset + offset; + buf->address = (void *)(agp_offset + offset + dev->agp->base); + buf->next = NULL; + buf->waiting = 0; + buf->pending = 0; + init_waitqueue_head(&buf->dma_wait); + buf->pid = 0; + + buf->dev_private = drm_alloc(sizeof(drm_i810_buf_priv_t), + DRM_MEM_BUFS); + buf->dev_priv_size = sizeof(drm_i810_buf_priv_t); + #if DRM_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; + buf->time_queued = 0; + buf->time_dispatched = 0; + buf->time_completed = 0; + buf->time_freed = 0; #endif - DRM_DEBUG("buffer %d @ %p\n", - entry->buf_count, buf->address); - } + offset = offset + alignment; + entry->buf_count++; byte_count += PAGE_SIZE << page_order; + + DRM_DEBUG("buffer %d @ %p\n", + entry->buf_count, buf->address); } - + dma->buflist = drm_realloc(dma->buflist, dma->buf_count * sizeof(*dma->buflist), (dma->buf_count + entry->buf_count) @@ -294,45 +142,43 @@ int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, DRM_MEM_BUFS); for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) dma->buflist[i] = &entry->buflist[i - dma->buf_count]; - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += entry->seg_count << page_order; - dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); - + + dma->buf_count += entry->buf_count; + dma->byte_count += byte_count; drm_freelist_create(&entry->freelist, entry->buf_count); for (i = 0; i < entry->buf_count; i++) { drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]); } - + up(&dev->struct_sem); - + request.count = entry->buf_count; request.size = size; - + copy_to_user_ret((drm_buf_desc_t *)arg, &request, sizeof(request), -EFAULT); - + atomic_dec(&dev->buf_alloc); + dma->flags = _DRM_DMA_USE_AGP; return 0; } int i810_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - drm_buf_desc_t request; + drm_buf_desc_t request; - copy_from_user_ret(&request, - (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + copy_from_user_ret(&request, + (drm_buf_desc_t *)arg, + sizeof(request), + -EFAULT); - if(request.flags & _DRM_AGP_BUFFER) - return i810_addbufs_agp(inode, filp, cmd, arg); - else - return i810_addbufs_pci(inode, filp, cmd, arg); + if(request.flags & _DRM_AGP_BUFFER) + return i810_addbufs_agp(inode, filp, cmd, arg); + else + return -EINVAL; } int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, @@ -487,7 +333,7 @@ int i810_freebufs(struct inode *inode, struct file *filp, unsigned int cmd, } int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; @@ -506,6 +352,7 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, spin_lock(&dev->count_lock); if (atomic_read(&dev->buf_alloc)) { spin_unlock(&dev->count_lock); + DRM_DEBUG("Busy\n"); return -EBUSY; } ++dev->buf_use; /* Can't allocate more after this call */ @@ -515,34 +362,46 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, (drm_buf_map_t *)arg, sizeof(request), -EFAULT); - - if (request.count >= dma->buf_count) { - if(dma->flags & _DRM_DMA_USE_AGP) { - /* This is an ugly vicious hack */ - drm_map_t *map = NULL; - for(i = 0; i < dev->map_count; i++) { - map = dev->maplist[i]; - if(map->type == _DRM_AGP) break; - } - if (i >= dev->map_count || !map) { - retcode = -EINVAL; - goto done; - } + DRM_DEBUG("dma->flags : %lx\n", dma->flags); + if (request.count >= dma->buf_count) { + if(dma->flags & _DRM_DMA_USE_AGP) { + drm_i810_private_t *dev_priv = + (drm_i810_private_t *)dev->dev_private; + drm_map_t *map = NULL; - virtual = do_mmap(filp, 0, map->size, PROT_READ|PROT_WRITE, - MAP_SHARED, (unsigned long)map->handle); - } - else { - virtual = do_mmap(filp, 0, dma->byte_count, - PROT_READ|PROT_WRITE, MAP_SHARED, 0); - } + map = dev->maplist[dev_priv->buffer_map_idx]; + if (!map) { + DRM_DEBUG("map is null\n"); + retcode = -EINVAL; + goto done; + } + DRM_DEBUG("map->offset : %lx\n", map->offset); + DRM_DEBUG("map->size : %lx\n", map->size); + DRM_DEBUG("map->type : %d\n", map->type); + DRM_DEBUG("map->flags : %x\n", map->flags); + DRM_DEBUG("map->handle : %lx\n", map->handle); + DRM_DEBUG("map->mtrr : %d\n", map->mtrr); + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, map->size, + PROT_READ|PROT_WRITE, + MAP_SHARED, + (unsigned long)map->offset); + + up(¤t->mm->mmap_sem); + } else { + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, dma->byte_count, + PROT_READ|PROT_WRITE, MAP_SHARED, 0); + up(¤t->mm->mmap_sem); + } if (virtual > -1024UL) { - /* Real error */ + /* Real error */ + DRM_DEBUG("mmap error\n"); retcode = (signed long)virtual; goto done; } request.virtual = (void *)virtual; - + for (i = 0; i < dma->buf_count; i++) { if (copy_to_user(&request.list[i].idx, &dma->buflist[i]->idx, @@ -571,14 +430,15 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, } } } -done: + done: request.count = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - + copy_to_user_ret((drm_buf_map_t *)arg, &request, sizeof(request), -EFAULT); + DRM_DEBUG("retcode : %d\n", retcode); return retcode; } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_context.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_context.c new file mode 100644 index 000000000..5503edf24 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_context.c @@ -0,0 +1,205 @@ +/* i810_context.c -- IOCTLs for i810 contexts -*- linux-c -*- + * Created: Mon Dec 13 09:51:35 1999 by faith@precisioninsight.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Rickard E. (Rik) Faith <faith@precisioninsight.com> + * + * $XFree86$ + * + */ + +#include <linux/sched.h> + +#define __NO_VERSION__ +#include "drmP.h" +#include "i810_drv.h" + +static int i810_alloc_queue(drm_device_t *dev) +{ + int temp = drm_ctxbitmap_next(dev); + DRM_DEBUG("i810_alloc_queue: %d\n", temp); + return temp; +} + +int i810_context_switch(drm_device_t *dev, int old, int new) +{ + char buf[64]; + + atomic_inc(&dev->total_ctx); + + if (test_and_set_bit(0, &dev->context_flag)) { + DRM_ERROR("Reentering -- FIXME\n"); + return -EBUSY; + } + +#if DRM_DMA_HISTOGRAM + dev->ctx_start = get_cycles(); +#endif + + DRM_DEBUG("Context switch from %d to %d\n", old, new); + + if (new == dev->last_context) { + clear_bit(0, &dev->context_flag); + return 0; + } + + if (drm_flags & DRM_FLAG_NOCTX) { + i810_context_switch_complete(dev, new); + } else { + sprintf(buf, "C %d %d\n", old, new); + drm_write_string(dev, buf); + } + + return 0; +} + +int i810_context_switch_complete(drm_device_t *dev, int new) +{ + dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ + dev->last_switch = jiffies; + + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("Lock isn't held after context switch\n"); + } + + /* If a context switch is ever initiated + when the kernel holds the lock, release + that lock here. */ +#if DRM_DMA_HISTOGRAM + atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles() + - dev->ctx_start)]); + +#endif + clear_bit(0, &dev->context_flag); + wake_up(&dev->context_wait); + + return 0; +} + +int i810_resctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_ctx_res_t res; + drm_ctx_t ctx; + int i; + + DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); + copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT); + if (res.count >= DRM_RESERVED_CONTEXTS) { + memset(&ctx, 0, sizeof(ctx)); + for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { + ctx.handle = i; + copy_to_user_ret(&res.contexts[i], + &i, + sizeof(i), + -EFAULT); + } + } + res.count = DRM_RESERVED_CONTEXTS; + copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT); + return 0; +} + +int i810_addctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + if ((ctx.handle = i810_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { + /* Skip kernel's context and get a new one. */ + ctx.handle = i810_alloc_queue(dev); + } + if (ctx.handle == -1) { + DRM_DEBUG("Not enough free contexts.\n"); + /* Should this return -EBUSY instead? */ + return -ENOMEM; + } + DRM_DEBUG("%d\n", ctx.handle); + copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT); + return 0; +} + +int i810_modctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + /* This does nothing for the i810 */ + return 0; +} + +int i810_getctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_ctx_t ctx; + + copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT); + /* This is 0, because we don't hanlde any context flags */ + ctx.flags = 0; + copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT); + return 0; +} + +int i810_switchctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + DRM_DEBUG("%d\n", ctx.handle); + return i810_context_switch(dev, dev->last_context, ctx.handle); +} + +int i810_newctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + DRM_DEBUG("%d\n", ctx.handle); + i810_context_switch_complete(dev, ctx.handle); + + return 0; +} + +int i810_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + DRM_DEBUG("%d\n", ctx.handle); + if(ctx.handle != DRM_KERNEL_CONTEXT) { + drm_ctxbitmap_free(dev, ctx.handle); + } + + return 0; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c index 09959b657..30fda5b8b 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c @@ -25,8 +25,9 @@ * * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> * Jeff Hartmann <jhartmann@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c,v 1.1 2000/02/11 17:26:04 dawes Exp $ + * $XFree86$ * */ @@ -36,6 +37,9 @@ #include <linux/interrupt.h> /* For task queue support */ +#define I810_BUF_FREE 1 +#define I810_BUF_USED 0 + #define I810_REG(reg) 2 #define I810_BASE(reg) ((unsigned long) \ dev->maplist[I810_REG(reg)]->handle) @@ -43,544 +47,457 @@ #define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg) #define I810_READ(reg) I810_DEREF(reg) #define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0) - -void i810_dma_init(drm_device_t *dev) +#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg) +#define I810_READ16(reg) I810_DEREF16(reg) +#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) + +#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; + +#define BEGIN_LP_RING(n) do { \ + if (I810_VERBOSE) \ + DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ + n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i810_wait_ring(dev, n*4); \ + dev_priv->ring.space -= n*4; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ +} while (0) + +#define ADVANCE_LP_RING() do { \ + if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ + dev_priv->ring.tail = outring; \ + I810_WRITE(LP_RING + RING_TAIL, outring); \ +} while(0) + +#define OUT_RING(n) do { \ + if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ +} while (0); + +static inline void i810_print_status_page(drm_device_t *dev) { - printk(KERN_INFO "i810_dma_init\n"); + drm_device_dma_t *dma = dev->dma; + drm_i810_private_t *dev_priv = dev->dev_private; + u32 *temp = (u32 *)dev_priv->hw_status_page; + int i; + + DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]); + DRM_DEBUG( "hw_status: LpRing Head ptr : %x\n", temp[1]); + DRM_DEBUG( "hw_status: IRing Head ptr : %x\n", temp[2]); + DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]); + DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]); + for(i = 6; i < dma->buf_count + 6; i++) { + DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]); + } } -void i810_dma_cleanup(drm_device_t *dev) +static drm_buf_t *i810_freelist_get(drm_device_t *dev) { - printk(KERN_INFO "i810_dma_cleanup\n"); + drm_device_dma_t *dma = dev->dma; + int i; + int used; + + /* Linear search might not be the best solution */ + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + /* In use is already a pointer */ + used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, + I810_BUF_USED); + if(used == I810_BUF_FREE) { + return buf; + } + } + return NULL; } -static inline void i810_dma_dispatch(drm_device_t *dev, unsigned long address, - unsigned long length) +/* This should only be called if the buffer is not sent to the hardware + * yet, the hardware updates in use for us once its on the ring buffer. + */ + +static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf) { - printk(KERN_INFO "i810_dma_dispatch\n"); + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + int used; + + /* In use is already a pointer */ + used = cmpxchg(buf_priv->in_use, I810_BUF_USED, I810_BUF_FREE); + if(used != I810_BUF_USED) { + DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); + return -EINVAL; + } + + return 0; } -static inline void i810_dma_quiescent(drm_device_t *dev) +static int i810_dma_get_buffers(drm_device_t *dev, drm_dma_t *d) { + int i; + drm_buf_t *buf; + + for (i = d->granted_count; i < d->request_count; i++) { + buf = i810_freelist_get(dev); + if (!buf) break; + buf->pid = current->pid; + copy_to_user_ret(&d->request_indices[i], + &buf->idx, + sizeof(buf->idx), + -EFAULT); + copy_to_user_ret(&d->request_sizes[i], + &buf->total, + sizeof(buf->total), + -EFAULT); + ++d->granted_count; + } + return 0; } -static inline void i810_dma_ready(drm_device_t *dev) +static unsigned long i810_alloc_page(drm_device_t *dev) { - i810_dma_quiescent(dev); - printk(KERN_INFO "i810_dma_ready\n"); + unsigned long address; + + address = __get_free_page(GFP_KERNEL); + if(address == 0UL) + return 0; + + atomic_inc(&mem_map[MAP_NR((void *) address)].count); + set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags); + + return address; } -static inline int i810_dma_is_ready(drm_device_t *dev) +static void i810_free_page(drm_device_t *dev, unsigned long page) { - - i810_dma_quiescent(dev); - - printk(KERN_INFO "i810_dma_is_ready\n"); - return 1; + if(page == 0UL) + return; + + atomic_dec(&mem_map[MAP_NR((void *) page)].count); + clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags); + wake_up(&mem_map[MAP_NR((void *) page)].wait); + free_page(page); + return; } - -static void i810_dma_service(int irq, void *device, struct pt_regs *regs) +static int i810_dma_cleanup(drm_device_t *dev) { - drm_device_t *dev = (drm_device_t *)device; - drm_device_dma_t *dma = dev->dma; - - atomic_inc(&dev->total_irq); - if (i810_dma_is_ready(dev)) { - /* Free previous buffer */ - if (test_and_set_bit(0, &dev->dma_flag)) { - atomic_inc(&dma->total_missed_free); - return; + if(dev->dev_private) { + drm_i810_private_t *dev_priv = + (drm_i810_private_t *) dev->dev_private; + + if(dev_priv->ring.virtual_start) { + drm_ioremapfree((void *) dev_priv->ring.virtual_start, + dev_priv->ring.Size); } - if (dma->this_buffer) { - drm_free_buffer(dev, dma->this_buffer); - dma->this_buffer = NULL; + if(dev_priv->hw_status_page != 0UL) { + i810_free_page(dev, dev_priv->hw_status_page); + /* Need to rewrite hardware status page */ + I810_WRITE(0x02080, 0x1ffff000); } - clear_bit(0, &dev->dma_flag); - - /* Dispatch new buffer */ - queue_task(&dev->tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); + drm_free(dev->dev_private, sizeof(drm_i810_private_t), + DRM_MEM_DRIVER); + dev->dev_private = NULL; } + return 0; } -/* Only called by i810_dma_schedule. */ -static int i810_do_dma(drm_device_t *dev, int locked) +static int i810_wait_ring(drm_device_t *dev, int n) { - unsigned long address; - unsigned long length; - drm_buf_t *buf; - int retcode = 0; - drm_device_dma_t *dma = dev->dma; -#if DRM_DMA_HISTOGRAM - cycles_t dma_start, dma_stop; -#endif - - if (test_and_set_bit(0, &dev->dma_flag)) { - atomic_inc(&dma->total_missed_dma); - return -EBUSY; - } - -#if DRM_DMA_HISTOGRAM - dma_start = get_cycles(); -#endif - - if (!dma->next_buffer) { - DRM_ERROR("No next_buffer\n"); - clear_bit(0, &dev->dma_flag); - return -EINVAL; - } - - buf = dma->next_buffer; - address = (unsigned long)buf->bus_address; - length = buf->used; + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_ring_buffer_t *ring = &(dev_priv->ring); + int iters = 0; + unsigned long end; + + end = jiffies + (HZ*3); + while (ring->space < n) { + int i; - - DRM_DEBUG("context %d, buffer %d (%ld bytes)\n", - buf->context, buf->idx, length); - - if (buf->list == DRM_LIST_RECLAIM) { - drm_clear_next_buffer(dev); - drm_free_buffer(dev, buf); - clear_bit(0, &dev->dma_flag); - return -EINVAL; - } - - if (!length) { - DRM_ERROR("0 length buffer\n"); - drm_clear_next_buffer(dev); - drm_free_buffer(dev, buf); - clear_bit(0, &dev->dma_flag); - return 0; - } - - if (!i810_dma_is_ready(dev)) { - clear_bit(0, &dev->dma_flag); - return -EBUSY; - } - - if (buf->while_locked) { - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("Dispatching buffer %d from pid %d" - " \"while locked\", but no lock held\n", - buf->idx, buf->pid); - } - } else { - if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - atomic_inc(&dma->total_missed_lock); - clear_bit(0, &dev->dma_flag); - return -EBUSY; + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->space = ring->head - (ring->tail+8); + + if (ring->space < 0) ring->space += ring->Size; + + iters++; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("space: %d wanted %d\n", ring->space, n); + DRM_ERROR("lockup\n"); + goto out_wait_ring; } - } - - if (dev->last_context != buf->context - && !(dev->queuelist[buf->context]->flags - & _DRM_CONTEXT_PRESERVED)) { - /* PRE: dev->last_context != buf->context */ - if (drm_context_switch(dev, dev->last_context, buf->context)) { - drm_clear_next_buffer(dev); - drm_free_buffer(dev, buf); - } - retcode = -EBUSY; - goto cleanup; - - /* POST: we will wait for the context - switch and will dispatch on a later call - when dev->last_context == buf->context. - NOTE WE HOLD THE LOCK THROUGHOUT THIS - TIME! */ - } - - drm_clear_next_buffer(dev); - buf->pending = 1; - buf->waiting = 0; - buf->list = DRM_LIST_PEND; -#if DRM_DMA_HISTOGRAM - buf->time_dispatched = get_cycles(); -#endif - i810_dma_dispatch(dev, address, length); - drm_free_buffer(dev, dma->this_buffer); - dma->this_buffer = buf; - - atomic_add(length, &dma->total_bytes); - atomic_inc(&dma->total_dmas); - - if (!buf->while_locked && !dev->context_flag && !locked) { - if (drm_lock_free(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("\n"); - } + for (i = 0 ; i < 2000 ; i++) ; } -cleanup: - - clear_bit(0, &dev->dma_flag); -#if DRM_DMA_HISTOGRAM - dma_stop = get_cycles(); - atomic_inc(&dev->histo.dma[drm_histogram_slot(dma_stop - dma_start)]); -#endif - - return retcode; -} - -static void i810_dma_schedule_timer_wrapper(unsigned long dev) -{ - i810_dma_schedule((drm_device_t *)dev, 0); +out_wait_ring: + return iters; } -static void i810_dma_schedule_tq_wrapper(void *dev) +static void i810_kernel_lost_context(drm_device_t *dev) { - i810_dma_schedule(dev, 0); + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_ring_buffer_t *ring = &(dev_priv->ring); + + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->tail = I810_READ(LP_RING + RING_TAIL); + ring->space = ring->head - (ring->tail+8); + if (ring->space < 0) ring->space += ring->Size; } -int i810_dma_schedule(drm_device_t *dev, int locked) +static int i810_freelist_init(drm_device_t *dev) { - int next; - drm_queue_t *q; - drm_buf_t *buf; - int retcode = 0; - int processed = 0; - int missed; - int expire = 20; - drm_device_dma_t *dma = dev->dma; -#if DRM_DMA_HISTOGRAM - cycles_t schedule_start; -#endif - - if (test_and_set_bit(0, &dev->interrupt_flag)) { - /* Not reentrant */ - atomic_inc(&dma->total_missed_sched); - return -EBUSY; - } - missed = atomic_read(&dma->total_missed_sched); - -#if DRM_DMA_HISTOGRAM - schedule_start = get_cycles(); -#endif - -again: - if (dev->context_flag) { - clear_bit(0, &dev->interrupt_flag); - return -EBUSY; - } - if (dma->next_buffer) { - /* Unsent buffer that was previously - selected, but that couldn't be sent - because the lock could not be obtained - or the DMA engine wasn't ready. Try - again. */ - atomic_inc(&dma->total_tried); - if (!(retcode = i810_do_dma(dev, locked))) { - atomic_inc(&dma->total_hit); - ++processed; - } - } else { - do { - next = drm_select_queue(dev, - i810_dma_schedule_timer_wrapper); - if (next >= 0) { - q = dev->queuelist[next]; - buf = drm_waitlist_get(&q->waitlist); - dma->next_buffer = buf; - dma->next_queue = q; - if (buf && buf->list == DRM_LIST_RECLAIM) { - drm_clear_next_buffer(dev); - drm_free_buffer(dev, buf); - } - } - } while (next >= 0 && !dma->next_buffer); - if (dma->next_buffer) { - if (!(retcode = i810_do_dma(dev, locked))) { - ++processed; - } - } + drm_device_dma_t *dma = dev->dma; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u8 *hw_status = (u8 *)dev_priv->hw_status_page; + int i; + int my_idx = 24; + + if(dma->buf_count > 1019) { + /* Not enough space in the status page for the freelist */ + return -EINVAL; } - if (--expire) { - if (missed != atomic_read(&dma->total_missed_sched)) { - atomic_inc(&dma->total_lost); - if (i810_dma_is_ready(dev)) goto again; - } - if (processed && i810_dma_is_ready(dev)) { - atomic_inc(&dma->total_lost); - processed = 0; - goto again; - } + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + + buf_priv->in_use = hw_status + my_idx; + DRM_DEBUG("buf_priv->in_use : %p\n", buf_priv->in_use); + *buf_priv->in_use = I810_BUF_FREE; + buf_priv->my_use_idx = my_idx; + my_idx += 4; } - - clear_bit(0, &dev->interrupt_flag); - -#if DRM_DMA_HISTOGRAM - atomic_inc(&dev->histo.schedule[drm_histogram_slot(get_cycles() - - schedule_start)]); -#endif - return retcode; + return 0; } -static int i810_dma_priority(drm_device_t *dev, drm_dma_t *d) +static int i810_dma_initialize(drm_device_t *dev, + drm_i810_private_t *dev_priv, + drm_i810_init_t *init) { - unsigned long address; - unsigned long length; - int must_free = 0; - int retcode = 0; - int i; - int idx; - drm_buf_t *buf; - drm_buf_t *last_buf = NULL; - drm_device_dma_t *dma = dev->dma; - DECLARE_WAITQUEUE(entry, current); - - /* Turn off interrupt handling */ - while (test_and_set_bit(0, &dev->interrupt_flag)) { - schedule(); - if (signal_pending(current)) return -EINTR; - } - if (!(d->flags & _DRM_DMA_WHILE_LOCKED)) { - while (!drm_lock_take(&dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - schedule(); - if (signal_pending(current)) { - clear_bit(0, &dev->interrupt_flag); - return -EINTR; - } - } - ++must_free; - } - atomic_inc(&dma->total_prio); - - for (i = 0; i < d->send_count; i++) { - idx = d->send_indices[i]; - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("Index %d (of %d max)\n", - d->send_indices[i], dma->buf_count - 1); - continue; - } - buf = dma->buflist[ idx ]; - if (buf->pid != current->pid) { - DRM_ERROR("Process %d using buffer owned by %d\n", - current->pid, buf->pid); - retcode = -EINVAL; - goto cleanup; - } - if (buf->list != DRM_LIST_NONE) { - DRM_ERROR("Process %d using %d's buffer on list %d\n", - current->pid, buf->pid, buf->list); - retcode = -EINVAL; - goto cleanup; - } - /* This isn't a race condition on - buf->list, since our concern is the - buffer reclaim during the time the - process closes the /dev/drm? handle, so - it can't also be doing DMA. */ - buf->list = DRM_LIST_PRIO; - buf->used = d->send_sizes[i]; - buf->context = d->context; - buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED; - address = (unsigned long)buf->address; - length = buf->used; - if (!length) { - DRM_ERROR("0 length buffer\n"); - } - if (buf->pending) { - DRM_ERROR("Sending pending buffer:" - " buffer %d, offset %d\n", - d->send_indices[i], i); - retcode = -EINVAL; - goto cleanup; - } - if (buf->waiting) { - DRM_ERROR("Sending waiting buffer:" - " buffer %d, offset %d\n", - d->send_indices[i], i); - retcode = -EINVAL; - goto cleanup; - } - buf->pending = 1; - - if (dev->last_context != buf->context - && !(dev->queuelist[buf->context]->flags - & _DRM_CONTEXT_PRESERVED)) { - add_wait_queue(&dev->context_wait, &entry); - current->state = TASK_INTERRUPTIBLE; - /* PRE: dev->last_context != buf->context */ - drm_context_switch(dev, dev->last_context, - buf->context); - /* POST: we will wait for the context - switch and will dispatch on a later call - when dev->last_context == buf->context. - NOTE WE HOLD THE LOCK THROUGHOUT THIS - TIME! */ - schedule(); - current->state = TASK_RUNNING; - remove_wait_queue(&dev->context_wait, &entry); - if (signal_pending(current)) { - retcode = -EINTR; - goto cleanup; - } - if (dev->last_context != buf->context) { - DRM_ERROR("Context mismatch: %d %d\n", - dev->last_context, - buf->context); - } - } - -#if DRM_DMA_HISTOGRAM - buf->time_queued = get_cycles(); - buf->time_dispatched = buf->time_queued; -#endif - i810_dma_dispatch(dev, address, length); - if (drm_lock_free(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("\n"); - } - - atomic_add(length, &dma->total_bytes); - atomic_inc(&dma->total_dmas); - - if (last_buf) { - drm_free_buffer(dev, last_buf); - } - last_buf = buf; - } + drm_map_t *sarea_map; + dev->dev_private = (void *) dev_priv; + memset(dev_priv, 0, sizeof(drm_i810_private_t)); -cleanup: - if (last_buf) { - i810_dma_ready(dev); - drm_free_buffer(dev, last_buf); + if (init->ring_map_idx >= dev->map_count || + init->buffer_map_idx >= dev->map_count) { + i810_dma_cleanup(dev); + DRM_ERROR("ring_map or buffer_map are invalid\n"); + return -EINVAL; } - - if (must_free && !dev->context_flag) { - if (drm_lock_free(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("\n"); - } + + dev_priv->ring_map_idx = init->ring_map_idx; + dev_priv->buffer_map_idx = init->buffer_map_idx; + sarea_map = dev->maplist[0]; + dev_priv->sarea_priv = (drm_i810_sarea_t *) + ((u8 *)sarea_map->handle + + init->sarea_priv_offset); + + atomic_set(&dev_priv->flush_done, 0); + init_waitqueue_head(&dev_priv->flush_queue); + + dev_priv->ring.Start = init->ring_start; + dev_priv->ring.End = init->ring_end; + dev_priv->ring.Size = init->ring_size; + dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + + init->ring_start, + init->ring_size); + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + + if (dev_priv->ring.virtual_start == NULL) { + i810_dma_cleanup(dev); + DRM_ERROR("can not ioremap virtual address for" + " ring buffer\n"); + return -ENOMEM; } - clear_bit(0, &dev->interrupt_flag); - return retcode; + + /* Program Hardware Status Page */ + dev_priv->hw_status_page = i810_alloc_page(dev); + memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); + if(dev_priv->hw_status_page == 0UL) { + i810_dma_cleanup(dev); + DRM_ERROR("Can not allocate hardware status page\n"); + return -ENOMEM; + } + DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); + + I810_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page)); + DRM_DEBUG("Enabled hardware status page\n"); + + /* Now we need to init our freelist */ + if(i810_freelist_init(dev) != 0) { + i810_dma_cleanup(dev); + DRM_ERROR("Not enough space in the status page for" + " the freelist\n"); + return -ENOMEM; + } + return 0; } -static int i810_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) +int i810_dma_init(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - DECLARE_WAITQUEUE(entry, current); - drm_buf_t *last_buf = NULL; - int retcode = 0; - drm_device_dma_t *dma = dev->dma; - - if (d->flags & _DRM_DMA_BLOCK) { - last_buf = dma->buflist[d->send_indices[d->send_count-1]]; - add_wait_queue(&last_buf->dma_wait, &entry); - } + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i810_private_t *dev_priv; + drm_i810_init_t init; + int retcode = 0; - if ((retcode = drm_dma_enqueue(dev, d))) { - if (d->flags & _DRM_DMA_BLOCK) - remove_wait_queue(&last_buf->dma_wait, &entry); - return retcode; - } - - i810_dma_schedule(dev, 0); + copy_from_user_ret(&init, (drm_i810_init_t *)arg, + sizeof(init), -EFAULT); - if (d->flags & _DRM_DMA_BLOCK) { - DRM_DEBUG("%d waiting\n", current->pid); - current->state = TASK_INTERRUPTIBLE; - for (;;) { - if (!last_buf->waiting - && !last_buf->pending) - break; /* finished */ - schedule(); - if (signal_pending(current)) { - retcode = -EINTR; /* Can't restart */ - break; - } - } - current->state = TASK_RUNNING; - DRM_DEBUG("%d running\n", current->pid); - remove_wait_queue(&last_buf->dma_wait, &entry); - if (!retcode - || (last_buf->list==DRM_LIST_PEND && !last_buf->pending)) { - if (!waitqueue_active(&last_buf->dma_wait)) { - drm_free_buffer(dev, last_buf); - } - } - if (retcode) { - DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n", - d->context, - last_buf->waiting, - last_buf->pending, - DRM_WAITCOUNT(dev, d->context), - last_buf->idx, - last_buf->list, - last_buf->pid, - current->pid); - } + switch(init.func) { + case I810_INIT_DMA: + dev_priv = drm_alloc(sizeof(drm_i810_private_t), + DRM_MEM_DRIVER); + if(dev_priv == NULL) return -ENOMEM; + retcode = i810_dma_initialize(dev, dev_priv, &init); + break; + case I810_CLEANUP_DMA: + retcode = i810_dma_cleanup(dev); + break; + default: + retcode = -EINVAL; + break; } - return retcode; + + return retcode; } -int i810_dma(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +static void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf, + int used ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_device_dma_t *dma = dev->dma; - int retcode = 0; - drm_dma_t d; - - printk("i810_dma start\n"); - copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); - DRM_DEBUG("%d %d: %d send, %d req\n", - current->pid, d.context, d.send_count, d.request_count); + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + unsigned long address = (unsigned long)buf->bus_address; + unsigned long start = address - dev->agp->base; + RING_LOCALS; + + dev_priv->counter++; + DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); + DRM_DEBUG( "i810_dma_dispatch\n"); + DRM_DEBUG( "start : 0x%lx\n", start); + DRM_DEBUG( "used : 0x%x\n", used); + DRM_DEBUG( "start + used - 4 : 0x%lx\n", start + used - 4); + i810_kernel_lost_context(dev); + + BEGIN_LP_RING(10); + OUT_RING( CMD_OP_BATCH_BUFFER ); + OUT_RING( start | BB1_PROTECTED ); + OUT_RING( start + used - 4 ); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( buf_priv->my_use_idx ); + OUT_RING( I810_BUF_FREE ); + OUT_RING( CMD_REPORT_HEAD ); + ADVANCE_LP_RING(); +} - if (d.context == DRM_KERNEL_CONTEXT || d.context >= dev->queue_slots) { - DRM_ERROR("Process %d using context %d\n", - current->pid, d.context); - return -EINVAL; - } +static void i810_dma_dispatch_vertex(drm_device_t *dev, + drm_buf_t *buf, + int discard, + int used) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_clip_rect_t *box = sarea_priv->boxes; + int nbox = sarea_priv->nbox; + unsigned long address = (unsigned long)buf->bus_address; + unsigned long start = address - dev->agp->base; + int i = 0; + RING_LOCALS; - if (d.send_count < 0 || d.send_count > dma->buf_count) { - DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n", - current->pid, d.send_count, dma->buf_count); - return -EINVAL; - } - if (d.request_count < 0 || d.request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - current->pid, d.request_count, dma->buf_count); - return -EINVAL; + + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; + + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + address, used, nbox); + + dev_priv->counter++; + DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); + DRM_DEBUG( "i810_dma_dispatch\n"); + DRM_DEBUG( "start : %lx\n", start); + DRM_DEBUG( "used : %d\n", used); + DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); + i810_kernel_lost_context(dev); + + if (used) { + do { + if (i < nbox) { + BEGIN_LP_RING(4); + OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | + SC_ENABLE ); + OUT_RING( GFX_OP_SCISSOR_INFO ); + OUT_RING( box[i].x1 | (box[i].y1 << 16) ); + OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) ); + ADVANCE_LP_RING(); + } + + BEGIN_LP_RING(4); + OUT_RING( CMD_OP_BATCH_BUFFER ); + OUT_RING( start | BB1_PROTECTED ); + OUT_RING( start + used - 4 ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + } while (++i < nbox); } - if (d.send_count) { -#if 0 - if (d.flags & _DRM_DMA_PRIORITY) - retcode = i810_dma_priority(dev, &d); - else - retcode = i810_dma_send_buffers(dev, &d); -#endif - printk("i810_dma priority\n"); + BEGIN_LP_RING(10); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); + OUT_RING( 0 ); - retcode = i810_dma_priority(dev, &d); + if (discard) { + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( buf_priv->my_use_idx ); + OUT_RING( I810_BUF_FREE ); + OUT_RING( 0 ); } - d.granted_count = 0; + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); +} - if (!retcode && d.request_count) { - retcode = drm_dma_get_buffers(dev, &d); - } - DRM_DEBUG("%d returning, granted = %d\n", - current->pid, d.granted_count); - copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT); +/* Interrupts are only for flushing */ +static void i810_dma_service(int irq, void *device, struct pt_regs *regs) +{ + drm_device_t *dev = (drm_device_t *)device; + u16 temp; + + atomic_inc(&dev->total_irq); + temp = I810_READ16(I810REG_INT_IDENTITY_R); + temp = temp & ~(0x6000); + if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, + temp); /* Clear all interrupts */ + + queue_task(&dev->tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} - printk("i810_dma end (granted)\n"); - return retcode; +static void i810_dma_task_queue(void *device) +{ + drm_device_t *dev = (drm_device_t *) device; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + + atomic_set(&dev_priv->flush_done, 1); + wake_up_interruptible(&dev_priv->flush_queue); } int i810_irq_install(drm_device_t *dev, int irq) { int retcode; - + u16 temp; + if (!irq) return -EINVAL; down(&dev->struct_sem); @@ -591,6 +508,7 @@ int i810_irq_install(drm_device_t *dev, int irq) dev->irq = irq; up(&dev->struct_sem); + DRM_DEBUG( "Interrupt Install : %d\n", irq); DRM_DEBUG("%d\n", irq); dev->context_flag = 0; @@ -603,12 +521,21 @@ int i810_irq_install(drm_device_t *dev, int irq) dev->tq.next = NULL; dev->tq.sync = 0; - dev->tq.routine = i810_dma_schedule_tq_wrapper; + dev->tq.routine = i810_dma_task_queue; dev->tq.data = dev; - /* Before installing handler */ - /* TODO */ + temp = I810_READ16(I810REG_HWSTAM); + temp = temp & 0x6000; + I810_WRITE16(I810REG_HWSTAM, temp); + + temp = I810_READ16(I810REG_INT_MASK_R); + temp = temp & 0x6000; + I810_WRITE16(I810REG_INT_MASK_R, temp); /* Unmask interrupts */ + temp = I810_READ16(I810REG_INT_ENABLE_R); + temp = temp & 0x6000; + I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Disable all interrupts */ + /* Install handler */ if ((retcode = request_irq(dev->irq, i810_dma_service, @@ -620,15 +547,18 @@ int i810_irq_install(drm_device_t *dev, int irq) up(&dev->struct_sem); return retcode; } - - /* After installing handler */ - /* TODO */ + temp = I810_READ16(I810REG_INT_ENABLE_R); + temp = temp & 0x6000; + temp = temp | 0x0003; + I810_WRITE16(I810REG_INT_ENABLE_R, + temp); /* Enable bp & user interrupts */ return 0; } int i810_irq_uninstall(drm_device_t *dev) { int irq; + u16 temp; down(&dev->struct_sem); irq = dev->irq; @@ -636,16 +566,25 @@ int i810_irq_uninstall(drm_device_t *dev) up(&dev->struct_sem); if (!irq) return -EINVAL; - + + DRM_DEBUG( "Interrupt UnInstall: %d\n", irq); DRM_DEBUG("%d\n", irq); - - /* TODO : Disable interrupts */ + + temp = I810_READ16(I810REG_INT_IDENTITY_R); + temp = temp & ~(0x6000); + if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, + temp); /* Clear all interrupts */ + + temp = I810_READ16(I810REG_INT_ENABLE_R); + temp = temp & 0x6000; + I810_WRITE16(I810REG_INT_ENABLE_R, + temp); /* Disable all interrupts */ + free_irq(irq, dev); return 0; } - int i810_control(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -654,8 +593,7 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd, drm_control_t ctl; int retcode; - printk(KERN_INFO "i810_control\n"); - i810_dma_init(dev); + DRM_DEBUG( "i810_control\n"); copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT); @@ -674,20 +612,134 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd, return 0; } +static inline void i810_dma_emit_flush(drm_device_t *dev) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + i810_kernel_lost_context(dev); + BEGIN_LP_RING(2); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); +} + +static inline void i810_dma_quiescent_emit(drm_device_t *dev) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + i810_kernel_lost_context(dev); + BEGIN_LP_RING(4); + + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); +} + +static void i810_dma_quiescent(drm_device_t *dev) +{ + DECLARE_WAITQUEUE(entry, current); + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + unsigned long end; + + if(dev_priv == NULL) { + return; + } + atomic_set(&dev_priv->flush_done, 0); + current->state = TASK_INTERRUPTIBLE; + add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + + for (;;) { + i810_dma_quiescent_emit(dev); + if (atomic_read(&dev_priv->flush_done) == 1) break; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("lockup\n"); + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->flush_queue, &entry); + + return; +} + +static int i810_flush_queue(drm_device_t *dev) +{ + DECLARE_WAITQUEUE(entry, current); + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + unsigned long end; + int ret = 0; + + if(dev_priv == NULL) { + return 0; + } + atomic_set(&dev_priv->flush_done, 0); + current->state = TASK_INTERRUPTIBLE; + add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + for (;;) { + i810_dma_emit_flush(dev); + if (atomic_read(&dev_priv->flush_done) == 1) break; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("lockup\n"); + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + ret = -EINTR; /* Can't restart */ + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->flush_queue, &entry); + + return ret; +} + +/* Must be called with the lock held */ +void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) +{ + drm_device_dma_t *dma = dev->dma; + int i; + + if (!dma) return; + if(dev->dev_private == NULL) return; + + i810_flush_queue(dev); + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + + if (buf->pid == pid) { + /* Only buffers that need to get reclaimed ever + * get set to free */ + if(buf_priv == NULL) return; + cmpxchg(buf_priv->in_use, + I810_BUF_USED, I810_BUF_FREE); + } + } +} + int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; + DECLARE_WAITQUEUE(entry, current); int ret = 0; drm_lock_t lock; - drm_queue_t *q; -#if DRM_DMA_HISTOGRAM - cycles_t start; - - dev->lck_start = start = get_cycles(); -#endif copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); @@ -696,16 +748,20 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, current->pid, lock.context); return -EINVAL; } + + DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", + lock.context, current->pid, dev->lock.hw_lock->lock, + lock.flags); - if (lock.context < 0 || lock.context >= dev->queue_count) { + if (lock.context < 0) { return -EINVAL; } - q = dev->queuelist[lock.context]; - - ret = drm_flush_block_and_flush(dev, lock.context, lock.flags); + /* Only one queue: + */ if (!ret) { - if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) +#if 0 + if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) != lock.context) { long j = jiffies - dev->lock.lock_time; @@ -716,6 +772,7 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, schedule_timeout(j); } } +#endif add_wait_queue(&dev->lock.lock_queue, &entry); for (;;) { if (!dev->lock.hw_lock) { @@ -728,13 +785,13 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->lock.pid = current->pid; dev->lock.lock_time = jiffies; atomic_inc(&dev->total_locks); - atomic_inc(&q->total_locks); break; /* Got lock */ } /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; + DRM_DEBUG("Calling lock schedule\n"); schedule(); if (signal_pending(current)) { ret = -ERESTARTSYS; @@ -744,19 +801,184 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, current->state = TASK_RUNNING; remove_wait_queue(&dev->lock.lock_queue, &entry); } - - drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */ if (!ret) { - if (lock.flags & _DRM_LOCK_READY) - i810_dma_ready(dev); - if (lock.flags & _DRM_LOCK_QUIESCENT) - i810_dma_quiescent(dev); + if (lock.flags & _DRM_LOCK_QUIESCENT) { + DRM_DEBUG("_DRM_LOCK_QUIESCENT\n"); + DRM_DEBUG("fred\n"); + i810_dma_quiescent(dev); + } } + DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); + return ret; +} -#if DRM_DMA_HISTOGRAM - atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]); -#endif +int i810_flush_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + + DRM_DEBUG("i810_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_flush_ioctl called without lock held\n"); + return -EINVAL; + } + + i810_flush_queue(dev); + return 0; +} + +static int i810DmaGeneral(drm_device_t *dev, drm_i810_general_t *args) +{ + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf = dma->buflist[ args->idx ]; + + if (!args->used) { + i810_freelist_put(dev, buf); + } else { + i810_dma_dispatch_general( dev, buf, args->used ); + atomic_add(args->used, &dma->total_bytes); + atomic_inc(&dma->total_dmas); + } + return 0; +} + +static int i810DmaVertex(drm_device_t *dev, drm_i810_vertex_t *args) +{ + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf = dma->buflist[ args->idx ]; + i810_dma_dispatch_vertex( dev, buf, args->discard, args->used ); + atomic_add(args->used, &dma->total_bytes); + atomic_inc(&dma->total_dmas); + return 0; +} + +int i810_dma_general(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i810_general_t general; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; + + int retcode = 0; - return ret; + copy_from_user_ret(&general, (drm_i810_general_t *)arg, sizeof(general), + -EFAULT); + + DRM_DEBUG("i810 dma general idx %d used %d\n", + general.idx, general.used); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_general called without lock held\n"); + return -EINVAL; + } + + retcode = i810DmaGeneral(dev, &general); + sarea_priv->last_enqueue = dev_priv->counter-1; + sarea_priv->last_dispatch = (int) hw_status[5]; + + return retcode; +} + +int i810_dma_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; + drm_i810_vertex_t vertex; + int retcode = 0; + + copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), + -EFAULT); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_vertex called without lock held\n"); + return -EINVAL; + } + + DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", + vertex.idx, vertex.used, vertex.discard); + + retcode = i810DmaVertex(dev, &vertex); + sarea_priv->last_enqueue = dev_priv->counter-1; + sarea_priv->last_dispatch = (int) hw_status[5]; + + return retcode; + +} + +int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; + + sarea_priv->last_dispatch = (int) hw_status[5]; + return 0; +} + +int i810_dma(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + int retcode = 0; + drm_dma_t d; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; + + + copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); + DRM_DEBUG("%d %d: %d send, %d req\n", + current->pid, d.context, d.send_count, d.request_count); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma called without lock held\n"); + return -EINVAL; + } + + /* Please don't send us buffers. + */ + if (d.send_count != 0) { + DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", + current->pid, d.send_count); + return -EINVAL; + } + + /* We'll send you buffers. + */ + if (d.request_count < 0 || d.request_count > dma->buf_count) { + DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", + current->pid, d.request_count, dma->buf_count); + return -EINVAL; + } + + d.granted_count = 0; + + if (!retcode && d.request_count) { + retcode = i810_dma_get_buffers(dev, &d); + } + + DRM_DEBUG("i810_dma: %d returning, granted = %d\n", + current->pid, d.granted_count); + + copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT); + sarea_priv->last_dispatch = (int) hw_status[5]; + + return retcode; } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h new file mode 100644 index 000000000..0754874c6 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h @@ -0,0 +1,93 @@ +#ifndef _I810_DRM_H_ +#define _I810_DRM_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +/* Might one day want to support the client-side ringbuffer code again. + */ +#ifndef _I810_DEFINES_ +#define _I810_DEFINES_ + +#define I810_USE_BATCH 1 +#define I810_DMA_BUF_ORDER 12 +#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER) +#define I810_DMA_BUF_NR 256 +#define I810_NR_SAREA_CLIPRECTS 2 + +/* Each region is a minimum of 64k, and there are at most 64 of them. + */ + +#define I810_NR_TEX_REGIONS 64 +#define I810_LOG_MIN_TEX_REGION_SIZE 16 +#endif + +typedef struct _drm_i810_init { + enum { + I810_INIT_DMA = 0x01, + I810_CLEANUP_DMA = 0x02 + } func; + int ring_map_idx; + int buffer_map_idx; + int sarea_priv_offset; + unsigned long ring_start; + unsigned long ring_end; + unsigned long ring_size; +} drm_i810_init_t; + +/* Warning: If you change the SAREA structure you must change the Xserver + * structure as well */ + +typedef struct _drm_i810_tex_region { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} drm_i810_tex_region_t; + +typedef struct _drm_i810_sarea { + unsigned int nbox; + drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS]; + + /* Maintain an LRU of contiguous regions of texture space. If + * you think you own a region of texture memory, and it has an + * age different to the one you set, then you are mistaken and + * it has been stolen by another client. If global texAge + * hasn't changed, there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained + * texture information of other clients - by maintaining them + * in the same lru which is used to age their own textures, + * clients have an approximate lru for the whole of global + * texture space, and can make informed decisions as to which + * areas to kick out. There is no need to choose whether to + * kick out your own texture or someone else's - simply eject + * them all in LRU order. + */ + + drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1]; + /* Last elt is sentinal */ + int texAge; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int last_quiescent; /* */ + int ctxOwner; /* last context to upload state */ +} drm_i810_sarea_t; + +typedef struct _drm_i810_general { + int idx; + int used; +} drm_i810_general_t; + +/* These may be placeholders if we have more cliprects than + * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to + * false, indicating that the buffer will be dispatched again with a + * new set of cliprects. + */ +typedef struct _drm_i810_vertex { + int idx; /* buffer index */ + int used; /* nr bytes in use */ + int discard; /* client is finished with the buffer? */ +} drm_i810_vertex_t; + +#endif /* _I810_DRM_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c index f33153a36..d3b35c493 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c @@ -33,11 +33,13 @@ #define EXPORT_SYMTAB #include "drmP.h" #include "i810_drv.h" + + EXPORT_SYMBOL(i810_init); EXPORT_SYMBOL(i810_cleanup); #define I810_NAME "i810" -#define I810_DESC "Matrox g200/g400" +#define I810_DESC "Intel I810" #define I810_DATE "19991213" #define I810_MAJOR 0 #define I810_MINOR 0 @@ -54,6 +56,7 @@ static struct file_operations i810_fops = { mmap: drm_mmap, read: drm_read, fasync: drm_fasync, + poll: drm_poll, }; static struct miscdevice i810_misc = { @@ -80,13 +83,13 @@ static drm_ioctl_desc_t i810_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { i810_mapbufs, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { i810_freebufs, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { i810_addctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { i810_rmctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { i810_modctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { i810_getctx, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { i810_switchctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { i810_newctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { i810_resctx, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 }, @@ -104,6 +107,11 @@ static drm_ioctl_desc_t i810_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general,1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl,1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, }; #define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls) @@ -121,7 +129,7 @@ MODULE_PARM(i810, "s"); int init_module(void) { - printk("doing i810_init()\n"); + DRM_DEBUG("doing i810_init()\n"); return i810_init(); } @@ -364,7 +372,7 @@ int i810_init(void) #ifdef MODULE drm_parse_options(i810); #endif - printk("doing misc_register\n"); + DRM_DEBUG("doing misc_register\n"); if ((retcode = misc_register(&i810_misc))) { DRM_ERROR("Cannot register \"%s\"\n", I810_NAME); return retcode; @@ -372,13 +380,22 @@ int i810_init(void) dev->device = MKDEV(MISC_MAJOR, i810_misc.minor); dev->name = I810_NAME; - printk("doing mem init\n"); + DRM_DEBUG("doing mem init\n"); drm_mem_init(); - printk("doing proc init\n"); + DRM_DEBUG("doing proc init\n"); drm_proc_init(dev); - printk("doing agp init\n"); + DRM_DEBUG("doing agp init\n"); dev->agp = drm_agp_init(); - printk("doing ctxbitmap init\n"); + if(dev->agp == NULL) { + DRM_INFO("The i810 drm module requires the agpgart module" + " to function correctly\nPlease load the agpgart" + " module before you load the i810 module\n"); + drm_proc_cleanup(); + misc_deregister(&i810_misc); + i810_takedown(dev); + return -ENOMEM; + } + DRM_DEBUG("doing ctxbitmap init\n"); if((retcode = drm_ctxbitmap_init(dev))) { DRM_ERROR("Cannot allocate memory for context bitmap.\n"); drm_proc_cleanup(); @@ -386,10 +403,6 @@ int i810_init(void) i810_takedown(dev); return retcode; } -#if 0 - printk("doing i810_dma_init\n"); - i810_dma_init(dev); -#endif DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", I810_NAME, @@ -417,7 +430,6 @@ void i810_cleanup(void) DRM_INFO("Module unloaded\n"); } drm_ctxbitmap_cleanup(dev); - i810_dma_cleanup(dev); i810_takedown(dev); if (dev->agp) { drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); @@ -484,24 +496,82 @@ int i810_release(struct inode *inode, struct file *filp) drm_device_t *dev = priv->dev; int retcode = 0; - DRM_DEBUG("open_count = %d\n", dev->open_count); - if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; - atomic_inc(&dev->total_close); - spin_lock(&dev->count_lock); - if (!--dev->open_count) { - if (atomic_read(&dev->ioctl_count) || dev->blocked) { - DRM_ERROR("Device busy: %d %d\n", - atomic_read(&dev->ioctl_count), - dev->blocked); - spin_unlock(&dev->count_lock); - return -EBUSY; + DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", + current->pid, dev->device, dev->open_count); + + if (_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) + && dev->lock.pid == current->pid) { + i810_reclaim_buffers(dev, priv->pid); + DRM_ERROR("Process %d dead, freeing lock for context %d\n", + current->pid, + _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); + drm_lock_free(dev, + &dev->lock.hw_lock->lock, + _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); + + /* FIXME: may require heavy-handed reset of + hardware at this point, possibly + processed via a callback to the X + server. */ + } else { + /* The lock is required to reclaim buffers */ + DECLARE_WAITQUEUE(entry, current); + add_wait_queue(&dev->lock.lock_queue, &entry); + for (;;) { + if (!dev->lock.hw_lock) { + /* Device has been unregistered */ + retcode = -EINTR; + break; + } + if (drm_lock_take(&dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + dev->lock.pid = priv->pid; + dev->lock.lock_time = jiffies; + atomic_inc(&dev->total_locks); + break; /* Got lock */ + } + /* Contention */ + atomic_inc(&dev->total_sleeps); + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (signal_pending(current)) { + retcode = -ERESTARTSYS; + break; } - spin_unlock(&dev->count_lock); - return i810_takedown(dev); } - spin_unlock(&dev->count_lock); + current->state = TASK_RUNNING; + remove_wait_queue(&dev->lock.lock_queue, &entry); + if(!retcode) { + i810_reclaim_buffers(dev, priv->pid); + drm_lock_free(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT); + } + } + drm_fasync(-1, filp, 0); + + down(&dev->struct_sem); + if (priv->prev) priv->prev->next = priv->next; + else dev->file_first = priv->next; + if (priv->next) priv->next->prev = priv->prev; + else dev->file_last = priv->prev; + up(&dev->struct_sem); + + drm_free(priv, sizeof(*priv), DRM_MEM_FILES); + MOD_DEC_USE_COUNT; + atomic_inc(&dev->total_close); + spin_lock(&dev->count_lock); + if (!--dev->open_count) { + if (atomic_read(&dev->ioctl_count) || dev->blocked) { + DRM_ERROR("Device busy: %d %d\n", + atomic_read(&dev->ioctl_count), + dev->blocked); + spin_unlock(&dev->count_lock); + return -EBUSY; + } + spin_unlock(&dev->count_lock); + return i810_takedown(dev); } + spin_unlock(&dev->count_lock); return retcode; } @@ -566,8 +636,7 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->total_unlocks); if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock)) atomic_inc(&dev->total_contends); - drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT); - i810_dma_schedule(dev, 1); + drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT); if (!dev->context_flag) { if (drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h index 0f5f42bb6..1badd36b8 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h @@ -32,6 +32,31 @@ #ifndef _I810_DRV_H_ #define _I810_DRV_H_ +typedef struct _drm_i810_ring_buffer{ + int tail_mask; + unsigned long Start; + unsigned long End; + unsigned long Size; + u8 *virtual_start; + int head; + int tail; + int space; +} drm_i810_ring_buffer_t; + +typedef struct drm_i810_private { + int ring_map_idx; + int buffer_map_idx; + + drm_i810_ring_buffer_t ring; + drm_i810_sarea_t *sarea_priv; + + unsigned long hw_status_page; + unsigned long counter; + + atomic_t flush_done; + wait_queue_head_t flush_queue; /* Processes waiting until flush */ +} drm_i810_private_t; + /* i810_drv.c */ extern int i810_init(void); extern void i810_cleanup(void); @@ -54,8 +79,13 @@ extern int i810_control(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern void i810_dma_init(drm_device_t *dev); -extern void i810_dma_cleanup(drm_device_t *dev); +extern int i810_dma_init(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_flush_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern void i810_reclaim_buffers(drm_device_t *dev, pid_t pid); +extern int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg); /* i810_bufs.c */ @@ -72,5 +102,103 @@ extern int i810_mapbufs(struct inode *inode, struct file *filp, extern int i810_addmap(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + /* i810_context.c */ +extern int i810_resctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_addctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_modctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_getctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_switchctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_newctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int i810_rmctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern int i810_context_switch(drm_device_t *dev, int old, int new); +extern int i810_context_switch_complete(drm_device_t *dev, int new); + + + + +/* Copy the outstanding cliprects for every I810_DMA_VERTEX buffer. + * This can be fixed by emitting directly to the ringbuffer in the + * 'vertex_dma' ioctl. +*/ +typedef struct { + u32 *in_use; + int my_use_idx; +} drm_i810_buf_priv_t; + + +#define I810_DMA_GENERAL 0 +#define I810_DMA_VERTEX 1 +#define I810_DMA_DISCARD 2 /* not used */ + +#define I810_VERBOSE 0 + + +int i810_dma_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +int i810_dma_general(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + + +#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) +#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) +#define CMD_REPORT_HEAD (7<<23) +#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) +#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) + +#define INST_PARSER_CLIENT 0x00000000 +#define INST_OP_FLUSH 0x02000000 +#define INST_FLUSH_MAP_CACHE 0x00000001 + + +#define BB1_START_ADDR_MASK (~0x7) +#define BB1_PROTECTED (1<<0) +#define BB1_UNPROTECTED (0<<0) +#define BB2_END_ADDR_MASK (~0x7) + +#define I810REG_HWSTAM 0x02098 +#define I810REG_INT_IDENTITY_R 0x020a4 +#define I810REG_INT_MASK_R 0x020a8 +#define I810REG_INT_ENABLE_R 0x020a0 + +#define LP_RING 0x2030 +#define HP_RING 0x2040 +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define RING_START 0x08 +#define START_ADDR 0x00FFFFF8 +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x000FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + +#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define SC_UPDATE_SCISSOR (0x1<<1) +#define SC_ENABLE_MASK (0x1<<0) +#define SC_ENABLE (0x1<<0) + +#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) +#define SCI_YMIN_MASK (0xffff<<16) +#define SCI_XMIN_MASK (0xffff<<0) +#define SCI_YMAX_MASK (0xffff<<16) +#define SCI_XMAX_MASK (0xffff<<0) #endif + diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c index a8a81abd8..559ac7391 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c @@ -44,21 +44,25 @@ static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED; static unsigned long drm_ram_available = 0; /* In pages */ static unsigned long drm_ram_used = 0; static drm_mem_stats_t drm_mem_stats[] = { - [DRM_MEM_DMA] = { "dmabufs" }, - [DRM_MEM_SAREA] = { "sareas" }, - [DRM_MEM_DRIVER] = { "driver" }, - [DRM_MEM_MAGIC] = { "magic" }, - [DRM_MEM_IOCTLS] = { "ioctltab" }, - [DRM_MEM_MAPS] = { "maplist" }, - [DRM_MEM_VMAS] = { "vmalist" }, - [DRM_MEM_BUFS] = { "buflist" }, - [DRM_MEM_SEGS] = { "seglist" }, - [DRM_MEM_PAGES] = { "pagelist" }, - [DRM_MEM_FILES] = { "files" }, - [DRM_MEM_QUEUES] = { "queues" }, - [DRM_MEM_CMDS] = { "commands" }, - [DRM_MEM_MAPPINGS] = { "mappings" }, - [DRM_MEM_BUFLISTS] = { "buflists" }, + [DRM_MEM_DMA] = { "dmabufs" }, + [DRM_MEM_SAREA] = { "sareas" }, + [DRM_MEM_DRIVER] = { "driver" }, + [DRM_MEM_MAGIC] = { "magic" }, + [DRM_MEM_IOCTLS] = { "ioctltab" }, + [DRM_MEM_MAPS] = { "maplist" }, + [DRM_MEM_VMAS] = { "vmalist" }, + [DRM_MEM_BUFS] = { "buflist" }, + [DRM_MEM_SEGS] = { "seglist" }, + [DRM_MEM_PAGES] = { "pagelist" }, + [DRM_MEM_FILES] = { "files" }, + [DRM_MEM_QUEUES] = { "queues" }, + [DRM_MEM_CMDS] = { "commands" }, + [DRM_MEM_MAPPINGS] = { "mappings" }, + [DRM_MEM_BUFLISTS] = { "buflists" }, + [DRM_MEM_AGPLISTS] = { "agplist" }, + [DRM_MEM_TOTALAGP] = { "totalagp" }, + [DRM_MEM_BOUNDAGP] = { "boundagp" }, + [DRM_MEM_CTXBITMAP] = { "ctxbitmap"}, { NULL, 0, } /* Last entry must be null */ }; @@ -324,3 +328,120 @@ void drm_ioremapfree(void *pt, unsigned long size) free_count, alloc_count); } } + +#ifdef DRM_AGP +agp_memory *drm_alloc_agp(int pages, u32 type) +{ + agp_memory *handle; + + if (!pages) { + DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n"); + return NULL; + } + + if (drm_agp.allocate_memory) { + if ((handle = (*drm_agp.allocate_memory)(pages, + type))) { + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; + drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated + += pages << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + return handle; + } + } + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count; + spin_unlock(&drm_mem_lock); + return NULL; +} + +int drm_free_agp(agp_memory *handle, int pages) +{ + int alloc_count; + int free_count; + int retval = -EINVAL; + + if (!handle) { + DRM_MEM_ERROR(DRM_MEM_TOTALAGP, + "Attempt to free NULL AGP handle\n"); + return retval;; + } + + if (drm_agp.free_memory) { + (*drm_agp.free_memory)(handle); + spin_lock(&drm_mem_lock); + free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count; + alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; + drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed + += pages << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + if (free_count > alloc_count) { + DRM_MEM_ERROR(DRM_MEM_TOTALAGP, + "Excess frees: %d frees, %d allocs\n", + free_count, alloc_count); + } + return 0; + } + return retval; +} + +int drm_bind_agp(agp_memory *handle, unsigned int start) +{ + int retcode = -EINVAL; + + DRM_DEBUG("drm_bind_agp called\n"); + if (!handle) { + DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, + "Attempt to bind NULL AGP handle\n"); + return retcode; + } + + DRM_DEBUG("drm_agp.bind_memory : %p\n", drm_agp.bind_memory); + if (drm_agp.bind_memory) { + if (!(retcode = (*drm_agp.bind_memory)(handle, start))) { + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; + drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated + += handle->page_count << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + DRM_DEBUG("drm_agp.bind_memory: retcode %d\n", retcode); + return retcode; + } + } + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count; + spin_unlock(&drm_mem_lock); + return retcode; +} + +int drm_unbind_agp(agp_memory *handle) +{ + int alloc_count; + int free_count; + int retcode = -EINVAL; + + if (!handle) { + DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, + "Attempt to unbind NULL AGP handle\n"); + return retcode; + } + + if (drm_agp.unbind_memory) { + int c = handle->page_count; + if ((retcode = (*drm_agp.unbind_memory)(handle))) + return retcode; + spin_lock(&drm_mem_lock); + free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count; + alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; + drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed += c << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + if (free_count > alloc_count) { + DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, + "Excess frees: %d frees, %d allocs\n", + free_count, alloc_count); + } + } + return retcode; +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_bufs.c index 34f1112a6..3ce428b27 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_bufs.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_bufs.c @@ -33,169 +33,168 @@ #define __NO_VERSION__ #include "drmP.h" #include "mga_drv.h" -#include "mga_dma.h" #include "linux/un.h" int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_device_dma_t *dma = dev->dma; - drm_buf_desc_t request; - drm_buf_entry_t *entry; - drm_buf_t *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - - if (!dma) return -EINVAL; - - copy_from_user_ret(&request, - (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); - - count = request.count; - order = drm_order(request.size); - size = 1 << order; - agp_offset = request.agp_start; - alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - byte_count = 0; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %d\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - DRM_DEBUG("byte_count: %d\n", byte_count); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; - if (dev->queue_count) return -EBUSY; /* Not while in use */ - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + drm_buf_desc_t request; + drm_buf_entry_t *entry; + drm_buf_t *buf; + unsigned long offset; + unsigned long agp_offset; + int count; + int order; + int size; + int alignment; + int page_order; + int total; + int byte_count; + int i; + + if (!dma) return -EINVAL; + + copy_from_user_ret(&request, + (drm_buf_desc_t *)arg, + sizeof(request), + -EFAULT); + + count = request.count; + order = drm_order(request.size); + size = 1 << order; + agp_offset = request.agp_start; + alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size; + page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; + total = PAGE_SIZE << page_order; + byte_count = 0; + + DRM_DEBUG("count: %d\n", count); + DRM_DEBUG("order: %d\n", order); + DRM_DEBUG("size: %d\n", size); + DRM_DEBUG("agp_offset: %ld\n", agp_offset); + DRM_DEBUG("alignment: %d\n", alignment); + DRM_DEBUG("page_order: %d\n", page_order); + DRM_DEBUG("total: %d\n", total); + DRM_DEBUG("byte_count: %d\n", byte_count); + + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; + if (dev->queue_count) return -EBUSY; /* Not while in use */ + spin_lock(&dev->count_lock); + if (dev->buf_use) { + spin_unlock(&dev->count_lock); + return -EBUSY; + } + atomic_inc(&dev->buf_alloc); + spin_unlock(&dev->count_lock); - down(&dev->struct_sem); - entry = &dma->bufs[order]; - if (entry->buf_count) { - up(&dev->struct_sem); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } + down(&dev->struct_sem); + entry = &dma->bufs[order]; + if (entry->buf_count) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; /* May only call once for each order */ + } - entry->buflist = drm_alloc(count * sizeof(*entry->buflist), - DRM_MEM_BUFS); - if (!entry->buflist) { - up(&dev->struct_sem); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->buflist, 0, count * sizeof(*entry->buflist)); + entry->buflist = drm_alloc(count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (!entry->buflist) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; + } + memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - entry->buf_size = size; - entry->page_order = page_order; - offset = 0; + entry->buf_size = size; + entry->page_order = page_order; + offset = 0; - while(entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - DRM_DEBUG("offset : %d\n", offset); - - buf->offset = offset; /* Hrm */ - buf->bus_address = dev->agp->base + agp_offset + offset; - buf->address = (void *)(agp_offset + offset + dev->agp->base); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->pid = 0; - - buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t), DRM_MEM_BUFS); - buf->dev_priv_size = sizeof(drm_mga_buf_priv_t); + while(entry->buf_count < count) { + buf = &entry->buflist[entry->buf_count]; + buf->idx = dma->buf_count + entry->buf_count; + buf->total = alignment; + buf->order = order; + buf->used = 0; + + DRM_DEBUG("offset : %ld\n", offset); + + buf->offset = offset; /* Hrm */ + buf->bus_address = dev->agp->base + agp_offset + offset; + buf->address = (void *)(agp_offset + offset + dev->agp->base); + buf->next = NULL; + buf->waiting = 0; + buf->pending = 0; + init_waitqueue_head(&buf->dma_wait); + buf->pid = 0; + + buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t), DRM_MEM_BUFS); + buf->dev_priv_size = sizeof(drm_mga_buf_priv_t); #if DRM_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; + buf->time_queued = 0; + buf->time_dispatched = 0; + buf->time_completed = 0; + buf->time_freed = 0; #endif - offset = offset + alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; + offset = offset + alignment; + entry->buf_count++; + byte_count += PAGE_SIZE << page_order; - DRM_DEBUG("buffer %d @ %p\n", - entry->buf_count, buf->address); - } + DRM_DEBUG("buffer %d @ %p\n", + entry->buf_count, buf->address); + } - dma->buflist = drm_realloc(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), - DRM_MEM_BUFS); - for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) - dma->buflist[i] = &entry->buflist[i - dma->buf_count]; + dma->buflist = drm_realloc(dma->buflist, + dma->buf_count * sizeof(*dma->buflist), + (dma->buf_count + entry->buf_count) + * sizeof(*dma->buflist), + DRM_MEM_BUFS); + for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) + dma->buflist[i] = &entry->buflist[i - dma->buf_count]; - dma->buf_count += entry->buf_count; + dma->buf_count += entry->buf_count; - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); + DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - dma->byte_count += byte_count; + dma->byte_count += byte_count; - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); + DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - drm_freelist_create(&entry->freelist, entry->buf_count); - for (i = 0; i < entry->buf_count; i++) { - drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]); - } + drm_freelist_create(&entry->freelist, entry->buf_count); + for (i = 0; i < entry->buf_count; i++) { + drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]); + } - up(&dev->struct_sem); + up(&dev->struct_sem); - request.count = entry->buf_count; - request.size = size; + request.count = entry->buf_count; + request.size = size; - copy_to_user_ret((drm_buf_desc_t *)arg, - &request, - sizeof(request), - -EFAULT); + copy_to_user_ret((drm_buf_desc_t *)arg, + &request, + sizeof(request), + -EFAULT); - atomic_dec(&dev->buf_alloc); + atomic_dec(&dev->buf_alloc); - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %d\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - DRM_DEBUG("byte_count: %d\n", byte_count); + DRM_DEBUG("count: %d\n", count); + DRM_DEBUG("order: %d\n", order); + DRM_DEBUG("size: %d\n", size); + DRM_DEBUG("agp_offset: %ld\n", agp_offset); + DRM_DEBUG("alignment: %d\n", alignment); + DRM_DEBUG("page_order: %d\n", page_order); + DRM_DEBUG("total: %d\n", total); + DRM_DEBUG("byte_count: %d\n", byte_count); - dma->flags = _DRM_DMA_USE_AGP; + dma->flags = _DRM_DMA_USE_AGP; - DRM_DEBUG("dma->flags : %lx\n", dma->flags); + DRM_DEBUG("dma->flags : %x\n", dma->flags); - return 0; + return 0; } int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, @@ -362,17 +361,17 @@ int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, int mga_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - drm_buf_desc_t request; + drm_buf_desc_t request; - copy_from_user_ret(&request, - (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + copy_from_user_ret(&request, + (drm_buf_desc_t *)arg, + sizeof(request), + -EFAULT); - if(request.flags & _DRM_AGP_BUFFER) - return mga_addbufs_agp(inode, filp, cmd, arg); - else - return mga_addbufs_pci(inode, filp, cmd, arg); + if(request.flags & _DRM_AGP_BUFFER) + return mga_addbufs_agp(inode, filp, cmd, arg); + else + return mga_addbufs_pci(inode, filp, cmd, arg); } int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, @@ -546,7 +545,7 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, spin_lock(&dev->count_lock); if (atomic_read(&dev->buf_alloc)) { spin_unlock(&dev->count_lock); - DRM_DEBUG("Buzy\n"); + DRM_DEBUG("Busy\n"); return -EBUSY; } ++dev->buf_use; /* Can't allocate more after this call */ @@ -558,79 +557,84 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, -EFAULT); DRM_DEBUG("mga_mapbufs\n"); - DRM_DEBUG("dma->flags : %lx\n", dma->flags); + DRM_DEBUG("dma->flags : %x\n", dma->flags); - if (request.count >= dma->buf_count) { - if(dma->flags & _DRM_DMA_USE_AGP) { - drm_mga_private_t *dev_priv = dev->dev_private; - drm_map_t *map = NULL; + if (request.count >= dma->buf_count) { + if(dma->flags & _DRM_DMA_USE_AGP) { + drm_mga_private_t *dev_priv = dev->dev_private; + drm_map_t *map = NULL; - map = dev->maplist[dev_priv->buffer_map_idx]; - if (!map) { - DRM_DEBUG("map is null\n"); - retcode = -EINVAL; - goto done; - } - - DRM_DEBUG("map->offset : %lx\n", map->offset); - DRM_DEBUG("map->size : %lx\n", map->size); - DRM_DEBUG("map->type : %d\n", map->type); - DRM_DEBUG("map->flags : %x\n", map->flags); - DRM_DEBUG("map->handle : %lx\n", map->handle); - DRM_DEBUG("map->mtrr : %d\n", map->mtrr); - - virtual = do_mmap(filp, 0, map->size, PROT_READ|PROT_WRITE, - MAP_SHARED, (unsigned long)map->offset); - } else { - virtual = do_mmap(filp, 0, dma->byte_count, - PROT_READ|PROT_WRITE, MAP_SHARED, 0); - } - if (virtual > -1024UL) { - /* Real error */ - DRM_DEBUG("mmap error\n"); - retcode = (signed long)virtual; - goto done; - } - request.virtual = (void *)virtual; + map = dev->maplist[dev_priv->buffer_map_idx]; + if (!map) { + DRM_DEBUG("map is null\n"); + retcode = -EINVAL; + goto done; + } + + DRM_DEBUG("map->offset : %lx\n", map->offset); + DRM_DEBUG("map->size : %lx\n", map->size); + DRM_DEBUG("map->type : %d\n", map->type); + DRM_DEBUG("map->flags : %x\n", map->flags); + DRM_DEBUG("map->handle : %p\n", map->handle); + DRM_DEBUG("map->mtrr : %d\n", map->mtrr); + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, map->size, + PROT_READ|PROT_WRITE, + MAP_SHARED, + (unsigned long)map->offset); + up(¤t->mm->mmap_sem); + } else { + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, dma->byte_count, + PROT_READ|PROT_WRITE, MAP_SHARED, 0); + up(¤t->mm->mmap_sem); + } + if (virtual > -1024UL) { + /* Real error */ + DRM_DEBUG("mmap error\n"); + retcode = (signed long)virtual; + goto done; + } + request.virtual = (void *)virtual; - for (i = 0; i < dma->buf_count; i++) { - if (copy_to_user(&request.list[i].idx, - &dma->buflist[i]->idx, - sizeof(request.list[0].idx))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request.list[i].total, - &dma->buflist[i]->total, - sizeof(request.list[0].total))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request.list[i].used, - &zero, - sizeof(zero))) { - retcode = -EFAULT; - goto done; - } - address = virtual + dma->buflist[i]->offset; - if (copy_to_user(&request.list[i].address, - &address, - sizeof(address))) { - retcode = -EFAULT; - goto done; - } - } - } - done: - request.count = dma->buf_count; - DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); + for (i = 0; i < dma->buf_count; i++) { + if (copy_to_user(&request.list[i].idx, + &dma->buflist[i]->idx, + sizeof(request.list[0].idx))) { + retcode = -EFAULT; + goto done; + } + if (copy_to_user(&request.list[i].total, + &dma->buflist[i]->total, + sizeof(request.list[0].total))) { + retcode = -EFAULT; + goto done; + } + if (copy_to_user(&request.list[i].used, + &zero, + sizeof(zero))) { + retcode = -EFAULT; + goto done; + } + address = virtual + dma->buflist[i]->offset; + if (copy_to_user(&request.list[i].address, + &address, + sizeof(address))) { + retcode = -EFAULT; + goto done; + } + } + } + done: + request.count = dma->buf_count; + DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - copy_to_user_ret((drm_buf_map_t *)arg, - &request, - sizeof(request), - -EFAULT); + copy_to_user_ret((drm_buf_map_t *)arg, + &request, + sizeof(request), + -EFAULT); - DRM_DEBUG("retcode : %d\n", retcode); + DRM_DEBUG("retcode : %d\n", retcode); - return retcode; + return retcode; } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_clear.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_clear.c deleted file mode 100644 index 05895415e..000000000 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_clear.c +++ /dev/null @@ -1,417 +0,0 @@ -/* mga_state.c -- State support for mga g200/g400 -*- linux-c -*- - * - * Created: February 2000 by keithw@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, 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 - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell <keithw@precisioninsight.com> - * - */ - -#define __NO_VERSION__ -#include "drmP.h" -#include "mga_drv.h" -#include "mgareg_flags.h" -#include "mga_dma.h" -#include "mga_state.h" - -#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \ - DC_sgnzero_enable | DC_shftzero_enable | \ - (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \ - DC_solid_enable | DC_transc_enable) - - -#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \ - DC_solid_disable | DC_arzero_disable | \ - DC_sgnzero_enable | DC_shftzero_enable | \ - (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol | \ - DC_pattern_disable | DC_transc_disable | \ - DC_clipdis_enable) \ - - - -/* Build and queue a TT_GENERAL secondary buffer to do the clears. - * With Jeff's ringbuffer idea, it might make sense if there are only - * one or two cliprects to emit straight to the primary buffer. - */ -static int mgaClearBuffers(drm_device_t *dev, - int clear_color, - int clear_depth, - int flags) -{ - int cmd, i; - drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - xf86drmClipRectRec *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - drm_buf_t *buf; - drm_dma_t d; - int order = 10; /* ??? what orders do we have ???*/ - DMALOCALS; - - - if (!nbox) - return -EINVAL; - - if ( dev_priv->sgram ) - cmd = MGA_CLEAR_CMD | DC_atype_blk; - else - cmd = MGA_CLEAR_CMD | DC_atype_rstr; - - buf = drm_freelist_get(&dma->bufs[order].freelist, _DRM_DMA_WAIT); - - - DMAGETPTR( buf ); - - for (i = 0 ; i < nbox ; i++) { - unsigned int height = pbox[i].y2 - pbox[i].y1; - - /* Is it necessary to be this paranoid? I don't think so. - if (pbox[i].x1 > dev_priv->width) continue; - if (pbox[i].y1 > dev_priv->height) continue; - if (pbox[i].x2 > dev_priv->width) continue; - if (pbox[i].y2 > dev_priv->height) continue; - if (pbox[i].x2 <= pbox[i].x1) continue; - if (pbox[i].y2 <= pbox[i].x1) continue; - */ - - DMAOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); - DMAOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); - - if ( flags & MGA_CLEAR_FRONT ) { - DMAOUTREG(MGAREG_FCOL, clear_color); - DMAOUTREG(MGAREG_DSTORG, dev_priv->frontOrg); - DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); - } - - if ( flags & MGA_CLEAR_BACK ) { - DMAOUTREG(MGAREG_FCOL, clear_color); - DMAOUTREG(MGAREG_DSTORG, dev_priv->backOrg); - DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); - } - - if ( flags & MGA_CLEAR_DEPTH ) - { - DMAOUTREG(MGAREG_FCOL, clear_depth); - DMAOUTREG(MGAREG_DSTORG, dev_priv->depthOrg); - DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); - } - } - - DMAADVANCE( buf ); - - /* Make sure we restore the 3D state next time. - */ - sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; - - ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL; - - d.context = DRM_KERNEL_CONTEXT; - d.send_count = 1; - d.send_indices = &buf->idx; - d.send_sizes = &buf->used; - d.flags = 0; - d.request_count = 0; - d.request_size = 0; - d.request_indices = NULL; - d.request_sizes = NULL; - d.granted_count = 0; - - atomic_inc(&dev_priv->pending_bufs); - if((drm_dma_enqueue(dev, &d)) != 0) - atomic_dec(&dev_priv->pending_bufs); - mga_dma_schedule(dev, 1); - return 0; -} - -int mgaSwapBuffers(drm_device_t *dev, int flags) -{ - drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - xf86drmClipRectRec *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - drm_buf_t *buf; - drm_dma_t d; - int order = 10; /* ??? */ - int i; - DMALOCALS; - - if (!nbox) - return -EINVAL; - - buf = drm_freelist_get(&dma->bufs[order].freelist, _DRM_DMA_WAIT); - - DMAGETPTR(buf); - - DMAOUTREG(MGAREG_DSTORG, dev_priv->frontOrg); - DMAOUTREG(MGAREG_MACCESS, dev_priv->mAccess); - DMAOUTREG(MGAREG_SRCORG, dev_priv->backOrg); - DMAOUTREG(MGAREG_AR5, dev_priv->stride); /* unnecessary? */ - DMAOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD); - - for (i = 0 ; i < nbox; i++) { - unsigned int h = pbox[i].y2 - pbox[i].y1; - unsigned int start = pbox[i].y1 * dev_priv->stride; - - /* - if (pbox[i].x1 > dev_priv->width) continue; - if (pbox[i].y1 > dev_priv->height) continue; - if (pbox[i].x2 > dev_priv->width) continue; - if (pbox[i].y2 > dev_priv->height) continue; - if (pbox[i].x2 <= pbox[i].x1) continue; - if (pbox[i].y2 <= pbox[i].x1) continue; - */ - - DMAOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1); - DMAOUTREG(MGAREG_AR3, start + pbox[i].x1); - DMAOUTREG(MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16)); - DMAOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h); - } - - DMAOUTREG(MGAREG_SRCORG, 0); - DMAADVANCE( buf ); - - /* Make sure we restore the 3D state next time. - */ - sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; - - ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL; - - d.context = DRM_KERNEL_CONTEXT; - d.send_count = 1; - d.send_indices = &buf->idx; - d.send_sizes = &buf->used; - d.flags = 0; - d.request_count = 0; - d.request_size = 0; - d.request_indices = NULL; - d.request_sizes = NULL; - d.granted_count = 0; - - atomic_inc(&dev_priv->pending_bufs); - if((drm_dma_enqueue(dev, &d)) != 0) - atomic_dec(&dev_priv->pending_bufs); - mga_dma_schedule(dev, 1); - return 0; -} - - -static int mgaIload(drm_device_t *dev, drm_mga_iload_t *args) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf = dma->buflist[ args->idx ]; - drm_mga_buf_priv_t *buf_priv = (drm_mga_buf_priv_t *)buf->dev_private; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_dma_t d; - int pixperdword; - - buf_priv->dma_type = MGA_DMA_ILOAD; - buf_priv->boxes[0].y1 = args->texture.y1; - buf_priv->boxes[0].y2 = args->texture.y2; - buf_priv->boxes[0].x1 = args->texture.x1; - buf_priv->boxes[0].x2 = args->texture.x2; - buf_priv->ContextState[MGA_CTXREG_DSTORG] = args->destOrg; - buf_priv->ContextState[MGA_CTXREG_MACCESS] = args->mAccess; - buf_priv->ServerState[MGA_2DREG_PITCH] = args->pitch; - buf_priv->nbox = 1; - sarea_priv->dirty |= (MGASAREA_NEW_CONTEXT | MGASAREA_NEW_2D); - switch((args->mAccess & 0x00000003)) { - case 0: - pixperdword = 4; - break; - case 1: - pixperdword = 2; - break; - case 2: - pixperdword = 1; - break; - default: - DRM_ERROR("Invalid maccess value passed" - " to mgaIload\n"); - return -EINVAL; - } - buf->used = ((args->texture.y2 - args->texture.y1) * - (args->texture.x2 - args->texture.x1) / - pixperdword); - DRM_DEBUG("buf->used : %d\n", buf->used); - d.context = DRM_KERNEL_CONTEXT; - d.send_count = 1; - d.send_indices = &buf->idx; - d.send_sizes = &buf->used; - d.flags = 0; - d.request_count = 0; - d.request_size = 0; - d.request_indices = NULL; - d.request_sizes = NULL; - d.granted_count = 0; - - atomic_inc(&dev_priv->pending_bufs); - if((drm_dma_enqueue(dev, &d)) != 0) - atomic_dec(&dev_priv->pending_bufs); - mga_dma_schedule(dev, 1); - - return 0; -} - - -/* Necessary? Not necessary?? - */ -static int check_lock(void) -{ - return 1; -} - -int mga_clear_bufs(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_mga_clear_t clear; - int retcode; - - copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, - sizeof(clear), -EFAULT); - -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - - retcode = mgaClearBuffers(dev, clear.clear_color, - clear.clear_depth, - clear.flags); - - return retcode; -} - -int mga_swap_bufs(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_mga_swap_t swap; - int retcode = 0; - -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - - copy_from_user_ret(&swap, (drm_mga_swap_t *)arg, - sizeof(swap), -EFAULT); - - retcode = mgaSwapBuffers(dev, swap.flags); - - return retcode; -} - -int mga_iload(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_mga_iload_t iload; - int retcode = 0; - -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - - copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, - sizeof(iload), -EFAULT); - - retcode = mgaIload(dev, &iload); - - return retcode; -} - - -int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_device_dma_t *dma = dev->dma; - int retcode = 0; - drm_dma_t d; - - copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); - DRM_DEBUG("%d %d: %d send, %d req\n", - current->pid, d.context, d.send_count, d.request_count); - - /* Per-context queues are unworkable if you are trying to do - * state management from the client. - */ - d.context = DRM_KERNEL_CONTEXT; - d.flags &= ~_DRM_DMA_WHILE_LOCKED; - - /* Maybe multiple buffers is useful for iload... - * But this ioctl is only for *despatching* vertex data... - */ - if (d.send_count < 0 || d.send_count > 1) { - DRM_ERROR("Process %d trying to send %d buffers (max 1)\n", - current->pid, d.send_count); - return -EINVAL; - } - - - /* But it *is* used to request buffers for all types of dma: - */ - if (d.request_count < 0 || d.request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - current->pid, d.request_count, dma->buf_count); - return -EINVAL; - } - - if (d.send_count) { - int idx = d.send_indices[0]; - drm_mga_buf_priv_t *buf_priv = dma->buflist[ idx ]->dev_private; - drm_mga_private_t *dev_priv = dev->dev_private; - - buf_priv->dma_type = MGA_DMA_VERTEX; - -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - - /* Snapshot the relevent bits of the sarea... - */ - mgaCopyAndVerifyState( dev_priv, buf_priv ); - - atomic_inc(&dev_priv->pending_bufs); - retcode = drm_dma_enqueue(dev, &d); - if(retcode != 0) - atomic_dec(&dev_priv->pending_bufs); - mga_dma_schedule(dev, 1); - } - - d.granted_count = 0; - - if (!retcode && d.request_count) { - retcode = drm_dma_get_buffers(dev, &d); - } - - DRM_DEBUG("%d returning, granted = %d\n", - current->pid, d.granted_count); - copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT); - - return retcode; -} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_context.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_context.c index fb0d336fa..2459b35bb 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_context.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_context.c @@ -38,7 +38,7 @@ static int mga_alloc_queue(drm_device_t *dev) { int temp = drm_ctxbitmap_next(dev); - printk("mga_alloc_queue: %d\n", temp); + DRM_DEBUG("mga_alloc_queue: %d\n", temp); return temp; } @@ -57,7 +57,7 @@ int mga_context_switch(drm_device_t *dev, int old, int new) dev->ctx_start = get_cycles(); #endif - printk("Context switch from %d to %d\n", old, new); + DRM_DEBUG("Context switch from %d to %d\n", old, new); if (new == dev->last_context) { clear_bit(0, &dev->context_flag); @@ -104,7 +104,7 @@ int mga_resctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_ctx_t ctx; int i; - printk("%d\n", DRM_RESERVED_CONTEXTS); + DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT); if (res.count >= DRM_RESERVED_CONTEXTS) { memset(&ctx, 0, sizeof(ctx)); @@ -134,11 +134,11 @@ int mga_addctx(struct inode *inode, struct file *filp, unsigned int cmd, ctx.handle = mga_alloc_queue(dev); } if (ctx.handle == -1) { - printk("Not enough free contexts.\n"); + DRM_DEBUG("Not enough free contexts.\n"); /* Should this return -EBUSY instead? */ return -ENOMEM; } - printk("%d\n", ctx.handle); + DRM_DEBUG("%d\n", ctx.handle); copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT); return 0; } @@ -170,7 +170,7 @@ int mga_switchctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_ctx_t ctx; copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); - printk("%d\n", ctx.handle); + DRM_DEBUG("%d\n", ctx.handle); return mga_context_switch(dev, dev->last_context, ctx.handle); } @@ -182,7 +182,7 @@ int mga_newctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_ctx_t ctx; copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); - printk("%d\n", ctx.handle); + DRM_DEBUG("%d\n", ctx.handle); mga_context_switch_complete(dev, ctx.handle); return 0; @@ -194,51 +194,11 @@ int mga_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_ctx_t ctx; - drm_queue_t *q; - drm_buf_t *buf; copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); - printk("%d\n", ctx.handle); - if(ctx.handle == DRM_KERNEL_CONTEXT) { - q = dev->queuelist[ctx.handle]; - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - atomic_inc(&q->finalization); /* Mark queue in finalization state */ - atomic_sub(2, &q->use_count); - /* Mark queue as unused (pending finalization) */ - - while (test_and_set_bit(0, &dev->interrupt_flag)) { - printk("Calling schedule from rmctx\n"); - schedule(); - if (signal_pending(current)) { - clear_bit(0, &dev->interrupt_flag); - return -EINTR; - } - } - - /* Remove queued buffers */ - while ((buf = drm_waitlist_get(&q->waitlist))) { - drm_free_buffer(dev, buf); - } - clear_bit(0, &dev->interrupt_flag); - - /* Wakeup blocked processes */ - wake_up_interruptible(&q->read_queue); - wake_up_interruptible(&q->write_queue); - wake_up_interruptible(&q->flush_queue); - - /* Finalization over. Queue is made - available when both use_count and - finalization become 0, which won't - happen until all the waiting processes - stop waiting. */ - atomic_dec(&q->finalization); - } else { - drm_ctxbitmap_free(dev, ctx.handle); + DRM_DEBUG("%d\n", ctx.handle); + if(ctx.handle != DRM_KERNEL_CONTEXT) { + drm_ctxbitmap_free(dev, ctx.handle); } return 0; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c index 2e24e5b48..59cbad6b4 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c @@ -25,17 +25,15 @@ * * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> * Jeff Hartmann <jhartmann@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c,v 1.1 2000/02/11 17:26:07 dawes Exp $ + * $XFree86$ * */ #define __NO_VERSION__ #include "drmP.h" #include "mga_drv.h" -#include "mgareg_flags.h" -#include "mga_dma.h" -#include "mga_state.h" #include <linux/interrupt.h> /* For task queue support */ @@ -48,643 +46,599 @@ #define MGA_WRITE(reg,val) do { MGA_DEREF(reg) = val; } while (0) #define PDEA_pagpxfer_enable 0x2 -#define MGA_SYNC_TAG 0x423f4200 -typedef enum { - TT_GENERAL, - TT_BLIT, - TT_VECTOR, - TT_VERTEX -} transferType_t; +static int mga_flush_queue(drm_device_t *dev); +static unsigned long mga_alloc_page(drm_device_t *dev) +{ + unsigned long address; + + address = __get_free_page(GFP_KERNEL); + if(address == 0UL) { + return 0; + } + atomic_inc(&mem_map[MAP_NR((void *) address)].count); + set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags); + + return address; +} + +static void mga_free_page(drm_device_t *dev, unsigned long page) +{ + if(page == 0UL) { + return; + } + atomic_dec(&mem_map[MAP_NR((void *) page)].count); + clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags); + wake_up(&mem_map[MAP_NR((void *) page)].wait); + free_page(page); + return; +} static void mga_delay(void) { return; } -int mga_dma_cleanup(drm_device_t *dev) +static void mga_flush_write_combine(void) { - if(dev->dev_private) { - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; - - if(dev_priv->ioremap) { - int temp = (dev_priv->warp_ucode_size + - dev_priv->primary_size + - PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; - - drm_ioremapfree((void *) dev_priv->ioremap, temp); - } - - drm_free(dev->dev_private, sizeof(drm_mga_private_t), - DRM_MEM_DRIVER); - dev->dev_private = NULL; - } - - return 0; + int xchangeDummy; + __asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy)); + __asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;" + " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" + " pop %%eax" : /* no outputs */ : /* no inputs */ ); } -static int mga_alloc_kernel_queue(drm_device_t *dev) +/* These are two age tags that will never be sent to + * the hardware */ +#define MGA_BUF_USED 0xffffffff +#define MGA_BUF_FREE 0 + +static void mga_freelist_debug(drm_mga_freelist_t *item) { - drm_queue_t *queue = NULL; - /* Allocate a new queue */ - down(&dev->struct_sem); - - if(dev->queue_count != 0) { - /* Reseting the kernel context here is not - * a race, since it can only happen when that - * queue is empty. - */ - queue = dev->queuelist[DRM_KERNEL_CONTEXT]; - printk("Kernel queue already allocated\n"); + if(item->buf != NULL) { + DRM_DEBUG("buf index : %d\n", item->buf->idx); } else { - queue = drm_alloc(sizeof(*queue), DRM_MEM_QUEUES); - if(!queue) { - up(&dev->struct_sem); - printk("out of memory\n"); - return -ENOMEM; - } - ++dev->queue_count; - dev->queuelist = drm_alloc(sizeof(*dev->queuelist), - DRM_MEM_QUEUES); - if(!dev->queuelist) { - up(&dev->struct_sem); - drm_free(queue, sizeof(*queue), DRM_MEM_QUEUES); - printk("out of memory\n"); - return -ENOMEM; - } + DRM_DEBUG("Freelist head\n"); } - - memset(queue, 0, sizeof(*queue)); - atomic_set(&queue->use_count, 1); - atomic_set(&queue->finalization, 0); - atomic_set(&queue->block_count, 0); - atomic_set(&queue->block_read, 0); - atomic_set(&queue->block_write, 0); - atomic_set(&queue->total_queued, 0); - atomic_set(&queue->total_flushed, 0); - atomic_set(&queue->total_locks, 0); - - init_waitqueue_head(&queue->write_queue); - init_waitqueue_head(&queue->read_queue); - init_waitqueue_head(&queue->flush_queue); - - queue->flags = 0; - - drm_waitlist_create(&queue->waitlist, dev->dma->buf_count); - - dev->queue_slots = 1; - dev->queuelist[DRM_KERNEL_CONTEXT] = queue; - dev->queue_count--; - - up(&dev->struct_sem); - printk("%d (new)\n", dev->queue_count - 1); - return DRM_KERNEL_CONTEXT; + DRM_DEBUG("item->age : %x\n", item->age); + DRM_DEBUG("item->next : %p\n", item->next); + DRM_DEBUG("item->prev : %p\n", item->prev); } -static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { - drm_mga_private_t *dev_priv; - drm_map_t *prim_map = NULL; - drm_map_t *sarea_map = NULL; - int temp; - - - dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); - if(dev_priv == NULL) return -ENOMEM; - dev->dev_private = (void *) dev_priv; - - printk("dev_private\n"); - - memset(dev_priv, 0, sizeof(drm_mga_private_t)); - atomic_set(&dev_priv->pending_bufs, 0); - - if((init->reserved_map_idx >= dev->map_count) || - (init->buffer_map_idx >= dev->map_count)) { - mga_dma_cleanup(dev); - printk("reserved_map or buffer_map are invalid\n"); - return -EINVAL; - } +static int mga_freelist_init(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_mga_buf_priv_t *buf_priv; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_freelist_t *item; + int i; + + dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); + if(dev_priv->head == NULL) return -ENOMEM; + memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t)); + dev_priv->head->age = MGA_BUF_USED; - if(mga_alloc_kernel_queue(dev) != DRM_KERNEL_CONTEXT) { - mga_dma_cleanup(dev); - DRM_ERROR("Kernel context queue not present\n"); + for (i = 0; i < dma->buf_count; i++) { + buf = dma->buflist[ i ]; + buf_priv = buf->dev_private; + item = drm_alloc(sizeof(drm_mga_freelist_t), + DRM_MEM_DRIVER); + if(item == NULL) return -ENOMEM; + memset(item, 0, sizeof(drm_mga_freelist_t)); + item->age = MGA_BUF_FREE; + item->prev = dev_priv->head; + item->next = dev_priv->head->next; + if(dev_priv->head->next != NULL) + dev_priv->head->next->prev = item; + if(item->next == NULL) dev_priv->tail = item; + item->buf = buf; + buf_priv->my_freelist = item; + buf_priv->discard = 0; + dev_priv->head->next = item; } - - dev_priv->reserved_map_idx = init->reserved_map_idx; - dev_priv->buffer_map_idx = init->buffer_map_idx; - sarea_map = dev->maplist[0]; - dev_priv->sarea_priv = (drm_mga_sarea_t *) - ((u8 *)sarea_map->handle + - init->sarea_priv_offset); - printk("sarea_priv\n"); - - /* Scale primary size to the next page */ - dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) / - PAGE_SIZE) * PAGE_SIZE; - dev_priv->warp_ucode_size = init->warp_ucode_size; - dev_priv->chipset = init->chipset; - dev_priv->fbOffset = init->fbOffset; - dev_priv->backOffset = init->backOffset; - dev_priv->depthOffset = init->depthOffset; - dev_priv->textureOffset = init->textureOffset; - dev_priv->textureSize = init->textureSize; - dev_priv->cpp = init->cpp; - dev_priv->sgram = init->sgram; - dev_priv->stride = init->stride; - - dev_priv->frontOrg = init->frontOrg; - dev_priv->backOrg = init->backOrg; - dev_priv->depthOrg = init->depthOrg; - dev_priv->mAccess = init->mAccess; - - printk("memcpy\n"); - memcpy(&dev_priv->WarpIndex, &init->WarpIndex, - sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES); - printk("memcpy done\n"); - prim_map = dev->maplist[init->reserved_map_idx]; - dev_priv->prim_phys_head = dev->agp->base + init->reserved_map_agpstart; - temp = init->warp_ucode_size + dev_priv->primary_size; - temp = ((temp + PAGE_SIZE - 1) / - PAGE_SIZE) * PAGE_SIZE; - printk("temp : %x\n", temp); - printk("dev->agp->base: %lx\n", dev->agp->base); - printk("init->reserved_map_agpstart: %x\n", init->reserved_map_agpstart); - - - dev_priv->ioremap = drm_ioremap(dev->agp->base + init->reserved_map_agpstart, - temp); - if(dev_priv->ioremap == NULL) { - printk("Ioremap failed\n"); - mga_dma_cleanup(dev); - return -ENOMEM; + item = dev_priv->head; + while(item) { + mga_freelist_debug(item); + item = item->next; } - - - - dev_priv->prim_head = (u32 *)dev_priv->ioremap; - printk("dev_priv->prim_head : %p\n", dev_priv->prim_head); - dev_priv->current_dma_ptr = dev_priv->prim_head; - dev_priv->prim_num_dwords = 0; - dev_priv->prim_max_dwords = dev_priv->primary_size / 4; + DRM_DEBUG("Head\n"); + mga_freelist_debug(dev_priv->head); + DRM_DEBUG("Tail\n"); + mga_freelist_debug(dev_priv->tail); - printk("dma initialization\n"); - - /* Private is now filled in, initialize the hardware */ - { - PRIMLOCALS; - PRIMRESET( dev_priv ); - PRIMGETPTR( dev_priv ); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0); - PRIMOUTREG(MGAREG_SOFTRAP, 0); - PRIMADVANCE( dev_priv ); + return 0; +} - /* Poll for the first buffer to insure that - * the status register will be correct - */ - printk("phys_head : %lx\n", phys_head); +static void mga_freelist_cleanup(drm_device_t *dev) +{ + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_freelist_t *item; + drm_mga_freelist_t *prev; + + item = dev_priv->head; + while(item) { + prev = item; + item = item->next; + drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); + } - MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); + dev_priv->head = dev_priv->tail = NULL; +} - while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) { - int i; - for(i = 0 ; i < 4096; i++) mga_delay(); +/* Frees dispatch lock */ +static inline void mga_dma_quiescent(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + unsigned long end; + int i; + + end = jiffies + (HZ*3); + while(1) { + if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) { + break; } - - MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); - - MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) | - PDEA_pagpxfer_enable)); - - while(MGA_READ(MGAREG_DWGSYNC) == MGA_SYNC_TAG) { - int i; - for(i = 0; i < 4096; i++) mga_delay(); + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), + atomic_read(&dma->total_lost)); + DRM_ERROR("lockup\n"); + goto out_nolock; } - + for (i = 0 ; i < 2000 ; i++) mga_delay(); } - - printk("dma init was successful\n"); - return 0; + end = jiffies + (HZ*3); + DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS)); + while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) { + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), + atomic_read(&dma->total_lost)); + DRM_ERROR("lockup\n"); + goto out_status; + } + for (i = 0 ; i < 2000 ; i++) mga_delay(); + } + DRM_DEBUG("status[1] : %x last_sync_tag : %x\n", status[1], + dev_priv->last_sync_tag); + sarea_priv->dirty |= MGA_DMA_FLUSH; + +out_status: + clear_bit(0, &dev_priv->dispatch_lock); +out_nolock: } -int mga_dma_init(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +#define FREELIST_INITIAL (MGA_DMA_BUF_NR * 2) +#define FREELIST_COMPARE(age) ((age >> 2)) + +unsigned int mga_create_sync_tag(drm_device_t *dev) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_mga_init_t init; + drm_mga_private_t *dev_priv = + (drm_mga_private_t *) dev->dev_private; + unsigned int temp; + drm_buf_t *buf; + drm_mga_buf_priv_t *buf_priv; + drm_device_dma_t *dma = dev->dma; + int i; - copy_from_user_ret(&init, (drm_mga_init_t *)arg, sizeof(init), -EFAULT); + dev_priv->sync_tag++; - switch(init.func) { - case MGA_INIT_DMA: - return mga_dma_initialize(dev, &init); - case MGA_CLEANUP_DMA: - return mga_dma_cleanup(dev); + if(dev_priv->sync_tag < FREELIST_INITIAL) { + dev_priv->sync_tag = FREELIST_INITIAL; } + if(dev_priv->sync_tag > 0x3fffffff) { + mga_flush_queue(dev); + mga_dma_quiescent(dev); + + for (i = 0; i < dma->buf_count; i++) { + buf = dma->buflist[ i ]; + buf_priv = buf->dev_private; + buf_priv->my_freelist->age = MGA_BUF_FREE; + } + + dev_priv->sync_tag = FREELIST_INITIAL; + } + temp = dev_priv->sync_tag << 2; - return -EINVAL; -} - -#define MGA_ILOAD_CMD (DC_opcod_iload | DC_atype_rpl | \ - DC_linear_linear | DC_bltmod_bfcol | \ - (0xC << DC_bop_SHIFT) | DC_sgnzero_enable | \ - DC_shftzero_enable | DC_clipdis_enable) + dev_priv->sarea_priv->last_enqueue = temp; -static void __mga_iload_small(drm_device_t *dev, - drm_buf_t *buf, - int use_agp) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned long address = (unsigned long)buf->bus_address; - int length = buf->used; - int y1 = buf_priv->boxes[0].y1; - int x1 = buf_priv->boxes[0].x1; - int y2 = buf_priv->boxes[0].y2; - int x2 = buf_priv->boxes[0].x2; - int dstorg = buf_priv->ContextState[MGA_CTXREG_DSTORG]; - int maccess = buf_priv->ContextState[MGA_CTXREG_MACCESS]; - PRIMLOCALS; - - PRIMRESET(dev_priv); - PRIMGETPTR(dev_priv); - - PRIMOUTREG(MGAREG_DSTORG, dstorg | use_agp); - PRIMOUTREG(MGAREG_MACCESS, maccess); - PRIMOUTREG(MGAREG_PITCH, (1 << 15)); - PRIMOUTREG(MGAREG_YDST, y1 * (x2 - x1)); - PRIMOUTREG(MGAREG_LEN, 1); - PRIMOUTREG(MGAREG_FXBNDRY, ((x2 - x1) * (y2 - y1) - 1) << 16); - PRIMOUTREG(MGAREG_AR0, (x2 - x1) * (y2 - y1) - 1); - PRIMOUTREG(MGAREG_AR3, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, MGA_ILOAD_CMD); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_SECADDRESS, address | TT_BLIT); - PRIMOUTREG(MGAREG_SECEND, (address + length) | use_agp); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0); - PRIMOUTREG(MGAREG_SOFTRAP, 0); - PRIMADVANCE(dev_priv); -#if 0 - /* For now we need to set this in the ioctl */ - sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; -#endif - MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); - while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; - - MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL); - MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); + DRM_DEBUG("sync_tag : %x\n", temp); + return temp; } -static void __mga_iload_xy(drm_device_t *dev, - drm_buf_t *buf, - int use_agp) +/* Least recently used : + * These operations are not atomic b/c they are protected by the + * hardware lock */ + +drm_buf_t *mga_freelist_get(drm_device_t *dev) { - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned long address = (unsigned long)buf->bus_address; - int length = buf->used; - int y1 = buf_priv->boxes[0].y1; - int x1 = buf_priv->boxes[0].x1; - int y2 = buf_priv->boxes[0].y2; - int x2 = buf_priv->boxes[0].x2; - int dstorg = buf_priv->ContextState[MGA_CTXREG_DSTORG]; - int maccess = buf_priv->ContextState[MGA_CTXREG_MACCESS]; - int pitch = buf_priv->ServerState[MGA_2DREG_PITCH]; - int width, height; - int texperdword = 0; - PRIMLOCALS; - - width = (x2 - x1); - height = (y2 - y1); - switch((maccess & 0x00000003)) { - case 0: - texperdword = 4; - break; - case 1: - texperdword = 2; - break; - case 2: - texperdword = 1; - break; - default: - DRM_ERROR("Invalid maccess value passed to __mga_iload_xy\n"); - return; - } - - x2 = x1 + width; - x2 = (x2 + (texperdword - 1)) & ~(texperdword - 1); - x1 = (x1 + (texperdword - 1)) & ~(texperdword - 1); - width = x2 - x1; - - PRIMRESET(dev_priv); - PRIMGETPTR(dev_priv); - PRIMOUTREG(MGAREG_DSTORG, dstorg | use_agp); - PRIMOUTREG(MGAREG_MACCESS, maccess); - PRIMOUTREG(MGAREG_PITCH, pitch); - PRIMOUTREG(MGAREG_YDSTLEN, (y1 << 16) | height); - - PRIMOUTREG(MGAREG_FXBNDRY, ((x1+width-1) << 16) | x1); - PRIMOUTREG(MGAREG_AR0, width * height - 1); - PRIMOUTREG(MGAREG_AR3, 0 ); - PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, MGA_ILOAD_CMD); - - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_SECADDRESS, address | TT_BLIT); - PRIMOUTREG(MGAREG_SECEND, (address + length) | use_agp); - - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0); - PRIMOUTREG(MGAREG_SOFTRAP, 0); - PRIMADVANCE(dev_priv); -#if 0 - /* For now we need to set this in the ioctl */ - sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; -#endif - MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); - while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; - - MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL); - MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); + drm_mga_private_t *dev_priv = + (drm_mga_private_t *) dev->dev_private; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + drm_mga_freelist_t *prev; + drm_mga_freelist_t *next; + + if((dev_priv->tail->age >> 2) <= FREELIST_COMPARE(status[1])) { + prev = dev_priv->tail->prev; + next = dev_priv->tail; + prev->next = NULL; + next->prev = next->next = NULL; + dev_priv->tail = prev; + next->age = MGA_BUF_USED; + return next->buf; + } + + return NULL; } -static void mga_dma_dispatch_iload(drm_device_t *dev, drm_buf_t *buf) +int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf) { + drm_mga_private_t *dev_priv = + (drm_mga_private_t *) dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; - - int use_agp = PDEA_pagpxfer_enable; - int x1 = buf_priv->boxes[0].x1; - int x2 = buf_priv->boxes[0].x2; - - if((x2 - x1) < 32) { - printk("using iload small\n"); - __mga_iload_small(dev, buf, use_agp); + drm_mga_freelist_t *prev; + drm_mga_freelist_t *head; + drm_mga_freelist_t *next; + + if(buf_priv->my_freelist->age == MGA_BUF_USED) { + /* Discarded buffer, put it on the tail */ + next = buf_priv->my_freelist; + next->age = MGA_BUF_FREE; + prev = dev_priv->tail; + prev->next = next; + next->prev = prev; + next->next = NULL; + dev_priv->tail = next; + DRM_DEBUG("Discarded\n"); } else { - printk("using iload xy\n"); - __mga_iload_xy(dev, buf, use_agp); - } + /* Normally aged buffer, put it on the head + 1, + * as the real head is a sentinal element + */ + next = buf_priv->my_freelist; + head = dev_priv->head; + prev = head->next; + head->next = next; + prev->prev = next; + next->prev = head; + next->next = prev; + } + + return 0; } -static void mga_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf) +static void mga_print_all_primary(drm_device_t *dev) { - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - unsigned long address = (unsigned long)buf->bus_address; - int length = buf->used; - int use_agp = PDEA_pagpxfer_enable; - int i, count; - PRIMLOCALS; - - PRIMRESET(dev_priv); - - count = buf_priv->nbox; - if (count == 0) - count = 1; - - mgaEmitState( dev_priv, buf_priv ); - - for (i = 0 ; i < count ; i++) { - if (i < buf_priv->nbox) - mgaEmitClipRect( dev_priv, &buf_priv->boxes[i] ); - - PRIMGETPTR(dev_priv); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_SECADDRESS, address | TT_VERTEX); - PRIMOUTREG( MGAREG_SECEND, (address + length) | use_agp); - - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DWGSYNC, 0); - PRIMOUTREG( MGAREG_SOFTRAP, 0); - PRIMADVANCE(dev_priv); + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_prim_buf_t *prim; + int i; + + DRM_DEBUG("Full list of primarys\n"); + for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) { + prim = dev_priv->prim_bufs[i]; + DRM_DEBUG("index : %d num_dwords : %d " + "max_dwords : %d phy_head : %x\n", + prim->idx, prim->num_dwords, + prim->max_dwords, prim->phys_head); + DRM_DEBUG("sec_used : %d swap_pending : %x " + "in_use : %x force_fire : %d\n", + prim->sec_used, prim->swap_pending, + prim->in_use, atomic_read(&prim->force_fire)); + DRM_DEBUG("needs_overflow : %d\n", + atomic_read(&prim->needs_overflow)); } - - PRIMGETPTR( dev_priv ); - - MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); - while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; - - MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL); - MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); + + DRM_DEBUG("current_idx : %d, next_idx : %d, last_idx : %d\n", + dev_priv->next_prim->idx, dev_priv->last_prim->idx, + dev_priv->current_prim->idx); } - -/* Used internally for the small buffers generated from client state - * information. - */ -static void mga_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) +static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init) { drm_mga_private_t *dev_priv = dev->dev_private; - unsigned long address = (unsigned long)buf->bus_address; - int length = buf->used; - int use_agp = PDEA_pagpxfer_enable; - PRIMLOCALS; - - PRIMRESET(dev_priv); - PRIMGETPTR(dev_priv); - - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_SECADDRESS, address | TT_GENERAL); - PRIMOUTREG( MGAREG_SECEND, (address + length) | use_agp); - - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DWGSYNC, 0); - PRIMOUTREG( MGAREG_SOFTRAP, 0); - PRIMADVANCE(dev_priv); - - MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); - while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; - - MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL); - MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); -} + drm_mga_prim_buf_t *prim_buffer; + int i, temp, size_of_buf; + int offset = init->reserved_map_agpstart; -/* Frees dispatch lock */ -static inline void mga_dma_quiescent(drm_device_t *dev) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - - while(1) { - atomic_inc(&dev_priv->dispatch_lock); - if(atomic_read(&dev_priv->dispatch_lock) == 1) { - break; - } else { - atomic_dec(&dev_priv->dispatch_lock); - } - } - while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) ; -#if 0 - MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); -#endif - while(MGA_READ(MGAREG_DWGSYNC) == MGA_SYNC_TAG) ; - MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); - while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; - atomic_dec(&dev_priv->dispatch_lock); + DRM_DEBUG("mga_init_primary_bufs\n"); + dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) / + PAGE_SIZE) * PAGE_SIZE; + DRM_DEBUG("primary_size\n"); + size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS; + dev_priv->warp_ucode_size = init->warp_ucode_size; + dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) * + (MGA_NUM_PRIM_BUFS + 1), + DRM_MEM_DRIVER); + if(dev_priv->prim_bufs == NULL) { + DRM_ERROR("Unable to allocate memory for prim_buf\n"); + return -ENOMEM; + } + DRM_DEBUG("memset\n"); + memset(dev_priv->prim_bufs, + 0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1)); + + temp = init->warp_ucode_size + dev_priv->primary_size; + temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; + + DRM_DEBUG("temp : %x\n", temp); + DRM_DEBUG("dev->agp->base: %lx\n", dev->agp->base); + DRM_DEBUG("init->reserved_map_agpstart: %x\n", + init->reserved_map_agpstart); + DRM_DEBUG("ioremap\n"); + dev_priv->ioremap = drm_ioremap(dev->agp->base + offset, + temp); + if(dev_priv->ioremap == NULL) { + DRM_DEBUG("Ioremap failed\n"); + return -ENOMEM; + } + init_waitqueue_head(&dev_priv->wait_queue); + + for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) { + DRM_DEBUG("For loop\n"); + prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t), + DRM_MEM_DRIVER); + if(prim_buffer == NULL) return -ENOMEM; + DRM_DEBUG("memset\n"); + memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t)); + prim_buffer->phys_head = offset + dev->agp->base; + prim_buffer->current_dma_ptr = + prim_buffer->head = + (u32 *) (dev_priv->ioremap + + offset - + init->reserved_map_agpstart); + prim_buffer->num_dwords = 0; + prim_buffer->max_dwords = size_of_buf / sizeof(u32); + prim_buffer->max_dwords -= 5; /* Leave room for the softrap */ + prim_buffer->sec_used = 0; + prim_buffer->idx = i; + offset = offset + size_of_buf; + dev_priv->prim_bufs[i] = prim_buffer; + DRM_DEBUG("Looping\n"); + } + dev_priv->current_prim_idx = 0; + dev_priv->next_prim = + dev_priv->last_prim = + dev_priv->current_prim = + dev_priv->prim_bufs[0]; + set_bit(0, &dev_priv->current_prim->in_use); + DRM_DEBUG("init done\n"); + return 0; } -/* Keeps dispatch lock held */ - -static inline int mga_dma_is_ready(drm_device_t *dev) +void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) { - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + int use_agp = PDEA_pagpxfer_enable; + unsigned long end; + int i; + int next_idx; + PRIMLOCALS; + + DRM_DEBUG("mga_fire_primary\n"); + dev_priv->last_sync_tag = mga_create_sync_tag(dev); + dev_priv->last_prim = prim; - atomic_inc(&dev_priv->dispatch_lock); - if(atomic_read(&dev_priv->dispatch_lock) == 1) { - /* We got the lock */ - return 1; + /* We never check for overflow, b/c there is always room */ + PRIMPTR(prim); + if(num_dwords <= 0) { + DRM_DEBUG("num_dwords == 0 when dispatched\n"); + goto out_prim_wait; + } + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag); + PRIMOUTREG( MGAREG_SOFTRAP, 0); + PRIMFINISH(prim); + + end = jiffies + (HZ*3); + if(sarea_priv->dirty & MGA_DMA_FLUSH) { + DRM_DEBUG("Dma top flush\n"); + while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) { + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), + atomic_read(&dma->total_lost)); + DRM_ERROR("lockup in fire primary " + "(Dma Top Flush)\n"); + goto out_prim_wait; + } + + for (i = 0 ; i < 4096 ; i++) mga_delay(); + } + sarea_priv->dirty &= ~(MGA_DMA_FLUSH); } else { - atomic_dec(&dev_priv->dispatch_lock); - return 0; + DRM_DEBUG("Status wait\n"); + while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) { + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), + atomic_read(&dma->total_lost)); + DRM_ERROR("lockup in fire primary " + "(Status Wait)\n"); + goto out_prim_wait; + } + + for (i = 0 ; i < 4096 ; i++) mga_delay(); + } } + + mga_flush_write_combine(); + atomic_inc(&dev_priv->pending_bufs); + atomic_inc(&dma->total_lost); + MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); + MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); + prim->num_dwords = 0; + + next_idx = prim->idx + 1; + if(next_idx >= MGA_NUM_PRIM_BUFS) + next_idx = 0; + + dev_priv->next_prim = dev_priv->prim_bufs[next_idx]; + return; + + out_prim_wait: + prim->num_dwords = 0; + prim->sec_used = 0; + clear_bit(0, &prim->in_use); + wake_up_interruptible(&dev_priv->wait_queue); + clear_bit(0, &prim->swap_pending); + clear_bit(0, &dev_priv->dispatch_lock); + atomic_dec(&dev_priv->pending_bufs); } -static inline int mga_dma_is_ready_no_hold(drm_device_t *dev) +int mga_advance_primary(drm_device_t *dev) { - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + DECLARE_WAITQUEUE(entry, current); + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_prim_buf_t *prim_buffer; + drm_device_dma_t *dma = dev->dma; + int next_prim_idx; + int ret = 0; - atomic_inc(&dev_priv->dispatch_lock); - if(atomic_read(&dev_priv->dispatch_lock) == 1) { - /* We got the lock, but free it */ - atomic_dec(&dev_priv->dispatch_lock); - return 1; - } else { - atomic_dec(&dev_priv->dispatch_lock); - return 0; + /* This needs to reset the primary buffer if available, + * we should collect stats on how many times it bites + * it's tail */ + + next_prim_idx = dev_priv->current_prim_idx + 1; + if(next_prim_idx >= MGA_NUM_PRIM_BUFS) + next_prim_idx = 0; + prim_buffer = dev_priv->prim_bufs[next_prim_idx]; + atomic_set(&dev_priv->in_wait, 1); + + /* In use is cleared in interrupt handler */ + + if(test_and_set_bit(0, &prim_buffer->in_use)) { + add_wait_queue(&dev_priv->wait_queue, &entry); + for (;;) { + current->state = TASK_INTERRUPTIBLE; + mga_dma_schedule(dev, 0); + if(!test_and_set_bit(0, &prim_buffer->in_use)) break; + atomic_inc(&dev->total_sleeps); + atomic_inc(&dma->total_missed_sched); + mga_print_all_primary(dev); + DRM_DEBUG("Schedule in advance\n"); + /* Three second delay */ + schedule_timeout(HZ*3); + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + } + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->wait_queue, &entry); + if(ret) return ret; } + atomic_set(&dev_priv->in_wait, 0); + /* This primary buffer is now free to use */ + prim_buffer->current_dma_ptr = prim_buffer->head; + prim_buffer->num_dwords = 0; + prim_buffer->sec_used = 0; + atomic_set(&prim_buffer->needs_overflow, 0); + dev_priv->current_prim = prim_buffer; + dev_priv->current_prim_idx = next_prim_idx; + DRM_DEBUG("Primarys at advance\n"); + mga_print_all_primary(dev); + return 0; } -static void mga_dma_service(int irq, void *device, struct pt_regs *regs) +/* More dynamic performance decisions */ +static inline int mga_decide_to_fire(drm_device_t *dev) { - drm_device_t *dev = (drm_device_t *)device; - drm_device_dma_t *dma = dev->dma; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_device_dma_t *dma = dev->dma; + + if(atomic_read(&dev_priv->next_prim->force_fire)) + { + atomic_inc(&dma->total_prio); + return 1; + } - atomic_dec(&dev_priv->dispatch_lock); - atomic_inc(&dev->total_irq); - MGA_WRITE(MGAREG_ICLEAR, 0xfa7); - - /* Free previous buffer */ - if (test_and_set_bit(0, &dev->dma_flag)) { - atomic_inc(&dma->total_missed_free); - return; + if (atomic_read(&dev_priv->in_flush) && dev_priv->next_prim->num_dwords) + { + atomic_inc(&dma->total_prio); + return 1; } - if (dma->this_buffer) { - drm_free_buffer(dev, dma->this_buffer); - dma->this_buffer = NULL; + + if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) { + if(test_bit(0, &dev_priv->next_prim->swap_pending)) { + atomic_inc(&dma->total_dmas); + return 1; + } } - clear_bit(0, &dev->dma_flag); - /* Dispatch new buffer */ - queue_task(&dev->tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); + if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) { + if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) { + atomic_inc(&dma->total_hit); + return 1; + } + } + if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) { + if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) { + atomic_inc(&dma->total_missed_free); + return 1; + } + } + + atomic_inc(&dma->total_tried); + return 0; } -/* Only called by mga_dma_schedule. */ -static int mga_do_dma(drm_device_t *dev, int locked) +int mga_dma_schedule(drm_device_t *dev, int locked) { - drm_buf_t *buf; - int retcode = 0; - drm_device_dma_t *dma = dev->dma; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_buf_priv_t *buf_priv; + drm_device_dma_t *dma = dev->dma; - printk("mga_do_dma\n"); - if (test_and_set_bit(0, &dev->dma_flag)) { + if (test_and_set_bit(0, &dev->dma_flag)) { atomic_inc(&dma->total_missed_dma); return -EBUSY; } - - if (!dma->next_buffer) { - DRM_ERROR("No next_buffer\n"); - clear_bit(0, &dev->dma_flag); - return -EINVAL; - } - - buf = dma->next_buffer; - - printk("context %d, buffer %d\n", buf->context, buf->idx); - - if (buf->list == DRM_LIST_RECLAIM) { - drm_clear_next_buffer(dev); - drm_free_buffer(dev, buf); - clear_bit(0, &dev->dma_flag); - return -EINVAL; - } + + DRM_DEBUG("mga_dma_schedule\n"); - if (!buf->used) { - DRM_ERROR("0 length buffer\n"); - drm_clear_next_buffer(dev); - drm_free_buffer(dev, buf); - clear_bit(0, &dev->dma_flag); - return 0; - } - - if (mga_dma_is_ready(dev) == 0) { - clear_bit(0, &dev->dma_flag); - return -EBUSY; + if(atomic_read(&dev_priv->in_flush) || + atomic_read(&dev_priv->in_wait)) { + locked = 1; } - /* Always hold the hardware lock while dispatching. - */ - if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - atomic_inc(&dma->total_missed_lock); - clear_bit(0, &dev->dma_flag); - atomic_dec(&dev_priv->dispatch_lock); - return -EBUSY; + if (!locked && + !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { + atomic_inc(&dma->total_missed_lock); + clear_bit(0, &dev->dma_flag); + return -EBUSY; } + DRM_DEBUG("I'm locked\n"); - dma->next_queue = dev->queuelist[DRM_KERNEL_CONTEXT]; - drm_clear_next_buffer(dev); - buf->pending = 1; - buf->waiting = 0; - buf->list = DRM_LIST_PEND; - - buf_priv = buf->dev_private; - - printk("dispatch!\n"); - switch (buf_priv->dma_type) { - case MGA_DMA_GENERAL: - mga_dma_dispatch_general(dev, buf); - break; - case MGA_DMA_VERTEX: - mga_dma_dispatch_vertex(dev, buf); - break; -/* case MGA_DMA_SETUP: */ -/* mga_dma_dispatch_setup(dev, address, length); */ -/* break; */ - case MGA_DMA_ILOAD: - mga_dma_dispatch_iload(dev, buf); - break; - default: - printk("bad buffer type %x in dispatch\n", buf_priv->dma_type); - break; + + if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) { + /* Fire dma buffer */ + if(mga_decide_to_fire(dev)) { + DRM_DEBUG("mga_fire_primary\n"); + DRM_DEBUG("idx :%d\n", dev_priv->next_prim->idx); + atomic_set(&dev_priv->next_prim->force_fire, 0); + if(dev_priv->current_prim == dev_priv->next_prim && + dev_priv->next_prim->num_dwords != 0) { + /* Schedule overflow for a later time */ + atomic_set( + &dev_priv->current_prim->needs_overflow, + 1); + } + mga_fire_primary(dev, dev_priv->next_prim); + } else { + clear_bit(0, &dev_priv->dispatch_lock); + } + } else { + DRM_DEBUG("I can't get the dispatch lock\n"); } - atomic_dec(&dev_priv->pending_bufs); - - drm_free_buffer(dev, dma->this_buffer); - dma->this_buffer = buf; - - atomic_add(buf->used, &dma->total_bytes); - atomic_inc(&dma->total_dmas); - + if (!locked) { if (drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { @@ -692,90 +646,251 @@ static int mga_do_dma(drm_device_t *dev, int locked) } } - clear_bit(0, &dev->dma_flag); - - if(!atomic_read(&dev_priv->pending_bufs)) { - wake_up_interruptible(&dev->queuelist[DRM_KERNEL_CONTEXT]->flush_queue); - } - -#if 0 - wake_up_interruptible(&dev->lock.lock_queue); -#endif + clear_bit(0, &dev->dma_flag); - /* We hold the dispatch lock until the interrupt handler - * frees it - */ - return retcode; + if(atomic_read(&dev_priv->in_flush) == 1 && + dev_priv->next_prim->num_dwords == 0) { + /* Everything is on the hardware */ + DRM_DEBUG("Primarys at Flush\n"); + mga_print_all_primary(dev); + atomic_set(&dev_priv->in_flush, 0); + wake_up_interruptible(&dev_priv->flush_queue); + } + + return 0; } -static void mga_dma_schedule_timer_wrapper(unsigned long dev) +static void mga_dma_service(int irq, void *device, struct pt_regs *regs) { - mga_dma_schedule((drm_device_t *)dev, 0); + drm_device_t *dev = (drm_device_t *)device; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_prim_buf_t *last_prim_buffer; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + + atomic_inc(&dev->total_irq); + MGA_WRITE(MGAREG_ICLEAR, 0x00000001); + last_prim_buffer = dev_priv->last_prim; + last_prim_buffer->num_dwords = 0; + last_prim_buffer->sec_used = 0; + clear_bit(0, &last_prim_buffer->in_use); + wake_up_interruptible(&dev_priv->wait_queue); + clear_bit(0, &last_prim_buffer->swap_pending); + clear_bit(0, &dev_priv->dispatch_lock); + atomic_dec(&dev_priv->pending_bufs); + dev_priv->sarea_priv->last_dispatch = status[1]; + queue_task(&dev->tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); } -static void mga_dma_schedule_tq_wrapper(void *dev) +static void mga_dma_task_queue(void *device) { + drm_device_t *dev = (drm_device_t *) device; + mga_dma_schedule(dev, 0); } -int mga_dma_schedule(drm_device_t *dev, int locked) +int mga_dma_cleanup(drm_device_t *dev) { - drm_queue_t *q; - drm_buf_t *buf; - int retcode = 0; - int processed = 0; - int missed; - int expire = 20; - drm_device_dma_t *dma = dev->dma; - - printk("mga_dma_schedule\n"); - - if (test_and_set_bit(0, &dev->interrupt_flag)) { - /* Not reentrant */ - atomic_inc(&dma->total_missed_sched); - return -EBUSY; - } - missed = atomic_read(&dma->total_missed_sched); + if(dev->dev_private) { + drm_mga_private_t *dev_priv = + (drm_mga_private_t *) dev->dev_private; + + if(dev_priv->ioremap) { + int temp = (dev_priv->warp_ucode_size + + dev_priv->primary_size + + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; -again: - /* There is only one queue: - */ - if (!dma->next_buffer && DRM_WAITCOUNT(dev, DRM_KERNEL_CONTEXT)) { - q = dev->queuelist[DRM_KERNEL_CONTEXT]; - buf = drm_waitlist_get(&q->waitlist); - dma->next_buffer = buf; - dma->next_queue = q; - if (buf && buf->list == DRM_LIST_RECLAIM) { - drm_clear_next_buffer(dev); - drm_free_buffer(dev, buf); + drm_ioremapfree((void *) dev_priv->ioremap, temp); + } + if(dev_priv->status_page != NULL) { + iounmap(dev_priv->status_page); + } + if(dev_priv->real_status_page != 0UL) { + mga_free_page(dev, dev_priv->real_status_page); + } + if(dev_priv->prim_bufs != NULL) { + int i; + for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) { + if(dev_priv->prim_bufs[i] != NULL) { + drm_free(dev_priv->prim_bufs[i], + sizeof(drm_mga_prim_buf_t), + DRM_MEM_DRIVER); + } + } + drm_free(dev_priv->prim_bufs, sizeof(void *) * + (MGA_NUM_PRIM_BUFS + 1), + DRM_MEM_DRIVER); + } + if(dev_priv->head != NULL) { + mga_freelist_cleanup(dev); } + + + drm_free(dev->dev_private, sizeof(drm_mga_private_t), + DRM_MEM_DRIVER); + dev->dev_private = NULL; } - if (dma->next_buffer) { - if (!(retcode = mga_do_dma(dev, locked))) - ++processed; + return 0; +} + +static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { + drm_mga_private_t *dev_priv; + drm_map_t *sarea_map = NULL; + int i; + + dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); + if(dev_priv == NULL) return -ENOMEM; + dev->dev_private = (void *) dev_priv; + + DRM_DEBUG("dev_private\n"); + + memset(dev_priv, 0, sizeof(drm_mga_private_t)); + atomic_set(&dev_priv->in_flush, 0); + + if((init->reserved_map_idx >= dev->map_count) || + (init->buffer_map_idx >= dev->map_count)) { + mga_dma_cleanup(dev); + DRM_DEBUG("reserved_map or buffer_map are invalid\n"); + return -EINVAL; } + + dev_priv->reserved_map_idx = init->reserved_map_idx; + dev_priv->buffer_map_idx = init->buffer_map_idx; + sarea_map = dev->maplist[0]; + dev_priv->sarea_priv = (drm_mga_sarea_t *) + ((u8 *)sarea_map->handle + + init->sarea_priv_offset); + DRM_DEBUG("sarea_priv\n"); - /* Try again if we succesfully dispatched a buffer, or if someone - * tried to schedule while we were working. - */ - if (--expire) { - if (missed != atomic_read(&dma->total_missed_sched)) { - atomic_inc(&dma->total_lost); - if (mga_dma_is_ready_no_hold(dev)) - goto again; - } + /* Scale primary size to the next page */ + dev_priv->chipset = init->chipset; + dev_priv->frontOffset = init->frontOffset; + dev_priv->backOffset = init->backOffset; + dev_priv->depthOffset = init->depthOffset; + dev_priv->textureOffset = init->textureOffset; + dev_priv->textureSize = init->textureSize; + dev_priv->cpp = init->cpp; + dev_priv->sgram = init->sgram; + dev_priv->stride = init->stride; - if (processed && mga_dma_is_ready_no_hold(dev)) { - atomic_inc(&dma->total_lost); - processed = 0; - goto again; - } + dev_priv->mAccess = init->mAccess; + init_waitqueue_head(&dev_priv->flush_queue); + dev_priv->WarpPipe = -1; + + DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n", + dev_priv->chipset, dev_priv->warp_ucode_size, + dev_priv->backOffset, dev_priv->depthOffset); + DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %x\n", + dev_priv->cpp, dev_priv->sgram, dev_priv->stride, + dev_priv->mAccess); + + memcpy(&dev_priv->WarpIndex, &init->WarpIndex, + sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES); + + for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++) + DRM_DEBUG("warp pipe %d: installed: %d phys: %lx size: %x\n", + i, + dev_priv->WarpIndex[i].installed, + dev_priv->WarpIndex[i].phys_addr, + dev_priv->WarpIndex[i].size); + + DRM_DEBUG("Doing init prim buffers\n"); + if(mga_init_primary_bufs(dev, init) != 0) { + DRM_ERROR("Can not initialize primary buffers\n"); + mga_dma_cleanup(dev); + return -ENOMEM; } - - clear_bit(0, &dev->interrupt_flag); - - return retcode; + DRM_DEBUG("Done with init prim buffers\n"); + dev_priv->real_status_page = mga_alloc_page(dev); + if(dev_priv->real_status_page == 0UL) { + mga_dma_cleanup(dev); + DRM_ERROR("Can not allocate status page\n"); + return -ENOMEM; + } + DRM_DEBUG("Status page at %lx\n", dev_priv->real_status_page); + + dev_priv->status_page = + ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page), + PAGE_SIZE); + + if(dev_priv->status_page == NULL) { + mga_dma_cleanup(dev); + DRM_ERROR("Can not remap status page\n"); + return -ENOMEM; + } + + DRM_DEBUG("Status page remapped to %p\n", dev_priv->status_page); + /* Write status page when secend or softrap occurs */ + MGA_WRITE(MGAREG_PRIMPTR, + virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003); + + dev_priv->device = pci_find_device(0x102b, 0x0525, NULL); + if(dev_priv->device == NULL) { + DRM_ERROR("Could not find pci device for card\n"); + mga_dma_cleanup(dev); + return -EINVAL; + } + + DRM_DEBUG("dma initialization\n"); + + /* Private is now filled in, initialize the hardware */ + { + __volatile__ unsigned int *status = + (unsigned int *)dev_priv->status_page; + PRIMLOCALS; + PRIMGETPTR( dev_priv ); + + dev_priv->last_sync_tag = mga_create_sync_tag(dev); + + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag); + PRIMOUTREG(MGAREG_SOFTRAP, 0); + /* Poll for the first buffer to insure that + * the status register will be correct + */ + DRM_DEBUG("phys_head : %lx\n", (unsigned long)phys_head); + status[1] = 0; + + mga_flush_write_combine(); + MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); + + MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) | + PDEA_pagpxfer_enable)); + + while(MGA_READ(MGAREG_DWGSYNC) != dev_priv->last_sync_tag) ; + DRM_DEBUG("status[0] after initialization : %x\n", status[0]); + DRM_DEBUG("status[1] after initialization : %x\n", status[1]); + } + + if(mga_freelist_init(dev) != 0) { + DRM_ERROR("Could not initialize freelist\n"); + mga_dma_cleanup(dev); + return -ENOMEM; + } + DRM_DEBUG("dma init was successful\n"); + return 0; +} + +int mga_dma_init(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_mga_init_t init; + + copy_from_user_ret(&init, (drm_mga_init_t *)arg, sizeof(init), -EFAULT); + + switch(init.func) { + case MGA_INIT_DMA: + return mga_dma_initialize(dev, &init); + case MGA_CLEANUP_DMA: + return mga_dma_cleanup(dev); + } + + return -EINVAL; } int mga_irq_install(drm_device_t *dev, int irq) @@ -792,7 +907,7 @@ int mga_irq_install(drm_device_t *dev, int irq) dev->irq = irq; up(&dev->struct_sem); - printk("install irq handler %d\n", irq); + DRM_DEBUG("install irq handler %d\n", irq); dev->context_flag = 0; dev->interrupt_flag = 0; @@ -802,13 +917,11 @@ int mga_irq_install(drm_device_t *dev, int irq) dev->dma->this_buffer = NULL; dev->tq.next = NULL; dev->tq.sync = 0; - dev->tq.routine = mga_dma_schedule_tq_wrapper; + dev->tq.routine = mga_dma_task_queue; dev->tq.data = dev; /* Before installing handler */ - MGA_WRITE(MGAREG_ICLEAR, 0xfa7); MGA_WRITE(MGAREG_IEN, 0); - /* Install handler */ if ((retcode = request_irq(dev->irq, mga_dma_service, @@ -820,11 +933,9 @@ int mga_irq_install(drm_device_t *dev, int irq) up(&dev->struct_sem); return retcode; } - /* After installing handler */ - MGA_WRITE(MGAREG_ICLEAR, 0xfa7); + MGA_WRITE(MGAREG_ICLEAR, 0x00000001); MGA_WRITE(MGAREG_IEN, 0x00000001); - return 0; } @@ -838,19 +949,13 @@ int mga_irq_uninstall(drm_device_t *dev) up(&dev->struct_sem); if (!irq) return -EINVAL; - - printk("remove irq handler %d\n", irq); - - MGA_WRITE(MGAREG_ICLEAR, 0xfa7); + DRM_DEBUG("remove irq handler %d\n", irq); + MGA_WRITE(MGAREG_ICLEAR, 0x00000001); MGA_WRITE(MGAREG_IEN, 0); - MGA_WRITE(MGAREG_ICLEAR, 0xfa7); - free_irq(irq, dev); - return 0; } - int mga_control(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -870,36 +975,64 @@ int mga_control(struct inode *inode, struct file *filp, unsigned int cmd, } } -int mga_flush_queue(drm_device_t *dev) +static int mga_flush_queue(drm_device_t *dev) { DECLARE_WAITQUEUE(entry, current); - drm_queue_t *q = dev->queuelist[DRM_KERNEL_CONTEXT]; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; int ret = 0; - - printk("mga_flush_queue\n"); - if(atomic_read(&dev_priv->pending_bufs) != 0) { - current->state = TASK_INTERRUPTIBLE; - add_wait_queue(&q->flush_queue, &entry); - for (;;) { - if (!atomic_read(&dev_priv->pending_bufs)) break; - printk("Calling schedule from flush_queue : %d\n", - atomic_read(&dev_priv->pending_bufs)); - mga_dma_schedule(dev, 1); - schedule(); - if (signal_pending(current)) { - ret = -EINTR; /* Can't restart */ - break; - } - } - printk("Exited out of schedule from flush_queue\n"); - current->state = TASK_RUNNING; - remove_wait_queue(&q->flush_queue, &entry); + + if(dev_priv == NULL) { + return 0; } + if(dev_priv->next_prim->num_dwords != 0) { + atomic_set(&dev_priv->in_flush, 1); + current->state = TASK_INTERRUPTIBLE; + add_wait_queue(&dev_priv->flush_queue, &entry); + for (;;) { + mga_dma_schedule(dev, 0); + if (atomic_read(&dev_priv->in_flush) == 0) + break; + atomic_inc(&dev->total_sleeps); + DRM_DEBUG("Schedule in flush_queue\n"); + schedule_timeout(HZ*3); + if (signal_pending(current)) { + ret = -EINTR; /* Can't restart */ + break; + } + } + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->flush_queue, &entry); + } + atomic_set(&dev_priv->in_flush, 0); return ret; } +/* Must be called with the lock held */ +void mga_reclaim_buffers(drm_device_t *dev, pid_t pid) +{ + drm_device_dma_t *dma = dev->dma; + int i; + + if (!dma) return; + if(dev->dev_private == NULL) return; + + mga_flush_queue(dev); + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_mga_buf_priv_t *buf_priv = buf->dev_private; + + if (buf->pid == pid) { + if(buf_priv == NULL) return; + /* Only buffers that need to get reclaimed ever + * get set to free */ + if(buf_priv->my_freelist->age == MGA_BUF_USED) + buf_priv->my_freelist->age = MGA_BUF_FREE; + } + } +} + int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -916,16 +1049,15 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, current->pid, lock.context); return -EINVAL; } - - printk("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", - lock.context, current->pid, dev->lock.hw_lock->lock, - lock.flags); - + + DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", + lock.context, current->pid, dev->lock.hw_lock->lock, + lock.flags); if (lock.context < 0) { return -EINVAL; } - + /* Only one queue: */ @@ -948,8 +1080,7 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; - current->policy |= SCHED_YIELD; - printk("Calling lock schedule\n"); + DRM_DEBUG("Calling lock schedule\n"); schedule(); if (signal_pending(current)) { ret = -ERESTARTSYS; @@ -962,17 +1093,60 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, if (!ret) { if (lock.flags & _DRM_LOCK_QUIESCENT) { - printk("_DRM_LOCK_QUIESCENT\n"); - ret = mga_flush_queue(dev); - if(ret != 0) { - drm_lock_free(dev, &dev->lock.hw_lock->lock, - lock.context); - } else { - mga_dma_quiescent(dev); - } + DRM_DEBUG("_DRM_LOCK_QUIESCENT\n"); + mga_flush_queue(dev); + mga_dma_quiescent(dev); } } - printk("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); + + DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); return ret; } +int mga_flush_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_lock_t lock; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + int i; + + copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_flush_ioctl called without lock held\n"); + return -EINVAL; + } + + if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) { + mga_flush_queue(dev); + + if((MGA_READ(MGAREG_STATUS) & 0x00030001) == 0x00020000 && + status[1] != dev_priv->last_sync_tag) + { + DRM_DEBUG("Reseting hardware status\n"); + MGA_WRITE(MGAREG_DWGSYNC, dev_priv->last_sync_tag); + + while(MGA_READ(MGAREG_DWGSYNC) != + dev_priv->last_sync_tag) + { + for(i = 0; i < 4096; i++) mga_delay(); + } + + status[1] = + sarea_priv->last_dispatch = + dev_priv->last_sync_tag; + } else { + sarea_priv->last_dispatch = status[1]; + } + } + if(lock.flags & _DRM_LOCK_QUIESCENT) { + mga_dma_quiescent(dev); + } + + return 0; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.h deleted file mode 100644 index 7f1c57957..000000000 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef MGA_DMA_H -#define MGA_DMA_H - -#include "mga_drm_public.h" - - -/* Isn't this fun. This has to be fixed asap by emitting primary - * dma commands in the 'do_dma' ioctl. - */ -typedef struct { - int dma_type; - - unsigned int ContextState[MGA_CTX_SETUP_SIZE]; - unsigned int ServerState[MGA_2D_SETUP_SIZE]; - unsigned int TexState[2][MGA_TEX_SETUP_SIZE]; - unsigned int WarpPipe; - unsigned int dirty; - - unsigned int nbox; - xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS]; -} drm_mga_buf_priv_t; - - -#define MGA_DMA_GENERAL 0 -#define MGA_DMA_VERTEX 1 -#define MGA_DMA_SETUP 2 -#define MGA_DMA_ILOAD 3 - - -#define DWGREG0 0x1c00 -#define DWGREG0_END 0x1dff -#define DWGREG1 0x2c00 -#define DWGREG1_END 0x2dff - -#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END) -#define ADRINDEX0(r) (u8)((r - DWGREG0) >> 2) -#define ADRINDEX1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) -#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r)) - - -/* Macros for inserting commands into a secondary dma buffer. - */ - -#define DMALOCALS u8 tempIndex[4]; u32 *dma_ptr; \ - int outcount, num_dwords; - -#define DMAGETPTR(buf) do { \ - dma_ptr = (u32 *)((u8 *)buf->address + buf->used); \ - outcount = 0; \ - num_dwords = buf->used / 4; \ -} while(0) - -#define DMAADVANCE(buf) do { \ - buf->used = num_dwords * 4; \ -} while(0) - -#define DMAOUTREG(reg, val) do { \ - tempIndex[outcount]=ADRINDEX(reg); \ - dma_ptr[++outcount] = val; \ - if (outcount == 4) { \ - outcount = 0; \ - dma_ptr[0] = *(u32 *)tempIndex; \ - dma_ptr+=5; \ - num_dwords += 5; \ - } \ -}while (0) - - - -#define VERBO 0 - - -/* Primary buffer versions of above -- pretty similar really. - */ -#define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \ - int outcount, num_dwords - -#define PRIMRESET(dev_priv) do { \ - dev_priv->prim_num_dwords = 0; \ - dev_priv->current_dma_ptr = dev_priv->prim_head; \ -} while (0) - -#define PRIMGETPTR(dev_priv) do { \ - dma_ptr = dev_priv->current_dma_ptr; \ - phys_head = dev_priv->prim_phys_head; \ - num_dwords = dev_priv->prim_num_dwords; \ - outcount = 0; \ -} while (0) - -#define PRIMADVANCE(dev_priv) do { \ - dev_priv->prim_num_dwords = num_dwords; \ - dev_priv->current_dma_ptr = dma_ptr; \ -} while (0) - -#define PRIMOUTREG(reg, val) do { \ - tempIndex[outcount]=ADRINDEX(reg); \ - dma_ptr[1+outcount] = val; \ - if( ++outcount == 4) { \ - outcount = 0; \ - dma_ptr[0] = *(u32 *)tempIndex; \ - dma_ptr+=5; \ - num_dwords += 5; \ - } \ - if (VERBO) \ - printk(KERN_INFO \ - "OUT %x val %x dma_ptr %p nr_dwords %d\n", \ - outcount, ADRINDEX(reg), dma_ptr, \ - num_dwords); \ -}while (0) - - -#endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm_public.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h index 8b21df11f..12a858e7a 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm_public.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h @@ -1,4 +1,4 @@ -/* mga_drm_public.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- +/* mga_drm.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. @@ -26,12 +26,17 @@ * Authors: Jeff Hartmann <jhartmann@precisioninsight.com> * Keith Whitwell <keithw@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm_public.h,v 1.1 2000/02/11 17:26:07 dawes Exp $ + * $XFree86$ */ -#ifndef _MGA_DRM_PUBLIC_H_ -#define _MGA_DRM_PUBLIC_H_ +#ifndef _MGA_DRM_H_ +#define _MGA_DRM_H_ +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmMga.h) + */ +#ifndef _MGA_DEFINES_ +#define _MGA_DEFINES_ #define MGA_F 0x1 /* fog */ #define MGA_A 0x2 /* alpha */ #define MGA_S 0x4 /* specular */ @@ -54,66 +59,18 @@ #define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A) #define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A) - #define MGA_MAX_G400_PIPES 16 #define MGA_MAX_G200_PIPES 8 /* no multitex */ - #define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES #define MGA_CARD_TYPE_G200 1 #define MGA_CARD_TYPE_G400 2 +#define MGA_FRONT 0x1 +#define MGA_BACK 0x2 +#define MGA_DEPTH 0x4 - -typedef struct _drm_mga_warp_index { - int installed; - unsigned long phys_addr; - int size; -} mgaWarpIndex; - -typedef struct drm_mga_init { - enum { - MGA_INIT_DMA = 0x01, - MGA_CLEANUP_DMA = 0x02 - } func; - int reserved_map_agpstart; - int reserved_map_idx; - int buffer_map_idx; - int sarea_priv_offset; - int primary_size; - int warp_ucode_size; - int fbOffset; - int backOffset; - int depthOffset; - int textureOffset; - int textureSize; - int cpp; - int stride; - int sgram; - int chipset; - mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES]; - - /* Redundant? - */ - int frontOrg; - int backOrg; - int depthOrg; - int mAccess; -} drm_mga_init_t; - -typedef struct _xf86drmClipRectRec { - unsigned short x1; - unsigned short y1; - unsigned short x2; - unsigned short y2; -} xf86drmClipRectRec; - -#define MGA_CLEAR_FRONT 0x1 -#define MGA_CLEAR_BACK 0x2 -#define MGA_CLEAR_DEPTH 0x4 - - -/* Each context has a state: +/* 3d state excluding texture units: */ #define MGA_CTXREG_DSTORG 0 /* validated */ #define MGA_CTXREG_MACCESS 1 @@ -124,7 +81,8 @@ typedef struct _xf86drmClipRectRec { #define MGA_CTXREG_WFLAG 6 #define MGA_CTXREG_TDUAL0 7 #define MGA_CTXREG_TDUAL1 8 -#define MGA_CTX_SETUP_SIZE 9 +#define MGA_CTXREG_FCOL 9 +#define MGA_CTX_SETUP_SIZE 10 /* 2d state */ @@ -146,33 +104,89 @@ typedef struct _xf86drmClipRectRec { #define MGA_TEXREG_HEIGHT 10 #define MGA_TEX_SETUP_SIZE 11 - /* What needs to be changed for the current vertex dma buffer? */ -#define MGASAREA_NEW_CONTEXT 0x1 -#define MGASAREA_NEW_TEX0 0x2 -#define MGASAREA_NEW_TEX1 0x4 -#define MGASAREA_NEW_PIPE 0x8 -#define MGASAREA_NEW_2D 0x10 - +#define MGA_UPLOAD_CTX 0x1 +#define MGA_UPLOAD_TEX0 0x2 +#define MGA_UPLOAD_TEX1 0x4 +#define MGA_UPLOAD_PIPE 0x8 +#define MGA_UPLOAD_TEX0IMAGE 0x10 +#define MGA_UPLOAD_TEX1IMAGE 0x20 +#define MGA_UPLOAD_2D 0x40 +#define MGA_WAIT_AGE 0x80 /* handled client-side */ +#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */ +#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock + quiescent */ + +/* 64 buffers of 16k each, total 1 meg. + */ +#define MGA_DMA_BUF_ORDER 14 +#define MGA_DMA_BUF_SZ (1<<MGA_DMA_BUF_ORDER) +#define MGA_DMA_BUF_NR 63 -/* Keep this small for testing +/* Keep these small for testing. */ -#define MGA_NR_SAREA_CLIPRECTS 2 +#define MGA_NR_SAREA_CLIPRECTS 8 -/* Upto 128 regions. Minimum region size of 256k. +/* 2 heaps (1 for card, 1 for agp), each divided into upto 128 + * regions, subject to a minimum region size of (1<<16) == 64k. + * + * Clients may subdivide regions internally, but when sharing between + * clients, the region size is the minimum granularity. */ -#define MGA_NR_TEX_REGIONS 128 -#define MGA_MIN_LOG_TEX_GRANULARITY 18 -typedef struct { - unsigned char next, prev; - unsigned char in_use; - int age; -} mgaTexRegion; +#define MGA_CARD_HEAP 0 +#define MGA_AGP_HEAP 1 +#define MGA_NR_TEX_HEAPS 2 +#define MGA_NR_TEX_REGIONS 16 +#define MGA_LOG_MIN_TEX_REGION_SIZE 16 +#endif + +typedef struct _drm_mga_warp_index { + int installed; + unsigned long phys_addr; + int size; +} drm_mga_warp_index_t; + +typedef struct drm_mga_init { + enum { + MGA_INIT_DMA = 0x01, + MGA_CLEANUP_DMA = 0x02 + } func; + int reserved_map_agpstart; + int reserved_map_idx; + int buffer_map_idx; + int sarea_priv_offset; + int primary_size; + int warp_ucode_size; + int frontOffset; + int backOffset; + int depthOffset; + int textureOffset; + int textureSize; + int agpTextureOffset; + int agpTextureSize; + int cpp; + int stride; + int sgram; + int chipset; + drm_mga_warp_index_t WarpIndex[MGA_MAX_WARP_PIPES]; + int mAccess; +} drm_mga_init_t; + +/* Warning: if you change the sarea structure, you must change the Xserver + * structures as well */ + +typedef struct _drm_mga_tex_region { + unsigned char next, prev; + unsigned char in_use; + int age; +} drm_mga_tex_region_t; -typedef struct -{ +typedef struct _drm_mga_sarea { + /* The channel for communication of state information to the kernel + * on firing a vertex dma buffer. + */ unsigned int ContextState[MGA_CTX_SETUP_SIZE]; unsigned int ServerState[MGA_2D_SETUP_SIZE]; unsigned int TexState[2][MGA_TEX_SETUP_SIZE]; @@ -180,39 +194,68 @@ typedef struct unsigned int dirty; unsigned int nbox; - xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS]; + drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS]; - /* kernel doesn't touch from here down */ - int ctxOwner; - mgaTexRegion texList[MGA_NR_TEX_REGIONS+1]; - int texAge; -} drm_mga_sarea_t; + + /* Information about the most recently used 3d drawable. The + * client fills in the req_* fields, the server fills in the + * exported_ fields and puts the cliprects into boxes, above. + * + * The client clears the exported_drawable field before + * clobbering the boxes data. + */ + unsigned int req_drawable; /* the X drawable id */ + unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */ + + unsigned int exported_drawable; + unsigned int exported_index; + unsigned int exported_stamp; + unsigned int exported_buffers; + unsigned int exported_nfront; + unsigned int exported_nback; + int exported_back_x, exported_front_x, exported_w; + int exported_back_y, exported_front_y, exported_h; + drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS]; + + /* Counters for aging textures and for client-side throttling. + */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int last_quiescent; /* */ + /* LRU lists for texture memory in agp space and on the card + */ + drm_mga_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1]; + unsigned int texAge[MGA_NR_TEX_HEAPS]; + + /* Mechanism to validate card state. + */ + int ctxOwner; +} drm_mga_sarea_t; + /* Device specific ioctls: */ -typedef struct { +typedef struct _drm_mga_clear { int clear_color; int clear_depth; int flags; } drm_mga_clear_t; - -typedef struct { - int flags; /* not actually used? */ +typedef struct _drm_mga_swap { + int dummy; } drm_mga_swap_t; -typedef struct { +typedef struct _drm_mga_iload { + int idx; + int length; unsigned int destOrg; - unsigned int mAccess; - unsigned int pitch; - xf86drmClipRectRec texture; - int idx; } drm_mga_iload_t; +typedef struct _drm_mga_vertex { + int idx; /* buffer to queue */ + int used; /* bytes in use */ + int discard; /* client finished with buffer? */ +} drm_mga_vertex_t; -#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) -#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) -#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) -#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c index 8bc25617e..480413549 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c @@ -54,6 +54,7 @@ static struct file_operations mga_fops = { mmap: drm_mmap, read: drm_read, fasync: drm_fasync, + poll: drm_poll, }; static struct miscdevice mga_misc = { @@ -105,9 +106,11 @@ static drm_ioctl_desc_t mga_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_clear_bufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_swap_bufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_flush_ioctl, 1, 0 }, }; #define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls) @@ -380,6 +383,21 @@ int mga_init(void) drm_proc_init(dev); DRM_DEBUG("doing agp init\n"); dev->agp = drm_agp_init(); + if(dev->agp == NULL) { + DRM_DEBUG("The mga drm module requires the agpgart module" + " to function correctly\nPlease load the agpgart" + " module before you load the mga module\n"); + drm_proc_cleanup(); + misc_deregister(&mga_misc); + mga_takedown(dev); + return -ENOMEM; + } +#ifdef CONFIG_MTRR + dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base, + dev->agp->agp_info.aper_size * 1024 * 1024, + MTRR_TYPE_WRCOMB, + 1); +#endif DRM_DEBUG("doing ctxbitmap init\n"); if((retcode = drm_ctxbitmap_init(dev))) { DRM_ERROR("Cannot allocate memory for context bitmap.\n"); @@ -416,6 +434,16 @@ void mga_cleanup(void) } drm_ctxbitmap_cleanup(dev); mga_dma_cleanup(dev); +#ifdef CONFIG_MTRR + if(dev->agp && dev->agp->agp_mtrr) { + int retval; + retval = mtrr_del(dev->agp->agp_mtrr, + dev->agp->agp_info.aper_base, + dev->agp->agp_info.aper_size * 1024*1024); + DRM_DEBUG("mtrr_del = %d\n", retval); + } +#endif + mga_takedown(dev); if (dev->agp) { drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h index bc7808b0a..43deb613e 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h @@ -26,12 +26,32 @@ * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> * Jeff Hartmann <jhartmann@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h,v 1.1 2000/02/11 17:26:08 dawes Exp $ + * $XFree86$ */ #ifndef _MGA_DRV_H_ #define _MGA_DRV_H_ -#include "mga_drm_public.h" + +typedef struct { + unsigned int num_dwords; + unsigned int max_dwords; + u32 *current_dma_ptr; + u32 *head; + u32 phys_head; + int sec_used; + int idx; + int swap_pending; + u32 in_use; + atomic_t force_fire; + atomic_t needs_overflow; +} drm_mga_prim_buf_t; + +typedef struct _drm_mga_freelist { + unsigned int age; + drm_buf_t *buf; + struct _drm_mga_freelist *next; + struct _drm_mga_freelist *prev; +} drm_mga_freelist_t; typedef struct _drm_mga_private { int reserved_map_idx; @@ -40,7 +60,7 @@ typedef struct _drm_mga_private { int primary_size; int warp_ucode_size; int chipset; - int fbOffset; + int frontOffset; int backOffset; int depthOffset; int textureOffset; @@ -49,25 +69,32 @@ typedef struct _drm_mga_private { int stride; int sgram; int use_agp; - mgaWarpIndex WarpIndex[MGA_MAX_G400_PIPES]; + drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES]; + unsigned int WarpPipe; __volatile__ unsigned long softrap_age; - atomic_t dispatch_lock; + u32 dispatch_lock; + atomic_t in_flush; + atomic_t in_wait; atomic_t pending_bufs; - void *ioremap; - u32 *prim_head; - u32 *current_dma_ptr; - u32 prim_phys_head; - int prim_num_dwords; - int prim_max_dwords; - + unsigned int last_sync_tag; + unsigned int sync_tag; + void *status_page; + unsigned long real_status_page; + u8 *ioremap; + drm_mga_prim_buf_t **prim_bufs; + drm_mga_prim_buf_t *next_prim; + drm_mga_prim_buf_t *last_prim; + drm_mga_prim_buf_t *current_prim; + int current_prim_idx; + struct pci_dev *device; + drm_mga_freelist_t *head; + drm_mga_freelist_t *tail; + wait_queue_head_t flush_queue; /* Processes waiting until flush */ + wait_queue_head_t wait_queue; /* Processes waiting until interrupt */ /* Some validated register values: */ - u32 frontOrg; - u32 backOrg; - u32 depthOrg; u32 mAccess; - } drm_mga_private_t; /* mga_drv.c */ @@ -92,16 +119,18 @@ extern int mga_control(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -#if 0 -extern void mga_dma_init(drm_device_t *dev); -extern void mga_dma_cleanup(drm_device_t *dev); -#endif +/* mga_dma_init does init and release */ extern int mga_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int mga_dma_cleanup(drm_device_t *dev); +extern int mga_flush_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); -/* mga_dma_init does init and release */ +extern unsigned int mga_create_sync_tag(drm_device_t *dev); +extern drm_buf_t *mga_freelist_get(drm_device_t *dev); +extern int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf); +extern int mga_advance_primary(drm_device_t *dev); /* mga_bufs.c */ @@ -124,6 +153,8 @@ extern int mga_swap_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int mga_iload(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern int mga_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); /* mga_context.c */ extern int mga_resctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); @@ -144,13 +175,115 @@ extern int mga_context_switch(drm_device_t *dev, int old, int new); extern int mga_context_switch_complete(drm_device_t *dev, int new); +typedef enum { + TT_GENERAL, + TT_BLIT, + TT_VECTOR, + TT_VERTEX +} transferType_t; + +typedef struct { + drm_mga_freelist_t *my_freelist; + int discard; +} drm_mga_buf_priv_t; + +#define DWGREG0 0x1c00 +#define DWGREG0_END 0x1dff +#define DWGREG1 0x2c00 +#define DWGREG1_END 0x2dff + +#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END) +#define ADRINDEX0(r) (u8)((r - DWGREG0) >> 2) +#define ADRINDEX1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) +#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r)) + +#define MGA_VERBOSE 0 +#define MGA_NUM_PRIM_BUFS 8 + +#define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \ + int outcount, num_dwords + +#define PRIM_OVERFLOW(dev, dev_priv, length) do { \ + drm_mga_prim_buf_t *tmp_buf = \ + dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ + if( tmp_buf->max_dwords - tmp_buf->num_dwords < length || \ + tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \ + atomic_set(&tmp_buf->force_fire, 1); \ + mga_advance_primary(dev); \ + mga_dma_schedule(dev, 1); \ + } else if( atomic_read(&tmp_buf->needs_overflow)) { \ + mga_advance_primary(dev); \ + mga_dma_schedule(dev, 1); \ + } \ +} while(0) + +#define PRIMGETPTR(dev_priv) do { \ + drm_mga_prim_buf_t *tmp_buf = \ + dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ + if(MGA_VERBOSE) \ + DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \ + dma_ptr = tmp_buf->current_dma_ptr; \ + num_dwords = tmp_buf->num_dwords; \ + phys_head = tmp_buf->phys_head; \ + outcount = 0; \ +} while(0) + +#define PRIMPTR(prim_buf) do { \ + if(MGA_VERBOSE) \ + DRM_DEBUG("PRIMPTR in %s\n", __FUNCTION__); \ + dma_ptr = prim_buf->current_dma_ptr; \ + num_dwords = prim_buf->num_dwords; \ + phys_head = prim_buf->phys_head; \ + outcount = 0; \ +} while(0) + +#define PRIMFINISH(prim_buf) do { \ + if (MGA_VERBOSE) { \ + DRM_DEBUG( "PRIMFINISH in %s\n", __FUNCTION__); \ + if (outcount & 3) \ + DRM_DEBUG(" --- truncation\n"); \ + } \ + prim_buf->num_dwords = num_dwords; \ + prim_buf->current_dma_ptr = dma_ptr; \ +} while(0) + +#define PRIMADVANCE(dev_priv) do { \ +drm_mga_prim_buf_t *tmp_buf = \ + dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ + if (MGA_VERBOSE) { \ + DRM_DEBUG("PRIMADVANCE in %s\n", __FUNCTION__); \ + if (outcount & 3) \ + DRM_DEBUG(" --- truncation\n"); \ + } \ + tmp_buf->num_dwords = num_dwords; \ + tmp_buf->current_dma_ptr = dma_ptr; \ +} while (0) + +#define PRIMUPDATE(dev_priv) do { \ + drm_mga_prim_buf_t *tmp_buf = \ + dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ + tmp_buf->sec_used++; \ +} while (0) + +#define PRIMOUTREG(reg, val) do { \ + tempIndex[outcount]=ADRINDEX(reg); \ + dma_ptr[1+outcount] = val; \ + if (MGA_VERBOSE) \ + DRM_DEBUG(" PRIMOUT %d: 0x%x -- 0x%x\n", \ + num_dwords + 1 + outcount, ADRINDEX(reg), val); \ + if( ++outcount == 4) { \ + outcount = 0; \ + dma_ptr[0] = *(u32 *)tempIndex; \ + dma_ptr+=5; \ + num_dwords += 5; \ + } \ +}while (0) + +/* A reduced set of the mga registers. + */ #define MGAREG_MGA_EXEC 0x0100 -#define MGAREG_AGP_PLL 0x1e4c #define MGAREG_ALPHACTRL 0x2c7c -#define MGAREG_ALPHASTART 0x2c70 -#define MGAREG_ALPHAXINC 0x2c74 -#define MGAREG_ALPHAYINC 0x2c78 #define MGAREG_AR0 0x1c60 #define MGAREG_AR1 0x1c64 #define MGAREG_AR2 0x1c68 @@ -158,39 +291,16 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_AR4 0x1c70 #define MGAREG_AR5 0x1c74 #define MGAREG_AR6 0x1c78 -#define MGAREG_BCOL 0x1c20 #define MGAREG_CXBNDRY 0x1c80 #define MGAREG_CXLEFT 0x1ca0 #define MGAREG_CXRIGHT 0x1ca4 #define MGAREG_DMAPAD 0x1c54 -#define MGAREG_DR0_Z32LSB 0x2c50 -#define MGAREG_DR0_Z32MSB 0x2c54 -#define MGAREG_DR2_Z32LSB 0x2c60 -#define MGAREG_DR2_Z32MSB 0x2c64 -#define MGAREG_DR3_Z32LSB 0x2c68 -#define MGAREG_DR3_Z32MSB 0x2c6c -#define MGAREG_DR0 0x1cc0 -#define MGAREG_DR2 0x1cc8 -#define MGAREG_DR3 0x1ccc -#define MGAREG_DR4 0x1cd0 -#define MGAREG_DR6 0x1cd8 -#define MGAREG_DR7 0x1cdc -#define MGAREG_DR8 0x1ce0 -#define MGAREG_DR10 0x1ce8 -#define MGAREG_DR11 0x1cec -#define MGAREG_DR12 0x1cf0 -#define MGAREG_DR14 0x1cf8 -#define MGAREG_DR15 0x1cfc #define MGAREG_DSTORG 0x2cb8 -#define MGAREG_DWG_INDIR_WT 0x1e80 #define MGAREG_DWGCTL 0x1c00 #define MGAREG_DWGSYNC 0x2c4c #define MGAREG_FCOL 0x1c24 #define MGAREG_FIFOSTATUS 0x1e10 #define MGAREG_FOGCOL 0x1cf4 -#define MGAREG_FOGSTART 0x1cc4 -#define MGAREG_FOGXINC 0x1cd4 -#define MGAREG_FOGYINC 0x1ce4 #define MGAREG_FXBNDRY 0x1c84 #define MGAREG_FXLEFT 0x1ca8 #define MGAREG_FXRIGHT 0x1cac @@ -198,44 +308,22 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_IEN 0x1e1c #define MGAREG_LEN 0x1c5c #define MGAREG_MACCESS 0x1c04 -#define MGAREG_MCTLWTST 0x1c08 -#define MGAREG_MEMRDBK 0x1e44 -#define MGAREG_OPMODE 0x1e54 -#define MGAREG_PAT0 0x1c10 -#define MGAREG_PAT1 0x1c14 #define MGAREG_PITCH 0x1c8c #define MGAREG_PLNWT 0x1c1c #define MGAREG_PRIMADDRESS 0x1e58 #define MGAREG_PRIMEND 0x1e5c #define MGAREG_PRIMPTR 0x1e50 -#define MGAREG_RST 0x1e40 #define MGAREG_SECADDRESS 0x2c40 #define MGAREG_SECEND 0x2c44 #define MGAREG_SETUPADDRESS 0x2cd0 #define MGAREG_SETUPEND 0x2cd4 -#define MGAREG_SGN 0x1c58 -#define MGAREG_SHIFT 0x1c50 #define MGAREG_SOFTRAP 0x2c48 -#define MGAREG_SPECBSTART 0x2c98 -#define MGAREG_SPECBXINC 0x2c9c -#define MGAREG_SPECBYINC 0x2ca0 -#define MGAREG_SPECGSTART 0x2c8c -#define MGAREG_SPECGXINC 0x2c90 -#define MGAREG_SPECGYINC 0x2c94 -#define MGAREG_SPECRSTART 0x2c80 -#define MGAREG_SPECRXINC 0x2c84 -#define MGAREG_SPECRYINC 0x2c88 -#define MGAREG_SRC0 0x1c30 -#define MGAREG_SRC1 0x1c34 -#define MGAREG_SRC2 0x1c38 -#define MGAREG_SRC3 0x1c3c #define MGAREG_SRCORG 0x2cb4 #define MGAREG_STATUS 0x1e14 #define MGAREG_STENCIL 0x2cc8 #define MGAREG_STENCILCTL 0x2ccc #define MGAREG_TDUALSTAGE0 0x2cf8 #define MGAREG_TDUALSTAGE1 0x2cfc -#define MGAREG_TEST0 0x1e48 #define MGAREG_TEXBORDERCOL 0x2c5c #define MGAREG_TEXCTL 0x2c30 #define MGAREG_TEXCTL2 0x2c3c @@ -249,18 +337,6 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_TEXTRANS 0x2c34 #define MGAREG_TEXTRANSHIGH 0x2c38 #define MGAREG_TEXWIDTH 0x2c28 -#define MGAREG_TMR0 0x2c00 -#define MGAREG_TMR1 0x2c04 -#define MGAREG_TMR2 0x2c08 -#define MGAREG_TMR3 0x2c0c -#define MGAREG_TMR4 0x2c10 -#define MGAREG_TMR5 0x2c14 -#define MGAREG_TMR6 0x2c18 -#define MGAREG_TMR7 0x2c1c -#define MGAREG_TMR8 0x2c20 -#define MGAREG_VBIADDR0 0x3e08 -#define MGAREG_VBIADDR1 0x3e0c -#define MGAREG_VCOUNT 0x1e20 #define MGAREG_WACCEPTSEQ 0x1dd4 #define MGAREG_WCODEADDR 0x1e6c #define MGAREG_WFLAG 0x1dc4 @@ -270,18 +346,8 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_WGETMSB 0x1dc8 #define MGAREG_WIADDR 0x1dc0 #define MGAREG_WIADDR2 0x1dd8 -#define MGAREG_WIADDRNB 0x1e60 -#define MGAREG_WIADDRNB1 0x1e04 -#define MGAREG_WIADDRNB2 0x1e00 -#define MGAREG_WIMEMADDR 0x1e68 -#define MGAREG_WIMEMDATA 0x2000 -#define MGAREG_WIMEMDATA1 0x2100 #define MGAREG_WMISC 0x1e70 -#define MGAREG_WR 0x2d00 #define MGAREG_WVRTXSZ 0x1dcc -#define MGAREG_XDST 0x1cb0 -#define MGAREG_XYEND 0x1c44 -#define MGAREG_XYSTRT 0x1c40 #define MGAREG_YBOT 0x1c9c #define MGAREG_YDST 0x1c90 #define MGAREG_YDSTLEN 0x1c88 @@ -289,4 +355,40 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_YTOP 0x1c98 #define MGAREG_ZORG 0x1c0c +#define DC_atype_rstr 0x10 +#define DC_atype_blk 0x40 +#define PDEA_pagpxfer_enable 0x2 +#define WIA_wmode_suspend 0x0 +#define WIA_wmode_start 0x3 +#define WIA_wagp_agp 0x4 +#define DC_opcod_trap 0x4 +#define DC_arzero_enable 0x1000 +#define DC_sgnzero_enable 0x2000 +#define DC_shftzero_enable 0x4000 +#define DC_bop_SHIFT 16 +#define DC_clipdis_enable 0x80000000 +#define DC_solid_enable 0x800 +#define DC_transc_enable 0x40000000 +#define DC_opcod_bitblt 0x8 +#define DC_atype_rpl 0x0 +#define DC_linear_xy 0x0 +#define DC_solid_disable 0x0 +#define DC_arzero_disable 0x0 +#define DC_bltmod_bfcol 0x4000000 +#define DC_pattern_disable 0x0 +#define DC_transc_disable 0x0 + +#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \ + DC_sgnzero_enable | DC_shftzero_enable | \ + (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \ + DC_solid_enable | DC_transc_enable) + + +#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \ + DC_solid_disable | DC_arzero_disable | \ + DC_sgnzero_enable | DC_shftzero_enable | \ + (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol | \ + DC_pattern_disable | DC_transc_disable | \ + DC_clipdis_enable) \ + #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c index d09881bad..a70f86d22 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c @@ -26,189 +26,217 @@ * Authors: Jeff Hartmann <jhartmann@precisioninsight.com> * Keith Whitwell <keithw@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c,v 1.1 2000/02/11 17:26:08 dawes Exp $ + * $XFree86$ * */ #define __NO_VERSION__ #include "drmP.h" #include "mga_drv.h" -#include "mgareg_flags.h" -#include "mga_dma.h" -#include "mga_state.h" #include "drm.h" -void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box ) +static void mgaEmitClipRect( drm_mga_private_t *dev_priv, + drm_clip_rect_t *box ) { + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int *regs = sarea_priv->ContextState; PRIMLOCALS; + /* This takes 10 dwords */ PRIMGETPTR( dev_priv ); + + /* Force reset of dwgctl (eliminates clip disable) */ + PRIMOUTREG( MGAREG_DMAPAD, 0 ); + PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 ); + PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 ); + PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] ); - /* The G400 seems to have an issue with the second WARP not - * stalling clipper register writes. This bothers me, but the only - * way I could get it to never clip the last triangle under any - * circumstances is by inserting TWO dwgsync commands. - */ - if (dev_priv->chipset == MGA_CARD_TYPE_G400) { - PRIMOUTREG( MGAREG_DWGSYNC, 0 ); - PRIMOUTREG( MGAREG_DWGSYNC, 0 ); - } - + PRIMOUTREG( MGAREG_DMAPAD, 0 ); PRIMOUTREG( MGAREG_CXBNDRY, ((box->x2)<<16)|(box->x1) ); - PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride ); - PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride ); + PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride/2 ); + PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride/2 ); + PRIMADVANCE( dev_priv ); } - -static void mgaEmitContext(drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv) +static void mgaEmitContext(drm_mga_private_t *dev_priv ) { - unsigned int *regs = buf_priv->ContextState; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int *regs = sarea_priv->ContextState; PRIMLOCALS; + /* This takes a max of 15 dwords */ PRIMGETPTR( dev_priv ); + PRIMOUTREG( MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG] ); PRIMOUTREG( MGAREG_MACCESS, regs[MGA_CTXREG_MACCESS] ); PRIMOUTREG( MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT] ); PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] ); + PRIMOUTREG( MGAREG_ALPHACTRL, regs[MGA_CTXREG_ALPHACTRL] ); PRIMOUTREG( MGAREG_FOGCOL, regs[MGA_CTXREG_FOGCOLOR] ); PRIMOUTREG( MGAREG_WFLAG, regs[MGA_CTXREG_WFLAG] ); + PRIMOUTREG( MGAREG_ZORG, dev_priv->depthOffset ); /* invarient */ if (dev_priv->chipset == MGA_CARD_TYPE_G400) { PRIMOUTREG( MGAREG_WFLAG1, regs[MGA_CTXREG_WFLAG] ); PRIMOUTREG( MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0] ); PRIMOUTREG( MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1] ); - } + PRIMOUTREG( MGAREG_FCOL, regs[MGA_CTXREG_FCOL] ); + } else { + PRIMOUTREG( MGAREG_FCOL, regs[MGA_CTXREG_FCOL] ); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + } PRIMADVANCE( dev_priv ); } -static void mgaG200EmitTex( drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv ) +static void mgaG200EmitTex( drm_mga_private_t *dev_priv ) { - unsigned int *regs = buf_priv->TexState[0]; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int *regs = sarea_priv->TexState[0]; PRIMLOCALS; PRIMGETPTR( dev_priv ); + + /* This takes 20 dwords */ + PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] ); PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] ); PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] ); PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] ); + PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] ); PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] ); PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] ); PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] ); + PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] ); PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] ); - PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); - + PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); PRIMOUTREG(0x2d00 + 24*4, regs[MGA_TEXREG_WIDTH] ); + PRIMOUTREG(0x2d00 + 34*4, regs[MGA_TEXREG_HEIGHT] ); + PRIMOUTREG( MGAREG_TEXTRANS, 0xffff ); + PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff ); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); PRIMADVANCE( dev_priv ); } -static void mgaG400EmitTex0( drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv ) +static void mgaG400EmitTex0( drm_mga_private_t *dev_priv ) { - unsigned int *regs = buf_priv->TexState[0]; - int multitex = buf_priv->WarpPipe & MGA_T2; - + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int *regs = sarea_priv->TexState[0]; + int multitex = sarea_priv->WarpPipe & MGA_T2; PRIMLOCALS; + PRIMGETPTR( dev_priv ); + + /* This takes a max of 30 dwords */ PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] ); PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] ); PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] ); PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] ); + PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] ); PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] ); PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] ); PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] ); + PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] ); PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] ); - PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); - + PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); PRIMOUTREG(0x2d00 + 49*4, 0); + PRIMOUTREG(0x2d00 + 57*4, 0); PRIMOUTREG(0x2d00 + 53*4, 0); PRIMOUTREG(0x2d00 + 61*4, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); if (!multitex) { PRIMOUTREG(0x2d00 + 52*4, 0x40 ); PRIMOUTREG(0x2d00 + 60*4, 0x40 ); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); } - PRIMOUTREG(0x2d00 + 54*4, regs[MGA_TEXREG_WIDTH] | 0x40 ); - PRIMOUTREG(0x2d00 + 62*4, regs[MGA_TEXREG_HEIGHT] | 0x40 ); + PRIMOUTREG( 0x2d00 + 54*4, regs[MGA_TEXREG_WIDTH] | 0x40 ); + PRIMOUTREG( 0x2d00 + 62*4, regs[MGA_TEXREG_HEIGHT] | 0x40 ); + PRIMOUTREG( MGAREG_TEXTRANS, 0xffff ); + PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff ); PRIMADVANCE( dev_priv ); } #define TMC_map1_enable 0x80000000 - -static void mgaG400EmitTex1( drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv ) +static void mgaG400EmitTex1( drm_mga_private_t *dev_priv ) { - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->TexState[1]; - PRIMLOCALS; + PRIMGETPTR(dev_priv); + /* This takes 25 dwords */ PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | TMC_map1_enable); PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] ); PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] ); PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] ); + PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] ); PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] ); PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] ); PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] ); + PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] ); PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] ); - PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); - + PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); PRIMOUTREG(0x2d00 + 49*4, 0); + PRIMOUTREG(0x2d00 + 57*4, 0); PRIMOUTREG(0x2d00 + 53*4, 0); PRIMOUTREG(0x2d00 + 61*4, 0); - PRIMOUTREG(0x2d00 + 52*4, regs[MGA_TEXREG_WIDTH] | 0x40 ); - PRIMOUTREG(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 ); + PRIMOUTREG(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 ); + PRIMOUTREG( MGAREG_TEXTRANS, 0xffff ); + PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff ); PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] ); - PRIMADVANCE( dev_priv ); + PRIMADVANCE( dev_priv ); } - -static void mgaG400EmitPipe(drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv) +static void mgaG400EmitPipe(drm_mga_private_t *dev_priv ) { - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int pipe = sarea_priv->WarpPipe; float fParam = 12800.0f; PRIMLOCALS; PRIMGETPTR(dev_priv); - PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); + + /* This takes 25 dwords */ /* Establish vertex size. */ if (pipe & MGA_T2) { + PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09); PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000); + PRIMOUTREG(MGAREG_WFLAG, 0); } else { + PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807); PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x18000000); - } - - PRIMOUTREG(MGAREG_WFLAG, 0); - PRIMOUTREG(MGAREG_WFLAG1, 0); - + PRIMOUTREG(MGAREG_WFLAG, 0); + } + + PRIMOUTREG(MGAREG_WFLAG1, 0); PRIMOUTREG(0x2d00 + 56*4, *((u32 *)(&fParam))); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -227,19 +255,21 @@ static void mgaG400EmitPipe(drm_mga_private_t *dev_priv, PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_WIADDR2, (dev_priv->WarpIndex[pipe].phys_addr | - WIA_wmode_start | WIA_wagp_agp)); + PRIMOUTREG(MGAREG_WIADDR2, (__u32)(dev_priv->WarpIndex[pipe].phys_addr | + WIA_wmode_start | WIA_wagp_agp)); PRIMADVANCE(dev_priv); } -static void mgaG200EmitPipe( drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv ) +static void mgaG200EmitPipe( drm_mga_private_t *dev_priv ) { - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int pipe = sarea_priv->WarpPipe; PRIMLOCALS; PRIMGETPTR(dev_priv); + + /* This takes 15 dwords */ + PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend); PRIMOUTREG(MGAREG_WVRTXSZ, 7); PRIMOUTREG(MGAREG_WFLAG, 0); @@ -254,109 +284,629 @@ static void mgaG200EmitPipe( drm_mga_private_t *dev_priv, PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_WIADDR, (dev_priv->WarpIndex[pipe].phys_addr | - WIA_wmode_start | WIA_wagp_agp)); + PRIMOUTREG(MGAREG_WIADDR, (__u32)(dev_priv->WarpIndex[pipe].phys_addr | + WIA_wmode_start | WIA_wagp_agp)); PRIMADVANCE(dev_priv); } -void mgaEmitState( drm_mga_private_t *dev_priv, drm_mga_buf_priv_t *buf_priv ) +static void mgaEmitState( drm_mga_private_t *dev_priv ) { - unsigned int dirty = buf_priv->dirty; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int dirty = sarea_priv->dirty; if (dev_priv->chipset == MGA_CARD_TYPE_G400) { - if (dirty & MGASAREA_NEW_CONTEXT) - mgaEmitContext( dev_priv, buf_priv ); - - if (dirty & MGASAREA_NEW_TEX1) - mgaG400EmitTex1( dev_priv, buf_priv ); - - if (dirty & MGASAREA_NEW_TEX0) - mgaG400EmitTex0( dev_priv, buf_priv ); - - if (dirty & MGASAREA_NEW_PIPE) - mgaG400EmitPipe( dev_priv, buf_priv ); + int multitex = sarea_priv->WarpPipe & MGA_T2; + + if (sarea_priv->WarpPipe != dev_priv->WarpPipe) { + mgaG400EmitPipe( dev_priv ); + dev_priv->WarpPipe = sarea_priv->WarpPipe; + } + + if (dirty & MGA_UPLOAD_CTX) { + mgaEmitContext( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_CTX; + } + + if (dirty & MGA_UPLOAD_TEX0) { + mgaG400EmitTex0( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; + } + + if ((dirty & MGA_UPLOAD_TEX1) && multitex) { + mgaG400EmitTex1( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_TEX1; + } } else { - if (dirty & MGASAREA_NEW_CONTEXT) - mgaEmitContext( dev_priv, buf_priv ); - - if (dirty & MGASAREA_NEW_TEX0) - mgaG200EmitTex( dev_priv, buf_priv ); - - if (dirty & MGASAREA_NEW_PIPE) - mgaG200EmitPipe( dev_priv, buf_priv ); - } + if (sarea_priv->WarpPipe != dev_priv->WarpPipe) { + mgaG200EmitPipe( dev_priv ); + dev_priv->WarpPipe = sarea_priv->WarpPipe; + } + + if (dirty & MGA_UPLOAD_CTX) { + mgaEmitContext( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_CTX; + } + + if (dirty & MGA_UPLOAD_TEX0) { + mgaG200EmitTex( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; + } + } } - /* Disallow all write destinations except the front and backbuffer. */ -static int mgaCopyContext(drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv) +static int mgaVerifyContext(drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; - - if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOrg && - regs[MGA_CTXREG_DSTORG] != dev_priv->backOrg) + + if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset && + regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) { + DRM_DEBUG("BAD DSTORG: %x (front %x, back %x)\n\n", + regs[MGA_CTXREG_DSTORG], dev_priv->frontOffset, + dev_priv->backOffset); + regs[MGA_CTXREG_DSTORG] = 0; return -1; + } - memcpy(buf_priv->ContextState, sarea_priv->ContextState, - sizeof(buf_priv->ContextState)); return 0; } - /* Disallow texture reads from PCI space. */ -static int mgaCopyTex(drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv, +static int mgaVerifyTex(drm_mga_private_t *dev_priv, int unit) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) + if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) { + DRM_DEBUG("BAD TEXREG_ORG: %x, unit %d\n", + sarea_priv->TexState[unit][MGA_TEXREG_ORG], + unit); + sarea_priv->TexState[unit][MGA_TEXREG_ORG] = 0; return -1; - - memcpy(buf_priv->TexState[unit], sarea_priv->TexState[unit], - sizeof(buf_priv->TexState[0])); + } return 0; } - -int mgaCopyAndVerifyState( drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv ) +static int mgaVerifyState( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty ; + unsigned int dirty = sarea_priv->dirty; int rv = 0; - buf_priv->dirty = sarea_priv->dirty; - buf_priv->WarpPipe = sarea_priv->WarpPipe; + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) + sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - if (dirty & MGASAREA_NEW_CONTEXT) - rv |= mgaCopyContext( dev_priv, buf_priv ); + if (dirty & MGA_UPLOAD_CTX) + rv |= mgaVerifyContext( dev_priv ); - if (dirty & MGASAREA_NEW_TEX0) - rv |= mgaCopyTex( dev_priv, buf_priv, 0 ); + if (dirty & MGA_UPLOAD_TEX0) + rv |= mgaVerifyTex( dev_priv, 0 ); if (dev_priv->chipset == MGA_CARD_TYPE_G400) { - if (dirty & MGASAREA_NEW_TEX1) - rv |= mgaCopyTex( dev_priv, buf_priv, 1 ); + if (dirty & MGA_UPLOAD_TEX1) + rv |= mgaVerifyTex( dev_priv, 1 ); - if (dirty & MGASAREA_NEW_PIPE) - rv |= (buf_priv->WarpPipe > MGA_MAX_G400_PIPES); + if (dirty & MGA_UPLOAD_PIPE) + rv |= (sarea_priv->WarpPipe > MGA_MAX_G400_PIPES); } else { - if (dirty & MGASAREA_NEW_PIPE) - rv |= (buf_priv->WarpPipe > MGA_MAX_G200_PIPES); + if (dirty & MGA_UPLOAD_PIPE) + rv |= (sarea_priv->WarpPipe > MGA_MAX_G200_PIPES); } return rv == 0; } +static int mgaVerifyIload( drm_mga_private_t *dev_priv, + unsigned long bus_address, + unsigned int dstOrg, int length ) +{ + if(dstOrg < dev_priv->textureOffset || + dstOrg + length > + (dev_priv->textureOffset + dev_priv->textureSize)) { + return -EINVAL; + } + if(length % 64) { + return -EINVAL; + } + return 0; +} + +/* This copies a 64 byte aligned agp region to the frambuffer + * with a standard blit, the ioctl needs to do checking */ + +static void mga_dma_dispatch_tex_blit( drm_device_t *dev, + unsigned long bus_address, + int length, + unsigned int destOrg ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + int use_agp = PDEA_pagpxfer_enable | 0x00000001; + u16 y2; + PRIMLOCALS; + + y2 = length / 64; + + PRIM_OVERFLOW(dev, dev_priv, 30); + PRIMGETPTR( dev_priv ); + + dev_priv->last_sync_tag = mga_create_sync_tag(dev); + + PRIMOUTREG( MGAREG_DSTORG, destOrg); + PRIMOUTREG( MGAREG_MACCESS, 0x00000000); + DRM_DEBUG("srcorg : %lx\n", bus_address | use_agp); + PRIMOUTREG( MGAREG_SRCORG, (u32) bus_address | use_agp); + PRIMOUTREG( MGAREG_AR5, 64); + + PRIMOUTREG( MGAREG_PITCH, 64); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DWGCTL, MGA_COPY_CMD); + + PRIMOUTREG(MGAREG_AR0, 63); + PRIMOUTREG(MGAREG_AR3, 0); + PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16)); + PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, y2); + + PRIMOUTREG( MGAREG_SRCORG, 0); + PRIMOUTREG( MGAREG_PITCH, dev_priv->stride / dev_priv->cpp); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag); + PRIMADVANCE(dev_priv); +} + +static void mga_dma_dispatch_vertex(drm_device_t *dev, + drm_buf_t *buf) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_buf_priv_t *buf_priv = buf->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned long address = (unsigned long)buf->bus_address; + int length = buf->used; + int use_agp = PDEA_pagpxfer_enable; + int i = 0; + int primary_needed; + PRIMLOCALS; + + DRM_DEBUG("dispatch vertex %d addr 0x%lx, " + "length 0x%x nbox %d dirty %x\n", + buf->idx, address, length, + sarea_priv->nbox, sarea_priv->dirty); + + + dev_priv->last_sync_tag = mga_create_sync_tag(dev); + + if (buf_priv->discard) { + buf_priv->my_freelist->age = dev_priv->last_sync_tag; + mga_freelist_put(dev, buf); + } + + + /* WARNING: if you change any of the state functions verify + * these numbers (Overestimating this doesn't hurt). + */ + primary_needed = (25+15+30+25+ + 10 + + 15 * MGA_NR_SAREA_CLIPRECTS); + + + PRIM_OVERFLOW(dev, dev_priv, primary_needed); + mgaEmitState( dev_priv ); + + if (buf->used) { + do { + if (i < sarea_priv->nbox) { + DRM_DEBUG("idx %d Emit box %d/%d:" + "%d,%d - %d,%d\n", + buf->idx, + i, sarea_priv->nbox, + sarea_priv->boxes[i].x1, + sarea_priv->boxes[i].y1, + sarea_priv->boxes[i].x2, + sarea_priv->boxes[i].y2); + + mgaEmitClipRect( dev_priv, + &sarea_priv->boxes[i] ); + } + + PRIMGETPTR(dev_priv); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_SECADDRESS, + ((__u32)address) | TT_VERTEX); + PRIMOUTREG( MGAREG_SECEND, + (((__u32)(address + length)) | + use_agp)); + PRIMADVANCE( dev_priv ); + } while (++i < sarea_priv->nbox); + } + + PRIMGETPTR( dev_priv ); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag); + PRIMADVANCE( dev_priv ); +} + +static void mga_dma_dispatch_clear( drm_device_t *dev, int flags, + unsigned int clear_color, + unsigned int clear_zval ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int *regs = sarea_priv->ContextState; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + unsigned int cmd; + int i; + int primary_needed; + PRIMLOCALS; + + if ( dev_priv->sgram ) + cmd = MGA_CLEAR_CMD | DC_atype_blk; + else + cmd = MGA_CLEAR_CMD | DC_atype_rstr; + + primary_needed = nbox * 70; + if(primary_needed == 0) primary_needed = 70; + PRIM_OVERFLOW(dev, dev_priv, primary_needed); + PRIMGETPTR( dev_priv ); + dev_priv->last_sync_tag = mga_create_sync_tag(dev); + + for (i = 0 ; i < nbox ; i++) { + unsigned int height = pbox[i].y2 - pbox[i].y1; + + DRM_DEBUG("dispatch clear %d,%d-%d,%d flags %x!\n", + pbox[i].x1, pbox[i].y1, pbox[i].x2, + pbox[i].y2, flags); + + if ( flags & MGA_FRONT ) { + DRM_DEBUG("clear front\n"); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); + PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); + + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_FCOL, clear_color); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset); + PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); + } + + if ( flags & MGA_BACK ) { + DRM_DEBUG("clear back\n"); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); + PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); + + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_FCOL, clear_color); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset); + PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); + } + + if ( flags & MGA_DEPTH ) { + DRM_DEBUG("clear depth\n"); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); + PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); + + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_FCOL, clear_zval); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->depthOffset); + PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); + } + } + + /* Force reset of DWGCTL */ + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] ); + + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag); + PRIMADVANCE(dev_priv); +} + +static void mga_dma_dispatch_swap( drm_device_t *dev ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int *regs = sarea_priv->ContextState; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int i; + int primary_needed; + PRIMLOCALS; + + primary_needed = nbox * 5; + primary_needed += 60; + PRIM_OVERFLOW(dev, dev_priv, primary_needed); + PRIMGETPTR( dev_priv ); + + dev_priv->last_sync_tag = mga_create_sync_tag(dev); + + PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset); + PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess); + PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset); + PRIMOUTREG(MGAREG_AR5, dev_priv->stride/2); + + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD); + + for (i = 0 ; i < nbox; i++) { + unsigned int h = pbox[i].y2 - pbox[i].y1; + unsigned int start = pbox[i].y1 * dev_priv->stride/2; + + DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", + pbox[i].x1, pbox[i].y1, + pbox[i].x2, pbox[i].y2); + + PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1); + PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1); + PRIMOUTREG(MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16)); + PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h); + } + + /* Force reset of DWGCTL */ + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] ); + + PRIMOUTREG( MGAREG_SRCORG, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag); + PRIMADVANCE(dev_priv); +} + +int mga_clear_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + drm_mga_clear_t clear; + + copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, sizeof(clear), + -EFAULT); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_clear_bufs called without lock held\n"); + return -EINVAL; + } + + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) + sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX; + mga_dma_dispatch_clear( dev, clear.flags, + clear.clear_color, + clear.clear_depth ); + PRIMUPDATE(dev_priv); + mga_dma_schedule(dev, 1); + sarea_priv->last_dispatch = status[1]; + return 0; +} + +int mga_swap_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_swap_bufs called without lock held\n"); + return -EINVAL; + } + + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) + sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX; + mga_dma_dispatch_swap( dev ); + PRIMUPDATE(dev_priv); + set_bit(0, &dev_priv->current_prim->swap_pending); + dev_priv->current_prim->swap_pending = 1; + mga_dma_schedule(dev, 1); + sarea_priv->last_dispatch = status[1]; + return 0; +} + +int mga_iload(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + drm_buf_t *buf; + drm_mga_buf_priv_t *buf_priv; + drm_mga_iload_t iload; + unsigned long bus_address; + + DRM_DEBUG("Starting Iload\n"); + copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload), + -EFAULT); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_iload called without lock held\n"); + return -EINVAL; + } + + buf = dma->buflist[ iload.idx ]; + buf_priv = buf->dev_private; + bus_address = buf->bus_address; + DRM_DEBUG("bus_address %lx, length %d, destorg : %x\n", + bus_address, iload.length, iload.destOrg); + + if(mgaVerifyIload(dev_priv, + bus_address, + iload.destOrg, + iload.length)) { + mga_freelist_put(dev, buf); + return -EINVAL; + } + + sarea_priv->dirty |= MGA_UPLOAD_CTX; + + mga_dma_dispatch_tex_blit(dev, bus_address, iload.length, + iload.destOrg); + buf_priv->my_freelist->age = dev_priv->last_sync_tag; + buf_priv->discard = 1; + mga_freelist_put(dev, buf); + mga_dma_schedule(dev, 1); + sarea_priv->last_dispatch = status[1]; + return 0; +} + +int mga_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_mga_buf_priv_t *buf_priv; + drm_mga_vertex_t vertex; + + copy_from_user_ret(&vertex, (drm_mga_vertex_t *)arg, sizeof(vertex), + -EFAULT); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_vertex called without lock held\n"); + return -EINVAL; + } + + DRM_DEBUG("mga_vertex\n"); + + buf = dma->buflist[ vertex.idx ]; + buf_priv = buf->dev_private; + + buf->used = vertex.used; + buf_priv->discard = vertex.discard; + + if (!mgaVerifyState(dev_priv)) { + if (vertex.discard) { + buf_priv->my_freelist->age = dev_priv->last_sync_tag; + mga_freelist_put(dev, buf); + } + return -EINVAL; + } + + mga_dma_dispatch_vertex(dev, buf); + + PRIMUPDATE(dev_priv); + mga_dma_schedule(dev, 1); + sarea_priv->last_dispatch = status[1]; + return 0; +} + +static int mga_dma_get_buffers(drm_device_t *dev, drm_dma_t *d) +{ + int i; + drm_buf_t *buf; + + for (i = d->granted_count; i < d->request_count; i++) { + buf = mga_freelist_get(dev); + if (!buf) break; + buf->pid = current->pid; + copy_to_user_ret(&d->request_indices[i], + &buf->idx, + sizeof(buf->idx), + -EFAULT); + copy_to_user_ret(&d->request_sizes[i], + &buf->total, + sizeof(buf->total), + -EFAULT); + ++d->granted_count; + } + return 0; +} + +int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + int retcode = 0; + drm_dma_t d; + + copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); + DRM_DEBUG("%d %d: %d send, %d req\n", + current->pid, d.context, d.send_count, d.request_count); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_dma called without lock held\n"); + return -EINVAL; + } + + /* Please don't send us buffers. + */ + if (d.send_count != 0) { + DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", + current->pid, d.send_count); + return -EINVAL; + } + + /* We'll send you buffers. + */ + if (d.request_count < 0 || d.request_count > dma->buf_count) { + DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", + current->pid, d.request_count, dma->buf_count); + return -EINVAL; + } + + d.granted_count = 0; + + if (d.request_count) { + retcode = mga_dma_get_buffers(dev, &d); + } + + DRM_DEBUG("%d returning, granted = %d\n", + current->pid, d.granted_count); + copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT); + sarea_priv->last_dispatch = status[1]; + return retcode; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.h deleted file mode 100644 index e7b952e0c..000000000 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MGA_STATE_H -#define MGA_STATE_H - -#include "mga_drv.h" - -int mgaCopyAndVerifyState( drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv ); - -void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box ); - -void mgaEmitState( drm_mga_private_t *dev_priv, drm_mga_buf_priv_t *buf_priv ); - -#endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mgareg_flags.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mgareg_flags.h deleted file mode 100644 index 901f18310..000000000 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mgareg_flags.h +++ /dev/null @@ -1,930 +0,0 @@ -/* author: stephen crowley, crow@debian.org */ - -/* - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * STEPHEN CROWLEY, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _MGAREGS_H_ -#define _MGAREGS_H_ - -/*************** (START) AUTOMATICLY GENERATED REGISTER FILE *****************/ -/* - * Generated on Sat Nov 20 21:25:36 CST 1999 - */ - - - -/* - * Power Graphic Mode Memory Space Registers - */ - - #define AGP_PLL_agp2xpllen_MASK 0xfffffffe /* bit 0 */ - #define AGP_PLL_agp2xpllen_disable 0x0 - #define AGP_PLL_agp2xpllen_enable 0x1 - - #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 AR0_ar0_MASK 0xfffc0000 /* bits 0-17 */ - #define AR0_ar0_SHIFT 0 - - #define AR1_ar1_MASK 0xff000000 /* bits 0-23 */ - #define AR1_ar1_SHIFT 0 - - #define AR2_ar2_MASK 0xfffc0000 /* bits 0-17 */ - #define AR2_ar2_SHIFT 0 - - #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 AR4_ar4_MASK 0xfffc0000 /* bits 0-17 */ - #define AR4_ar4_SHIFT 0 - - #define AR5_ar5_MASK 0xfffc0000 /* bits 0-17 */ - #define AR5_ar5_SHIFT 0 - - #define AR6_ar6_MASK 0xfffc0000 /* bits 0-17 */ - #define AR6_ar6_SHIFT 0 - - #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 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 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 BHISF_beshiscal_MASK 0xffe00003 /* bits 2-20 */ - #define BHISF_beshiscal_SHIFT 2 - - #define BHSE_beshsrcend_MASK 0xfc000003 /* bits 2-25 */ - #define BHSE_beshsrcend_SHIFT 2 - - #define BHSL_beshsrclst_MASK 0xfc00ffff /* bits 16-25 */ - #define BHSL_beshsrclst_SHIFT 16 - - #define BHSS_beshsrcst_MASK 0xfc000003 /* bits 2-25 */ - #define BHSS_beshsrcst_SHIFT 2 - - #define BP_bespitch_MASK 0xfffff000 /* bits 0-11 */ - #define BP_bespitch_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 BSF_besv1srclast_MASK 0xfffffc00 /* bits 0-9 */ - #define BSF_besv1srclast_SHIFT 0 - - #define BSF_besv2srclst_MASK 0xfffffc00 /* bits 0-9 */ - #define BSF_besv2srclst_SHIFT 0 - - #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_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 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 BVISF_besviscal_MASK 0xffe00003 /* bits 2-20 */ - #define BVISF_besviscal_SHIFT 2 - - #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 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 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 DS_dwgsyncaddr_MASK 0x3 /* bits 2-31 */ - #define DS_dwgsyncaddr_SHIFT 2 - - #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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 SETDCA_setupmod_MASK 0xfffffffc /* bits 0-1 */ - #define SETDCA_setupmod_vertlist 0x0 /* val 0, shift 0 */ - #define SETDCA_setupaddress_MASK 0x3 /* bits 2-31 */ - #define SETDCA_setupaddress_SHIFT 2 - - #define SETDEA_setupagpxfer_MASK 0xfffffffd /* bit 1 */ - #define SETDEA_setupagpxfer_disable 0x0 - #define SETDEA_setupagpxfer_enable 0x2 - #define SETDEA_setupend_MASK 0x3 /* bits 2-31 */ - #define SETDEA_setupend_SHIFT 2 - - #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 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 STH_softraphand_MASK 0x3 /* bits 2-31 */ - #define STH_softraphand_SHIFT 2 - - #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 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 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 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 TD1_color1arg2selMASK 0xfffffffc /* bits 0-1 */ - #define TD1_color1alphaselMASK 0xffffffe3 /* bits 2-4 */ - #define TD1_color1alphaselSHIFT 2 - #define TD1_color1arg1alphaMASK 0xffffffdf /* bit 5 */ - #define TD1_color1arg1alphadisable 0x0 - #define TD1_color1arg1alphaenable 0x20 - #define TD1_color1arg1invMASK 0xffffffbf /* bit 6 */ - #define TD1_color1arg1invdisable 0x0 - #define TD1_color1arg1invenable 0x40 - #define TD1_color1arg2alphaMASK 0xffffff7f /* bit 7 */ - #define TD1_color1arg2alphadisable 0x0 - #define TD1_color1arg2alphaenable 0x80 - #define TD1_color1arg2invMASK 0xfffffeff /* bit 8 */ - #define TD1_color1arg2invdisable 0x0 - #define TD1_color1arg2invenable 0x100 - #define TD1_color1alpha1invMASK 0xfffffdff /* bit 9 */ - #define TD1_color1alpha1invdisable 0x0 - #define TD1_color1alpha1invenable 0x200 - #define TD1_color1alpha2invMASK 0xfffffbff /* bit 10 */ - #define TD1_color1alpha2invdisable 0x0 - #define TD1_color1alpha2invenable 0x400 - #define TD1_color1selMASK 0xff9fffff /* bits 21-22 */ - #define TD1_color1selarg1 0x0 /* val 0, shift 21 */ - #define TD1_color1selarg2 0x200000 /* val 1, shift 21 */ - #define TD1_color1seladd 0x400000 /* val 2, shift 21 */ - #define TD1_color1selmul 0x600000 /* val 3, shift 21 */ - #define TD1_alpha1selMASK 0x3fffffff /* bits 30-31 */ - #define TD1_alpha1selarg1 0x0 /* val 0, shift 30 */ - #define TD1_alpha1selarg2 0x40000000 /* val 1, shift 30 */ - #define TD1_alpha1seladd 0x80000000 /* val 2, shift 30 */ - #define TD1_alpha1selmul 0xc0000000 /* val 3, shift 30 */ - - #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 TMC_tformat_MASK 0xfffffff0 /* bits 0-3 */ - #define TMC_tformat_tw4 0x0 /* val 0, shift 0 */ - #define TMC_tformat_tw8 0x1 /* val 1, shift 0 */ - #define TMC_tformat_tw15 0x2 /* val 2, shift 0 */ - #define TMC_tformat_tw16 0x3 /* val 3, shift 0 */ - #define TMC_tformat_tw12 0x4 /* val 4, shift 0 */ - #define TMC_tformat_tw32 0x6 /* val 6, shift 0 */ - #define TMC_tformat_tw422 0xa /* val 10, shift 0 */ - #define TMC_tpitchlin_MASK 0xfffffeff /* bit 8 */ - #define TMC_tpitchlin_disable 0x0 - #define TMC_tpitchlin_enable 0x100 - #define TMC_tpitchext_MASK 0xfff001ff /* bits 9-19 */ - #define TMC_tpitchext_SHIFT 9 - #define TMC_tpitch_MASK 0xfff8ffff /* bits 16-18 */ - #define TMC_tpitch_SHIFT 16 - #define TMC_owalpha_MASK 0xffbfffff /* bit 22 */ - #define TMC_owalpha_disable 0x0 - #define TMC_owalpha_enable 0x400000 - #define TMC_azeroextend_MASK 0xff7fffff /* bit 23 */ - #define TMC_azeroextend_disable 0x0 - #define TMC_azeroextend_enable 0x800000 - #define TMC_decalckey_MASK 0xfeffffff /* bit 24 */ - #define TMC_decalckey_disable 0x0 - #define TMC_decalckey_enable 0x1000000 - #define TMC_takey_MASK 0xfdffffff /* bit 25 */ - #define TMC_takey_0 0x0 - #define TMC_takey_1 0x2000000 - #define TMC_tamask_MASK 0xfbffffff /* bit 26 */ - #define TMC_tamask_0 0x0 - #define TMC_tamask_1 0x4000000 - #define TMC_clampv_MASK 0xf7ffffff /* bit 27 */ - #define TMC_clampv_disable 0x0 - #define TMC_clampv_enable 0x8000000 - #define TMC_clampu_MASK 0xefffffff /* bit 28 */ - #define TMC_clampu_disable 0x0 - #define TMC_clampu_enable 0x10000000 - #define TMC_tmodulate_MASK 0xdfffffff /* bit 29 */ - #define TMC_tmodulate_disable 0x0 - #define TMC_tmodulate_enable 0x20000000 - #define TMC_strans_MASK 0xbfffffff /* bit 30 */ - #define TMC_strans_disable 0x0 - #define TMC_strans_enable 0x40000000 - #define TMC_itrans_MASK 0x7fffffff /* bit 31 */ - #define TMC_itrans_disable 0x0 - #define TMC_itrans_enable 0x80000000 - - #define 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 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 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 TO_texorgmap_MASK 0xfffffffe /* bit 0 */ - #define TO_texorgmap_fb 0x0 - #define TO_texorgmap_sys 0x1 - #define TO_texorgacc_MASK 0xfffffffd /* bit 1 */ - #define TO_texorgacc_pci 0x0 - #define TO_texorgacc_agp 0x2 - #define TO_texorg_MASK 0x1f /* bits 5-31 */ - #define TO_texorg_SHIFT 5 - - #define 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_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 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 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 WMA_wcodeaddr_MASK 0xff /* bits 8-31 */ - #define WMA_wcodeaddr_SHIFT 8 - - #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 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 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 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 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 WIMA_wimemaddr_MASK 0xffffff00 /* bits 0-7 */ - #define WIMA_wimemaddr_SHIFT 0 - - #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 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 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 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 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 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 ZO_zorgmap_MASK 0xfffffffe /* bit 0 */ - #define ZO_zorgmap_fb 0x0 - #define ZO_zorgmap_sys 0x1 - #define ZO_zorgacc_MASK 0xfffffffd /* bit 1 */ - #define ZO_zorgacc_pci 0x0 - #define ZO_zorgacc_agp 0x2 - #define ZO_zorg_MASK 0x3 /* bits 2-31 */ - #define ZO_zorg_SHIFT 2 - - - - -/**************** (END) AUTOMATICLY GENERATED REGISTER FILE ******************/ - -#endif /* _MGAREGS_H_ */ - diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c index ecdb2c15a..0bd8bfd57 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c @@ -9,6 +9,16 @@ #define CONFIG_MODVERSIONS 0 #endif +#ifndef CONFIG_AGP_MODULE +#define CONFIG_AGP_MODULE 0 +#endif + +#ifndef CONFIG_AGP +#define CONFIG_AGP 0 +#endif + SMP = CONFIG_SMP MODVERSIONS = CONFIG_MODVERSIONS +AGP = CONFIG_AGP +AGP_MODULE = CONFIG_AGP_MODULE RELEASE = UTS_RELEASE diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c index 54aba58c4..db98fd6a4 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c @@ -164,7 +164,10 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len, { drm_device_t *dev = (drm_device_t *)data; drm_map_t *map; - const char *types[] = { "FB", "REG", "SHM" }; + /* Hardcoded from _DRM_FRAME_BUFFER, + _DRM_REGISTERS, _DRM_SHM, and + _DRM_AGP. */ + const char *types[] = { "FB", "REG", "SHM", "AGP" }; const char *type; int i; @@ -175,7 +178,7 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len, "address mtrr\n\n"); for (i = 0; i < dev->map_count; i++) { map = dev->maplist[i]; - if (map->type < 0 || map->type > 2) type = "??"; + if (map->type < 0 || map->type > 3) type = "??"; else type = types[map->type]; DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", i, diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_context.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_context.c index 842d6f5d5..74b107bd2 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_context.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_context.c @@ -38,9 +38,7 @@ extern drm_ctx_t tdfx_res_ctx; static int tdfx_alloc_queue(drm_device_t *dev) { - static int context = 0; - - return ++context; /* Should this reuse contexts in the future? */ + return drm_ctxbitmap_next(dev); } int tdfx_context_switch(drm_device_t *dev, int old, int new) @@ -137,6 +135,12 @@ int tdfx_addctx(struct inode *inode, struct file *filp, unsigned int cmd, ctx.handle = tdfx_alloc_queue(dev); } DRM_DEBUG("%d\n", ctx.handle); + if (ctx.handle == -1) { + DRM_DEBUG("Not enough free contexts.\n"); + /* Should this return -EBUSY instead? */ + return -ENOMEM; + } + copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT); return 0; } @@ -193,13 +197,13 @@ int tdfx_newctx(struct inode *inode, struct file *filp, unsigned int cmd, int tdfx_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_ctx_t ctx; copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); DRM_DEBUG("%d\n", ctx.handle); - /* This is currently a noop because we - don't reuse context values. Perhaps we - should? */ - + drm_ctxbitmap_free(dev, ctx.handle); + return 0; } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c index 57c1c719d..fb7a997b4 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c @@ -85,6 +85,16 @@ static drm_ioctl_desc_t tdfx_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { tdfx_lock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { tdfx_unlock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, +#ifdef DRM_AGP + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_unbind, 1, 1}, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_bind, 1, 1}, +#endif }; #define TDFX_IOCTL_COUNT DRM_ARRAY_SIZE(tdfx_ioctls) @@ -228,7 +238,24 @@ static int tdfx_takedown(drm_device_t *dev) } dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } - +#ifdef DRM_AGP + /* Clear AGP information */ + if (dev->agp) { + drm_agp_mem_t *temp; + drm_agp_mem_t *temp_next; + + temp = dev->agp->memory; + while(temp != NULL) { + temp_next = temp->next; + drm_free_agp(temp->memory, temp->pages); + drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); + temp = temp_next; + } + if(dev->agp->acquired) (*drm_agp.release)(); + drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); + dev->agp = NULL; + } +#endif /* Clear vma list (only built for debugging) */ if (dev->vmalist) { for (vma = dev->vmalist; vma; vma = vma_next) { @@ -262,6 +289,10 @@ static int tdfx_takedown(drm_device_t *dev) - PAGE_SHIFT, DRM_MEM_SAREA); break; + case _DRM_AGP: + /* Do nothing here, because this is all + handled in the AGP/GART driver. */ + break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); } @@ -309,6 +340,16 @@ int tdfx_init(void) drm_mem_init(); drm_proc_init(dev); +#ifdef DRM_AGP + dev->agp = drm_agp_init(); +#endif + if((retcode = drm_ctxbitmap_init(dev))) { + DRM_ERROR("Cannot allocate memory for context bitmap.\n"); + drm_proc_cleanup(); + misc_deregister(&tdfx_misc); + tdfx_takedown(dev); + return retcode; + } DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", TDFX_NAME, @@ -335,6 +376,7 @@ void tdfx_cleanup(void) } else { DRM_INFO("Module unloaded\n"); } + drm_ctxbitmap_cleanup(dev); tdfx_takedown(dev); } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c index 85470ac52..389f2faee 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c @@ -250,9 +250,10 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) switch (map->type) { case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: + case _DRM_AGP: if (VM_OFFSET(vma) >= __pa(high_memory)) { #if defined(__i386__) - if (boot_cpu_data.x86 > 3) { + if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) { pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c index 3b0f98acd..8b97c7da9 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c @@ -418,7 +418,8 @@ int drmAddMap(int fd, return 0; } -int drmAddBufs(int fd, int count, int size, int flags) +int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, + int agp_offset) { drm_buf_desc_t request; @@ -427,6 +428,8 @@ int drmAddBufs(int fd, int count, int size, int flags) request.low_mark = 0; request.high_mark = 0; request.flags = flags; + request.agp_start = agp_offset; + if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno; return request.count; } @@ -744,6 +747,143 @@ int drmDestroyDrawable(int fd, drmDrawable handle) return 0; } +int drmAgpAcquire(int fd) +{ + if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno; + return 0; +} + +int drmAgpRelease(int fd) +{ + if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno; + return 0; +} + +int drmAgpEnable(int fd, unsigned long mode) +{ + drm_agp_mode_t m; + + m.mode = mode; + if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) return -errno; + return 0; +} + +int drmAgpAlloc(int fd, unsigned long size, unsigned long type, + unsigned long *address, unsigned long *handle) +{ + drm_agp_buffer_t b; + *handle = 0; + b.size = size; + b.handle = 0; + b.type = type; + if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) return -errno; + if (address != 0UL) *address = b.physical; + *handle = b.handle; + return 0; +} + +int drmAgpFree(int fd, unsigned long handle) +{ + drm_agp_buffer_t b; + + b.size = 0; + b.handle = handle; + if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b)) return -errno; + return 0; +} + +int drmAgpBind(int fd, unsigned long handle, unsigned long offset) +{ + drm_agp_binding_t b; + + b.handle = handle; + b.offset = offset; + if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b)) return -errno; + return 0; +} + +int drmAgpUnbind(int fd, unsigned long handle) +{ + drm_agp_binding_t b; + + b.handle = handle; + b.offset = 0; + if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) return -errno; + return 0; +} + +int drmAgpVersionMajor(int fd) +{ + drm_agp_info_t i; + + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; + return i.agp_version_major; +} + +int drmAgpVersionMinor(int fd) +{ + drm_agp_info_t i; + + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; + return i.agp_version_minor; +} + +unsigned long drmAgpGetMode(int fd) +{ + drm_agp_info_t i; + + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; + return i.mode; +} + +unsigned long drmAgpBase(int fd) +{ + drm_agp_info_t i; + + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; + return i.aperture_base; +} + +unsigned long drmAgpSize(int fd) +{ + drm_agp_info_t i; + + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; + return i.aperture_size; +} + +unsigned long drmAgpMemoryUsed(int fd) +{ + drm_agp_info_t i; + + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; + return i.memory_used; +} + +unsigned long drmAgpMemoryAvail(int fd) +{ + drm_agp_info_t i; + + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; + return i.memory_allowed; +} + +unsigned int drmAgpVendorId(int fd) +{ + drm_agp_info_t i; + + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; + return i.id_vendor; +} + +unsigned int drmAgpDeviceId(int fd) +{ + drm_agp_info_t i; + + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; + return i.id_device; +} + int drmError(int err, const char *label) { switch (err) { diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c new file mode 100644 index 000000000..a7b95fbf0 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c @@ -0,0 +1,81 @@ +#ifdef XFree86Server +# include "xf86.h" +# include "xf86_OSproc.h" +# include "xf86_ansic.h" +# include "xf86Priv.h" +# define _DRM_MALLOC xalloc +# define _DRM_FREE xfree +# ifndef XFree86LOADER +# include <sys/stat.h> +# include <sys/mman.h> +# endif +#else +# include <stdio.h> +# include <stdlib.h> +# include <unistd.h> +# include <string.h> +# include <ctype.h> +# include <fcntl.h> +# include <errno.h> +# include <signal.h> +# include <sys/types.h> +# include <sys/stat.h> +# include <sys/ioctl.h> +# include <sys/mman.h> +# include <sys/time.h> +# ifdef DRM_USE_MALLOC +# define _DRM_MALLOC malloc +# define _DRM_FREE free +extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *); +extern int xf86RemoveSIGIOHandler(int fd); +# else +# include <Xlibint.h> +# define _DRM_MALLOC Xmalloc +# define _DRM_FREE Xfree +# endif +#endif + +/* Not all systems have MAP_FAILED defined */ +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +#include <sys/sysmacros.h> /* for makedev() */ +#include "xf86drm.h" +#include "xf86drmI810.h" +#include "drm.h" + +Bool drmI810CleanupDma(int driSubFD) +{ + drm_i810_init_t init; + + memset(&init, 0, sizeof(drm_i810_init_t)); + init.func = I810_CLEANUP_DMA; + + if(ioctl(driSubFD, DRM_IOCTL_I810_INIT, &init)) { + return FALSE; + } + + return TRUE; +} + +Bool drmI810InitDma(int driSubFD, unsigned long start, unsigned long end, + unsigned long size, int ring_map_idx, int buffer_map_idx, + int sarea_off) +{ + drm_i810_init_t init; + + memset(&init, 0, sizeof(drm_i810_init_t)); + init.func = I810_INIT_DMA; + init.ring_map_idx = ring_map_idx; + init.buffer_map_idx = buffer_map_idx; + init.ring_start = start; + init.ring_end = end; + init.ring_size = size; + init.sarea_priv_offset = sarea_off; + + if(ioctl(driSubFD, DRM_IOCTL_I810_INIT, &init)) { + return FALSE; + } + return TRUE; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c new file mode 100644 index 000000000..5957ffe33 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c @@ -0,0 +1,117 @@ +#ifdef XFree86Server +# include "xf86.h" +# include "xf86_OSproc.h" +# include "xf86_ansic.h" +# include "xf86Priv.h" +# define _DRM_MALLOC xalloc +# define _DRM_FREE xfree +# ifndef XFree86LOADER +# include <sys/stat.h> +# include <sys/mman.h> +# endif +#else +# include <stdio.h> +# include <stdlib.h> +# include <unistd.h> +# include <string.h> +# include <ctype.h> +# include <fcntl.h> +# include <errno.h> +# include <signal.h> +# include <sys/types.h> +# include <sys/stat.h> +# include <sys/ioctl.h> +# include <sys/mman.h> +# include <sys/time.h> +# ifdef DRM_USE_MALLOC +# define _DRM_MALLOC malloc +# define _DRM_FREE free +extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *); +extern int xf86RemoveSIGIOHandler(int fd); +# else +# include <Xlibint.h> +# define _DRM_MALLOC Xmalloc +# define _DRM_FREE Xfree +# endif +#endif + +/* Not all systems have MAP_FAILED defined */ +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +#include <sys/sysmacros.h> /* for makedev() */ +#include "xf86drm.h" +#include "xf86drmMga.h" +#include "drm.h" + +Bool drmMgaCleanupDma(int driSubFD) +{ + drm_mga_init_t init; + memset(&init, 0, sizeof(drm_mga_init_t)); + init.func = MGA_CLEANUP_DMA; + if(ioctl(driSubFD, DRM_IOCTL_MGA_INIT, &init)) { + return FALSE; + } + + return TRUE; +} + +Bool drmMgaLockUpdate(int driSubFD, drmLockFlags flags) +{ + drm_lock_t lock; + + memset(&lock, 0, sizeof(drm_lock_t)); + + 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; + + if(ioctl(driSubFD, DRM_IOCTL_MGA_FLUSH, &lock)) { + return FALSE; + } + + return TRUE; +} + +Bool drmMgaInitDma(int driSubFD, drmMgaInit *info) +{ + drm_mga_init_t init; + int i; + + memset(&init, 0, sizeof(drm_mga_init_t)); + init.func = MGA_INIT_DMA; + init.reserved_map_agpstart = info->reserved_map_agpstart; + init.reserved_map_idx = info->reserved_map_idx; + init.buffer_map_idx = info->buffer_map_idx; + init.sarea_priv_offset = info->sarea_priv_offset; + init.primary_size = info->primary_size; + init.warp_ucode_size = info->warp_ucode_size; + init.frontOffset = info->frontOffset; + init.backOffset = info->backOffset; + init.depthOffset = info->depthOffset; + init.textureOffset = info->textureOffset; + init.textureSize = info->textureSize; + init.agpTextureSize = info->agpTextureSize; + init.agpTextureOffset = info->agpTextureOffset; + init.cpp = info->cpp; + init.stride = info->stride; + init.sgram = info->sgram; + init.chipset = info->chipset; + + for(i = 0; i < MGA_MAX_WARP_PIPES; i++) { + init.WarpIndex[i].installed = info->WarpIndex[i].installed; + init.WarpIndex[i].phys_addr = info->WarpIndex[i].phys_addr; + init.WarpIndex[i].size = info->WarpIndex[i].size; + } + + init.mAccess = info->mAccess; + + + + if(ioctl(driSubFD, DRM_IOCTL_MGA_INIT, &init)) { + return FALSE; + } + return TRUE; +} + diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h index 7b8e88265..ae4c65ca3 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h @@ -61,6 +61,19 @@ typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; +/* Warning: If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well */ + +typedef struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +} drm_clip_rect_t; + +/* Seperate include files for the i810/mga specific structures */ +#include "mga_drm.h" +#include "i810_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -101,7 +114,8 @@ typedef struct drm_control { typedef enum drm_map_type { _DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */ _DRM_REGISTERS = 1, /* no caching, no core dump */ - _DRM_SHM = 2 /* shared, cached */ + _DRM_SHM = 2, /* shared, cached */ + _DRM_AGP = 3 /* AGP/GART */ } drm_map_type_t; typedef enum drm_map_flags { @@ -165,8 +179,11 @@ typedef struct drm_buf_desc { int low_mark; /* Low water mark */ int high_mark; /* High water mark */ enum { - DRM_PAGE_ALIGN = 0x01 /* Align on page boundaries for DMA */ + _DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */ + _DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */ } flags; + unsigned long agp_start; /* Start address of where the agp buffers + * are in the agp aperture */ } drm_buf_desc_t; typedef struct drm_buf_info { @@ -237,6 +254,38 @@ typedef struct drm_irq_busid { int funcnum; } drm_irq_busid_t; +typedef struct drm_agp_mode { + unsigned long mode; +} drm_agp_mode_t; + + /* For drm_agp_alloc -- allocated a buffer */ +typedef struct drm_agp_buffer { + unsigned long size; /* In bytes -- will round to page boundary */ + unsigned long handle; /* Used for BIND/UNBIND ioctls */ + unsigned long type; /* Type of memory to allocate */ + unsigned long physical; /* Physical used by i810 */ +} drm_agp_buffer_t; + + /* For drm_agp_bind */ +typedef struct drm_agp_binding { + unsigned long handle; /* From drm_agp_buffer */ + unsigned long offset; /* In bytes -- will round to page boundary */ +} drm_agp_binding_t; + +typedef struct drm_agp_info { + int agp_version_major; + int agp_version_minor; + unsigned long mode; + unsigned long aperture_base; /* physical address */ + unsigned long aperture_size; /* bytes */ + unsigned long memory_allowed; /* bytes */ + unsigned long memory_used; + + /* PCI information */ + unsigned short id_vendor; + unsigned short id_device; +} drm_agp_info_t; + #define DRM_IOCTL_BASE 'd' #define DRM_IOCTL_NR(n) _IOC_NR(n) #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) @@ -276,4 +325,28 @@ typedef struct drm_irq_busid { #define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t) #define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t) +#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) +#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) +#define DRM_IOCTL_AGP_ENABLE DRM_IOR( 0x32, drm_agp_mode_t) +#define DRM_IOCTL_AGP_INFO DRM_IOW( 0x33, drm_agp_info_t) +#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) +#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) + +/* Mga specific ioctls */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) + +/* I810 specific ioctls */ +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) + #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h index 61287e3e2..0fd1141b5 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h @@ -65,7 +65,8 @@ typedef struct _drmVersion { typedef enum { DRM_FRAME_BUFFER = 0, /* WC, no caching, no core dump */ DRM_REGISTERS = 1, /* no caching, no core dump */ - DRM_SHM = 2 /* shared, cached */ + DRM_SHM = 2, /* shared, cached */ + DRM_AGP = 3 /* AGP/GART */ } drmMapType; typedef enum { @@ -95,6 +96,11 @@ typedef enum { /* These values *MUST* match drm.h */ } drmDMAFlags; typedef enum { + DRM_PAGE_ALIGN = 0x01, + DRM_AGP_BUFFER = 0x02 +} drmBufDescFlags; + +typedef enum { DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */ DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */ DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */ @@ -196,7 +202,7 @@ typedef struct { unsigned int a[100]; } __drm_dummy_lock_t; #endif #ifndef DRM_CAS -#define DRM_CAS(lock,old,new,ret) /* FAST LOCK FAILS */ +#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */ #endif #define DRM_LIGHT_LOCK(fd,lock,context) \ @@ -291,7 +297,9 @@ extern int drmAddMap(int fd, drmMapType type, drmMapFlags flags, drmHandlePtr handle); -extern int drmAddBufs(int fd, int count, int size, int flags); +extern int drmAddBufs(int fd, int count, int size, + drmBufDescFlags flags, + int agp_offset); extern int drmMarkBufs(int fd, double low, double high); extern int drmCreateContext(int fd, drmContextPtr handle); extern int drmSetContextFlags(int fd, drmContext context, @@ -332,6 +340,29 @@ extern int drmGetLock(int fd, extern int drmUnlock(int fd, drmContext context); extern int drmFinish(int fd, int context, drmLockFlags flags); +/* AGP/GART support: X server (root) only */ +extern int drmAgpAcquire(int fd); +extern int drmAgpRelease(int fd); +extern int drmAgpEnable(int fd, unsigned long mode); +extern int drmAgpAlloc(int fd, unsigned long size, + unsigned long type, unsigned long *address, + unsigned long *handle); +extern int drmAgpFree(int fd, unsigned long handle); +extern int drmAgpBind(int fd, unsigned long handle, + unsigned long offset); +extern int drmAgpUnbind(int fd, unsigned long handle); + +/* AGP/GART info: authenticated client and/or X */ +extern int drmAgpVersionMajor(int fd); +extern int drmAgpVersionMinor(int fd); +extern unsigned long drmAgpGetMode(int fd); +extern unsigned long drmAgpBase(int fd); /* Physical location */ +extern unsigned long drmAgpSize(int fd); /* Bytes */ +extern unsigned long drmAgpMemoryUsed(int fd); +extern unsigned long drmAgpMemoryAvail(int fd); +extern unsigned int drmAgpVendorId(int fd); +extern unsigned int drmAgpDeviceId(int fd); + /* Support routines */ extern int drmError(int err, const char *label); extern void *drmMalloc(int size); diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h new file mode 100644 index 000000000..88bb58a3b --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h @@ -0,0 +1,29 @@ + +/* WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (i810_drm.h) + */ + +#ifndef _XF86DRI_I810_H_ +#define _XF86DRI_I810_H_ + +#ifndef _I810_DEFINES_ +#define _I810_DEFINES_ +#define I810_USE_BATCH 1 + +#define I810_DMA_BUF_ORDER 12 +#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER) +#define I810_DMA_BUF_NR 256 + +#define I810_NR_SAREA_CLIPRECTS 2 + +/* Each region is a minimum of 64k, and there are at most 64 of them. + */ +#define I810_NR_TEX_REGIONS 64 +#define I810_LOG_MIN_TEX_REGION_SIZE 16 +#endif + +Bool drmI810CleanupDma(int driSubFD); +Bool drmI810InitDma(int driSubFD, unsigned long start, unsigned long end, + unsigned long size, int ring_map_idx, int buffer_map_idx, + int sarea_off); +#endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h new file mode 100644 index 000000000..9525a2710 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h @@ -0,0 +1,147 @@ + +/* WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (mga_drm.h) + */ + +#ifndef _XF86DRI_MGA_H_ +#define _XF86DRI_MGA_H_ +#ifndef _MGA_DEFINES_ +#define _MGA_DEFINES_ +#define MGA_F 0x1 /* fog */ +#define MGA_A 0x2 /* alpha */ +#define MGA_S 0x4 /* specular */ +#define MGA_T2 0x8 /* multitexture */ + +#define MGA_WARP_TGZ 0 +#define MGA_WARP_TGZF (MGA_F) +#define MGA_WARP_TGZA (MGA_A) +#define MGA_WARP_TGZAF (MGA_F|MGA_A) +#define MGA_WARP_TGZS (MGA_S) +#define MGA_WARP_TGZSF (MGA_S|MGA_F) +#define MGA_WARP_TGZSA (MGA_S|MGA_A) +#define MGA_WARP_TGZSAF (MGA_S|MGA_F|MGA_A) +#define MGA_WARP_T2GZ (MGA_T2) +#define MGA_WARP_T2GZF (MGA_T2|MGA_F) +#define MGA_WARP_T2GZA (MGA_T2|MGA_A) +#define MGA_WARP_T2GZAF (MGA_T2|MGA_A|MGA_F) +#define MGA_WARP_T2GZS (MGA_T2|MGA_S) +#define MGA_WARP_T2GZSF (MGA_T2|MGA_S|MGA_F) +#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A) +#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A) + +#define MGA_MAX_G400_PIPES 16 +#define MGA_MAX_G200_PIPES 8 /* no multitex */ + +#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES + +#define MGA_CARD_TYPE_G200 1 +#define MGA_CARD_TYPE_G400 2 +#define MGA_FRONT 0x1 +#define MGA_BACK 0x2 +#define MGA_DEPTH 0x4 + +/* 3d state excluding texture units: + */ +#define MGA_CTXREG_DSTORG 0 /* validated */ +#define MGA_CTXREG_MACCESS 1 +#define MGA_CTXREG_PLNWT 2 +#define MGA_CTXREG_DWGCTL 3 +#define MGA_CTXREG_ALPHACTRL 4 +#define MGA_CTXREG_FOGCOLOR 5 +#define MGA_CTXREG_WFLAG 6 +#define MGA_CTXREG_TDUAL0 7 +#define MGA_CTXREG_TDUAL1 8 +#define MGA_CTXREG_FCOL 9 +#define MGA_CTX_SETUP_SIZE 10 + +/* 2d state + */ +#define MGA_2DREG_PITCH 0 +#define MGA_2D_SETUP_SIZE 1 + +/* Each texture unit has a state: + */ +#define MGA_TEXREG_CTL 0 +#define MGA_TEXREG_CTL2 1 +#define MGA_TEXREG_FILTER 2 +#define MGA_TEXREG_BORDERCOL 3 +#define MGA_TEXREG_ORG 4 /* validated */ +#define MGA_TEXREG_ORG1 5 +#define MGA_TEXREG_ORG2 6 +#define MGA_TEXREG_ORG3 7 +#define MGA_TEXREG_ORG4 8 +#define MGA_TEXREG_WIDTH 9 +#define MGA_TEXREG_HEIGHT 10 +#define MGA_TEX_SETUP_SIZE 11 + +/* What needs to be changed for the current vertex dma buffer? + */ +#define MGA_UPLOAD_CTX 0x1 +#define MGA_UPLOAD_TEX0 0x2 +#define MGA_UPLOAD_TEX1 0x4 +#define MGA_UPLOAD_PIPE 0x8 +#define MGA_UPLOAD_TEX0IMAGE 0x10 +#define MGA_UPLOAD_TEX1IMAGE 0x20 +#define MGA_UPLOAD_2D 0x40 +#define MGA_WAIT_AGE 0x80 /* handled client-side */ +#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */ +#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock + quiescent */ + +/* 64 buffers of 16k each, total 1 meg. + */ +#define MGA_DMA_BUF_ORDER 14 +#define MGA_DMA_BUF_SZ (1<<MGA_DMA_BUF_ORDER) +#define MGA_DMA_BUF_NR 63 + +/* Keep these small for testing. + */ +#define MGA_NR_SAREA_CLIPRECTS 8 + +/* 2 heaps (1 for card, 1 for agp), each divided into upto 128 + * regions, subject to a minimum region size of (1<<16) == 64k. + * + * Clients may subdivide regions internally, but when sharing between + * clients, the region size is the minimum granularity. + */ + +#define MGA_CARD_HEAP 0 +#define MGA_AGP_HEAP 1 +#define MGA_NR_TEX_HEAPS 2 +#define MGA_NR_TEX_REGIONS 16 +#define MGA_LOG_MIN_TEX_REGION_SIZE 16 +#endif + +typedef struct _drmMgaWarpIndex { + int installed; + unsigned long phys_addr; + int size; +} drmMgaWarpIndex; + +typedef struct _drmMgaInit { + int reserved_map_agpstart; + int reserved_map_idx; + int buffer_map_idx; + int sarea_priv_offset; + int primary_size; + int warp_ucode_size; + int frontOffset; + int backOffset; + int depthOffset; + int textureOffset; + int textureSize; + int agpTextureSize; + int agpTextureOffset; + int cpp; + int stride; + int sgram; + int chipset; + drmMgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES]; + int mAccess; +} drmMgaInit; + + +Bool drmMgaCleanupDma(int driSubFD); +Bool drmMgaLockUpdate(int driSubFD, drmLockFlags flags); +Bool drmMgaInitDma(int driSubFD, drmMgaInit *info); +#endif |