diff options
Diffstat (limited to 'xc/lib/GL/mesa')
98 files changed, 15927 insertions, 3550 deletions
diff --git a/xc/lib/GL/mesa/dri/dri_mesa.c b/xc/lib/GL/mesa/dri/dri_mesa.c index 08f3dfcfd..b679b41a4 100644 --- a/xc/lib/GL/mesa/dri/dri_mesa.c +++ b/xc/lib/GL/mesa/dri/dri_mesa.c @@ -29,7 +29,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Kevin E. Martin <kevin@precisioninsight.com> - * Brian Paul <brian@precisioninsight.com> + * Brian E. Paul <brian@precisioninsight.com> */ #ifdef GLX_DIRECT_RENDERING @@ -39,16 +39,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <Xext.h> #include <extutil.h> #include "glxclient.h" -#include "GL/xmesa.h" #include "xf86dri.h" #include "sarea.h" #include "dri_mesaint.h" #include "dri_xmesaapi.h" - - -#if XMESA_MAJOR_VERSION != 3 || XMESA_MINOR_VERSION != 3 -#error using wrong version of Mesa (need 3.3) -#endif +#include "../src/context.h" +#include "../src/mmath.h" /* Context binding */ @@ -109,6 +105,8 @@ static __DRIdrawable *__driMesaFindDrawable(GLXDrawable draw) return pdraw; } +#if 0 +/* not used yet */ static void __driMesaRemoveDrawable(__DRIdrawable *pdraw) { int retcode; @@ -122,23 +120,22 @@ static void __driMesaRemoveDrawable(__DRIdrawable *pdraw) drmHashDelete(drawHash, pdp->draw); } } +#endif /*****************************************************************/ -static void driMesaInitAPI(__XMESAapi *XMesaAPI) +static void driMesaInitAPI(__MesaAPI *MesaAPI) { - XMesaAPI->InitDriver = XMesaInitDriver; - XMesaAPI->ResetDriver = XMesaResetDriver; - XMesaAPI->CreateVisual = XMesaCreateVisual; - XMesaAPI->DestroyVisual = XMesaDestroyVisual; - XMesaAPI->CreateContext = XMesaCreateContext; - XMesaAPI->DestroyContext = XMesaDestroyContext; - XMesaAPI->CreateWindowBuffer = XMesaCreateWindowBuffer; - XMesaAPI->CreatePixmapBuffer = XMesaCreatePixmapBuffer; - XMesaAPI->DestroyBuffer = XMesaDestroyBuffer; - XMesaAPI->SwapBuffers = XMesaSwapBuffers; - XMesaAPI->MakeCurrent = XMesaMakeCurrent; - XMesaAPI->UnbindContext = XMesaUnbindContext; + MesaAPI->InitDriver = XMesaInitDriver; + MesaAPI->ResetDriver = XMesaResetDriver; + MesaAPI->CreateVisual = XMesaCreateVisual; + MesaAPI->CreateContext = XMesaCreateContext; + MesaAPI->DestroyContext = XMesaDestroyContext; + MesaAPI->CreateWindowBuffer = XMesaCreateWindowBuffer; + MesaAPI->CreatePixmapBuffer = XMesaCreatePixmapBuffer; + MesaAPI->SwapBuffers = XMesaSwapBuffers; + MesaAPI->MakeCurrent = XMesaMakeCurrent; + MesaAPI->UnbindContext = XMesaUnbindContext; } /*****************************************************************/ @@ -176,7 +173,7 @@ static Bool driMesaUnbindContext(Display *dpy, int scrn, } /* Unbind Mesa's drawable from Mesa's context */ - (*psp->XMesaAPI.UnbindContext)(pcp->xm_ctx); + (*psp->MesaAPI.UnbindContext)(pcp); if (pdp->refcount == 0) { /* ERROR!!! */ @@ -279,7 +276,7 @@ static Bool driMesaBindContext(Display *dpy, int scrn, } /* Bind Mesa's drawable to Mesa's context */ - (*psp->XMesaAPI.MakeCurrent)(pcp->xm_ctx, pdp->xm_buf); + (*psp->MesaAPI.MakeCurrent)(pcp, pdp, pdp); return GL_TRUE; } @@ -307,14 +304,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!!! */ } @@ -332,7 +341,7 @@ static void *driMesaCreateDrawable(Display *dpy, int scrn, GLXDrawable draw, __DRIscreenPrivate *psp; __DRIdrawablePrivate *pdp; int i; - XMesaVisual xm_vis = NULL; + GLvisual *mesaVis = NULL; pdp = (__DRIdrawablePrivate *)Xmalloc(sizeof(__DRIdrawablePrivate)); if (!pdp) { @@ -354,7 +363,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; @@ -363,20 +374,19 @@ static void *driMesaCreateDrawable(Display *dpy, int scrn, GLXDrawable draw, for (i = 0; i < psp->numVisuals; i++) { if (vid == psp->visuals[i].vid) { - xm_vis = psp->visuals[i].xm_vis; + mesaVis = psp->visuals[i].mesaVisual; break; } } - if (1 /* NOT_DONE: Determine if it is a pixmap or not */) { - pdp->xm_buf = (*psp->XMesaAPI.CreateWindowBuffer)(xm_vis, draw, pdp); - } else { - XMesaVisual xm_vis = NULL; - XMesaColormap cmap = 0; - pdp->xm_buf = (*psp->XMesaAPI.CreatePixmapBuffer)(xm_vis, draw, cmap, - pdp); + /* XXX pixmap rendering not implemented yet */ + if (1) { + pdp->mesaBuffer = (*psp->MesaAPI.CreateWindowBuffer)(dpy, psp, pdp, mesaVis); + } + else { + pdp->mesaBuffer = (*psp->MesaAPI.CreatePixmapBuffer)(dpy, psp, pdp, mesaVis); } - if (!pdp->xm_buf) { + if (!pdp->mesaBuffer) { (void)XF86DRIDestroyDrawable(dpy, scrn, pdp->draw); Xfree(pdp); return NULL; @@ -402,7 +412,7 @@ static void driMesaSwapBuffers(Display *dpy, void *private) __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)private; __DRIscreenPrivate *psp = pdp->driScreenPriv; - (*psp->XMesaAPI.SwapBuffers)(pdp->xm_buf); + (*psp->MesaAPI.SwapBuffers)(pdp); } static void driMesaDestroyDrawable(Display *dpy, void *private) @@ -412,7 +422,7 @@ static void driMesaDestroyDrawable(Display *dpy, void *private) int scrn = psp->myNum; if (pdp) { - (*psp->XMesaAPI.DestroyBuffer)(pdp->xm_buf); + gl_destroy_framebuffer(pdp->mesaBuffer); (void)XF86DRIDestroyDrawable(dpy, scrn, pdp->draw); if (pdp->pClipRects) Xfree(pdp->pClipRects); @@ -427,8 +437,6 @@ static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared, { __DRIcontextPrivate *pcp; __DRIcontextPrivate *pshare = (__DRIcontextPrivate *)shared; - XMesaContext shared_xm_ctx = (pshare ? - pshare->xm_ctx : (XMesaContext)NULL); __DRIscreenPrivate *psp; __DRIscreen *pDRIScreen; int i; @@ -443,7 +451,7 @@ static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared, return NULL; } psp->dummyContextPriv.driScreenPriv = psp; - psp->dummyContextPriv.xm_ctx = NULL; + psp->dummyContextPriv.mesaContext = NULL; psp->dummyContextPriv.driDrawablePriv = NULL; /* No other fields should be used! */ } @@ -453,8 +461,9 @@ static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared, return NULL; } + pcp->display = dpy; pcp->driScreenPriv = psp; - pcp->xm_ctx = NULL; + pcp->mesaContext = NULL; pcp->driDrawablePriv = NULL; if (!XF86DRICreateContext(dpy, vis->screen, vis->visual, @@ -463,12 +472,28 @@ static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared, return NULL; } - for (i = 0; i < psp->numVisuals; i++) - if (psp->visuals[i].vid == vis->visualid) - pcp->xm_ctx = (*psp->XMesaAPI.CreateContext) - (psp->visuals[i].xm_vis, shared_xm_ctx, pcp); - - if (!pcp->xm_ctx) { + for (i = 0; i < psp->numVisuals; i++) { + if (psp->visuals[i].vid == vis->visualid) { + GLvisual *mesaVis = psp->visuals[i].mesaVisual; + GLcontext *sharedMesaCtx = pshare ? pshare->mesaContext : NULL; + pcp->mesaContext = gl_create_context(mesaVis, + sharedMesaCtx, + NULL, /* set below */ + GL_TRUE); + if (pcp->mesaContext) { + /* Driver now creates its private context data */ + if ((*psp->MesaAPI.CreateContext)(dpy, mesaVis, pcp)) { + pcp->mesaContext->DriverCtx = pcp->driverPrivate; + } + else { + gl_destroy_context(pcp->mesaContext); + pcp->mesaContext = NULL; + } + } + } + } + + if (!pcp->mesaContext) { (void)XF86DRIDestroyContext(dpy, vis->screen, pcp->contextID); Xfree(pcp); return NULL; @@ -487,7 +512,8 @@ static void driMesaDestroyContext(Display *dpy, int scrn, void *private) if (pcp) { (void)XF86DRIDestroyContext(dpy, scrn, pcp->contextID); - (*pcp->driScreenPriv->XMesaAPI.DestroyContext)(pcp->xm_ctx); + (*pcp->driScreenPriv->MesaAPI.DestroyContext)(pcp); + gl_destroy_context(pcp->mesaContext); Xfree(pcp); } } @@ -565,7 +591,7 @@ static void *driMesaCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, return NULL; } - driMesaInitAPI(&psp->XMesaAPI); + driMesaInitAPI(&psp->MesaAPI); if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, @@ -627,22 +653,13 @@ static void *driMesaCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, for (i = 0; i < numConfigs; i++, config++) { psp->visuals[i].vid = visinfo[i].visualid; - psp->visuals[i].xm_vis = - (*psp->XMesaAPI.CreateVisual)(dpy, - &visinfo[i], - config->rgba, - (config->alphaSize > 0), - config->doubleBuffer, - config->stereo, - GL_TRUE, /* ximage_flag */ - config->depthSize, - config->stencilSize, - config->accumRedSize, - config->level); - if (!psp->visuals[i].xm_vis) { + psp->visuals[i].mesaVisual = + (*psp->MesaAPI.CreateVisual) (dpy, psp, &visinfo[i], config); + + if (!psp->visuals[i].mesaVisual) { /* Free the visuals so far created */ while (--i >= 0) { - (*psp->XMesaAPI.DestroyVisual)(psp->visuals[i].xm_vis); + _mesa_destroy_visual(psp->visuals[i].mesaVisual); } Xfree(psp->visuals); XFree(visinfo); @@ -658,11 +675,10 @@ static void *driMesaCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, XFree(visinfo); /* Initialize the screen specific GLX driver */ - if (psp->XMesaAPI.InitDriver) { - if (!(*psp->XMesaAPI.InitDriver)(psp)) { + if (psp->MesaAPI.InitDriver) { + if (!(*psp->MesaAPI.InitDriver)(psp)) { while (--psp->numVisuals >= 0) { - (*psp->XMesaAPI.DestroyVisual) - (psp->visuals[psp->numVisuals].xm_vis); + _mesa_destroy_visual(psp->visuals[psp->numVisuals].mesaVisual); } Xfree(psp->visuals); (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); @@ -699,11 +715,10 @@ static void driMesaDestroyScreen(Display *dpy, int scrn, void *private) (void)XF86DRIDestroyContext(dpy, scrn, psp->dummyContextPriv.contextID); } - if (psp->XMesaAPI.ResetDriver) - (*psp->XMesaAPI.ResetDriver)(psp); + if (psp->MesaAPI.ResetDriver) + (*psp->MesaAPI.ResetDriver)(psp); while (--psp->numVisuals >= 0) { - (*psp->XMesaAPI.DestroyVisual) - (psp->visuals[psp->numVisuals].xm_vis); + _mesa_destroy_visual(psp->visuals[psp->numVisuals].mesaVisual); } Xfree(psp->visuals); (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); diff --git a/xc/lib/GL/mesa/dri/dri_mesaint.h b/xc/lib/GL/mesa/dri/dri_mesaint.h index 6b64114d0..e8918724c 100644 --- a/xc/lib/GL/mesa/dri/dri_mesaint.h +++ b/xc/lib/GL/mesa/dri/dri_mesaint.h @@ -29,6 +29,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Kevin E. Martin <kevin@precisioninsight.com> + * Brian E. Paul <brian@precisioninsight.com> * */ @@ -40,10 +41,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <GL/glx.h> #include "xf86dri.h" #include "sarea.h" -#include "GL/xmesa.h" #include "dri_mesa.h" #include "dri_xmesaapi.h" + #define DRI_MESA_VALIDATE_DRAWABLE_INFO(dpy,scrn,pDrawPriv) \ do { \ if (*(pDrawPriv->pStamp) != pDrawPriv->lastStamp) { \ @@ -59,9 +60,9 @@ struct __DRIdrawablePrivateRec { drmDrawable hHWDrawable; /* - ** Mesa's private context information. This structure is opaque. + ** Mesa's private frame buffer information. This structure is opaque. */ - XMesaBuffer xm_buf; + GLframebuffer *mesaBuffer; /* ** X's drawable ID associated with this private drawable. @@ -104,6 +105,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; @@ -128,7 +139,17 @@ struct __DRIcontextPrivateRec { /* ** Mesa's private context information. This structure is opaque. */ - XMesaContext xm_ctx; + GLcontext *mesaContext; + + /* + ** Device driver's private context data. This structure is opaque. + */ + void *driverPrivate; + + /* + ** This context's display pointer. + */ + Display *display; /* ** Pointer to drawable currently bound to this context. @@ -145,7 +166,7 @@ struct __DRIvisualPrivateRec { /* ** Mesa's private visual information. This structure is opaque. */ - XMesaVisual xm_vis; + GLvisual *mesaVisual; /* ** X's visual ID associated with this private visual. @@ -169,7 +190,7 @@ struct __DRIscreenPrivateRec { /* ** Function pointers associated with Mesa's GLX functions. */ - __XMESAapi XMesaAPI; + __MesaAPI MesaAPI; /* ** Core rendering library's driver version information. diff --git a/xc/lib/GL/mesa/dri/dri_xmesaapi.h b/xc/lib/GL/mesa/dri/dri_xmesaapi.h index 18aa3db8d..54f22df70 100644 --- a/xc/lib/GL/mesa/dri/dri_xmesaapi.h +++ b/xc/lib/GL/mesa/dri/dri_xmesaapi.h @@ -29,48 +29,110 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Kevin E. Martin <kevin@precisioninsight.com> - * + * Brian E. Paul <brian@precisioninsight.com> */ + #ifndef _DRI_XMESAAPI_H_ #define _DRI_XMESAAPI_H_ -#ifdef GLX_DIRECT_RENDERING - -#include "GL/xmesa.h" +#include "glxclient.h" #include "dri_mesa.h" +#include "../src/types.h" + + +extern GLboolean XMesaInitDriver( __DRIscreenPrivate *driScrnPriv ); + +extern void XMesaResetDriver( __DRIscreenPrivate *driScrnPriv ); + +/* Driver creates a GLvisual and returns pointer to it. + */ +extern GLvisual *XMesaCreateVisual(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config); + +/* Driver creates its private context struct and hooks it into + * the driContextPriv->driverPrivate field. Return true/false for + * success/error. + */ +extern GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv ); + +/* Driver frees data attached to driContextPriv->driverPrivate pointer. + */ +extern void XMesaDestroyContext( __DRIcontextPrivate *driContextPriv ); + +/* Driver creates a GLframebuffer struct indicating which ancillary + * buffers are in hardware or software. + */ +extern GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis); -typedef struct __XMESAapiRec __XMESAapi; +extern GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis); -struct __XMESAapiRec { +extern GLboolean XMesaMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ); + +extern GLboolean XMesaUnbindContext( __DRIcontextPrivate *driContextPriv ); + +extern void XMesaSwapBuffers( __DRIdrawablePrivate *driDrawPriv ); + + + + + +#define XMESA_VALIDATE_DRAWABLE_INFO(dpy, psp, pdp) \ +do { \ + while (*(pdp->pStamp) != pdp->lastStamp) { \ + DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, \ + pdp->driContextPriv->hHWContext); \ + \ + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ + DRI_MESA_VALIDATE_DRAWABLE_INFO(dpy, psp->myNum, pdp); \ + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ + \ + DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, \ + pdp->driContextPriv->hHWContext); \ + } \ +} while (0) + + + +typedef struct __MesaAPIRec __MesaAPI; + +struct __MesaAPIRec { /* XMESA Functions */ GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv); void (*ResetDriver)(__DRIscreenPrivate *driScrnPriv); - XMesaVisual (*CreateVisual)(XMesaDisplay *display, - XMesaVisualInfo visinfo, - GLboolean rgb_flag, - GLboolean alpha_flag, - GLboolean db_flag, - GLboolean stereo_flag, - GLboolean ximage_flag, - GLint depth_size, - GLint stencil_size, - GLint accum_size, - GLint level); - void (*DestroyVisual)(XMesaVisual v); - XMesaContext (*CreateContext)(XMesaVisual v, XMesaContext share_list, - __DRIcontextPrivate *driContextPriv); - void (*DestroyContext)(XMesaContext c); - XMesaBuffer (*CreateWindowBuffer)(XMesaVisual v, XMesaWindow w, - __DRIdrawablePrivate *driDrawPriv); - XMesaBuffer (*CreatePixmapBuffer)(XMesaVisual v, XMesaPixmap p, - XMesaColormap c, - __DRIdrawablePrivate *driDrawPriv); - void (*DestroyBuffer)(XMesaBuffer b); - void (*SwapBuffers)(XMesaBuffer b); - GLboolean (*MakeCurrent)(XMesaContext c, XMesaBuffer b); - GLboolean (*UnbindContext)(XMesaContext c); + GLvisual * (*CreateVisual)(Display *display, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config); + GLboolean (*CreateContext)(Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv); + void (*DestroyContext)(__DRIcontextPrivate *driContextPriv); + GLframebuffer * (*CreateWindowBuffer)(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis); + GLframebuffer * (*CreatePixmapBuffer)(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis); + void (*SwapBuffers)(__DRIdrawablePrivate *driDrawPriv); + GLboolean (*MakeCurrent)(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv); + GLboolean (*UnbindContext)(__DRIcontextPrivate *driContextPriv); }; -#endif + + #endif /* _DRI_XMESAAPI_H_ */ diff --git a/xc/lib/GL/mesa/src/Imakefile b/xc/lib/GL/mesa/src/Imakefile index d93aa3f7e..4f5af973c 100644 --- a/xc/lib/GL/mesa/src/Imakefile +++ b/xc/lib/GL/mesa/src/Imakefile @@ -16,6 +16,9 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL TDFX_DEFS = -DFX #endif +LinkSourceFile(aatriangle.c, ../../../../extras/Mesa/src) +LinkSourceFile(aatriangle.h, ../../../../extras/Mesa/src) +LinkSourceFile(aatritemp.h, ../../../../extras/Mesa/src) LinkSourceFile(accum.c, ../../../../extras/Mesa/src) LinkSourceFile(accum.h, ../../../../extras/Mesa/src) LinkSourceFile(all.h, ../../../../extras/Mesa/src) @@ -120,6 +123,8 @@ LinkSourceFile(pipeline.c, ../../../../extras/Mesa/src) LinkSourceFile(pipeline.h, ../../../../extras/Mesa/src) LinkSourceFile(pixel.c, ../../../../extras/Mesa/src) LinkSourceFile(pixel.h, ../../../../extras/Mesa/src) +LinkSourceFile(pixeltex.c, ../../../../extras/Mesa/src) +LinkSourceFile(pixeltex.h, ../../../../extras/Mesa/src) LinkSourceFile(points.c, ../../../../extras/Mesa/src) LinkSourceFile(points.h, ../../../../extras/Mesa/src) LinkSourceFile(polygon.c, ../../../../extras/Mesa/src) @@ -156,6 +161,8 @@ LinkSourceFile(texstate.c, ../../../../extras/Mesa/src) LinkSourceFile(texstate.h, ../../../../extras/Mesa/src) LinkSourceFile(texture.c, ../../../../extras/Mesa/src) LinkSourceFile(texture.h, ../../../../extras/Mesa/src) +LinkSourceFile(texutil.c, ../../../../extras/Mesa/src) +LinkSourceFile(texutil.h, ../../../../extras/Mesa/src) LinkSourceFile(trans_tmp.h, ../../../../extras/Mesa/src) LinkSourceFile(translate.c, ../../../../extras/Mesa/src) LinkSourceFile(translate.h, ../../../../extras/Mesa/src) @@ -189,7 +196,8 @@ LinkSourceFile(xform_tmp.h, ../../../../extras/Mesa/src) LinkSourceFile(zoom.c, ../../../../extras/Mesa/src) LinkSourceFile(zoom.h, ../../../../extras/Mesa/src) - CORE_SRCS = accum.c \ + CORE_SRCS = aatriangle.c \ + accum.c \ alpha.c \ alphabuf.c \ attrib.c \ @@ -220,7 +228,7 @@ LinkSourceFile(zoom.h, ../../../../extras/Mesa/src) hash.c \ hint.c \ image.c \ - imaging.o \ + imaging.c \ light.c \ lines.c \ logic.c \ @@ -231,6 +239,7 @@ LinkSourceFile(zoom.h, ../../../../extras/Mesa/src) pb.c \ pipeline.c \ pixel.c \ + pixeltex.c \ points.c \ polygon.c \ quads.c \ @@ -247,6 +256,7 @@ LinkSourceFile(zoom.h, ../../../../extras/Mesa/src) texobj.c \ texstate.c \ texture.c \ + texutil.c \ translate.c \ triangle.c \ varray.c \ @@ -262,7 +272,8 @@ LinkSourceFile(zoom.h, ../../../../extras/Mesa/src) xform.c \ zoom.c - CORE_OBJS = accum.o \ + CORE_OBJS = aatriangle.o \ + accum.o \ alpha.o \ alphabuf.o \ attrib.o \ @@ -301,6 +312,7 @@ LinkSourceFile(zoom.h, ../../../../extras/Mesa/src) pb.o \ pipeline.o \ pixel.o \ + pixeltex.o \ points.o \ polygon.o \ quads.o \ @@ -317,6 +329,7 @@ LinkSourceFile(zoom.h, ../../../../extras/Mesa/src) texobj.o \ texstate.o \ texture.o \ + texutil.o \ translate.o \ triangle.o \ varray.o \ @@ -335,8 +348,12 @@ LinkSourceFile(zoom.h, ../../../../extras/Mesa/src) #ifdef i386Architecture ASM_SRCS = ASM_OBJS = +#ifdef MesaUse3DNow + ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM -DUSE_3DNOW_ASM +#else ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM #endif +#endif DEFINES = $(ALLOC_DEFINES) GlxDefines $(TDFX_DEFS) $(ASM_DEFS) INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) -I../include -I../../dri -I. -I../../../../include @@ -351,9 +368,7 @@ LinkSourceFile(zoom.h, ../../../../extras/Mesa/src) #endif #if GlxBuiltInMesa || GlxDriverUsesMesa || !GlxUseBuiltInDRIDriver -# We have to go into X to make the xmesaP.h symbolic link - MESASUBDIRS = X - + MESASUBDIRS = ASMSUBDIRS = X86 #include <Library.tmpl> @@ -371,13 +386,4 @@ SUBDIRS = $(MESASUBDIRS) $(ASMSUBDIRS) drv MakeSubdirs($(SUBDIRS)) DependSubdirs($(SUBDIRS)) - -#if !GlxUseBuiltInDRIDriver && !GlxDriverUsesMesa -LIBNAME = mesa_dri.so -ALL_OBJS = $(CORE_OBJS) X/?*.o X86/?*.o -ALL_DEPS = $(SUBDIRS) DONE X/DONE X86/DONE -SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) -InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.) -#endif - DependTarget() diff --git a/xc/lib/GL/mesa/src/X86/Imakefile b/xc/lib/GL/mesa/src/X86/Imakefile index 858f0cd73..53402ac67 100644 --- a/xc/lib/GL/mesa/src/X86/Imakefile +++ b/xc/lib/GL/mesa/src/X86/Imakefile @@ -16,7 +16,6 @@ LinkSourceFile(x86.h, ../../../../../extras/Mesa/src/X86) LinkSourceFile(x86a.S, ../../../../../extras/Mesa/src/X86) LinkSourceFile(vertex.S, ../../../../../extras/Mesa/src/X86) LinkSourceFile(x86flatregs.m4, ../../../../../extras/Mesa/src/X86) -LinkSourceFile(x86a.S.m4, ../../../../../extras/Mesa/src/X86) LinkSourceFile(mmx.h, ../../../../../extras/Mesa/src/X86) LinkSourceFile(mmx_blend.S, ../../../../../extras/Mesa/src/X86) @@ -55,9 +54,7 @@ XCOMM We'll learn at runtime whether 3dNow, MMX, etc are really present. MMX_DEFS = -DUSE_MMX_ASM - -XCOMM Disabling 3DNow code for the time being -#if 0 +#ifdef MesaUse3DNow 3DNOW_SRCS = 3dnow.c 3dnow_norm_raw.S 3dnow_xform_masked1.S \ 3dnow_xform_masked2.S 3dnow_xform_masked3.S \ 3dnow_xform_masked4.S 3dnow_xform_raw1.S \ @@ -73,6 +70,7 @@ XCOMM Disabling 3DNow code for the time being 3DNOW_DEFS = -DUSE_3DNOW_ASM #endif + #endif DEFINES = $(ALLOC_DEFINES) GlxDefines -DFX $(X86_DEFS) $(MMX_DEFS) $(3DNOW_DEFS) @@ -96,7 +94,7 @@ STD_CPP_DEFINES = StandardDefines $(PROJECT_DEFINES) SubdirLibraryRule($(OBJS)) NormalLintTarget($(SRCS)) -#ifdef HAVE_3DNOW +#ifdef MesaUse3DNow ObjectFromAsmSource(3dnow_norm_raw, NullParameter) ObjectFromAsmSource(3dnow_xform_masked1, NullParameter) ObjectFromAsmSource(3dnow_xform_masked2, NullParameter) @@ -109,9 +107,7 @@ ObjectFromAsmSource(3dnow_xform_raw4, NullParameter) ObjectFromAsmSource(vertex_3dnow, NullParameter) #endif -#ifdef HAVE_MMX ObjectFromAsmSource(mmx_blend, NullParameter) -#endif ObjectFromAsmSource(common_x86asm, NullParameter) ObjectFromAsmSource(vertex, NullParameter) @@ -119,6 +115,3 @@ ObjectFromAsmSource(x86a, NullParameter) DependTarget() -x86a.S: x86flatregs.m4 -x86a.S: x86a.S.m4 - m4 $< >$@ diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile index fadb29bb2..ed30e7196 100644 --- a/xc/lib/GL/mesa/src/drv/Imakefile +++ b/xc/lib/GL/mesa/src/drv/Imakefile @@ -16,6 +16,15 @@ DRIVER += gamma #if GlxBuiltInTdfx DRIVER += tdfx #endif +#if GlxBuiltInMga +DRIVER += common mga +#endif +#if GlxBuiltInI810 +DRIVER += common i810 +#endif +#if GlxBuiltInR128 +DRIVER += r128 +#endif SUBDIRS = $(DRIVER) #else @@ -23,6 +32,10 @@ SUBDIRS += gamma #if HasGlide3 SUBDIRS += tdfx #endif +SUBDIRS += common +SUBDIRS += mga +SUBDIRS += i810 +SUBDIRS += r128 #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..d47b662e8 100644 --- a/xc/lib/GL/mesa/src/drv/common/Imakefile +++ b/xc/lib/GL/mesa/src/drv/common/Imakefile @@ -22,13 +22,12 @@ 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 - SRCS = $(DRISRCS) - OBJS = $(DRIOBJS) + SRCS = $(DRISRCS) + OBJS = $(DRIOBJS) #if !GlxUseBuiltInDRIDriver #undef DoNormalLib NormalLibGlx @@ -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/gamma/Imakefile b/xc/lib/GL/mesa/src/drv/gamma/Imakefile index 05e35561e..2a690a3e1 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/Imakefile +++ b/xc/lib/GL/mesa/src/drv/gamma/Imakefile @@ -1,4 +1,5 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.8 2000/03/02 16:07:35 martin Exp $ + +#include <Threads.tmpl> #define DoNormalLib NormalLibGlx #define DoSharedLib SharedLibGlx @@ -6,28 +7,35 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.8 2000/03/02 16:07:35 #define DoDebugLib DebugLibGlx #define DoProfileLib ProfileLibGlx -LinkSourceFile(xmesaP.h, ../../../../../../extras/Mesa/src/X) -LinkSourceFile(glapi.h, ../../../../../../extras/Mesa/src) - - #if Malloc0ReturnsNull ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif #if BuildXF86DRI - DRI_DEFINES = GlxDefines + 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)/glint \ - -I../../../include -I../.. -I../../X + -I../../../include -I../.. -I../../X -I../common \ + -I$(XF86OSSRC)/linux/drm/kernel #endif MESA_INCLUDES = -I. -I.. -I../../include + + DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) - INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) + 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 @@ -46,16 +54,216 @@ MESA_INCLUDES = -I. -I.. -I../../include ../../../../dri/drm/xf86drmSL.o GAMMASRCS = gamma_gl.c gamma_xmesa.c gamma_init.c gamma_matrix.c \ - gamma_inithw.c gamma_texture.c + gamma_inithw.c gamma_texture.c /* gamma_dlist.c */ GAMMAOBJS = gamma_gl.o gamma_xmesa.o gamma_init.o gamma_matrix.o \ - gamma_inithw.o gamma_texture.o + gamma_inithw.o gamma_texture.o /* gamma_dlist.o */ + + MESASRCS = ../../aatriangle.c \ + ../../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.c \ + ../../light.c \ + ../../lines.c \ + ../../logic.c \ + ../../masking.c \ + ../../matrix.c \ + ../../mem.c \ + ../../mmath.c \ + ../../pb.c \ + ../../pipeline.c \ + ../../pixel.c \ + ../../pixeltex.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 \ + ../../texutil.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 = ../../aatriangle.o \ + ../../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 \ + ../../pixeltex.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 \ + ../../texutil.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 -XCOMM SRCS = $(DRISRCS) $(DRMSRCS) $(GAMMASRCS) -XCOMM OBJS = $(DRIOBJS) $(DRMOBJS) $(GAMMAOBJS) + X86_OBJS = ../../X86/x86.o \ + ../../X86/x86a.o \ + ../../X86/common_x86.o \ + ../../X86/common_x86asm.o \ + ../../X86/vertex.o - SRCS = $(GAMMASRCS) - OBJS = $(DRIOBJS) $(DRMOBJS) $(GAMMAOBJS) + MMX_SRCS = ../../X86/mmx_blend.S + + MMX_OBJS = ../../X86/mmx_blend.o + +XCOMM Disabling 3Dnow code for the time being. +#if 0 + 3DNOW_SRCS = ../../X86/3dnow.c \ + ../../X86/3dnow_norm_raw.S \ + ../../X86/3dnow_xform_masked1.S \ + ../../X86/3dnow_xform_masked2.S \ + ../../X86/3dnow_xform_masked3.S \ + ../../X86/3dnow_xform_masked4.S \ + ../../X86/3dnow_xform_raw1.S \ + ../../X86/3dnow_xform_raw2.S \ + ../../X86/3dnow_xform_raw3.S \ + ../../X86/3dnow_xform_raw4.S \ + ../../X86/vertex_3dnow.S + + 3DNOW_OBJS = ../../X86/3dnow.o \ + ../../X86/3dnow_norm_raw.o \ + ../../X86/3dnow_xform_masked1.o \ + ../../X86/3dnow_xform_masked2.o \ + ../../X86/3dnow_xform_masked3.o \ + ../../X86/3dnow_xform_masked4.o \ + ../../X86/3dnow_xform_raw1.o \ + ../../X86/3dnow_xform_raw2.o \ + ../../X86/3dnow_xform_raw3.o \ + ../../X86/3dnow_xform_raw4.o \ + ../../X86/vertex_3dnow.o +#endif + +#endif + + ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) + ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) + + SRCS = $(LOWSRC) $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) $(GAMMASRCS) $(HISRC) + OBJS = $(LOWOBJ) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) $(GAMMAOBJS) $(HIOBJ) + +REQUIREDLIBS += -lm +#if !GlxBuiltInGamma +REQUIREDLIBS += -L../../../.. -lGL +#endif #if !GlxUseBuiltInDRIDriver diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c index 3bd2fd0f3..541f4d69c 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c @@ -30,13 +30,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <kevin@precisioninsight.com> * Brian Paul <brian@precisioninsight.com> + * Alan Hourihane <Alan.Hourihane@btinternet.com> */ #ifdef GLX_DIRECT_RENDERING +#include <Xarch.h> #include <math.h> #include "gamma_gl.h" #include "gamma_init.h" +#include "glint_dri.h" #ifdef RANDOMIZE_COLORS #include <stdlib.h> #endif @@ -114,7 +117,7 @@ void _gamma_Begin(GLenum mode) DEBUG_GLCMDS(("Begin: %04x\n", (int)mode)); if ((gCCPriv->Begin & B_PrimType_Mask) != B_PrimType_Null) { - /* ERROR!!! */ + DEBUG_ERROR(("Begin: Error\n")); return; } @@ -177,8 +180,9 @@ void _gamma_BindTexture(GLenum target, GLuint texture) gCCPriv->curTexObj = gammaTOFind(texture); /* Make the new texture images resident */ - if (!driTMMMakeImagesResident(gCCPriv->tmm, MIPMAP_LEVELS, - gCCPriv->curTexObj->image, addrs)) { + if (driTMMMakeImagesResident(gCCPriv->tmm, MIPMAP_LEVELS, + gCCPriv->curTexObj->image, addrs) < 0) { + DEBUG_ERROR(("BindTexture: unable\n")); /* NOT_DONE: Handle error */ } @@ -358,10 +362,12 @@ void _gamma_CallLists(GLsizei n, GLenum type, const GLvoid *lists) void _gamma_Clear(GLbitfield mask) { + int temp; unsigned int depth = 0; int do_clear = 0; + GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)gCC->driScreenPriv->pDevPriv; #ifdef DO_VALIDATE - __DRIscreenPrivate *driScrnPriv = gCC->driContextPriv->driScreenPriv; + __DRIscreenPrivate *driScrnPriv = gCC->driScreenPriv; #endif DEBUG_GLCMDS(("Clear: %04x\n", (int)mask)); @@ -437,11 +443,12 @@ void _gamma_Clear(GLbitfield mask) gCCPriv->FrameCount &= 0xff; #endif + temp = (gCCPriv->LBReadMode & LBPartialProdMask) | LBWindowOriginBot; + /* UGH - move this later ! */ + if (gDRIPriv->numMXDevices == 2) temp |= LBScanLineInt2; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); - WRITE(gCCPriv->buf, LBReadMode, - ((gCCPriv->LBReadMode & LBPartialProdMask) | - LBScanLineInt2 | - LBWindowOriginBot)); + WRITE(gCCPriv->buf, LBReadMode, temp); /* Force FCP to be written */ CHECK_DMA_BUFFER(gCC, gCCPriv, 1); @@ -627,34 +634,48 @@ void _gamma_ClipPlane(GLenum plane, const GLdouble *equation) void _gamma_Color3b(GLbyte red, GLbyte green, GLbyte blue) { + GLfloat r,g,b; + DEBUG_GLCMDS(("Color3b: %d %d %d\n", red, green, blue)); + + r = BYTE_TO_FLOAT(red); + g = BYTE_TO_FLOAT(green); + b = BYTE_TO_FLOAT(blue); + + _gamma_Color3f(r,g,b); } void _gamma_Color3bv(const GLbyte *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Color3bv: %d %d %d\n", v[0], v[1], v[2])); + + p[0] = BYTE_TO_FLOAT(v[0]); + p[1] = BYTE_TO_FLOAT(v[1]); + p[2] = BYTE_TO_FLOAT(v[2]); + + _gamma_Color3fv(p); } void _gamma_Color3d(GLdouble red, GLdouble green, GLdouble blue) { DEBUG_GLCMDS(("Color3d: %f %f %f\n", red, green, blue)); + + _gamma_Color3f((GLfloat)red,(GLfloat)green,(GLfloat)blue); } void _gamma_Color3dv(const GLdouble *v) { DEBUG_GLCMDS(("Color3dv: %f %f %f\n", v[0], v[1], v[2])); + + _gamma_Color3fv((GLfloat*)v); } void _gamma_Color3f(GLfloat red, GLfloat green, GLfloat blue) { DEBUG_GLCMDS(("Color3f: %f %f %f\n", red, green, blue)); -#ifdef RANDOMIZE_COLORS - red = (random() / (double)RAND_MAX); - green = (random() / (double)RAND_MAX); - blue = (random() / (double)RAND_MAX); -#endif - CHECK_DMA_BUFFER(gCC, gCCPriv, 3); WRITEF(gCCPriv->buf, Cb, blue); WRITEF(gCCPriv->buf, Cg, green); @@ -665,107 +686,188 @@ void _gamma_Color3fv(const GLfloat *v) { DEBUG_GLCMDS(("Color3fv: %f %f %f\n", v[0], v[1], v[2])); -#ifdef RANDOMIZE_COLORS - { - float r, g, b; - r = (random() / (double)RAND_MAX); - g = (random() / (double)RAND_MAX); - b = (random() / (double)RAND_MAX); - CHECK_DMA_BUFFER(gCC, gCCPriv, 3); - WRITEF(gCCPriv->buf, Cb, b); - WRITEF(gCCPriv->buf, Cg, g); - WRITEF(gCCPriv->buf, Cr3, r); - } -#else CHECK_DMA_BUFFER(gCC, gCCPriv, 3); WRITEF(gCCPriv->buf, Cb, v[2]); WRITEF(gCCPriv->buf, Cg, v[1]); WRITEF(gCCPriv->buf, Cr3, v[0]); -#endif } void _gamma_Color3i(GLint red, GLint green, GLint blue) { + GLfloat r,g,b; + DEBUG_GLCMDS(("Color3i: %d %d %d\n", (int)red, (int)green, (int)blue)); + + r = INT_TO_FLOAT(red); + g = INT_TO_FLOAT(green); + b = INT_TO_FLOAT(blue); + + _gamma_Color3f(r,g,b); } void _gamma_Color3iv(const GLint *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Color3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2])); + + p[0] = INT_TO_FLOAT(v[0]); + p[1] = INT_TO_FLOAT(v[1]); + p[2] = INT_TO_FLOAT(v[2]); + + _gamma_Color3fv(p); } void _gamma_Color3s(GLshort red, GLshort green, GLshort blue) { + GLfloat r,g,b; + DEBUG_GLCMDS(("Color3s: %d %d %d\n", red, green, blue)); + + r = SHORT_TO_FLOAT(red); + g = SHORT_TO_FLOAT(green); + b = SHORT_TO_FLOAT(blue); + + _gamma_Color3f(r,g,b); } void _gamma_Color3sv(const GLshort *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Color3sv: %d %d %d\n", v[0], v[1], v[2])); + + p[0] = SHORT_TO_FLOAT(v[0]); + p[1] = SHORT_TO_FLOAT(v[1]); + p[2] = SHORT_TO_FLOAT(v[2]); + + _gamma_Color3fv(p); } void _gamma_Color3ub(GLubyte red, GLubyte green, GLubyte blue) { + GLuint c; + DEBUG_GLCMDS(("Color3ub: %d %d %d\n", red, green, blue)); + + c = (blue << 16) | (green << 8) | red; + + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, PackedColor3, c); } void _gamma_Color3ubv(const GLubyte *v) { + GLuint c; + DEBUG_GLCMDS(("Color3ubv: %d %d %d\n", v[0], v[1], v[2])); + + c = (v[2] << 16) | (v[1] << 8) | v[0]; + + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, PackedColor3, c); } void _gamma_Color3ui(GLuint red, GLuint green, GLuint blue) { + GLfloat r,g,b; + DEBUG_GLCMDS(("Color3ui: %d %d %d\n", (unsigned int)red, (unsigned int)green, (unsigned int)blue)); + + r = UINT_TO_FLOAT(red); + g = UINT_TO_FLOAT(green); + b = UINT_TO_FLOAT(blue); + + _gamma_Color3f(r,g,b); } void _gamma_Color3uiv(const GLuint *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Color3uiv: %d %d %d\n", (unsigned int)v[0], (unsigned int)v[1], (unsigned int)v[2])); + + p[0] = UINT_TO_FLOAT(v[0]); + p[1] = UINT_TO_FLOAT(v[1]); + p[2] = UINT_TO_FLOAT(v[2]); + + _gamma_Color3fv(p); } void _gamma_Color3us(GLushort red, GLushort green, GLushort blue) { + GLfloat r,g,b; + DEBUG_GLCMDS(("Color3us: %d %d %d\n", red, green, blue)); + + r = USHORT_TO_FLOAT(red); + g = USHORT_TO_FLOAT(green); + b = USHORT_TO_FLOAT(blue); + + _gamma_Color3f(r,g,b); } void _gamma_Color3usv(const GLushort *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Color3usv: %d %d %d\n", v[0], v[1], v[2])); + + p[0] = USHORT_TO_FLOAT(v[0]); + p[1] = USHORT_TO_FLOAT(v[1]); + p[2] = USHORT_TO_FLOAT(v[2]); + + _gamma_Color3fv(p); } void _gamma_Color4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) { + GLfloat r,g,b,a; + DEBUG_GLCMDS(("Color4b: %d %d %d %d\n", red, green, blue, alpha)); + + r = BYTE_TO_FLOAT(red); + g = BYTE_TO_FLOAT(green); + b = BYTE_TO_FLOAT(blue); + a = BYTE_TO_FLOAT(alpha); + + _gamma_Color4f(r,g,b,a); } void _gamma_Color4bv(const GLbyte *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("Color4bv: %d %d %d %d\n", v[0], v[1], v[2], v[3])); + + p[0] = BYTE_TO_FLOAT(v[0]); + p[1] = BYTE_TO_FLOAT(v[1]); + p[2] = BYTE_TO_FLOAT(v[2]); + p[3] = BYTE_TO_FLOAT(v[3]); + + _gamma_Color4fv(p); } void _gamma_Color4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) { DEBUG_GLCMDS(("Color4d: %f %f %f %f\n", red, green, blue, alpha)); + + _gamma_Color4f((GLfloat)red,(GLfloat)green,(GLfloat)blue,(GLfloat)alpha); } void _gamma_Color4dv(const GLdouble *v) { DEBUG_GLCMDS(("Color4dv: %f %f %f %f\n", v[0], v[1], v[2], v[3])); + + _gamma_Color4fv((GLfloat*)v); } void _gamma_Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { DEBUG_GLCMDS(("Color4f: %f %f %f %f\n", red, green, blue, alpha)); -#ifdef RANDOMIZE_COLORS - red = (random() / (double)RAND_MAX); - green = (random() / (double)RAND_MAX); - blue = (random() / (double)RAND_MAX); -#endif - CHECK_DMA_BUFFER(gCC, gCCPriv, 4); WRITEF(gCCPriv->buf, Ca, alpha); WRITEF(gCCPriv->buf, Cb, blue); @@ -777,47 +879,69 @@ void _gamma_Color4fv(const GLfloat *v) { DEBUG_GLCMDS(("Color4fv: %f %f %f %f\n", v[0], v[1], v[2], v[3])); -#ifdef RANDOMIZE_COLORS - { - float r, g, b; - r = (random() / (double)RAND_MAX); - g = (random() / (double)RAND_MAX); - b = (random() / (double)RAND_MAX); - CHECK_DMA_BUFFER(gCC, gCCPriv, 4); - WRITEF(gCCPriv->buf, Ca, v[3]); - WRITEF(gCCPriv->buf, Cb, b); - WRITEF(gCCPriv->buf, Cg, g); - WRITEF(gCCPriv->buf, Cr3, r); - } -#else CHECK_DMA_BUFFER(gCC, gCCPriv, 4); WRITEF(gCCPriv->buf, Ca, v[3]); WRITEF(gCCPriv->buf, Cb, v[2]); WRITEF(gCCPriv->buf, Cg, v[1]); WRITEF(gCCPriv->buf, Cr4, v[0]); -#endif } void _gamma_Color4i(GLint red, GLint green, GLint blue, GLint alpha) { + GLfloat r,g,b,a; + DEBUG_GLCMDS(("Color4i: %d %d %d %d\n", (int)red, (int)green, (int)blue, (int)alpha)); + + r = INT_TO_FLOAT(red); + g = INT_TO_FLOAT(green); + b = INT_TO_FLOAT(blue); + a = INT_TO_FLOAT(alpha); + + _gamma_Color4f(r,g,b,a); } void _gamma_Color4iv(const GLint *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("Color4iv: %d %d %d %d\n", (int)v[0], (int)v[1], (int)v[2], (int)v[3])); + + p[0] = INT_TO_FLOAT(v[0]); + p[1] = INT_TO_FLOAT(v[1]); + p[2] = INT_TO_FLOAT(v[2]); + p[3] = INT_TO_FLOAT(v[3]); + + _gamma_Color4fv(p); } void _gamma_Color4s(GLshort red, GLshort green, GLshort blue, GLshort alpha) { + GLfloat r,g,b,a; + DEBUG_GLCMDS(("Color4s: %d %d %d %d\n", red, green, blue, alpha)); + + r = SHORT_TO_FLOAT(red); + g = SHORT_TO_FLOAT(green); + b = SHORT_TO_FLOAT(blue); + a = SHORT_TO_FLOAT(alpha); + + _gamma_Color4f(r,g,b,a); } void _gamma_Color4sv(const GLshort *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("Color4sv: %d %d %d %d\n", v[0], v[1], v[2], v[3])); + + p[0] = SHORT_TO_FLOAT(v[0]); + p[1] = SHORT_TO_FLOAT(v[1]); + p[2] = SHORT_TO_FLOAT(v[2]); + p[3] = SHORT_TO_FLOAT(v[3]); + + _gamma_Color4fv(p); } void _gamma_Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) @@ -826,11 +950,7 @@ void _gamma_Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) DEBUG_GLCMDS(("Color4ub: %d %d %d %d\n", red, green, blue, alpha)); -#ifdef RANDOMIZE_COLORS - c = (random() / (double)RAND_MAX) * 16777216; -#else c = (alpha << 24) | (blue << 16) | (green << 8) | red; -#endif CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, PackedColor4, c); @@ -842,17 +962,7 @@ void _gamma_Color4ubv(const GLubyte *v) DEBUG_GLCMDS(("Color4ubv: %d %d %d %d\n", v[0], v[1], v[2], v[3])); -#ifdef RANDOMIZE_COLORS - c = (random() / (double)RAND_MAX) * 16777216; -#else -/* NOT_DONE: Is there a standard define for endianness? */ -#define IS_LITTLE_ENDIAN 1 -#if IS_LITTLE_ENDIAN - c = *((GLuint *)v); -#else c = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0]; -#endif -#endif CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, PackedColor4, c); @@ -860,26 +970,62 @@ void _gamma_Color4ubv(const GLubyte *v) void _gamma_Color4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha) { + GLfloat r,g,b,a; + DEBUG_GLCMDS(("Color4ui: %d %d %d %d\n", (unsigned int)red, (unsigned int)green, (unsigned int)blue, (unsigned int)alpha)); + + r = UINT_TO_FLOAT(red); + g = UINT_TO_FLOAT(green); + b = UINT_TO_FLOAT(blue); + a = UINT_TO_FLOAT(alpha); + + _gamma_Color4f(r,g,b,a); } void _gamma_Color4uiv(const GLuint *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("Color4uiv: %d %d %d %d\n", (unsigned int)v[0], (unsigned int)v[1], (unsigned int)v[2], (unsigned int)v[3])); + + p[0] = UINT_TO_FLOAT(v[0]); + p[1] = UINT_TO_FLOAT(v[1]); + p[2] = UINT_TO_FLOAT(v[2]); + p[3] = UINT_TO_FLOAT(v[3]); + + _gamma_Color4fv(p); } void _gamma_Color4us(GLushort red, GLushort green, GLushort blue, GLushort alpha) { + GLfloat r,g,b,a; + DEBUG_GLCMDS(("Color4us: %d %d %d %d\n", red, green, blue, alpha)); + + r = USHORT_TO_FLOAT(red); + g = USHORT_TO_FLOAT(green); + b = USHORT_TO_FLOAT(blue); + a = USHORT_TO_FLOAT(alpha); + + _gamma_Color4f(r,g,b,a); } void _gamma_Color4usv(const GLushort *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("Color4usv: %d %d %d %d\n", v[0], v[1], v[2], v[3])); + + p[0] = USHORT_TO_FLOAT(v[0]); + p[1] = USHORT_TO_FLOAT(v[1]); + p[2] = USHORT_TO_FLOAT(v[2]); + p[3] = USHORT_TO_FLOAT(v[3]); + + _gamma_Color4fv(p); } void _gamma_ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) @@ -890,6 +1036,43 @@ void _gamma_ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean void _gamma_ColorMaterial(GLenum face, GLenum mode) { DEBUG_GLCMDS(("ColorMaterial: %04x %04x\n", (int)face, (int)mode)); + + gCCPriv->MaterialMode &= ~MaterialModeEnable; + gCCPriv->ColorMaterialMode = ColorMaterialModeDisable; + + switch (face) { + case GL_FRONT: + gCCPriv->ColorMaterialMode |= ColorMaterialModeFront; + break; + case GL_BACK: + gCCPriv->ColorMaterialMode |= ColorMaterialModeBack; + break; + case GL_FRONT_AND_BACK: + gCCPriv->ColorMaterialMode |= ColorMaterialModeFrontAndBack; + break; + } + + switch (mode) { + case GL_AMBIENT: + gCCPriv->ColorMaterialMode |= ColorMaterialModeAmbient; + break; + case GL_EMISSION: + gCCPriv->ColorMaterialMode |= ColorMaterialModeEmission; + break; + case GL_DIFFUSE: + gCCPriv->ColorMaterialMode |= ColorMaterialModeDiffuse; + break; + case GL_SPECULAR: + gCCPriv->ColorMaterialMode |= ColorMaterialModeSpecular; + break; + case GL_AMBIENT_AND_DIFFUSE: + gCCPriv->ColorMaterialMode |= ColorMaterialModeAmbAndDiff; + break; + } + + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, ColorMaterialMode, gCCPriv->ColorMaterialMode); + WRITE(gCCPriv->buf, MaterialMode, gCCPriv->MaterialMode); } void _gamma_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) @@ -938,9 +1121,6 @@ void _gamma_CullFace(GLenum mode) gCCPriv->GeometryMode &= ~GM_PolyCullMask; -#ifdef CULL_ALL_PRIMS - gCCPriv->GeometryMode |= GM_PolyCullBoth; -#else switch (mode) { case GL_FRONT: gCCPriv->GeometryMode |= GM_PolyCullFront; @@ -955,7 +1135,7 @@ void _gamma_CullFace(GLenum mode) /* ERROR!! */ break; } -#endif + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode); } @@ -980,7 +1160,8 @@ void _gamma_DeleteTextures(GLsizei n, const GLuint *textures) for (i = 0; i < n; i++) { gammaTexObj *t = gammaTOFind(textures[i]); - if (!driTMMDeleteImages(gCCPriv->tmm, MIPMAP_LEVELS, t->image)) { + if (driTMMDeleteImages(gCCPriv->tmm, MIPMAP_LEVELS, t->image) < 0) { + DEBUG_ERROR(("DeleteTextures: unable\n")); /* NOT_DONE: Handle error */ } gammaTODelete(textures[i]); @@ -1068,11 +1249,9 @@ void _gamma_Disable(GLenum cap) switch (cap) { case GL_CULL_FACE: -#ifdef CULL_ALL_PRIMS gCCPriv->GeometryMode &= ~GM_PolyCullEnable; CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode); -#endif break; case GL_DEPTH_TEST: if (gCCPriv->Flags & GAMMA_DEPTH_BUFFER) { @@ -1106,6 +1285,35 @@ void _gamma_Disable(GLenum cap) WRITE(gCCPriv->buf, FBReadMode, (gCCPriv->FBReadMode | gCCPriv->AB_FBReadMode)); break; + case GL_COLOR_MATERIAL: + gCCPriv->ColorMaterialMode &= ~ColorMaterialModeEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, ColorMaterialMode, gCCPriv->ColorMaterialMode); + break; + case GL_FOG: + gCCPriv->Begin &= ~B_FogEnable; + gCCPriv->GeometryMode &= ~GM_FogEnable; + gCCPriv->DeltaMode &= ~DM_FogEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode); + WRITE(gCCPriv->buf, DeltaMode, gCCPriv->DeltaMode); + WRITE(gCCPriv->buf, FogMode, FogModeDisable); + break; + case GL_LIGHTING: + gCCPriv->LightingMode &= ~LightingModeEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, LightingMode, gCCPriv->LightingMode); + break; + case GL_LIGHT0: + gCCPriv->Light0Mode &= ~LNM_On; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode); + break; + case GL_LIGHT1: + gCCPriv->Light1Mode &= ~LNM_On; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode); + break; case GL_TEXTURE_2D: gCCPriv->Texture2DEnabled = GL_FALSE; gCCPriv->Begin &= ~B_TextureEnable; @@ -1227,6 +1435,35 @@ void _gamma_Enable(GLenum cap) WRITE(gCCPriv->buf, FBReadMode, (gCCPriv->FBReadMode | gCCPriv->AB_FBReadMode)); break; + case GL_COLOR_MATERIAL: + gCCPriv->ColorMaterialMode |= ColorMaterialModeEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, ColorMaterialMode, gCCPriv->ColorMaterialMode); + break; + case GL_FOG: + gCCPriv->Begin |= B_FogEnable; + gCCPriv->GeometryMode |= GM_FogEnable; + gCCPriv->DeltaMode |= DM_FogEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode); + WRITE(gCCPriv->buf, DeltaMode, gCCPriv->DeltaMode); + WRITE(gCCPriv->buf, FogMode, FogModeEnable); + break; + case GL_LIGHTING: + gCCPriv->LightingMode |= LightingModeEnable | 16<<6; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, LightingMode, gCCPriv->LightingMode); + break; + case GL_LIGHT0: + gCCPriv->Light0Mode |= LNM_On; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode); + break; + case GL_LIGHT1: + gCCPriv->Light1Mode |= LNM_On; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode); + break; case GL_TEXTURE_2D: gCCPriv->Texture2DEnabled = GL_TRUE; #ifndef TURN_OFF_TEXTURES @@ -1294,34 +1531,42 @@ void _gamma_EvalCoord1d(GLdouble u) void _gamma_EvalCoord1dv(const GLdouble *u) { + DEBUG_GLCMDS(("EvalCoord1dv: %f\n", *u)); } void _gamma_EvalCoord1f(GLfloat u) { + DEBUG_GLCMDS(("EvalCoord1f: %f\n", u)); } void _gamma_EvalCoord1fv(const GLfloat *u) { + DEBUG_GLCMDS(("EvalCoord1fv: %f\n", *u)); } void _gamma_EvalCoord2d(GLdouble u, GLdouble v) { + DEBUG_GLCMDS(("EvalCoord2d: %f %f\n", u, v)); } void _gamma_EvalCoord2dv(const GLdouble *u) { + DEBUG_GLCMDS(("EvalCoord2dv: %f %f\n", u[0], u[1])); } void _gamma_EvalCoord2f(GLfloat u, GLfloat v) { + DEBUG_GLCMDS(("EvalCoord2f: %f %f\n", u, v)); } void _gamma_EvalCoord2fv(const GLfloat *u) { + DEBUG_GLCMDS(("EvalCoord1fv: %f %f\n", u[0], u[1])); } void _gamma_EvalMesh1(GLenum mode, GLint i1, GLint i2) { + DEBUG_GLCMDS(("EvalMesh1: %d %d %d\n", mode, i1, i2)); } void _gamma_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) @@ -1358,16 +1603,55 @@ void _gamma_Flush(void) void _gamma_Fogf(GLenum pname, GLfloat param) { DEBUG_GLCMDS(("Fogf: %04x %f\n", (int)pname, param)); + + switch (pname) { + case GL_FOG_DENSITY: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, FogDensity, param); + break; + } } void _gamma_Fogfv(GLenum pname, const GLfloat *params) { + int color; + DEBUG_GLCMDS(("Fogfv: %04x %f\n", (int)pname, *params)); + + switch (pname) { + case GL_FOG_COLOR: + color = ((int)params[3]<<24) | ((int)params[2]<<16) | + ((int)params[1]<<8) | ((int)params[0]); + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, FogColor, color); + break; + } } void _gamma_Fogi(GLenum pname, GLint param) { DEBUG_GLCMDS(("Fogi: %04x %d\n", (int)pname, (int)param)); + + gCCPriv->GeometryMode &= ~GM_FogMask; + + switch (pname) { + case GL_FOG_MODE: + switch (param) { + case GL_EXP: + gCCPriv->GeometryMode |= GM_FogExp; + break; + case GL_EXP2: + gCCPriv->GeometryMode |= GM_FogExpSquared; + break; + case GL_LINEAR: + gCCPriv->GeometryMode |= GM_FogLinear; + break; + } + break; + } + + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode); } void _gamma_Fogiv(GLenum pname, const GLint *params) @@ -1378,6 +1662,16 @@ void _gamma_Fogiv(GLenum pname, const GLint *params) void _gamma_FrontFace(GLenum mode) { DEBUG_GLCMDS(("FrontFace: %04x\n", (int)mode)); + + gCCPriv->GeometryMode &= ~GM_FFMask; + + if (mode == GL_CCW) + gCCPriv->GeometryMode |= GM_FrontFaceCCW; + else + gCCPriv->GeometryMode |= GM_FrontFaceCW; + + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode); } void _gamma_Frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) @@ -1463,14 +1757,24 @@ void _gamma_GetFloatv(GLenum val, GLfloat *f) void _gamma_GetIntegerv(GLenum val, GLint *i) { DEBUG_GLCMDS(("GetIntegerv: %04x\n", (int)val)); + + switch (val) { + case GL_MAX_TEXTURE_SIZE: + *i = 2048; + break; + } } void _gamma_GetLightfv(GLenum light, GLenum pname, GLfloat *params) { + DEBUG_GLCMDS(("GetLightfv: %04x %04x %f\n", + (int)light, (int)pname, *params)); } void _gamma_GetLightiv(GLenum light, GLenum pname, GLint *params) { + DEBUG_GLCMDS(("GetLightiv: %04x %04x %d\n", + (int)light, (int)pname, *params)); } void _gamma_GetMapdv(GLenum target, GLenum query, GLdouble *v) @@ -1517,7 +1821,7 @@ void _gamma_GetPolygonStipple(GLubyte *mask) const GLubyte *_gamma_GetString(GLenum name) { static unsigned char vendor[] = "Precision Insight, Inc."; - static unsigned char renderer[] = "DRI Glint-Gamma 20000228"; + static unsigned char renderer[] = "DRI Glint-Gamma 20000605"; static unsigned char version[] = "1.1"; static unsigned char ext[] = ""; @@ -1654,6 +1958,12 @@ GLboolean _gamma_IsEnabled(GLenum cap) { DEBUG_GLCMDS(("IsEnabled: %04x\n", (int)cap)); + switch (cap) { + case GL_LIGHTING: + return ((gCCPriv->LightingMode & LightingModeEnable)?GL_TRUE:GL_FALSE); + break; + } + return GL_TRUE; } @@ -1673,10 +1983,44 @@ GLboolean _gamma_IsTexture(GLuint texture) void _gamma_LightModelf(GLenum pname, GLfloat param) { + DEBUG_GLCMDS(("LightModelf: %04x %f\n", + (int)pname, param)); } void _gamma_LightModelfv(GLenum pname, const GLfloat *params) { + DEBUG_GLCMDS(("LightModelfv: %04x %f\n", + (int)pname, *params)); + + switch (pname) { + case GL_LIGHT_MODEL_AMBIENT: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + /* We don't do alpha */ + WRITEF(gCCPriv->buf, SceneAmbientColorBlue, params[2]); + WRITEF(gCCPriv->buf, SceneAmbientColorGreen, params[1]); + WRITEF(gCCPriv->buf, SceneAmbientColorRed, params[0]); + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + if ((int)params[0] != 0) + gCCPriv->LightingMode |= LightingModeLocalViewer; + else + gCCPriv->LightingMode &= ~LightingModeLocalViewer; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, LightingMode, gCCPriv->LightingMode); + break; + case GL_LIGHT_MODEL_TWO_SIDE: + if ((int)params[0] != 0) { + gCCPriv->LightingMode |= LightingModeTwoSides; + gCCPriv->MaterialMode |= MaterialModeTwoSides; + } else { + gCCPriv->LightingMode &= ~LightingModeTwoSides; + gCCPriv->MaterialMode &= ~MaterialModeTwoSides; + } + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, LightingMode, gCCPriv->LightingMode); + WRITE(gCCPriv->buf, MaterialMode, gCCPriv->MaterialMode); + break; + } } void _gamma_LightModeli(GLenum pname, GLint param) @@ -1689,10 +2033,173 @@ void _gamma_LightModeliv(GLenum pname, const GLint *params) void _gamma_Lightf(GLenum light, GLenum pname, GLfloat param) { + DEBUG_GLCMDS(("Lightf: %04x %04x %f\n", + (int)light, (int)pname, param)); } void _gamma_Lightfv(GLenum light, GLenum pname, const GLfloat *params) { + GLfloat l,x,y,z; + DEBUG_GLCMDS(("Lightfv: %04x %04x %f\n", + (int)light, (int)pname, *params)); + + switch(light) { + case GL_LIGHT0: + switch (pname) { + case GL_AMBIENT: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + /* We don't do alpha */ + WRITEF(gCCPriv->buf, Light0AmbientIntensityBlue, params[2]); + WRITEF(gCCPriv->buf, Light0AmbientIntensityGreen, params[1]); + WRITEF(gCCPriv->buf, Light0AmbientIntensityRed, params[0]); + break; + case GL_DIFFUSE: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + /* We don't do alpha */ + WRITEF(gCCPriv->buf, Light0DiffuseIntensityBlue, params[2]); + WRITEF(gCCPriv->buf, Light0DiffuseIntensityGreen, params[1]); + WRITEF(gCCPriv->buf, Light0DiffuseIntensityRed, params[0]); + break; + case GL_SPECULAR: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + /* We don't do alpha */ + WRITEF(gCCPriv->buf, Light0SpecularIntensityBlue, params[2]); + WRITEF(gCCPriv->buf, Light0SpecularIntensityGreen, params[1]); + WRITEF(gCCPriv->buf, Light0SpecularIntensityRed, params[0]); + break; + case GL_POSITION: + /* Normalize <x,y,z> */ + x = params[0]; y = params[1]; z = params[2]; + l = sqrt(x*x + y*y + z*z); + x /= l; + y /= l; + z /= l; + if ((int)params[3] != 0) { + gCCPriv->Light0Mode |= Light0ModeAttenuation; + gCCPriv->Light0Mode |= Light0ModeLocal; + } else { + gCCPriv->Light0Mode &= ~Light0ModeAttenuation; + gCCPriv->Light0Mode &= ~Light0ModeLocal; + } + CHECK_DMA_BUFFER(gCC, gCCPriv, 5); + WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode); + WRITEF(gCCPriv->buf, Light0PositionW, params[3]); + WRITEF(gCCPriv->buf, Light0PositionZ, z); + WRITEF(gCCPriv->buf, Light0PositionY, y); + WRITEF(gCCPriv->buf, Light0PositionX, x); + break; + case GL_SPOT_DIRECTION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, Light0SpotlightDirectionZ, params[3]); + WRITEF(gCCPriv->buf, Light0SpotlightDirectionY, params[2]); + WRITEF(gCCPriv->buf, Light0SpotlightDirectionX, params[1]); + /* WRITEF(gCCPriv->buf, Light0SpotlightDirectionW, params[0]); */ + break; + case GL_SPOT_EXPONENT: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, Light0SpotlightExponent, params[0]); + break; + case GL_SPOT_CUTOFF: + if ((int)params[0] != -1) + gCCPriv->Light0Mode |= Light0ModeSpotLight; + else + gCCPriv->Light0Mode &= ~Light0ModeSpotLight; + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode); + WRITEF(gCCPriv->buf, Light0CosSpotlightCutoffAngle, params[0]); + break; + case GL_CONSTANT_ATTENUATION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, Light0ConstantAttenuation, params[0]); + break; + case GL_LINEAR_ATTENUATION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, Light0LinearAttenuation, params[0]); + break; + case GL_QUADRATIC_ATTENUATION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, Light0QuadraticAttenuation, params[0]); + break; + } + break; + case GL_LIGHT1: + switch (pname) { + case GL_AMBIENT: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + /* We don't do alpha */ + WRITEF(gCCPriv->buf, Light1AmbientIntensityBlue, params[2]); + WRITEF(gCCPriv->buf, Light1AmbientIntensityGreen, params[1]); + WRITEF(gCCPriv->buf, Light1AmbientIntensityRed, params[0]); + break; + case GL_DIFFUSE: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + /* We don't do alpha */ + WRITEF(gCCPriv->buf, Light1DiffuseIntensityBlue, params[2]); + WRITEF(gCCPriv->buf, Light1DiffuseIntensityGreen, params[1]); + WRITEF(gCCPriv->buf, Light1DiffuseIntensityRed, params[0]); + break; + case GL_SPECULAR: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + /* We don't do alpha */ + WRITEF(gCCPriv->buf, Light1SpecularIntensityBlue, params[2]); + WRITEF(gCCPriv->buf, Light1SpecularIntensityGreen, params[1]); + WRITEF(gCCPriv->buf, Light1SpecularIntensityRed, params[0]); + break; + case GL_POSITION: + /* Normalize <x,y,z> */ + x = params[0]; y = params[1]; z = params[2]; + l = sqrt(x*x + y*y + z*z); + x /= l; + y /= l; + z /= l; + if ((int)params[3] != 0) { + gCCPriv->Light1Mode |= Light1ModeAttenuation; + gCCPriv->Light1Mode |= Light1ModeLocal; + } else { + gCCPriv->Light0Mode &= ~Light0ModeAttenuation; + gCCPriv->Light0Mode &= ~Light0ModeLocal; + } + CHECK_DMA_BUFFER(gCC, gCCPriv, 5); + WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode); + WRITEF(gCCPriv->buf, Light1PositionW, params[3]); + WRITEF(gCCPriv->buf, Light1PositionZ, z); + WRITEF(gCCPriv->buf, Light1PositionY, y); + WRITEF(gCCPriv->buf, Light1PositionX, x); + break; + case GL_SPOT_DIRECTION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, Light1SpotlightDirectionZ, params[3]); + WRITEF(gCCPriv->buf, Light1SpotlightDirectionY, params[2]); + WRITEF(gCCPriv->buf, Light1SpotlightDirectionX, params[1]); + /* WRITEF(gCCPriv->buf, Light1SpotlightDirectionW, params[0]); */ + break; + case GL_SPOT_EXPONENT: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, Light1SpotlightExponent, params[0]); + break; + case GL_SPOT_CUTOFF: + if ((int)params[0] != -1) + gCCPriv->Light1Mode |= Light1ModeSpotLight; + else + gCCPriv->Light1Mode &= ~Light1ModeSpotLight; + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode); + WRITEF(gCCPriv->buf, Light1CosSpotlightCutoffAngle, params[0]); + break; + case GL_CONSTANT_ATTENUATION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, Light1ConstantAttenuation, params[0]); + break; + case GL_LINEAR_ATTENUATION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, Light1LinearAttenuation, params[0]); + break; + case GL_QUADRATIC_ATTENUATION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, Light1QuadraticAttenuation, params[0]); + break; + } + } } void _gamma_Lighti(GLenum light, GLenum pname, GLint param) @@ -1817,6 +2324,104 @@ void _gamma_Materialfv(GLenum face, GLenum pname, const GLfloat *params) { DEBUG_GLCMDS(("Materialfv: %04x %04x %f\n", (int)face, (int)pname, *params)); + + gCCPriv->MaterialMode |= MaterialModeEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, MaterialMode, gCCPriv->MaterialMode); + + if ((face == GL_FRONT) || (face == GL_FRONT_AND_BACK)) { + switch (pname) { + case GL_AMBIENT: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, FrontAmbientColorBlue, params[2]); + WRITEF(gCCPriv->buf, FrontAmbientColorGreen, params[1]); + WRITEF(gCCPriv->buf, FrontAmbientColorRed, params[0]); + break; + case GL_DIFFUSE: + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); + WRITEF(gCCPriv->buf, FrontAlpha, params[3]); + WRITEF(gCCPriv->buf, FrontDiffuseColorBlue, params[2]); + WRITEF(gCCPriv->buf, FrontDiffuseColorGreen, params[1]); + WRITEF(gCCPriv->buf, FrontDiffuseColorRed, params[0]); + break; + case GL_SPECULAR: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, FrontSpecularColorBlue, params[2]); + WRITEF(gCCPriv->buf, FrontSpecularColorGreen, params[1]); + WRITEF(gCCPriv->buf, FrontSpecularColorRed, params[0]); + break; + case GL_EMISSION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, FrontEmissiveColorBlue, params[2]); + WRITEF(gCCPriv->buf, FrontEmissiveColorGreen, params[1]); + WRITEF(gCCPriv->buf, FrontEmissiveColorRed, params[0]); + break; + case GL_SHININESS: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, FrontSpecularExponent, params[0]); + break; + case GL_AMBIENT_AND_DIFFUSE: + CHECK_DMA_BUFFER(gCC, gCCPriv, 7); + WRITEF(gCCPriv->buf, FrontAmbientColorBlue, params[2]); + WRITEF(gCCPriv->buf, FrontAmbientColorGreen, params[1]); + WRITEF(gCCPriv->buf, FrontAmbientColorRed, params[0]); + WRITEF(gCCPriv->buf, FrontAlpha, params[3]); + WRITEF(gCCPriv->buf, FrontDiffuseColorBlue, params[2]); + WRITEF(gCCPriv->buf, FrontDiffuseColorGreen, params[1]); + WRITEF(gCCPriv->buf, FrontDiffuseColorRed, params[0]); + break; + case GL_COLOR_INDEXES: + /* NOT_DONE */ + break; + } + } + + if ((face == GL_BACK) || (face == GL_FRONT_AND_BACK)) { + switch (pname) { + case GL_AMBIENT: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, BackAmbientColorBlue, params[2]); + WRITEF(gCCPriv->buf, BackAmbientColorGreen, params[1]); + WRITEF(gCCPriv->buf, BackAmbientColorRed, params[0]); + break; + case GL_DIFFUSE: + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); + WRITEF(gCCPriv->buf, BackAlpha, params[3]); + WRITEF(gCCPriv->buf, BackDiffuseColorBlue, params[2]); + WRITEF(gCCPriv->buf, BackDiffuseColorGreen, params[1]); + WRITEF(gCCPriv->buf, BackDiffuseColorRed, params[0]); + break; + case GL_SPECULAR: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, BackSpecularColorBlue, params[2]); + WRITEF(gCCPriv->buf, BackSpecularColorGreen, params[1]); + WRITEF(gCCPriv->buf, BackSpecularColorRed, params[0]); + break; + case GL_EMISSION: + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, BackEmissiveColorBlue, params[2]); + WRITEF(gCCPriv->buf, BackEmissiveColorGreen, params[1]); + WRITEF(gCCPriv->buf, BackEmissiveColorRed, params[0]); + break; + case GL_SHININESS: + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITEF(gCCPriv->buf, BackSpecularExponent, params[0]); + break; + case GL_AMBIENT_AND_DIFFUSE: + CHECK_DMA_BUFFER(gCC, gCCPriv, 7); + WRITEF(gCCPriv->buf, BackAmbientColorBlue, params[2]); + WRITEF(gCCPriv->buf, BackAmbientColorGreen, params[1]); + WRITEF(gCCPriv->buf, BackAmbientColorRed, params[0]); + WRITEF(gCCPriv->buf, BackAlpha, params[3]); + WRITEF(gCCPriv->buf, BackDiffuseColorBlue, params[2]); + WRITEF(gCCPriv->buf, BackDiffuseColorGreen, params[1]); + WRITEF(gCCPriv->buf, BackDiffuseColorRed, params[0]); + break; + case GL_COLOR_INDEXES: + /* NOT_DONE */ + break; + } + } } void _gamma_Materiali(GLenum face, GLenum pname, GLint param) @@ -1837,9 +2442,9 @@ void _gamma_MatrixMode(GLenum mode) switch (mode) { case GL_TEXTURE: - /* Eanble the Texture transform */ + /* Enable the Texture transform */ CHECK_DMA_BUFFER(gCC, gCCPriv, 1); - WRITE(gCCPriv->buf, TransformModeOr, 0x00000010); + WRITE(gCCPriv->buf, TransformModeOr, XM_XformTexture); case GL_MODELVIEW: case GL_PROJECTION: gCCPriv->MatrixMode = mode; @@ -1878,52 +2483,114 @@ void _gamma_NewList(GLuint list, GLenum mode) void _gamma_Normal3b(GLbyte nx, GLbyte ny, GLbyte nz) { + GLfloat x,y,z; + DEBUG_GLCMDS(("Normal3b: %d %d %d\n", nx, ny, nz)); + + x = BYTE_TO_FLOAT(nx); + y = BYTE_TO_FLOAT(ny); + z = BYTE_TO_FLOAT(nz); + + _gamma_Normal3f(x,y,z); } void _gamma_Normal3bv(const GLbyte *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Normal3bv: %d %d %d\n", v[0], v[1], v[2])); + + p[0] = BYTE_TO_FLOAT(v[0]); + p[1] = BYTE_TO_FLOAT(v[1]); + p[2] = BYTE_TO_FLOAT(v[2]); + + _gamma_Normal3fv(p); } void _gamma_Normal3d(GLdouble nx, GLdouble ny, GLdouble nz) { DEBUG_GLCMDS(("Normal3d: %f %f %f\n", nx, ny, nz)); + + _gamma_Normal3f((GLfloat)nx,(GLfloat)ny,(GLfloat)nz); } void _gamma_Normal3dv(const GLdouble *v) { DEBUG_GLCMDS(("Normal3dv: %f %f %f\n", v[0], v[1], v[2])); + + _gamma_Normal3fv((GLfloat*)v); } void _gamma_Normal3f(GLfloat nx, GLfloat ny, GLfloat nz) { DEBUG_GLCMDS(("Normal3f: %f %f %f\n", nx, ny, nz)); + + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, Nz, nz); + WRITEF(gCCPriv->buf, Ny, ny); + WRITEF(gCCPriv->buf, Nx, nx); } void _gamma_Normal3fv(const GLfloat *v) { DEBUG_GLCMDS(("Normal3fv: %f %f %f\n", v[0], v[1], v[2])); + + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); + WRITEF(gCCPriv->buf, Nz, v[2]); + WRITEF(gCCPriv->buf, Ny, v[1]); + WRITEF(gCCPriv->buf, Nx, v[0]); } void _gamma_Normal3i(GLint nx, GLint ny, GLint nz) { + GLfloat x,y,z; + DEBUG_GLCMDS(("Normal3i: %d %d %d\n", (int)nx, (int)ny, (int)nz)); + + x = INT_TO_FLOAT(nx); + y = INT_TO_FLOAT(ny); + z = INT_TO_FLOAT(nz); + + _gamma_Normal3f(x,y,z); } void _gamma_Normal3iv(const GLint *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Normal3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2])); + + p[0] = INT_TO_FLOAT(v[0]); + p[1] = INT_TO_FLOAT(v[1]); + p[2] = INT_TO_FLOAT(v[2]); + + _gamma_Normal3fv(p); } void _gamma_Normal3s(GLshort nx, GLshort ny, GLshort nz) { + GLfloat x,y,z; + DEBUG_GLCMDS(("Normal3s: %d %d %d\n", nx, ny, nz)); + + x = SHORT_TO_FLOAT(nx); + y = SHORT_TO_FLOAT(ny); + z = SHORT_TO_FLOAT(nz); + + _gamma_Normal3f(x,y,z); } void _gamma_Normal3sv(const GLshort *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Normal3sv: %d %d %d\n", v[0], v[1], v[2])); + + p[0] = SHORT_TO_FLOAT(v[0]); + p[1] = SHORT_TO_FLOAT(v[1]); + p[2] = SHORT_TO_FLOAT(v[2]); + + _gamma_Normal3fv(p); } void _gamma_NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) @@ -2020,6 +2687,56 @@ void _gamma_PointSize(GLfloat size) void _gamma_PolygonMode(GLenum face, GLenum mode) { DEBUG_GLCMDS(("PolygonMode: %04x %04x\n", (int)face, (int)mode)); + + gCCPriv->GeometryMode &= ~GM_FB_PolyMask; + + switch (mode) { + case GL_FILL: + switch (face) { + case GL_FRONT: + gCCPriv->GeometryMode |= GM_FrontPolyFill; + break; + case GL_BACK: + gCCPriv->GeometryMode |= GM_BackPolyFill; + break; + case GL_FRONT_AND_BACK: + gCCPriv->GeometryMode |= GM_FrontPolyFill; + gCCPriv->GeometryMode |= GM_BackPolyFill; + break; + } + break; + case GL_LINE: + switch (face) { + case GL_FRONT: + gCCPriv->GeometryMode |= GM_FrontPolyLine; + break; + case GL_BACK: + gCCPriv->GeometryMode |= GM_BackPolyLine; + break; + case GL_FRONT_AND_BACK: + gCCPriv->GeometryMode |= GM_FrontPolyLine; + gCCPriv->GeometryMode |= GM_BackPolyLine; + break; + } + break; + case GL_POINT: + switch (face) { + case GL_FRONT: + gCCPriv->GeometryMode |= GM_FrontPolyPoint; + break; + case GL_BACK: + gCCPriv->GeometryMode |= GM_BackPolyPoint; + break; + case GL_FRONT_AND_BACK: + gCCPriv->GeometryMode |= GM_FrontPolyPoint; + gCCPriv->GeometryMode |= GM_BackPolyPoint; + break; + } + break; + } + + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode); } void _gamma_PolygonOffset(GLfloat factor, GLfloat units) @@ -2272,6 +2989,15 @@ void _gamma_Rectdv(const GLdouble *v1, const GLdouble *v2) void _gamma_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { DEBUG_GLCMDS(("Rectf: %f %f %f %f\n", x1, y1, x2, y2)); + + /* This should be done with Gamma's Rectangle engine - later */ + + _gamma_Begin(GL_POLYGON); + _gamma_Vertex2f(x1,y1); + _gamma_Vertex2f(x2,y1); + _gamma_Vertex2f(x2,y2); + _gamma_Vertex2f(x1,y2); + _gamma_End(); } void _gamma_Rectfv(const GLfloat *v1, const GLfloat *v2) @@ -2474,51 +3200,87 @@ void _gamma_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) void _gamma_TexCoord1d(GLdouble s) { DEBUG_GLCMDS(("TexCoord1d: %f\n", s)); + + _gamma_TexCoord1f((GLfloat)s); } void _gamma_TexCoord1dv(const GLdouble *v) { DEBUG_GLCMDS(("TexCoord1dv: %f\n", *v)); + + _gamma_TexCoord1fv((GLfloat*)v); } void _gamma_TexCoord1f(GLfloat s) { DEBUG_GLCMDS(("TexCoord1f: %f\n", s)); + + WRITEF(gCCPriv->buf, Ts1, s); } void _gamma_TexCoord1fv(const GLfloat *v) { DEBUG_GLCMDS(("TexCoord1fv: %f\n", *v)); + + WRITEF(gCCPriv->buf, Ts1, v[0]); } void _gamma_TexCoord1i(GLint s) { + GLfloat x; + DEBUG_GLCMDS(("TexCoord1i: %d\n", (int)s)); + + x = INT_TO_FLOAT(s); + + _gamma_TexCoord1f(x); } void _gamma_TexCoord1iv(const GLint *v) { + GLfloat p[1]; + DEBUG_GLCMDS(("TexCoord1iv: %d\n", (int)*v)); + + p[0] = INT_TO_FLOAT(v[0]); + + _gamma_TexCoord1fv(p); } void _gamma_TexCoord1s(GLshort s) { + GLfloat x; + DEBUG_GLCMDS(("TexCoord1s: %d\n", s)); + + x = SHORT_TO_FLOAT(s); + + _gamma_TexCoord1f(x); } void _gamma_TexCoord1sv(const GLshort *v) { + GLfloat p[1]; + DEBUG_GLCMDS(("TexCoord1sv: %d\n", *v)); + + p[0] = SHORT_TO_FLOAT(v[0]); + + _gamma_TexCoord1fv(p); } void _gamma_TexCoord2d(GLdouble s, GLdouble t) { DEBUG_GLCMDS(("TexCoord2d: %f %f\n", s, t)); + + _gamma_TexCoord2f((GLfloat)s,(GLfloat)t); } void _gamma_TexCoord2dv(const GLdouble *v) { DEBUG_GLCMDS(("TexCoord2dv: %f %f\n", v[0], v[1])); + + _gamma_TexCoord2fv((GLfloat*)v); } void _gamma_TexCoord2f(GLfloat s, GLfloat t) @@ -2533,107 +3295,240 @@ void _gamma_TexCoord2f(GLfloat s, GLfloat t) void _gamma_TexCoord2fv(const GLfloat *v) { DEBUG_GLCMDS(("TexCoord2fv: %f %f\n", v[0], v[1])); + + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITEF(gCCPriv->buf, Tt2, v[1]); + WRITEF(gCCPriv->buf, Ts2, v[0]); } void _gamma_TexCoord2i(GLint s, GLint t) { + GLfloat x,y; + DEBUG_GLCMDS(("TexCoord2i: %d %d\n", (int)s, (int)t)); + + x = INT_TO_FLOAT(s); + y = INT_TO_FLOAT(t); + + _gamma_TexCoord2f(x,y); } void _gamma_TexCoord2iv(const GLint *v) { + GLfloat p[2]; + DEBUG_GLCMDS(("TexCoord2iv: %d %d\n", (int)v[0], (int)v[1])); + + p[0] = INT_TO_FLOAT(v[0]); + p[1] = INT_TO_FLOAT(v[1]); + + _gamma_TexCoord2fv(p); } void _gamma_TexCoord2s(GLshort s, GLshort t) { + GLfloat x,y; + DEBUG_GLCMDS(("TexCoord2s: %d %d\n", s, t)); + + x = SHORT_TO_FLOAT(s); + y = SHORT_TO_FLOAT(t); + + _gamma_TexCoord2f(x,y); } void _gamma_TexCoord2sv(const GLshort *v) { + GLfloat p[2]; + DEBUG_GLCMDS(("TexCoord2sv: %d %d\n", v[0], v[1])); + + p[0] = SHORT_TO_FLOAT(v[0]); + p[1] = SHORT_TO_FLOAT(v[1]); + + _gamma_TexCoord2fv(p); } void _gamma_TexCoord3d(GLdouble s, GLdouble t, GLdouble r) { DEBUG_GLCMDS(("TexCoord3d: %f %f %f\n", s, t, r)); + + _gamma_TexCoord3f((GLfloat)s,(GLfloat)t,(GLfloat)r); } void _gamma_TexCoord3dv(const GLdouble *v) { DEBUG_GLCMDS(("TexCoord3dv: %f %f %f\n", v[0], v[1], v[2])); + + _gamma_TexCoord3fv((GLfloat*)v); } void _gamma_TexCoord3f(GLfloat s, GLfloat t, GLfloat r) { DEBUG_GLCMDS(("TexCoord3f: %f %f %f\n", s, t, r)); + + _gamma_TexCoord4f(s,t,r,1.0f); } void _gamma_TexCoord3fv(const GLfloat *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("TexCoord3fv: %f %f %f\n", v[0], v[1], v[2])); + + p[0] = v[0]; + p[1] = v[1]; + p[2] = v[2]; + p[3] = 1.0f; + + _gamma_TexCoord4fv(p); } void _gamma_TexCoord3i(GLint s, GLint t, GLint r) { + GLfloat x,y,z; + DEBUG_GLCMDS(("TexCoord3i: %d %d %d\n", (int)s, (int)t, (int)r)); + + x = INT_TO_FLOAT(s); + y = INT_TO_FLOAT(t); + z = INT_TO_FLOAT(r); + + _gamma_TexCoord4f(x,y,z,1.0f); } void _gamma_TexCoord3iv(const GLint *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("TexCoord3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2])); + + p[0] = INT_TO_FLOAT(v[0]); + p[1] = INT_TO_FLOAT(v[1]); + p[2] = INT_TO_FLOAT(v[2]); + p[3] = 1.0f; + + _gamma_TexCoord4fv(p); } void _gamma_TexCoord3s(GLshort s, GLshort t, GLshort r) { + GLfloat x,y,z; + DEBUG_GLCMDS(("TexCoord3s: %d %d %d\n", s, t, r)); + + x = SHORT_TO_FLOAT(s); + y = SHORT_TO_FLOAT(t); + z = SHORT_TO_FLOAT(r); + + _gamma_TexCoord4f(x,y,z,1.0f); } void _gamma_TexCoord3sv(const GLshort *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("TexCoord3sv: %d %d %d\n", v[0], v[1], v[2])); + + p[0] = SHORT_TO_FLOAT(v[0]); + p[1] = SHORT_TO_FLOAT(v[1]); + p[2] = SHORT_TO_FLOAT(v[2]); + p[3] = 1.0f; + + _gamma_TexCoord4fv(p); } void _gamma_TexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q) { DEBUG_GLCMDS(("TexCoord4d: %f %f %f %f\n", s, t, r, q)); + + _gamma_TexCoord4f((GLfloat)s,(GLfloat)t,(GLfloat)r,(GLfloat)q); } void _gamma_TexCoord4dv(const GLdouble *v) { DEBUG_GLCMDS(("TexCoord4dv: %f %f %f %f\n", v[0], v[1], v[2], v[3])); + + _gamma_TexCoord4fv((GLfloat*)v); } void _gamma_TexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { DEBUG_GLCMDS(("TexCoord4f: %f %f %f %f\n", s, t, r, q)); + + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); + WRITEF(gCCPriv->buf, Tq4, q); + WRITEF(gCCPriv->buf, Tr4, r); + WRITEF(gCCPriv->buf, Tt4, t); + WRITEF(gCCPriv->buf, Ts4, s); } void _gamma_TexCoord4fv(const GLfloat *v) { DEBUG_GLCMDS(("TexCoord4fv: %f %f %f %f\n", v[0], v[1], v[2], v[3])); + + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); + WRITEF(gCCPriv->buf, Tq4, v[3]); + WRITEF(gCCPriv->buf, Tr4, v[2]); + WRITEF(gCCPriv->buf, Tt4, v[1]); + WRITEF(gCCPriv->buf, Ts4, v[0]); } void _gamma_TexCoord4i(GLint s, GLint t, GLint r, GLint q) { + GLfloat x,y,z,a; + DEBUG_GLCMDS(("TexCoord4i: %d %d %d %d\n", (int)s, (int)t, (int)r, (int)q)); + + x = INT_TO_FLOAT(s); + y = INT_TO_FLOAT(t); + z = INT_TO_FLOAT(r); + a = INT_TO_FLOAT(q); + + _gamma_TexCoord4f(x,y,z,a); } void _gamma_TexCoord4iv(const GLint *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("TexCoord4iv: %d %d %d %d\n", (int)v[0], (int)v[1], (int)v[2], (int)v[3])); + + p[0] = INT_TO_FLOAT(v[0]); + p[1] = INT_TO_FLOAT(v[1]); + p[2] = INT_TO_FLOAT(v[2]); + p[3] = INT_TO_FLOAT(v[3]); + + _gamma_TexCoord4fv(p); } void _gamma_TexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q) { + GLfloat x,y,z,a; + DEBUG_GLCMDS(("TexCoord4s: %d %d %d %d\n", s, t, r, q)); + + x = SHORT_TO_FLOAT(s); + y = SHORT_TO_FLOAT(t); + z = SHORT_TO_FLOAT(r); + a = SHORT_TO_FLOAT(q); + + _gamma_TexCoord4f(s,t,r,q); } void _gamma_TexCoord4sv(const GLshort *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("TexCoord4sv: %d %d %d %d\n", v[0], v[1], v[2], v[3])); + + p[0] = SHORT_TO_FLOAT(v[0]); + p[1] = SHORT_TO_FLOAT(v[1]); + p[2] = SHORT_TO_FLOAT(v[2]); + p[3] = SHORT_TO_FLOAT(v[3]); + + _gamma_TexCoord4fv(p); } void _gamma_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) @@ -2678,6 +3573,33 @@ void _gamma_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params) { DEBUG_GLCMDS(("TexEnvfv: %04x %04x %f\n", (int)target, (int)pname, *params)); + + if (target != GL_TEXTURE_ENV) { + /* ERROR !! */ + } + + switch (pname) { + case GL_TEXTURE_ENV_MODE: + gCCPriv->curTexObj->TextureColorMode &= ~TCM_ApplicationMask; + switch ((int)params[0]) { + case GL_MODULATE: + gCCPriv->curTexObj->TextureColorMode |= TCM_Modulate; + break; + case GL_DECAL: + gCCPriv->curTexObj->TextureColorMode |= TCM_Decal; + break; + case GL_BLEND: + gCCPriv->curTexObj->TextureColorMode |= TCM_Blend; + break; + case GL_REPLACE: + gCCPriv->curTexObj->TextureColorMode |= TCM_Replace; + break; + } + } + + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, TextureColorMode, + gCCPriv->curTexObj->TextureColorMode); } void _gamma_TexEnvi(GLenum target, GLenum pname, GLint param) @@ -2745,10 +3667,12 @@ void _gamma_TexImage2D(GLenum target, GLint level, GLint components, GLsizei wid if (target == GL_TEXTURE_1D) { /* NOT_DONE */ + DEBUG_ERROR(("TexImage2D: 1D requested - ERROR\n")); } else if (target == GL_TEXTURE_2D) { /* NOT_DONE: The follow are not currently supported... */ - if (border != 0 || format != GL_RGBA || type != GL_UNSIGNED_BYTE || + if (border != 0 /* || format != GL_RGBA */ || type != GL_UNSIGNED_BYTE || (components != 3 && components != 4)) { + DEBUG_ERROR(("TexImage2D: 2D op not supported - ERROR\n")); return; } @@ -2790,7 +3714,11 @@ void _gamma_TexImage2D(GLenum target, GLint level, GLint components, GLsizei wid break; } +#if X_BYTE_ORDER == X_LITTLE_ENDIAN t->TextureFormat = (TF_LittleEndian | +#else + t->TextureFormat = (TF_BigEndian | +#endif TF_ColorOrder_BGR | TF_Compnents_4 | TF_OutputFmt_Texel); @@ -2804,14 +3732,17 @@ void _gamma_TexImage2D(GLenum target, GLint level, GLint components, GLsizei wid t->image[level] = driTMMInsertImage(gCCPriv->tmm, width, height, 1<<l2d, image, NULL); + if (!t->image[level]) { /* NOT_DONE: Handle error */ + DEBUG_ERROR(("TexImage2D: unable1\n")); } /* Make the new image resident (and all of the other mipmaps) */ - if (!driTMMMakeImagesResident(gCCPriv->tmm, MIPMAP_LEVELS, - t->image, addrs)) { + if (driTMMMakeImagesResident(gCCPriv->tmm, MIPMAP_LEVELS, + t->image, addrs) < 0) { /* NOT_DONE: Handle error */ + DEBUG_ERROR(("TexImage2D: unable2\n")); } for (i = 0; i < MIPMAP_LEVELS; i++) @@ -3010,6 +3941,123 @@ void _gamma_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { DEBUG_GLCMDS(("TexParameterfv: %04x %04x %f\n", (int)target, (int)pname, *params)); + + if (target == GL_TEXTURE_1D) { + /* NOT_DONE */ + } else if (target == GL_TEXTURE_2D) { + switch (pname) { + case GL_TEXTURE_MAG_FILTER: + gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_Mag_Mask; + switch ((int)params[0]) { + case GL_NEAREST: + gCCPriv->curTexObj2D->TextureReadMode |= + TRM_Mag_Nearest; + break; + case GL_LINEAR: + gCCPriv->curTexObj2D->TextureReadMode |= + TRM_Mag_Linear; + break; + default: + break; + } + + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, TextureReadMode, + gCCPriv->curTexObj2D->TextureReadMode); + break; + case GL_TEXTURE_MIN_FILTER: + gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_Min_Mask; + gCCPriv->curTexObj2D->TextureReadMode |= TRM_MipMapEnable; + gCCPriv->curTexObj2D->TextureAddressMode |= TAM_LODEnable; + switch ((int)params[0]) { + case GL_NEAREST: + gCCPriv->curTexObj2D->TextureReadMode |= + TRM_Min_Nearest; + gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_MipMapEnable; + gCCPriv->curTexObj2D->TextureAddressMode &= ~TAM_LODEnable; + break; + case GL_LINEAR: + gCCPriv->curTexObj2D->TextureReadMode |= + TRM_Min_Linear; + gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_MipMapEnable; + gCCPriv->curTexObj2D->TextureAddressMode &= ~TAM_LODEnable; + break; + case GL_NEAREST_MIPMAP_NEAREST: + gCCPriv->curTexObj2D->TextureReadMode |= + TRM_Min_NearestMMNearest; + break; + case GL_LINEAR_MIPMAP_NEAREST: + gCCPriv->curTexObj2D->TextureReadMode |= + TRM_Min_NearestMMLinear; + break; + case GL_NEAREST_MIPMAP_LINEAR: + gCCPriv->curTexObj2D->TextureReadMode |= + TRM_Min_LinearMMNearest; + break; + case GL_LINEAR_MIPMAP_LINEAR: + gCCPriv->curTexObj2D->TextureReadMode |= + TRM_Min_LinearMMLinear; + break; + default: + break; + } + + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, TextureReadMode, + gCCPriv->curTexObj2D->TextureReadMode); + WRITE(gCCPriv->buf, TextureAddressMode, + gCCPriv->curTexObj2D->TextureAddressMode); + break; + case GL_TEXTURE_WRAP_S: + gCCPriv->curTexObj2D->TextureAddressMode &= ~TAM_SWrap_Mask; + gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_UWrap_Mask; + switch ((int)params[0]) { + case GL_CLAMP: + gCCPriv->curTexObj2D->TextureAddressMode |= TAM_SWrap_Clamp; + gCCPriv->curTexObj2D->TextureReadMode |= TRM_UWrap_Clamp; + break; + case GL_REPEAT: + gCCPriv->curTexObj2D->TextureAddressMode |= TAM_SWrap_Repeat; + gCCPriv->curTexObj2D->TextureReadMode |= TRM_UWrap_Repeat; + break; + default: + break; + } + + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, TextureReadMode, + gCCPriv->curTexObj2D->TextureReadMode); + WRITE(gCCPriv->buf, TextureAddressMode, + gCCPriv->curTexObj2D->TextureAddressMode); + break; + case GL_TEXTURE_WRAP_T: + gCCPriv->curTexObj2D->TextureAddressMode &= ~TAM_TWrap_Mask; + gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_VWrap_Mask; + switch ((int)params[0]) { + case GL_CLAMP: + gCCPriv->curTexObj2D->TextureAddressMode |= TAM_TWrap_Clamp; + gCCPriv->curTexObj2D->TextureReadMode |= TRM_VWrap_Clamp; + break; + case GL_REPEAT: + gCCPriv->curTexObj2D->TextureAddressMode |= TAM_TWrap_Repeat; + gCCPriv->curTexObj2D->TextureReadMode |= TRM_VWrap_Repeat; + break; + default: + break; + } + + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, TextureReadMode, + gCCPriv->curTexObj2D->TextureReadMode); + WRITE(gCCPriv->buf, TextureAddressMode, + gCCPriv->curTexObj2D->TextureAddressMode); + break; + default: + break; + } + } else { + /* ERROR !! */ + } } void _gamma_TexParameteri(GLenum target, GLenum pname, GLint param) @@ -3054,8 +4102,8 @@ void _gamma_TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffs ** format for the image that it is replacing. */ - if (!driTMMSubImage(gCCPriv->tmm, gCCPriv->curTexObj2D->image[level], - xoffset, yoffset, width, height, image)) { + if (driTMMSubImage(gCCPriv->tmm, gCCPriv->curTexObj2D->image[level], + xoffset, yoffset, width, height, image) < 0) { /* NOT_DONE: Handle error */ } } else { @@ -3089,7 +4137,7 @@ void _gamma_Translatef(GLfloat x, GLfloat y, GLfloat z) GLfloat m[16]; int i; - DEBUG_GLCMDS(("Tranlatef: %f %f %f\n", x, y, z)); + DEBUG_GLCMDS(("Translatef: %f %f %f\n", x, y, z)); for (i = 0; i < 16; i++) if (i % 5 == 0) @@ -3108,26 +4156,21 @@ void _gamma_Translatef(GLfloat x, GLfloat y, GLfloat z) void _gamma_Vertex2d(GLdouble x, GLdouble y) { DEBUG_GLCMDS(("Vertex2d: %f %f\n", x, y)); + + _gamma_Vertex2f((GLfloat)x,(GLfloat)y); } void _gamma_Vertex2dv(const GLdouble *v) { DEBUG_GLCMDS(("Vertex2dv: %f %f\n", v[0], v[1])); + + _gamma_Vertex2fv((GLfloat*)v); } void _gamma_Vertex2f(GLfloat x, GLfloat y) { DEBUG_GLCMDS(("Vertex2f: %f %f\n", x, y)); -#ifdef RANDOMIZE_COLORS - { - GLuint c; - c = (random() / (double)RAND_MAX) * 16777216; - CHECK_DMA_BUFFER(gCC, gCCPriv, 1); - WRITE(gCCPriv->buf, PackedColor4, c); - } -#endif - CHECK_DMA_BUFFER(gCC, gCCPriv, 2); WRITEF(gCCPriv->buf, Vy, y); WRITEF(gCCPriv->buf, Vx2, x); @@ -3136,51 +4179,78 @@ void _gamma_Vertex2f(GLfloat x, GLfloat y) void _gamma_Vertex2fv(const GLfloat *v) { DEBUG_GLCMDS(("Vertex2fv: %f %f\n", v[0], v[1])); + + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITEF(gCCPriv->buf, Vy, v[1]); + WRITEF(gCCPriv->buf, Vx2, v[0]); } void _gamma_Vertex2i(GLint x, GLint y) { + GLfloat a,b; + DEBUG_GLCMDS(("Vertex2i: %d %d\n", (int)x, (int)y)); + + a = INT_TO_FLOAT(x); + b = INT_TO_FLOAT(y); + + _gamma_Vertex2f(a,b); } void _gamma_Vertex2iv(const GLint *v) { + GLfloat p[2]; + DEBUG_GLCMDS(("Vertex2iv: %d %d\n", (int)v[0], (int)v[1])); + + p[0] = INT_TO_FLOAT(v[0]); + p[1] = INT_TO_FLOAT(v[1]); + + _gamma_Vertex2fv(p); } void _gamma_Vertex2s(GLshort x, GLshort y) { + GLfloat a,b; + DEBUG_GLCMDS(("Vertex2s: %d %d\n", x, y)); + + a = SHORT_TO_FLOAT(x); + b = SHORT_TO_FLOAT(y); + + _gamma_Vertex2f(a,b); } void _gamma_Vertex2sv(const GLshort *v) { + GLfloat p[2]; + DEBUG_GLCMDS(("Vertex2sv: %d %d\n", v[0], v[1])); + + p[0] = SHORT_TO_FLOAT(v[0]); + p[1] = SHORT_TO_FLOAT(v[1]); + + _gamma_Vertex2fv(p); } void _gamma_Vertex3d(GLdouble x, GLdouble y, GLdouble z) { DEBUG_GLCMDS(("Vertex3d: %f %f %f\n", x, y, z)); + + _gamma_Vertex3f((GLfloat)x,(GLfloat)y,(GLfloat)z); } void _gamma_Vertex3dv(const GLdouble *v) { DEBUG_GLCMDS(("Vertex2fv: %f %f %f\n", v[0], v[1], v[2])); + + _gamma_Vertex3fv((GLfloat*)v); } void _gamma_Vertex3f(GLfloat x, GLfloat y, GLfloat z) { DEBUG_GLCMDS(("Vertex3f: %f %f %f\n", x, y, z)); -#ifdef RANDOMIZE_COLORS - { - GLuint c; - c = (random() / (double)RAND_MAX) * 16777216; - CHECK_DMA_BUFFER(gCC, gCCPriv, 1); - WRITE(gCCPriv->buf, PackedColor4, c); - } -#endif - CHECK_DMA_BUFFER(gCC, gCCPriv, 3); WRITEF(gCCPriv->buf, Vz, z); WRITEF(gCCPriv->buf, Vy, y); @@ -3191,15 +4261,6 @@ void _gamma_Vertex3fv(const GLfloat *v) { DEBUG_GLCMDS(("Vertex3fv: %f %f %f\n", v[0], v[1], v[2])); -#ifdef RANDOMIZE_COLORS - { - GLuint c; - c = (random() / (double)RAND_MAX) * 16777216; - CHECK_DMA_BUFFER(gCC, gCCPriv, 1); - WRITE(gCCPriv->buf, PackedColor4, c); - } -#endif - CHECK_DMA_BUFFER(gCC, gCCPriv, 3); WRITEF(gCCPriv->buf, Vz, v[2]); WRITEF(gCCPriv->buf, Vy, v[1]); @@ -3208,63 +4269,147 @@ void _gamma_Vertex3fv(const GLfloat *v) void _gamma_Vertex3i(GLint x, GLint y, GLint z) { + GLfloat a,b,c; + DEBUG_GLCMDS(("Vertex3i: %d %d %d\n", (int)x, (int)y, (int)z)); + + a = INT_TO_FLOAT(x); + b = INT_TO_FLOAT(y); + c = INT_TO_FLOAT(z); + + _gamma_Vertex3f(a,b,c); } void _gamma_Vertex3iv(const GLint *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Vertex3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2])); + + p[0] = INT_TO_FLOAT(v[0]); + p[1] = INT_TO_FLOAT(v[1]); + p[2] = INT_TO_FLOAT(v[2]); + + _gamma_Vertex3fv(p); } void _gamma_Vertex3s(GLshort x, GLshort y, GLshort z) { + GLfloat a,b,c; + DEBUG_GLCMDS(("Vertex3s: %d %d %d\n", x, y, z)); + + a = SHORT_TO_FLOAT(x); + b = SHORT_TO_FLOAT(y); + c = SHORT_TO_FLOAT(z); + + _gamma_Vertex3f(a,b,c); } void _gamma_Vertex3sv(const GLshort *v) { + GLfloat p[3]; + DEBUG_GLCMDS(("Vertex3sv: %d %d %d\n", v[0], v[1], v[2])); + + p[0] = SHORT_TO_FLOAT(v[0]); + p[1] = SHORT_TO_FLOAT(v[1]); + p[2] = SHORT_TO_FLOAT(v[2]); + + _gamma_Vertex3fv(p); } void _gamma_Vertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { DEBUG_GLCMDS(("Vertex4d: %f %f %f %f\n", x, y, z, w)); + + _gamma_Vertex4f((GLfloat)x,(GLfloat)y,(GLfloat)z,(GLfloat)w); } void _gamma_Vertex4dv(const GLdouble *v) { DEBUG_GLCMDS(("Vertex4dv: %f %f %f %f\n", v[0], v[1], v[2], v[3])); + + _gamma_Vertex4fv((GLfloat*)v); } void _gamma_Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { DEBUG_GLCMDS(("Vertex4f: %f %f %f %f\n", x, y, z, w)); + + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); + WRITEF(gCCPriv->buf, Vw, w); + WRITEF(gCCPriv->buf, Vz, z); + WRITEF(gCCPriv->buf, Vy, y); + WRITEF(gCCPriv->buf, Vx4, x); } void _gamma_Vertex4fv(const GLfloat *v) { DEBUG_GLCMDS(("Vertex4fv: %f %f %f %f\n", v[0], v[1], v[2], v[3])); + + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); + WRITEF(gCCPriv->buf, Vw, v[3]); + WRITEF(gCCPriv->buf, Vz, v[2]); + WRITEF(gCCPriv->buf, Vy, v[1]); + WRITEF(gCCPriv->buf, Vx4, v[0]); } void _gamma_Vertex4i(GLint x, GLint y, GLint z, GLint w) { + GLfloat a,b,c,d; + DEBUG_GLCMDS(("Vertex4i: %d %d %d %d\n", (int)x, (int)y, (int)z, (int)w)); + + a = INT_TO_FLOAT(x); + b = INT_TO_FLOAT(y); + c = INT_TO_FLOAT(z); + d = INT_TO_FLOAT(w); + + _gamma_Vertex4f(a,b,c,d); } void _gamma_Vertex4iv(const GLint *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("Vertex4iv: %d %d %d %d\n", (int)v[0], (int)v[1], (int)v[2], (int)v[3])); + + p[0] = INT_TO_FLOAT(v[0]); + p[1] = INT_TO_FLOAT(v[1]); + p[2] = INT_TO_FLOAT(v[2]); + p[3] = INT_TO_FLOAT(v[3]); + + _gamma_Vertex4fv(p); } void _gamma_Vertex4s(GLshort x, GLshort y, GLshort z, GLshort w) { + GLfloat a,b,c,d; + DEBUG_GLCMDS(("Vertex4s: %d %d %d %d\n", x, y, z, w)); + + a = SHORT_TO_FLOAT(x); + b = SHORT_TO_FLOAT(y); + c = SHORT_TO_FLOAT(z); + d = SHORT_TO_FLOAT(w); + + _gamma_Vertex4f(a,b,c,d); } void _gamma_Vertex4sv(const GLshort *v) { + GLfloat p[4]; + DEBUG_GLCMDS(("Vertex4sv: %d %d %d %d\n", v[0], v[1], v[2], v[3])); + + p[0] = SHORT_TO_FLOAT(v[0]); + p[1] = SHORT_TO_FLOAT(v[1]); + p[2] = SHORT_TO_FLOAT(v[2]); + p[3] = SHORT_TO_FLOAT(v[3]); + + _gamma_Vertex4fv(p); } void _gamma_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) @@ -3280,10 +4425,10 @@ void _gamma_Viewport(GLint x, GLint y, GLsizei width, GLsizei height) DEBUG_GLCMDS(("Viewport: %d %d %d %d\n", (int)x, (int)y, (int)width, (int)height)); - gCCPriv->x = gCC->driContextPriv->driDrawablePriv->x + x; - gCCPriv->y = gCC->driContextPriv->driScreenPriv->fbHeight - - (gCC->driContextPriv->driDrawablePriv->y + - gCC->driContextPriv->driDrawablePriv->h) + y; + gCCPriv->x = gCC->driDrawablePriv->x + x; + gCCPriv->y = gCC->driScreenPriv->fbHeight - + (gCC->driDrawablePriv->y + + gCC->driDrawablePriv->h) + y; gCCPriv->w = width; gCCPriv->h = height; @@ -3296,16 +4441,21 @@ void _gamma_Viewport(GLint x, GLint y, GLsizei width, GLsizei height) oy = y + sy; CHECK_DMA_BUFFER(gCC, gCCPriv, 4); - WRITEF(gCCPriv->buf, ViewPortOffsetX, ox); - WRITEF(gCCPriv->buf, ViewPortOffsetY, oy); WRITEF(gCCPriv->buf, ViewPortScaleX, sx); WRITEF(gCCPriv->buf, ViewPortScaleY, sy); + WRITEF(gCCPriv->buf, ViewPortOffsetX, ox); + WRITEF(gCCPriv->buf, ViewPortOffsetY, oy); +#if 1 /* Err - this shouldn't be needed, but something isn't flushing */ + FLUSH_DMA_BUFFER(gCC,gCCPriv); +#endif } static GLint generic_noop(void) { + DEBUG_GLCMDS(("OOPS GENERIC NOOP CALLED\n")); + return 0; } diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h index ce804d018..e8fd5a0df 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h @@ -43,7 +43,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "gamma_regs.h" #include "gamma_macros.h" #include "gamma_texture.h" -#include "xmesaP.h" typedef struct { int regionCount; /* Count of register regions */ @@ -109,6 +108,12 @@ typedef struct { int AB_FBReadMode; int AB_FBReadMode_Save; int DeltaMode; + int ColorMaterialMode; + int MaterialMode; + int LightingMode; + int Light0Mode; + int Light1Mode; + int ScissorMode; int Window; /* GID part probably should be in draw priv */ gammaTexObj *curTexObj; @@ -140,8 +145,8 @@ extern void gammaLoadHWMatrix(void); extern void gammaInitHW(gammaContextPrivate *gcp); extern float IdentityMatrix[16]; -extern XMesaContext nullCC; -extern XMesaContext gCC; +extern __DRIcontextPrivate *nullCC; +extern __DRIcontextPrivate *gCC; extern gammaContextPrivate *gCCPriv; #endif diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c index edb1d3da0..87d68278b 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c @@ -29,27 +29,32 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Kevin E. Martin <kevin@precisioninsight.com> + * Alan Hourihane <Alan.Hourihane@btinternet.com> * */ #ifdef GLX_DIRECT_RENDERING #include "gamma_init.h" +#include "glint_dri.h" void gammaInitHW(gammaContextPrivate *gcp) { __DRIscreenPrivate *driScrnPriv = gcp->gammaScrnPriv->driScrnPriv; + GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv; - /* Set up each MX's ScanLineOwnership for OpenGL */ - CHECK_DMA_BUFFER(nullCC, gcp, 4); - WRITE(gcp->buf, BroadcastMask, 1); - WRITE(gcp->buf, ScanLineOwnership, 5); /* Use bottom left as [0,0] */ - WRITE(gcp->buf, BroadcastMask, 2); - WRITE(gcp->buf, ScanLineOwnership, 1); /* Use bottom left as [0,0] */ + if (gDRIPriv->numMXDevices == 2) { + /* Set up each MX's ScanLineOwnership for OpenGL */ + CHECK_DMA_BUFFER(nullCC, gcp, 4); + WRITE(gcp->buf, BroadcastMask, 1); + WRITE(gcp->buf, ScanLineOwnership, 5); /* Use bottom left as [0,0] */ + WRITE(gcp->buf, BroadcastMask, 2); + WRITE(gcp->buf, ScanLineOwnership, 1); /* Use bottom left as [0,0] */ - /* Broadcast to both MX's */ - CHECK_DMA_BUFFER(nullCC, gcp, 1); - WRITE(gcp->buf, BroadcastMask, 3); + /* Broadcast to both MX's */ + CHECK_DMA_BUFFER(nullCC, gcp, 1); + WRITE(gcp->buf, BroadcastMask, 3); + } /* Set MXs to known state */ CHECK_DMA_BUFFER(nullCC, gcp, 27); @@ -82,6 +87,7 @@ void gammaInitHW(gammaContextPrivate *gcp) WRITE(gcp->buf, PixelSize, 0); /* Set Gamma to known state */ + CHECK_DMA_BUFFER(nullCC, gcp, 10); WRITE(gcp->buf, TriangleMode, 0); WRITE(gcp->buf, GeometryMode, 0); WRITE(gcp->buf, NormalizeMode, 0); @@ -136,7 +142,10 @@ void gammaInitHW(gammaContextPrivate *gcp) WRITE(gcp->buf, AlphaTestMode, gcp->AlphaTestMode); WRITE(gcp->buf, AlphaBlendMode, gcp->AlphaBlendMode); WRITE(gcp->buf, DitherMode, DitherModeEnable | DM_ColorOrder_RGB); - WRITE(gcp->buf, RasterizerMode, RM_MultiGLINT | RM_BiasCoordNearHalf); + if (gDRIPriv->numMXDevices == 2) + WRITE(gcp->buf, RasterizerMode, RM_MultiGLINT | RM_BiasCoordNearHalf); + else + WRITE(gcp->buf, RasterizerMode, RM_BiasCoordNearHalf); WRITE(gcp->buf, GLINTWindow, gcp->Window); WRITE(gcp->buf, FastClearDepth, 0xffffffff); WRITE(gcp->buf, GLINTDepth, 0xffffffff); @@ -242,7 +251,7 @@ void gammaInitHW(gammaContextPrivate *gcp) CHECK_DMA_BUFFER(nullCC, gcp, 5); WRITE(gcp->buf, GeometryMode, gcp->GeometryMode); WRITE(gcp->buf, NormalizeMode, NormalizeModeDisable); - WRITE(gcp->buf, LightingMode, LightingModeDisable); + WRITE(gcp->buf, LightingMode, gcp->LightingMode); WRITE(gcp->buf, ColorMaterialMode, ColorMaterialModeDisable); WRITE(gcp->buf, MaterialMode, MaterialModeDisable); @@ -251,18 +260,18 @@ void gammaInitHW(gammaContextPrivate *gcp) WRITE(gcp->buf, BackSpecularExponent, 0); /* fixed point */ CHECK_DMA_BUFFER(nullCC, gcp, 29); - WRITEF(gcp->buf, FrontAmbientColorRed, 0.0); - WRITEF(gcp->buf, FrontAmbientColorGreen, 0.0); - WRITEF(gcp->buf, FrontAmbientColorBlue, 0.0); - WRITEF(gcp->buf, BackAmbientColorRed, 0.0); - WRITEF(gcp->buf, BackAmbientColorGreen, 0.0); - WRITEF(gcp->buf, BackAmbientColorBlue, 0.0); - WRITEF(gcp->buf, FrontDiffuseColorRed, 0.0); - WRITEF(gcp->buf, FrontDiffuseColorGreen, 0.0); - WRITEF(gcp->buf, FrontDiffuseColorBlue, 0.0); - WRITEF(gcp->buf, BackDiffuseColorRed, 0.0); - WRITEF(gcp->buf, BackDiffuseColorGreen, 0.0); - WRITEF(gcp->buf, BackDiffuseColorBlue, 0.0); + WRITEF(gcp->buf, FrontAmbientColorRed, 0.2); + WRITEF(gcp->buf, FrontAmbientColorGreen, 0.2); + WRITEF(gcp->buf, FrontAmbientColorBlue, 0.2); + WRITEF(gcp->buf, BackAmbientColorRed, 0.2); + WRITEF(gcp->buf, BackAmbientColorGreen, 0.2); + WRITEF(gcp->buf, BackAmbientColorBlue, 0.2); + WRITEF(gcp->buf, FrontDiffuseColorRed, 0.8); + WRITEF(gcp->buf, FrontDiffuseColorGreen, 0.8); + WRITEF(gcp->buf, FrontDiffuseColorBlue, 0.8); + WRITEF(gcp->buf, BackDiffuseColorRed, 0.8); + WRITEF(gcp->buf, BackDiffuseColorGreen, 0.8); + WRITEF(gcp->buf, BackDiffuseColorBlue, 0.8); WRITEF(gcp->buf, FrontSpecularColorRed, 0.0); WRITEF(gcp->buf, FrontSpecularColorGreen, 0.0); WRITEF(gcp->buf, FrontSpecularColorBlue, 0.0); @@ -275,11 +284,11 @@ void gammaInitHW(gammaContextPrivate *gcp) WRITEF(gcp->buf, BackEmissiveColorRed, 0.0); WRITEF(gcp->buf, BackEmissiveColorGreen, 0.0); WRITEF(gcp->buf, BackEmissiveColorBlue, 0.0); - WRITEF(gcp->buf, SceneAmbientColorRed, 0.0); - WRITEF(gcp->buf, SceneAmbientColorGreen, 0.0); - WRITEF(gcp->buf, SceneAmbientColorBlue, 0.0); - WRITEF(gcp->buf, FrontAlpha, 0.0); - WRITEF(gcp->buf, BackAlpha, 0.0); + WRITEF(gcp->buf, SceneAmbientColorRed, 0.2); + WRITEF(gcp->buf, SceneAmbientColorGreen, 0.2); + WRITEF(gcp->buf, SceneAmbientColorBlue, 0.2); + WRITEF(gcp->buf, FrontAlpha, 1.0); + WRITEF(gcp->buf, BackAlpha, 1.0); CHECK_DMA_BUFFER(nullCC, gcp, 8); WRITE(gcp->buf, PointMode, (PM_AntialiasDisable | @@ -319,28 +328,28 @@ void gammaInitHW(gammaContextPrivate *gcp) WRITE(gcp->buf, Light14Mode, LNM_Off); WRITE(gcp->buf, Light15Mode, LNM_Off); - CHECK_DMA_BUFFER(nullCC, gcp, 21); - WRITEF(gcp->buf, FrontAmbientColorRed, 1.0); - WRITEF(gcp->buf, FrontAmbientColorGreen, 1.0); - WRITEF(gcp->buf, FrontAmbientColorBlue, 1.0); - WRITEF(gcp->buf, BackAmbientColorRed, 1.0); - WRITEF(gcp->buf, BackAmbientColorGreen, 1.0); - WRITEF(gcp->buf, BackAmbientColorBlue, 1.0); - WRITEF(gcp->buf, FrontDiffuseColorRed, 1.0); - WRITEF(gcp->buf, FrontDiffuseColorGreen, 1.0); - WRITEF(gcp->buf, FrontDiffuseColorBlue, 1.0); - WRITEF(gcp->buf, BackDiffuseColorRed, 1.0); - WRITEF(gcp->buf, BackDiffuseColorGreen, 1.0); - WRITEF(gcp->buf, BackDiffuseColorBlue, 1.0); - WRITEF(gcp->buf, FrontSpecularColorRed, 0.0); - WRITEF(gcp->buf, FrontSpecularColorGreen, 0.0); - WRITEF(gcp->buf, FrontSpecularColorBlue, 0.0); - WRITEF(gcp->buf, BackSpecularColorRed, 0.0); - WRITEF(gcp->buf, BackSpecularColorGreen, 0.0); - WRITEF(gcp->buf, BackSpecularColorBlue, 0.0); - WRITEF(gcp->buf, SceneAmbientColorRed, 0.0); - WRITEF(gcp->buf, SceneAmbientColorGreen, 0.0); - WRITEF(gcp->buf, SceneAmbientColorBlue, 0.0); + CHECK_DMA_BUFFER(nullCC, gcp, 22); + WRITEF(gcp->buf, Light0AmbientIntensityBlue, 0.0); + WRITEF(gcp->buf, Light0AmbientIntensityGreen, 0.0); + WRITEF(gcp->buf, Light0AmbientIntensityRed, 0.0); + WRITEF(gcp->buf, Light0DiffuseIntensityBlue, 1.0); + WRITEF(gcp->buf, Light0DiffuseIntensityGreen, 1.0); + WRITEF(gcp->buf, Light0DiffuseIntensityRed, 1.0); + WRITEF(gcp->buf, Light0SpecularIntensityBlue, 1.0); + WRITEF(gcp->buf, Light0SpecularIntensityGreen, 1.0); + WRITEF(gcp->buf, Light0SpecularIntensityRed, 1.0); + WRITEF(gcp->buf, Light0SpotlightDirectionZ, 0.0); + WRITEF(gcp->buf, Light0SpotlightDirectionY, 0.0); + WRITEF(gcp->buf, Light0SpotlightDirectionX, -1.0); + WRITEF(gcp->buf, Light0SpotlightExponent, 0.0); + WRITEF(gcp->buf, Light0PositionZ, 0.0); + WRITEF(gcp->buf, Light0PositionY, 0.0); + WRITEF(gcp->buf, Light0PositionX, 1.0); + WRITEF(gcp->buf, Light0PositionW, 0.0); + WRITEF(gcp->buf, Light0CosSpotlightCutoffAngle, -1.0); + WRITEF(gcp->buf, Light0ConstantAttenuation, 1.0); + WRITEF(gcp->buf, Light0LinearAttenuation, 0.0); + WRITEF(gcp->buf, Light0QuadraticAttenuation,0.0); CHECK_DMA_BUFFER(nullCC, gcp, 6); WRITEF(gcp->buf, ViewPortScaleX, (gcp->w)/2.0); diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_macros.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_macros.h index ae923c7bf..c458bf642 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_macros.h +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_macros.h @@ -228,14 +228,14 @@ do { \ #ifdef DO_VALIDATE #define VALIDATE_DRAWABLE_INFO_NO_LOCK(gcc,gcp) \ do { \ - __DRIcontextPrivate *pcp = gcc->driContextPriv; \ + __DRIcontextPrivate *pcp = gcc; \ __DRIscreenPrivate *psp = pcp->driScreenPriv; \ __DRIdrawablePrivate *pdp = pcp->driDrawablePriv; \ \ if (*(pdp->pStamp) != pdp->lastStamp) { \ int old_index = pdp->index; \ while (*(pdp->pStamp) != pdp->lastStamp) { \ - DRI_MESA_VALIDATE_DRAWABLE_INFO(gcc->display, psp->myNum, pdp);\ + DRI_MESA_VALIDATE_DRAWABLE_INFO(pcp->display, psp->myNum, pdp);\ } \ \ if (pdp->index != old_index) { \ @@ -303,7 +303,7 @@ do { \ #define VALIDATE_DRAWABLE_INFO(gcc,gcp) \ do { \ - __DRIcontextPrivate *pcp = gcc->driContextPriv; \ + __DRIcontextPrivate *pcp = gcc; \ __DRIscreenPrivate *psp = pcp->driScreenPriv; \ \ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_matrix.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_matrix.c index f6c166609..17220fbb4 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_matrix.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_matrix.c @@ -163,9 +163,7 @@ void gammaLoadHWMatrix(void) WRITEF(gCCPriv->buf, ModelViewMatrix13, gCCPriv->ModelView[13]); WRITEF(gCCPriv->buf, ModelViewMatrix14, gCCPriv->ModelView[14]); WRITEF(gCCPriv->buf, ModelViewMatrix15, gCCPriv->ModelView[15]); - /* Fall through to load ModelViewProjectionMatrix */ #endif - case GL_PROJECTION: CHECK_DMA_BUFFER(gCC, gCCPriv, 16); WRITEF(gCCPriv->buf, diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h index 3dd4b8783..b13dbdba5 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h @@ -163,6 +163,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define FBWriteModeEnable 0x00000001 #define FBW_UploadColorData 0x00000008 +/* FogMode */ +#define FogModeDisable 0x00000000 +#define FogModeEnable 0x00000001 + /* LBWriteMode */ #define LBWriteModeDisable 0x00000000 #define LBWriteModeEnable 0x00000001 @@ -391,14 +395,17 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define GM_FogLinear 0x00000000 #define GM_FogExp 0x00000004 #define GM_FogExpSquared 0x00000008 +#define GM_FogMask 0x0000000C #define GM_FrontPolyPoint 0x00000000 #define GM_FrontPolyLine 0x00000010 #define GM_FrontPolyFill 0x00000020 #define GM_BackPolyPoint 0x00000000 #define GM_BackPolyLine 0x00000040 #define GM_BackPolyFill 0x00000080 +#define GM_FB_PolyMask 0x000000F0 #define GM_FrontFaceCW 0x00000000 #define GM_FrontFaceCCW 0x00000100 +#define GM_FFMask 0x00000100 #define GM_PolyCullDisable 0x00000000 #define GM_PolyCullEnable 0x00000200 #define GM_PolyCullFront 0x00000000 @@ -480,18 +487,44 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* LightingMode */ #define LightingModeDisable 0x00000000 #define LightingModeEnable 0x00000001 +#define LightingModeTwoSides 0x00000002 +#define LightingModeLocalViewer 0x00000008 + +/* Light0Mode */ +#define Light0ModeDisable 0x00000000 +#define Light0ModeEnable 0x00000001 +#define Light0ModeSpotLight 0x00000002 +#define Light0ModeAttenuation 0x00000004 +#define Light0ModeLocal 0x00000008 + +/* Light0Mode */ +#define Light1ModeDisable 0x00000000 +#define Light1ModeEnable 0x00000001 +#define Light1ModeSpotLight 0x00000002 +#define Light1ModeAttenuation 0x00000004 +#define Light1ModeLocal 0x00000008 /* ColorMaterialMode */ #define ColorMaterialModeDisable 0x00000000 #define ColorMaterialModeEnable 0x00000001 +#define ColorMaterialModeFront 0x00000000 +#define ColorMaterialModeBack 0x00000002 +#define ColorMaterialModeFrontAndBack 0x00000004 +#define ColorMaterialModeEmission 0x00000000 +#define ColorMaterialModeAmbient 0x00000008 +#define ColorMaterialModeDiffuse 0x00000010 +#define ColorMaterialModeSpecular 0x00000018 +#define ColorMaterialModeAmbAndDiff 0x00000020 +#define ColorMaterialModeMask 0x0000003e /* MaterialMode */ #define MaterialModeDisable 0x00000000 #define MaterialModeEnable 0x00000001 +#define MaterialModeTwoSides 0x00000080 /* DeltaMode */ #define DM_Target300SX 0x00000000 -#define DM_Target300TXMX 0x00000001 +#define DM_Target500TXMX 0x00000001 #define DM_Depth16 0x00000004 #define DM_Depth24 0x00000008 #define DM_Depth32 0x0000000c diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_texture.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_texture.c index 14a993969..ffa437ed2 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_texture.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_texture.c @@ -34,6 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING +#include <Xarch.h> #include <X11/Xlibint.h> #include "gamma_init.h" #include <string.h> @@ -74,7 +75,11 @@ void gammaTOInit(gammaTexObj *t) t->TextureFilterMode = (TextureFilterModeDisable); +#if X_BYTE_ORDER == X_LITTLE_ENDIAN t->TextureFormat = (TF_LittleEndian | +#else + t->TextureFormat = (TF_BigEndian | +#endif TF_16Bit_565 | TF_ColorOrder_RGB | TF_Compnents_4 | diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c index 1f968e39b..3c1fe64fc 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c @@ -30,31 +30,26 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <kevin@precisioninsight.com> * Brian Paul <brian@precisioninsight.com> + * Alan Hourihane <Alan.Hourihane@btinternet.com> */ #ifdef GLX_DIRECT_RENDERING #include <X11/Xlibint.h> #include "gamma_init.h" +#include "gamma_gl.h" #include "glapi.h" +#include "glint_dri.h" +#include "context.h" +#include "mmath.h" -XMesaContext nullCC = NULL; -XMesaContext gCC = NULL; +__DRIcontextPrivate *nullCC = NULL; +__DRIcontextPrivate *gCC = NULL; gammaContextPrivate *gCCPriv = NULL; static struct _glapi_table *Dispatch = NULL; -static int count_bits(unsigned int n) -{ - int bits = 0; - - while (n > 0) { - if (n & 1) bits++; - n >>= 1; - } - return bits; -} GLboolean XMesaInitDriver(__DRIscreenPrivate *driScrnPriv) { @@ -83,78 +78,41 @@ void XMesaResetDriver(__DRIscreenPrivate *driScrnPriv) Xfree(driScrnPriv->private); } -XMesaVisual XMesaCreateVisual(XMesaDisplay *display, - XMesaVisualInfo visinfo, - GLboolean rgb_flag, - GLboolean alpha_flag, - GLboolean db_flag, - GLboolean stereo_flag, - GLboolean ximage_flag, - GLint depth_size, - GLint stencil_size, - GLint accum_size, - GLint level) +GLvisual *XMesaCreateVisual(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config) { - XMesaVisual v; - - /* Only RGB visuals are supported on the GMX2000 */ - if (!rgb_flag) { - return NULL; - } - - v = (XMesaVisual)Xmalloc(sizeof(struct xmesa_visual)); - if (!v) { - return NULL; - } - - v->visinfo = (XVisualInfo *)Xmalloc(sizeof(*visinfo)); - if(!v->visinfo) { - Xfree(v); - return NULL; - } - memcpy(v->visinfo, visinfo, sizeof(*visinfo)); - - v->display = display; - v->level = level; - - v->gl_visual = (GLvisual *)Xmalloc(sizeof(GLvisual)); - if (!v->gl_visual) { - Xfree(v->visinfo); - XFree(v); - return 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; + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual( config->rgba, + config->doubleBuffer, + config->stereo, + _mesa_bitcount(visinfo->red_mask), + _mesa_bitcount(visinfo->green_mask), + _mesa_bitcount(visinfo->blue_mask), + config->alphaSize, + 0, /* index bits */ + config->depthSize, + config->stencilSize, + config->accumRedSize, + config->accumGreenSize, + config->accumBlueSize, + config->accumAlphaSize, + 0 /* num samples */ ); } -void XMesaDestroyVisual(XMesaVisual v) -{ - Xfree(v->gl_visual); - Xfree(v->visinfo); - Xfree(v); -} -XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, - __DRIcontextPrivate *driContextPriv) +GLboolean XMesaCreateContext( Display *dpy, + GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv ) { int i; - XMesaContext c; gammaContextPrivate *cPriv; __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; gammaScreenPrivate *gPriv = (gammaScreenPrivate *)driScrnPriv->private; + GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv; if (!Dispatch) { GLuint size = _glapi_get_dispatch_table_size() * sizeof(GLvoid *); @@ -162,20 +120,9 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, _gamma_init_dispatch(Dispatch); } - c = (XMesaContext)Xmalloc(sizeof(struct xmesa_context)); - if (!c) { - return NULL; - } - - c->driContextPriv = driContextPriv; - c->xm_visual = v; - c->xm_buffer = NULL; /* Set by MakeCurrent */ - c->display = v->display; - cPriv = (gammaContextPrivate *)Xmalloc(sizeof(gammaContextPrivate)); if (!cPriv) { - Xfree(c); - return NULL; + return GL_FALSE; } cPriv->hHWContext = driContextPriv->hHWContext; @@ -216,27 +163,26 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, cPriv->ModelViewProj[i] = cPriv->Texture[i] = 0.0; - /* - ** NOT_DONE: The 0xe4 in LBReadMode and FBReadMode refers to the - ** partial products for the 640x480 mode. We will need to look up - ** the partial products in a table (c.f., glint_driver.c) to support - ** other FB sizes. - */ cPriv->LBReadMode = (LBReadSrcDisable | LBReadDstDisable | LBDataTypeDefault | LBWindowOriginBot | - LBScanLineInt2 | - 0xe4); /* NOT_DONE: 640x480 partial products */ + gDRIPriv->pprod); cPriv->FBReadMode = (FBReadSrcDisable | FBReadDstDisable | FBDataTypeDefault | FBWindowOriginBot | - FBScanLineInt2 | - 0xe4); /* NOT_DONE: 640x480 partial products */ - - cPriv->FBWindowBase = driScrnPriv->fbWidth * (driScrnPriv->fbHeight/2 - 1); - cPriv->LBWindowBase = driScrnPriv->fbWidth * (driScrnPriv->fbHeight/2 - 1); + gDRIPriv->pprod); + + if (gDRIPriv->numMXDevices == 2) { + cPriv->LBReadMode |= LBScanLineInt2; + cPriv->FBReadMode |= FBScanLineInt2; + cPriv->FBWindowBase =driScrnPriv->fbWidth*(driScrnPriv->fbHeight/2 - 1); + cPriv->LBWindowBase =driScrnPriv->fbWidth*(driScrnPriv->fbHeight/2 - 1); + } else { + cPriv->FBWindowBase = driScrnPriv->fbWidth * driScrnPriv->fbHeight; + cPriv->LBWindowBase = driScrnPriv->fbWidth * driScrnPriv->fbHeight; + } cPriv->Begin = (B_AreaStippleDisable | B_LineStippleDisable | @@ -328,7 +274,7 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, 4, 1, gammaTOLoad, gammaTOLoadSub); - + cPriv->curTexObj = gammaTOFind(0); cPriv->curTexObj1D = cPriv->curTexObj; cPriv->curTexObj2D = cPriv->curTexObj; @@ -338,17 +284,17 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, #ifdef FORCE_DEPTH32 cPriv->DepthSize = 32; #else - cPriv->DepthSize = v->gl_visual->DepthBits; + cPriv->DepthSize = mesaVis->DepthBits; #endif cPriv->zNear = 0.0; cPriv->zFar = 1.0; cPriv->Flags = GAMMA_FRONT_BUFFER; - cPriv->Flags |= (v->gl_visual->DBflag ? GAMMA_BACK_BUFFER : 0); + cPriv->Flags |= (mesaVis->DBflag ? GAMMA_BACK_BUFFER : 0); cPriv->Flags |= (cPriv->DepthSize > 0 ? GAMMA_DEPTH_BUFFER : 0); cPriv->EnabledFlags = GAMMA_FRONT_BUFFER; - cPriv->EnabledFlags |= (v->gl_visual->DBflag ? GAMMA_BACK_BUFFER : 0); + cPriv->EnabledFlags |= (mesaVis->DBflag ? GAMMA_BACK_BUFFER : 0); cPriv->DepthMode = (DepthModeDisable | DM_WriteMask | @@ -356,7 +302,7 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, cPriv->DeltaMode = (DM_SubPixlCorrectionEnable | DM_SmoothShadingEnable | - DM_Target300TXMX); + DM_Target500TXMX); switch (cPriv->DepthSize) { case 16: @@ -374,36 +320,68 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, cPriv->gammaScrnPriv = gPriv; - c->private = (void *)cPriv; + cPriv->LightingMode = LightingModeDisable; + cPriv->Light0Mode = LNM_Off; + cPriv->Light1Mode = LNM_Off; + + cPriv->MaterialMode = MaterialModeDisable; + + cPriv->ScissorMode = UserScissorDisable | ScreenScissorDisable; + + driContextPriv->driverPrivate = cPriv; /* Initialize the HW to a known state */ gammaInitHW(cPriv); - return c; + return GL_TRUE; } -void XMesaDestroyContext(XMesaContext c) +void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) { + gammaContextPrivate *cPriv; + cPriv = (gammaContextPrivate *) driContextPriv->driverPrivate; + if (cPriv) { + /* XXX free driver context data? */ + } } -XMesaBuffer XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w, - __DRIdrawablePrivate *driDrawPriv) -{ - return (XMesaBuffer)1; -} -XMesaBuffer XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, - XMesaColormap c, - __DRIdrawablePrivate *driDrawPriv) +GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) { - return (XMesaBuffer)1; + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); } -void XMesaDestroyBuffer(XMesaBuffer b) + +GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) { +#if 0 + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); +#else + return NULL; /* not implemented yet */ +#endif } -void XMesaSwapBuffers(XMesaBuffer b) + +void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) { /* ** NOT_DONE: This assumes buffer is currently bound to a context. @@ -420,11 +398,9 @@ void XMesaSwapBuffers(XMesaBuffer b) if (gCCPriv->EnabledFlags & GAMMA_BACK_BUFFER) { int src, dst, x0, y0, x1, h; int i; - __DRIdrawablePrivate *driDrawPriv = - gCC->driContextPriv->driDrawablePriv; int nRect = driDrawPriv->numClipRects; XF86DRIClipRectPtr pRect = driDrawPriv->pClipRects; - __DRIscreenPrivate *driScrnPriv = gCC->driContextPriv->driScreenPriv; + __DRIscreenPrivate *driScrnPriv = gCC->driScreenPriv; #ifdef DO_VALIDATE DRM_SPINLOCK(&driScrnPriv->pSAREA->drawable_lock, @@ -487,19 +463,23 @@ void XMesaSwapBuffers(XMesaBuffer b) } } -GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b) +GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) { - if (c) { - gCC = c; - gCCPriv = (gammaContextPrivate *)c->private; + if (driContextPriv) { + gCC = driContextPriv; + gCCPriv = (gammaContextPrivate *) driContextPriv->driverPrivate; gCCPriv->Window &= ~W_GIDMask; - gCCPriv->Window |= (gCC->driContextPriv->driDrawablePriv->index << 5); + gCCPriv->Window |= (driDrawPriv->index << 5); CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, GLINTWindow, gCCPriv->Window); _glapi_set_dispatch(Dispatch); + + _gamma_Viewport(0, 0, driDrawPriv->w, driDrawPriv->h); } else { gCC = NULL; gCCPriv = NULL; @@ -508,7 +488,7 @@ GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b) } -GLboolean XMesaUnbindContext( XMesaContext c ) +GLboolean XMesaUnbindContext( __DRIcontextPrivate *driContextPriv ) { /* XXX not 100% sure what's supposed to be done here */ return GL_TRUE; diff --git a/xc/lib/GL/mesa/src/drv/i810/Imakefile b/xc/lib/GL/mesa/src/drv/i810/Imakefile index 7260846fd..6b72c80e4 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 @@ -9,13 +11,22 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif +#if defined(LinuxArchitecture) +OS_SUBDIR = linux +#endif +#if defined(FreeBSDArchitecture) +OS_SUBDIR = bsd +#endif + #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)/i810 \ - -I../../../include -I../.. -I../common -I../../X + -I../../../include -I../.. -I../common -I../../X \ + -I$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel #endif MESA_INCLUDES = -I. -I.. -I../../include @@ -23,20 +34,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 = i810_xmesa.c i810clear.c \ - i810dd.c i810depth.c i810dma.c i810ring.c \ - i810pipeline.c i810span.c i810state.c i810swap.c \ - i810tex.c i810tris.c i810vb.c i810fastpath.c + 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 \ + i810dd.c \ + i810pipeline.c i810span.c i810state.c \ + i810tex.c i810tris.c i810vb.c i810fastpath.c i810ioctl.c + + I810OBJS = i810_xmesa.o \ + i810dd.o \ + i810pipeline.o i810span.o i810state.o \ + i810tex.o i810tris.o i810vb.o i810fastpath.o i810ioctl.o + + MESASRCS = ../../aatriangle.c \ + ../../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.c \ + ../../light.c \ + ../../lines.c \ + ../../logic.c \ + ../../masking.c \ + ../../matrix.c \ + ../../mem.c \ + ../../mmath.c \ + ../../pb.c \ + ../../pipeline.c \ + ../../pixel.c \ + ../../pixeltex.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 \ + ../../texutil.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 = ../../aatriangle.o \ + ../../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 \ + ../../pixeltex.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 \ + ../../texutil.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 - DRIOBJS = i810_xmesa.o i810clear.o \ - i810dd.o i810depth.o i810dma.o i810ring.o \ - i810pipeline.o i810span.o i810state.o i810swap.o \ - i810tex.o i810tris.o i810vb.o i810fastpath.o +#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) + +REQUIREDLIBS += -lm +#if !GlxBuiltInI810 +REQUIREDLIBS += -L../../../.. -lGL +#endif - SRCS = $(DRISRCS) - OBJS = $(DRIOBJS) #if !GlxUseBuiltInDRIDriver #undef DoNormalLib NormalLibGlx @@ -57,7 +292,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 8e6942497..a4b947b30 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 @@ -108,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) @@ -616,9 +618,6 @@ typedef struct { #define DV_PF_555 (0x1<<8) #define DV_PF_565 (0x2<<8) - - - #define GFX_OP_ANTIALIAS ((0x3<<29)|(0x6<<24)) #define AA_UPDATE_EDGEFLAG (1<<13) #define AA_ENABLE_EDGEFLAG (1<<12) @@ -641,84 +640,16 @@ typedef struct { #define ST1_ENABLE (1<<16) #define ST1_MASK (0xffff) +#define I810_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) -/* Indices into buf.Setup where various bits of state are mirrored per - * context and per buffer. These can be fired at the card as a unit, - * or in a piecewise fashion as required. - */ - -/* Destbuffer state - * - backbuffer linear offset and pitch -- invarient in the current dri - * - zbuffer linear offset and pitch -- also invarient - * - drawing origin in back and depth buffers. - * - * Keep the depth/back buffer state here to acommodate private buffers - * in the future. - */ -#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */ -#define I810_DESTREG_DI1 1 -#define I810_DESTREG_ZB0 2 /* CMD_OP_Z_BUFFER_INFO */ -#define I810_DESTREG_ZB1 3 /* CMD_OP_Z_BUFFER_INFO */ -#define I810_DESTREG_DV0 4 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */ -#define I810_DESTREG_DV1 5 -#define I810_DESTREG_DR0 6 /* GFX_OP_DRAWRECT_INFO (4 dwords) */ -#define I810_DESTREG_DR1 7 -#define I810_DESTREG_DR2 8 -#define I810_DESTREG_DR3 9 -#define I810_DESTREG_DR4 10 - -#define I810_DEST_SETUP_SIZE (11+1) - -/* Context state - */ -#define I810_CTXREG_VF 0 /* GFX_OP_VERTEX_FMT */ -#define I810_CTXREG_MT 1 /* GFX_OP_MAP_TEXELS */ -#define I810_CTXREG_MC0 2 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */ -#define I810_CTXREG_MC1 3 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */ -#define I810_CTXREG_MC2 4 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */ -#define I810_CTXREG_MA0 5 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */ -#define I810_CTXREG_MA1 6 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */ -#define I810_CTXREG_MA2 7 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */ -#define I810_CTXREG_SDM 8 /* GFX_OP_SRC_DEST_MONO */ -#define I810_CTXREG_CF0 9 /* GFX_OP_COLOR_FACTOR */ -#define I810_CTXREG_CF1 10 -#define I810_CTXREG_FOG 11 /* GFX_OP_FOG_COLOR */ -#define I810_CTXREG_B1 12 /* GFX_OP_BOOL_1 */ -#define I810_CTXREG_B2 13 /* GFX_OP_BOOL_2 */ -#define I810_CTXREG_LCS 14 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */ -#define I810_CTXREG_PV 15 /* GFX_OP_PV_RULE -- Invarient! */ -#define I810_CTXREG_ZA 16 /* GFX_OP_ZBIAS_ALPHAFUNC */ -#define I810_CTXREG_ST0 17 /* GFX_OP_STIPPLE */ -#define I810_CTXREG_ST1 18 -#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */ -#define I810_CTX_SETUP_SIZE (20) /* pad to qword */ - - -/* Cliprect state - keep seperate from context as it is used for - * drawing triangles to the shared backbuffer, and - * changes more frequently than the 'normal' context. - */ -#define I810_CLIPREG_SCI0 0 /* GFX_OP_SCISSOR_INFO (3 dwords) */ -#define I810_CLIPREG_SCI1 1 -#define I810_CLIPREG_SCI2 2 -#define I810_CLIPREG_SC 3 /* GFX_OP_SCISSOR */ - -#define I810_CLIP_SETUP_SIZE 4 - -/* Texture state (per tex_buffer) - */ -#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */ -#define I810_TEXREG_MI1 1 -#define I810_TEXREG_MI2 2 -#define I810_TEXREG_MI3 3 -#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */ -#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */ -#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */ -#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */ - -#define I810_TEX_SETUP_SIZE 8 +#define I810PACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) +#define I810PACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) -#define I810_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) +#define I810PACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) #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 f6aa8bd30..df5362787 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_init.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810_init.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). * */ @@ -42,16 +41,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri_mesaint.h" #include "dri_mesa.h" #include "types.h" -#include "xmesaP.h" typedef struct { - drmHandle handle; - drmSize size; - drmAddress map; + drmHandle handle; + drmSize size; + char *map; } i810Region, *i810RegionPtr; typedef struct { - i810Region regs; + i810Region front; + i810Region back; + i810Region depth; + i810Region tex; int deviceID; int width; @@ -68,21 +69,22 @@ typedef struct { int backOffset; int depthOffset; - int auxPitch; - int auxPitchBits; + int backPitch; + int backPitchBits; int textureOffset; int textureSize; int logTextureGranularity; __DRIscreenPrivate *driScrnPriv; + drmBufMapPtr bufs; } i810ScreenPrivate; #include "i810context.h" -extern void i810XMesaUpdateState( i810ContextPtr imesa ); +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 ); @@ -90,6 +92,10 @@ extern void i810XMesaSetBackClipRects( i810ContextPtr imesa ); extern void i810XMesaSetFrontClipRects( i810ContextPtr imesa ); +#define GET_DISPATCH_AGE( imesa ) imesa->sarea->last_dispatch +#define GET_ENQUEUE_AGE( imesa ) imesa->sarea->last_enqueue + + /* Lock the hardware and validate our state. */ #define LOCK_HARDWARE( imesa ) \ @@ -97,38 +103,28 @@ extern void i810XMesaSetFrontClipRects( i810ContextPtr imesa ); char __ret=0; \ DRM_CAS(imesa->driHwLock, imesa->hHWContext, \ (DRM_LOCK_HELD|imesa->hHWContext), __ret); \ - if (__ret) { \ - drmGetLock(imesa->driFd, imesa->hHWContext, 0); \ - i810XMesaUpdateState( imesa ); \ - } \ + 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 pair of macros makes a loop over the drawing operations - so it is not self contained and doesn't have the nice single - statement semantics of most macros -*/ -#define BEGIN_CLIP_LOOP(imesa) \ - do { \ - int _nc; \ - LOCK_HARDWARE( imesa ); \ - for (_nc = imesa->numClipRects; _nc ; _nc--) { \ - if (imesa->needClip) \ - i810EmitScissorValues(imesa, _nc-1, 1); - - - -#define END_CLIP_LOOP(imesa) \ - } \ - UNLOCK_HARDWARE(imesa); \ - } while (0) +/* 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_xmesa.c b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c index 50b7e0689..5edcf2620 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c @@ -46,10 +46,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i810state.h" #include "i810tex.h" #include "i810span.h" -#include "i810depth.h" #include "i810tris.h" -#include "i810swap.h" #include "i810pipeline.h" +#include "i810ioctl.h" #include "i810_dri.h" @@ -57,36 +56,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef I810_DEBUG int I810_DEBUG = (0 - | DEBUG_ALWAYS_SYNC - | DEBUG_VERBOSE_RING - | DEBUG_VERBOSE_OUTREG +/* | 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_VALIDATE_RING */ +/* | DEBUG_VERBOSE_IOCTL */ ); #endif static i810ContextPtr i810Ctx = 0; -i810Glx_t i810glx; -static int count_bits(unsigned int n) -{ - int bits = 0; - - while (n > 0) { - if (n & 1) bits++; - n >>= 1; - } - return bits; -} - -/* These functions are accessed by dlsym from dri_mesa_init.c: +/* These functions are accessed externally to the driver: * * XMesaInitDriver * XMesaResetDriver @@ -100,14 +88,26 @@ static int count_bits(unsigned int n) * XMesaSwapBuffers * XMesaMakeCurrent * - * So this is kind of the public interface to the driver. The driver - * uses the X11 mesa driver context as a kind of wrapper around its - * own driver context - but there isn't much justificiation for doing - * it that way - the DRI might as well use a (void *) to refer to the - * driver contexts. Nothing in the X context really gets used. */ +static drmBufMapPtr i810_create_empty_buffers(void) +{ + drmBufMapPtr retval; + + retval = (drmBufMapPtr)Xmalloc(sizeof(drmBufMap)); + if(retval == NULL) return NULL; + memset(retval, 0, sizeof(drmBufMap)); + retval->list = (drmBufPtr)Xmalloc(sizeof(drmBuf) * I810_DMA_BUF_NR); + if(retval->list == NULL) { + Xfree(retval); + return NULL; + } + memset(retval->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR); + fprintf(stderr, "retval : %p, retval->list : %p\n", retval, retval->list); + return retval; +} + GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { i810ScreenPrivate *i810Screen; @@ -120,8 +120,6 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) i810Screen->driScrnPriv = sPriv; sPriv->private = (void *)i810Screen; - i810Screen->regs.handle=gDRIPriv->regs; - i810Screen->regs.size=gDRIPriv->regsSize; i810Screen->deviceID=gDRIPriv->deviceID; i810Screen->width=gDRIPriv->width; i810Screen->height=gDRIPriv->height; @@ -137,39 +135,60 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) i810Screen->backOffset=gDRIPriv->backOffset; i810Screen->depthOffset=gDRIPriv->depthOffset; - i810Screen->auxPitch = gDRIPriv->auxPitch; - i810Screen->auxPitchBits = gDRIPriv->auxPitchBits; + i810Screen->backPitch = gDRIPriv->auxPitch; + i810Screen->backPitchBits = gDRIPriv->auxPitchBits; i810Screen->textureOffset=gDRIPriv->textureOffset; i810Screen->textureSize=gDRIPriv->textureSize; i810Screen->logTextureGranularity = gDRIPriv->logTextureGranularity; - - if (0) + if (1) fprintf(stderr, "Tex heap size %x, granularity %x bytes\n", i810Screen->textureSize, 1<<(i810Screen->logTextureGranularity)); + + i810Screen->bufs = i810_create_empty_buffers(); + if(i810Screen->bufs == NULL) + { + Xfree(i810Screen); + return GL_FALSE; + } + i810Screen->back.handle = gDRIPriv->backbuffer; + i810Screen->back.size = gDRIPriv->backbufferSize; + if (drmMap(sPriv->fd, - i810Screen->regs.handle, - i810Screen->regs.size, - &i810Screen->regs.map) != 0) + i810Screen->back.handle, + i810Screen->back.size, + (drmAddress *)&i810Screen->back.map) != 0) { Xfree(i810Screen); return GL_FALSE; } - /* Ditch i810glx in favor of i810Screen? - */ - memset(&i810glx, 0, sizeof(i810glx)); + i810Screen->depth.handle = gDRIPriv->depthbuffer; + i810Screen->depth.size = gDRIPriv->depthbufferSize; + + if (drmMap(sPriv->fd, + i810Screen->depth.handle, + i810Screen->depth.size, + (drmAddress *)&i810Screen->depth.map) != 0) + { + Xfree(i810Screen); + return GL_FALSE; + } + + i810Screen->tex.handle = gDRIPriv->textures; + i810Screen->tex.size = gDRIPriv->textureSize; + + if (drmMap(sPriv->fd, + i810Screen->tex.handle, + i810Screen->tex.size, + (drmAddress *)&i810Screen->tex.map) != 0) + { + Xfree(i810Screen); + return GL_FALSE; + } - i810glx.LpRing.mem.Start = gDRIPriv->ringOffset; - i810glx.LpRing.mem.Size = gDRIPriv->ringSize; - i810glx.LpRing.mem.End = gDRIPriv->ringOffset + gDRIPriv->ringSize; - i810glx.LpRing.virtual_start = sPriv->pFB + i810glx.LpRing.mem.Start; - i810glx.LpRing.tail_mask = i810glx.LpRing.mem.Size - 1; - i810glx.MMIOBase = i810Screen->regs.map; - i810glx.texVirtual = sPriv->pFB + i810Screen->textureOffset; - i810DDFastPathInit(); i810DDTrifuncInit(); i810DDSetupInit(); @@ -183,111 +202,75 @@ void XMesaResetDriver(__DRIscreenPrivate *sPriv) { i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private; - drmUnmap(i810Screen->regs.map, i810Screen->regs.size); - Xfree(i810Screen); -} - -/* Accessed by dlsym from dri_mesa_init.c - */ -XMesaVisual XMesaCreateVisual(XMesaDisplay *display, - XMesaVisualInfo visinfo, - GLboolean rgb_flag, - GLboolean alpha_flag, - GLboolean db_flag, - GLboolean stereo_flag, - GLboolean ximage_flag, - GLint depth_size, - GLint stencil_size, - GLint accum_size, - GLint level) -{ - XMesaVisual v; - - /* Only RGB visuals are supported on the I810 boards */ - if (!rgb_flag) return 0; - - v = (XMesaVisual)Xmalloc(sizeof(struct xmesa_visual)); - if (!v) return 0; - - v->visinfo = (XVisualInfo *)Xmalloc(sizeof(*visinfo)); - if(!v->visinfo) { - Xfree(v); - return 0; - } - memcpy(v->visinfo, visinfo, sizeof(*visinfo)); - - v->display = display; - v->level = level; - - v->gl_visual = (GLvisual *)Xmalloc(sizeof(GLvisual)); - if (!v->gl_visual) { - Xfree(v->visinfo); - XFree(v); - return 0; - } - - v->gl_visual->RGBAflag = rgb_flag; - v->gl_visual->DBflag = db_flag; - v->gl_visual->StereoFlag = stereo_flag; - - v->gl_visual->RedBits = count_bits(visinfo->red_mask); - v->gl_visual->GreenBits = count_bits(visinfo->green_mask); - v->gl_visual->BlueBits = count_bits(visinfo->blue_mask); - v->gl_visual->AlphaBits = 0; /* Not currently supported */ + /* Need to unmap all the bufs and maps here: + */ - v->gl_visual->AccumBits = accum_size; - v->gl_visual->DepthBits = depth_size; - v->gl_visual->StencilBits = stencil_size; - return v; + Xfree(i810Screen); } -void XMesaDestroyVisual(XMesaVisual v) + +GLvisual *XMesaCreateVisual(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config) { - Xfree(v->gl_visual); - Xfree(v->visinfo); - Xfree(v); + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual( config->rgba, + config->doubleBuffer, + config->stereo, + _mesa_bitcount(visinfo->red_mask), + _mesa_bitcount(visinfo->green_mask), + _mesa_bitcount(visinfo->blue_mask), + config->alphaSize, + 0, /* index bits */ + config->depthSize, + config->stencilSize, + config->accumRedSize, + config->accumGreenSize, + config->accumBlueSize, + config->accumAlphaSize, + 0 /* num samples */ ); } -XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, - __DRIcontextPrivate *driContextPriv) + +GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv ) { - GLcontext *ctx; - XMesaContext c; + GLcontext *ctx = driContextPriv->mesaContext; i810ContextPtr imesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private; - I810SAREAPriv *saPriv=(I810SAREAPriv*)(((char*)sPriv->pSAREA)+ - sizeof(XF86DRISAREARec)); + 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; - } - - imesa = (i810ContextPtr)Xmalloc(sizeof(i810Context)); + imesa = (i810ContextPtr)Xcalloc(sizeof(i810Context), 1); if (!imesa) { - Xfree(c); - return 0; + return GL_FALSE; } - c->driContextPriv = driContextPriv; - c->xm_visual = v; - c->xm_buffer = 0; /* Set by MakeCurrent */ - c->display = v->display; - c->private = (void *)imesa; - if (share_list) - shareCtx=((i810ContextPtr)(share_list->private))->glCtx; + /* 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 = 9; + ctx->Const.MaxTextureSize = 1<<8; + } else if (i810Screen->textureSize < 8*1024*1024) { + ctx->Const.MaxTextureLevels = 10; + ctx->Const.MaxTextureSize = 1<<9; + } else { + ctx->Const.MaxTextureLevels = 11; + ctx->Const.MaxTextureSize = 1<<10; + } - ctx = imesa->glCtx = gl_create_context(v->gl_visual, shareCtx, - (void*)imesa, GL_TRUE); /* Dri stuff */ - imesa->display = v->display; + imesa->display = dpy; imesa->hHWContext = driContextPriv->hHWContext; imesa->driFd = sPriv->fd; imesa->driHwLock = &sPriv->pSAREA->lock; @@ -295,10 +278,7 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, imesa->i810Screen = i810Screen; imesa->driScreen = sPriv; imesa->sarea = saPriv; - - imesa->glBuffer = gl_create_framebuffer(v->gl_visual); - - imesa->needClip=1; + imesa->glBuffer = NULL; imesa->texHeap = mmInit( 0, i810Screen->textureSize ); @@ -315,17 +295,21 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, imesa->TextureMode = ctx->Texture.Unit[0].EnvMode; imesa->CurrentTexObj[0] = 0; imesa->CurrentTexObj[1] = 0; + + ctx->DriverCtx = (void *) imesa; + imesa->glCtx = ctx; i810DDExtensionsInit( ctx ); i810DDInitStateFuncs( ctx ); i810DDInitTextureFuncs( ctx ); i810DDInitSpanFuncs( ctx ); - i810DDInitDepthFuncs( 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. @@ -346,18 +330,19 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, i810DDInitState( imesa ); - return c; + driContextPriv->driverPrivate = (void *) imesa; + + return GL_TRUE; } -void XMesaDestroyContext(XMesaContext c) +void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) { - i810ContextPtr imesa = (i810ContextPtr) c->private; + i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate; if (imesa) { i810TextureObjectPtr next_t, t; gl_destroy_context(imesa->glCtx); - gl_destroy_framebuffer(imesa->glBuffer); foreach_s (t, next_t, &(imesa->TexObjList)) i810DestroyTexObj(imesa, t); @@ -366,58 +351,53 @@ void XMesaDestroyContext(XMesaContext c) i810DestroyTexObj(imesa, t); Xfree(imesa); - - c->private = 0; } } -XMesaBuffer XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w, - __DRIdrawablePrivate *driDrawPriv) +GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) { - return (XMesaBuffer)1; + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); } -XMesaBuffer XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, - XMesaColormap c, - __DRIdrawablePrivate *driDrawPriv) -{ - return (XMesaBuffer)1; -} -void XMesaDestroyBuffer(XMesaBuffer b) +GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) { +#if 0 + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); +#else + return NULL; /* not implemented yet */ +#endif } -void XMesaSwapBuffers(XMesaBuffer bogus) + +void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) { + /* XXX should do swap according to the buffer, not the context! */ i810ContextPtr imesa = i810Ctx; FLUSH_VB( imesa->glCtx, "swap buffers" ); i810SwapBuffers(imesa); } -static void i810InitClipRects( i810ContextPtr imesa ) -{ - switch (imesa->numClipRects) { - case 0: - imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR | - SC_UPDATE_SCISSOR ); - imesa->ClipSetup[I810_CLIPREG_SCI1] = 0; - imesa->ClipSetup[I810_CLIPREG_SCI2] = 0; - imesa->needClip = 0; - imesa->dirty |= I810_EMIT_CLIPRECT; - break; - case 1: - imesa->needClip = 0; - i810EmitScissorValues( imesa, 0, 0 ); - imesa->dirty |= I810_EMIT_CLIPRECT; - break; - default: - imesa->needClip=1; - break; - } -} - void i810XMesaSetFrontClipRects( i810ContextPtr imesa ) @@ -426,12 +406,12 @@ void i810XMesaSetFrontClipRects( i810ContextPtr imesa ) imesa->numClipRects = dPriv->numClipRects; imesa->pClipRects = dPriv->pClipRects; + imesa->dirty |= I810_UPLOAD_CLIPRECTS; imesa->drawX = dPriv->x; imesa->drawY = dPriv->y; - imesa->drawOffset = imesa->i810Screen->fbOffset; + imesa->drawMap = imesa->driScreen->pFB; i810EmitDrawingRectangle( imesa ); - i810InitClipRects( imesa ); } @@ -440,7 +420,7 @@ void i810XMesaSetBackClipRects( i810ContextPtr imesa ) __DRIdrawablePrivate *dPriv = imesa->driDrawable; int i; - if (dPriv->numAuxClipRects == 0) + if (dPriv->numBackClipRects == 0) { if (I810_DEBUG & DEBUG_VERBOSE_DRI) fprintf(stderr, "FRONT_CLIPRECTS, %d rects\n", @@ -452,18 +432,18 @@ void i810XMesaSetBackClipRects( i810ContextPtr imesa ) imesa->drawY = dPriv->y; } else { if (I810_DEBUG & DEBUG_VERBOSE_DRI) - fprintf(stderr, "AUX_RECTS, %d rects\n", - dPriv->numAuxClipRects); + fprintf(stderr, "BACK_RECTS, %d rects\n", + dPriv->numBackClipRects); - imesa->numClipRects = dPriv->numAuxClipRects; - imesa->pClipRects = dPriv->pAuxClipRects; - imesa->drawX = dPriv->auxX; - imesa->drawY = dPriv->auxY; + imesa->numClipRects = dPriv->numBackClipRects; + imesa->pClipRects = dPriv->pBackClipRects; + imesa->drawX = dPriv->backX; + imesa->drawY = dPriv->backY; } - imesa->drawOffset = imesa->i810Screen->backOffset; + imesa->drawMap = imesa->i810Screen->back.map; i810EmitDrawingRectangle( imesa ); - i810InitClipRects( imesa ); + imesa->dirty |= I810_UPLOAD_CLIPRECTS; if (I810_DEBUG & DEBUG_VERBOSE_DRI) for (i = 0 ; i < imesa->numClipRects ; i++) @@ -478,6 +458,9 @@ void i810XMesaSetBackClipRects( i810ContextPtr imesa ) static void i810XMesaWindowMoved( i810ContextPtr imesa ) { + if (0) + fprintf(stderr, "i810XMesaWindowMoved\n\n"); + switch (imesa->glCtx->Color.DriverDrawBuffer) { case GL_FRONT_LEFT: i810XMesaSetFrontClipRects( imesa ); @@ -489,35 +472,40 @@ static void i810XMesaWindowMoved( i810ContextPtr imesa ) fprintf(stderr, "fallback buffer\n"); break; } - } -/* This looks buggy to me - the 'b' variable isn't used anywhere... - * Hmm - It seems that the drawable is already hooked in to - * driDrawablePriv. - */ -GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b) +GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) { + i810ContextPtr i810 = (i810ContextPtr) driContextPriv->driverPrivate; + if (i810) + i810->dirty = ~0; - if (c->private==(void *)i810Ctx) return GL_TRUE; - - if (c) { - __DRIdrawablePrivate *dPriv = c->driContextPriv->driDrawablePriv; - - i810Ctx = (i810ContextPtr)c->private; + return GL_TRUE; +} - gl_make_current(i810Ctx->glCtx, i810Ctx->glBuffer); - i810Ctx->driDrawable = dPriv; +GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + if (driContextPriv) { + i810Ctx = (i810ContextPtr) driContextPriv->driverPrivate; + + gl_make_current2(i810Ctx->glCtx, driDrawPriv->mesaBuffer, + driReadPriv->mesaBuffer); + + + i810Ctx->driDrawable = driDrawPriv; i810Ctx->dirty = ~0; - + i810XMesaWindowMoved( i810Ctx ); - + if (!i810Ctx->glCtx->Viewport.Width) - gl_Viewport(i810Ctx->glCtx, 0, 0, dPriv->w, dPriv->h); - - } else { + gl_Viewport(i810Ctx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h); + } + else + { gl_make_current(0,0); i810Ctx = NULL; } @@ -525,15 +513,26 @@ GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b) } -void i810XMesaUpdateState( i810ContextPtr imesa ) +void i810GetLock( i810ContextPtr imesa, GLuint flags ) { __DRIdrawablePrivate *dPriv = imesa->driDrawable; __DRIscreenPrivate *sPriv = imesa->driScreen; - I810SAREAPriv *sarea = imesa->sarea; + 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 @@ -541,26 +540,24 @@ void i810XMesaUpdateState( i810ContextPtr imesa ) */ XMESA_VALIDATE_DRAWABLE_INFO(imesa->display, sPriv, dPriv); - i810glx.LpRing.synced = 0; - /* If another client has touched the ringbuffer, need to update - * where we think the pointers are: - */ - if (sarea->ringOwner != me) { - i810glx.c_ringlost++; - imesa->dirty |= I810_REFRESH_RING; - } - + if (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; + imesa->dirty |= (I810_UPLOAD_CTX | + I810_UPLOAD_CLIPRECTS | + I810_UPLOAD_BUFFERS | + I810_UPLOAD_TEX0 | + I810_UPLOAD_TEX1); + sarea->ctxOwner = me; } /* Shared texture managment - if another client has played with @@ -587,23 +584,18 @@ void i810XMesaUpdateState( i810ContextPtr imesa ) 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; - imesa->dirty |= I810_UPLOAD_TEX0IMAGE | I810_UPLOAD_TEX1IMAGE; } if (dPriv->lastStamp != stamp) i810XMesaWindowMoved( imesa ); - sarea->ctxOwner=me; - sarea->ringOwner=me; - - - _I810RefreshLpRing(imesa, 0); - - if (imesa->dirty) - i810EmitHwStateLocked( imesa ); - + + sarea->last_quiescent = -1; /* just kill it for now */ } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.c b/xc/lib/GL/mesa/src/drv/i810/i810clear.c deleted file mode 100644 index 5ba264059..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810clear.c +++ /dev/null @@ -1,193 +0,0 @@ - - -#include "types.h" -#include "vbrender.h" -#include "i810log.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include "mm.h" -#include "i810lib.h" -#include "i810dd.h" -#include "i810clear.h" -#include "i810state.h" -#include "i810tris.h" - - - -/* Clear the depthbuffer. Always uses the auxillary cliprects and - * origin from 'dPriv'. - */ -static void i810_clear_depthbuffer( GLcontext *ctx, - GLboolean all, - GLint cx, GLint cy, - GLint cwidth, GLint cheight ) -{ - i810ContextPtr imesa = I810_CONTEXT( ctx ); - GLuint zval = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE); - i810ScreenPrivate *i810Screen = imesa->i810Screen; - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - -/* int _nc = dPriv->numAuxClipRects; */ -/* XF86DRIClipRectPtr box = dPriv->pAuxClipRects; */ - - int _nc = imesa->numClipRects; - XF86DRIClipRectPtr box = imesa->pClipRects; - - cy = dPriv->h-cy-cheight; - cx += dPriv->auxX; - cy += dPriv->auxY; - - while (_nc--) { - GLint x = box[_nc].x1; - GLint y = box[_nc].y1; - GLint width = box[_nc].x2 - x; - GLint height = box[_nc].y2 - y; - - if (!all) { - if (x < cx) width -= cx - x, x = cx; - if (y < cy) height -= cy - y, y = cy; - if (x + width > cx + cwidth) width = cx + cwidth - x; - if (y + height > cy + cheight) height = cy + cheight - y; - if (width <= 0) continue; - if (height <= 0) continue; - } - - if (I810_DEBUG&DEBUG_VERBOSE_2D) - fprintf(stderr, "clear depth rect %d,%d %dx%d\n", - (int) x, (int) y, (int) width, (int) height); - - { - int start = (i810Screen->depthOffset + - y * i810Screen->auxPitch + - x * 2); - - BEGIN_BATCH(imesa, 6); - - OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); - OUT_BATCH( BR13_SOLID_PATTERN | - (0xF0 << 16) | - i810Screen->auxPitch ); - OUT_BATCH( (height << 16) | (width * 2)); - OUT_BATCH( start ); - OUT_BATCH( zval ); - OUT_BATCH( 0 ); - - ADVANCE_BATCH(); - } - } -} - - -/* Clear the current drawbuffer. Checks 'imesa' to determine which set of - * cliprects and origin to use. - */ -static void i810_clear_colorbuffer( GLcontext *ctx, - GLboolean all, - GLint cx, GLint cy, - GLint cwidth, GLint cheight ) -{ - i810ContextPtr imesa = I810_CONTEXT( ctx ); - GLushort c = imesa->ClearColor; - i810ScreenPrivate *i810Screen = imesa->i810Screen; - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - - int _nc = imesa->numClipRects; - XF86DRIClipRectPtr box = imesa->pClipRects; - - cy = dPriv->h-cy-cheight; - cx += imesa->drawX; - cy += imesa->drawY; - - while (_nc--) { - GLint x = box[_nc].x1; - GLint y = box[_nc].y1; - GLint width = box[_nc].x2 - x; - GLint height = box[_nc].y2 - y; - - if (!all) { - if (x < cx) width -= cx - x, x = cx; - if (y < cy) height -= cy - y, y = cy; - if (x + width > cx + cwidth) width = cx + cwidth - x; - if (y + height > cy + cheight) height = cy + cheight - y; - if (width <= 0) continue; - if (height <= 0) continue; - } - - if (I810_DEBUG&DEBUG_VERBOSE_2D) - fprintf(stderr, "clear color rect %d,%d %dx%d\n", - (int) x, (int) y, (int) width, (int) height); - - - { - int start = (imesa->drawOffset + - y * i810Screen->auxPitch + - x * i810Screen->cpp); - - BEGIN_BATCH( imesa, 6 ); - - OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); - OUT_BATCH( BR13_SOLID_PATTERN | - (0xF0 << 16) | - i810Screen->auxPitch ); - OUT_BATCH( (height << 16) | (width * i810Screen->cpp)); - OUT_BATCH( start ); - OUT_BATCH( c ); - OUT_BATCH( 0 ); - - ADVANCE_BATCH(); - } - } -} - - - - -/* - * i810Clear - * - * Clear the color and/or depth buffers. If 'all' is GL_TRUE, clear - * whole buffer, otherwise clear the region defined by the remaining - * parameters. - */ -GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cwidth, GLint cheight ) -{ - i810ContextPtr imesa = I810_CONTEXT( ctx ); - - if (I810_DEBUG&DEBUG_VERBOSE_API) - fprintf(stderr, "i810Clear( %d, %d, %d, %d, %d )\n", - (int)mask, (int)cx, (int)cy, (int)cwidth, (int)cheight ); - - LOCK_HARDWARE(imesa); - - { - BEGIN_BATCH( imesa, 2 ); - OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH ); - OUT_BATCH( 0 ); - ADVANCE_BATCH(); - } - - if (mask & GL_COLOR_BUFFER_BIT) { - i810_clear_colorbuffer( ctx, all, cx, cy, cwidth, cheight ); - mask &= ~GL_COLOR_BUFFER_BIT; - } - - if ( (mask & GL_DEPTH_BUFFER_BIT) && ctx->Depth.Mask ) { - i810_clear_depthbuffer( ctx, all, cx, cy, cwidth, cheight ); - mask &= ~GL_DEPTH_BUFFER_BIT; - } - - { - BEGIN_BATCH( imesa, 2 ); - OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH ); - OUT_BATCH( 0 ); - ADVANCE_BATCH(); - } - - UNLOCK_HARDWARE( imesa ); - return mask; -} - diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.h b/xc/lib/GL/mesa/src/drv/i810/i810clear.h deleted file mode 100644 index aedbf84d9..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810clear.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _I810_CLEAR_H -#define _I810_CLEAR_H - -extern GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ); - -#endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.h b/xc/lib/GL/mesa/src/drv/i810/i810context.h index 9f316f6fd..629abf0b8 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810context.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810context.h @@ -28,24 +28,32 @@ typedef struct i810_context_t i810Context; typedef struct i810_context_t *i810ContextPtr; +typedef struct i810_texture_object_t *i810TextureObjectPtr; #include <X11/Xlibint.h> #include "dri_tmm.h" #include "dri_mesaint.h" #include "dri_mesa.h" -#include "xmesaP.h" #include "types.h" #include "i810_init.h" -#include "i810_sarea.h" +#include "drm.h" +#include "mm.h" +#include "i810log.h" #include "i810tex.h" #include "i810vb.h" - -#define I810_FALLBACK_TEXTURE 0x1 -#define I810_FALLBACK_BUFFER 0x2 +/* Reasons to fallback on all primitives. (see also + * imesa->IndirectTriangles). + */ +#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 @@ -53,17 +61,6 @@ typedef struct i810_context_t *i810ContextPtr; */ #define I810_NEW_TEXTURE 0x1 -/* for i810ctx.dirty - manage driver->hw state changes, including - * lost contexts. - */ -#define I810_REQUIRE_QUIESCENT 0x1 -#define I810_UPLOAD_TEX0IMAGE 0x2 -#define I810_UPLOAD_TEX1IMAGE 0x4 -#define I810_UPLOAD_CTX 0x8 -#define I810_UPLOAD_BUFFERS 0x10 -#define I810_REFRESH_RING 0x20 -#define I810_EMIT_CLIPRECT 0x40 - typedef void (*i810_interp_func)( GLfloat t, GLfloat *result, @@ -88,7 +85,6 @@ struct i810_context_t { */ GLuint Setup[I810_CTX_SETUP_SIZE]; GLuint BufferSetup[I810_DEST_SETUP_SIZE]; - GLuint ClipSetup[I810_CLIP_SETUP_SIZE]; /* Support for CVA and the fast paths. @@ -125,24 +121,38 @@ struct i810_context_t { /* DRI stuff */ + drmBufPtr vertex_dma_buffer; + GLuint vertex_prim; + GLframebuffer *glBuffer; + /* Two flags to keep track of fallbacks. + */ + GLuint IndirectTriangles; GLuint Fallback; + + GLuint needClip; /* These refer to the current draw (front vs. back) buffer: */ - int drawOffset; /* draw buffer address in agp space */ + 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; - int lastSwap; + int secondLastSwap; int texAge; + int ctxAge; + int dirtyAge; + int any_contend; /* throttle me harder */ - XF86DRIClipRectRec draw_rect; + int scissor; + drm_clip_rect_t draw_rect; + drm_clip_rect_t scissor_rect; drmContext hHWContext; drmLock *driHwLock; @@ -152,7 +162,7 @@ struct i810_context_t { __DRIdrawablePrivate *driDrawable; __DRIscreenPrivate *driScreen; i810ScreenPrivate *i810Screen; - I810SAREAPriv *sarea; + drm_i810_sarea_t *sarea; }; @@ -161,7 +171,7 @@ struct i810_context_t { */ #define I810_DEBUG 0 #ifndef I810_DEBUG -/* #warning "Debugging enabled - expect reduced performance" */ +#warning "Debugging enabled - expect reduced performance" extern int I810_DEBUG; #endif @@ -176,6 +186,7 @@ extern int I810_DEBUG; #define DEBUG_VALIDATE_RING 0x800 #define DEBUG_VERBOSE_LRU 0x1000 #define DEBUG_VERBOSE_DRI 0x2000 +#define DEBUG_VERBOSE_IOCTL 0x4000 diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.c b/xc/lib/GL/mesa/src/drv/i810/i810dd.c index 17436bf0d..7c04f6d56 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810dd.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.c @@ -29,10 +29,7 @@ #include <stdio.h> #include "mm.h" -#include "i810lib.h" -#include "i810clear.h" #include "i810dd.h" -#include "i810depth.h" #include "i810log.h" #include "i810state.h" #include "i810span.h" @@ -59,7 +56,7 @@ static const GLubyte *i810DDGetString( GLcontext *ctx, GLenum name ) case GL_VENDOR: return "Keith Whitwell, Precision Insight Inc."; case GL_RENDERER: - return "DRI-I810"; + return "Mesa DRI I810 20000415"; default: return 0; } @@ -100,10 +97,13 @@ void i810DDExtensionsInit( GLcontext *ctx ) /* The imaging subset of 1.2 isn't supported by any mesa driver. */ gl_extensions_disable( ctx, "ARB_imaging" ); + gl_extensions_disable( ctx, "GL_EXT_blend_color" ); gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" ); gl_extensions_disable( ctx, "GL_EXT_blend_subtract" ); gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); + gl_extensions_disable( ctx, "GL_EXT_texture_lod_bias" ); + gl_extensions_disable( ctx, "GL_MESA_resize_buffers" ); if (0) gl_extensions_disable( ctx, "GL_ARB_multitexture" ); @@ -115,18 +115,6 @@ void i810DDExtensionsInit( GLcontext *ctx ) } -static void i810DDFlush( GLcontext *ctx ) -{ - i810DmaFlush( I810_CONTEXT(ctx) ); -} - -static void i810DDFinish( GLcontext *ctx ) -{ - i810ContextPtr imesa = I810_CONTEXT(ctx); - LOCK_HARDWARE( imesa ); - i810DmaFinish( imesa ); - UNLOCK_HARDWARE( imesa ); -} void i810DDInitDriverFuncs( GLcontext *ctx ) @@ -139,8 +127,5 @@ void i810DDInitDriverFuncs( GLcontext *ctx ) ctx->Driver.Clear = i810Clear; - ctx->Driver.Flush = i810DDFlush; - ctx->Driver.Finish = i810DDFinish; - ctx->Driver.BuildPrecalcPipeline = i810DDBuildPrecalcPipeline; } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.h b/xc/lib/GL/mesa/src/drv/i810/i810dma.h deleted file mode 100644 index 9d472719a..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810dma.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - GLX Hardware Device Driver for Intel i810 - Copyright (C) 1999 Keith Whitwell <keithw@precisioninsight.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - original by Jeff Hartmann <slicer@ionet.net> - 6/16/99: rewrite by John Carmack <johnc@idsoftware.com> - Oct 99: port to i180 by Keith Whitwell <keithw@precisioninsight.com> -*/ - -#ifndef I810DMA_H -#define I810DMA_H - -#include "i810lib.h" -#include "mm.h" - -/* a flush command will guarantee that all data added to the dma buffer -is on its way to the card, and will eventually complete with no more -intervention. -*/ -void i810DmaFlush( i810ContextPtr imesa ); - -/* the overflow function is called when a block can't be allocated -in the current dma buffer. It flushes the current buffer and -records some information */ -void i810DmaOverflow(int newDwords); - -/* a finish command will guarantee that all dma commands have actually -been consumed by the card. Note that there may still be a couple primitives -that have not yet been executed out of the internal FIFO, so this does not -guarantee that the drawing engine is idle. */ -void i810DmaFinish( i810ContextPtr imesa ); - - - -typedef struct { - unsigned long Start; - unsigned long End; - unsigned long Size; -} I810MemRange; - - - -typedef struct i810_batch_buffer { - I810MemRange mem; - char *virtual_start; - int head; - int space; - int additional_space; - int texture_age; -} i810BatchBuffer; - - - -#define I810_USE_BATCH 0 -#if I810_USE_BATCH - -#define BEGIN_BATCH( imesa, n ) \ - unsigned int outbatch; \ - volatile char *virt; \ - if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - fprintf(stderr, \ - "BEGIN_BATCH(%d) in %s\n" \ - "(spc left %d/%ld, head %x vstart %p start %lx)\n", \ - n, __FUNCTION__, i810glx.dma_buffer->space, \ - i810glx.dma_buffer->mem.Size - i810glx.dma_buffer->head, \ - i810glx.dma_buffer->head, \ - i810glx.dma_buffer->virtual_start, \ - i810glx.dma_buffer->mem.Start ); \ - if (i810glx.dma_buffer->space < n*4) \ - i810DmaOverflow(n); \ - outbatch = i810glx.dma_buffer->head; \ - virt = i810glx.dma_buffer->virtual_start; - - -#define OUT_BATCH(val) { \ - *(volatile unsigned int *)(virt + outbatch) = val; \ - if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - fprintf(stderr, "OUT_BATCH %x: %x\n", (int)(outbatch/4), (int)(val)); \ - outbatch += 4; \ -} - - -#define ADVANCE_BATCH() { \ - if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - fprintf(stderr, "ADVANCE_BATCH(%f) in %s\n", \ - (outbatch - i810glx.dma_buffer->head) / 4.0, \ - __FUNCTION__); \ - i810glx.dma_buffer->space -= outbatch - i810glx.dma_buffer->head; \ - i810glx.dma_buffer->head = outbatch; \ -} - -#define FINISH_PRIM() - -#else - - -/* As an alternate path to dma, we can export the registers (and hence - * ringbuffer) to the client. For security we should alloc these - * things in agp memory which isn't exported to the client. But then - * again, the client could blit over such things if it wanted to hang - * the system. - * - * Malicious clients aren't really delt with by the DRI. - */ - - -extern void _I810RefreshLpRing( i810ContextPtr imesa, int update ); -extern int _I810WaitLpRing( i810ContextPtr imesa, int n, int timeout_usec ); -extern int _I810Sync( i810ContextPtr imesa ); - - -#define OUT_RING(n) { \ - if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - fprintf(stderr, "OUT_RING %x: %x\n", outring, (int)(n)); \ - if (!(I810_DEBUG & DEBUG_NO_OUTRING)) { \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ - } \ -} - -#define ADVANCE_LP_RING() { \ - i810glx.LpRing.tail = outring; \ - OUTREG(LP_RING + RING_TAIL, outring); \ -} - -#define BEGIN_LP_RING(imesa, n) \ - unsigned int outring, ringmask; \ - volatile char *virt; \ - if ((I810_DEBUG&DEBUG_ALWAYS_SYNC) && n>2) _I810Sync( imesa ); \ - if (i810glx.LpRing.space < n*4) _I810WaitLpRing( imesa, n*4, 0); \ - i810glx.LpRing.space -= n*4; \ - if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - fprintf(stderr, "BEGIN_LP_RING %d in %s\n", n, __FUNCTION__); \ - if (I810_DEBUG & DEBUG_VALIDATE_RING) { \ - CARD32 tail = INREG(LP_RING+RING_TAIL); \ - if (tail != i810glx.LpRing.tail) { \ - fprintf(stderr, "tail %x pI810->LpRing.tail %x\n", \ - (int) tail, (int) i810glx.LpRing.tail); \ - exit(1); \ - } \ - } \ - i810glx.LpRing.synced = 0; \ - outring = i810glx.LpRing.tail; \ - ringmask = i810glx.LpRing.tail_mask; \ - virt = i810glx.LpRing.virtual_start; - - -#define EXTRAAA \ - -#define INREG(addr) *(volatile CARD32 *)(i810glx.MMIOBase + (addr)) -#define INREG16(addr) *(volatile CARD16 *)(i810glx.MMIOBase + (addr)) -#define INREG8(addr) *(volatile CARD8 *)(i810glx.MMIOBase + (addr)) - -#define OUTREG(addr, val) do { \ - if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) \ - fprintf(stderr, "OUTREG(%x, %x)\n", addr, val); \ - if (!(I810_DEBUG&DEBUG_NO_OUTREG)) \ - *(volatile CARD32 *)(i810glx.MMIOBase + (addr)) = (val); \ -} while (0) - - -#define BEGIN_BATCH(imesa, n) BEGIN_LP_RING(imesa, n) -#define ADVANCE_BATCH() ADVANCE_LP_RING() -#define OUT_BATCH(val) OUT_RING(val) -#define FINISH_PRIM() OUTREG(LP_RING + RING_TAIL, i810glx.LpRing.tail) - -#endif - - - -#endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c new file mode 100644 index 000000000..b4e86cff2 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c @@ -0,0 +1,477 @@ +#include <stdio.h> +#include <unistd.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 drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa ) +{ + drm_i810_dma_t dma; + drmBufPtr buf; + int retcode; + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "Getting dma buffer\n"); + + while (1) { + retcode = ioctl(imesa->driFd, DRM_IOCTL_I810_GETBUF, &dma); + + if (dma.granted == 1 && retcode == 0) + break; + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "Retcode : %d, granted : %d\n", retcode, dma.granted); + + ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH); + } + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, + "imesa->i810Screen->bufs->list : %p, " + "dma.request_idx : %d\n", + imesa->i810Screen->bufs->list, dma.request_idx); + + buf = &(imesa->i810Screen->bufs->list[dma.request_idx]); + buf->idx = dma.request_idx; + buf->used = 0; + buf->total = dma.request_size; + buf->address = (drmAddress)dma.virtual; + return buf; +} + + + +#define DEPTH_SCALE ((1<<16)-1) + +GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + drm_i810_clear_t clear; + int i; + + clear.flags = 0; + clear.clear_color = imesa->ClearColor; + clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE); + + FLUSH_BATCH( imesa ); + + if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) { + clear.flags |= I810_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) { + clear.flags |= I810_BACK; + mask &= ~DD_BACK_LEFT_BIT; + } + + if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) { + clear.flags |= I810_DEPTH; + mask &= ~DD_DEPTH_BIT; + } + + if (!clear.flags) + return mask; + + LOCK_HARDWARE( imesa ); + + /* flip top to bottom */ + cy = dPriv->h-cy-ch; + cx += imesa->drawX; + cy += imesa->drawY; + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "Clear, bufs %x nbox %d\n", + (int)clear.flags, (int)imesa->numClipRects); + + for (i = 0 ; i < imesa->numClipRects ; ) + { + int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, imesa->numClipRects); + XF86DRIClipRectRec *box = imesa->pClipRects; + drm_clip_rect_t *b = imesa->sarea->boxes; + int n = 0; + + if (!all) { + for ( ; i < nr ; i++) { + GLint x = box[i].x1; + GLint y = box[i].y1; + GLint w = box[i].x2 - x; + GLint h = box[i].y2 - y; + + if (x < cx) w -= cx - x, x = cx; + if (y < cy) h -= cy - y, y = cy; + if (x + w > cx + cw) w = cx + cw - x; + if (y + h > cy + ch) h = cy + ch - y; + if (w <= 0) continue; + if (h <= 0) continue; + + b->x1 = x; + b->y1 = y; + b->x2 = x + w; + b->y2 = y + h; + b++; + n++; + } + } else { + for ( ; i < nr ; i++) { + *b++ = *(drm_clip_rect_t *)&box[i]; + n++; + } + } + + imesa->sarea->nbox = n; + ioctl(imesa->driFd, DRM_IOCTL_I810_CLEAR, &clear); + } + + UNLOCK_HARDWARE( imesa ); + imesa->dirty |= I810_UPLOAD_CLIPRECTS; + + return mask; +} + + + + +/* + * Copy the back buffer to the front buffer. + */ +void i810SwapBuffers( i810ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + XF86DRIClipRectPtr pbox; + int nbox; + int i; + int tmp; + + FLUSH_BATCH( imesa ); + LOCK_HARDWARE( imesa ); + + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + + for (i = 0 ; i < nbox ; ) + { + int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, dPriv->numClipRects); + XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)imesa->sarea->boxes; + + imesa->sarea->nbox = nr - i; + + for ( ; i < nr ; i++) + *b++ = pbox[i]; + + ioctl(imesa->driFd, DRM_IOCTL_I810_SWAP); + } + + tmp = GET_ENQUEUE_AGE(imesa); + UNLOCK_HARDWARE( imesa ); + + if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) + i810WaitAge(imesa, imesa->lastSwap); + + imesa->lastSwap = tmp; + imesa->dirty |= I810_UPLOAD_CLIPRECTS; +} + + + + + + +/* 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; + + + 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->used %d\n", + buffer->used); + + if (!buffer) + return; + + if (imesa->dirty & ~I810_UPLOAD_CLIPRECTS) + i810EmitHwStateLocked( imesa ); + + if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) + fprintf(stderr, "i810FlushVerticesLocked, used %d\n", + buffer->used); + + 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_UPLOAD_CLIPRECTS; + + imesa->sarea->vertex_prim = imesa->vertex_prim; + + if (!nbox || !(imesa->dirty & I810_UPLOAD_CLIPRECTS)) + { + 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 prim ) +{ + GLuint *start; + + 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 ); + imesa->vertex_dma_buffer->used = 4; + imesa->vertex_prim = prim; + UNLOCK_HARDWARE(imesa); + } + else if (imesa->vertex_prim != prim || + 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 ); + imesa->vertex_dma_buffer->used = 4; + imesa->vertex_prim = prim; + 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; + + 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..004b723b4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h @@ -0,0 +1,36 @@ +#ifndef MGA_IOCTL_H +#define MGA_IOCTL_H + +#include "i810context.h" + + +GLuint *i810AllocDwords( i810ContextPtr imesa, int dwords, GLuint prim ); + +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 ); + +void i810SwapBuffers( i810ContextPtr imesa ); + +GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ); + +#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 deleted file mode 100644 index ad80674f0..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810lib.h +++ /dev/null @@ -1,130 +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. - * - * - */ - -#ifndef I810LIB_INC -#define I810LIB_INC - -#include <stdio.h> - -#include "i810context.h" -#include "mm.h" -#include "i810log.h" - - -struct i810_mem_range { - unsigned long Start; - unsigned long End; - unsigned long Size; -}; - -struct i810_batch_buffer; - -struct i810_ring_buffer { - int tail_mask; - struct i810_mem_range mem; - char *virtual_start; - int head; - int tail; - int space; - int synced; -}; - -typedef struct { - /* logging stuff */ - GLuint logLevel; - FILE *logFile; - - /* bookkeeping for texture swaps */ - GLuint dma_buffer_age; - GLuint current_texture_age; - - /* options */ - GLuint nullprims; /* skip all primitive generation */ - GLuint boxes; /* draw performance boxes */ - GLuint noFallback; /* don't fall back to software */ - GLuint skipDma; /* don't send anything to hardware */ - - /* performance counters */ - GLuint c_setupPointers; - GLuint c_triangles; - GLuint c_points; - GLuint c_lines; - GLuint c_drawWaits; - GLuint c_textureSwaps; - GLuint c_dmaFlush; - GLuint c_overflows; - - GLuint c_ringlost; - GLuint c_texlost; - GLuint c_ctxlost; - - GLuint hardwareWentIdle; /* cleared each swapbuffers, set if a - waitfordmacompletion ever exited - without having to wait */ - - unsigned char *texVirtual; - - - struct i810_batch_buffer *dma_buffer; - struct i810_ring_buffer LpRing; - unsigned char *MMIOBase; - -} i810Glx_t; - -extern i810Glx_t i810glx; - - -#define I810PACKCOLOR1555(r,g,b,a) \ - ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ - ((a) ? 0x8000 : 0)) - -#define I810PACKCOLOR565(r,g,b) \ - ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) - -#define I810PACKCOLOR4444(r,g,b,a) \ - ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) - - -#include "i810_3d_reg.h" - -static __inline__ GLuint i810PackColor(GLuint format, - GLubyte r, GLubyte g, - GLubyte b, GLubyte a) -{ - switch (format) { - case DV_PF_555: - return I810PACKCOLOR1555(r,g,b,a); - case DV_PF_565: - return I810PACKCOLOR565(r,g,b); - default: - fprintf(stderr, "unknown format %d\n", (int)format); - return 0; - } -} - - - - -#endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c index fb2d368fe..34171d943 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c @@ -1,13 +1,15 @@ /* #include "i810pipeline.h" */ #include <stdio.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" static struct gl_pipeline_stage i810_fast_stage = { "I810 fast path", diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c index 5ea27fd84..aa4f22d0c 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810span.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810span.c @@ -1,31 +1,39 @@ #include "types.h" #include "i810dd.h" -#include "i810lib.h" -#include "i810dma.h" #include "i810log.h" #include "i810span.h" +#include "i810ioctl.h" #define DBG 0 - #define LOCAL_VARS \ - i810ContextPtr imesa = I810_CONTEXT(ctx); \ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ - __DRIscreenPrivate *sPriv = imesa->driScreen; \ i810ScreenPrivate *i810Screen = imesa->i810Screen; \ - GLuint pitch = i810Screen->auxPitch; \ + GLuint pitch = i810Screen->backPitch; \ GLuint height = dPriv->h; \ - char *buf = (char *)(sPriv->pFB + \ - imesa->drawOffset + \ - dPriv->x * 2 + \ + 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 + +#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) -#define INIT_MONO_PIXEL(p) \ - GLushort p = I810_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,_i) \ @@ -34,15 +42,20 @@ _n1 = _n; \ _x1 = _x; \ if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \ - if (_x1 + _n1 > maxx) n1 -= (_x1 + n1 - maxx); \ + if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \ } +#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; \ - LOCK_HARDWARE(imesa); \ - if (!i810glx.LpRing.synced) _I810Sync( imesa ); \ while (_nc--) { \ int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \ int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \ @@ -52,13 +65,16 @@ #define HW_ENDCLIPLOOP() \ } \ - UNLOCK_HARDWARE(imesa); \ } while (0) +#define HW_UNLOCK() \ + UNLOCK_HARDWARE(imesa); + -#define Y_FLIP(_y) (height - _y) +/* 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) | \ @@ -66,13 +82,13 @@ #define WRITE_PIXEL( _x, _y, p ) \ *(GLushort *)(buf + _x*2 + _y*pitch) = p -#define READ_RGBA( rgba, _x, _y ) \ -do { \ - GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 8) & 0xf8; \ - rgba[1] = (p >> 3) & 0xfc; \ - rgba[2] = (p << 3) & 0xf8; \ - rgba[3] = 0; /* or 255? */ \ +#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] = 255; \ } while(0) #define TAG(x) i810##x##_565 @@ -81,28 +97,46 @@ do { \ - -#define WRITE_RGBA( _x, _y, r, g, b, a ) \ +/* 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) | \ + ((g & 0xf8) << 3) | \ ((b & 0xf8) >> 3)) #define WRITE_PIXEL( _x, _y, p ) \ *(GLushort *)(buf + _x*2 + _y*pitch) = p -#define READ_RGBA( rgba, _x, _y ) \ -do { \ - GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 7) & 0xf8; \ - rgba[1] = (p >> 3) & 0xf8; \ - rgba[2] = (p << 3) & 0xf8; \ - rgba[3] = 0; /* or 255? */ \ +#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] = 255; \ } while(0) #define TAG(x) i810##x##_555 #include "spantmp.h" + + +/* 16 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + _x*2 + _y*pitch); + +/* d = 0xffff; */ + +#define TAG(x) i810##x##_16 +#include "depthtmp.h" + + + void i810DDInitSpanFuncs( GLcontext *ctx ) { if (1) { @@ -123,6 +157,11 @@ void i810DDInitSpanFuncs( GLcontext *ctx ) 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; diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.c b/xc/lib/GL/mesa/src/drv/i810/i810state.c index bc3391e42..80332e3b3 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810state.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810state.c @@ -7,24 +7,40 @@ #include "dd.h" #include "mm.h" -#include "i810lib.h" #include "i810dd.h" #include "i810context.h" #include "i810state.h" -#include "i810depth.h" #include "i810tex.h" #include "i810log.h" #include "i810vb.h" #include "i810tris.h" +#include "i810ioctl.h" + + +static __inline__ GLuint i810PackColor(GLuint format, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + switch (format) { + case DV_PF_555: + return I810PACKCOLOR1555(r,g,b,a); + case DV_PF_565: + return I810PACKCOLOR565(r,g,b); + default: + fprintf(stderr, "unknown format %d\n", (int)format); + return 0; + } +} 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; @@ -44,10 +60,6 @@ static void i810DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref) imesa->Setup[I810_CTXREG_ZA] |= a; } -/* This shouldn't get called, as the extension is disabled. However, - * there are internal Mesa calls, and rogue use of the api which must be - * caught. - */ static void i810DDBlendEquation(GLcontext *ctx, GLenum mode) { if (mode != GL_FUNC_ADD_EXT) { @@ -60,9 +72,8 @@ static void i810DDBlendEquation(GLcontext *ctx, GLenum mode) static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) { i810ContextPtr imesa = I810_CONTEXT(ctx); - GLuint a; - - a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND; + GLuint a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND; + FLUSH_BATCH(imesa); switch (ctx->Color.BlendSrcRGB) { case GL_ZERO: a |= SDM_SRC_ZERO; break; @@ -73,13 +84,8 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_SRC_INV_SRC_ALPHA; break; case GL_DST_ALPHA: a |= SDM_SRC_ONE; break; case GL_ONE_MINUS_DST_ALPHA: a |= SDM_SRC_ZERO; break; - case GL_SRC_ALPHA_SATURATE: - a |= SDM_SRC_SRC_ALPHA; /* use GFXRENDERSTATE_COLOR_FACTOR ??? */ - break; - default: - i810Error("unknown blend source func"); - exit(1); - return; + case GL_SRC_ALPHA_SATURATE: a |= SDM_SRC_SRC_ALPHA; break; + default: return; } switch (ctx->Color.BlendDstRGB) { @@ -91,10 +97,7 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) case GL_ONE_MINUS_SRC_COLOR: a |= SDM_DST_INV_SRC_COLOR; break; case GL_DST_ALPHA: a |= SDM_DST_ONE; break; case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break; - default: - i810Error( "unknown blend dst func"); - exit(1); - return; + default: return; } imesa->dirty |= I810_UPLOAD_CTX; @@ -123,6 +126,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; @@ -134,9 +139,9 @@ static void i810DDDepthFunc(GLcontext *ctx, GLenum func) case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break; default: return; } - + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK; - imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_ZMODE | zmode; + imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_ZMODE | zmode; imesa->dirty |= I810_UPLOAD_CTX; } @@ -144,20 +149,62 @@ static void i810DDDepthMask(GLcontext *ctx, GLboolean flag) { i810ContextPtr imesa = I810_CONTEXT(ctx); + 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; } +/* ============================================================= + * 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->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; +} @@ -167,40 +214,26 @@ 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); - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - int x1,x2,y1,y2; - x1 = ctx->Scissor.X; - x2 = ctx->Scissor.X + ctx->Scissor.Width - 1; - y1 = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; - y2 = dPriv->h - ctx->Scissor.Y - 1; - - if (x1 < 0) x1 = 0; - if (y1 < 0) y1 = 0; - if (x2 >= dPriv->w) x2 = dPriv->w-1; - if (y2 >= dPriv->h) y2 = dPriv->h-1; - - if (x1 > x2 || y1 > y2) { - x1 = 0; x2 = 0; - y2 = 0; y1 = 1; - } + 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; - /* Need to push this into drawing rectangle. - */ -#if 0 - imesa->Setup[I810_CTXREG_SCI0] = GFX_OP_SCISSOR_INFO; - imesa->Setup[I810_CTXREG_SCI1] = (y1<<16)|x1; - imesa->Setup[I810_CTXREG_SCI2] = (y2<<16)|x2; + 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); - /* Need to intersect with cliprects??? - */ - imesa->dirty |= I810_UPLOAD_CTX; -#endif + imesa->dirty |= I810_UPLOAD_CLIPRECTS; } @@ -209,38 +242,56 @@ static void i810DDDither(GLcontext *ctx, GLboolean enable) } -static GLboolean i810DDSetBuffer(GLcontext *ctx, GLenum mode ) +static GLboolean i810DDSetDrawBuffer(GLcontext *ctx, GLenum mode ) { i810ContextPtr imesa = I810_CONTEXT(ctx); + FLUSH_BATCH(imesa); - fprintf(stderr, "i810DDSetBuffer %s\n", gl_lookup_enum_by_nr( mode )); - - imesa->Fallback &= ~I810_FALLBACK_BUFFER; + imesa->Fallback &= ~I810_FALLBACK_DRAW_BUFFER; if (mode == GL_FRONT_LEFT) { - imesa->drawOffset = imesa->i810Screen->fbOffset; + imesa->drawMap = imesa->driScreen->pFB; imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset | - imesa->i810Screen->auxPitchBits); + imesa->i810Screen->backPitchBits); imesa->dirty |= I810_UPLOAD_BUFFERS; i810XMesaSetFrontClipRects( imesa ); return GL_TRUE; } else if (mode == GL_BACK_LEFT) { - imesa->drawOffset = imesa->i810Screen->backOffset; + imesa->drawMap = imesa->i810Screen->back.map; imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset | - imesa->i810Screen->auxPitchBits); + imesa->i810Screen->backPitchBits); imesa->dirty |= I810_UPLOAD_BUFFERS; i810XMesaSetBackClipRects( imesa ); return GL_TRUE; } - imesa->Fallback |= I810_FALLBACK_BUFFER; + imesa->Fallback |= I810_FALLBACK_DRAW_BUFFER; return GL_FALSE; } +static void i810DDSetReadBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, + GLenum mode ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + 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, @@ -248,9 +299,7 @@ static void i810DDSetColor(GLcontext *ctx, GLubyte b, GLubyte a ) { i810ContextPtr imesa = I810_CONTEXT(ctx); - - imesa->MonoColor = i810PackColor( imesa->i810Screen->fbFormat, - r, g, b, a ); + imesa->MonoColor = i810PackColor( imesa->i810Screen->fbFormat, r, g, b, a ); } @@ -259,9 +308,7 @@ static void i810DDClearColor(GLcontext *ctx, GLubyte b, GLubyte a ) { i810ContextPtr imesa = I810_CONTEXT(ctx); - - imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat, - r, g, b, a ); + imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat, r, g, b, a ); } @@ -274,6 +321,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) @@ -288,27 +337,49 @@ static void i810DDCullFaceFrontFace(GLcontext *ctx, GLenum unused) { 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->dirty |= I810_UPLOAD_CTX; - 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); - LOCK_HARDWARE(imesa); - i810EmitHwStateLocked( imesa ); - UNLOCK_HARDWARE(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: + 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; } } @@ -318,15 +389,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 @@ -336,8 +428,14 @@ static GLboolean i810DDColorMask(GLcontext *ctx, static void i810DDLightModelfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { - if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { - I810_CONTEXT(ctx)->new_state |= I810_NEW_TEXTURE; + 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; } } @@ -372,64 +470,105 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) switch(cap) { case GL_ALPHA_TEST: + 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: + 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: + 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: -#if 0 - imesa->dirty |= I810_UPLOAD_CTX; - imesa->Setup[I810_CTXREG_SC] &= ~SC_ENABLE_MASK; - imesa->Setup[I810_CTXREG_SC] |= SC_UPDATE_SCISSOR; - if (state) - imesa->Setup[I810_CTXREG_SC] |= SC_ENABLE; -#endif + FLUSH_BATCH(imesa); + imesa->scissor = state; + imesa->dirty |= I810_UPLOAD_CLIPRECTS; + 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_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: + 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) { + 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: + 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; } @@ -444,92 +583,20 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) /* ============================================================= */ -/* Delightfully few possibilities: - */ -void i810DDPrintState( const char *msg, GLuint state ) -{ - fprintf(stderr, "%s (0x%x): %s\n", - msg, - (unsigned int) state, - (state & I810_NEW_TEXTURE) ? "texture, " : ""); -} void i810DDUpdateHwState( GLcontext *ctx ) { i810ContextPtr imesa = I810_CONTEXT(ctx); - if (imesa->new_state & I810_NEW_TEXTURE) + if (imesa->new_state & I810_NEW_TEXTURE) { + FLUSH_BATCH(imesa); i810UpdateTextureState( ctx ); - - imesa->new_state = 0; - - if (imesa->dirty) { - LOCK_HARDWARE(imesa); - i810EmitHwStateLocked( imesa ); - UNLOCK_HARDWARE(imesa); - } -} - - - -/* - * i810DmaExecute - * Add a block of data to the dma buffer - * - * -- In ring buffer mode, must be called with lock held, and translates to - * OUT_RING rather than outbatch - * - * -- In dma mode, probably won't be used because state updates will have - * to be done via the kernel for security... - */ -static void i810DmaExecute( i810ContextPtr imesa, - GLuint *code, int dwords, const char *where ) -{ - if (I810_DEBUG & DEBUG_VERBOSE_RING) - fprintf(stderr, "i810DmaExecute (%s)\n", where); - - if (dwords & 1) { - i810Error( "Misaligned buffer in i810DmaExecute\n" ); - exit(1); } - { - int i; - BEGIN_BATCH( imesa, dwords); - - for ( i = 0 ; i < dwords ; i++ ) { - if (0) fprintf(stderr, "%d: %x\n", i, code[i]); - OUT_BATCH( code[i] ); - } - - ADVANCE_BATCH(); - } + imesa->new_state = 0; } - -void i810EmitScissorValues( i810ContextPtr imesa, int nr, int emit ) -{ - int x1 = imesa->pClipRects[nr].x1 - imesa->drawX; - int y1 = imesa->pClipRects[nr].y1 - imesa->drawY; - int x2 = imesa->pClipRects[nr].x2 - imesa->drawX; - int y2 = imesa->pClipRects[nr].y2 - imesa->drawY; - - if (I810_DEBUG&DEBUG_VERBOSE_DRI) - fprintf(stderr, "i810EmitScissorValues %d,%d - %d,%d\n", - x1,y1,x2,y2); - - imesa->ClipSetup[I810_CLIPREG_SCI1] = (x1 | (y1 << 16)); - imesa->ClipSetup[I810_CLIPREG_SCI2] = (x2 | (y2 << 16)); - imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR | - SC_UPDATE_SCISSOR | - SC_ENABLE ); - - if (emit) - i810DmaExecute( imesa, - imesa->ClipSetup, I810_CLIP_SETUP_SIZE, "cliprect" ); -} - void i810EmitDrawingRectangle( i810ContextPtr imesa ) { __DRIdrawablePrivate *dPriv = imesa->driDrawable; @@ -545,7 +612,6 @@ void i810EmitDrawingRectangle( i810ContextPtr imesa ) */ imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) | (((unsigned)x0)&0xFFFF)); - /* Clip to screen. */ @@ -556,74 +622,74 @@ void i810EmitDrawingRectangle( i810ContextPtr imesa ) /* Onscreen drawing rectangle. - * - * TODO: clip again to GL scissor values. */ imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0); - imesa->BufferSetup[I810_DESTREG_DR3] = ((y1<<16) | x1); + imesa->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", + fprintf(stderr, "%s (0x%x): %s%s%s%s%s\n", msg, (unsigned int) state, - (state & I810_REFRESH_RING) ? "read-lp-ring, " : "", - (state & I810_REQUIRE_QUIESCENT) ? "req-quiescent, " : "", (state & I810_UPLOAD_TEX0IMAGE) ? "upload-tex0, " : "", (state & I810_UPLOAD_TEX1IMAGE) ? "upload-tex1, " : "", (state & I810_UPLOAD_CTX) ? "upload-ctx, " : "", (state & I810_UPLOAD_BUFFERS) ? "upload-bufs, " : "", - (state & I810_EMIT_CLIPRECT) ? "emit-single-cliprect, " : "" + (state & I810_UPLOAD_CLIPRECTS) ? "upload-cliprects, " : "" ); } -/* Spew the state onto the ringbuffer and/or texture memory. +/* Push the state into the sarea and/or texture memory. */ void i810EmitHwStateLocked( i810ContextPtr imesa ) { if (I810_DEBUG & DEBUG_VERBOSE_API) - i810DDPrintDirty( "i810EmitHwStateLocked", imesa->dirty ); - - if (imesa->dirty & I810_REQUIRE_QUIESCENT) { - i810glx.c_drawWaits += _I810Sync( imesa ); - } + i810DDPrintDirty( "\n\n\ni810EmitHwStateLocked", imesa->dirty ); - /* TODO: Refine mechanism to be equivalent to UploadSubImage - */ - if ((imesa->dirty & I810_UPLOAD_TEX0IMAGE) && imesa->CurrentTexObj[0]) - i810UploadTexImages(imesa, imesa->CurrentTexObj[0]); + if (imesa->dirty & ~I810_UPLOAD_CLIPRECTS) + { + 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_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->dirty & I810_UPLOAD_CTX) + memcpy( imesa->sarea->ContextState, + imesa->Setup, + sizeof(imesa->Setup) ); + + if ((imesa->dirty & I810_UPLOAD_TEX0) && imesa->CurrentTexObj[0]) { + imesa->sarea->dirty |= I810_UPLOAD_TEX0; + memcpy(imesa->sarea->TexState[0], + imesa->CurrentTexObj[0]->Setup, + sizeof(imesa->sarea->TexState[0])); + } - if (imesa->CurrentTexObj[1]) - i810DmaExecute( imesa, imesa->CurrentTexObj[1]->Setup, - I810_TEX_SETUP_SIZE, "tex-1"); + if ((imesa->dirty & I810_UPLOAD_TEX1) && imesa->CurrentTexObj[1]) { + imesa->sarea->dirty |= I810_UPLOAD_TEX1; + memcpy(imesa->sarea->TexState[1], + imesa->CurrentTexObj[1]->Setup, + sizeof(imesa->sarea->TexState[1])); + } + + if (imesa->dirty & I810_UPLOAD_BUFFERS) + memcpy( imesa->sarea->BufferState, + imesa->BufferSetup, + sizeof(imesa->BufferSetup) ); + + imesa->sarea->dirty |= (imesa->dirty & + ~(I810_UPLOAD_TEX1|I810_UPLOAD_TEX0)); + imesa->dirty &= I810_UPLOAD_CLIPRECTS; } - - if (imesa->dirty & I810_UPLOAD_BUFFERS) - i810DmaExecute( imesa, imesa->BufferSetup, - I810_DEST_SETUP_SIZE, "buffers" ); - - if (imesa->dirty & I810_EMIT_CLIPRECT) - i810DmaExecute( imesa, imesa->ClipSetup, - I810_CLIP_SETUP_SIZE, "cliprect" ); - - imesa->dirty = 0; } + void i810DDInitState( i810ContextPtr imesa ) { i810ScreenPrivate *i810Screen = imesa->i810Screen; @@ -797,7 +863,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 | @@ -825,11 +891,9 @@ void i810DDInitState( i810ContextPtr imesa ) imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE; imesa->Setup[I810_CTXREG_ST1] = 0; - - imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS | AA_UPDATE_EDGEFLAG | - 0 | + AA_ENABLE_EDGEFLAG | /* ? */ AA_UPDATE_POLYWIDTH | AA_POLYWIDTH_05 | AA_UPDATE_LINEWIDTH | @@ -839,38 +903,29 @@ void i810DDInitState( i810ContextPtr imesa ) AA_UPDATE_AA_ENABLE | 0 ); - - - memset(imesa->ClipSetup, 0, sizeof(imesa->ClipSetup)); - imesa->ClipSetup[I810_CLIPREG_SCI0] = GFX_OP_SCISSOR_INFO; - imesa->ClipSetup[I810_CLIPREG_SCI1] = 0; - imesa->ClipSetup[I810_CLIPREG_SCI2] = 0; - imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR | - SC_UPDATE_SCISSOR | - 0 ); - - /* This stuff is all invarient as long as we are using - * shared back and depth buffers. - */ memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup)); - imesa->drawOffset = i810Screen->backOffset; imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO; - if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT) + if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT) { + imesa->drawMap = i810Screen->back.map; imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset | - i810Screen->auxPitchBits); - else + i810Screen->backPitchBits); + } else { + imesa->drawMap = imesa->driScreen->pFB; imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset | - i810Screen->auxPitchBits); + 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->auxPitchBits); imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO; imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE; @@ -886,17 +941,31 @@ 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) { 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; + } } @@ -919,8 +988,13 @@ void i810DDInitStateFuncs(GLcontext *ctx) 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.SetBuffer = i810DDSetBuffer; ctx->Driver.Color = i810DDSetColor; ctx->Driver.ClearColor = i810DDClearColor; ctx->Driver.Dither = i810DDDither; @@ -928,6 +1002,5 @@ void i810DDInitStateFuncs(GLcontext *ctx) 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 d0551631e..b43a1a4ff 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810state.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810state.h @@ -1,13 +1,12 @@ #ifndef _I810_STATE_H #define _I810_STATE_H +#include "i810context.h" extern void i810DDUpdateHwState( GLcontext *ctx ); extern void i810DDUpdateState( GLcontext *ctx ); extern void i810DDInitState( i810ContextPtr imesa ); extern void i810DDInitStateFuncs( GLcontext *ctx ); -extern void i810DDPrintState( const char *msg, GLuint state ); - #endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810swap.c b/xc/lib/GL/mesa/src/drv/i810/i810swap.c deleted file mode 100644 index 9220ef9f4..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810swap.c +++ /dev/null @@ -1,259 +0,0 @@ - - -#include "types.h" -#include "vbrender.h" -#include "i810log.h" - -#include <stdio.h> -#include <stdlib.h> - -#include "mm.h" -#include "i810lib.h" -#include "i810dd.h" -#include "i810dma.h" -#include "i810state.h" -#include "i810swap.h" -#include "i810dma.h" - -/* - * i810BackToFront - * - * Blit the visible rectangles from the back buffer to the screen. - * Respects the frontbuffer cliprects, and applies the offset - * necessary if the backbuffer is positioned elsewhere in the screen. - */ -static int i810BackToFront( i810ContextPtr imesa ) -{ - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - i810ScreenPrivate *i810Screen = imesa->i810Screen; - - - /* Use the frontbuffer cliprects: - */ - XF86DRIClipRectPtr pbox = dPriv->pClipRects; - int nbox = dPriv->numClipRects; - - if( nbox ) - { - int i; - int pitch = i810Screen->auxPitch; - - int dx = dPriv->auxX - dPriv->x; - int dy = dPriv->auxY - dPriv->y; - int ofs = ( i810Screen->backOffset + - dy * i810Screen->auxPitch + - dx * i810Screen->cpp); - - unsigned int BR13 = ((i810Screen->fbStride) | - (0xCC << 16)); - - - for (i=0; i < nbox; i++, pbox++) { - int w = pbox->x2 - pbox->x1; - int h = pbox->y2 - pbox->y1; - - int start = ofs + pbox->x1*i810Screen->cpp + pbox->y1*pitch; - int dst = pbox->x1*i810Screen->cpp + pbox->y1*i810Screen->fbStride; - - if (I810_DEBUG&DEBUG_VERBOSE_2D) - fprintf(stderr, "i810BackToFront %d,%d-%dx%d\n", - pbox->x1,pbox->y1,w,h); - - { - BEGIN_BATCH( imesa, 6 ); - OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); - OUT_BATCH( BR13 ); /* dest pitch, rop */ - - OUT_BATCH( (h << 16) | (w * i810Screen->cpp)); - OUT_BATCH( dst ); - - OUT_BATCH( pitch ); /* src pitch */ - OUT_BATCH( start ); - ADVANCE_BATCH(); - } - } - } - - return Success; -} - - -/* - * ClearBox - * - * Add hardware commands to draw a filled box for the debugging - * display. These are drawn into the current drawbuffer, so should - * work with both front and backbuffer rendering. (However, it - * is only ever called on swapbuffer - ie backbuffer rendering). - */ -static void ClearBox( i810ContextPtr imesa, - int cx, int cy, int cw, int ch, - int r, int g, int b ) -{ - __DRIdrawablePrivate *dPriv = imesa->driDrawable; - i810ScreenPrivate *i810Screen = imesa->i810Screen; - - int _nc = imesa->numClipRects; - - while (_nc--) { - int x1 = cx + dPriv->x; - int y1 = cy + dPriv->y; - int x2 = x1 + cw; - int y2 = y1 + ch; - - if (imesa->needClip) { - int rx1 = imesa->pClipRects[_nc].x1; - int ry1 = imesa->pClipRects[_nc].y1; - int rx2 = imesa->pClipRects[_nc].x2; - int ry2 = imesa->pClipRects[_nc].y2; - - - if (x2 < rx1) continue; - if (y2 < ry1) continue; - if (x1 > rx2) continue; - if (y1 > ry2) continue; - if (x1 < rx1) x1 = rx1; - if (y1 < ry1) y1 = ry1; - if (x2 > rx2) x2 = rx2; - if (y2 > ry2) y2 = ry2; - } - - - { - int start = (imesa->drawOffset + - y1 * i810Screen->auxPitch + - x1 * i810Screen->cpp); - - BEGIN_BATCH( imesa, 6 ); - - OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); - OUT_BATCH( BR13_SOLID_PATTERN | - (0xF0 << 16) | - i810Screen->auxPitch ); - OUT_BATCH( ((y2-y1) << 16) | ((x2-x1) * i810Screen->cpp)); - OUT_BATCH( start ); - OUT_BATCH( i810PackColor( i810Screen->fbFormat, r, g, b, 0 ) ); - OUT_BATCH( 0 ); - - if (I810_DEBUG&DEBUG_VERBOSE_2D) - fprintf(stderr, "box %d,%x %d,%d col %x (%d,%d,%d)\n", - (int)x1,(int)y1, (int)x2,(int)y2, - (int)i810PackColor( i810Screen->fbFormat, r, g, b, 0 ), - (int)r, (int)g, (int)b); - - ADVANCE_BATCH(); - } - } -} - - -/* - * performanceBoxes - * Draw some small boxesin the corner of the buffer - * based on some performance information - */ -static void i810PerformanceBoxes( i810ContextPtr imesa ) { - - - /* draw a box to show we are active, so if it is't seen it means - that it is completely software based. Purple is traditional for - direct rendering */ - ClearBox( imesa, 4, 4, 8, 8, 255, 0, 255 ); - - /* draw a red box if we had to wait for drawing to complete - (software render or texture swap) */ - if ( i810glx.c_drawWaits ) { - ClearBox( imesa, 16, 4, 8, 8, 255, 0, 0 ); - i810glx.c_drawWaits = 0; - } - - /* draw a blue box if the 3d context was lost - */ - if ( i810glx.c_ctxlost ) { - ClearBox( imesa, 28, 4, 8, 8, 0, 0, 255 ); - i810glx.c_ctxlost = 0; - } - - /* draw an orange box if texture state was stomped */ - if ( i810glx.c_texlost ) { - ClearBox( imesa, 40, 4, 8, 8, 255, 128, 0 ); - i810glx.c_texlost = 0; - } - - /* draw a yellow box if textures were swapped */ - if ( i810glx.c_textureSwaps ) { - ClearBox( imesa, 56, 4, 8, 8, 255, 255, 0 ); - i810glx.c_textureSwaps = 0; - } - - /* draw a green box if we had to wait for dma to complete (full utilization) - on the previous frame */ - if ( !i810glx.hardwareWentIdle ) { - ClearBox( imesa, 72, 4, 8, 8, 0, 255, 0 ); - } - i810glx.hardwareWentIdle = 0; - -#if 0 - /* show buffer utilization */ - if ( i810glx.c_dmaFlush > 1 ) { - /* draw a solid bar if we flushed more than one buffer */ - ClearBox( imesa, 4, 16, 252, 4, 255, 32, 32 ); - } else { - /* draw bars to represent the utilization of primary and - secondary buffers */ - ClearBox( imesa, 4, 16, 252, 4, 32, 32, 32 ); - t = i810glx.dma_buffer->mem.Size; - w = 252 * i810glx.dma_buffer->head / t; - if ( w < 1 ) { - w = 1; - } - ClearBox( imesa, 4, 16, w, 4, 196, 128, 128 ); - } -#endif - - i810glx.c_dmaFlush = 0; -} - - -static void i810SendDmaFlush( i810ContextPtr imesa ) -{ - BEGIN_BATCH( imesa, 2 ); - OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH ); - OUT_BATCH( 0 ); - ADVANCE_BATCH(); -} - -void i810SwapBuffers( i810ContextPtr imesa ) -{ - if (I810_DEBUG & DEBUG_VERBOSE_API) - fprintf(stderr, "i810SwapBuffers()\n"); - - LOCK_HARDWARE( imesa ); - i810SendDmaFlush( imesa ); - if ( i810glx.boxes ) - i810PerformanceBoxes( imesa ); - i810BackToFront( imesa ); - - /* Check if we are emitting thousands of tiny frames, and if so - * throttle them. Would be better to simply go to sleep until - * our stuff had cleared, rather than polling. A dma solution - * should provide for this. - */ - if (imesa->lastSwap >= imesa->sarea->lastWrap && - imesa->lastSwap >= imesa->sarea->lastSync) { - - if (I810_DEBUG & DEBUG_VERBOSE_API) - fprintf(stderr, "."); - - _I810Sync( imesa ); - } - - imesa->lastSwap = imesa->sarea->lastSync; - if (imesa->sarea->lastWrap > imesa->lastSwap) - imesa->lastSwap = imesa->sarea->lastWrap; - - - UNLOCK_HARDWARE( imesa ); - -/* XSync(imesa->display, 0); */ -} diff --git a/xc/lib/GL/mesa/src/drv/i810/i810swap.h b/xc/lib/GL/mesa/src/drv/i810/i810swap.h deleted file mode 100644 index 1657a717d..000000000 --- a/xc/lib/GL/mesa/src/drv/i810/i810swap.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef I810_SWAP_H -#define I810_SWAP_H - -extern void i810SwapBuffers( i810ContextPtr imesa ); - -#endif diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c index 039c0af59..8c88f2b2b 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tex.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c @@ -28,9 +28,10 @@ #include <GL/gl.h> #include "mm.h" -#include "i810lib.h" +#include "i810context.h" #include "i810tex.h" #include "i810log.h" +#include "i810ioctl.h" #include "simple_list.h" #include "enums.h" @@ -204,6 +205,7 @@ static i810TextureObjectPtr i810CreateTexObj(i810ContextPtr imesa, 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]; @@ -278,24 +280,24 @@ static i810TextureObjectPtr i810CreateTexObj(i810ContextPtr imesa, void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t) { - int i; if (!t) return; /* This is sad - need to sync *in case* we upload a texture * to this newly free memory... */ if (t->MemBlock) { - imesa->dirty |= I810_REQUIRE_QUIESCENT; mmFreeMem(t->MemBlock); - t->MemBlock = 0; + t->MemBlock = 0; + + if (t->age > imesa->dirtyAge) + imesa->dirtyAge = t->age; } if (t->globj) t->globj->DriverData = 0; - for ( i = 0 ; i < 2 ; i++ ) - if ( imesa->CurrentTexObj[i] == t ) - imesa->CurrentTexObj[i] = 0; + if (t->bound) + imesa->CurrentTexObj[t->bound - 1] = 0; remove_from_list(t); free(t); @@ -305,9 +307,11 @@ void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t) static void i810SwapOutTexObj(i810ContextPtr imesa, i810TextureObjectPtr t) { if (t->MemBlock) { - imesa->dirty |= I810_REQUIRE_QUIESCENT; mmFreeMem(t->MemBlock); t->MemBlock = 0; + + if (t->age > imesa->dirtyAge) + imesa->dirtyAge = t->age; } t->dirty_images = ~0; @@ -413,13 +417,28 @@ static void i810UploadTexLevel( i810TextureObjectPtr t, int level ) } break; + case GL_ALPHA: + { + GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset); + GLubyte *src = (GLubyte *)image->Data; + i810Msg(10," CopyA: %p %p\n", dst, src); + + for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { + for (i = 0 ; i < image->Width ; i++) { + dst[i] = I810PACKCOLOR4444(255,255,255,src[0]); + src += 1; + } + } + } + break; + /* TODO: Translate color indices *now*: */ case GL_COLOR_INDEX: { GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset); GLubyte *src = (GLubyte *)image->Data; - i810Msg(10," CopyIndex %p %p\n", dst, src); + i810Msg(10," CopyIndex: %p %p\n", dst, src); for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) { for (i = 0 ; i < image->Width ; i++) { @@ -431,8 +450,8 @@ static void i810UploadTexLevel( i810TextureObjectPtr t, int level ) break; default: - i810Error("Not supported texture format %d\n",(int)image->Format); - exit(1); + i810Error("Not supported texture format %s\n", + gl_lookup_enum_by_nr(image->Format)); } } @@ -449,13 +468,19 @@ void i810PrintLocalLRU( i810ContextPtr imesa ) 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; - i810TexRegion *list = imesa->sarea->texList; + 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", @@ -471,7 +496,7 @@ void i810PrintGlobalLRU( i810ContextPtr imesa ) void i810ResetGlobalLRU( i810ContextPtr imesa ) { - i810TexRegion *list = imesa->sarea->texList; + drm_i810_tex_region_t *list = imesa->sarea->texList; int sz = 1 << imesa->i810Screen->logTextureGranularity; int i; @@ -481,7 +506,7 @@ void i810ResetGlobalLRU( i810ContextPtr imesa ) * when looking up objects at a particular location in texture * memory. */ - for (i = 0 ; (i+1) * sz < imesa->i810Screen->textureSize ; i++) { + for (i = 0 ; (i+1) * sz <= imesa->i810Screen->textureSize ; i++) { list[i].prev = i-1; list[i].next = i+1; list[i].age = 0; @@ -503,7 +528,7 @@ static void i810UpdateTexLRU( i810ContextPtr imesa, i810TextureObjectPtr t ) int logsz = imesa->i810Screen->logTextureGranularity; int start = t->MemBlock->ofs >> logsz; int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - i810TexRegion *list = imesa->sarea->texList; + drm_i810_tex_region_t *list = imesa->sarea->texList; imesa->texAge = ++imesa->sarea->texAge; @@ -556,7 +581,7 @@ void i810TexturesGone( i810ContextPtr imesa, /* It overlaps - kick it off. Need to hold onto the currently bound * objects, however. */ - if (t == imesa->CurrentTexObj[0] || t == imesa->CurrentTexObj[1]) + if (t->bound) i810SwapOutTexObj( imesa, t ); else i810DestroyTexObj( imesa, t ); @@ -583,7 +608,6 @@ int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t ) { int i; int ofs; - i810glx.c_textureSwaps++; /* Do we need to eject LRU texture objects? */ @@ -594,18 +618,24 @@ int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t ) if (t->MemBlock) break; + if (imesa->TexObjList.prev->bound) { + fprintf(stderr, "Hit bound texture in upload\n"); + i810PrintLocalLRU( imesa ); + return -1; + } + if (imesa->TexObjList.prev == &(imesa->TexObjList)) { - fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); + 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; + t->BufAddr = imesa->i810Screen->tex.map + ofs; imesa->dirty |= I810_UPLOAD_CTX; } @@ -613,6 +643,14 @@ int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t ) */ 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, "*"); @@ -694,21 +732,37 @@ static void i810UpdateTex0State( GLcontext *ctx ) if (t->dirty_images) 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: - imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX0_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_ARG1 ); + case GL_REPLACE: + if (t->image[0].internalFormat == GL_ALPHA) + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_ARG2 ); + else + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_ARG1 ); if (t->image[0].internalFormat == GL_RGB) { ma_modulate_op = MA_OP_ARG1; @@ -812,16 +866,28 @@ static void i810UpdateTex0State( GLcontext *ctx ) MA_OP_ARG1 ); break; case GL_BLEND: - imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_COLOR_FACTOR | - MC_UPDATE_ARG2 | - MC_ARG2_ITERATED_COLOR | - MC_UPDATE_OP | - MC_OP_LIN_BLEND_TEX0_COLOR ); + if (t->image[0].internalFormat == GL_ALPHA) + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_ARG2 ); + else + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_COLOR_FACTOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_LIN_BLEND_TEX0_COLOR ); if (t->image[0].internalFormat == GL_RGB) { imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | @@ -911,7 +977,10 @@ static void i810UpdateTex1State( GLcontext *ctx ) imesa->dirty |= I810_UPLOAD_TEX1IMAGE; imesa->CurrentTexObj[1] = t; + t->bound = 2; + if (t->MemBlock) + i810UpdateTexLRU( imesa, t ); switch (ctx->Texture.Unit[1].EnvMode) { case GL_REPLACE: @@ -1078,11 +1147,15 @@ static void i810UpdateTex1State( GLcontext *ctx ) 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; + imesa->CurrentTexObj[1] = 0; i810UpdateTex0State( ctx ); i810UpdateTex1State( ctx ); - I810_CONTEXT( ctx )->dirty |= I810_UPLOAD_CTX; + I810_CONTEXT( ctx )->dirty |= (I810_UPLOAD_CTX | + I810_UPLOAD_TEX0 | + I810_UPLOAD_TEX1); } @@ -1091,25 +1164,30 @@ void i810UpdateTextureState( GLcontext *ctx ) * DRIVER functions *****************************************/ -static void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param ) +static void i810TexEnv( GLcontext *ctx, GLenum target, + 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->dirty |= I810_UPLOAD_CTX; } @@ -1137,6 +1215,7 @@ static 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; @@ -1163,10 +1242,10 @@ static void i810TexSubImage( GLcontext *ctx, GLenum target, t = (i810TextureObjectPtr) tObj->DriverData; if (t) { + if (t->bound) FLUSH_BATCH( imesa ); i810DestroyTexObj( imesa, t ); tObj->DriverData = 0; imesa->new_state |= I810_NEW_TEXTURE; - i810glx.c_textureSwaps++; } } @@ -1183,15 +1262,18 @@ static 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; @@ -1206,7 +1288,14 @@ static void i810BindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); - imesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0; + + FLUSH_BATCH(imesa); + + 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; } @@ -1216,6 +1305,13 @@ static void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) i810ContextPtr imesa = I810_CONTEXT( ctx ); if (t) { + + if (t->bound) { + FLUSH_BATCH(imesa); + imesa->CurrentTexObj[t->bound-1] = 0; + imesa->new_state |= I810_NEW_TEXTURE; + } + i810DestroyTexObj(imesa,t); tObj->DriverData=0; } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.h b/xc/lib/GL/mesa/src/drv/i810/i810tex.h index d2b153ad8..a16733ec1 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tex.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.h @@ -61,10 +61,11 @@ struct i810_texture_object_t { int Height; int texelBytes; int totalSize; + int bound; PMemBlock MemBlock; char *BufAddr; - + GLuint min_level; GLuint max_level; GLuint dirty_images; @@ -87,8 +88,6 @@ struct i810_texture_object_t { #define I810_UPDATE_PALETTE 0x2 #define I810_FALLBACK_PALETTE 0x4 -typedef struct i810_texture_object_t *i810TextureObjectPtr; - void i810UpdateTextureState( GLcontext *ctx ); void i810DDInitTextureFuncs( GLcontext *ctx ); diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.c b/xc/lib/GL/mesa/src/drv/i810/i810tris.c index 08e012c66..df28991f1 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.c @@ -26,35 +26,17 @@ #include <stdio.h> #include <math.h> +#include "types.h" #include "vb.h" #include "pipeline.h" #include "mm.h" -#include "i810lib.h" #include "i810tris.h" #include "i810vb.h" #include "i810log.h" - -static void i810_null_quad( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint v3, GLuint pv ) -{ -} - -static void i810_null_triangle( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint pv ) -{ -} - -static void i810_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) -{ -} - -static void i810_null_points( GLcontext *ctx, GLuint first, GLuint last ) -{ -} - - +/* Used in i810tritmp.h + */ #define I810_COLOR(to, from) { \ (to)[0] = (from)[2]; \ (to)[1] = (from)[1]; \ @@ -69,17 +51,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, (int) state, - (state & I810_FLAT_BIT) ? "flat, " : "", - (state & I810_OFFSET_BIT) ? "offset, " : "", - (state & I810_TWOSIDE_BIT) ? "twoside, " : "", - (state & I810_ANTIALIAS_BIT) ? "antialias, " : "", - (state & I810_NODRAW_BIT) ? "no-draw, " : "", - (state & I810_FALLBACK_BIT) ? "fallback" : ""); -} #define IND (0) #define TAG(x) x @@ -89,33 +60,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(); @@ -124,128 +94,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( i810ContextPtr imesa, int dwords ) -{ - GLuint orig_dwords = dwords; - - dwords+=2; - dwords&=~1; - - while (1) { - if (i810glx.dma_buffer->space < dwords * 4) - { - if (I810_DEBUG & DEBUG_VERBOSE_RING) - fprintf(stderr, "i810AllocPrimitiveVerts: dma buffer overflow\n"); - i810DmaOverflow( dwords ); - } - else - { - GLuint start = i810glx.dma_buffer->head; - i810glx.dma_buffer->head += dwords * 4; - i810glx.dma_buffer->space -= dwords * 4; - - if ((orig_dwords & 1) == 0) { - *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) = 0; - start += 4; - } - - *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) = - GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1); - - return (GLuint *)(i810glx.dma_buffer->virtual_start + start + 4); - } - } -} - -#else - -/* Hardware lock is held. - */ -GLuint *i810AllocPrimitiveVerts( i810ContextPtr imesa, int dwords ) -{ - GLuint orig_dwords = dwords; - - dwords+=2; - dwords&=~1; - - while (1) - { - BEGIN_LP_RING( imesa, dwords ); - - if (outring + dwords * 4 != ((outring + dwords * 4) & ringmask)) - { - int i; - - if (I810_DEBUG & DEBUG_VERBOSE_RING) - fprintf(stderr, "\n\nwrap case in i810AllocPrimitiveVerts\n\n"); - - for (i = 0 ; i < dwords ; i++) - OUT_RING( 0 ); - ADVANCE_LP_RING(); - } - else - { - i810glx.LpRing.tail = outring + dwords * 4; - - if ((orig_dwords & 1) == 0) - OUT_RING(0); - - OUT_RING( GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1) ); - return (GLuint *)(virt + outring); - } - } -} - -#if 0 -void i810FinishPrim( void ) -{ - char *virt = i810glx.LpRing.virtual_start; - - for (i = i810glx.LpRing.head ; i != i810glx.LpRing.tail ; i += 4) - fprintf(stderr, "prim %x (%f)", *(virt + i), *(float *)(virt + i)); - - OUTREG(LP_RING + RING_TAIL, i810glx.LpRing.tail); -} -#endif -#endif - void i810DDChooseRenderState( GLcontext *ctx ) @@ -253,50 +104,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) { @@ -307,9 +149,9 @@ void i810DDChooseRenderState( GLcontext *ctx ) imesa->QuadFunc = quad_tab[0]; } + if (I810_DEBUG&DEBUG_VERBOSE_API) { gl_print_tri_caps("tricaps", ctx->TriangleCaps); - i810PrintRenderState("i810: Render state", imesa->renderindex); } } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h index 81cdb5159..3b3843683 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h @@ -27,37 +27,48 @@ #define I810TRIS_INC #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( void ); -extern GLuint *i810AllocPrimitiveVerts( i810ContextPtr imesa, int dwords ); - - -/* Todo: - * - multidraw, ... - * - Antialiasing (?) - * - line and polygon stipple - * - select and feedback - * - stencil - * - point parameters - * - - */ -#define I810_ANTIALIAS_BIT 0 /* ignored for now, no fallback */ +/* shared */ #define I810_FLAT_BIT 0x1 + +/* triangle */ #define I810_OFFSET_BIT 0x2 #define I810_TWOSIDE_BIT 0x4 -#define I810_NODRAW_BIT 0x8 -#define I810_FALLBACK_BIT 0x10 -/* Not in use: - */ -#define I810_FEEDBACK_BIT 0x20 -#define I810_SELECT_BIT 0x40 -#define I810_POINT_PARAM_BIT 0x80 /* not needed? */ +/* line */ +#define I810_WIDE_LINE_BIT 0x2 +#define I810_STIPPLE_LINE_BIT 0x4 + +/* shared */ +#define I810_FALLBACK_BIT 0x8 + + + + + +static i810_vertex __inline__ *i810AllocTriangles( i810ContextPtr imesa, int nr) +{ + GLuint *start = i810AllocDwords( imesa, 30*nr, PR_TRIANGLES ); + return (i810_vertex *)start; +} + +static i810_vertex __inline__ *i810AllocLine( i810ContextPtr imesa ) +{ + GLuint *start = i810AllocDwords( imesa, 20, PR_LINES ); + return (i810_vertex *)start; +} + +static i810_vertex __inline__ *i810AllocRect( i810ContextPtr imesa ) +{ + GLuint *start = i810AllocDwords( imesa, 30, PR_RECTS ); + return (i810_vertex *)start; +} @@ -66,23 +77,17 @@ static void __inline__ i810_draw_triangle( i810ContextPtr imesa, i810_vertex *v1, i810_vertex *v2 ) { - i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 30 ); + 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( i810ContextPtr imesa, i810_vertex *tmp, float sz ) { - i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 6*10 ); + i810_vertex *wv = i810AllocTriangles( imesa, 2 ); wv[0] = *tmp; wv[0].x = tmp->x - sz; @@ -108,16 +113,25 @@ static __inline__ void i810_draw_point( i810ContextPtr imesa, wv[5].x = tmp->x - sz; wv[5].y = tmp->y - sz; - FINISH_PRIM(); } -static __inline__ void i810_draw_line( i810ContextPtr imesa, - i810_vertex *tmp0, - i810_vertex *tmp1, - float width ) +static __inline__ void i810_draw_line_line( i810ContextPtr imesa, + i810_vertex *tmp0, + i810_vertex *tmp1 ) { - i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 6 * 10 ); + i810_vertex *wv = i810AllocLine( imesa ); + wv[0] = *tmp0; + wv[1] = *tmp1; +} + +static __inline__ void i810_draw_tri_line( i810ContextPtr imesa, + i810_vertex *tmp0, + i810_vertex *tmp1, + float width ) +{ + i810_vertex *wv = i810AllocTriangles( imesa, 2 ); + float dx, dy, ix, iy; dx = tmp0->x - tmp1->x; @@ -151,8 +165,15 @@ static __inline__ void i810_draw_line( i810ContextPtr imesa, 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 97c101c17..9d6b43d93 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h @@ -63,44 +63,37 @@ static __inline__ void TAG(triangle)( GLcontext *ctx, GLuint e0, } #endif - i810glx.c_triangles++; - - BEGIN_CLIP_LOOP(imesa) - { - i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 30 ); - 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(imesa); + } } - static void TAG(quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, GLuint pv ) @@ -109,25 +102,35 @@ 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; - i810_vertex tmp1 = i810VB[v1].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.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(imesa) - i810_draw_line( imesa, &tmp0, &tmp1, width ); - END_CLIP_LOOP(imesa); + 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; + } } @@ -143,28 +146,22 @@ static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) * ctx->Driver.ReducedPrimitiveChange() callback. */ - BEGIN_CLIP_LOOP(imesa) - for(i=first;i<=last;i++) { - if(VB->ClipMask[i]==0) { - i810_vertex *tmp = &i810VB[i].v; - i810_draw_point( imesa, tmp, sz ); - } + for(i=first;i<=last;i++) { + if(VB->ClipMask[i]==0) { + i810_vertex *tmp = &i810VB[i].v; + i810_draw_point( imesa, tmp, sz ); } - END_CLIP_LOOP(imesa); + } } -#endif static void TAG(init)( void ) { tri_tab[IND] = TAG(triangle); quad_tab[IND] = TAG(quad); - -#if ((IND & ~I810_FLAT_BIT) == 0) line_tab[IND] = TAG(line); points_tab[IND] = TAG(points); -#endif } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c index 6ba7eb9a5..6f8d163c4 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810vb.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c @@ -23,11 +23,9 @@ * */ -#include "i810lib.h" #include "i810context.h" #include "i810vb.h" #include "i810log.h" -#include "i810dma.h" #include "stages.h" diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile index e4e39b747..cbcd09821 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 @@ -9,38 +11,285 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif +#if defined(LinuxArchitecture) +OS_SUBDIR = linux +#endif +#if defined(FreeBSDArchitecture) +OS_SUBDIR = bsd +#endif + +#ifdef i386Architecture +#ifdef MesaUse3DNow + ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM -DUSE_3DNOW_ASM +#else + ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM +#endif +#endif + + #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 \ -I../../../include -I../.. -I../../X -I../common \ - -I$(XF86OSSRC)/linux/drm/kernel + -I$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel #endif MESA_INCLUDES = -I. -I.. -I../../include - DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) - INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \ - -I/usr/include/glide - DRISRCS = mgaclear.c mgacnvtex.c mgadd.c mgadepth.c \ - mgafastpath.c \ + DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(ASM_DEFS) + 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 mgaeltpath.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 \ - mgafastpath.o \ + MGAOBJS = mgaclear.o mgacnvtex.o mgadd.o \ + mgafastpath.o mgaeltpath.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 = ../../aatriangle.c \ + ../../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.c \ + ../../light.c \ + ../../lines.c \ + ../../logic.c \ + ../../masking.c \ + ../../matrix.c \ + ../../mem.c \ + ../../mmath.c \ + ../../pb.c \ + ../../pipeline.c \ + ../../pixel.c \ + ../../pixeltex.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 \ + ../../texutil.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 = ../../aatriangle.o \ + ../../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 \ + ../../pixeltex.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 \ + ../../texutil.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 + +#ifdef MesaUse3DNow + 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) + +REQUIREDLIBS += -lm +#if !GlxBuiltInMga +REQUIREDLIBS += -L../../../.. -lGL +#endif - SRCS = $(DRISRCS) - OBJS = $(DRIOBJS) #if !GlxUseBuiltInDRIDriver #undef DoNormalLib NormalLibGlx @@ -61,7 +310,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..c6aadc144 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,10 +36,12 @@ 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" #include "matrix.h" +#include "mmath.h" #include "simple_list.h" #include "mgadd.h" @@ -49,20 +51,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 @@ -71,18 +78,7 @@ static mgaContextPtr mgaCtx = 0; mgaGlx_t mgaglx; -static int count_bits(unsigned int n) -{ - int bits = 0; - - while (n > 0) { - if (n & 1) bits++; - n >>= 1; - } - return bits; -} - -/* These functions are accessed by dlsym from dri_mesa_init.c: +/* These functions are accessed externally to the driver: * * XMesaInitDriver * XMesaResetDriver @@ -96,18 +92,12 @@ static int count_bits(unsigned int n) * XMesaSwapBuffers * XMesaMakeCurrent * - * So this is kind of the public interface to the driver. The driver - * uses the X11 mesa driver context as a kind of wrapper around its - * own driver context - but there isn't much justificiation for doing - * it that way - the DRI might as well use a (void *) to refer to the - * driver contexts. Nothing in the X context really gets used. */ - GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { mgaScreenPrivate *mgaScreen; - MGADRIPtr gDRIPriv = (MGADRIPtr)sPriv->pDevPriv; + MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv; /* Allocate the private area */ mgaScreen = (mgaScreenPrivate *)Xmalloc(sizeof(mgaScreenPrivate)); @@ -116,30 +106,84 @@ 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.handle = serverInfo->agp; + mgaScreen->agp.size = serverInfo->agpSize; + + if (drmMap(sPriv->fd, + mgaScreen->agp.handle, + mgaScreen->agp.size, + (drmAddress *)&mgaScreen->agp.map) != 0) + { + Xfree(mgaScreen); + return GL_FALSE; + } - mgaScreen->bufs = drmMapBufs(sPriv->fd); + mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset; + mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset | + 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 + + serverInfo->textureOffset); + mgaScreen->texVirtual[MGA_AGP_HEAP] = (mgaScreen->agp.map + + serverInfo->agpTextureOffset); + + mgaScreen->mAccess = serverInfo->mAccess; + + + /* For calculating setupdma addresses. + */ + mgaScreen->dmaOffset = serverInfo->agpBufferOffset; + + /* + fprintf(stderr, "\n\n\nbackOffset: %x pitch %x\n", + mgaScreen->backOffset, + mgaScreen->backPitch); + */ + + mgaScreen->Attrib = MGA_PF_565; + mgaScreen->bufs = drmMapBufs(sPriv->fd); /* Other mgaglx stuff, too?? */ memset(&mgaglx, 0, sizeof(mgaglx)); mgaDDFastPathInit(); + mgaDDEltPathInit(); mgaDDTrifuncInit(); mgaDDSetupInit(); @@ -153,106 +197,53 @@ void XMesaResetDriver(__DRIscreenPrivate *sPriv) Xfree(sPriv->private); } -/* Accessed by dlsym from dri_mesa_init.c - */ -XMesaVisual XMesaCreateVisual(XMesaDisplay *display, - XMesaVisualInfo visinfo, - GLboolean rgb_flag, - GLboolean alpha_flag, - GLboolean db_flag, - GLboolean stereo_flag, - GLboolean ximage_flag, - GLint depth_size, - GLint stencil_size, - GLint accum_size, - GLint level) -{ - XMesaVisual v; - /* Only RGB visuals are supported on the MGA boards */ - if (!rgb_flag) return 0; - - v = (XMesaVisual)Xmalloc(sizeof(struct xmesa_visual)); - if (!v) return 0; - - v->visinfo = (XVisualInfo *)Xmalloc(sizeof(*visinfo)); - if(!v->visinfo) { - Xfree(v); - return 0; - } - memcpy(v->visinfo, visinfo, sizeof(*visinfo)); - - v->display = display; - v->level = level; - - v->gl_visual = (GLvisual *)Xmalloc(sizeof(GLvisual)); - if (!v->gl_visual) { - Xfree(v->visinfo); - XFree(v); - return 0; - } - - v->gl_visual->RGBAflag = rgb_flag; - v->gl_visual->DBflag = db_flag; - v->gl_visual->StereoFlag = stereo_flag; - - v->gl_visual->RedBits = count_bits(visinfo->red_mask); - v->gl_visual->GreenBits = count_bits(visinfo->green_mask); - v->gl_visual->BlueBits = count_bits(visinfo->blue_mask); - v->gl_visual->AlphaBits = 0; /* Not currently supported */ - - v->gl_visual->AccumBits = accum_size; - v->gl_visual->DepthBits = depth_size; - v->gl_visual->StencilBits = stencil_size; - - return v; -} - -void XMesaDestroyVisual(XMesaVisual v) +GLvisual *XMesaCreateVisual(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config) { - Xfree(v->gl_visual); - Xfree(v->visinfo); - Xfree(v); + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual( config->rgba, + config->doubleBuffer, + config->stereo, + _mesa_bitcount(visinfo->red_mask), + _mesa_bitcount(visinfo->green_mask), + _mesa_bitcount(visinfo->blue_mask), + config->alphaSize, + 0, /* index bits */ + config->depthSize, + config->stencilSize, + config->accumRedSize, + config->accumGreenSize, + config->accumBlueSize, + config->accumAlphaSize, + 0 /* num samples */ ); } -XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, - __DRIcontextPrivate *driContextPriv) + +GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv ) { + int i; GLcontext *ctx; - XMesaContext c; mgaContextPtr mmesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private; drm_mga_sarea_t *saPriv=(drm_mga_sarea_t*)(((char*)sPriv->pSAREA)+ sizeof(XF86DRISAREARec)); - GLcontext *shareCtx = 0; + /*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; + return GL_FALSE; } - c->driContextPriv = driContextPriv; - c->xm_visual = v; - c->xm_buffer = 0; /* Set by MakeCurrent */ - c->display = v->display; - c->private = (void *)mmesa; - - if (share_list) - shareCtx=((mgaContextPtr)(share_list->private))->glCtx; - - ctx = mmesa->glCtx = gl_create_context(v->gl_visual, shareCtx, - (void*)mmesa, GL_TRUE); + ctx = driContextPriv->mesaContext; - /* Dri stuff - */ - mmesa->display = v->display; + mmesa->display = dpy; mmesa->hHWContext = driContextPriv->hHWContext; mmesa->driFd = sPriv->fd; mmesa->driHwLock = &sPriv->pSAREA->lock; @@ -260,41 +251,42 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, mmesa->mgaScreen = mgaScreen; mmesa->driScreen = sPriv; mmesa->sarea = saPriv; + mmesa->glBuffer = NULL; - mmesa->glBuffer=gl_create_framebuffer(v->gl_visual); - + 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; + + ctx->DriverCtx = (void *) mmesa; + mmesa->glCtx = ctx; + 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,19 +304,21 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, mgaDDRegisterPipelineStages(ctx->PipelineStage, ctx->PipelineStage, ctx->NrPipelineStages); - return c; + + mgaInitState( mmesa ); + + driContextPriv->driverPrivate = (void *) mmesa; + + return GL_TRUE; } -void XMesaDestroyContext(XMesaContext c) +void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) { - mgaContextPtr mmesa = (mgaContextPtr) c->private; + mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; if (mmesa) { /* mgaTextureObjectPtr next_t, t; */ - gl_destroy_context(mmesa->glCtx); - gl_destroy_framebuffer(mmesa->glBuffer); - /* foreach_s (t, next_t, &(mmesa->TexObjList)) */ /* mgaDestroyTexObj(mmesa, t); */ @@ -333,90 +327,62 @@ void XMesaDestroyContext(XMesaContext c) Xfree(mmesa); - c->private = 0; + driContextPriv->driverPrivate = NULL; } } -XMesaBuffer XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w, - __DRIdrawablePrivate *driDrawPriv) -{ - return (XMesaBuffer)1; -} -XMesaBuffer XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, - XMesaColormap c, - __DRIdrawablePrivate *driDrawPriv) +GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) { - return (XMesaBuffer)1; + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); } -void XMesaDestroyBuffer(XMesaBuffer b) + +GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) { +#if 0 + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); +#else + return NULL; /* not implemented yet */ +#endif } -void XMesaSwapBuffers(XMesaBuffer bogus_value_do_not_use) + +void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) { + /* XXX should do swap according to the buffer, not the context! */ mgaContextPtr mmesa = mgaCtx; FLUSH_VB( mmesa->glCtx, "swap buffers" ); mgaSwapBuffers(mmesa); } - - - -void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ) -{ - __DRIdrawablePrivate *dPriv = mmesa->driDrawable; - - mmesa->numClipRects = dPriv->numClipRects; - mmesa->pClipRects = dPriv->pClipRects; - mmesa->drawX = dPriv->x; - mmesa->drawY = dPriv->y; - - mmesa->drawOffset = mmesa->mgaScreen->frontOffset; -} - - -void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) -{ - __DRIdrawablePrivate *dPriv = mmesa->driDrawable; - - if (dPriv->numAuxClipRects == 0) - { - mmesa->numClipRects = dPriv->numClipRects; - mmesa->pClipRects = dPriv->pClipRects; - mmesa->drawX = dPriv->x; - mmesa->drawY = dPriv->y; - } else { - mmesa->numClipRects = dPriv->numAuxClipRects; - mmesa->pClipRects = dPriv->pAuxClipRects; - mmesa->drawX = dPriv->auxX; - mmesa->drawY = dPriv->auxY; - } - - mmesa->drawOffset = mmesa->mgaScreen->backOffset; -} - - -static void mgaXMesaWindowMoved( mgaContextPtr mmesa ) +GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) { - /* 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; - } + mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; + if (mmesa) + mmesa->dirty = ~0; + return GL_TRUE; } @@ -426,27 +392,24 @@ static void mgaXMesaWindowMoved( mgaContextPtr mmesa ) * * But why are we doing context initialization here??? */ -GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b) +GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) { + if (driContextPriv) { + mgaCtx = (mgaContextPtr) driContextPriv->driverPrivate; - if (c->private==(void *)mgaCtx) return GL_TRUE; - - if (c) { - __DRIdrawablePrivate *dPriv = c->driContextPriv->driDrawablePriv; - - mgaCtx = (mgaContextPtr)c->private; + gl_make_current2(mgaCtx->glCtx, driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer); - - gl_make_current(mgaCtx->glCtx, mgaCtx->glBuffer); - - mgaXMesaWindowMoved( mgaCtx ); - mgaCtx->driDrawable = dPriv; + mgaCtx->driDrawable = driDrawPriv; 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); + gl_Viewport(mgaCtx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h); - } else { + } + else { gl_make_current(0,0); mgaCtx = NULL; } @@ -455,58 +418,37 @@ 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; - - /* 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); + int i; - if (sarea->ctxOwner != me) { - mmesa->dirty |= MGA_UPLOAD_CTX; - } + drmGetLock(mmesa->driFd, mmesa->hHWContext, flags); - if (sarea->texAge != mmesa->texAge) { - int sz = 1 << (mmesa->mgaScreen->logTextureGranularity); - int idx, nr = 0; - - /* Have to go right round from the back to ensure stuff ends up - * LRU in our local list... - */ - for (idx = sarea->texList[MGA_NR_TEX_REGIONS].prev ; - idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ; - idx = sarea->texList[idx].prev, nr++) - { - if (sarea->texList[idx].age > mmesa->texAge) - mgaTexturesGone(mmesa, idx * sz, sz, 1); - } - - if (nr == MGA_NR_TEX_REGIONS) { - mgaTexturesGone(mmesa, 0, mmesa->mgaScreen->textureSize, 0); - mgaResetGlobalLRU( mmesa ); - } - - mmesa->texAge = sarea->texAge; - mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE; + if (*(dPriv->pStamp) != dPriv->lastStamp) { + mmesa->setupdone = 0; + mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); + mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) ); } - if (dPriv->lastStamp != stamp) - mgaXMesaWindowMoved( mmesa ); + mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_CLIPRECTS; - sarea->ctxOwner=me; -} + 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; + } + for (i = 0 ; i < mmesa->lastTexHeap ; i++) + if (sarea->texAge[i] != mmesa->texAge[i]) + mgaAgeTextures( mmesa, i ); + 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..489b71836 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). * */ @@ -42,7 +41,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri_mesaint.h" #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,53 +59,69 @@ typedef struct { int cpp; /* for front and back buffers */ int Attrib; + unsigned int mAccess; - int frontOffset; - int frontPitch; - int backOffset; - int backPitch; + unsigned int frontOffset; + unsigned int frontPitch; + unsigned int backOffset; + unsigned int backPitch; - int depthOffset; - int depthPitch; + unsigned int depthOffset; + unsigned int depthPitch; int depthCpp; - int textureOffset; - int textureSize; - int logTextureGranularity; + unsigned int dmaOffset; + + unsigned int textureOffset[MGA_NR_TEX_HEAPS]; + unsigned int textureSize[MGA_NR_TEX_HEAPS]; + int logTextureGranularity[MGA_NR_TEX_HEAPS]; + char *texVirtual[MGA_NR_TEX_HEAPS]; + __DRIscreenPrivate *sPriv; drmBufMapPtr bufs; + /* Maps the dma buffers as well as textures ? + */ + mgaRegion agp; + } 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 +130,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/mgaeltpath.c b/xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c new file mode 100644 index 000000000..4751eb091 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c @@ -0,0 +1,457 @@ +/* + * GLX Hardware Device Driver for Matrox G400 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include <stdio.h> + +#include "types.h" +#include "enums.h" +#include "cva.h" +#include "vertices.h" +#include "mmath.h" +#include "xform.h" + +#include "mgalib.h" +#include "mgapipeline.h" +#include "mgatris.h" +#include "mgastate.h" +#include "mgavb.h" + + +/* Always use a full-sized stride for vertices. [FIXME] + * Stride in the buffers must be a quadword multiple. + */ +#define BUFFER_STRIDE 12 +#define CLIP_STRIDE 10 + + +static void fire_elts( mgaContextPtr mmesa ) +{ + LOCK_HARDWARE( mmesa ); + + /* Fire queued elements and discard that buffer if its contents + * won't be referenced by future elements. + */ + if (mmesa->elt_buf) { + GLuint retain = (mmesa->elt_buf == mmesa->retained_buf); + + if (mmesa->first_elt != mmesa->next_elt) { + mgaFireEltsLocked( mmesa, + ((GLuint)mmesa->first_elt - + (GLuint)mmesa->elt_buf->address), + ((GLuint)mmesa->next_elt - + (GLuint)mmesa->elt_buf->address), + !retain ); + } else if (!retain) + mgaReleaseBufLocked( mmesa, mmesa->elt_buf ); + + mmesa->elt_buf = 0; + } + else if (mmesa->vertex_dma_buffer) + { + mgaFlushVerticesLocked( mmesa ); + } + + mgaGetEltBufLocked( mmesa ); + + UNLOCK_HARDWARE( mmesa ); + + mmesa->next_vert = (GLfloat *)((GLuint)mmesa->elt_buf->address + + mmesa->elt_buf->total - + BUFFER_STRIDE * sizeof(GLfloat)); + + mmesa->next_vert_phys = (mmesa->mgaScreen->dmaOffset + + mmesa->elt_buf->idx * MGA_DMA_BUF_SZ + + mmesa->elt_buf->total - + BUFFER_STRIDE * sizeof(GLfloat)); + + mmesa->first_elt = (GLuint *)mmesa->elt_buf->address; + mmesa->next_elt = (GLuint *)mmesa->elt_buf->address; + +} + + +static void release_bufs( mgaContextPtr mmesa ) +{ + if (mmesa->retained_buf && mmesa->retained_buf != mmesa->elt_buf) + { + LOCK_HARDWARE( mmesa ); + if (mmesa->first_elt != mmesa->next_elt) { + mgaFireEltsLocked( mmesa, + ((GLuint)mmesa->first_elt - + (GLuint)mmesa->elt_buf->address), + ((GLuint)mmesa->next_elt - + (GLuint)mmesa->elt_buf->address), + 0 ); + + mmesa->first_elt = mmesa->next_elt; + } + + mgaReleaseBufLocked( mmesa, mmesa->retained_buf ); + UNLOCK_HARDWARE( mmesa ); + } + + mmesa->retained_buf = 0; +} + + + + +#define NEGATIVE(f) (f < 0) +#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) +#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) ) + + +#define INTERP_RGBA(t, out, a, b) { \ + int i; \ + for (i = 0; i < 4; i++) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \ + GLfloat fo = LINTERP(t, fa, fb); \ + FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \ + } \ +} + + +#define CLIP(SGN,V,PLANE) \ +if (mask & PLANE) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]]; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + for (i = n = 0 ; i < nr ; i++) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i]; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert]; \ + outdata[n++] = next_vert++; \ + \ + if (NEGATIVE(dpI)) { \ + GLfloat t = dpI / (dpI - dpJ); \ + interp(t, O, I, J); \ + } \ + else \ + { \ + GLfloat t = dpJ / (dpJ - dpI); \ + interp(t, O, J, I); \ + } \ + } \ + \ + if (!NEGATIVE(dpI)) \ + outdata[n++] = elt_i; \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if (n < 3) return; \ +} + + +static void mga_tri_clip( mgaContextPtr mmesa, + struct vertex_buffer *VB, + GLuint *elt, + GLubyte mask ) +{ + struct mga_elt_tab *tab = mmesa->elt_tab; + mga_interp_func interp = tab->interp; + GLuint inlist[2][VB_MAX_CLIPPED_VERTS]; + GLuint in = 0; + GLuint n = 3, next_vert = 3; + GLuint i; + GLfloat verts[VB_MAX_CLIPPED_VERTS][CLIP_STRIDE]; + + /* Build temporary vertices in clipspace. This is the potential + * downside to this path. + */ + tab->build_tri_verts( mmesa, VB, (GLfloat *)verts, elt ); + + inlist[0][0] = 0; + inlist[0][1] = 1; + inlist[0][2] = 2; + + CLIP(-,0,CLIP_RIGHT_BIT); + CLIP(+,0,CLIP_LEFT_BIT); + CLIP(-,1,CLIP_TOP_BIT); + CLIP(+,1,CLIP_BOTTOM_BIT); + CLIP(-,2,CLIP_FAR_BIT); + CLIP(+,2,CLIP_NEAR_BIT); + + + { + GLuint *out = inlist[in]; + GLuint space = (GLuint)mmesa->next_vert - (GLuint)mmesa->next_elt; + + if (space < n * (BUFFER_STRIDE + 3) * sizeof(GLuint)) + fire_elts(mmesa); + + /* Project the new vertices and emit to dma buffers. Translate + * out values to physical addresses for setup dma. + */ + tab->project_and_emit_verts( mmesa, (GLfloat *)verts, out, n ); + + /* Convert the planar polygon to a list of triangles and emit to + * elt buffers. + */ + for (i = 2 ; i < n ; i++) { + mmesa->next_elt[0] = out[0]; + mmesa->next_elt[1] = out[i-1]; + mmesa->next_elt[2] = out[i]; + mmesa->next_elt += 3; + } + } +} + + + + +/* Build a table of functions to clip each primitive type. These + * produce a list of elements in the appropriate 'reduced' primitive, + * ie (points, lines, triangles) containing all the clipped and + * unclipped primitives from the original list. + */ + +#define INIT(x) + +#define TRI_THRESHOLD (3 * sizeof(GLuint)) + +#define UNCLIPPED_VERT(x) (mmesa->first_vert_phys - x * BUFFER_STRIDE * 4) + +#define TRIANGLE( e2, e1, e0 ) \ +do { \ + if ((GLuint)mmesa->next_vert - \ + (GLuint)mmesa->next_elt < TRI_THRESHOLD) \ + fire_elts(mmesa); \ + mmesa->next_elt[0] = UNCLIPPED_VERT(e2); \ + mmesa->next_elt[1] = UNCLIPPED_VERT(e1); \ + mmesa->next_elt[2] = UNCLIPPED_VERT(e0); \ + mmesa->next_elt+=3; \ +} while (0) + +#define CLIP_TRIANGLE( e2, e1, e0 ) \ +do { \ + GLubyte ormask = mask[e2] | mask[e1] | mask[e0]; \ + if (ormask == 0) { \ + TRIANGLE( e2, e1, e0 ); \ + } else if ((mask[e2] & mask[e1] & mask[e0]) == 0) { \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + mga_tri_clip( mmesa, VB, out, ormask ); \ + } \ +} while (0) + +#define LOCAL_VARS \ + mgaContextPtr mmesa = MGA_CONTEXT( VB->ctx ); \ + GLuint *elt = VB->EltPtr->data; \ + GLuint out[VB_MAX_CLIPPED_VERTS]; \ + GLubyte *mask = VB->ClipMask; \ + (void) mask; (void) out; (void) elt; (void) mmesa; + + + +#define RENDER_POINTS(start, count) +#define RENDER_LINE(i1, i0) +#define RENDER_TRI(i2, i1, i0, pv, parity) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if (parity) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD(i3, i2, i1, i0, pv ) \ + CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \ + CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0]) + +#define TAG(x) mga_##x##_elt +#include "render_tmp.h" + + + +#define LOCAL_VARS \ + mgaContextPtr mmesa = MGA_CONTEXT( VB->ctx ); \ + GLuint *elt = VB->EltPtr->data; \ + (void) elt; (void) mmesa; + +#define RENDER_POINTS(start, count) +#define RENDER_LINE(i1, i0) +#define RENDER_TRI(i2, i1, i0, pv, parity) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if (parity) e2 = elt[i1], e1 = elt[i2]; \ + TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD(i3, i2, i1, i0, pv ) \ + TRIANGLE(elt[i3], elt[i2], elt[i0]); \ + TRIANGLE(elt[i2], elt[i1], elt[i0]) + +#define TAG(x) mga_##x##_elt_unclipped +#include "render_tmp.h" + + + + +static void refresh_projection_matrix( GLcontext *ctx ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + GLfloat *m = mmesa->device_matrix; + GLmatrix *mat = &ctx->Viewport.WindowMap; + + 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]); + m[MAT_TY] = (- mat->m[MAT_TY]) + mmesa->driDrawable->h + mmesa->drawY - .5; + m[MAT_SZ] = mat->m[MAT_SZ] * (1.0 / 0x10000); + m[MAT_TZ] = mat->m[MAT_TZ] * (1.0 / 0x10000); +} + +#define CLIP_UBYTE_B 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_R 2 +#define CLIP_UBYTE_A 3 + + +#define TYPE (0) +#define TAG(x) x +#include "mgaelttmp.h" + +#define TYPE (MGA_RGBA_BIT) +#define TAG(x) x##_RGBA +#include "mgaelttmp.h" + +#define TYPE (MGA_TEX0_BIT) +#define TAG(x) x##_TEX0 +#include "mgaelttmp.h" + +#define TYPE (MGA_RGBA_BIT|MGA_TEX0_BIT) +#define TAG(x) x##_RGBA_TEX0 +#include "mgaelttmp.h" + +#define TYPE (MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_RGBA_TEX0_TEX1 +#include "mgaelttmp.h" + +#define TYPE (MGA_TEX0_BIT|MGA_TEX1_BIT) +#define TAG(x) x##_TEX0_TEX1 +#include "mgaelttmp.h" + + +/* Very sparsely popluated array - fix the indices. + */ +static struct mga_elt_tab mgaEltTab[0x80]; + +void mgaDDEltPathInit( void ) +{ + mga_render_init_elt(); + mga_render_init_elt_unclipped(); + + mga_init_eltpath( &mgaEltTab[0] ); + mga_init_eltpath_RGBA( &mgaEltTab[MGA_RGBA_BIT] ); + mga_init_eltpath_TEX0( &mgaEltTab[MGA_TEX0_BIT] ); + mga_init_eltpath_RGBA_TEX0( &mgaEltTab[MGA_RGBA_BIT|MGA_TEX0_BIT] ); + mga_init_eltpath_TEX0_TEX1( &mgaEltTab[MGA_TEX0_BIT|MGA_TEX1_BIT] ); + mga_init_eltpath_RGBA_TEX0_TEX1( &mgaEltTab[MGA_RGBA_BIT|MGA_TEX0_BIT| + MGA_TEX1_BIT] ); +} + +#define VALID_SETUP (MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT) + + + +/* Use a temporary array for device coordinates, so that we can easily + * tap into existing mesa assembly. Otherwise consider emitting + * device coordinates to dma buffers directly from the project/cliptest + * routine. (requires output stride, potential loss of writecombining + * efficiency?) + * + * This path is a lot closer to the standard vertex path in the + * initial stages than the original fastpath. A slightly more optimal + * path could be constructed, but would require us to write new + * assembly. + */ +void mgaDDEltPath( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + struct mga_elt_tab *tab = &mgaEltTab[mmesa->setupindex & VALID_SETUP]; + + VB->ClipPtr = TransformRaw(&VB->Clip, &ctx->ModelProjectMatrix, VB->ObjPtr ); + + refresh_projection_matrix( ctx ); + + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + VB->Projected = gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, + &VB->Win, + VB->ClipMask, + &VB->ClipOrMask, + &VB->ClipAndMask ); + + if (VB->ClipAndMask) + return; + + if (mmesa->vertex_dma_buffer) + mgaFlushVertices( mmesa ); + + if (mmesa->new_state) + mgaDDUpdateHwState( ctx ); + + /* Allocate a single buffer to hold unclipped vertices. All + * unclipped vertices must be contiguous. + */ + if ((GLuint)mmesa->next_vert - (GLuint)mmesa->next_elt < + VB->Count * BUFFER_STRIDE * sizeof(GLuint)) + fire_elts( mmesa ); + + mmesa->retained_buf = mmesa->elt_buf; + + /* Emit unclipped vertices to the buffer. + */ + tab->emit_unclipped_verts( VB ); + + /* Emit indices and clipped vertices to one or more buffers. + */ + if (VB->ClipOrMask) { + mmesa->elt_tab = tab; + mga_render_tab_elt[prim]( VB, 0, VB->EltPtr->count, 0 ); + } else + mga_render_tab_elt_unclipped[prim]( VB, 0, VB->EltPtr->count, 0 ); + + /* Send to hardware and release any retained buffers. + */ + release_bufs( mmesa ); + + /* This indicates that there is no cached data to reuse. + */ + VB->pipeline->data_valid = 0; + VB->pipeline->new_state = 0; +} + diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaelttmp.h b/xc/lib/GL/mesa/src/drv/mga/mgaelttmp.h new file mode 100644 index 000000000..ce758a532 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mgaelttmp.h @@ -0,0 +1,269 @@ +/* + * DRI Hardware Device Driver for G200/G400 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/* Buffers fill from high addresses down with vertices and from low + * addresses up with elements. + */ + + +/* Emit the bulk of the vertices to the first dma buffer. Leave + * empty slots for clipped vertices so that we can still address + * vertices by index. + */ +static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) +{ + GLuint i; + mgaContextPtr mmesa = MGA_CONTEXT(VB->ctx); + GLfloat *dev = VB->Projected->start; + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + + GLfloat *f = mmesa->next_vert; + GLuint count = VB->Count; + GLubyte *clipmask = VB->ClipMask; + + const GLfloat *m = mmesa->device_matrix; + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + + mmesa->retained_buf = mmesa->elt_buf; + mmesa->first_vert_phys = mmesa->next_vert_phys; + + for (i = 0 ; i < count ; f -= BUFFER_STRIDE, i++) + { + if (!clipmask[i]) + { + f[0] = sx * dev[0] + tx; + f[1] = sy * dev[1] + ty; + f[2] = sz * dev[2] + tz; + f[3] = dev[3]; + + if (TYPE & MGA_RGBA_BIT) { +#if defined(USE_X86_ASM) + __asm__ ( + "movl (%%edx),%%eax \n" + "bswap %%eax \n" + "rorl $8,%%eax \n" + "movl %%eax,16(%%edi) \n" + : + : "d" (color), "D" (f) + : "%eax" ); +#else + GLubyte *b = (GLubyte *)&f[4]; + b[CLIP_UBYTE_B] = color[2]; + b[CLIP_UBYTE_G] = color[1]; + b[CLIP_UBYTE_R] = color[0]; + b[CLIP_UBYTE_A] = color[3]; +#endif + } + + if (TYPE & MGA_TEX0_BIT) { +/* fprintf(stderr, "i %d tex0 %f, %f\n", i, */ +/* tex0_data[0], tex0_data[1]); */ + *(int*)&f[6] = *(int*)&tex0_data[0]; + *(int*)&f[7] = *(int*)&tex0_data[1]; + } + + if (TYPE & MGA_TEX1_BIT) { + *(int*)&f[8] = *(int*)&tex1_data[0]; + *(int*)&f[9] = *(int*)&tex1_data[1]; + } + } + + STRIDE_F(dev, 16); + if (TYPE & MGA_RGBA_BIT) color += color_stride; + if (TYPE & MGA_TEX0_BIT) STRIDE_F(tex0_data, tex0_stride); + if (TYPE & MGA_TEX1_BIT) STRIDE_F(tex1_data, tex1_stride); + } + + mmesa->next_vert = f; + mmesa->next_vert_phys -= count * BUFFER_STRIDE * sizeof(GLuint); +} + + +/* Build three temporary clipspace vertex for clipping a triangle. + * Recreate from the VB data rather than trying to read back from + * uncached memory. + */ +static void TAG(build_tri_verts)( mgaContextPtr mmesa, + struct vertex_buffer *VB, + GLfloat *O, + GLuint *elt ) +{ + int i; + + for (i = 0 ; i < 3 ; i++, O += CLIP_STRIDE) { + GLfloat *clip = VB->Clip.start + elt[i]*4; + + O[0] = clip[0]; + O[1] = clip[1]; + O[2] = clip[2]; + O[3] = clip[3]; + + if (TYPE & MGA_RGBA_BIT) { + GLubyte *col = VEC_ELT(VB->ColorPtr, GLubyte, elt[i]); + GLubyte *b = (GLubyte *)&O[4]; + b[CLIP_UBYTE_R] = col[0]; + b[CLIP_UBYTE_G] = col[1]; + b[CLIP_UBYTE_B] = col[2]; + b[CLIP_UBYTE_A] = col[3]; + } + + if (0) + fprintf(stderr, + "build_tri_vert elt[%d]: %d phys: %x (first_phys %x elt_buf %x\n", + i, elt[i], UNCLIPPED_VERT(elt[i]), + mmesa->first_vert_phys, (GLuint)mmesa->elt_buf); + + *(GLuint *)&O[5] = UNCLIPPED_VERT(elt[i]); + + if (TYPE & MGA_TEX0_BIT) { + GLfloat *tex0_data = VEC_ELT(VB->TexCoordPtr[0], GLfloat, elt[i]); + *(int*)&O[6] = *(int*)&tex0_data[0]; + *(int*)&O[7] = *(int*)&tex0_data[1]; + } + + if (TYPE & MGA_TEX1_BIT) { + GLfloat *tex1_data = VEC_ELT(VB->TexCoordPtr[1], GLfloat, elt[i]); + *(int*)&O[8] = *(int*)&tex1_data[0]; + *(int*)&O[9] = *(int*)&tex1_data[1]; + } + } +} + + +/* Interpolate between two of the vertices constructed above. + */ +static void TAG(interp)( GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J ) +{ + O[0] = LINTERP(t, I[0], J[0]); + O[1] = LINTERP(t, I[1], J[1]); + O[2] = LINTERP(t, I[2], J[2]); + O[3] = LINTERP(t, I[3], J[3]); + + if (TYPE & MGA_RGBA_BIT) { + INTERP_RGBA(t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4]))); + } + + if (0) fprintf(stderr, "setting 0x%x to ~0\n", (GLuint)&O[5]); + + *(GLuint *)&O[5] = ~0; /* note that this is a new vertex */ + + if (TYPE & MGA_TEX0_BIT) { + O[6] = LINTERP(t, I[6], J[6]); + O[7] = LINTERP(t, I[7], J[7]); + } + + if (TYPE & MGA_TEX1_BIT) { + O[8] = LINTERP(t, I[8], J[8]); + O[9] = LINTERP(t, I[9], J[9]); + } +} + + + +/* When clipping is complete, scan the final vertex list and emit any + * new ones to dma buffers. Update the element list to a format + * suitable for sending to hardware. + */ +static void TAG(project_and_emit_verts)( mgaContextPtr mmesa, + const GLfloat *verts, + GLuint *elt, + int nr) +{ + + GLfloat *O = mmesa->next_vert; + GLuint phys = mmesa->next_vert_phys; + + const GLfloat *m = mmesa->device_matrix; + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLuint i; + + for (i = 0 ; i < nr ; i++) { + const GLfloat *I = &verts[elt[i] * CLIP_STRIDE]; + GLuint tmp = *(GLuint *)&I[5]; + + if (0) fprintf(stderr, "elt[%d] (tmp 0x%x %d) %d --> ", i, (GLuint)&I[5], + tmp, elt[i]); + + + if ((elt[i] = tmp) == ~0) + { + GLfloat oow = 1.0/I[3]; + + elt[i] = phys; + phys -= BUFFER_STRIDE * sizeof(GLuint); + + O[0] = sx * I[0] * oow + tx; + O[1] = sy * I[1] * oow + ty; + O[2] = sz * I[2] * oow + tz; + O[3] = oow; + + if (TYPE & MGA_RGBA_BIT) { + *(int*)&O[4] = *(int*)&I[4]; + } + + if (TYPE & MGA_TEX0_BIT) { + *(int*)&O[6] = *(int*)&I[6]; + *(int*)&O[7] = *(int*)&I[7]; + } + + if (TYPE & MGA_TEX1_BIT) { + *(int*)&O[8] = *(int*)&I[8]; + *(int*)&O[9] = *(int*)&I[9]; + } + + O -= BUFFER_STRIDE; + } + if (0) fprintf(stderr, "0x%x\n", elt[i]); + } + + mmesa->next_vert = O; + mmesa->next_vert_phys = phys; +} + + + +static void TAG(mga_init_eltpath)( struct mga_elt_tab *tab ) +{ + tab->emit_unclipped_verts = TAG(emit_unclipped_verts); + tab->build_tri_verts = TAG(build_tri_verts); + tab->interp = TAG(interp); + tab->project_and_emit_verts = TAG(project_and_emit_verts); +} + +#undef TYPE +#undef TAG +#undef STRIDE diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c index 8017e7f02..76e0047f8 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c @@ -380,8 +380,10 @@ 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_TX] = mat->m[MAT_TX] + mmesa->drawX + .5; m[MAT_SY] = (- mat->m[MAT_SY]); m[MAT_TY] = (- mat->m[MAT_TY]) + mmesa->driDrawable->h + mmesa->drawY - .5; m[MAT_SZ] = mat->m[MAT_SZ] * (1.0 / 0x10000); @@ -401,8 +403,10 @@ 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_TX] = mat->m[MAT_TX] + mmesa->drawX + .5; m[MAT_SY] = (- mat->m[MAT_SY]); m[MAT_TY] = (- mat->m[MAT_TY]) + mmesa->driDrawable->h + mmesa->drawY - .5; m[MAT_SZ] = mat->m[MAT_SZ] * (1.0 / 0x10000); @@ -484,6 +488,16 @@ void mgaDDFastPath( struct vertex_buffer *VB ) gl_prepare_arrays_cva( VB ); /* still need this */ + if (gl_reduce_prim[prim] == GL_TRIANGLES && + VB->Count < (MGA_DMA_BUF_SZ / 48) && + (ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL| + MAT_FLAG_PERSPECTIVE)) && + mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400) + { + mgaDDEltPath( VB ); + return; + } + /* Reserve enough space for the pathological case. */ if (VB->EltPtr->count * 12 > MGA_DRIVER_DATA(VB)->size) { @@ -507,18 +521,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..683640409 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h @@ -39,7 +39,6 @@ static void TAG(mga_setup_full)( struct vertex_buffer *VB, GLuint do_cliptest ) const GLfloat * const m = ctx->ModelProjectMatrix.m; GLuint start = VB->CopyStart; GLuint count = VB->Count; - GLuint i; gl_xform_points3_v16_general(MGA_DRIVER_DATA(VB)->verts[start].f, m, @@ -71,26 +70,63 @@ static void TAG(mga_setup_full)( struct vertex_buffer *VB, GLuint do_cliptest ) GLuint tex1_stride = VB->TexCoordPtr[1]->stride; GLfloat *f = MGA_DRIVER_DATA(VB)->verts[start].f; - - for (i = start ; i < count ; i++, f += 16) { + GLfloat *end = f+(16*(count-start)); + while (f != end) { if (TYPE & MGA_RGBA_BIT) { +#if defined(USE_X86_ASM) + __asm__ ( + "movl (%%edx),%%eax \n" + "bswap %%eax \n" + "rorl $8,%%eax \n" + "movl %%eax,16(%%edi) \n" + : + : "d" (color), "D" (f) + : "%eax" ); +#else + GLubyte *col = color; GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR]; - GLubyte *col = color; color += color_stride; - b[CLIP_UBYTE_R] = col[0]; - b[CLIP_UBYTE_G] = col[1]; b[CLIP_UBYTE_B] = col[2]; + b[CLIP_UBYTE_G] = col[1]; + b[CLIP_UBYTE_R] = col[0]; b[CLIP_UBYTE_A] = col[3]; +#endif } if (TYPE & MGA_TEX0_BIT) { - f[CLIP_S0] = tex0_data[0]; - f[CLIP_T0] = tex0_data[1]; - STRIDE_F(tex0_data, tex0_stride); +#if defined (USE_X86_ASM) + __asm__ ( + "movl (%%ecx), %%eax \n" + "movl %%eax, 24(%%edi) \n" + "movl 4(%%ecx), %%eax \n" + "movl %%eax, 28(%%edi)" + : + : "c" (tex0_data), "D" (f) + : "%eax"); +#else + *(unsigned int *)(f+CLIP_S0) = *(unsigned int *)tex0_data; + *(unsigned int *)(f+CLIP_T0) = *(unsigned int *)(tex0_data+1); +#endif } if (TYPE & MGA_TEX1_BIT) { - f[CLIP_S1] = tex1_data[0]; - f[CLIP_T1] = tex1_data[1]; - STRIDE_F(tex1_data, tex1_stride); + /* Hits a second cache line. + */ +#if defined (USE_X86_ASM) + __asm__ ( + "movl (%%esi), %%eax \n" + "movl %%eax, 32(%%edi) \n" + "movl 4(%%esi), %%eax \n" + "movl %%eax, 36(%%edi)" + : + : "S" (tex1_data), "D" (f) + : "%eax"); +#else + *(unsigned int *)(f+CLIP_S1) = *(unsigned int *)tex1_data; + *(unsigned int *)(f+CLIP_T1) = *(unsigned int *)(tex1_data+1); +#endif } + if(TYPE & MGA_RGBA_BIT)color += color_stride; + if(TYPE & MGA_TEX0_BIT)STRIDE_F(tex0_data, tex0_stride); + if(TYPE & MGA_TEX1_BIT)STRIDE_F(tex1_data, tex1_stride); + f += 16; } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c index c1819924d..640849e3f 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)) { + fprintf(stderr, "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,59 @@ 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 ); - + if (0) fprintf(stderr, "clear %d: %d,%d %dx%d\n", all,cx,cy,cw,ch); - 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 +226,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 +269,61 @@ 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 (0) 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,13 +331,165 @@ 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); + + FLUSH_BATCH( mmesa ); + + 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); + } +} + + +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_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 ) +{ + 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; + + mmesa->vertex_dma_buffer = 0; + + if (!buffer) + return; + + if (mmesa->dirty_cliprects & mmesa->draw_buffer) + mgaUpdateRects( mmesa, mmesa->draw_buffer ); + + if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS) + mgaEmitHwStateLocked( mmesa ); + + /* 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); + + 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)) + { + 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]; + } + + /* 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 ) { @@ -284,38 +498,221 @@ void mgaFlushVertices( mgaContextPtr mmesa ) UNLOCK_HARDWARE( mmesa ); } +void mgaFlushEltsLocked( mgaContextPtr mmesa ) +{ + if (mmesa->first_elt != mmesa->next_elt) { + mgaFireEltsLocked( mmesa, + ((GLuint)mmesa->first_elt - + (GLuint)mmesa->elt_buf->address), + ((GLuint)mmesa->next_elt - + (GLuint)mmesa->elt_buf->address), + 0 ); + mmesa->first_elt = mmesa->next_elt; + } +} -void mgaFlushVerticesLocked( mgaContextPtr mmesa ) +void mgaFlushElts( mgaContextPtr mmesa ) +{ + LOCK_HARDWARE( mmesa ); + mgaFlushEltsLocked( mmesa ); + UNLOCK_HARDWARE( mmesa ); +} + + +mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ) +{ + int bytes = dwords * 4; + mgaUI32 *head; + + if (!mmesa->vertex_dma_buffer) { + LOCK_HARDWARE( mmesa ); + + if (mmesa->first_elt != mmesa->next_elt) + mgaFlushEltsLocked(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; +} + + +void mgaFireILoadLocked( mgaContextPtr mmesa, + GLuint offset, GLuint length ) +{ + if (!mmesa->iload_buffer) { + fprintf(stderr, "mgaFireILoad: no buffer\n"); + return; + } + + 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 ); +} + + + void mgaDDFlush( GLcontext *ctx ) { - XF86DRIClipRectPtr pbox = mmesa->pClipRects; + 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 %d %d\n", GET_DISPATCH_AGE( mmesa ), mmesa->sarea->last_enqueue); + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); + UNLOCK_HARDWARE( mmesa ); + } +} + + + +void mgaFireEltsLocked( mgaContextPtr mmesa, + GLuint start, + GLuint end, + GLuint discard ) +{ + drm_clip_rect_t *pbox = (drm_clip_rect_t *)mmesa->pClipRects; int nbox = mmesa->numClipRects; + drmBufPtr buffer = mmesa->elt_buf; + drm_mga_indices_t elts; int i; - if (mmesa->dirty) + + if (0) fprintf(stderr, "FireElts %d %d\n", start/4, end/4); + + 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; + + elts.idx = buffer->idx; + elts.start = start; + elts.end = end; + elts.discard = 0; + + if (!nbox) + elts.end = start; + + if (nbox >= MGA_NR_SAREA_CLIPRECTS) + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; + + if (elts.end == start || !(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 (0) + fprintf(stderr, "Firing elts -- case a nbox %d\n", nbox); + + elts.discard = discard; + ioctl(mmesa->driFd, DRM_IOCTL_MGA_INDICES, &elts); + 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; + elts.end = start; + } + } 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 ); + /* Potentially finished with the buffer? + */ + if (nr == nbox) + elts.discard = discard; - break; /* fix dma multiple dispatch */ + if (0) + fprintf(stderr, "Firing elts -- case b nbox %d\n", nbox); + + mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS; + ioctl(mmesa->driFd, DRM_IOCTL_MGA_INDICES, &elts); + age_mmesa(mmesa, mmesa->sarea->last_enqueue); + } } - mga_get_buffer_ioctl( mmesa ); + mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS; +} + +void mgaGetEltBufLocked( mgaContextPtr mmesa ) +{ + mmesa->elt_buf = mga_get_buffer_ioctl( mmesa ); } +void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer ) +{ + drm_mga_vertex_t vertex; + + if (!buffer) return; + + vertex.idx = buffer->idx; + vertex.used = 0; + vertex.discard = 1; + ioctl(mmesa->driFd, DRM_IOCTL_MGA_VERTEX, &vertex); +} 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..900e4a4f8 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h @@ -9,9 +9,37 @@ 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 ); + +void mgaFireEltsLocked( mgaContextPtr mmesa, + GLuint start, + GLuint end, + GLuint discard ); + +void mgaGetEltBufLocked( mgaContextPtr mmesa ); +void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer ); + +void mgaFlushEltsLocked( mgaContextPtr mmesa ); +void mgaFlushElts( mgaContextPtr mmesa ) ; + + /* upload texture */ @@ -19,5 +47,12 @@ 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); \ + else if (mmesa->next_elt != mmesa->first_elt) mgaFlushElts(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..7d086ae28 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgalib.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgalib.h @@ -32,10 +32,10 @@ #include "dri_tmm.h" #include "dri_mesaint.h" #include "dri_mesa.h" -#include "xmesaP.h" #include "types.h" +#include "drm.h" #include "mgacommon.h" #include "mm.h" #include "mgalog.h" @@ -43,7 +43,6 @@ #include "mgatex.h" #include "mgavb.h" -#include "mga_drm_public.h" #include "mga_xmesa.h" @@ -51,11 +50,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 +61,7 @@ */ #define MGA_FALLBACK_TEXTURE 0x1 #define MGA_FALLBACK_BUFFER 0x2 +#define MGA_FALLBACK_STIPPLE 0x3 /* For mgaCtx->new_state. @@ -97,17 +94,45 @@ 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_elt_tab { + void (*emit_unclipped_verts)( struct vertex_buffer *VB ); + + void (*build_tri_verts)( mgaContextPtr mmesa, + struct vertex_buffer *VB, + GLfloat *O, GLuint *elt ); + + void (*interp)( GLfloat t, GLfloat *O, + const GLfloat *I, const GLfloat *J ); + + void (*project_and_emit_verts)( mgaContextPtr mmesa, + const GLfloat *verts, + GLuint *elts, + int nr ); +}; + 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,72 +141,99 @@ 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 */ + unsigned 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 */ + unsigned int dirtyAge; /* buffer age for synchronization */ + unsigned 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; drm_mga_sarea_t *sarea; + + + /* New setupdma path + */ + drmBufPtr elt_buf, retained_buf; + GLuint *first_elt, *next_elt; + GLfloat *next_vert; + GLuint next_vert_phys; + GLuint first_vert_phys; + struct mga_elt_tab *elt_tab; + GLfloat device_matrix[16]; }; @@ -191,16 +243,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 +288,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/mgapipeline.h b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h index d42abddfe..dc0179227 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h @@ -12,4 +12,7 @@ extern GLboolean mgaDDBuildPrecalcPipeline( GLcontext *ctx ); extern void mgaDDFastPath( struct vertex_buffer *VB ); extern void mgaDDFastPathInit( void ); +extern void mgaDDEltPath( struct vertex_buffer *VB ); +extern void mgaDDEltPathInit( void ); + #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgarender.c b/xc/lib/GL/mesa/src/drv/mga/mgarender.c deleted file mode 100644 index 6f406db2d..000000000 --- a/xc/lib/GL/mesa/src/drv/mga/mgarender.c +++ /dev/null @@ -1,334 +0,0 @@ -#include <stdio.h> -#include "mgadd.h" -#include "mgavb.h" -#include "mgadma.h" -#include "mgalib.h" -#include "mgatris.h" -#include "mgastate.h" -#include "xsmesaP.h" -#include "enums.h" - -#define POINT(x) mga_draw_point(&gWin[x], psize) -#define LINE(x,y) mga_draw_line(&gWin[x], &gWin[y], lwidth) -#define TRI(x,y,z) mga_draw_triangle(&gWin[x], &gWin[y], &gWin[z]) - - -/* Direct, and no clipping required. I haven't written the clip funcs - * yet, so this is only useful for the fast path, which does its own - * clipping. - */ -#define RENDER_POINTS( start, count ) \ -do { \ - GLuint e; \ - for(e=start;e<=count;e++) \ - POINT(elt[e]); \ -} while (0) - -#define RENDER_LINE( i1, i ) \ -do { \ - GLuint e1 = elt[i1], e = elt[i]; \ - LINE( e1, e ); \ -} while (0) - - -#define RENDER_TRI( i2, i1, i, pv, parity) \ -do { \ -{ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - if (parity) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \ - TRI(e2, e1, e); \ -}} while (0) - - -#define RENDER_QUAD( i3, i2, i1, i, pv) \ -do { \ - GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - TRI(e3, e2, e); \ - TRI(e2, e1, e); \ -} while (0) - -#define LOCAL_VARS \ - mgaVertexPtr gWin = MGA_DRIVER_DATA(VB)->verts; \ - const GLuint *elt = VB->EltPtr->data; \ - const GLfloat lwidth = VB->ctx->Line.Width; \ - const GLfloat psize = VB->ctx->Point.Size; \ - GLcontext *ctx = VB->ctx; \ - (void) lwidth; (void)psize; (void)ctx; (void) gWin; - - -#define TAG(x) x##_mga_smooth_indirect -#include "render_tmp.h" - - - - -#define RENDER_POINTS( start, count ) \ -do { \ - GLuint e; \ - for(e=start;e<=count;e++) \ - POINT(e); \ -} while (0) - -#define RENDER_LINE( i1, i ) \ -do { \ - LINE( i1, i ); \ -} while (0) - - -#define RENDER_TRI( i2, i1, i, pv, parity) \ -do { \ - GLuint e2 = i2, e1 = i1; \ - if (parity) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \ - TRI(e2, e1, i); \ -} while (0) - - -#define RENDER_QUAD( i3, i2, i1, i, pv) \ -do { \ - TRI(i3, i2, i); \ - TRI(i2, i1, i); \ -} while (0) - -#define LOCAL_VARS \ - mgaVertexPtr gWin = MGA_DRIVER_DATA(VB)->verts; \ - const GLfloat lwidth = VB->ctx->Line.Width; \ - const GLfloat psize = VB->ctx->Point.Size; \ - GLcontext *ctx = VB->ctx; \ - (void) lwidth; (void)psize; (void)ctx; (void) gWin; - -#define TAG(x) x##_mga_smooth_direct -#include "render_tmp.h" - - - - - -/* Vertex array rendering via. the SetupDma function - no clipping required. - */ -#define RENDER_POINTS( start, count ) \ -do { \ - FatalError("Dead code in mgarender.c\n"); \ -} while (0) - -#define RENDER_LINE( i1, i ) \ -do { \ - FatalError("Dead code in mgarender.c\n"); \ -} while (0) - - -#define RENDER_TRI( i2, i1, i, pv, parity) \ -do { \ - GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - if (/*parity*/0) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \ - TRI(e2, e1, e); \ -} while (0) - -#define RENDER_QUAD( i3, i2, i1, i, pv) \ -do { \ - GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - TRI(e3, e2, e); \ - TRI(e2, e1, e); \ -} while (0) - -#define LOCAL_VARS \ - mgaVertexBufferPtr mgaVB = MGA_DRIVER_DATA(VB); \ - mgaUI32 phys = mgaVB->vert_phys_start; \ - const GLuint *elt = VB->EltPtr->data; \ - (void) phys; (void) elt; - -#define PRESERVE_VB_DEFS -#undef TRI -#define VERT_ADDR_10( phys, elt ) ( phys + elt * 48 ) -#define TRI( ee0, ee1, ee2 ) \ -{ \ - mgaVB->elt_buf[0] = VERT_ADDR_10(phys, ee0); \ - mgaVB->elt_buf[1] = VERT_ADDR_10(phys, ee1); \ - mgaVB->elt_buf[2] = VERT_ADDR_10(phys, ee2); \ - mgaVB->elt_buf += 3; \ -} -#define TAG(x) x##_mga_elt_10 -#include "render_tmp.h" - - -#define TAG(x) x##_mga_elt_8 -#undef TRI -#define VERT_ADDR_8( phys, elt ) ( phys + elt * 32 ) -#define TRI( ee0, ee1, ee2 ) \ -{ \ - mgaVB->elt_buf[0] = VERT_ADDR_8(phys, ee0); \ - mgaVB->elt_buf[1] = VERT_ADDR_8(phys, ee1); \ - mgaVB->elt_buf[2] = VERT_ADDR_8(phys, ee2); \ - mgaVB->elt_buf += 3; \ -} -#include "render_tmp.h" - - - - -/* Currently only used on the fast path - need a set of render funcs - * for clipped primitives. - */ -void mgaDDRenderElementsDirect( struct vertex_buffer *VB ) -{ - mgaVertexBufferPtr mgaVB = MGA_DRIVER_DATA(VB); - GLcontext *ctx = VB->ctx; - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLenum prim = ctx->CVA.elt_mode; - GLuint nr = VB->EltPtr->count; - render_func func = render_tab_mga_smooth_indirect[prim]; - GLuint p = 0; - mgaUI32 *start = mgaVB->elt_buf; - - struct vertex_buffer *saved_vb = ctx->VB; - - if (mmesa->new_state) - mgaDDUpdateHwState( ctx ); - - /* Are we using Setup DMA? - */ - if (start) { - switch (MGA_CONTEXT(ctx)->vertsize) { - case 10: - func = render_tab_mga_elt_10[prim]; - break; - case 8: - func = render_tab_mga_elt_8[prim]; - break; - default: - } - } - - ctx->VB = VB; - - do { - func( VB, 0, nr, 0 ); - } while (ctx->Driver.MultipassFunc && - ctx->Driver.MultipassFunc( VB, ++p )); - - ctx->VB = saved_vb; - - - if (start && nr) { - if (0) - fprintf(stderr, "%d/%d elts\n", nr, mgaVB->elt_buf-start); - mgaSetupDma( start, mgaVB->elt_buf - start ); - mgaVB->elt_buf = mgaVB->vert_buf = 0; - } -} - - -void mgaDDRenderElementsImmediate( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLuint nr = VB->EltPtr->count; - render_func *tab = render_tab_mga_smooth_indirect; - GLuint parity = VB->Parity; - GLuint p = 0; - GLuint i, next; - - if (mmesa->new_state) - mgaDDUpdateHwState( ctx ); - - do { - for ( i= VB->CopyStart ; i < nr ; parity = 0, i = next ) - { - GLenum prim = VB->Primitive[i]; - next = VB->NextPrimitive[i]; - tab[prim]( VB, i, next, parity ); - } - } while (ctx->Driver.MultipassFunc && - ctx->Driver.MultipassFunc( VB, ++p )); -} - - -void mgaDDRenderDirect( struct vertex_buffer *VB ) -{ - GLcontext *ctx = VB->ctx; - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLuint nr = VB->Count; - render_func *tab = render_tab_mga_smooth_direct; - GLuint parity = VB->Parity; - GLuint p = 0; - GLuint i, next; - - if (mmesa->new_state) - mgaDDUpdateHwState( ctx ); - - do { - for ( i= VB->CopyStart ; i < nr ; parity = 0, i = next ) - { - GLenum prim = VB->Primitive[i]; - next = VB->NextPrimitive[i]; - tab[prim]( VB, i, next, parity ); - } - } while (ctx->Driver.MultipassFunc && - ctx->Driver.MultipassFunc( VB, ++p )); -} - - -static void optimized_render_vb_triangle_mga_smooth_indirect(struct vertex_buffer *VB, - GLuint start, - GLuint count, - GLuint parity) -{ - mgaVertexPtr gWin = MGA_DRIVER_DATA(VB)->verts; - const GLuint *elt = VB->EltPtr->data; - GLcontext *ctx = VB->ctx; - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - - mgaUI32 vertsize = mmesa->vertsize; - - /* We know how many dwords we need so we can allocate all of it - * in one call */ - mgaUI32 *wv = mgaAllocSecondaryBuffer( count * vertsize ); - - int vertex; - - (void)ctx; (void) gWin; (void) parity; - - - for(vertex=start+2;vertex<count;vertex+=3){ - GLuint e2=elt[vertex-2],e1=elt[vertex-1],e=elt[vertex]; - mgaUI32 *src; - - int j; - - if(parity){ - GLuint tmp=e2; - e2=e1; - e1=tmp; - } - - src=&gWin[e2].ui[0]; - - for(j=vertsize;j;j--){ - *wv++=*src++; - } - - src=&gWin[e1].ui[0]; - for(j=vertsize;j;j--){ - *wv++=*src++; - } - - src=&gWin[e].ui[0]; - for(j=vertsize;j;j--){ - *wv++=*src++; - } - } - -} - - -void mgaDDRenderInit() -{ - - render_init_mga_smooth_indirect(); - render_init_mga_smooth_direct(); - render_init_mga_elt_10(); - render_init_mga_elt_8(); - - render_tab_mga_smooth_indirect[GL_TRIANGLES] = - optimized_render_vb_triangle_mga_smooth_indirect; -} - - diff --git a/xc/lib/GL/mesa/src/drv/mga/mgarender.h b/xc/lib/GL/mesa/src/drv/mga/mgarender.h deleted file mode 100644 index c772ac459..000000000 --- a/xc/lib/GL/mesa/src/drv/mga/mgarender.h +++ /dev/null @@ -1,10 +0,0 @@ - -#ifndef _MGA_RENDER_H -#define _MGA_RENDER_H - -extern void mgaDDRenderElementsDirect( struct vertex_buffer *VB ); -extern void mgaDDRenderElementsImmediate( struct vertex_buffer *VB ); -extern void mgaDDRenderDirect( struct vertex_buffer *VB ); -extern void mgaDDRenderInit(); - -#endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c index ff9063e0b..7a3b82930 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,83 @@ 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. + */ +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 +531,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 +549,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 +558,34 @@ 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) | + MGA_ALPHA_BIT | MGA_SPEC_BIT | MGA_FOG_BIT); + + mmesa->sarea->dirty |= mmesa->dirty; - mmesa->dirty = 0; + +#if 0 + mgaPrintSetupFlags("warp pipe", mmesa->sarea->WarpPipe); + fprintf(stderr, "in mgaEmitHwStateLocked: dirty now %x\n", + mmesa->sarea->dirty); +#endif + + mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE); } @@ -533,29 +595,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 +664,7 @@ static void mgaWarpUpdateState( GLcontext *ctx ) { mmesa->warp_pipe = index; mmesa->new_state |= MGA_NEW_WARP; + mmesa->dirty |= MGA_UPLOAD_PIPE; } } @@ -611,21 +695,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 +719,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 +730,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 +762,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 +780,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 +855,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/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c index be7ad6018..eafccbaa2 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) { @@ -797,6 +997,8 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) { if ( !tObj || tObj != ctx->Texture.Unit[source].CurrentD[2] ) return; + +/* fprintf(stderr, "unit %d: %d\n", unit, tObj->Name); */ /* if the texture object doesn't exist at all (never used or swapped out), create it now, uploading all texture images */ @@ -804,7 +1006,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 +1016,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 +1025,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 +1053,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 +1093,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 +1163,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 +1193,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 +1214,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 +1233,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/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c index bd8ef083f..387a79f3e 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,61 @@ void mgaDDChooseRenderState( GLcontext *ctx ) mgaContextPtr mmesa = MGA_CONTEXT( ctx ); GLuint flags = ctx->TriangleCaps; - ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + if (mmesa->Fallback) + return; + + mmesa->IndirectTriangles = 0; 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 0 if (flags & DD_POINT_SMOOTH) ind |= MGA_ANTIALIAS_BIT; - if (flags & DD_POINT_ATTEN) ind |= fallback; +#else + if (flags & DD_POINT_SMOOTH) ind |= MGA_FALLBACK_BIT; +#endif 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 0 if (flags & DD_LINE_SMOOTH) ind |= MGA_ANTIALIAS_BIT; - if (flags & DD_LINE_STIPPLE) ind |= fallback; +#else + if (flags & DD_LINE_SMOOTH) ind |= MGA_FALLBACK_BIT; +#endif + 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/mgatritmp.h b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h index ac5a545d2..2a9d16b86 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h @@ -98,19 +98,31 @@ 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 ); mgaVertexPtr mgaVB = MGA_DRIVER_DATA(ctx->VB)->verts; float width = ctx->Line.Width; - if (IND & MGA_FLAT_BIT) { + if (IND & (MGA_TWOSIDE_BIT|MGA_FLAT_BIT)) { mgaVertex tmp0 = mgaVB[v0]; mgaVertex tmp1 = mgaVB[v1]; - *(int *)&tmp0.warp1.color = *(int *)&mgaVB[pv].warp1.color; - *(int *)&tmp1.warp1.color = *(int *)&mgaVB[pv].warp1.color; + + if (IND & MGA_TWOSIDE_BIT) { + GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + + if (IND & MGA_FLAT_BIT) { + MGA_COLOR((char *)&tmp0.warp1.color,vbcolor[pv]); + *(int *)&tmp1.warp1.color = *(int *)&tmp0.warp1.color; + } else { + MGA_COLOR((char *)&tmp0.warp1.color,vbcolor[v0]); + MGA_COLOR((char *)&tmp1.warp1.color,vbcolor[v1]); + } + + } else { + *(int *)&tmp0.warp1.color = *(int *)&mgaVB[pv].warp1.color; + *(int *)&tmp1.warp1.color = *(int *)&mgaVB[pv].warp1.color; + } mga_draw_line( mmesa, &tmp0, &tmp1, width ); } else @@ -125,13 +137,20 @@ static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) mgaVertexPtr mgaVB = MGA_DRIVER_DATA(VB)->verts; GLfloat sz = ctx->Point.Size * .5; int i; - + for(i=first;i<=last;i++) - if(VB->ClipMask[i]==0) - mga_draw_point( mmesa, &mgaVB[i], sz ); + if(VB->ClipMask[i]==0) { + if (IND & MGA_TWOSIDE_BIT) { + GLubyte (*vbcolor)[4] = VB->ColorPtr->data; + mgaVertex tmp0 = mgaVB[i]; + MGA_COLOR((char *)&tmp0.warp1.color, vbcolor[i]); + mga_draw_point( mmesa, &tmp0, sz ); + } else + mga_draw_point( mmesa, &mgaVB[i], sz ); + } } -#endif + static void TAG(init)( void ) @@ -139,10 +158,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..2d61f301d 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c @@ -104,7 +104,7 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ GLfloat yoffset = mmesa->driDrawable->h - 0.5 + mmesa->drawY; \ int i; \ (void) xoffset; (void) yoffset; \ - \ + if (0) fprintf(stderr, "V"); \ gl_import_client_data( VB, VB->ctx->RenderFlags, \ (VB->ClipOrMask \ ? VEC_WRITABLE|VEC_GOOD_STRIDE \ @@ -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/r128/Imakefile b/xc/lib/GL/mesa/src/drv/r128/Imakefile new file mode 100644 index 000000000..4cd07b8ff --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/Imakefile @@ -0,0 +1,325 @@ +XCOMM $XFree86$ + +#include <Threads.tmpl> + +#define DoNormalLib NormalLibGlx +#define DoSharedLib SharedLibGlx +#define DoExtraLib SharedLibGlx +#define DoDebugLib DebugLibGlx +#define DoProfileLib ProfileLibGlx + +#if Malloc0ReturnsNull +ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL +#endif + +#if BuildXF86DRI + DRI_DEFINES = GlxDefines -DDRIVERTS + DRI_INCLUDES = -I../../../../dri \ + -I../../../../glx \ + -I../../../dri \ + -I$(TOP)/include \ + -I$(TOP)/include/GL \ + -I$(XF86OSSRC) \ + -I$(XF86COMSRC) \ + -I$(SERVERSRC)/GL/dri \ + -I$(XF86DRIVERSRC)/r128 \ + -I../../../include \ + -I../.. \ + -I../../X \ + -I../common +#endif + +LinkSourceFile(mm.c, ../common) +LinkSourceFile(mm.h, ../common) +LinkSourceFile(hwlog.c, ../common) +LinkSourceFile(hwlog.h, ../common) + +MESA_INCLUDES = -I. -I.. -I../../include + + DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) + INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) + + R128SRCS = r128_cce.c \ + r128_clear.c \ + r128_context.c \ + r128_dd.c \ + r128_fastpath.c \ + r128_pipeline.c \ + r128_screen.c \ + r128_span.c \ + r128_state.c \ + r128_swap.c \ + r128_tex.c \ + r128_tris.c \ + r128_vb.c \ + r128_xmesa.c + + R128OBJS = r128_cce.o \ + r128_clear.o \ + r128_context.o \ + r128_dd.o \ + r128_fastpath.o \ + r128_pipeline.o \ + r128_screen.o \ + r128_span.o \ + r128_state.o \ + r128_swap.o \ + r128_tex.o \ + r128_tris.o \ + r128_vb.o \ + r128_xmesa.o + +#if !GlxUseBuiltInDRIDriver + 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 \ + ../../../../dri/drm/xf86drmR128.c + + DRMOBJS = ../../../../dri/drm/xf86drm.o \ + ../../../../dri/drm/xf86drmHash.o \ + ../../../../dri/drm/xf86drmRandom.o \ + ../../../../dri/drm/xf86drmSL.o \ + ../../../../dri/drm/xf86drmR128.o + + MESASRCS = ../../aatriangle.c \ + ../../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.c \ + ../../light.c \ + ../../lines.c \ + ../../logic.c \ + ../../masking.c \ + ../../matrix.c \ + ../../mem.c \ + ../../mmath.c \ + ../../pb.c \ + ../../pipeline.c \ + ../../pixel.c \ + ../../pixeltex.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 \ + ../../texutil.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 = ../../aatriangle.o \ + ../../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 \ + ../../pixeltex.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 \ + ../../texutil.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 +#endif + + ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) + ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) + + COMMONSRCS = mm.c hwlog.c + COMMONOBJS = mm.o hwlog.o + + SRCS = $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) \ + $(COMMONSRCS) $(R128SRCS) + OBJS = $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) \ + $(COMMONOBJS) $(R128OBJS) + +REQUIREDLIBS += -lm +#if !GlxBuiltInMga +REQUIREDLIBS += -L../../../.. -lGL +#endif + +#if !GlxUseBuiltInDRIDriver +#undef DoNormalLib NormalLibGlx +#undef DoExtraLib SharedLibGlx +#undef DoDebugLib DebugLibGlx +#undef DoProfileLib ProfileLibGlx +#endif + +#include <Library.tmpl> + +LibraryObjectRule() + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) + +#if !GlxUseBuiltInDRIDriver +LIBNAME = r128_dri.so +ALL_OBJS = $(OBJS) +ALL_DEPS = DONE +SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.) +#endif + +DependTarget() diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.c b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c new file mode 100644 index 000000000..e949dd37c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c @@ -0,0 +1,389 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_reg.h" +#include "r128_cce.h" + +#if USE_USER_SPACE_RING + +#define USE_IOCTLS 0 +#define DO_SECURITY_CHECK 1 +#define R128_TIMEOUT 2000000 + +#if DEBUG +static void r128RingStatus(r128ScreenPtr pScrn) +{ + unsigned char *R128MMIO = pScrn->mmio; + + R128_DEBUG(("GUI_STAT = 0x%08x\n", + (unsigned int)INREG(R128_GUI_STAT))); + R128_DEBUG(("PM4_STAT = 0x%08x\n", + (unsigned int)INREG(R128_PM4_STAT))); + R128_DEBUG(("PM4_BUFFER_DL_WPTR = 0x%08x\n", + (unsigned int)INREG(R128_PM4_BUFFER_DL_WPTR))); + R128_DEBUG(("PM4_BUFFER_DL_RPTR = 0x%08x\n", + (unsigned int)INREG(R128_PM4_BUFFER_DL_RPTR))); + R128_DEBUG(("ringWrite = 0x%08x\n", pScrn->SAREA->ringWrite)); + R128_DEBUG(("*ringReadPtr = 0x%08x\n", *pScrn->ringReadPtr)); +} +#endif + +/* FIXME: Requires access to secure registers */ +static int INPLL(r128ScreenPtr pScrn, int addr) +{ + unsigned char *R128MMIO = pScrn->mmio; + + OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); + return INREG(R128_CLOCK_CNTL_DATA); +} + +/* FIXME: Requires access to secure registers */ +static void r128EngineFlush(r128ScreenPtr pScrn) +{ + unsigned char *R128MMIO = pScrn->mmio; + int i; + + OUTREGP(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, ~R128_PC_FLUSH_ALL); + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) break; + } +} + +/* FIXME: Requires access to secure registers */ +static void r128EngineReset(r128ScreenPtr pScrn) +{ +#if USE_IOCTLS +#if DEBUG + r128RingStatus(pScrn); +#endif + + (void)drmR128EngineReset(pScrn->driScreen->fd); +#else + unsigned char *R128MMIO = pScrn->mmio; + CARD32 clock_cntl_index; + CARD32 mclk_cntl; + CARD32 gen_reset_cntl; + +#if DEBUG + r128RingStatus(pScrn); +#endif + + r128EngineFlush(pScrn); + + clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); + mclk_cntl = INPLL(pScrn, R128_MCLK_CNTL); + + OUTPLL(R128_MCLK_CNTL, mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CPP); + + gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); + + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + + OUTPLL(R128_MCLK_CNTL, mclk_cntl); + OUTREG(R128_CLOCK_CNTL_INDEX, clock_cntl_index); + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl); + + /* Reset the ring buffer status */ + if (R128CCE_USE_RING_BUFFER(pScrn->CCEMode)) { + OUTREG(R128_PM4_BUFFER_DL_WPTR, 0); + OUTREG(R128_PM4_BUFFER_DL_RPTR, 0); + pScrn->SAREA->ringWrite = 0; + *pScrn->ringReadPtr = 0; + } +#endif + fprintf(stderr, "Error: Rage 128 timed out... exiting\n"); + exit(-1); +} + +#define r128CCEWaitForFifo(pScrn, entries) \ +do { \ + if (pScrn->CCEFifoSlots < entries) \ + r128CCEWaitForFifoFunction(pScrn, entries); \ + pScrn->CCEFifoSlots -= entries; \ +} while (0) + +/* Wait for at least `entries' slots are free. The actual number of + slots available is stored in info->CCEFifoSize. */ +static void r128CCEWaitForFifoFunction(r128ScreenPtr pScrn, int entries) +{ + unsigned char *R128MMIO = pScrn->mmio; + int i; + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + pScrn->CCEFifoSlots = INREG(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK; + if (pScrn->CCEFifoSlots >= entries) return; + } + R128_DEBUG(("Reseting Engine: PM4_STAT = 0x%08x\n", + (unsigned int)INREG(R128_PM4_STAT))); + r128EngineReset(pScrn); + } +} + +/* Wait until the CCE is completely idle: the FIFO has drained and the + CCE is idle. */ +void r128CCEWaitForIdle(r128ScreenPtr pScrn) +{ +#if USE_IOCTLS + if (drmR128WaitForIdle(pScrn->driScreen->fd) < 0) { + fprintf(stderr, "Error: Rage 128 timed out... exiting\n"); + exit(-1); + } +#else + unsigned char *R128MMIO = pScrn->mmio; + int i; + + if (R128CCE_USE_RING_BUFFER(pScrn->CCEMode)) { + OUTREGP(R128_PM4_BUFFER_DL_WPTR, + R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (*pScrn->ringReadPtr == pScrn->SAREA->ringWrite) { + int pm4stat = INREG(R128_PM4_STAT); + if ((pm4stat & R128_PM4_FIFOCNT_MASK) == pScrn->CCEFifoSize + && !(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) + return; + } + } + R128_DEBUG(("Reseting Engine: PM4_STAT = 0x%08x\n", + (unsigned int)INREG(R128_PM4_STAT))); + r128EngineReset(pScrn); + } + } else { + r128CCEWaitForFifoFunction(pScrn, pScrn->CCEFifoSize); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_PM4_STAT) + & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) { + r128EngineFlush(pScrn); + return; + } + } + R128_DEBUG(("Reseting Engine: PM4_STAT = 0x%08x\n", + (unsigned int)INREG(R128_PM4_STAT))); + r128EngineReset(pScrn); + } + } +#endif +} + +/* Send a packet to the CCE via the PIO registers */ +static void r128CCESubmitPacketPIO(r128ContextPtr r128ctx, + CARD32 *buf, int count) +{ + unsigned char *R128MMIO = r128ctx->r128Screen->mmio; +#if DO_SECURITY_CHECK + CARD32 tmp = 0; + int psize = 0; + int writing = 1; + int addr = R128_PM4_FIFO_DATA_EVEN; +#endif + +#if DO_SECURITY_CHECK + while (count > 0) { + tmp = *buf++; + if (!psize) { + writing = 1; + + if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) { + if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) { + if ((tmp & R128_CCE_PACKET0_REG_MASK) != + (R128_PM4_VC_FPU_SETUP >> 2)) { + writing = 0; + } + } + psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; + } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) { + if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) { + if ((tmp & R128_CCE_PACKET1_REG0_MASK) != + (R128_PM4_VC_FPU_SETUP >> 2)) { + writing = 0; + } + } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <= + (0x1004 << 9)) { + if ((tmp & R128_CCE_PACKET1_REG1_MASK) != + (R128_PM4_VC_FPU_SETUP << 9)) { + writing = 0; + } + } + psize = 3; + } else { + psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; + } + } + psize--; + + if (writing) { + r128CCEWaitForFifo(r128ctx->r128Screen, 1); + OUTREG(addr, tmp); + addr ^= 0x0004; + } + + count--; + } + + if (addr == R128_PM4_FIFO_DATA_ODD) { + r128CCEWaitForFifo(r128ctx->r128Screen, 1); + OUTREG(addr, R128_CCE_PACKET2); + } +#else + while (count > 1) { + r128CCEWaitForFifo(r128ctx->r128Screen, 2); + OUTREG(R128_PM4_FIFO_DATA_EVEN, *buf++); + OUTREG(R128_PM4_FIFO_DATA_ODD, *buf++); + count -= 2; + } + + if (count) { + r128CCEWaitForFifo(r128ctx->r128Screen, 2); + OUTREG(R128_PM4_FIFO_DATA_EVEN, *buf); + OUTREG(R128_PM4_FIFO_DATA_ODD, R128_CCE_PACKET2); + } +#endif +} + +/* Send a packet to the CCE via the ring */ +static void r128CCESubmitPacketRing(r128ContextPtr r128ctx, + CARD32 *buf, int count) +{ + r128ScreenPtr r128scrn = r128ctx->r128Screen; + unsigned char *R128MMIO = r128ctx->r128Screen->mmio; + int ringWrite = r128scrn->SAREA->ringWrite; + int *ringWritePtr = r128scrn->ringStartPtr + ringWrite; + int timeout; +#if DO_SECURITY_CHECK + CARD32 tmp = 0; + int psize = 0; + int writing = 1; +#endif + + if (count > r128scrn->ringEntries) { + /* FIXME */ + return; + } + + while (count > 0) { +#if DO_SECURITY_CHECK + tmp = *buf++; + if (!psize) { + writing = 1; + + if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) { + if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) { + if ((tmp & R128_CCE_PACKET0_REG_MASK) != + (R128_PM4_VC_FPU_SETUP >> 2)) { + writing = 0; + } + } + psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; + } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) { + if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) { + if ((tmp & R128_CCE_PACKET1_REG0_MASK) != + (R128_PM4_VC_FPU_SETUP >> 2)) { + writing = 0; + } + } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <= + (0x1004 << 9)) { + if ((tmp & R128_CCE_PACKET1_REG1_MASK) != + (R128_PM4_VC_FPU_SETUP << 9)) { + writing = 0; + } + } + psize = 3; + } else { + psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; + } + } + psize--; + + if (writing) { + ringWrite++; + *ringWritePtr++ = tmp; + } +#else + ringWrite++; + *ringWritePtr++ = *buf++; +#endif + if (ringWrite >= r128scrn->ringEntries) { + ringWrite = 0; + ringWritePtr = r128scrn->ringStartPtr; + } + timeout = 0; + while (ringWrite == *r128scrn->ringReadPtr) { + (void)INREG(R128_PM4_BUFFER_DL_RPTR); + if (timeout++ >= R128_TIMEOUT) r128EngineReset(r128scrn); + } + + count--; + } + + if (ringWrite < 32) { + memcpy(r128scrn->ringEndPtr, + r128scrn->ringStartPtr, + ringWrite * sizeof(int)); + } + + r128scrn->SAREA->ringWrite = ringWrite; + OUTREG(R128_PM4_BUFFER_DL_WPTR, ringWrite); +} + +void r128CCESubmitPackets(r128ContextPtr r128ctx, CARD32 *buf, int count) +{ +#if USE_IOCTLS + if (drmR128SubmitPackets(r128ctx->r128Screen->driScreen->fd, + r128ctx->CCEbuf, r128ctx->CCEcount, + 0) < 0) { + r128EngineReset(r128ctx->r128Screen); + fprintf(stderr, "Error: Illegal CCE packet... exiting\n"); + exit(-1); + } +#else + if (R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode)) + r128CCESubmitPacketRing(r128ctx, buf, count); + else + r128CCESubmitPacketPIO(r128ctx, buf, count); +#endif +} + +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.h b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h new file mode 100644 index 000000000..162686cb7 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h @@ -0,0 +1,142 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_CCE_H_ +#define _R128_CCE_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include "r128_dri.h" +#include "r128_reg.h" + +#include "xf86drmR128.h" + +typedef union { + float f; + int i; +} floatTOint; + +#define R128_DEFAULT_TOTAL_CCE_TIMEOUT 1000000 /* usecs */ + +/* Insert an integer value into the CCE ring buffer. */ +#define R128CCE(v) \ + do { \ + r128ctx->CCEbuf[r128ctx->CCEcount] = (v); \ + r128ctx->CCEcount++; \ + } while (0) + +/* Insert an floating point value into the CCE ring buffer. */ +#define R128CCEF(v) \ + do { \ + floatTOint fTi; \ + fTi.f = (v); \ + r128ctx->CCEbuf[r128ctx->CCEcount] = fTi.i; \ + r128ctx->CCEcount++; \ + } while (0) + +#if USE_USER_SPACE_RING + +#define R128CCE_SUBMIT_PACKETS() \ + do { \ + r128CCESubmitPackets(r128ctx, r128ctx->CCEbuf, r128ctx->CCEcount); \ + r128ctx->CCEcount = 0; \ + } while (0) + +#define R128CCE_WAIT_FOR_IDLE(r128ctx) \ + r128CCEWaitForIdle(r128ctx->r128Screen) + +#else /* if !USE_USER_SPACE_RING */ + +#define R128CCE_SUBMIT_PACKETS() \ + do { \ + CARD32 *_buf; \ + int _c = r128ctx->CCEcount; \ + int _fd = r128ctx->r128Screen->driScreen->fd; \ + int _to = 0; \ + int _ret; \ + \ + do { \ + _buf = r128ctx->CCEbuf + (r128ctx->CCEcount - _c); \ + _ret = drmR128SubmitPackets(_fd, _buf, &_c, 0); \ + } while (_ret < 0 && _ret == -EBUSY && _to++ < r128ctx->CCEtimeout); \ + if (_ret < 0) { \ + (void)drmR128EngineReset(_fd); \ + fprintf(stderr, "Error: Could not submit packet... exiting\n"); \ + exit(-1); \ + } \ + r128ctx->CCEcount = 0; \ + } while (0) + +#define R128CCE_WAIT_FOR_IDLE(r128ctx) \ + do { \ + int _fd = r128ctx->r128Screen->driScreen->fd; \ + int _to = 0; \ + int _ret; \ + \ + (void)drmR128EngineFlush(_fd); \ + do { \ + _ret = drmR128CCEWaitForIdle(_fd); \ + } while (_ret < 0 && _ret == -EBUSY && _to++ < r128ctx->CCEtimeout); \ + if (_ret < 0) { \ + (void)drmR128EngineReset(_fd); \ + fprintf(stderr, "Error: Rage 128 timed out... exiting\n"); \ + exit(-1); \ + } \ + } while (0) + +#endif + +#define R128CCE_WAIT_FOR_IDLE_LOCK(r128ctx) \ + do { \ + LOCK_HARDWARE(r128ctx); \ + R128CCE_WAIT_FOR_IDLE(r128ctx); \ + UNLOCK_HARDWARE(r128ctx); \ + } while (0) + + +/* Insert a type-[0123] packet header into the ring buffer */ +#define R128CCE0(p,r,n) R128CCE((p) | ((n) << 16) | ((r) >> 2)) +#define R128CCE1(p,r1,r2) R128CCE((p) | (((r2) >> 2) << 11) | ((r1) >> 2)) +#define R128CCE2(p) R128CCE((p)) +#define R128CCE3(p,n) R128CCE((p) | ((n) << 16)) + + +#if USE_USER_SPACE_RING +extern void r128CCEWaitForIdle(r128ScreenPtr pScrn); +extern void r128CCESubmitPackets(r128ContextPtr r128ctx, + CARD32 *buf, int count); +#endif + +#endif +#endif /* _R128_CCE_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h b/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h new file mode 100644 index 000000000..2084b8672 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h @@ -0,0 +1,224 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_CCEVB_H_ +#define _R128_CCEVB_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include "xf86drmR128.h" + +typedef struct { + CARD32 *buf; /* Pointer to current VB */ + int index; /* Index of current VB */ + int start; /* in bytes from the beginning of the VB map */ + int size; /* in vertices */ + int count; /* in vertices */ + drmR128PrimType prim; /* Primitive type for vertices in VB */ + int done; /* VB has been sent to ring */ +} r128CCEVertBuf, *r128CCEVertBufPtr; + + + +/* Flush the CPU's write-combining cache */ +/* FIXME: This code is both processor and compiler specific */ +#define R128_FLUSH_WC_MEMORY() \ + do { \ + 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 */); \ + } while (0) + + +/* Get a new VB from the pool of vertex buffers in AGP space */ +/* NOTE: By default the primitive type for a VB is set to individual tris */ +#define R128CCE_GET_NEW_VB(r128ctx) \ + do { \ + r128CCEVertBufPtr vb = &r128ctx->vb; \ + int to = 0; \ + int fd = r128ctx->r128Screen->driScreen->fd; \ + int num; \ + int index; \ + int size; \ + \ + vb->buf = NULL; \ + \ + LOCK_HARDWARE(r128ctx); \ + while (!vb->buf && to++ < r128ctx->CCEtimeout) { \ + /* Ask the kernel a new vertex buffer */ \ + num = drmR128GetVertexBuffers(fd, 1, &index, &size); \ + \ + if (num > 0) { \ + vb->buf = (CARD32 *)(r128ctx->r128Screen-> \ + vbBufs->list[index].address); \ + vb->index = index; \ + vb->start = index*r128ctx->r128Screen->vbBufSize; \ + vb->size = size/sizeof(r128_vertex); \ + vb->count = 0; \ + vb->prim = DRM_R128_PRIM_TRI_LIST; \ + vb->done = GL_FALSE; \ + } \ + } \ + UNLOCK_HARDWARE(r128ctx); \ + \ + if (!vb->buf) { \ + (void)drmR128EngineReset(fd); \ + fprintf(stderr, "Error: Could not get new VB... exiting\n"); \ + exit(-1); \ + } \ + } while (0) + +/* Submit a VB to the hardware for processing */ +/* NOTE: This macro is only called while holding the hardware lock */ +#define R128CCE_SUBMIT_VB(r128ctx) \ + do { \ + int index = r128ctx->vb.index; \ + int size = r128ctx->vb.count; \ + int fd = r128ctx->r128Screen->driScreen->fd; \ + int to = 0; \ + int ret; \ + CARD32 prim; \ + \ + switch (r128ctx->vb.prim) { \ + case DRM_R128_PRIM_NONE: \ + prim = R128_CCE_VC_CNTL_PRIM_TYPE_NONE; \ + break; \ + case DRM_R128_PRIM_POINT: \ + prim = R128_CCE_VC_CNTL_PRIM_TYPE_POINT; \ + break; \ + case DRM_R128_PRIM_LINE: \ + prim = R128_CCE_VC_CNTL_PRIM_TYPE_LINE; \ + break; \ + case DRM_R128_PRIM_POLY_LINE: \ + prim = R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE; \ + break; \ + case DRM_R128_PRIM_TRI_LIST: \ + prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST; \ + break; \ + case DRM_R128_PRIM_TRI_FAN: \ + prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN; \ + break; \ + case DRM_R128_PRIM_TRI_STRIP: \ + prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP; \ + break; \ + case DRM_R128_PRIM_TRI_TYPE2: \ + prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2; \ + break; \ + default: \ + prim = R128_CCE_VC_CNTL_PRIM_TYPE_NONE; \ + break; \ + } \ + \ + /* Send the vertex buffer to the hardware */ \ + BEGIN_CLIP_LOOP(r128ctx); \ + \ + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3); \ + R128CCE(r128ctx->r128Screen->vbOffset + r128ctx->vb.start); \ + R128CCE(r128ctx->vb.count); \ + R128CCE(R128_FULL_VERTEX_FORMAT); \ + R128CCE(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | \ + (r128ctx->vb.count << R128_CCE_VC_CNTL_NUM_SHIFT)); \ + R128CCE_SUBMIT_PACKETS(); \ + \ + END_CLIP_LOOP(r128ctx); \ + \ + /* Tell the kernel to release the vertex buffer */ \ + do { \ + ret = drmR128FlushVertexBuffers(fd, 1, &index, &size, \ + r128ctx->vb.prim); \ + } while (ret < 0 && ret == -EBUSY && to++ < r128ctx->CCEtimeout); \ + if (ret < 0) { \ + (void)drmR128EngineReset(fd); \ + fprintf(stderr, "Error: Could not flush VB... exiting\n"); \ + exit(-1); \ + } \ + \ + r128ctx->vb.done = GL_TRUE; \ + } while (0) + +/* Flush the vertex buffer (assuming we already hold the lock) */ +#define R128CCE_FLUSH_VB(r128ctx) \ + do { \ + if (r128ctx->vb.count && !r128ctx->vb.done) { \ + /* FIXME: Is this _really_ needed? */ \ + if (!R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode)) \ + R128CCE_WAIT_FOR_IDLE(r128ctx); \ + \ + R128CCE_SUBMIT_VB(r128ctx); \ + } \ + } while (0) + +/* Flush the vertex buffer */ +#define R128CCE_FLUSH_VB_LOCK(r128ctx) \ + do { \ + LOCK_HARDWARE(r128ctx); \ + R128CCE_FLUSH_VB(r128ctx); \ + UNLOCK_HARDWARE(r128ctx); \ + } while (0) + +/* Reserve space in a VB to store `n' vertices, and set the pointer `p' + to point to the next vertex in the current VB. If adding these + vertices to the VB would exceed the size of the VB, then flush the + current VB, get a new one from the pool of VBs, reserve space in the + new VB for the `n' vertices, and set the pointer `p' to point to the + first vertex in the new VB. */ +#define R128CCE_ALLOC_VB_SPACE(r128ctx, p, n) \ + do { \ + r128CCEVertBufPtr vb = &r128ctx->vb; \ + \ + if (vb->done) R128CCE_GET_NEW_VB(r128ctx); \ + \ + if (vb->count + (n) > vb->size) { \ + R128CCE_FLUSH_VB_LOCK(r128ctx); \ + R128CCE_GET_NEW_VB(r128ctx); \ + } \ + \ + (p) = (r128_vertex *)vb->buf + vb->count; \ + vb->count += (n); \ + } while (0) + +#endif +#endif /* _R128_CCEVB_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_clear.c b/xc/lib/GL/mesa/src/drv/r128/r128_clear.c new file mode 100644 index 000000000..9ab0581b0 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_clear.c @@ -0,0 +1,248 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_reg.h" +#include "r128_cce.h" +#include "r128_state.h" +#include "r128_vb.h" +#include "r128_clear.h" + +/* Clear the depth buffer */ +void r128ClearDepthBuffer(r128ContextPtr r128ctx, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch) +{ + __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; + int nc; + XF86DRIClipRectPtr c; + int dst_bpp; + CARD32 write_mask; + + if (!(r128ctx->regs.tex_cntl_c & R128_Z_WRITE_ENABLE)) return; + + switch (r128ctx->regs.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK) { + case R128_Z_PIX_WIDTH_16: + write_mask = 0x0000ffff; + dst_bpp = R128_GMC_DST_16BPP; + break; + case R128_Z_PIX_WIDTH_24: + write_mask = 0x00ffffff; + dst_bpp = R128_GMC_DST_32BPP; + break; + case R128_Z_PIX_WIDTH_32: + write_mask = 0xffffffff; + dst_bpp = R128_GMC_DST_32BPP; + break; + default: return; + } + + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + + LOCK_HARDWARE(r128ctx); + + /* Flush any outstanding vertex buffers */ + R128CCE_FLUSH_VB(r128ctx); + + /* Init the clip rects here in case they changed during the + LOCK_HARDWARE macro */ + c = dPriv->pClipRects; + nc = dPriv->numClipRects; + + /* Set the write mask so that we _only_ clear the Z buffer */ + R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0); + R128CCE(write_mask); + + /* Temporarily disable Z and stencil buffer and texture mapping modes */ + R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0); + R128CCE(r128ctx->regs.tex_cntl_c & ~(R128_Z_ENABLE | + R128_STENCIL_ENABLE | + R128_TEXMAP_ENABLE)); + + /* Cycle through the clip rects */ + while (nc--) { + int x = c[nc].x1; + int y = c[nc].y1; + int w = c[nc].x2 - x; + int h = c[nc].y2 - y; + + if (!all) { + if (x < cx) w -= cx - x, x = cx; + if (y < cy) h -= cy - y, y = cy; + + if (x + w > cx + cw) w = cx + cw - x; + if (y + h > cy + ch) h = cy + ch - y; + + if (w <= 0 || h <= 0) continue; + } + + x += r128ctx->r128Screen->depthX; + y += r128ctx->r128Screen->depthY; + + R128CCE3(R128_CCE_PACKET3_CNTL_PAINT_MULTI, 3); + R128CCE(R128_GMC_BRUSH_SOLID_COLOR + | dst_bpp + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP3_P + | R128_GMC_3D_FCN_EN /* FIXME?? */ + | R128_GMC_CLR_CMP_CNTL_DIS /* FIXME?? */ + | R128_AUX_CLIP_DIS /* FIXME?? */ + | R128_GMC_WR_MSK_DIS); /* FIXME?? */ + R128CCE(r128ctx->ClearDepth); + R128CCE((x << 16) | y); + R128CCE((w << 16) | h); + } + +#if 0 + /* Set the write mask so that we _only_ clear the Z buffer */ + R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0); + R128CCE(0xffffffff); + + /* Restore Z and stencil buffer and texture mapping modes */ + R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0); + R128CCE(r128ctx->regs.tex_cntl_c); +#else + /* FIXME: We should be able to optimize this by restoring only the + registers that change (above) */ + /* NOTE: The restore of TEX_CNTL_C and R128_DP_WRITE_MASK is handled by + vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ALL_DIRTY; +#endif + + R128CCE_SUBMIT_PACKETS(); + + UNLOCK_HARDWARE(r128ctx); +} + +/* Clear a color buffer */ +void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch, + GLint drawX, GLint drawY) +{ + __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; + int nc; + XF86DRIClipRectPtr c; + int dst_bpp; + + switch (r128ctx->r128Screen->bpp) { + case 8: + dst_bpp = R128_GMC_DST_8BPP_CI; + break; + case 16: + if (r128ctx->r128Screen->depth == 15) dst_bpp = R128_GMC_DST_15BPP; + else dst_bpp = R128_GMC_DST_16BPP; + break; + case 24: + dst_bpp = R128_GMC_DST_24BPP; + break; + case 32: + default: + dst_bpp = R128_GMC_DST_32BPP; + break; + } + + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + + LOCK_HARDWARE(r128ctx); + + /* Flush any outstanding vertex buffers */ + R128CCE_FLUSH_VB(r128ctx); + + /* Init the clip rects here in case they changed during the + LOCK_HARDWARE macro */ + c = dPriv->pClipRects; + nc = dPriv->numClipRects; + + /* Temporarily disable Z and stencil buffer and texture mapping modes */ + R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0); + R128CCE(r128ctx->regs.tex_cntl_c & ~(R128_Z_ENABLE | + R128_STENCIL_ENABLE | + R128_TEXMAP_ENABLE)); + + /* Cycle through the clip rects */ + while (nc--) { + int x = c[nc].x1; + int y = c[nc].y1; + int w = c[nc].x2 - x; + int h = c[nc].y2 - y; + + if (!all) { + if (x < cx) w -= cx - x, x = cx; + if (y < cy) h -= cy - y, y = cy; + + if (x + w > cx + cw) w = cx + cw - x; + if (y + h > cy + ch) h = cy + ch - h; + + if (w <= 0 || h <= 0) continue; + } + + x += drawX; + y += drawY; + + R128CCE3(R128_CCE_PACKET3_CNTL_PAINT_MULTI, 3); + R128CCE(R128_GMC_BRUSH_SOLID_COLOR + | dst_bpp + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP3_P + | R128_GMC_3D_FCN_EN /* FIXME?? */ + | R128_GMC_CLR_CMP_CNTL_DIS /* FIXME?? */ + | R128_AUX_CLIP_DIS); /* FIXME?? */ + R128CCE(r128ctx->ClearColor); + R128CCE((x << 16) | y); + R128CCE((w << 16) | h); + } + +#if 0 + /* Restore Z and stencil buffer and texture mapping modes */ + R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0); + R128CCE(r128ctx->regs.tex_cntl_c); +#else + /* FIXME: We should be able to optimize this by restoring only the + registers that change (above) */ + /* NOTE: The restore of TEX_CNTL_C is handled by + vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ALL_DIRTY; +#endif + + R128CCE_SUBMIT_PACKETS(); + + UNLOCK_HARDWARE(r128ctx); +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_clear.h b/xc/lib/GL/mesa/src/drv/r128/r128_clear.h new file mode 100644 index 000000000..7018b05b4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_clear.h @@ -0,0 +1,47 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_CLEAR_H_ +#define _R128_CLEAR_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128ClearDepthBuffer(r128ContextPtr r128ctx, GLboolean all, + GLint x, GLint y, GLint width, GLint height); +extern void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all, + GLint x, GLint y, GLint width, GLint height, + GLint drawX, GLint drawY); + +#endif +#endif /* _R128_CLEAR_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c new file mode 100644 index 000000000..01573f559 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c @@ -0,0 +1,203 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include <stdlib.h> + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_cce.h" +#include "r128_dd.h" +#include "r128_state.h" +#include "r128_span.h" +#include "r128_tex.h" +#include "r128_vb.h" +#include "r128_pipeline.h" + +#include "context.h" +#include "simple_list.h" + +/* Create the device specific context */ +GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv) +{ + r128ContextPtr r128ctx; + r128ScreenPtr r128scrn; + GLcontext *glCtx = driContextPriv->mesaContext; + int i; + char *v; + + r128ctx = (r128ContextPtr)Xmalloc(sizeof(*r128ctx)); + if (!r128ctx) return GL_FALSE; + + /* Initialize r128Context */ + r128ctx->glCtx = glCtx; + r128ctx->display = dpy; + r128ctx->driContext = driContextPriv; + r128ctx->driDrawable = NULL; /* Set by XMesaMakeCurrent */ + + if (getenv("LIBGL_SOFTWARE_RENDERING")) + r128ctx->SWonly = GL_TRUE; + else + r128ctx->SWonly = GL_FALSE; + if (getenv("LIBGL_NO_SOFTWARE_FALLBACKS")) + r128ctx->SWfallbackDisable = GL_TRUE; + else + r128ctx->SWfallbackDisable = GL_FALSE; + r128scrn = r128ctx->r128Screen = + (r128ScreenPtr)(driContextPriv->driScreenPriv->private); + + r128ctx->CurrentTexObj[0] = NULL; + r128ctx->CurrentTexObj[1] = NULL; + make_empty_list(&r128ctx->SwappedOut); + for (i = 0; i < r128scrn->NRTexHeaps; i++) { + make_empty_list(&r128ctx->TexObjList[i]); + r128ctx->texHeap[i] = mmInit(0, r128scrn->texSize[i]); + r128ctx->lastTexAge[i] = -1; + } + + r128ctx->lastSwapAge = 0; + + r128ctx->useFastPath = GL_FALSE; + + r128ctx->vb.start = 0; + r128ctx->vb.count = 0; + r128ctx->vb.size = 0; + r128ctx->vb.index = 0; + r128ctx->vb.buf = NULL; + r128ctx->vb.done = GL_TRUE; + + if (r128scrn->IsPCI || getenv("LIBGL_DISABLE_VERTEX_BUFFERS")) + r128ctx->disableVB = GL_TRUE; + else + r128ctx->disableVB = GL_FALSE; + + r128ctx->CCEbuf = (CARD32 *)malloc(sizeof(*r128ctx->CCEbuf) * + r128scrn->ringEntries); + r128ctx->CCEcount = 0; + + if ((v = getenv("LIBGL_CCE_TIMEOUT"))) + r128ctx->CCEtimeout = strtoul(v, NULL, 10); + else + r128ctx->CCEtimeout = (R128_DEFAULT_TOTAL_CCE_TIMEOUT / + R128_DEFAULT_CCE_TIMEOUT); + if (r128ctx->CCEtimeout <= 0) r128ctx->CCEtimeout = 1; + + /* Initialize GLcontext */ + glCtx->DriverCtx = (void *)r128ctx; + + r128DDInitExtensions(glCtx); + + r128DDInitDriverFuncs(glCtx); + r128DDInitStateFuncs(glCtx); + r128DDInitSpanFuncs(glCtx); + r128DDInitTextureFuncs(glCtx); + + glCtx->Driver.TriangleCaps = (DD_TRI_CULL + | DD_TRI_LIGHT_TWOSIDE + | DD_TRI_OFFSET); +#if 0 + /* FIXME */ + glCtx->TriangleCaps |= DD_CLIP_FOG_COORD; +#endif + + /* Reset Mesa's current 2D texture pointers to the driver's textures */ + glCtx->Shared->DefaultD[2][0].DriverData = NULL; + glCtx->Shared->DefaultD[2][1].DriverData = NULL; + + /* If Mesa has current a vertex buffer, make sure the driver's VB + data is up to date */ + if (glCtx->VB) r128DDRegisterVB(glCtx->VB); + + /* Register the fast path */ + if (glCtx->NrPipelineStages) + glCtx->NrPipelineStages = + r128RegisterPipelineStages(glCtx->PipelineStage, + glCtx->PipelineStage, + glCtx->NrPipelineStages); + + r128DDInitState(r128ctx); + + driContextPriv->driverPrivate = (void *)r128ctx; + + return GL_TRUE; +} + +/* Destroy the device specific context */ +void r128DestroyContext(r128ContextPtr r128ctx) +{ + if (r128ctx) { + r128TexObjPtr t, next_t; + int i; + + free(r128ctx->CCEbuf); + + for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++) { + foreach_s (t, next_t, &r128ctx->TexObjList[i]) + r128DestroyTexObj(r128ctx, t); + } + + foreach_s (t, next_t, &r128ctx->SwappedOut) + r128DestroyTexObj(r128ctx, t); + + gl_destroy_context(r128ctx->glCtx); + Xfree(r128ctx); + } +} + +/* Load the device specific context into the hardware. The actual + setting of the hardware state is done in the r128UpdateHWState(). */ +r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx, + r128ContextPtr newCtx, + __DRIdrawablePrivate *dPriv) +{ + if (oldCtx) { + if (!R128CCE_USE_RING_BUFFER(newCtx->r128Screen->CCEMode)) + newCtx->dirty |= R128_REQUIRE_QUIESCENCE; + if (oldCtx != newCtx) { + newCtx->dirty |= R128_UPDATE_CONTEXT; + newCtx->dirty_context |= R128_CTX_ALL_DIRTY; + } + if (oldCtx->driDrawable != dPriv) + newCtx->dirty |= R128_UPDATE_WINPOS; + } else { + newCtx->dirty |= R128_UPDATE_CONTEXT; + newCtx->dirty_context |= R128_CTX_ALL_DIRTY; + } + + newCtx->driDrawable = dPriv; + + return newCtx; +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.h b/xc/lib/GL/mesa/src/drv/r128/r128_context.h new file mode 100644 index 000000000..189a22cbe --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h @@ -0,0 +1,219 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_CONTEXT_H_ +#define _R128_CONTEXT_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include "r128_texobj.h" +#include "r128_fastpath.h" +#include "r128_ccevb.h" + +/* Flags for what needs to be updated before a new primitive is rendered */ +#define R128_CLEAN 0x0000 +#define R128_REQUIRE_QUIESCENCE 0x0001 +#define R128_UPDATE_CONTEXT 0x0002 +#define R128_UPDATE_WINPOS 0x0004 +#define R128_UPDATE_TEX0IMAGES 0x0008 +#define R128_UPDATE_TEX1IMAGES 0x0010 +#define R128_UPDATE_TEXSTATE 0x0020 +#define R128_ALL_DIRTY 0xffff + +/* Flags for what context state needs to be updated */ +#define R128_CTX_CLEAN 0x0000 +#define R128_CTX_MISC 0x0001 +#define R128_CTX_ENGINESTATE 0x0002 +#define R128_CTX_TEX0STATE 0x0004 +#define R128_CTX_TEX1STATE 0x0008 +#define R128_CTX_TEXENVSTATE 0x0010 +#define R128_CTX_FOGSTATE 0x0020 +#define R128_CTX_FOGTABLE 0x0040 +#define R128_CTX_ZSTENSTATE 0x0080 +#define R128_CTX_SCISSORS 0x0100 +#define R128_CTX_ALPHASTATE 0x0200 +#define R128_CTX_SETUPSTATE 0x0400 +#define R128_CTX_WIN_Z_POS 0x0800 +#define R128_CTX_FLUSH_PIX_CACHE 0x1000 +#define R128_CTX_ALL_DIRTY 0xffff + +/* Flags for software fallback cases */ +#define R128_FALLBACK_TEXTURE 0x0001 +#define R128_FALLBACK_DRAW_BUFFER 0x0002 +#define R128_FALLBACK_READ_BUFFER 0x0004 +#define R128_FALLBACK_COLORMASK 0x0008 +#define R128_FALLBACK_STIPPLE 0x0010 + +/* NOTE: The groups below need to be kept together so that a single + memcpy can be used to transfer data to the ring buffer */ +typedef struct { + CARD32 scale_3d_cntl; /* 0x1a00 */ + + CARD32 aux_sc_cntl; /* 0x1660 */ + CARD32 aux1_sc_left; + CARD32 aux1_sc_right; + CARD32 aux1_sc_top; + CARD32 aux1_sc_bottom; + CARD32 aux2_sc_left; + CARD32 aux2_sc_right; + CARD32 aux2_sc_top; + CARD32 aux2_sc_bottom; + CARD32 aux3_sc_left; + CARD32 aux3_sc_right; + CARD32 aux3_sc_top; + CARD32 aux3_sc_bottom; /* 0x1690 */ + + CARD32 dst_pitch_offset_c; /* 0x1c80 */ + CARD32 dp_gui_master_cntl; + CARD32 sc_top_left_c; + CARD32 sc_bottom_right_c; + CARD32 z_offset_c; + CARD32 z_pitch_c; + CARD32 z_sten_cntl_c; + CARD32 tex_cntl_c; + CARD32 misc_3d_state_cntl_reg; + CARD32 texture_clr_cmp_clr_c; + CARD32 texture_clr_cmp_msk_c; + CARD32 fog_color_c; + CARD32 prim_tex_cntl_c; + CARD32 prim_texture_combine_cntl_c; + CARD32 tex_size_pitch_c; + CARD32 prim_tex_offset[R128_TEX_MAXLEVELS]; /* 0x1ce4 */ + + CARD32 sec_tex_cntl_c; /* 0x1d00 */ + CARD32 sec_tex_combine_cntl_c; + CARD32 sec_tex_offset[R128_TEX_MAXLEVELS]; + CARD32 constant_color_c; + CARD32 prim_texture_border_color_c; + CARD32 sec_texture_border_color_c; + CARD32 sten_ref_mask_c; + CARD32 plane_3d_mask_c; /* 0x1d44 */ + + CARD32 setup_cntl; /* 0x1bc4 */ + + CARD32 pm4_vc_fpu_setup; /* 0x071c */ + + CARD32 fog_3d_table_start; /* 0x1810 */ + CARD32 fog_3d_table_end; + CARD32 fog_3d_table_density; /* 0x181c */ + + CARD32 window_xy_offset; /* 0x1bcc */ + + CARD32 dp_write_mask; /* 0x16cc */ + + CARD32 pc_gui_ctlstat; /* 0x1748 */ +} r128ContextRegs; + +typedef struct { + GLcontext *glCtx; /* Mesa context */ + int dirty; /* Hardware state to be updated */ + int dirty_context; /* Context state to be updated */ + + int SWonly; /* Force software-only rendering */ + int SWfallbackDisable; /* Disable software fallbacks */ + + r128TexObjPtr CurrentTexObj[2]; /* Ptr to current texture + object associated with + each texture unit */ + /* List of tex swapped in per heap*/ + r128TexObj TexObjList[R128_NR_TEX_HEAPS]; + r128TexObj SwappedOut; /* List of textures swapped out */ + memHeap_t *texHeap[R128_NR_TEX_HEAPS]; /* Global tex heaps */ + /* Last known global tex heap ages */ + int lastTexAge[R128_NR_TEX_HEAPS]; + + CARD32 lastSwapAge; /* Last known swap age */ + + GLenum FogMode; /* Current fog equation */ + + int Scissor; + XF86DRIClipRectRec ScissorRect; /* Current software scissor */ + + int useFastPath; /* Currently using Fast Path code */ + int SetupIndex; /* Raster setup function index */ + int SetupDone; /* Partial raster setup done? */ + int RenderIndex; /* Render state function index */ + r128InterpFunc interp; /* Current vert interp function */ + + r128CCEVertBuf vb; /* VB currently being filled */ + int disableVB; /* Disable the use of vertex buffers */ + + points_func PointsFunc; /* Current Points, Line, Triangle */ + line_func LineFunc; /* and Quad rendering functions */ + triangle_func TriangleFunc; + quad_func QuadFunc; + + CARD32 IndirectTriangles; /* Flags for point, line, + tri and quad software + fallbacks */ + CARD32 Fallback; /* Need software fallback */ + + r128ContextRegs regs; /* Hardware state */ + CARD32 Color; /* Current draw color */ + CARD32 ClearColor; /* Color used to clear color buffer */ + CARD32 ClearDepth; /* Value used to clear depth buffer */ + + int drawX; /* x-offset to current draw buffer */ + int drawY; /* y-offset to current draw buffer */ + + int readX; /* x-offset to current read buffer */ + int readY; /* y-offset to current read buffer */ + + CARD32 *CCEbuf; /* buffer to submit to CCE */ + int CCEcount; /* number of dwords in CCEbuf */ + + int CCEtimeout; /* number of times to loop + before exiting */ + + Display *display; /* X server display */ + + __DRIcontextPrivate *driContext; /* DRI context */ + __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ + + r128ScreenPtr r128Screen; /* Screen private DRI data */ +} r128ContextRec, *r128ContextPtr; + +#define R128_MESACTX(r128ctx) ((r128ctx)->glCtx) +#define R128_DRIDRAWABLE(r128ctx) ((r128ctx)->driDrawable) +#define R128_DRISCREEN(r128ctx) ((r128ctx)->r128Screen->driScreen) + +extern GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv); +extern void r128DestroyContext(r128ContextPtr r128ctx); +extern r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx, + r128ContextPtr newCtx, + __DRIdrawablePrivate *dPriv); + +#endif +#endif /* _R128_CONTEXT_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c new file mode 100644 index 000000000..0ed7ae471 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c @@ -0,0 +1,182 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_cce.h" +#include "r128_clear.h" +#include "r128_state.h" +#include "r128_vb.h" +#include "r128_pipeline.h" +#include "r128_dd.h" + +/* Driver entry point for clearing color and ancillary buffers */ +static GLbitfield r128DDClear(GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + if (r128ctx->SWonly) { + /* FIXME: Provide software fallback for this case?? */ + } + + if (mask & DD_FRONT_LEFT_BIT) { + r128ClearColorBuffer(r128ctx, all, x, y, width, height, + r128ctx->r128Screen->fbX, + r128ctx->r128Screen->fbY); + mask &= ~DD_FRONT_LEFT_BIT; + } + + if (mask & DD_BACK_LEFT_BIT) { + r128ClearColorBuffer(r128ctx, all, x, y, width, height, + r128ctx->r128Screen->backX, + r128ctx->r128Screen->backY); + mask &= ~DD_BACK_LEFT_BIT; + } + + if (mask & DD_DEPTH_BIT) { + r128ClearDepthBuffer(r128ctx, all, x, y, width, height); + mask &= ~DD_DEPTH_BIT; + } + +#if 0 + /* FIXME: Add stencil support */ + if (mask & DD_STENCIL_BIT) { + r128ClearStencilBuffer(r128ctx, all, x, y, width, height); + mask &= ~DD_STENCIL_BIT; + } +#endif + + return mask; +} + +/* Return the current color buffer size */ +static void r128DDGetBufferSize(GLcontext *ctx, GLuint *width, GLuint *height) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + *width = r128ctx->driDrawable->w; + *height = r128ctx->driDrawable->h; +} + +/* Return various strings for glGetString() */ +static const GLubyte *r128DDGetString(GLcontext *ctx, GLenum name) +{ + switch (name) { + case GL_VENDOR: + return (GLubyte *)"Precision Insight, Inc."; + case GL_RENDERER: + return (GLubyte *)"Mesa DRI Rage128 20000320"; + default: + return NULL; + } +} + +/* Send all commands to the hardware. If vertex buffers or indirect + buffers are in use, then we need to make sure they are sent to the + hardware. All commands that are normally sent to the ring are + already considered `flushed'. */ +static void r128DDFlush(GLcontext *ctx) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + R128CCE_FLUSH_VB_LOCK(r128ctx); +} + +/* Make sure all commands have been sent to the hardware and have + completed processing. */ +static void r128DDFinish(GLcontext *ctx) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + r128DDFlush(ctx); + R128CCE_WAIT_FOR_IDLE_LOCK(r128ctx); +} + +/* Return various parameters requested by Mesa */ +static GLint r128DDGetParameteri(const GLcontext *ctx, GLint param) +{ + switch (param) { +#if 0 + /* FIXME: Support for these needs to be added to Mesa */ + case DD_MAX_TEXTURE_SIZE: return 1024; + case DD_MAX_TEXTURES: return 2; +#endif +#if 0 + case DD_HAVE_HARDWARE_FOG: return 1; /* FIXME: Add HW fog support */ +#endif + default: return 0; + } +} + +/* Initialize the extensions supported by this driver */ +void r128DDInitExtensions(GLcontext *ctx) +{ + /* FIXME: Are there other extensions to enable/disable??? */ + gl_extensions_disable(ctx, "GL_EXT_shared_texture_palette"); + gl_extensions_disable(ctx, "GL_EXT_paletted_texture"); + gl_extensions_disable(ctx, "GL_EXT_point_parameters"); + gl_extensions_disable(ctx, "ARB_imaging"); + gl_extensions_disable(ctx, "GL_EXT_blend_minmax"); + gl_extensions_disable(ctx, "GL_EXT_blend_logic_op"); + gl_extensions_disable(ctx, "GL_EXT_blend_subtract"); + gl_extensions_disable(ctx, "GL_INGR_blend_func_separate"); + + if (getenv("LIBGL_NO_MULTITEXTURE")) + gl_extensions_disable(ctx, "GL_ARB_multitexture"); +} + +/* Initialize the driver's misc functions */ +void r128DDInitDriverFuncs(GLcontext *ctx) +{ + ctx->Driver.Clear = r128DDClear; + + ctx->Driver.GetBufferSize = r128DDGetBufferSize; + ctx->Driver.GetString = r128DDGetString; + ctx->Driver.Finish = r128DDFinish; + ctx->Driver.Flush = r128DDFlush; + + ctx->Driver.Error = NULL; + ctx->Driver.GetParameteri = r128DDGetParameteri; + + ctx->Driver.DrawPixels = NULL; + ctx->Driver.Bitmap = NULL; + + ctx->Driver.RegisterVB = r128DDRegisterVB; + ctx->Driver.UnregisterVB = r128DDUnregisterVB; + ctx->Driver.BuildPrecalcPipeline = r128DDBuildPrecalcPipeline; +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h new file mode 100644 index 000000000..91aa02586 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h @@ -0,0 +1,44 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_DD_H_ +#define _R128_DD_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128DDInitExtensions(GLcontext *ctx); +extern void r128DDInitDriverFuncs(GLcontext *ctx); + +#endif +#endif /* _R128_DD_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c new file mode 100644 index 000000000..330e5a23d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c @@ -0,0 +1,551 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_state.h" +#include "r128_vb.h" +#include "r128_tris.h" +#include "r128_fastpath.h" + +#include "mmath.h" +#include "cva.h" +#include "vertices.h" + +/* FIXME: These routines were copied from the i810 driver, and were only + slightly modified for the Rage 128. They still need to be optmizied + and cleaned up. Also, support for USE_RHW2 needs to be added. */ + +typedef struct r128_fast_table { + r128BuildVerticesFunc build_vertices; + r128InterpFunc interp; +} r128FastPathTable; + +#define POINT(x) r128DrawPointVB(r128ctx, &vert[x].v, psize) +#define LINE(x,y) r128DrawLineVB(r128ctx, &vert[x].v, &vert[y].v, lwidth) +#define TRI(x,y,z) r128DrawTriangleVB(r128ctx, &vert[x].v, &vert[y].v, &vert[z].v) + +/* Direct, and no clipping required. The clip funcs have not been + written yet, so this is only useful for the fast path. */ +#define RENDER_POINTS(start, count) \ +do { \ + GLuint e; \ + for (e = start; e <= count; e++) \ + POINT(elt[e]); \ +} while (0) + +#define RENDER_LINE(i1, i) \ +do { \ + GLuint e1 = elt[i1], e = elt[i]; \ + LINE(e1, e); \ +} while (0) + +#define RENDER_TRI(i2, i1, i, pv, parity) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + if (parity) { \ + GLuint tmp = e2; \ + e2 = e1; \ + e1 = tmp; \ + } \ + TRI(e2, e1, e); \ +} while (0) + +#define RENDER_QUAD(i3, i2, i1, i, pv) \ +do { \ + GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + TRI(e3, e2, e); \ + TRI(e2, e1, e); \ +} while (0) + +#define LOCAL_VARS \ + r128VertexPtr vert = R128_DRIVER_DATA(VB)->verts; \ + const GLuint *elt = VB->EltPtr->data; \ + GLcontext *ctx = VB->ctx; \ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ + const GLfloat lwidth = ctx->Line.Width; \ + const GLfloat psize = ctx->Point.Size; \ + (void) lwidth; (void)psize; (void) vert; + +#define TAG(x) x##_r128_smooth_indirect +#include "render_tmp.h" + + + +#define NEGATIVE(f) (f < 0) +#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) +#define LINTERP(T, A, B) ((A) + (T) * ((B) - (A))) + + +#define INTERP_RGBA(t, out, a, b) \ +do { \ + int i; \ + for (i = 0; i < 4; i++) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \ + GLfloat fo = LINTERP(t, fa, fb); \ + FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \ + } \ +} while (0) + + +#define CLIP(SGN, V, PLANE) \ +do { \ + if (mask & PLANE) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]].f; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + inlist[0] = vlist1; \ + for (i = n = 0 ; i < nr ; i++) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i].f; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t, *in, *out; \ + \ + if (NEGATIVE(dpI)) { \ + t = dpI / (dpI - dpJ); \ + in = I; \ + out = J; \ + } else { \ + t = dpJ / (dpJ - dpI); \ + in = J; \ + out = I; \ + } \ + \ + interp(t, O, in, out); \ + \ + clipmask[next_vert] = 0; \ + outdata[n++] = next_vert++; \ + } \ + \ + clipmask[elt_i] |= PLANE; /* don't set up */ \ + \ + if (!NEGATIVE(dpI)) { \ + outdata[n++] = elt_i; \ + clipmask[elt_i] &= ~PLANE; /* set up after all */ \ + } \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if (n < 3) return; \ + } \ +} while (0) + +#define LINE_CLIP(x,y,z,w,PLANE) \ +do { \ + if (mask & PLANE) { \ + GLfloat dpI = DOT4V(I,x,y,z,w); \ + GLfloat dpJ = DOT4V(J,x,y,z,w); \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t = dpI / (dpI - dpJ); \ + \ + interp(t, O, I, J); \ + \ + clipmask[next_vert] = 0; \ + \ + if (NEGATIVE(dpI)) { \ + clipmask[elts[0]] |= PLANE; \ + I = O; \ + elts[0] = next_vert++; \ + } else { \ + clipmask[elts[1]] |= PLANE; \ + J = O; \ + elts[1] = next_vert++; \ + } \ + } else if (NEGATIVE(dpI)) return; \ + } \ +} while (0) + + +static void r128TriClip(GLuint **p_elts, + r128Vertex *verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + r128InterpFunc interp) +{ + GLuint *elts = *p_elts; + GLuint next_vert = *p_next_vert; + GLuint in = 0; + GLuint n = 3; + GLuint vlist1[VB_MAX_CLIPPED_VERTS]; + GLuint vlist2[VB_MAX_CLIPPED_VERTS]; + GLuint *inlist[2]; + GLuint *out; + GLuint i; + + inlist[0] = elts; + inlist[1] = vlist2; + + CLIP(-,0,CLIP_RIGHT_BIT); + CLIP(+,0,CLIP_LEFT_BIT); + CLIP(-,1,CLIP_TOP_BIT); + CLIP(+,1,CLIP_BOTTOM_BIT); + CLIP(-,2,CLIP_FAR_BIT); + CLIP(+,2,CLIP_NEAR_BIT); + + /* Convert the planar polygon to a list of triangles */ + out = inlist[in]; + + for (i = 2 ; i < n ; i++) { + elts[0] = out[0]; + elts[1] = out[i-1]; + elts[2] = out[i]; + elts += 3; + } + + *p_next_vert = next_vert; + *p_elts = elts; +} + + +static void r128LineClip(GLuint **p_elts, + r128Vertex *verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + r128InterpFunc interp) +{ + GLuint *elts = *p_elts; + GLfloat *I = verts[elts[0]].f; + GLfloat *J = verts[elts[1]].f; + GLuint next_vert = *p_next_vert; + + LINE_CLIP(1,0,0,-1,CLIP_LEFT_BIT); + LINE_CLIP(-1,0,0,1,CLIP_RIGHT_BIT); + LINE_CLIP(0,1,0,-1,CLIP_TOP_BIT); + LINE_CLIP(0,-1,0,1,CLIP_BOTTOM_BIT); + LINE_CLIP(0,0,1,-1,CLIP_FAR_BIT); + LINE_CLIP(0,0,-1,1,CLIP_NEAR_BIT); + + *p_next_vert = next_vert; + *p_elts += 2; +} + + + +#define CLIP_POINT(e) \ +do { \ + if (mask[e]) *out++ = e; \ +} while (0) + +#define CLIP_LINE(e1, e0) \ +do { \ + GLubyte ormask = mask[e0] | mask[e1]; \ + out[0] = e1; \ + out[1] = e0; \ + out += 2; \ + if (ormask) { \ + out-=2; \ + if (!(mask[e0] & mask[e1])) { \ + r128LineClip(&out, verts, mask, &next_vert, ormask, interp); \ + } \ + } \ +} while (0) + +#define CLIP_TRIANGLE(e2, e1, e0) \ +do { \ + GLubyte ormask; \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + out += 3; \ + ormask = mask[e2] | mask[e1] | mask[e0]; \ + if (ormask) { \ + out -= 3; \ + if (!(mask[e2] & mask[e1] & mask[e0])) { \ + r128TriClip(&out, verts, mask, &next_vert, ormask, interp); \ + } \ + } \ +} while (0) + + + +/* Build a table of functions to clip each primitive type. These + * produce a list of elements in the appropriate 'reduced' primitive, + * ie (points, lines, triangles) containing all the clipped and + * unclipped primitives from the original list. + */ +#define LOCAL_VARS \ + r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \ + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); \ + GLuint *elt = VB->EltPtr->data; \ + r128Vertex *verts = r128VB->verts; \ + GLuint next_vert = r128VB->last_vert; \ + GLuint *out = r128VB->clipped_elements.data; \ + GLubyte *mask = VB->ClipMask; \ + r128InterpFunc interp = r128ctx->interp; \ + (void) interp; (void) verts; + +#define POSTFIX \ + r128VB->clipped_elements.count = out - r128VB->clipped_elements.data; \ + r128VB->last_vert = next_vert; + + +#define INIT(x) + +#define RENDER_POINTS(start, count) \ +do { \ + GLuint i; \ + for (i = start; i < count; i++) \ + CLIP_POINT(elt[i]); \ +} while (0) + +#define RENDER_LINE(i1, i0) \ +do { \ + CLIP_LINE(elt[i1], elt[i0]); \ +} while (0) + +#define RENDER_TRI(i2, i1, i0, pv, parity) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if (parity) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE(e2, e1, e0); \ +} while (0) + +#define RENDER_QUAD(i3, i2, i1, i0, pv) \ +do { \ + CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \ + CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0]); \ +} while (0) + +#define TAG(x) r128_clip_##x##_elt +#include "render_tmp.h" + + +/* Pack rgba and/or texture into the remaining half of a 32 byte vertex. + */ +#define CLIP_UBYTE_COLOR 4 +#define CLIP_UBYTE_B 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_R 2 +#define CLIP_UBYTE_A 3 +#define CLIP_S0 6 +#define CLIP_T0 7 +#define CLIP_S1 8 +#define CLIP_T1 9 + +#define TYPE (0) +#define TAG(x) x +#include "r128_fasttmp.h" + +#define TYPE (R128_RGBA_BIT) +#define TAG(x) x##_RGBA +#include "r128_fasttmp.h" + +#define TYPE (R128_TEX0_BIT) +#define TAG(x) x##_TEX0 +#include "r128_fasttmp.h" + +#define TYPE (R128_RGBA_BIT | R128_TEX0_BIT) +#define TAG(x) x##_RGBA_TEX0 +#include "r128_fasttmp.h" + +#define TYPE (R128_RGBA_BIT | R128_TEX0_BIT | R128_TEX1_BIT) +#define TAG(x) x##_RGBA_TEX0_TEX1 +#include "r128_fasttmp.h" + +/* This one *could* get away with sneaking TEX1 into the color and + * specular slots, thus fitting inside a cache line. Would be even + * better to switch to a smaller vertex. + */ +#define TYPE (R128_TEX0_BIT | R128_TEX1_BIT) +#define TAG(x) x##_TEX0_TEX1 +#include "r128_fasttmp.h" + + + +/* Render elements directly from original list of vertices. */ +static void r128RenderElementsDirect(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + GLenum prim = ctx->CVA.elt_mode; + GLuint nr = VB->EltPtr->count; + render_func func = render_tab_r128_smooth_indirect[prim]; + GLuint p = 0; + + if (r128ctx->dirty) r128UpdateHWState(r128ctx); + + do { + func(VB, 0, nr, 0); + } while (ctx->Driver.MultipassFunc && + ctx->Driver.MultipassFunc(VB, ++p)); +} + +/* Project vertices from clip to device space */ +static void r128ProjectVertices(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLfloat m[16]; + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ]; + m[MAT_TZ] = mat->m[MAT_TZ]; + + switch (ctx->Visual->DepthBits) { + case 16: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break; + case 24: m[MAT_SZ] /= 16777216.0; m[MAT_TZ] /= 16777216.0; break; + case 32: m[MAT_SZ] /= 4294967296.0; m[MAT_TZ] /= 4294967296.0; break; + default: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break; + } + +#if USE_RHW2 + /* FIXME: Handle RHW2?? */ + gl_project_v16(r128VB->verts[VB->CopyStart].f, + r128VB->verts[r128VB->last_vert].f, + m, + 16 * 4); +#else + gl_project_v16(r128VB->verts[VB->CopyStart].f, + r128VB->verts[r128VB->last_vert].f, + m, + 16 * 4); +#endif +} + +/* Project clipped vertices from clip to device space */ +static void r128ProjectClippedVertices(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLfloat m[16]; + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ]; + m[MAT_TZ] = mat->m[MAT_TZ]; + + switch (ctx->Visual->DepthBits) { + case 16: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break; + case 24: m[MAT_SZ] /= 16777216.0; m[MAT_TZ] /= 16777216.0; break; + case 32: m[MAT_SZ] /= 4294967296.0; m[MAT_TZ] /= 4294967296.0; break; + default: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break; + } + +#if USE_RHW2 + /* FIXME: Handle RHW2?? */ + gl_project_clipped_v16(r128VB->verts[VB->CopyStart].f, + r128VB->verts[r128VB->last_vert].f, + m, + 16 * 4, + VB->ClipMask + VB->CopyStart); +#else + gl_project_clipped_v16(r128VB->verts[VB->CopyStart].f, + r128VB->verts[r128VB->last_vert].f, + m, + 16 * 4, + VB->ClipMask + VB->CopyStart); +#endif +} + +static r128FastPathTable r128FastTab[0x80]; + +/* Initialize the table of fast path support functions */ +void r128FastPathInit(void) +{ + r128_clip_render_init_elt(); + render_init_r128_smooth_indirect(); + + r128_init_fastpath(&r128FastTab[0]); + r128_init_fastpath_RGBA(&r128FastTab[R128_RGBA_BIT]); + r128_init_fastpath_TEX0(&r128FastTab[R128_TEX0_BIT]); + r128_init_fastpath_RGBA_TEX0(&r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT]); + r128_init_fastpath_TEX0_TEX1(&r128FastTab[R128_TEX0_BIT|R128_TEX1_BIT]); + r128_init_fastpath_RGBA_TEX0_TEX1(&r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT| + R128_TEX1_BIT]); +} + +#define VALID_SETUP (R128_RGBA_BIT | R128_TEX0_BIT | R128_TEX1_BIT) + +void r128FastPath(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128FastPathTable *tab = &r128FastTab[r128ctx->SetupIndex & VALID_SETUP]; + GLuint do_cliptest = 1; + + gl_prepare_arrays_cva(VB); /* still need this */ + + /* Reserve enough space for the pathological case */ + if (VB->EltPtr->count * 12 > R128_DRIVER_DATA(VB)->size) { + r128ResizeVB(VB, VB->EltPtr->count * 12); + do_cliptest = 1; + } + + tab->build_vertices(VB, do_cliptest); /* object->clip space */ + + if (r128ctx->dirty) r128UpdateHWState(r128ctx); + + if (VB->ClipOrMask) { + if (!VB->ClipAndMask) { + render_func *clip = r128_clip_render_tab_elt; + + r128ctx->interp = tab->interp; + clip[prim](VB, 0, VB->EltPtr->count, 0); /* build new elts */ + ctx->CVA.elt_mode = gl_reduce_prim[prim]; + VB->EltPtr = &(R128_DRIVER_DATA(VB)->clipped_elements); + r128ProjectClippedVertices(VB); /* clip->device space */ + r128RenderElementsDirect(VB); /* render using new list */ + } + } else { + r128ProjectVertices(VB); /* clip->device space */ + r128RenderElementsDirect(VB); /* render using orig list */ + } + + /* This indicates that there is no cached data to reuse */ + VB->pipeline->data_valid = 0; + VB->pipeline->new_state = 0; +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h new file mode 100644 index 000000000..47bb92049 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h @@ -0,0 +1,48 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_FASTPATH_H_ +#define _R128_FASTPATH_H_ + +typedef void (*r128BuildVerticesFunc)(struct vertex_buffer *VB, + GLuint do_cliptest); +typedef void (*r128InterpFunc)(GLfloat t, + GLfloat *result, + const GLfloat *in, + const GLfloat *out); + +extern void r128FastPathInit(void); +extern void r128FastPath(struct vertex_buffer *VB); + +#endif /* _R128_FASTPATH_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h new file mode 100644 index 000000000..e76dd52b4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h @@ -0,0 +1,155 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +/* FIXME: These routines were copied from the i810 driver, and were only + slightly modified for the Rage 128. They still need to be optmizied + and cleaned up. Also, support for USE_RHW2 needs to be added. */ + +/* The first part of setup is applied to all vertices, clipped or + * unclipped. This data w!ill be used for clipping, and then all + * vertices with a zero clipmask will be projected to device space. + * + * This could be split into several loops, but - it seems that the + * large stride of the fxVertices makes cache issues the big + * performance factor, and that multiple loops mean multiple cache + * misses.... + */ +static void TAG(r128_setup_full)(struct vertex_buffer *VB, GLuint do_cliptest) +{ + GLcontext *ctx = VB->ctx; + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + const GLfloat *m = ctx->ModelProjectMatrix.m; + GLuint start = VB->CopyStart; + GLuint count = VB->Count; + GLuint i; + + gl_xform_points3_v16_general(r128VB->verts[start].f, + m, + VB->ObjPtr->start, + VB->ObjPtr->stride, + count - start); + + if (do_cliptest) { + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + gl_cliptest_points4_v16(r128VB->verts[start].f, + r128VB->verts[count].f, + &(VB->ClipOrMask), + &(VB->ClipAndMask), + VB->ClipMask + start); + } + + /* These branches are all resolved at compile time. Hopefully all + * the pointers are valid addresses even when not enabled. + */ + if (TYPE) { + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + + GLfloat *f = r128VB->verts[start].f; + + for (i = start ; i < count ; i++, f += 16) { + if (TYPE & R128_RGBA_BIT) { + GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR]; + GLubyte *col = color; color += color_stride; + b[CLIP_UBYTE_R] = col[0]; + b[CLIP_UBYTE_G] = col[1]; + b[CLIP_UBYTE_B] = col[2]; + b[CLIP_UBYTE_A] = col[3]; + } + if (TYPE & R128_TEX0_BIT) { + f[CLIP_S0] = tex0_data[0]; + f[CLIP_T0] = tex0_data[1]; + STRIDE_F(tex0_data, tex0_stride); + } + if (TYPE & R128_TEX1_BIT) { + f[CLIP_S1] = tex1_data[0]; + f[CLIP_T1] = tex1_data[1]; + STRIDE_F(tex1_data, tex1_stride); + } + } + } + + r128VB->clipped_elements.count = start; + r128VB->last_vert = count; +} + + +/* Changed to just put the interp func instead of the whole clip + * routine into the header. Less code and better chance of doing some + * of this stuff in assembly. + */ +static void TAG(r128_interp_vert)(GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J) +{ + O[0] = LINTERP(t, I[0], J[0]); + O[1] = LINTERP(t, I[1], J[1]); + O[2] = LINTERP(t, I[2], J[2]); + O[3] = LINTERP(t, I[3], J[3]); + + if (TYPE & R128_RGBA_BIT) { + INTERP_RGBA(t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4]))); + } + + if (TYPE & R128_TEX0_BIT) { + O[6] = LINTERP(t, I[6], J[6]); + O[7] = LINTERP(t, I[7], J[7]); + } + + if (TYPE & R128_TEX1_BIT) { + O[8] = LINTERP(t, I[8], J[8]); + O[9] = LINTERP(t, I[9], J[9]); + } +} + + +static void TAG(r128_init_fastpath)(r128FastPathTable *tab) +{ + tab->build_vertices = TAG(r128_setup_full); + tab->interp = TAG(r128_interp_vert); +} + +#undef TYPE +#undef TAG +#undef SIZE diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_init.h b/xc/lib/GL/mesa/src/drv/r128/r128_init.h new file mode 100644 index 000000000..fcaf70a51 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_init.h @@ -0,0 +1,92 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_INIT_H_ +#define _R128_INIT_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include <X11/Xlibint.h> + +#include "types.h" +#include "xf86drm.h" +#include "dri_tmm.h" +#include "dri_mesaint.h" + +#include "r128_screen.h" +#include "r128_context.h" + +/* NOTE: The vertex buffer code is currently unstable because of the + switches between CCE and MMIO mode in the X server. Fixing the X + server to use the CCE should fix this problem. So, for now, it is + recommended that you do not use it. */ + +#define DEBUG 1 +#define DEBUG_LOCKING 1 +#define USE_FAST_PATH 1 +#define USE_USER_SPACE_RING 0 + + +#if DEBUG + +#include <stdio.h> +#define R128_DEBUG(p) \ + do { \ + printf p ; \ + fflush(stdout); \ + } while (0) + +extern int R128_DEBUG_FLAGS; + +#define DEBUG_VERBOSE_2D 0x0001 +#define DEBUG_VERBOSE_CCE 0x0008 +#define DEBUG_VERBOSE_OUTREG 0x0010 +#define DEBUG_ALWAYS_SYNC 0x0040 +#define DEBUG_VERBOSE_MSG 0x0080 +#define DEBUG_NO_OUTRING 0x0100 +#define DEBUG_NO_OUTREG 0x0200 +#define DEBUG_VERBOSE_API 0x0400 +#define DEBUG_VALIDATE_RING 0x0800 +#define DEBUG_VERBOSE_LRU 0x1000 +#define DEBUG_VERBOSE_DRI 0x2000 +#define DEBUG_VERBOSE_IOCTL 0x4000 + +#else + +#define R128_DEBUG_FLAGS 0 + +#endif + +#endif +#endif /* _R128_INIT_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h new file mode 100644 index 000000000..7fd81f807 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h @@ -0,0 +1,134 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_LOCK_H_ +#define _R128_LOCK_H_ + +#ifdef GLX_DIRECT_RENDERING + +/* Turn DEBUG_LOCKING on to find locking conflicts (see r128_init.h) */ +#if DEBUG_LOCKING +extern char *prevLockFile; +extern int prevLockLine; + +#define DEBUG_LOCK() \ + do { \ + prevLockFile = (__FILE__); \ + prevLockLine = (__LINE__); \ + } while (0) + +#define DEBUG_RESET() \ + do { \ + prevLockFile = 0; \ + prevLockLine = 0; \ + } while (0) + +#define DEBUG_CHECK_LOCK() \ + do { \ + if (prevLockFile) { \ + fprintf(stderr, \ + "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ + prevLockFile, prevLockLine, __FILE__, __LINE__); \ + exit(1); \ + } \ + } while (0) + +#else + +#define DEBUG_LOCK() +#define DEBUG_RESET() +#define DEBUG_CHECK_LOCK() + +#endif + +/* + * !!! We may want to separate locks from locks with validation. This + * could be used to improve performance for those things commands that + * do not do any drawing !!! + */ + +/* Lock the hardware using the current context */ +#define LOCK_HARDWARE(CC) \ + do { \ + char __ret = 0; \ + __DRIcontextPrivate *cPriv = CC->driContext; \ + __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \ + \ + DEBUG_CHECK_LOCK(); \ + DRM_CAS(&sPriv->pSAREA->lock, cPriv->hHWContext, \ + DRM_LOCK_HELD|cPriv->hHWContext, __ret); \ + if (__ret) { \ + /* We lost the context, so we need to request the lock from \ + the kernel and update our state. */ \ + drmGetLock(sPriv->fd, cPriv->hHWContext, 0); \ + XMesaUpdateState(cPriv); \ + } \ + DEBUG_LOCK(); \ + } while (0) + +/* Unlock the hardware using the current context */ +#define UNLOCK_HARDWARE(CC) \ + do { \ + __DRIcontextPrivate *cPriv = CC->driContext; \ + __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \ + \ + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, cPriv->hHWContext); \ + DEBUG_RESET(); \ + } while (0) + +/* + * This pair of macros makes a loop over the drawing operations, so it + * is not self contained and does not have the nice single statement + * semantics of most macros. + */ +#define BEGIN_CLIP_LOOP(CC) \ + do { \ + __DRIdrawablePrivate *_dPriv = CC->driDrawable; \ + XF86DRIClipRectPtr _pc = _dPriv->pClipRects; \ + int _nc, _sc; \ + \ + for (_nc = _dPriv->numClipRects; _nc > 0; _nc -= 3, _pc += 3) { \ + _sc = (_nc <= 3) ? _nc : 3; \ + r128SetClipRects(CC, _pc, _sc) + +/* FIXME: This should be a function call to turn off aux clipping */ +#define END_CLIP_LOOP(CC) \ + R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0); \ + R128CCE(0x00000000); \ + R128CCE_SUBMIT_PACKETS(); \ + } \ + } while (0) + +#endif +#endif /* _R128_LOCK_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_mesa.h b/xc/lib/GL/mesa/src/drv/r128/r128_mesa.h new file mode 100644 index 000000000..3a697b466 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_mesa.h @@ -0,0 +1,43 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_MESA_H_ +#define _R128_MESA_H_ + +#ifdef GLX_DIRECT_RENDERING + +#define R128_CONTEXT(ctx) ((r128ContextPtr)(ctx->DriverCtx)) + +#endif +#endif /* _R128_MESA_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c new file mode 100644 index 000000000..55487ffcd --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c @@ -0,0 +1,126 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_vb.h" +#include "r128_fastpath.h" +#include "r128_pipeline.h" + +#include "types.h" + +static struct gl_pipeline_stage r128FastStage = { + "R128 Fast Path", + (PIPE_OP_VERT_XFORM | + PIPE_OP_RAST_SETUP_0 | + PIPE_OP_RAST_SETUP_1 | + PIPE_OP_RENDER), + PIPE_PRECALC, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + r128FastPath +}; + +/* Build the PRECALC pipeline with our stage, if possible. Otherwise, + return GL_FALSE */ +GLboolean r128DDBuildPrecalcPipeline(GLcontext *ctx) +{ +#if USE_FAST_PATH + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + struct gl_pipeline *pipe = &ctx->CVA.pre; + + if (r128ctx->RenderIndex == 0 && + !(ctx->Enabled & (TEXTURE0_3D | + TEXTURE1_3D | + ENABLE_TEXMAT0 | + ENABLE_TEXMAT1 | + ENABLE_TEXGEN0 | + ENABLE_TEXGEN1 | + ENABLE_USERCLIP | + ENABLE_LIGHT | + ENABLE_FOG)) && + (ctx->Array.Flags & (VERT_OBJ_234 | + VERT_TEX0_4 | + VERT_TEX1_4 | + VERT_ELT)) == (VERT_OBJ_23 | + VERT_ELT)) { + pipe->stages[0] = &r128FastStage; + pipe->stages[1] = 0; + pipe->new_inputs = ctx->RenderFlags & VERT_DATA; + pipe->ops = pipe->stages[0]->ops; + + r128ctx->useFastPath = GL_TRUE; + return GL_TRUE; + } + + if (r128ctx->useFastPath) { + r128ctx->useFastPath = GL_FALSE; + + ctx->CVA.VB->ClipOrMask = 0; + ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; + ctx->Array.NewArrayState |= ctx->Array.Summary; + } +#endif + + return GL_FALSE; +} + +/* Register the pipeline with our stages included */ +GLuint r128RegisterPipelineStages(struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, + GLuint nr) +{ +#if USE_FAST_PATH + int i; + + for (i = 0; i < nr; i++) { + out[i] = in[i]; + switch (in[i].ops) { + case PIPE_OP_RAST_SETUP_0: + out[i].cva_state_change = (NEW_LIGHTING | + NEW_TEXTURING | + NEW_RASTER_OPS); + out[i].state_change = ~0; + out[i].check = r128CheckPartialRasterSetup; + out[i].run = r128PartialRasterSetup; + break; + + case PIPE_OP_RAST_SETUP_0|PIPE_OP_RAST_SETUP_1: + out[i].run = r128DoRasterSetup; + break; + } + } +#endif + + return nr; +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h new file mode 100644 index 000000000..280e6b943 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h @@ -0,0 +1,43 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_PIPELINE_H_ +#define _R128_PIPELINE_H_ + +extern GLboolean r128DDBuildPrecalcPipeline(GLcontext *ctx); +extern GLuint r128RegisterPipelineStages(struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, + GLuint nr); + +#endif /* _R128_PIPELINE_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c new file mode 100644 index 000000000..b385271f4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c @@ -0,0 +1,258 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_dri.h" +#include "r128_reg.h" + +#include "r128_init.h" +#include "r128_context.h" +#include "r128_xmesa.h" +#include "r128_cce.h" +#include "r128_tris.h" +#include "r128_vb.h" +#include "r128_fastpath.h" + +#include <sys/mman.h> + +/* Create the device specific screen private data struct */ +r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) +{ + r128ScreenPtr r128Screen; + R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv; + + /* Allocate the private area */ + r128Screen = (r128ScreenPtr)Xmalloc(sizeof(*r128Screen)); + if (!r128Screen) return NULL; + + /* This is first since which regions we map depends on whether or + not we are using a PCI card */ + r128Screen->IsPCI = r128DRIPriv->IsPCI; + + r128Screen->mmioRgn.handle = r128DRIPriv->registerHandle; + r128Screen->mmioRgn.size = r128DRIPriv->registerSize; + if (drmMap(sPriv->fd, + r128Screen->mmioRgn.handle, + r128Screen->mmioRgn.size, + (drmAddressPtr)&r128Screen->mmio)) { + Xfree(r128Screen); + return NULL; + } + + if (!r128Screen->IsPCI) { + r128Screen->ringRgn.handle = r128DRIPriv->ringHandle; + r128Screen->ringRgn.size = r128DRIPriv->ringMapSize; + if (drmMap(sPriv->fd, + r128Screen->ringRgn.handle, + r128Screen->ringRgn.size, + (drmAddressPtr)&r128Screen->ring)) { + drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); + Xfree(r128Screen); + return NULL; + } + + r128Screen->ringReadRgn.handle = r128DRIPriv->ringReadPtrHandle; + r128Screen->ringReadRgn.size = r128DRIPriv->ringReadMapSize; + if (drmMap(sPriv->fd, + r128Screen->ringReadRgn.handle, + r128Screen->ringReadRgn.size, + (drmAddressPtr)&r128Screen->ringReadPtr)) { + drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); + drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); + Xfree(r128Screen); + return NULL; + } + + r128Screen->vbRgn.handle = r128DRIPriv->vbHandle; + r128Screen->vbRgn.size = r128DRIPriv->vbMapSize; + r128Screen->vbOffset = r128DRIPriv->vbOffset; + if (drmMap(sPriv->fd, + r128Screen->vbRgn.handle, + r128Screen->vbRgn.size, + (drmAddressPtr)&r128Screen->vb)) { + drmUnmap((drmAddress)r128Screen->ringReadPtr, + r128Screen->ringReadRgn.size); + drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); + drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); + Xfree(r128Screen); + return NULL; + } + r128Screen->vbOffset = r128DRIPriv->vbOffset; + r128Screen->vbBufSize = r128DRIPriv->vbBufSize; + + r128Screen->indRgn.handle = r128DRIPriv->indHandle; + r128Screen->indRgn.size = r128DRIPriv->indMapSize; + if (drmMap(sPriv->fd, + r128Screen->indRgn.handle, + r128Screen->indRgn.size, + (drmAddressPtr)&r128Screen->ind)) { + drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size); + drmUnmap((drmAddress)r128Screen->ringReadPtr, + r128Screen->ringReadRgn.size); + drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); + drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); + Xfree(r128Screen); + return NULL; + } + + r128Screen->agpTexRgn.handle = r128DRIPriv->agpTexHandle; + r128Screen->agpTexRgn.size = r128DRIPriv->agpTexMapSize; + if (drmMap(sPriv->fd, + r128Screen->agpTexRgn.handle, + r128Screen->agpTexRgn.size, + (drmAddressPtr)&r128Screen->agpTex)) { + drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size); + drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size); + drmUnmap((drmAddress)r128Screen->ringReadPtr, + r128Screen->ringReadRgn.size); + drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); + drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); + Xfree(r128Screen); + return NULL; + } + r128Screen->agpTexOffset = r128DRIPriv->agpTexOffset; + + if (!(r128Screen->vbBufs = drmMapBufs(sPriv->fd))) { + drmUnmap((drmAddress)r128Screen->agpTex, + r128Screen->agpTexRgn.size); + drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size); + drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size); + drmUnmap((drmAddress)r128Screen->ringReadPtr, + r128Screen->ringReadRgn.size); + drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); + drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); + Xfree(r128Screen); + return NULL; + } + } + + r128Screen->deviceID = r128DRIPriv->deviceID; + + r128Screen->width = r128DRIPriv->width; + r128Screen->height = r128DRIPriv->height; + r128Screen->depth = r128DRIPriv->depth; + r128Screen->bpp = r128DRIPriv->bpp; + r128Screen->pixel_code = (r128Screen->bpp != 16 ? + r128Screen->bpp : + r128Screen->depth); + + r128Screen->fb = sPriv->pFB; + r128Screen->fbOffset = sPriv->fbOrigin; + r128Screen->fbStride = sPriv->fbStride; + r128Screen->fbSize = sPriv->fbSize; + + r128Screen->fbX = r128DRIPriv->fbX; + r128Screen->fbY = r128DRIPriv->fbY; + r128Screen->backX = r128DRIPriv->backX; + r128Screen->backY = r128DRIPriv->backY; + r128Screen->depthX = r128DRIPriv->depthX; + r128Screen->depthY = r128DRIPriv->depthY; + + r128Screen->texOffset[R128_LOCAL_TEX_HEAP] = (r128DRIPriv->textureY * + r128Screen->fbStride + + r128DRIPriv->textureX * + (r128Screen->bpp/8)); + r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize; + r128Screen->log2TexGran[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran; + + if (r128Screen->IsPCI) { + r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0; + r128Screen->texSize[R128_AGP_TEX_HEAP] = 0; + r128Screen->log2TexGran[R128_AGP_TEX_HEAP] = 0; + r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS-1; + } else { + r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0; + r128Screen->texSize[R128_AGP_TEX_HEAP] = + r128DRIPriv->agpTexMapSize; + r128Screen->log2TexGran[R128_AGP_TEX_HEAP] = + r128DRIPriv->log2AGPTexGran; + r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS; + } + +#if 1 + /* FIXME: For testing only */ + if (getenv("LIBGL_SHOW_BUFFERS")) { + r128Screen->backX = 0; + r128Screen->backY = r128DRIPriv->height/2; + r128Screen->depthX = r128DRIPriv->width/2; + r128Screen->depthY = r128DRIPriv->height/2; + } +#endif + + r128Screen->CCEMode = r128DRIPriv->CCEMode; + r128Screen->CCEFifoSize = r128DRIPriv->CCEFifoSize; + + r128Screen->ringEntries = r128DRIPriv->ringSize/sizeof(CARD32); + if (!r128Screen->IsPCI) { + r128Screen->ringStartPtr = (int *)r128Screen->ring; + r128Screen->ringEndPtr = (int *)(r128Screen->ring + + r128DRIPriv->ringSize); + } + + r128Screen->MMIOFifoSlots = 0; + r128Screen->CCEFifoSlots = 0; + + r128Screen->CCEFifoAddr = R128_PM4_FIFO_DATA_EVEN; + + r128Screen->SAREA = (R128SAREAPrivPtr)((char *)sPriv->pSAREA + + sizeof(XF86DRISAREARec)); + + r128Screen->driScreen = sPriv; + + r128FastPathInit(); + r128TriangleFuncsInit(); + r128SetupInit(); + + return r128Screen; +} + +/* Destroy the device specific screen private data struct */ +void r128DestroyScreen(__DRIscreenPrivate *sPriv) +{ + r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private; + + if (!r128Screen->IsPCI) { + drmUnmapBufs(r128Screen->vbBufs); + + drmUnmap((drmAddress)r128Screen->agpTex, r128Screen->agpTexRgn.size); + drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size); + drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size); + drmUnmap((drmAddress)r128Screen->ringReadPtr, + r128Screen->ringReadRgn.size); + drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); + } + drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); + + Xfree(r128Screen); + sPriv->private = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h new file mode 100644 index 000000000..02deb64e9 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h @@ -0,0 +1,129 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_SCREEN_H_ +#define _R128_SCREEN_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include "r128_sarea.h" + +typedef struct { + drmHandle handle; /* Handle to the DRM region */ + drmSize size; /* Size of the DRM region */ +} r128RegionRec, *r128RegionPtr; + +typedef struct { + /* MMIO register data */ + r128RegionRec mmioRgn; + unsigned char *mmio; + + /* CCE ring buffer data */ + r128RegionRec ringRgn; + unsigned char *ring; + + /* CCE ring read pointer data */ + r128RegionRec ringReadRgn; + + /* CCE vertex buffer data */ + r128RegionRec vbRgn; + unsigned char *vb; + int vbOffset; + int vbBufSize; + drmBufMapPtr vbBufs; + + /* CCE indirect buffer data */ + r128RegionRec indRgn; + unsigned char *ind; + + /* CCE AGP Texture data */ + r128RegionRec agpTexRgn; + unsigned char *agpTex; + int agpTexOffset; + + /* Frame buffer data */ + unsigned char *fb; + unsigned long fbOffset; + int fbStride; + int fbSize; + + int IsPCI; /* Current card is a PCI card */ + + int CCEMode; /* CCE mode that server/clients use */ + int CCEFifoSize; /* Size of the CCE command FIFO */ + + /* CCE ring buffer data */ + int ringEntries; + + volatile int *ringReadPtr; /* Pointer to current read addr */ + int *ringStartPtr; /* Pointer to end of ring buffer */ + int *ringEndPtr; /* Pointer to end of ring buffer */ + + /* DRI screen private data */ + int deviceID; /* PCI device ID */ + int width; /* Width in pixels of display */ + int height; /* Height in scanlines of display */ + int depth; /* Depth of display (8, 15, 16, 24) */ + int bpp; /* Bit depth of disp (8, 16, 24, 32) */ + int pixel_code; /* 8, 15, 16, 24, 32 */ + + int fbX; /* Start of frame buffer */ + int fbY; + int backX; /* Start of shared back buffer */ + int backY; + int depthX; /* Start of shared depth buffer */ + int depthY; + + /* Shared texture data */ + int NRTexHeaps; + int texOffset[R128_NR_TEX_HEAPS]; + int texSize[R128_NR_TEX_HEAPS]; + int log2TexGran[R128_NR_TEX_HEAPS]; + + int MMIOFifoSlots; /* Free slots in the FIFO (64 max) */ + int CCEFifoSlots; /* Free slots in the CCE FIFO */ + + int CCEFifoAddr; /* MMIO offset to write next CCE + value (only used when CCE is + in PIO mode). */ + R128SAREAPrivPtr SAREA; /* Pointer to SAREA private data */ + + __DRIscreenPrivate *driScreen; +} r128ScreenRec, *r128ScreenPtr; + +r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv); +void r128DestroyScreen(__DRIscreenPrivate *sPriv); + +#endif +#endif /* _R128_SCREEN_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.c b/xc/lib/GL/mesa/src/drv/r128/r128_span.c new file mode 100644 index 000000000..b5d1774fd --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c @@ -0,0 +1,329 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * Gareth Hughes <gareth@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_state.h" +#include "r128_reg.h" +#include "r128_cce.h" +#include "r128_span.h" + +#define DBG 0 + +#define LOCAL_VARS \ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ + r128ScreenPtr r128scrn = r128ctx->r128Screen; \ + __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ + GLuint pitch = r128scrn->fbStride; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(r128scrn->fb + \ + (r128ctx->drawX + dPriv->x) * (r128scrn->bpp/8) + \ + (r128ctx->drawY + dPriv->y) * pitch); \ + char *read_buf = (char *)(r128scrn->fb + \ + (r128ctx->readX + dPriv->x) * (r128scrn->bpp/8)+\ + (r128ctx->readY + dPriv->y) * pitch); \ + GLushort p; \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ + r128ScreenPtr r128scrn = r128ctx->r128Screen; \ + __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ + GLuint pitch = r128scrn->fbStride; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(r128scrn->fb + \ + (r128scrn->depthX + dPriv->x) * (r128scrn->bpp/8) + \ + (r128scrn->depthY + dPriv->y) * pitch); \ + (void) buf + +#define INIT_MONO_PIXEL(p) \ + p = R128_CONTEXT(ctx)->Color + +#define CLIPPIXEL(_x, _y) \ + ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) + + +#define CLIPSPAN(_x, _y, _n, _x1, _n1, _i) \ + if (( _y < miny) || (_y >= maxy)) { \ + _n1 = 0, _x1 = x; \ + } else { \ + _n1 = _n; \ + _x1 = _x; \ + if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \ + if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \ + } + +#define Y_FLIP(_y) (height - _y - 1) + + +#define HW_LOCK() \ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ + LOCK_HARDWARE(r128ctx); \ + R128CCE_WAIT_FOR_IDLE(r128ctx); + +#define HW_CLIPLOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = r128ctx->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(r128ctx) + + + +/* 16 bit, RGB565 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] = 0xff; \ + } while (0) + +#define TAG(x) r128##x##_RGB565 +#include "spantmp.h" + + + +/* 15 bit, ARGB1555 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) << 2) | \ + ((b & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#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 >> 2) & 0xf8; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = (p & 0x8000) ? 0xff : 0; \ + } while (0) + +#define TAG(x) r128##x##_ARGB1555 +#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) + +#define TAG(x) r128##x##_16 +#include "depthtmp.h" + + + +/* 24 bit, RGB888 color spanline and pixel functions */ +#define WRITE_RGBA(_x, _y, r, g, b, a) \ + *(GLuint *)(buf + _x*3 + _y*pitch) = ((r << 16) | \ + (g << 8) | \ + (b << 0)) + +#define WRITE_PIXEL(_x, _y, p) \ + *(GLuint *)(buf + _x*3 + _y*pitch) = p + +#define READ_RGBA(rgba, _x, _y) \ + do { \ + GLuint p = *(GLuint *)(read_buf + _x*3 + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = 0xff; \ + } while (0) + +#define TAG(x) r128##x##_RGB888 +#include "spantmp.h" + + + +/* 24 bit depthbuffer functions */ +#define WRITE_DEPTH(_x, _y, d) \ + *(GLdepth *)(buf + _x*3 + _y*pitch) = d + +#define READ_DEPTH(d, _x, _y) \ + d = *(GLdepth *)(buf + _x*3 + _y*pitch) + +#define TAG(x) r128##x##_24 +#include "depthtmp.h" + + + +/* 32 bit, ARGB8888 color spanline and pixel functions */ +#define WRITE_RGBA(_x, _y, r, g, b, a) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \ + (g << 8) | \ + (b << 0) | \ + (a << 24) ) + +#define WRITE_PIXEL(_x, _y, p) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = p + +#define READ_RGBA(rgba, _x, _y) \ + do { \ + GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = (p >> 24) & 0xff; \ + } while (0) + +#define TAG(x) r128##x##_ARGB8888 +#include "spantmp.h" + + + +/* 32 bit depthbuffer functions */ +#define WRITE_DEPTH(_x, _y, d) \ + *(GLdepth *)(buf + _x*4 + _y*pitch) = d + +#define READ_DEPTH(d, _x, _y) \ + d = *(GLdepth *)(buf + _x*4 + _y*pitch) + +#define TAG(x) r128##x##_32 +#include "depthtmp.h" + + + +void r128DDInitSpanFuncs(GLcontext *ctx) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + switch (r128ctx->r128Screen->pixel_code) { + case 8: /* Color Index mode not supported */ + break; + + case 15: + ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB1555; + ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB1555; + ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB1555; + ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB1555; + ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB1555; + ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB1555; + ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB1555; + + ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16; + ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16; + ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_16; + ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_16; + break; + + case 16: + ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB565; + ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB565; + ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB565; + ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB565; + ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB565; + ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB565; + ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB565; + + ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16; + ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16; + ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_16; + ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_16; + break; + + case 24: + ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB888; + ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB888; + ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB888; + ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB888; + ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB888; + ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB888; + ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB888; + + ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_24; + ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_24; + ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_24; + ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_24; + break; + + case 32: + ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB8888; + ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB8888; + ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB8888; + ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB8888; + ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB8888; + ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB8888; + ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB8888; + + ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_32; + ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_32; + ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_32; + ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_32; + break; + + default: + break; + } + + 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/r128/r128_span.h b/xc/lib/GL/mesa/src/drv/r128/r128_span.h new file mode 100644 index 000000000..f83a4da9f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.h @@ -0,0 +1,44 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * Gareth Hughes <gareth@precisioninsight.com> + * + */ + +#ifndef _R128_SPAN_H_ +#define _R128_SPAN_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128DDInitSpanFuncs(GLcontext *ctx); + +#endif +#endif /* _R128_SPAN_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c new file mode 100644 index 000000000..3d1ceaa24 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c @@ -0,0 +1,1309 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_state.h" +#include "r128_reg.h" +#include "r128_cce.h" +#include "r128_tris.h" +#include "r128_vb.h" +#include "r128_tex.h" + +#include "mmath.h" + +#define INTERESTED (~(NEW_MODELVIEW | \ + NEW_PROJECTION | \ + NEW_TEXTURE_MATRIX | \ + NEW_USER_CLIP | \ + NEW_CLIENT_STATE | \ + NEW_TEXTURE_ENABLE)) + +static void r128DDUpdateState(GLcontext *ctx) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { + fprintf(stderr, "r128DDUpdateState(%p)\n", ctx); + } + + if (ctx->NewState & INTERESTED) { + r128ChooseRenderState(ctx); + r128ChooseRasterSetupFunc(ctx); + } + + if (!r128ctx->Fallback) { + ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + ctx->IndirectTriangles |= r128ctx->IndirectTriangles; + + ctx->Driver.PointsFunc = r128ctx->PointsFunc; + ctx->Driver.LineFunc = r128ctx->LineFunc; + ctx->Driver.TriangleFunc = r128ctx->TriangleFunc; + ctx->Driver.QuadFunc = r128ctx->QuadFunc; + ctx->Driver.RectFunc = NULL; + } +} + +static void r128DDUpdateHWState(GLcontext *ctx) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + /* FIXME: state is being updated too often */ + if (r128ctx->dirty) + r128UpdateHWState(r128ctx); +} + +static void r128DDReducedPrimitiveChange(GLcontext *ctx, GLenum prim) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + /* FIXME: Also need to flush between tris and tristrips/fans when we + support them directly */ + R128CCE_FLUSH_VB_LOCK(r128ctx); +} + +static void r128DDClearColor(GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + r128ctx->ClearColor = r128PackColor(r128ctx->r128Screen->depth, + r, g, b, a); +} + +static void r128DDColor(GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + r128ctx->Color = r128PackColor(r128ctx->r128Screen->depth, r, g, b, a); +} + +static GLboolean r128DDSetDrawBuffer(GLcontext *ctx, GLenum mode) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + int x = r128ctx->driDrawable->x; + int y = r128ctx->driDrawable->y; + int found; + + r128ctx->Fallback &= ~R128_FALLBACK_DRAW_BUFFER; + + switch (mode) { + case GL_FRONT_LEFT: + r128ctx->drawX = r128ctx->r128Screen->fbX; + r128ctx->drawY = r128ctx->r128Screen->fbY; + found = GL_TRUE; + break; + case GL_BACK_LEFT: + r128ctx->drawX = r128ctx->r128Screen->backX; + r128ctx->drawY = r128ctx->r128Screen->backY; + found = GL_TRUE; + break; + default: + r128ctx->Fallback |= R128_FALLBACK_DRAW_BUFFER; + found = GL_FALSE; + break; + } + + x += r128ctx->drawX; + y += r128ctx->drawY; + + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | + (x << R128_WINDOW_X_SHIFT)); + + /* Recalculate the Z buffer offset since we might be drawing to the + back buffer and window_xy_offset affects both color buffer and + depth drawing */ + r128ctx->regs.z_offset_c = ((r128ctx->r128Screen->depthX - + r128ctx->drawX) * + (r128ctx->r128Screen->bpp/8) + + (r128ctx->r128Screen->depthY - + r128ctx->drawY) * + r128ctx->r128Screen->fbStride); + + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_WIN_Z_POS; + return found; +} + +static void r128DDSetReadBuffer(GLcontext *ctx, + GLframebuffer *colorBuffer, + GLenum mode) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + r128ctx->Fallback &= ~R128_FALLBACK_READ_BUFFER; + + switch (mode) { + case GL_FRONT_LEFT: + r128ctx->readX = r128ctx->r128Screen->fbX; + r128ctx->readY = r128ctx->r128Screen->fbY; + break; + case GL_BACK_LEFT: + r128ctx->readX = r128ctx->r128Screen->backX; + r128ctx->readY = r128ctx->r128Screen->backY; + break; + default: + r128ctx->Fallback |= R128_FALLBACK_READ_BUFFER; + break; + } +} + +static GLboolean r128DDColorMask(GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + GLuint mask = r128PackColor(r128ctx->r128Screen->pixel_code, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + if (r128ctx->regs.plane_3d_mask_c != mask) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.plane_3d_mask_c = mask; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_MISC; + } + + return GL_TRUE; +} + +static void r128DDDither(GLcontext *ctx, GLboolean enable) +{ +} + +static void r128DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + CARD32 a = r128ctx->regs.misc_3d_state_cntl_reg; + + a &= ~(R128_ALPHA_TEST_MASK | R128_REF_ALPHA_MASK); + a |= ctx->Color.AlphaRef & R128_REF_ALPHA_MASK; + + switch (func) { + case GL_NEVER: a |= R128_ALPHA_TEST_NEVER; break; + case GL_LESS: a |= R128_ALPHA_TEST_LESS; break; + case GL_LEQUAL: a |= R128_ALPHA_TEST_LESSEQUAL; break; + case GL_EQUAL: a |= R128_ALPHA_TEST_EQUAL; break; + case GL_GEQUAL: a |= R128_ALPHA_TEST_GREATEREQUAL; break; + case GL_GREATER: a |= R128_ALPHA_TEST_GREATER; break; + case GL_NOTEQUAL: a |= R128_ALPHA_TEST_NEQUAL; break; + case GL_ALWAYS: a |= R128_ALPHA_TEST_ALWAYS; + break; + default: + /* ERROR!!! */ + return; + } + + if (r128ctx->regs.misc_3d_state_cntl_reg != a) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.misc_3d_state_cntl_reg = a; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ALPHASTATE; + } +} + +static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + CARD32 b = r128ctx->regs.misc_3d_state_cntl_reg; + + b &= ~(R128_ALPHA_BLEND_SRC_MASK | R128_ALPHA_BLEND_DST_MASK); + + switch (sfactor) { + case GL_ZERO: b |= R128_ALPHA_BLEND_SRC_ZERO; + break; + case GL_ONE: b |= R128_ALPHA_BLEND_SRC_ONE; + break; + case GL_DST_COLOR: b |= R128_ALPHA_BLEND_SRC_DESTCOLOR; + break; + case GL_ONE_MINUS_DST_COLOR: b |= R128_ALPHA_BLEND_SRC_INVDESTCOLOR; + break; + case GL_SRC_ALPHA: b |= R128_ALPHA_BLEND_SRC_SRCALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: b |= R128_ALPHA_BLEND_SRC_INVSRCALPHA; + break; + case GL_DST_ALPHA: b |= R128_ALPHA_BLEND_SRC_DESTALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_SRC_INVDESTALPHA; + break; + case GL_SRC_ALPHA_SATURATE: b |= R128_ALPHA_BLEND_SRC_SRCALPHASAT; + break; +#if 0 + /* FIXME: These are not supported directly by the Rage 128. + They could be emulated using something like the TexEnv + modes. */ + case GL_CONSTANT_COLOR: b |= 0; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0; + break; + case GL_CONSTANT_ALPHA: b |= 0; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: b |= 0; + break; +#endif + default: + /* ERROR!!! */ + return; + } + + switch (dfactor) { + case GL_ZERO: b |= R128_ALPHA_BLEND_DST_ZERO; + break; + case GL_ONE: b |= R128_ALPHA_BLEND_DST_ONE; + break; + case GL_SRC_COLOR: b |= R128_ALPHA_BLEND_DST_SRCCOLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: b |= R128_ALPHA_BLEND_DST_INVSRCCOLOR; + break; + case GL_SRC_ALPHA: b |= R128_ALPHA_BLEND_DST_SRCALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: b |= R128_ALPHA_BLEND_DST_INVSRCALPHA; + break; + case GL_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_DESTALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_INVDESTALPHA; + break; +#if 0 + /* FIXME: These are not supported directly by the Rage 128. + They could be emulated using something like the TexEnv + modes. */ + case GL_CONSTANT_COLOR: b |= 0; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0; + break; + case GL_CONSTANT_ALPHA: b |= 0; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: b |= 0; + break; +#endif + default: + /* ERROR!!! */ + return; + } + + if (r128ctx->regs.misc_3d_state_cntl_reg != b) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.misc_3d_state_cntl_reg = b; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ALPHASTATE; + } +} + +static void r128DDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, + GLenum dfactorA) +{ + if (sfactorRGB != sfactorA || dfactorRGB != dfactorA) { + /* ERROR!!! */ + return; + } + + r128DDBlendFunc(ctx, sfactorRGB, dfactorRGB); +} + +static void r128DDClearDepth(GLcontext *ctx, GLclampd d) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + switch (r128ctx->regs.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK) { + case R128_Z_PIX_WIDTH_16: r128ctx->ClearDepth = d * 0x0000ffff; break; + case R128_Z_PIX_WIDTH_24: r128ctx->ClearDepth = d * 0x00ffffff; break; + case R128_Z_PIX_WIDTH_32: r128ctx->ClearDepth = d * 0xffffffff; break; + default: return; + } +} + +static void r128DDCullFace(GLcontext *ctx, GLenum mode) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + CARD32 f = r128ctx->regs.pm4_vc_fpu_setup; + + if (!ctx->Polygon.CullFlag) return; + + f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK); + + switch (mode) { + case GL_FRONT: f |= R128_BACKFACE_SOLID; break; + case GL_BACK: f |= R128_FRONTFACE_SOLID; break; + case GL_FRONT_AND_BACK: break; + default: return; + } + + if (r128ctx->regs.pm4_vc_fpu_setup != f) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.pm4_vc_fpu_setup = f; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_SETUPSTATE; + } +} + +static void r128DDFrontFace(GLcontext *ctx, GLenum mode) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + CARD32 f = r128ctx->regs.pm4_vc_fpu_setup; + + f &= ~R128_FRONT_DIR_MASK; + + switch (mode) { + case GL_CW: f |= R128_FRONT_DIR_CW; break; + case GL_CCW: f |= R128_FRONT_DIR_CCW; break; + default: return; + } + + if (r128ctx->regs.pm4_vc_fpu_setup != f) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.pm4_vc_fpu_setup = f; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_SETUPSTATE; + } +} + +static void r128DDDepthFunc(GLcontext *ctx, GLenum func) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + CARD32 z = r128ctx->regs.z_sten_cntl_c; + + z &= ~R128_Z_TEST_MASK; + + switch (func) { + case GL_NEVER: z |= R128_Z_TEST_NEVER; break; + case GL_LESS: z |= R128_Z_TEST_LESS; break; + case GL_LEQUAL: z |= R128_Z_TEST_LESSEQUAL; break; + case GL_EQUAL: z |= R128_Z_TEST_EQUAL; break; + case GL_GEQUAL: z |= R128_Z_TEST_GREATEREQUAL; break; + case GL_GREATER: z |= R128_Z_TEST_GREATER; break; + case GL_NOTEQUAL: z |= R128_Z_TEST_NEQUAL; break; + case GL_ALWAYS: z |= R128_Z_TEST_ALWAYS; break; + default: return; + } + + if (r128ctx->regs.z_sten_cntl_c != z) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.z_sten_cntl_c = z; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ZSTENSTATE; + } +} + +static void r128DDDepthMask(GLcontext *ctx, GLboolean flag) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + CARD32 t = r128ctx->regs.tex_cntl_c; + + if (flag) t |= R128_Z_WRITE_ENABLE; + else t &= ~R128_Z_WRITE_ENABLE; + + if (r128ctx->regs.tex_cntl_c != t) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.tex_cntl_c = t; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ENGINESTATE; + } +} + +static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + CARD32 t = r128ctx->regs.tex_cntl_c; + CARD32 f = r128ctx->regs.pm4_vc_fpu_setup; + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { + fprintf(stderr, "r128DDEnable( %p, 0x%x = %s )\n", + ctx, cap, state ? "GL_TRUE" : "GL_FALSE"); + } + + switch (cap) { + case GL_ALPHA_TEST: + if (state) t |= R128_ALPHA_TEST_ENABLE; + else t &= ~R128_ALPHA_TEST_ENABLE; + break; + + case GL_AUTO_NORMAL: return; + + case GL_BLEND: + if (state) t |= R128_ALPHA_ENABLE; + else t &= ~R128_ALPHA_ENABLE; + break; + + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + case GL_COLOR_MATERIAL: return; + + case GL_CULL_FACE: + f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK); + if (state) { + switch (ctx->Polygon.CullFaceMode) { + case GL_FRONT: f |= R128_BACKFACE_SOLID; break; + case GL_BACK: f |= R128_FRONTFACE_SOLID; break; + case GL_FRONT_AND_BACK: break; + default: return; + } + } else { + f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID; + } + break; + + case GL_DEPTH_TEST: + if (state) t |= R128_Z_ENABLE; + else t &= ~R128_Z_ENABLE; + break; + + case GL_DITHER: + if (state) t |= R128_DITHER_ENABLE; + else t &= ~R128_DITHER_ENABLE; + break; + + case GL_FOG: + if (state) t |= R128_FOG_ENABLE; + else t &= ~R128_FOG_ENABLE; + break; + + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + case GL_LIGHTING: + case GL_LINE_SMOOTH: + case GL_LINE_STIPPLE: + case GL_INDEX_LOGIC_OP: + case GL_COLOR_LOGIC_OP: + case GL_MAP1_COLOR_4: + case GL_MAP1_INDEX: + case GL_MAP1_NORMAL: + case GL_MAP1_TEXTURE_COORD_1: + case GL_MAP1_TEXTURE_COORD_2: + case GL_MAP1_TEXTURE_COORD_3: + case GL_MAP1_TEXTURE_COORD_4: + case GL_MAP1_VERTEX_3: + case GL_MAP1_VERTEX_4: + case GL_MAP2_COLOR_4: + case GL_MAP2_INDEX: + case GL_MAP2_NORMAL: + case GL_MAP2_TEXTURE_COORD_1: + case GL_MAP2_TEXTURE_COORD_2: + case GL_MAP2_TEXTURE_COORD_3: + case GL_MAP2_TEXTURE_COORD_4: + case GL_MAP2_VERTEX_3: + case GL_MAP2_VERTEX_4: + case GL_NORMALIZE: + case GL_POINT_SMOOTH: + case GL_POLYGON_SMOOTH: + case GL_POLYGON_STIPPLE: + case GL_POLYGON_OFFSET_POINT: + case GL_POLYGON_OFFSET_LINE: + case GL_POLYGON_OFFSET_FILL: + case GL_RESCALE_NORMAL_EXT: return; + + case GL_SCISSOR_TEST: + /* FIXME: Hook up the software scissor */ +#if 0 + r128ctx->Scissor = state; +#endif + break; + + case GL_SHARED_TEXTURE_PALETTE_EXT: + case GL_STENCIL_TEST: return; + + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + /* This is handled in r128UpdateTex[01]State() */ + r128ctx->dirty |= R128_UPDATE_TEXSTATE; + break; + + case GL_TEXTURE_3D: + case GL_TEXTURE_GEN_Q: + case GL_TEXTURE_GEN_R: + case GL_TEXTURE_GEN_S: + case GL_TEXTURE_GEN_T: return; + + /* Client state */ + case GL_VERTEX_ARRAY: + case GL_NORMAL_ARRAY: + case GL_COLOR_ARRAY: + case GL_INDEX_ARRAY: + case GL_TEXTURE_COORD_ARRAY: + case GL_EDGE_FLAG_ARRAY: return; + + default: return; + } + + if (r128ctx->regs.tex_cntl_c != t) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.tex_cntl_c = t; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ENGINESTATE; + } + if (r128ctx->regs.pm4_vc_fpu_setup != f) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.pm4_vc_fpu_setup = f; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_SETUPSTATE; + } + +} + +static void r128DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + GLubyte c[4]; + CARD32 col; + floatTOint fog; + GLenum mode; + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { + fprintf(stderr, "r128DDFogfv(%p, 0x%x)\n", ctx, pname); + } + + switch (pname) { + case GL_FOG_MODE: + mode = (GLenum)(GLint)*param; + if (r128ctx->FogMode != mode) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->FogMode = mode; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_FOGTABLE; + } + break; + + case GL_FOG_DENSITY: + fog.f = *param; + if (r128ctx->regs.fog_3d_table_density != fog.i) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.fog_3d_table_density = fog.i; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_FOGSTATE; + } + break; + + case GL_FOG_START: + fog.f = *param; + if (r128ctx->regs.fog_3d_table_start != fog.i) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.fog_3d_table_start = fog.i; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_FOGSTATE; + } + break; + + case GL_FOG_END: + fog.f = *param; + if (r128ctx->regs.fog_3d_table_end != fog.i) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.fog_3d_table_end = fog.i; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_FOGSTATE; + } + break; + + case GL_FOG_COLOR: + FLOAT_RGBA_TO_UBYTE_RGBA(c, ctx->Fog.Color); + col = r128PackColor(32, c[0], c[1], c[2], c[3]); + if (r128ctx->regs.fog_color_c != col) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.fog_color_c = col; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_FOGSTATE; + } + break; + + default: + return; + } +} + +static void r128DDScissor(GLcontext *ctx, + GLint x, GLint y, GLsizei w, GLsizei h) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + r128ctx->ScissorRect.x1 = x; + r128ctx->ScissorRect.y1 = r128ctx->driDrawable->h - (y + h); + r128ctx->ScissorRect.x2 = x + w; + r128ctx->ScissorRect.y2 = r128ctx->driDrawable->h - y; +} + +/* Initialize the driver's state functions */ +void r128DDInitStateFuncs(GLcontext *ctx) +{ + ctx->Driver.UpdateState = r128DDUpdateState; + + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = r128DDClearColor; + ctx->Driver.Index = NULL; + ctx->Driver.Color = r128DDColor; + ctx->Driver.SetDrawBuffer = r128DDSetDrawBuffer; + ctx->Driver.SetReadBuffer = r128DDSetReadBuffer; + + ctx->Driver.IndexMask = NULL; + ctx->Driver.ColorMask = r128DDColorMask; + ctx->Driver.LogicOp = NULL; + ctx->Driver.Dither = r128DDDither; + + ctx->Driver.NearFar = NULL; + + ctx->Driver.RenderStart = r128DDUpdateHWState; + ctx->Driver.RenderFinish = NULL; + ctx->Driver.RasterSetup = NULL; + + ctx->Driver.RenderVBClippedTab = NULL; + ctx->Driver.RenderVBCulledTab = NULL; + ctx->Driver.RenderVBRawTab = NULL; + + ctx->Driver.ReducedPrimitiveChange = r128DDReducedPrimitiveChange; + ctx->Driver.MultipassFunc = NULL; + + ctx->Driver.AlphaFunc = r128DDAlphaFunc; + ctx->Driver.BlendEquation = NULL; + ctx->Driver.BlendFunc = r128DDBlendFunc; + ctx->Driver.BlendFuncSeparate = r128DDBlendFuncSeparate; + ctx->Driver.ClearDepth = r128DDClearDepth; + ctx->Driver.CullFace = r128DDCullFace; + ctx->Driver.FrontFace = r128DDFrontFace; + ctx->Driver.DepthFunc = r128DDDepthFunc; + ctx->Driver.DepthMask = r128DDDepthMask; + ctx->Driver.DepthRange = NULL; + ctx->Driver.Enable = r128DDEnable; + ctx->Driver.Fogfv = r128DDFogfv; + ctx->Driver.Hint = NULL; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LightModelfv = NULL; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.Scissor = r128DDScissor; + ctx->Driver.ShadeModel = NULL; + ctx->Driver.ClearStencil = NULL; + ctx->Driver.StencilFunc = NULL; + ctx->Driver.StencilMask = NULL; + ctx->Driver.StencilOp = NULL; + ctx->Driver.Viewport = NULL; +} + +/* Initialize the context's hardware state */ +void r128DDInitState(r128ContextPtr r128ctx) +{ + int dst_bpp, depth_bpp, pitch, i; + CARD32 depthClear; + + pitch = r128ctx->r128Screen->fbStride / r128ctx->r128Screen->bpp; + + switch (r128ctx->r128Screen->pixel_code) { + case 8: dst_bpp = R128_GMC_DST_8BPP_CI; break; + case 15: dst_bpp = R128_GMC_DST_15BPP; break; + case 16: dst_bpp = R128_GMC_DST_16BPP; break; + case 24: dst_bpp = R128_GMC_DST_24BPP; break; + case 32: dst_bpp = R128_GMC_DST_32BPP; break; + default: + fprintf(stderr, "Error: Unsupported pixel depth %d... exiting\n", + r128ctx->r128Screen->pixel_code); + exit(-1); + } + + /* FIXME: Figure out how to use 16bpp depth buffer in 32bpp mode */ + switch (r128ctx->glCtx->Visual->DepthBits) { + case 16: depthClear = 0x0000ffff; depth_bpp = R128_Z_PIX_WIDTH_16; break; + case 24: depthClear = 0x00ffffff; depth_bpp = R128_Z_PIX_WIDTH_24; break; + case 32: depthClear = 0xffffffff; depth_bpp = R128_Z_PIX_WIDTH_32; break; + default: + fprintf(stderr, "Error: Unsupported depth %d... exiting\n", + r128ctx->r128Screen->bpp); + exit(-1); + break; + } + + r128ctx->dirty = R128_ALL_DIRTY; + r128ctx->dirty_context = R128_CTX_ALL_DIRTY; + + r128ctx->RenderIndex = R128_FALLBACK_BIT; + r128ctx->PointsFunc = NULL; + r128ctx->LineFunc = NULL; + r128ctx->TriangleFunc = NULL; + r128ctx->QuadFunc = NULL; + + r128ctx->IndirectTriangles = 0; + r128ctx->Fallback = 0; + + if (r128ctx->glCtx->Visual->DBflag) { + r128ctx->drawX = r128ctx->r128Screen->backX; + r128ctx->drawY = r128ctx->r128Screen->backY; + r128ctx->readX = r128ctx->r128Screen->backX; + r128ctx->readY = r128ctx->r128Screen->backY; + } else { + r128ctx->drawX = r128ctx->r128Screen->fbX; + r128ctx->drawY = r128ctx->r128Screen->fbY; + r128ctx->readX = r128ctx->r128Screen->fbX; + r128ctx->readY = r128ctx->r128Screen->fbY; + } + + r128ctx->ClearColor = 0x00000000; + r128ctx->ClearDepth = depthClear; + + r128ctx->regs.scale_3d_cntl = + R128_SCALE_DITHER_TABLE | + R128_TEX_CACHE_SIZE_FULL | + R128_DITHER_INIT_RESET | + R128_SCALE_3D_TEXMAP_SHADE | + R128_SCALE_PIX_REPLICATE | + /* R128_TEX_CACHE_SPLIT | */ + R128_ALPHA_COMB_ADD_CLAMP | + R128_FOG_TABLE | + R128_ALPHA_BLEND_SRC_ONE | + R128_ALPHA_BLEND_DST_ZERO | + R128_ALPHA_TEST_ALWAYS | + R128_COMPOSITE_SHADOW_CMP_EQUAL | + R128_TEX_MAP_ALPHA_IN_TEXTURE | + R128_TEX_CACHE_LINE_SIZE_8QW; + + r128ctx->regs.dst_pitch_offset_c = pitch << R128_PITCH_SHIFT; + + r128ctx->regs.dp_gui_master_cntl = + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_DST_CLIPPING | + R128_GMC_BRUSH_SOLID_COLOR | + dst_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_GMC_BYTE_MSB_TO_LSB | + R128_GMC_CONVERSION_TEMP_6500 | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_3D_FCN_EN | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS; + + r128ctx->regs.sc_top_left_c = 0x00000000; + r128ctx->regs.sc_bottom_right_c = 0x1fff1fff; + + r128ctx->regs.aux_sc_cntl = 0x00000000; + + r128ctx->regs.aux1_sc_left = 0x00000000; + r128ctx->regs.aux1_sc_right = 0x00001fff; + r128ctx->regs.aux1_sc_top = 0x00000000; + r128ctx->regs.aux1_sc_bottom = 0x00001fff; + + r128ctx->regs.aux2_sc_left = 0x00000000; + r128ctx->regs.aux2_sc_right = 0x00001fff; + r128ctx->regs.aux2_sc_top = 0x00000000; + r128ctx->regs.aux2_sc_bottom = 0x00001fff; + + r128ctx->regs.aux3_sc_left = 0x00000000; + r128ctx->regs.aux3_sc_right = 0x00001fff; + r128ctx->regs.aux3_sc_top = 0x00000000; + r128ctx->regs.aux3_sc_bottom = 0x00001fff; + + r128ctx->regs.z_offset_c = (r128ctx->r128Screen->depthX * + (r128ctx->r128Screen->bpp/8) + + r128ctx->r128Screen->depthY * + r128ctx->r128Screen->fbStride); + r128ctx->regs.z_pitch_c = pitch; + + r128ctx->regs.z_sten_cntl_c = + depth_bpp | + R128_Z_TEST_LESS | + R128_STENCIL_TEST_ALWAYS | + R128_STENCIL_S_FAIL_KEEP | + R128_STENCIL_ZPASS_KEEP | + R128_STENCIL_ZFAIL_KEEP; + + r128ctx->regs.tex_cntl_c = + R128_Z_WRITE_ENABLE | + R128_SHADE_ENABLE | + R128_DITHER_ENABLE | + R128_ALPHA_IN_TEX_COMPLETE_A | + R128_LIGHT_DIS | + R128_ALPHA_LIGHT_DIS | + R128_TEX_CACHE_FLUSH | + (0x0f << R128_LOD_BIAS_SHIFT); + + r128ctx->regs.misc_3d_state_cntl_reg = + R128_MISC_SCALE_3D_TEXMAP_SHADE | + R128_MISC_SCALE_PIX_REPLICATE | + R128_ALPHA_COMB_ADD_CLAMP | + R128_FOG_TABLE | + R128_ALPHA_BLEND_SRC_ONE | + R128_ALPHA_BLEND_DST_ZERO | + R128_ALPHA_TEST_ALWAYS; + + r128ctx->regs.texture_clr_cmp_clr_c = 0x00000000; + r128ctx->regs.texture_clr_cmp_msk_c = 0xffffffff; + + r128ctx->regs.prim_tex_cntl_c = + R128_MIN_BLEND_NEAREST | + R128_MAG_BLEND_NEAREST | + R128_MIP_MAP_DISABLE | + R128_TEX_CLAMP_S_WRAP | + R128_TEX_CLAMP_T_WRAP; + + r128ctx->regs.prim_texture_combine_cntl_c = + R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA; + + r128ctx->regs.tex_size_pitch_c = + (0 << R128_TEX_PITCH_SHIFT) | + (0 << R128_TEX_SIZE_SHIFT) | + (0 << R128_TEX_HEIGHT_SHIFT) | + (0 << R128_TEX_MIN_SIZE_SHIFT) | + (0 << R128_SEC_TEX_PITCH_SHIFT) | + (0 << R128_SEC_TEX_SIZE_SHIFT) | + (0 << R128_SEC_TEX_HEIGHT_SHIFT) | + (0 << R128_SEC_TEX_MIN_SIZE_SHIFT); + + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.prim_tex_offset[i] = 0x00000000; + + r128ctx->regs.sec_tex_cntl_c = + R128_SEC_SELECT_PRIM_ST; + + r128ctx->regs.sec_tex_combine_cntl_c = + R128_COMB_DIS | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_DIS | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA; + + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.sec_tex_offset[i] = 0x00000000; + + r128ctx->regs.constant_color_c = 0x00ffffff; + r128ctx->regs.prim_texture_border_color_c = 0x00ffffff; + r128ctx->regs.sec_texture_border_color_c = 0x00ffffff; + r128ctx->regs.sten_ref_mask_c = 0xffff0000; + r128ctx->regs.plane_3d_mask_c = 0xffffffff; + + r128ctx->regs.setup_cntl = + R128_COLOR_GOURAUD | + R128_PRIM_TYPE_TRI | +#if 1 + /* FIXME: Let r128 multiply? */ + R128_TEXTURE_ST_MULT_W | +#else + /* FIXME: Or, pre multiply? */ + R128_TEXTURE_ST_DIRECT | +#endif + R128_STARTING_VERTEX_1 | + R128_ENDING_VERTEX_3 | + R128_SU_POLY_LINE_NOT_LAST | + R128_SUB_PIX_4BITS; + + r128ctx->regs.pm4_vc_fpu_setup = + R128_FRONT_DIR_CCW | + R128_BACKFACE_SOLID | + R128_FRONTFACE_SOLID | + R128_FPU_COLOR_GOURAUD | + R128_FPU_SUB_PIX_4BITS | + R128_FPU_MODE_3D | + R128_TRAP_BITS_DISABLE | + R128_XFACTOR_2 | + R128_YFACTOR_2 | + R128_FLAT_SHADE_VERTEX_OGL | + R128_FPU_ROUND_TRUNCATE | + R128_WM_SEL_8DW; + + r128ctx->FogMode = GL_EXP; + r128ctx->regs.fog_color_c = 0x00808080; + r128ctx->regs.fog_3d_table_start = 0x00000000; + r128ctx->regs.fog_3d_table_end = 0xffffffff; + r128ctx->regs.fog_3d_table_density = 0x00000000; + + r128ctx->regs.window_xy_offset = 0x00000000; + + r128ctx->regs.dp_write_mask = 0xffffffff; + + r128ctx->regs.pc_gui_ctlstat = R128_PC_FLUSH_GUI; + + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ALL_DIRTY; +} + +/* Upload the fog table for the current fog mode */ +static void r128UploadFogTable(r128ContextPtr r128ctx) +{ + int i; + + R128CCE0(R128_CCE_PACKET0, R128_FOG_TABLE_INDEX, 0); + R128CCE(0x00000000); + + R128CCE0(R128_CCE_PACKET0_ONE_REG_WR, R128_FOG_TABLE_DATA, 255); + + switch (r128ctx->FogMode) { + case GL_LINEAR: + for (i = 0; i < 256; i++) { + R128CCE(255 - i); + } + break; + case GL_EXP: + for (i = 0; i < 256; i++) { + R128CCE(255 - FLOAT_TO_UBYTE(exp(i - 255))); + } + break; + case GL_EXP2: + for (i = 0; i < 256; i++) { + R128CCE(255 - FLOAT_TO_UBYTE(exp((i - 255) * (i - 255)))); + } + break; + } +} + +/* Load the current context's state into the hardware */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128LoadContext(r128ContextPtr r128ctx) +{ + int i; + int tex_size_pitch_done = GL_FALSE; + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { + fprintf(stderr, "r128LoadContext(%p)\n", r128ctx->glCtx); + } + +#if 0 + r128ctx->dirty_context = R128_CTX_ALL_DIRTY; +#endif + +#if 1 + /* FIXME: Why do these need to be updated even when they don't change? */ + r128ctx->dirty_context |= (R128_CTX_MISC | + R128_CTX_ENGINESTATE | + R128_CTX_ALPHASTATE); +#endif + +#if 1 + /* FIXME: Is this _really_ needed? */ + if (r128ctx->dirty_context) + if (!R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode)) + R128CCE_WAIT_FOR_IDLE(r128ctx); +#endif + + if (r128ctx->dirty_context & R128_CTX_MISC) { + R128CCE1(R128_CCE_PACKET1, R128_SCALE_3D_CNTL, R128_DP_WRITE_MASK); + R128CCE(r128ctx->regs.scale_3d_cntl); + R128CCE(r128ctx->regs.dp_write_mask); + + R128CCE0(R128_CCE_PACKET0, R128_DST_PITCH_OFFSET_C, 1); + R128CCE(r128ctx->regs.dst_pitch_offset_c); + R128CCE(r128ctx->regs.dp_gui_master_cntl); + + R128CCE0(R128_CCE_PACKET0, R128_TEXTURE_CLR_CMP_CLR_C, 1); + R128CCE(r128ctx->regs.texture_clr_cmp_clr_c); + R128CCE(r128ctx->regs.texture_clr_cmp_msk_c); + + R128CCE0(R128_CCE_PACKET0, R128_STEN_REF_MASK_C, 1); + R128CCE(r128ctx->regs.sten_ref_mask_c); + R128CCE(r128ctx->regs.plane_3d_mask_c); + } + + if (r128ctx->dirty_context & R128_CTX_ENGINESTATE) { + R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0); + R128CCE(r128ctx->regs.tex_cntl_c); + } + + if (r128ctx->dirty_context & R128_CTX_TEX0STATE) { + R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEX_CNTL_C, 2+R128_TEX_MAXLEVELS); + R128CCE(r128ctx->regs.prim_tex_cntl_c); + R128CCE(r128ctx->regs.prim_texture_combine_cntl_c); + R128CCE(r128ctx->regs.tex_size_pitch_c); + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + R128CCE(r128ctx->regs.prim_tex_offset[i]); + + R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEXTURE_BORDER_COLOR_C, 0); + R128CCE(r128ctx->regs.prim_texture_border_color_c); + + tex_size_pitch_done = GL_TRUE; + } + + if (r128ctx->dirty_context & R128_CTX_TEX1STATE) { + if (!tex_size_pitch_done) { + R128CCE0(R128_CCE_PACKET0, R128_TEX_SIZE_PITCH_C, 0); + R128CCE(r128ctx->regs.tex_size_pitch_c); + } + + R128CCE0(R128_CCE_PACKET0, R128_SEC_TEX_CNTL_C, 1+R128_TEX_MAXLEVELS); + R128CCE(r128ctx->regs.sec_tex_cntl_c); + R128CCE(r128ctx->regs.sec_tex_combine_cntl_c); + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + R128CCE(r128ctx->regs.sec_tex_offset[i]); + + R128CCE0(R128_CCE_PACKET0, R128_SEC_TEXTURE_BORDER_COLOR_C, 0); + R128CCE(r128ctx->regs.sec_texture_border_color_c); + } + + if (r128ctx->dirty_context & R128_CTX_TEXENVSTATE) { + R128CCE0(R128_CCE_PACKET0, R128_CONSTANT_COLOR_C, 0); + R128CCE(r128ctx->regs.constant_color_c); + } + + if (r128ctx->dirty_context & R128_CTX_FOGSTATE) { + R128CCE0(R128_CCE_PACKET0, R128_FOG_3D_TABLE_START, 1); + R128CCE(r128ctx->regs.fog_3d_table_start); + R128CCE(r128ctx->regs.fog_3d_table_end); + + R128CCE1(R128_CCE_PACKET1, + R128_FOG_COLOR_C, R128_FOG_3D_TABLE_DENSITY); + R128CCE(r128ctx->regs.fog_color_c); + R128CCE(r128ctx->regs.fog_3d_table_density); + } + + if (r128ctx->dirty_context & R128_CTX_FOGTABLE) { + r128UploadFogTable(r128ctx); + } + + if (r128ctx->dirty_context & R128_CTX_ZSTENSTATE) { + R128CCE0(R128_CCE_PACKET0, R128_Z_STEN_CNTL_C, 0); + R128CCE(r128ctx->regs.z_sten_cntl_c); + } + + if (r128ctx->dirty_context & R128_CTX_SCISSORS) { + R128CCE0(R128_CCE_PACKET0, R128_SC_TOP_LEFT_C, 1); + R128CCE(r128ctx->regs.sc_top_left_c); + R128CCE(r128ctx->regs.sc_bottom_right_c); + } + + if (r128ctx->dirty_context & (R128_CTX_ALPHASTATE | + R128_CTX_FOGSTATE)) { + R128CCE0(R128_CCE_PACKET0, R128_MISC_3D_STATE_CNTL_REG, 0); + R128CCE(r128ctx->regs.misc_3d_state_cntl_reg); + } + + if (r128ctx->dirty_context & R128_CTX_SETUPSTATE) { + R128CCE1(R128_CCE_PACKET1, R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP); + R128CCE(r128ctx->regs.setup_cntl); + R128CCE(r128ctx->regs.pm4_vc_fpu_setup); + } + + if (r128ctx->dirty_context & R128_CTX_WIN_Z_POS) { + R128CCE0(R128_CCE_PACKET0, R128_WINDOW_XY_OFFSET, 0); + R128CCE(r128ctx->regs.window_xy_offset); + + R128CCE0(R128_CCE_PACKET0, R128_Z_OFFSET_C, 1); + R128CCE(r128ctx->regs.z_offset_c); + R128CCE(r128ctx->regs.z_pitch_c); + } + +#if 0 + if (r128ctx->dirty_context & R128_CTX_FLUSH_PIX_CACHE) { + R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0); + R128CCE(r128ctx->regs.pc_gui_ctlstat); + } +#endif + + R128CCE_SUBMIT_PACKETS(); + + /* Turn off the texture cache flushing */ + r128ctx->regs.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; + + /* Turn off the pixel cache flushing */ + r128ctx->regs.pc_gui_ctlstat &= ~R128_PC_FLUSH_ALL; + + r128ctx->dirty_context = R128_CTX_CLEAN; +} + +/* Set the hardware clip rects for drawing to the current color buffer */ +/* NOTE: This function is only called while holding the hardware lock */ +void r128SetClipRects(r128ContextPtr r128ctx, + XF86DRIClipRectPtr pc, int nc) +{ + if (!pc) return; + + /* Clear any previous auxiliary scissors */ + r128ctx->regs.aux_sc_cntl = 0x00000000; + + switch (nc) { + case 3: + R128CCE0(R128_CCE_PACKET0, R128_AUX3_SC_LEFT, 3); + R128CCE(pc[2].x1 + r128ctx->drawX); + R128CCE(pc[2].x2-1 + r128ctx->drawX); + R128CCE(pc[2].y1 + r128ctx->drawY); + R128CCE(pc[2].y2-1 + r128ctx->drawY); + + r128ctx->regs.aux_sc_cntl |= R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR; + + case 2: + R128CCE0(R128_CCE_PACKET0, R128_AUX2_SC_LEFT, 3); + R128CCE(pc[1].x1 + r128ctx->drawX); + R128CCE(pc[1].x2-1 + r128ctx->drawX); + R128CCE(pc[1].y1 + r128ctx->drawY); + R128CCE(pc[1].y2-1 + r128ctx->drawY); + + r128ctx->regs.aux_sc_cntl |= R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR; + + case 1: + R128CCE0(R128_CCE_PACKET0, R128_AUX1_SC_LEFT, 3); + R128CCE(pc[0].x1 + r128ctx->drawX); + R128CCE(pc[0].x2-1 + r128ctx->drawX); + R128CCE(pc[0].y1 + r128ctx->drawY); + R128CCE(pc[0].y2-1 + r128ctx->drawY); + + r128ctx->regs.aux_sc_cntl |= R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR; + break; + + default: + return; + } + + R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0); + R128CCE(r128ctx->regs.aux_sc_cntl); + + R128CCE_SUBMIT_PACKETS(); +} + +/* Update the driver's notion of the window position */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128UpdateWindowPosition(r128ContextPtr r128ctx) +{ + int x = r128ctx->driDrawable->x + r128ctx->drawX; + int y = r128ctx->driDrawable->y + r128ctx->drawY; + +#if 0 + /* FIXME: Is this _really_ needed? */ + R128CCE_FLUSH_VB(r128ctx); +#endif + r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | + (x << R128_WINDOW_X_SHIFT)); + + /* Recalculate the Z buffer offset since we might be drawing to the + back buffer and window_xy_offset affects both color buffer and + depth drawing */ + r128ctx->regs.z_offset_c = ((r128ctx->r128Screen->depthX - + r128ctx->drawX) * + (r128ctx->r128Screen->bpp/8) + + (r128ctx->r128Screen->depthY - + r128ctx->drawY) * + r128ctx->r128Screen->fbStride); + + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_WIN_Z_POS; +} + +/* Update the hardware state */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128UpdateHWStateLocked(r128ContextPtr r128ctx) +{ + if (r128ctx->dirty & R128_REQUIRE_QUIESCENCE) + R128CCE_WAIT_FOR_IDLE(r128ctx); + + /* Update any state that might have changed recently */ + + /* Update the clip rects */ + if (r128ctx->dirty & R128_UPDATE_WINPOS) + r128UpdateWindowPosition(r128ctx); + + /* Update texture state and then upload the images */ + /* Note: Texture images can only be updated after the state has been set */ + if (r128ctx->dirty & R128_UPDATE_TEXSTATE) + r128UpdateTextureState(r128ctx); + if (r128ctx->dirty & R128_UPDATE_TEX0IMAGES) + r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[0]); + if (r128ctx->dirty & R128_UPDATE_TEX1IMAGES) + r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[1]); + + /* Load the state into the hardware */ + /* Note: This must be done after all other state has been set */ + if (r128ctx->dirty & R128_UPDATE_CONTEXT) + r128LoadContext(r128ctx); + + r128ctx->dirty = R128_CLEAN; +} + +/* Update the hardware state */ +void r128UpdateHWState(r128ContextPtr r128ctx) +{ + LOCK_HARDWARE(r128ctx); + r128UpdateHWStateLocked(r128ctx); + UNLOCK_HARDWARE(r128ctx); +} + +/* Update the driver's state */ +/* NOTE: This function is only called while holding the hardware lock */ +void r128UpdateState(r128ContextPtr r128ctx, int winMoved) +{ + R128SAREAPrivPtr sarea = r128ctx->r128Screen->SAREA; + int i; + + if (sarea->ctxOwner != r128ctx->driContext->hHWContext) { + sarea->ctxOwner = r128ctx->driContext->hHWContext; + r128ctx->dirty_context = R128_CTX_ALL_DIRTY; + r128LoadContext(r128ctx); + } + + for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++) + r128AgeTextures(r128ctx, i); + + if (winMoved) r128ctx->dirty |= R128_UPDATE_WINPOS; +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.h b/xc/lib/GL/mesa/src/drv/r128/r128_state.h new file mode 100644 index 000000000..f847452f0 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.h @@ -0,0 +1,50 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_STATE_H_ +#define _R128_STATE_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128DDInitState(r128ContextPtr r128ctx); +extern void r128DDInitStateFuncs(GLcontext *ctx); + +extern void r128UpdateState(r128ContextPtr r128ctx, int winMoved); +extern void r128UpdateHWState(r128ContextPtr r128ctx); + +extern void r128SetClipRects(r128ContextPtr r128ctx, + XF86DRIClipRectPtr pc, int nc); + +#endif +#endif /* _R128_STATE_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_swap.c b/xc/lib/GL/mesa/src/drv/r128/r128_swap.c new file mode 100644 index 000000000..6b347023d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_swap.c @@ -0,0 +1,125 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_reg.h" +#include "r128_cce.h" +#include "r128_state.h" +#include "r128_vb.h" +#include "r128_swap.h" + +/* Copy the back color buffer to the front color buffer */ +void r128SwapBuffers(r128ContextPtr r128ctx) +{ + unsigned char *R128MMIO = r128ctx->r128Screen->mmio; + __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; + int nc; + XF86DRIClipRectPtr c; + int dst_bpp; + CARD32 swapAge; + + if (r128ctx->SWonly) { + /* FIXME: Provide software fallback for this case?? */ + } + + switch (r128ctx->r128Screen->bpp) { + case 8: + dst_bpp = R128_GMC_DST_8BPP_CI; + break; + case 16: + if (r128ctx->r128Screen->depth == 15) dst_bpp = R128_GMC_DST_15BPP; + else dst_bpp = R128_GMC_DST_16BPP; + break; + case 24: + dst_bpp = R128_GMC_DST_24BPP; + break; + case 32: + default: + dst_bpp = R128_GMC_DST_32BPP; + break; + } + + LOCK_HARDWARE(r128ctx); + + /* Flush any outstanding vertex buffers */ + R128CCE_FLUSH_VB(r128ctx); + + /* Throttle the frame rate -- only allow one pending swap buffers + request at a time */ + while (r128ctx->lastSwapAge > (swapAge = INREG(R128_SWAP_AGE_REG))); + + /* Init the clip rects here in case they changed during the + LOCK_HARDWARE macro */ + c = dPriv->pClipRects; + nc = dPriv->numClipRects; + + /* Cycle through the clip rects */ + while (nc--) { + int fx = c[nc].x1; + int fy = c[nc].y1; + int fw = c[nc].x2 - fx; + int fh = c[nc].y2 - fy; + int bx = fx + r128ctx->r128Screen->backX; + int by = fy + r128ctx->r128Screen->backY; + + fx += r128ctx->r128Screen->fbX; + fy += r128ctx->r128Screen->fbY; + + R128CCE3(R128_CCE_PACKET3_CNTL_BITBLT_MULTI, 3); + R128CCE(R128_GMC_BRUSH_NONE + | R128_GMC_SRC_DATATYPE_COLOR + | R128_DP_SRC_SOURCE_MEMORY + | dst_bpp + | R128_ROP3_S); + R128CCE((bx << 16) | by); + R128CCE((fx << 16) | fy); + R128CCE((fw << 16) | fh); + } + + ++swapAge; + R128CCE0(R128_CCE_PACKET0, R128_SWAP_AGE_REG, 0); + R128CCE(swapAge); + r128ctx->lastSwapAge = swapAge; + + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ALL_DIRTY; + + R128CCE_SUBMIT_PACKETS(); + + UNLOCK_HARDWARE(r128ctx); +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_swap.h b/xc/lib/GL/mesa/src/drv/r128/r128_swap.h new file mode 100644 index 000000000..32851041c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_swap.h @@ -0,0 +1,43 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_SWAP_H_ +#define _R128_SWAP_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128SwapBuffers(r128ContextPtr r128ctx); + +#endif +#endif /* _R128_SWAP_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c new file mode 100644 index 000000000..d75345404 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c @@ -0,0 +1,1851 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * Gareth Hughes <gareth@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_state.h" +#include "r128_reg.h" +#include "r128_cce.h" +#include "r128_vb.h" +#include "r128_tex.h" + +#include "mmath.h" +#include "simple_list.h" + +static void r128SetTexWrap(r128TexObjPtr t, GLenum srwap, GLenum twrap); +static void r128SetTexFilter(r128TexObjPtr t, GLenum minf, GLenum magf); +static void r128SetTexBorderColor(r128TexObjPtr t, GLubyte c[4]); + +/* Allocate and initialize hardware state associated with texture `t' */ +/* NOTE: This function is only called while holding the hardware lock */ +static r128TexObjPtr r128CreateTexObj(r128ContextPtr r128ctx, + struct gl_texture_object *tObj) +{ + r128TexObjPtr t; + struct gl_texture_image *image; + int log2Pitch, log2Height, log2Size, log2MinSize; + int totalSize; + int i; + + image = tObj->Image[0]; + if (!image) return NULL; /* ERROR!!! */ + + t = (r128TexObjPtr)calloc(1,sizeof(*t)); + if (!t) return NULL; /* ERROR!!! */ + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) + fprintf(stderr, "r128CreateTexObj(%p)\n", tObj); + + switch (image->Format) { + case GL_RGBA: + case GL_ALPHA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + if (r128ctx->r128Screen->bpp == 32) { + t->texelBytes = 4; + t->textureFormat = R128_DATATYPE_ARGB8888; + } else { + t->texelBytes = 2; + t->textureFormat = R128_DATATYPE_ARGB4444; + } + break; + + case GL_RGB: + if (r128ctx->r128Screen->bpp == 32) { + t->texelBytes = 4; + t->textureFormat = R128_DATATYPE_ARGB8888; + } else { + t->texelBytes = 2; + t->textureFormat = R128_DATATYPE_RGB565; + } + break; + + case GL_LUMINANCE: + if (r128ctx->r128Screen->bpp == 32) { + t->texelBytes = 4; + t->textureFormat = R128_DATATYPE_ARGB8888; + } else { + t->texelBytes = 2; + /* Use this to get true greys */ + t->textureFormat = R128_DATATYPE_ARGB1555; + } + break; + + case GL_COLOR_INDEX: + t->texelBytes = 1; + t->textureFormat = R128_DATATYPE_CI8; + break; + + default: + /* ERROR!!! */ + fprintf(stderr, "r128CreateTexObj: bad image->Format\n"); + free(t); + return NULL; + } + + /* Calculate dimensions in log domain */ + for (i = 1, log2Height = 0; i < image->Height; i *= 2) log2Height++; + for (i = 1, log2Pitch = 0; i < image->Width; i *= 2) log2Pitch++; + if (image->Width > image->Height) log2Size = log2Pitch; + else log2Size = log2Height; + + t->dirty_images = 0; + + /* Calculate mipmap offsets and dimensions */ + totalSize = 0; + for (i = 0; i <= log2Size && tObj->Image[i]; i++) { + t->image[i].offset = totalSize; + t->image[i].width = tObj->Image[i]->Width; + t->image[i].height = tObj->Image[i]->Height; + t->dirty_images |= 1 << i; + totalSize += (tObj->Image[i]->Height * + tObj->Image[i]->Width * + t->texelBytes); + + /* Offsets must be 32-byte aligned for host data blits */ + totalSize = (totalSize + 31) & ~31; + } + log2MinSize = log2Size - i + 1; + + t->totalSize = totalSize; + t->internFormat = image->IntFormat; + + t->bound = 0; + t->heap = 0; /* This is set in r128UploadTexImages */ + t->tObj = tObj; + + t->memBlock = NULL; + t->bufAddr = NULL; + + t->regs.tex_cntl = t->textureFormat; + t->regs.size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) | + (log2Size << R128_TEX_SIZE_SHIFT) | + (log2Height << R128_TEX_HEIGHT_SHIFT) | + (log2MinSize << R128_TEX_MIN_SIZE_SHIFT)); + t->regs.border_color = 0x00000000; + + if (log2MinSize == log2Size || + log2MinSize != 0) + t->regs.tex_cntl |= R128_MIP_MAP_DISABLE; + + r128SetTexWrap(t, tObj->WrapS, tObj->WrapT); + r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter); + r128SetTexBorderColor(t, tObj->BorderColor); + + tObj->DriverData = t; + + make_empty_list(t); + + return t; +} + +/* Destroy hardware state associated with texture `t' */ +/* NOTE: This function can be called while holding the hardware lock and + while not holding the lock*/ +void r128DestroyTexObj(r128ContextPtr r128ctx, r128TexObjPtr t) +{ + if (!t) return; + + if (t->memBlock) { + mmFreeMem(t->memBlock); + t->memBlock = NULL; + } + + if (t->tObj) t->tObj->DriverData = NULL; + if (t->bound) r128ctx->CurrentTexObj[t->bound-1] = NULL; + + remove_from_list(t); + free(t); +} + +/* Keep track of swapped out texture objects */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128SwapOutTexObj(r128ContextPtr r128ctx, r128TexObjPtr t) +{ + if (t->memBlock) { + mmFreeMem(t->memBlock); + t->memBlock = NULL; + } + + t->dirty_images = ~0; + move_to_tail(&r128ctx->SwappedOut, t); +} + +/* Print out debugging information about texture LRU */ +void r128PrintLocalLRU(r128ContextPtr r128ctx, int heap) +{ + r128TexObjPtr t; + int sz = 1 << (r128ctx->r128Screen->log2TexGran[heap]); + + foreach(t, &r128ctx->TexObjList[heap]) { + if (!t->tObj) { + fprintf(stderr, "Placeholder %d at 0x%x sz 0x%x\n", + t->memBlock->ofs / sz, + t->memBlock->ofs, + t->memBlock->size); + } else { + fprintf(stderr, "Texture (bound %d) at 0x%x sz 0x%x\n", + t->bound, + t->memBlock->ofs, + t->memBlock->size); + } + } +} + +void r128PrintGlobalLRU(r128ContextPtr r128ctx, int heap) +{ + R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap]; + int i, j; + + for (i = 0, j = R128_NR_TEX_REGIONS ; i < R128_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 == R128_NR_TEX_REGIONS) break; + } + + if (j != R128_NR_TEX_REGIONS) { + fprintf(stderr, "Loop detected in global LRU\n"); + } +} + +/* Reset the global texture LRU */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128ResetGlobalLRU(r128ContextPtr r128ctx, int heap) +{ + R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap]; + int log2sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; + int i; + + /* + * (Re)initialize the global circular LRU list. The last element in + * the array (R128_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) * log2sz <= r128ctx->r128Screen->texSize[heap]; i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = R128_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = R128_NR_TEX_REGIONS; + list[R128_NR_TEX_REGIONS].prev = i; + list[R128_NR_TEX_REGIONS].next = 0; + r128ctx->r128Screen->SAREA->texAge[heap] = 0; +} + +/* Update the local and glock texture LRUs */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128UpdateTexLRU(r128ContextPtr r128ctx, r128TexObjPtr t) +{ + int heap = t->heap; + R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap]; + int log2sz = r128ctx->r128Screen->log2TexGran[heap]; + + int start = t->memBlock->ofs >> log2sz; + int end = (t->memBlock->ofs + t->memBlock->size-1) >> log2sz; + int i; + + r128ctx->lastTexAge[heap] = ++r128ctx->r128Screen->SAREA->texAge[heap]; + + /* Update our local LRU */ + move_to_head(&r128ctx->TexObjList[heap], t); + + /* Update the global LRU */ + for (i = start ; i <= end ; i++) { + list[i].in_use = 1; + list[i].age = r128ctx->lastTexAge[heap]; + + /* remove_from_list(i) */ + list[(CARD32)list[i].next].prev = list[i].prev; + list[(CARD32)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) */ + list[i].prev = R128_NR_TEX_REGIONS; + list[i].next = list[R128_NR_TEX_REGIONS].next; + list[(CARD32)list[R128_NR_TEX_REGIONS].next].prev = i; + list[R128_NR_TEX_REGIONS].next = i; + } +} + +/* Update our notion of what textures have been changed since we last + held the lock. This pertains to both our local textures and the + textures belonging to other clients. Keep track of other client's + textures by pushing a placeholder texture onto the LRU list -- these + are denoted by (tObj == NULL). */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128TexturesGone(r128ContextPtr r128ctx, int heap, + int offset, int size, int in_use) +{ + r128TexObjPtr t, tmp; + + foreach_s (t, tmp, &r128ctx->TexObjList[heap]) { + if (t->memBlock->ofs >= offset + size || + t->memBlock->ofs + t->memBlock->size <= offset) + continue; + + /* It overlaps - kick it out. Need to hold onto the currently + bound objects, however. */ + if (t->bound) r128SwapOutTexObj(r128ctx, t); + else r128DestroyTexObj(r128ctx, t); + } + + if (in_use) { + t = (r128TexObjPtr) calloc(1,sizeof(*t)); + if (!t) return; + + t->memBlock = mmAllocMem(r128ctx->texHeap[heap], size, 0, offset); + insert_at_head(&r128ctx->TexObjList[heap], t); + } +} + +/* Update our client's shared texture state. If another client has + modified a region in which we have textures, then we need to figure + out which of our textures has been removed, and update our global + LRU. */ +void r128AgeTextures(r128ContextPtr r128ctx, int heap) +{ + R128SAREAPrivPtr sarea = r128ctx->r128Screen->SAREA; + + if (sarea->texAge[heap] != r128ctx->lastTexAge[heap]) { + int log2sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; + int nr = 0; + int idx; + + for (idx = sarea->texList[heap][R128_NR_TEX_REGIONS].prev; + idx != R128_NR_TEX_REGIONS && nr < R128_NR_TEX_REGIONS; + idx = sarea->texList[heap][idx].prev, nr++) { + + /* If switching texturing schemes, then the SAREA might not + have been properly cleared, so we need to reset the + global texture LRU. */ + if (idx * log2sz > r128ctx->r128Screen->texSize[heap]) { + nr = R128_NR_TEX_REGIONS; + break; + } + + if (sarea->texList[heap][idx].age > r128ctx->lastTexAge[heap]) + r128TexturesGone(r128ctx, heap, idx * log2sz, log2sz, + sarea->texList[heap][idx].in_use); + } + + if (nr == R128_NR_TEX_REGIONS) { + r128TexturesGone(r128ctx, heap, + 0, r128ctx->r128Screen->texSize[heap], 0); + r128ResetGlobalLRU(r128ctx, heap); + } + + r128ctx->dirty |= R128_UPDATE_TEX0IMAGES; + r128ctx->dirty |= R128_UPDATE_TEX1IMAGES; + r128ctx->lastTexAge[heap] = sarea->texAge[heap]; + } +} + +/* Convert a block of Mesa-formatted texture to an 8bpp hardware format */ +static void r128ConvertTexture8bpp(r128ContextPtr r128ctx, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch) +{ + CARD8 *src; + CARD32 pix; + int i, j; + + switch (image->Format) { + case GL_RGB: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for (j = width >> 2; j; j--) { + pix = ((R128PACKCOLOR332( src[0], src[1], src[2]) ) | + (R128PACKCOLOR332( src[3], src[4], src[5]) << 8) | + (R128PACKCOLOR332( src[6], src[7], src[8]) << 16) | + (R128PACKCOLOR332( src[9], src[10], src[11]) << 24)); + R128CCE(pix); + src += 12; + } + } + break; + + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_COLOR_INDEX: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for (j = width >> 2; j; j--) { + pix = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + R128CCE(pix); + src += 4; + } + } + break; + + default: + fprintf(stderr, "r128ConvertTexture8bpp: unsupported format 0x%x\n", + image->Format); + } +} + +/* Convert a block of Mesa-formatted texture to a 16bpp hardware format */ +static void r128ConvertTexture16bpp(r128ContextPtr r128ctx, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch) +{ + CARD8 *src; + CARD32 pix; + int i, j; + + switch (image->Format) { + case GL_RGB: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for (j = width >> 1; j; j--) { + pix = ((R128PACKCOLOR565(src[0], src[1], src[2]) ) | + (R128PACKCOLOR565(src[3], src[4], src[5]) << 16)); + R128CCE(pix); + src += 6; + } + } + break; + + case GL_RGBA: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; + for (j = width >> 1; j; j--) { + pix = + ((R128PACKCOLOR4444(src[0], src[1], src[2], src[3]) ) | + (R128PACKCOLOR4444(src[4], src[5], src[6], src[7])<<16)); + R128CCE(pix); + src += 8; + } + } + break; + + case GL_ALPHA: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for (j = width >> 1; j; j--) { + pix = ((R128PACKCOLOR4444(0xff, 0xff, 0xff, src[0]) ) | + (R128PACKCOLOR4444(0xff, 0xff, 0xff, src[1]) << 16)); + R128CCE(pix); + src += 2; + } + } + break; + + case GL_LUMINANCE: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for (j = width >> 1; j; j--) { + pix = ((R128PACKCOLOR1555(src[0], src[0], src[0], 0xff) ) | + (R128PACKCOLOR1555(src[1], src[1], src[1], 0xff)<<16)); + R128CCE(pix); + src += 2; + } + } + break; + + case GL_LUMINANCE_ALPHA: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2; + for (j = width >> 1; j; j--) { + pix = + ((R128PACKCOLOR4444(src[0], src[0], src[0], src[1]) ) | + (R128PACKCOLOR4444(src[2], src[2], src[2], src[3])<<16)); + R128CCE(pix); + src += 4; + } + } + break; + + case GL_INTENSITY: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for (j = width >> 1; j; j--) { + pix = + ((R128PACKCOLOR4444(src[0], src[0], src[0], src[0]) ) | + (R128PACKCOLOR4444(src[1], src[1], src[1], src[1])<<16)); + R128CCE(pix); + src += 2; + } + } + break; + + default: + fprintf(stderr, "r128ConvertTexture16bpp: unsupported format 0x%x\n", + image->Format); + } +} + +/* Convert a block of Mesa-formatted texture to a 32bpp hardware format */ +static void r128ConvertTexture32bpp(r128ContextPtr r128ctx, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch) +{ + CARD8 *src; + CARD32 pix; + int i, j; + + switch (image->Format) { + case GL_RGB: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for (j = width; j; j--) { + pix = R128PACKCOLOR8888(src[0], src[1], src[2], 0xff); + R128CCE(pix); + src += 3; + } + } + break; + + case GL_RGBA: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; + for (j = width; j; j--) { + pix = R128PACKCOLOR8888(src[0], src[1], src[2], src[3]); + R128CCE(pix); + src += 4; + } + } + break; + + case GL_ALPHA: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for (j = width; j; j--) { + pix = R128PACKCOLOR8888(0xff, 0xff, 0xff, src[0]); + R128CCE(pix); + src += 1; + } + } + break; + + case GL_LUMINANCE: + for (i = 0 ; i < height ; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for (j = width; j; j--) { + pix = R128PACKCOLOR8888(src[0], src[0], src[0], 0xff); + R128CCE(pix); + src += 1; + } + } + break; + + case GL_LUMINANCE_ALPHA: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2; + for (j = width; j; j-- ) { + pix = R128PACKCOLOR8888(src[0], src[0], src[0], src[1]); + R128CCE(pix); + src += 2; + } + } + break; + + case GL_INTENSITY: + for (i = 0; i < height; i++) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for (j = width; j; j--) { + pix = R128PACKCOLOR8888(src[0], src[0], src[0], src[0]); + R128CCE(pix); + src += 1; + } + } + break; + + default: + fprintf(stderr, "r128ConvertTexture32bpp: unsupported format 0x%x\n", + image->Format); + } +} + +/* Upload the texture image associated with texture `t' at level `level' + at the address relative to `start'. */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128UploadSubImage(r128ContextPtr r128ctx, + r128TexObjPtr t, int level, + int x, int y, int width, int height) +{ + struct gl_texture_image *image; + int texelsPerDword = 0; + int imageWidth, imageHeight; + int remaining, rows; + int format, pitch, dwords; + CARD32 offset; + + /* Ensure we have a valid texture to upload */ + if (level < 0 || level > R128_TEX_MAXLEVELS) return; + if (!(image = t->tObj->Image[level])) return; + + /* FIXME: support RGB888 (i.e., 24bpp) textures? */ + switch (t->texelBytes) { + case 1: texelsPerDword = 4; break; + case 2: texelsPerDword = 2; break; + case 4: texelsPerDword = 1; break; + } + + imageWidth = image->Width; + imageHeight = image->Height; + + format = t->textureFormat >> 16; + + /* The texel upload routines have a minimum width, so force the size + if needed */ + if (imageWidth < texelsPerDword) { + int factor; + + factor = texelsPerDword / imageWidth; + imageWidth = texelsPerDword; + imageHeight /= factor; + if (imageHeight == 0) { + /* In this case, the texel converter will actually walk a + texel or two off the end of the image, but normal malloc + alignment should prevent it from ever causing a fault. */ + imageHeight = 1; + } + } + + /* We can't upload to a pitch less than 8 texels so we will need to + linearly upload all modified rows for textures smaller than this. + This makes the x/y/width/height different for the blitter and the + texture walker. */ + if (imageWidth >= 8) { + /* The texture walker and the blitter look identical */ + pitch = imageWidth >> 3; + } else { + int factor; + int y2; + int start, end; + + start = (y * imageWidth) & ~7; + end = (y + height) * imageWidth; + + if (end - start < 8) { + /* Handle the case where the total number of texels uploaded + is < 8 */ + x = 0; + y = start / 8; + width = end - start; + height = 1; + } else { + /* Upload some number of full 8 texel blit rows */ + factor = 8 / imageWidth; + + y2 = y + height - 1; + y /= factor; + y2 /= factor; + + x = 0; + width = 8; + height = y2 - y + 1; + } + + /* Fixed pitch of 8 */ + pitch = 1; + } + + dwords = width * height / texelsPerDword; + offset = (CARD32)(t->bufAddr + t->image[level].offset); + + /* Fix offset for AGP textures */ + if (t->heap == R128_AGP_TEX_HEAP) + offset += R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset; + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { + fprintf(stderr, "r128UploadSubImage: %d,%d of %d,%d at %d,%d\n", + width, height, image->Width, image->Height, x, y); + fprintf(stderr, " blit ofs: 0x%08x pitch: 0x%x dwords: %d " + "level: %d format: %x\n", + (int)offset, pitch, dwords, level, format); + } + + /* Subdivide the texture if required */ + if (dwords < R128_CCE_PACKET_MAX_DWORDS) { + rows = height; + } else { + rows = (R128_CCE_PACKET_MAX_DWORDS * texelsPerDword) / (2 * width); + } + + /* Flush the pixel cache, and mark the contents as Read Invalid */ + R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0); + R128CCE(r128ctx->regs.pc_gui_ctlstat | + R128_PC_RI_GUI | + R128_PC_FLUSH_GUI); + R128CCE_SUBMIT_PACKETS(); + + /* Build the CCE host data blit header */ + R128CCE3(R128_CCE_PACKET3_CNTL_HOSTDATA_BLT, 0); + + /* DP_GUI_MASTER_CNTL */ + R128CCE(R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (format << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_HOST_DATA | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS ); + + /* DST_OFFSET_PITCH - fixed at the moment until we get better ring + control */ + R128CCE((pitch << 21) | (offset>>5)); + + /* FRGD_COLOR, BKGD_COLOR */ + R128CCE(0xffffffff); + R128CCE(0xffffffff); + + for (remaining = height; remaining > 0; remaining -= rows, y += rows) { + height = (remaining >= rows) ? rows : remaining; + dwords = width * height / texelsPerDword; + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { + fprintf(stderr, " blitting: %d,%d at %d,%d - %d dwords\n", + width, height, x, y, dwords); + } + + r128ctx->CCEbuf[0] &= ~R128_CCE_PACKET_COUNT_MASK; + r128ctx->CCEbuf[0] |= (dwords + 6) << 16; + + /* Blit coords, size */ + R128CCE((y << 16) | x); + R128CCE((height << 16) | width); + R128CCE(dwords); + + /* Actually do the texture conversion */ + switch (t->texelBytes) { + case 1: + r128ConvertTexture8bpp(r128ctx, image, + x, y, width, height, width); + break; + case 2: + r128ConvertTexture16bpp(r128ctx, image, + x, y, width, height, width); + break; + case 4: + r128ConvertTexture32bpp(r128ctx, + image, x, y, width, height, width); + break; + } + + /* Flush the pixel cache */ + R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0 ); + R128CCE(r128ctx->regs.pc_gui_ctlstat | R128_PC_FLUSH_GUI); + + /* Save the partial blit header */ + R128CCE_SUBMIT_PACKETS(); + r128ctx->CCEcount = 5; + } + + /* Clean up CCE ring buffer */ + r128ctx->CCEcount = 0; +} + +/* Upload the texture images associated with texture `t'. This might + require removing our own and/or other client's texture objects to + make room for these images. */ +/* NOTE: This function is only called while holding the hardware lock */ +int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t) +{ + int i; + int minLevel; + int maxLevel; + int heap; + + if (!t) return 0; + + /* Choose the heap appropriately */ + heap = t->heap = R128_LOCAL_TEX_HEAP; + if (!r128ctx->r128Screen->IsPCI && + t->totalSize > r128ctx->r128Screen->texSize[heap]) + heap = t->heap = R128_AGP_TEX_HEAP; + + /* Do we need to eject LRU texture objects? */ + if (!t->memBlock) { + /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ + t->memBlock = mmAllocMem(r128ctx->texHeap[heap], t->totalSize, 12, 0); + + /* Try AGP before kicking anything out of local mem */ + if (!t->memBlock && heap == R128_LOCAL_TEX_HEAP) { + t->memBlock = mmAllocMem(r128ctx->texHeap[R128_AGP_TEX_HEAP], + t->totalSize, 12, 0); + + if (t->memBlock) heap = t->heap = R128_AGP_TEX_HEAP; + } + + /* Kick out textures until the requested texture fits */ + while (!t->memBlock) { + if (r128ctx->TexObjList[heap].prev->bound) { + fprintf(stderr, + "r128UploadTexImages: ran into bound texture\n"); + return -1; + } + if (r128ctx->TexObjList[heap].prev == + &(r128ctx->TexObjList[heap])) { + if (r128ctx->r128Screen->IsPCI) { + fprintf(stderr, "r128UploadTexImages: upload texture " + "failure on local texture heaps, sz=%d\n", + t->totalSize); + return -1; + } else if (heap == R128_LOCAL_TEX_HEAP) { + heap = t->heap = R128_AGP_TEX_HEAP; + continue; + } else { + fprintf(stderr, "r128UploadTexImages: upload texture " + "failure on both local and AGP texture heaps, " + "sz=%d\n", + t->totalSize); + return -1; + } + } + + r128DestroyTexObj(r128ctx, r128ctx->TexObjList[heap].prev); + + t->memBlock = mmAllocMem(r128ctx->texHeap[heap], + t->totalSize, 12, 0); + } + + /* Set the base offset of the texture image */ + t->bufAddr = (unsigned char *)r128ctx->r128Screen->texOffset[heap]; + t->bufAddr += t->memBlock->ofs; + + maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> + R128_TEX_SIZE_SHIFT); + minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >> + R128_TEX_MIN_SIZE_SHIFT); + + /* Update the hardware's texture image addresses */ + switch (t->bound) { + case 1: + /* Set texture offsets */ + if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.prim_tex_offset[i] = (CARD32)t->bufAddr; + } else { + for (i = maxLevel; i >= minLevel; i--) + r128ctx->regs.prim_tex_offset[i] = + t->image[maxLevel-i].offset + (CARD32)t->bufAddr; + } + /* Fix AGP texture offsets */ + if (heap == R128_AGP_TEX_HEAP) + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.prim_tex_offset[i] += + R128_AGP_TEX_OFFSET + + r128ctx->r128Screen->agpTexOffset; + /* Force loading the new state into the hardware */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_TEX0STATE; + break; + + case 2: + /* Set texture offsets */ + if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.sec_tex_offset[i] = (CARD32)t->bufAddr; + } else { + for (i = maxLevel; i >= minLevel; i--) + r128ctx->regs.sec_tex_offset[i] = + t->image[maxLevel-i].offset + (CARD32)t->bufAddr; + } + /* Fix AGP texture offsets */ + if (heap == R128_AGP_TEX_HEAP) + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.sec_tex_offset[i] += + R128_AGP_TEX_OFFSET + + r128ctx->r128Screen->agpTexOffset; + /* Force loading the new state into the hardware */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_TEX1STATE; + break; + + default: + return -1; + } + } + + /* Let the world know we've used this memory recently */ + r128UpdateTexLRU(r128ctx, t); + + /* Upload any images that are new */ + if (t->dirty_images) { + int num_levels = (((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> + R128_TEX_SIZE_SHIFT) - + ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >> + R128_TEX_MIN_SIZE_SHIFT)); + + for (i = 0; i <= num_levels; i++) { + if (t->dirty_images & (1<<i)) { + r128UploadSubImage(r128ctx, t, i, 0, 0, + t->image[i].width, t->image[i].height); + } + } + + r128ctx->regs.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ENGINESTATE; + } + + t->dirty_images = 0; + return 0; +} + +/* Update the hardware state for texture unit 0 */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128UpdateTex0State(r128ContextPtr r128ctx) +{ + GLcontext *ctx = r128ctx->glCtx; + r128TexObjPtr t; + struct gl_texture_object *tObj; + int i; + CARD32 tex_size_pitch, tex_combine_cntl; + + /* Only update the hardware texture state if the texture is current, + complete and enabled. */ + if (!(tObj = ctx->Texture.Unit[0].Current)) return; + if ((tObj != ctx->Texture.Unit[0].CurrentD[2]) && + (tObj != ctx->Texture.Unit[0].CurrentD[1])) return; + if (!tObj->Complete) return; + + /* If neither tex0 nor tex1 is enabled, then disable tex0. However, + if tex1 is enabled but tex0 is disabled, then we need to enable + tex0 and have it to copy the input (see how tex_combine_cntl is + setup below). */ + if (!(ctx->Texture.Enabled & (ENABLE_TEX0 | ENABLE_TEX1))) { + r128ctx->regs.tex_cntl_c &= ~R128_TEXMAP_ENABLE; + return; + } + + /* If this is the first time the texture has been used, then create + a new texture object for it. */ + t = tObj->DriverData; + if (!t) t = r128CreateTexObj(r128ctx, tObj); + if (!t) return; + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) + fprintf(stderr, "r128UpdateTex0State(%p, 0x%08x)\n", + tObj, (int)t->dirty_images); + + /* Force any texture images to be loaded into the hardware */ + if (t->dirty_images) r128ctx->dirty |= R128_UPDATE_TEX0IMAGES; + + /* Bind texture to texture 0 unit */ + r128ctx->CurrentTexObj[0] = t; + t->bound = 1; + + if (t->memBlock) r128UpdateTexLRU(r128ctx, t); + + /* Set the texture environment state */ + switch (ctx->Texture.Unit[0].EnvMode) { + case GL_REPLACE: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + tex_combine_cntl = (R128_COMB_DIS | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_DIS | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_RGB: + case GL_LUMINANCE: + tex_combine_cntl = (R128_COMB_DIS | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_ALPHA: + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_DIS | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_BLEND: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + switch (r128ctx->regs.constant_color_c & + R128_CONSTANT_COLOR_MASK) { + case R128_CONSTANT_COLOR_ZERO: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_NTEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case R128_CONSTANT_COLOR_ONE: + default: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + break; + case GL_RGB: + case GL_LUMINANCE: + switch (r128ctx->regs.constant_color_c & + R128_CONSTANT_COLOR_MASK) { + case R128_CONSTANT_COLOR_ZERO: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_NTEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case R128_CONSTANT_COLOR_ONE: + default: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + break; + case GL_ALPHA: + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_INTENSITY: + switch (r128ctx->regs.constant_color_c & + R128_CONSTANT_COLOR_MASK) { + case R128_CONSTANT_COLOR_ZERO: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_NTEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_NTEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case R128_CONSTANT_COLOR_ONE: + default: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_MODULATE: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_RGB: + case GL_LUMINANCE: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_ALPHA: + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_DECAL: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + tex_combine_cntl = (R128_COMB_BLEND_TEXTURE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_RGB: + tex_combine_cntl = (R128_COMB_DIS | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + /* Undefined behaviour - just copy the input */ + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_ADD: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + tex_combine_cntl = (R128_COMB_ADD | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_RGB: + case GL_LUMINANCE: + tex_combine_cntl = (R128_COMB_ADD | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_ALPHA: + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + default: + return; + } + + /* If tex0 is disabled, then make sure it just copies the input */ + if (!(ctx->Texture.Enabled & ENABLE_TEX0)) + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_INT_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_INT_ALPHA); + + /* Enable tex0 */ + r128ctx->regs.tex_cntl_c |= R128_TEXMAP_ENABLE; + + tex_size_pitch = r128ctx->regs.tex_size_pitch_c; + tex_size_pitch &= ~R128_TEX_SIZE_PITCH_MASK; + tex_size_pitch |= t->regs.size_pitch << R128_TEX_SIZE_PITCH_SHIFT; + + /* Set the primary texture state in r128ctx->regs */ + r128ctx->regs.prim_tex_cntl_c = t->regs.tex_cntl; + r128ctx->regs.prim_texture_combine_cntl_c = tex_combine_cntl; + r128ctx->regs.tex_size_pitch_c = tex_size_pitch; + r128ctx->regs.prim_texture_border_color_c = t->regs.border_color; + + /* Set texture offsets */ + if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.prim_tex_offset[i] = (CARD32)t->bufAddr; + } else { + int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> + R128_TEX_SIZE_SHIFT); + int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >> + R128_TEX_MIN_SIZE_SHIFT); + for (i = maxLevel; i >= minLevel; i--) + r128ctx->regs.prim_tex_offset[i] = + t->image[maxLevel-i].offset + (CARD32)t->bufAddr; + } + /* Fix AGP texture offsets */ + if (t->heap == R128_AGP_TEX_HEAP) + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.prim_tex_offset[i] += + R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset; + + /* Force loading the new state into the hardware */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_TEX0STATE | R128_CTX_ENGINESTATE; +} + +/* Update the hardware state for texture unit 1 */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128UpdateTex1State(r128ContextPtr r128ctx) +{ + GLcontext *ctx = r128ctx->glCtx; + r128TexObjPtr t; + struct gl_texture_object *tObj; + int i; + CARD32 tex_size_pitch, tex_combine_cntl, tex_cntl; + + /* Only update the hardware texture state if the texture is current, + complete and enabled. */ + if (!(tObj = ctx->Texture.Unit[1].Current)) return; + if ((tObj != ctx->Texture.Unit[1].CurrentD[2]) && + (tObj != ctx->Texture.Unit[1].CurrentD[1])) return; + if (!tObj->Complete) return; + + /* If tex1 is not enabled, then disable it */ + if (!(ctx->Texture.Enabled & ENABLE_TEX1)) { + r128ctx->regs.tex_cntl_c &= ~R128_SEC_TEXMAP_ENABLE; + return; + } + + /* If this is the first time the texture has been used, then create + a new texture object for it. */ + t = tObj->DriverData; + if (!t) t = r128CreateTexObj(r128ctx, tObj); + if (!t) return; + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) + fprintf(stderr, "r128UpdateTex1State(%p, 0x%08x)\n", + tObj, (int)t->dirty_images); + + /* Force any texture images to be loaded into the hardware */ + if (t->dirty_images) r128ctx->dirty |= R128_UPDATE_TEX1IMAGES; + + /* Bind texture to texture 1 unit */ + r128ctx->CurrentTexObj[1] = t; + t->bound = 2; + + if (t->memBlock) r128UpdateTexLRU(r128ctx, t); + + /* Set the texture environment state */ + switch (ctx->Texture.Unit[1].EnvMode) { + case GL_REPLACE: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + tex_combine_cntl = (R128_COMB_DIS | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_DIS | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_RGB: + case GL_LUMINANCE: + tex_combine_cntl = (R128_COMB_DIS | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_ALPHA: + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_DIS | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_BLEND: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + switch ( r128ctx->regs.constant_color_c & R128_CONSTANT_COLOR_MASK ) { + case R128_CONSTANT_COLOR_ZERO: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_NTEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case R128_CONSTANT_COLOR_ONE: + default: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + break; + case GL_RGB: + case GL_LUMINANCE: + switch (r128ctx->regs.constant_color_c & + R128_CONSTANT_COLOR_MASK) { + case R128_CONSTANT_COLOR_ZERO: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_NTEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA ); + break; + case R128_CONSTANT_COLOR_ONE: + default: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA ); + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + break; + case GL_ALPHA: + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_INTENSITY: + switch (r128ctx->regs.constant_color_c & + R128_CONSTANT_COLOR_MASK) { + case R128_CONSTANT_COLOR_ZERO: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_NTEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_NTEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case R128_CONSTANT_COLOR_ONE: + default: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_MODULATE: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_RGB: + case GL_LUMINANCE: + tex_combine_cntl = (R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_ALPHA: + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_DECAL: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + tex_combine_cntl = (R128_COMB_BLEND_TEXTURE | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_RGB: + tex_combine_cntl = (R128_COMB_DIS | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + /* Undefined behaviour - just copy the input */ + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_ADD: + switch (tObj->Image[0]->Format) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + tex_combine_cntl = (R128_COMB_ADD | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_RGB: + case GL_LUMINANCE: + tex_combine_cntl = (R128_COMB_ADD | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_COPY_INP | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_ALPHA: + tex_combine_cntl = (R128_COMB_COPY_INP | + R128_COLOR_FACTOR_TEX | + R128_INPUT_FACTOR_PREV_COLOR | + R128_COMB_ALPHA_MODULATE | + R128_ALPHA_FACTOR_TEX_ALPHA | + R128_INP_FACTOR_A_PREV_ALPHA); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + default: + return; + } + + /* Enable tex1 */ + r128ctx->regs.tex_cntl_c |= R128_SEC_TEXMAP_ENABLE; + + tex_size_pitch = r128ctx->regs.tex_size_pitch_c; + tex_size_pitch &= ~R128_SEC_TEX_SIZE_PITCH_MASK; + tex_size_pitch |= t->regs.size_pitch << R128_SEC_TEX_SIZE_PITCH_SHIFT; + + tex_cntl = t->regs.tex_cntl | R128_SEC_SELECT_SEC_ST; + + /* Set the secondary texture state in r128ctx->regs */ + r128ctx->regs.sec_tex_cntl_c = tex_cntl; + r128ctx->regs.sec_tex_combine_cntl_c = tex_combine_cntl; + r128ctx->regs.tex_size_pitch_c = tex_size_pitch; + r128ctx->regs.sec_texture_border_color_c = t->regs.border_color; + + /* Set texture offsets */ + if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.sec_tex_offset[i] = (CARD32)t->bufAddr; + } else { + int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> + R128_TEX_SIZE_SHIFT); + int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >> + R128_TEX_MIN_SIZE_SHIFT); + for (i = maxLevel; i >= minLevel; i--) + r128ctx->regs.sec_tex_offset[i] = + t->image[maxLevel-i].offset + (CARD32)t->bufAddr; + } + /* Fix AGP texture offsets */ + if (t->heap == R128_AGP_TEX_HEAP) + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.sec_tex_offset[i] += + R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset; + + /* Force loading the new state into the hardware */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_TEX1STATE | R128_CTX_ENGINESTATE; +} + +/* Update the hardware texture state */ +/* NOTE: This function is only called while holding the hardware lock */ +void r128UpdateTextureState(r128ContextPtr r128ctx) +{ + /* Clear the GL_BLEND texturing fallback */ + r128ctx->Fallback &= ~R128_FALLBACK_TEXTURE; + + /* Unbind any currently bound textures */ + if (r128ctx->CurrentTexObj[0]) r128ctx->CurrentTexObj[0]->bound = 0; + if (r128ctx->CurrentTexObj[1]) r128ctx->CurrentTexObj[1]->bound = 0; + r128ctx->CurrentTexObj[0] = NULL; + r128ctx->CurrentTexObj[1] = NULL; + + /* Update the texture unit 0/1 state */ + r128UpdateTex0State(r128ctx); + r128UpdateTex1State(r128ctx); +} + +/* Set the texture wrap mode */ +static void r128SetTexWrap(r128TexObjPtr t, GLenum swrap, GLenum twrap) +{ + t->regs.tex_cntl &= ~(R128_TEX_CLAMP_S_MASK | R128_TEX_CLAMP_T_MASK); + + switch (swrap) { + case GL_CLAMP: t->regs.tex_cntl |= R128_TEX_CLAMP_S_CLAMP; break; + case GL_REPEAT: t->regs.tex_cntl |= R128_TEX_CLAMP_S_WRAP; break; + default: /* ERROR!! */ return; + } + + switch (twrap) { + case GL_CLAMP: t->regs.tex_cntl |= R128_TEX_CLAMP_T_CLAMP; break; + case GL_REPEAT: t->regs.tex_cntl |= R128_TEX_CLAMP_T_WRAP; break; + default: /* ERROR!! */ return; + } +} + +/* Set the texture filter mode */ +static void r128SetTexFilter(r128TexObjPtr t, GLenum minf, GLenum magf) +{ + t->regs.tex_cntl &= ~(R128_MIN_BLEND_MASK | R128_MAG_BLEND_MASK); + + switch (minf) { + case GL_NEAREST: + t->regs.tex_cntl |= R128_MIN_BLEND_NEAREST; + break; + case GL_LINEAR: + t->regs.tex_cntl |= R128_MIN_BLEND_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: + t->regs.tex_cntl |= R128_MIN_BLEND_MIPNEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + t->regs.tex_cntl |= R128_MIN_BLEND_LINEARMIPNEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + t->regs.tex_cntl |= R128_MIN_BLEND_MIPLINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + t->regs.tex_cntl |= R128_MIN_BLEND_LINEARMIPLINEAR; + break; + default: /* ERROR!! */ return; + } + + switch (magf) { + case GL_NEAREST: + t->regs.tex_cntl |= R128_MAG_BLEND_NEAREST; + break; + case GL_LINEAR: + t->regs.tex_cntl |= R128_MAG_BLEND_LINEAR; + break; + } +} + +/* Set the texture border color */ +static void r128SetTexBorderColor(r128TexObjPtr t, GLubyte c[4]) +{ + t->regs.border_color = r128PackColor(32, c[0], c[1], c[2], c[3]); +} + +/* Set the texture environment state */ +static void r128DDTexEnv(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + struct gl_texture_unit *texUnit; + GLubyte c[4]; + CARD32 col; + + /* FIXME: Add texture LOD bias extension */ + + switch (pname) { + case GL_TEXTURE_ENV_MODE: + /* TexEnv modes are handled in UpdateTextureState */ + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->dirty |= R128_UPDATE_TEXSTATE; + break; + case GL_TEXTURE_ENV_COLOR: + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c); + col = r128PackColor(32, c[0], c[1], c[2], c[3]); + if (r128ctx->regs.constant_color_c != col) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + r128ctx->regs.constant_color_c = col; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_TEXENVSTATE; + } + break; + default: + return; + } +} + +/* Upload a new texture image */ +static void r128DDTexImage(GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint internalFormat, + const struct gl_texture_image *image) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128TexObjPtr t; + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) + fprintf(stderr, "r128DDTexImage(%p, level %d)\n", tObj, level); + + if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return; + if (level >= R128_TEX_MAXLEVELS) return; + + t = (r128TexObjPtr)tObj->DriverData; + if (t) { + if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx); + + /* Destroy the old texture, and upload a new one. The actual + uploading of the texture image occurs in the UploadSubImage + function. */ + r128DestroyTexObj(r128ctx, t); + r128ctx->dirty |= R128_UPDATE_TEXSTATE; + } +} + +/* Upload a new texture sub-image */ +static void r128DDTexSubImage(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) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128TexObjPtr t; + + if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) + fprintf(stderr, "r128DDTexSubImage(%p, level %d) " + "size: %d,%d of %d,%d\n", + tObj, level, width, height, image->Width, image->Height); + + if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return; + if (level >= R128_TEX_MAXLEVELS) return; + + t = (r128TexObjPtr)tObj->DriverData; + if (t) { + if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx); + + LOCK_HARDWARE(r128ctx); + r128UploadSubImage(r128ctx, t, level, + xoffset, yoffset, width, height); + UNLOCK_HARDWARE(r128ctx); + + /* Update the context state */ + r128ctx->regs.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + + r128ctx->dirty |= (R128_UPDATE_CONTEXT | + R128_UPDATE_TEXSTATE); + r128ctx->dirty_context |= (R128_CTX_ENGINESTATE | + R128_CTX_TEX0STATE | + R128_CTX_TEX1STATE); + } +} + +/* Set the texture parameter state */ +static void r128DDTexParameter(GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; + + if (!t) return; + if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return; + + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx); + r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx); + r128SetTexWrap(t, tObj->WrapS, tObj->WrapT); + break; + + case GL_TEXTURE_BORDER_COLOR: + if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx); + r128SetTexBorderColor(t, tObj->BorderColor); + break; + + default: + return; + } + + r128ctx->dirty |= R128_UPDATE_TEXSTATE; +} + +/* Bind a texture to the currently active texture unit */ +static void r128DDBindTexture(GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + R128CCE_FLUSH_VB_LOCK(r128ctx); + + /* Unbind the old texture */ + if (r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit]) { + r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0; + r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit] = NULL; + } + + /* The actualy binding occurs in the Tex[01]UpdateState function */ + r128ctx->dirty |= R128_UPDATE_TEXSTATE; +} + +/* Remove texture from AGP/local texture memory */ +static void r128DDDeleteTexture(GLcontext *ctx, + struct gl_texture_object *tObj) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; + + if (t) { + if (t->bound) { + R128CCE_FLUSH_VB_LOCK(r128ctx); + + r128ctx->CurrentTexObj[t->bound-1] = 0; + r128ctx->dirty |= R128_UPDATE_TEXSTATE; + } + + r128DestroyTexObj(r128ctx, t); + tObj->DriverData = NULL; + } +} + +/* Determine if a texture is currently residing in either AGP/local + texture memory */ +static GLboolean r128DDIsTextureResident(GLcontext *ctx, + struct gl_texture_object *tObj) +{ + r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; + + return t && t->memBlock; +} + +/* Initialize the driver's texture functions */ +void r128DDInitTextureFuncs(GLcontext *ctx) +{ + ctx->Driver.TexEnv = r128DDTexEnv; + ctx->Driver.TexImage = r128DDTexImage; + ctx->Driver.TexSubImage = r128DDTexSubImage; + ctx->Driver.TexParameter = r128DDTexParameter; + ctx->Driver.BindTexture = r128DDBindTexture; + ctx->Driver.DeleteTexture = r128DDDeleteTexture; + ctx->Driver.UpdateTexturePalette = NULL; + ctx->Driver.ActiveTexture = NULL; + ctx->Driver.IsTextureResident = r128DDIsTextureResident; + ctx->Driver.PrioritizeTexture = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h new file mode 100644 index 000000000..20893110c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h @@ -0,0 +1,82 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * Gareth Hughes <gareth@precisioninsight.com> + * + */ + +#ifndef _R128_TEX_H_ +#define _R128_TEX_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128AgeTextures(r128ContextPtr r128ctx, int heap); +extern int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t); +extern void r128UpdateTextureState(r128ContextPtr r128ctx); +extern void r128DestroyTexObj(r128ContextPtr r128ctx, r128TexObjPtr t); + +extern void r128DDInitTextureFuncs(GLcontext *ctx); + +#define R128PACKCOLOR332(r, g, b) \ + (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) + +#define R128PACKCOLOR1555(r, g, b, a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define R128PACKCOLOR565(r, g, b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define R128PACKCOLOR888(r, g, b) \ + (((r) << 16) | ((g) << 8) | (b)) + +#define R128PACKCOLOR8888(r, g, b, a) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +#define R128PACKCOLOR4444(r, g, b, a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +static __inline__ CARD32 r128PackColor(GLuint depth, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + switch (depth) { + case 8: return R128PACKCOLOR332(r, g, b); + case 15: return R128PACKCOLOR1555(r, g, b, a); + case 16: return R128PACKCOLOR565(r, g, b); + case 24: return R128PACKCOLOR888(r, g, b); + case 32: return R128PACKCOLOR8888(r, g, b, a); + default: return 0; + } +} + +#endif +#endif /* _R128_TEX_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h new file mode 100644 index 000000000..588b768ed --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h @@ -0,0 +1,87 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * Gareth Hughes <gareth@precisioninsight.com> + * + */ + +#ifndef _R128_TEXOBJ_H_ +#define _R128_TEXOBJ_H_ + +#include "mm.h" + +#define R128_TEX_MAXLEVELS 11 + +/* Setup registers for each texture */ +typedef struct { + CARD32 tex_cntl; + CARD32 size_pitch; + CARD32 border_color; +} r128TextureRegs; + +/* Individual texture image information */ +typedef struct { + int offset; /* Offset into locally shared texture space (i.e., + relative to bufAddr (below) */ + int width; /* Width of texture image */ + int height; /* Height of texture image */ +} r128TexImage; + +typedef struct r128_tex_obj r128TexObj, *r128TexObjPtr; + +/* Texture object in locally shared texture space */ +struct r128_tex_obj { + r128TexObjPtr next, prev; + + struct gl_texture_object *tObj; /* Mesa texture object */ + + PMemBlock memBlock; /* Memory block containing texture */ + unsigned char *bufAddr; /* Offset to start of locally + shared texture block */ + + CARD32 dirty_images; /* Flags for whether or not + images need to be uploaded to + local or AGP texture space */ + int bound; /* Texture unit currently bound to */ + int heap; /* Texture heap currently stored in */ + r128TexImage image[R128_TEX_MAXLEVELS]; /* Image data for all + mipmap levels */ + int totalSize; /* Total size of the texture + including all mipmap levels */ + int internFormat; /* Internal GL format used to store + texture on card */ + int textureFormat; /* Actual hardware format */ + int texelBytes; /* Number of bytes per texel */ + + r128TextureRegs regs; /* Setup regs for texture */ +}; + +#endif /* _R128_TEXOBJ_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c new file mode 100644 index 000000000..1c1b45daf --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c @@ -0,0 +1,548 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_reg.h" +#include "r128_cce.h" +#include "r128_vb.h" +#include "r128_tris.h" +#include "r128_state.h" + +static triangle_func tri_tab[0x40]; /* only 0x20 actually used */ +static quad_func quad_tab[0x40]; /* only 0x20 actually used */ +static line_func line_tab[0x40]; /* less than 0x20 used */ +static points_func points_tab[0x40]; /* less than 0x20 used */ + +/* Draw a triangle from the vertices in the vertex buffer */ +void r128DrawTriangleVB(r128ContextPtr r128ctx, + r128_vertex *v0, + r128_vertex *v1, + r128_vertex *v2) +{ + r128_vertex *vbptr; + + if (r128ctx->disableVB) { + r128DrawTriangle(r128ctx, v0, v1, v2); + return; + } + + R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3); + + *vbptr++ = *v0; + *vbptr++ = *v1; + *vbptr++ = *v2; +} + +/* Draw a triangle */ +void r128DrawTriangle(r128ContextPtr r128ctx, + r128_vertex *v0, + r128_vertex *v1, + r128_vertex *v2) +{ + LOCK_HARDWARE(r128ctx); + BEGIN_CLIP_LOOP(r128ctx); + +#if USE_RHW2 + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 34); +#else + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 31); +#endif + R128CCE(R128_FULL_VERTEX_FORMAT); + R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST | + R128_CCE_VC_CNTL_PRIM_WALK_RING | + (3 << R128_CCE_VC_CNTL_NUM_SHIFT)); + + R128CCE_SEND_VERTEX(v0); + R128CCE_SEND_VERTEX(v1); + R128CCE_SEND_VERTEX(v2); + + R128CCE_SUBMIT_PACKETS(); + + END_CLIP_LOOP(r128ctx); + UNLOCK_HARDWARE(r128ctx); +} + +/* Draw a line from the vertices in the vertex buffer */ +void r128DrawLineVB(r128ContextPtr r128ctx, + r128_vertex *v0, r128_vertex *v1, + float width) +{ + float dx, dy, ix, iy; + r128_vertex *vbptr; + + /* FIXME: Use r128's line primitive for width 1 lines */ + if (r128ctx->disableVB) { + r128DrawLine(r128ctx, v0, v1, width); + return; + } + + R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3); + + dx = v0->x - v1->x; + dy = v0->y - v1->y; + + ix = width * 0.5; iy = 0; + if (dx*dx > dy*dy) { + iy = ix; ix = 0; + } + + *vbptr = *v0; vbptr->x = v0->x - ix; vbptr->y = v0->y - iy; + *++vbptr = *v1; vbptr->x = v1->x + ix; vbptr->y = v1->y + iy; + *++vbptr = *v0; vbptr->x = v0->x + ix; vbptr->y = v0->y + iy; + *++vbptr = *v0; vbptr->x = v0->x - ix; vbptr->y = v0->y - iy; + *++vbptr = *v1; vbptr->x = v1->x - ix; vbptr->y = v1->y - iy; + *++vbptr = *v1; vbptr->x = v1->x + ix; vbptr->y = v1->y + iy; +} + +/* Draw a line */ +void r128DrawLine(r128ContextPtr r128ctx, + r128_vertex *v0, r128_vertex *v1, + float width) +{ + LOCK_HARDWARE(r128ctx); + if (width != 1) { + float dx, dy, ix, iy; + + dx = v0->x - v1->x; + dy = v0->y - v1->y; + + ix = width * 0.5; iy = 0; + if (dx*dx > dy*dy) { + iy = ix; ix = 0; + } + + BEGIN_CLIP_LOOP(r128ctx); + +#if USE_RHW2 + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 67); +#else + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 61); +#endif + R128CCE(R128_FULL_VERTEX_FORMAT); + R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST | + R128_CCE_VC_CNTL_PRIM_WALK_RING | + (6 << R128_CCE_VC_CNTL_NUM_SHIFT)); + + R128CCEF(v0->x - ix); + R128CCEF(v0->y - iy); + R128CCEF(v0->z); + R128CCEF(v0->rhw); + R128CCE(*(int *)&v0->dif_argb); + R128CCE(*(int *)&v0->spec_frgb); + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCEF(v1->x + ix); + R128CCEF(v1->y + iy); + R128CCEF(v1->z); + R128CCEF(v1->rhw); + R128CCE(*(int *)&v1->dif_argb); + R128CCE(*(int *)&v1->spec_frgb); + R128CCEF(v1->tu0); + R128CCEF(v1->tv0); + R128CCEF(v1->tu1); + R128CCEF(v1->tv1); +#if USE_RHW2 + R128CCEF(v1->rhw2); +#endif + + R128CCEF(v0->x + ix); + R128CCEF(v0->y + iy); + R128CCEF(v0->z); + R128CCEF(v0->rhw); + R128CCE(*(int *)&v0->dif_argb); + R128CCE(*(int *)&v0->spec_frgb); + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCEF(v0->x - ix); + R128CCEF(v0->y - iy); + R128CCEF(v0->z); + R128CCEF(v0->rhw); + R128CCE(*(int *)&v0->dif_argb); + R128CCE(*(int *)&v0->spec_frgb); + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCEF(v1->x - ix); + R128CCEF(v1->y - iy); + R128CCEF(v1->z); + R128CCEF(v1->rhw); + R128CCE(*(int *)&v1->dif_argb); + R128CCE(*(int *)&v1->spec_frgb); + R128CCEF(v1->tu0); + R128CCEF(v1->tv0); + R128CCEF(v1->tu1); + R128CCEF(v1->tv1); +#if USE_RHW2 + R128CCEF(v1->rhw2); +#endif + + R128CCEF(v1->x + ix); + R128CCEF(v1->y + iy); + R128CCEF(v1->z); + R128CCEF(v1->rhw); + R128CCE(*(int *)&v1->dif_argb); + R128CCE(*(int *)&v1->spec_frgb); + R128CCEF(v1->tu0); + R128CCEF(v1->tv0); + R128CCEF(v1->tu1); + R128CCEF(v1->tv1); +#if USE_RHW2 + R128CCEF(v1->rhw2); +#endif + + R128CCE_SUBMIT_PACKETS(); + + END_CLIP_LOOP(r128ctx); + } else { + BEGIN_CLIP_LOOP(r128ctx); + +#if USE_RHW2 + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 23); +#else + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 21); +#endif + R128CCE(R128_FULL_VERTEX_FORMAT); + R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_LINE | + R128_CCE_VC_CNTL_PRIM_WALK_RING | + (2 << R128_CCE_VC_CNTL_NUM_SHIFT)); + + R128CCE_SEND_VERTEX(v0); + R128CCE_SEND_VERTEX(v1); + + R128CCE_SUBMIT_PACKETS(); + + END_CLIP_LOOP(r128ctx); + } + UNLOCK_HARDWARE(r128ctx); +} + +/* Draw a point from the vertices in the vertex buffer */ +void r128DrawPointVB(r128ContextPtr r128ctx, + r128_vertex *v0, float size) +{ + r128_vertex *vbptr; + + /* FIXME: Use r128's point primitive for diameter 1 points */ + if (r128ctx->disableVB) { + r128DrawPoint(r128ctx, v0, size); + return; + } + + R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3); + + *vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y - size; + *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y - size; + *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y + size; + *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y + size; + *++vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y + size; + *++vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y - size; +} + +/* Draw a point */ +void r128DrawPoint(r128ContextPtr r128ctx, + r128_vertex *v0, float size) +{ + LOCK_HARDWARE(r128ctx); + if (size != 0.5) { + BEGIN_CLIP_LOOP(r128ctx); + +#if USE_RHW2 + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 67); +#else + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 61); +#endif + R128CCE(R128_FULL_VERTEX_FORMAT); + R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST | + R128_CCE_VC_CNTL_PRIM_WALK_RING | + (6 << R128_CCE_VC_CNTL_NUM_SHIFT)); + + R128CCEF(v0->x - size); + R128CCEF(v0->y - size); + R128CCEF(v0->z); + R128CCEF(v0->rhw); + R128CCE(*(int *)&v0->dif_argb); + R128CCE(*(int *)&v0->spec_frgb); + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCEF(v0->x + size); + R128CCEF(v0->y - size); + R128CCEF(v0->z); + R128CCEF(v0->rhw); + R128CCE(*(int *)&v0->dif_argb); + R128CCE(*(int *)&v0->spec_frgb); + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCEF(v0->x + size); + R128CCEF(v0->y + size); + R128CCEF(v0->z); + R128CCEF(v0->rhw); + R128CCE(*(int *)&v0->dif_argb); + R128CCE(*(int *)&v0->spec_frgb); + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCEF(v0->x + size); + R128CCEF(v0->y + size); + R128CCEF(v0->z); + R128CCEF(v0->rhw); + R128CCE(*(int *)&v0->dif_argb); + R128CCE(*(int *)&v0->spec_frgb); + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCEF(v0->x - size); + R128CCEF(v0->y + size); + R128CCEF(v0->z); + R128CCEF(v0->rhw); + R128CCE(*(int *)&v0->dif_argb); + R128CCE(*(int *)&v0->spec_frgb); + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCEF(v0->x - size); + R128CCEF(v0->y - size); + R128CCEF(v0->z); + R128CCEF(v0->rhw); + R128CCE(*(int *)&v0->dif_argb); + R128CCE(*(int *)&v0->spec_frgb); + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCE_SUBMIT_PACKETS(); + + END_CLIP_LOOP(r128ctx); + } else { + BEGIN_CLIP_LOOP(r128ctx); + +#if USE_RHW2 + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 12); +#else + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 11); +#endif + R128CCE(R128_FULL_VERTEX_FORMAT); + R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_POINT | + R128_CCE_VC_CNTL_PRIM_WALK_RING | + (1 << R128_CCE_VC_CNTL_NUM_SHIFT)); + + R128CCE_SEND_VERTEX(v0); + + R128CCE_SUBMIT_PACKETS(); + + END_CLIP_LOOP(r128ctx); + } + UNLOCK_HARDWARE(r128ctx); +} + +#define R128_COLOR(to, from) \ +do { \ + (to)[0] = (from)[2]; \ + (to)[1] = (from)[1]; \ + (to)[2] = (from)[0]; \ + (to)[3] = (from)[3]; \ +} while (0) + +#define IND (0) +#define TAG(x) x +#include "r128_tritmp.h" + +#define IND (R128_FLAT_BIT) +#define TAG(x) x##_flat +#include "r128_tritmp.h" + +#define IND (R128_OFFSET_BIT) +#define TAG(x) x##_offset +#include "r128_tritmp.h" + +#define IND (R128_OFFSET_BIT | R128_FLAT_BIT) +#define TAG(x) x##_offset_flat +#include "r128_tritmp.h" + +#define IND (R128_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "r128_tritmp.h" + +#define IND (R128_TWOSIDE_BIT | R128_FLAT_BIT) +#define TAG(x) x##_twoside_flat +#include "r128_tritmp.h" + +#define IND (R128_TWOSIDE_BIT | R128_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "r128_tritmp.h" + +#define IND (R128_TWOSIDE_BIT | R128_OFFSET_BIT | R128_FLAT_BIT) +#define TAG(x) x##_twoside_offset_flat +#include "r128_tritmp.h" + +/* Initialize the table of points, line and triangle drawing functions */ +void r128TriangleFuncsInit(void) +{ + init(); + init_flat(); + init_offset(); + init_offset_flat(); + init_twoside(); + init_twoside_flat(); + init_twoside_offset(); + init_twoside_offset_flat(); +} + +/* Setup the Point, Line, Triangle and Quad functions based on the + current rendering state. Wherever possible, use the hardware to + render the primitive. Otherwise, fallback to software rendering. */ +void r128ChooseRenderState(GLcontext *ctx) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + GLuint flags = ctx->TriangleCaps; + + if (r128ctx->Fallback) return; + + if (r128ctx->SWonly) { + r128ctx->IndirectTriangles = DD_SW_RASTERIZE; + r128ctx->PointsFunc = NULL; + r128ctx->LineFunc = NULL; + r128ctx->TriangleFunc = NULL; + r128ctx->QuadFunc = NULL; + return; + } else { + r128ctx->IndirectTriangles = 0; + } + + if (flags) { + CARD32 index = 0; + CARD32 shared = 0; + CARD32 fallback = R128_FALLBACK_BIT; + + if (r128ctx->SWfallbackDisable) fallback = 0; /* No fallbacks */ + if (r128ctx->SWonly) shared = fallback; /* Everything's a fallback */ + + if (flags & DD_FLATSHADE) shared |= R128_FLAT_BIT; + if (flags & DD_MULTIDRAW) shared |= fallback; + if (flags & DD_SELECT) shared |= R128_FALLBACK_BIT; + if (flags & DD_FEEDBACK) shared |= R128_FALLBACK_BIT; + + /* Setup PointFunc */ + index = shared; + if (flags & DD_POINT_SMOOTH) index |= fallback; + if (flags & DD_POINT_ATTEN) index |= fallback; + + r128ctx->RenderIndex = index; + r128ctx->PointsFunc = points_tab[index]; + if (index & R128_FALLBACK_BIT) + r128ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + + /* Setup LineFunc */ + index = shared; + if (flags & DD_LINE_SMOOTH) index |= fallback; + if (flags & DD_LINE_STIPPLE) index |= fallback; + + r128ctx->RenderIndex |= index; + r128ctx->LineFunc = line_tab[index]; + if (index & R128_FALLBACK_BIT) + r128ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE; + + /* Setup TriangleFunc and QuadFunc */ + index = shared; + if (flags & DD_TRI_SMOOTH) index |= fallback; + if (flags & DD_TRI_OFFSET) index |= R128_OFFSET_BIT; + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R128_TWOSIDE_BIT; + if (flags & DD_TRI_UNFILLED) index |= fallback; + if (flags & DD_TRI_STIPPLE) index |= fallback; + + r128ctx->RenderIndex |= index; + r128ctx->TriangleFunc = tri_tab[index]; + r128ctx->QuadFunc = quad_tab[index]; + if (index & R128_FALLBACK_BIT) + r128ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | + DD_QUAD_SW_RASTERIZE); + } else if (r128ctx->RenderIndex) { + r128ctx->RenderIndex = 0; + r128ctx->PointsFunc = points_tab[0]; + r128ctx->LineFunc = line_tab[0]; + r128ctx->TriangleFunc = tri_tab[0]; + r128ctx->QuadFunc = quad_tab[0]; + } +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h new file mode 100644 index 000000000..0980f2791 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h @@ -0,0 +1,76 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_TRIS_H_ +#define _R128_TRIS_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include "r128_vb.h" + +#define R128_ANTIALIAS_BIT 0x00 /* ignored for now, no fallback */ +#define R128_FLAT_BIT 0x01 +#define R128_OFFSET_BIT 0x02 +#define R128_TWOSIDE_BIT 0x04 +#define R128_NODRAW_BIT 0x08 +#define R128_FALLBACK_BIT 0x10 +#define R128_FEEDBACK_BIT 0x20 +#define R128_SELECT_BIT 0x40 +#define R128_POINT_PARAM_BIT 0x80 /* not needed? */ + +extern void r128DrawTriangleVB(r128ContextPtr r128ctx, + r128_vertex *v0, + r128_vertex *v1, + r128_vertex *v2); +extern void r128DrawLineVB(r128ContextPtr r128ctx, + r128_vertex *tmp0, r128_vertex *tmp1, + float width); +extern void r128DrawPointVB(r128ContextPtr r128ctx, + r128_vertex *tmp, float size); + +extern void r128DrawTriangle(r128ContextPtr r128ctx, + r128_vertex *v0, + r128_vertex *v1, + r128_vertex *v2); +extern void r128DrawLine(r128ContextPtr r128ctx, + r128_vertex *tmp0, r128_vertex *tmp1, + float width); +extern void r128DrawPoint(r128ContextPtr r128ctx, + r128_vertex *tmp, float size); + +extern void r128ChooseRenderState(GLcontext *ctx); +extern void r128TriangleFuncsInit(void); + +#endif +#endif /* _R128_TRIS_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h new file mode 100644 index 000000000..833bd832a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h @@ -0,0 +1,327 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#if !defined(TAG) || !defined(IND) + this is an error +#endif + +/* Draw a single triangle. Note that the device-dependent vertex data + might need to be changed based on the render state. */ +static void TAG(triangle)(GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, + GLuint pv) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; + const r128_vertex *v0 = &r128verts[e0].v; + const r128_vertex *v1 = &r128verts[e1].v; + const r128_vertex *v2 = &r128verts[e2].v; + +#if (IND & R128_OFFSET_BIT) + GLfloat offset; +#endif + +#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT)) + int c0 = *(int *)&r128verts[pv].v.dif_argb; + int c1 = c0; + int c2 = c0; +#endif + +#if (IND & R128_OFFSET_BIT) + switch (ctx->Visual->DepthBits) { + case 16: offset = ctx->Polygon.OffsetUnits / 65536.0; break; + case 24: offset = ctx->Polygon.OffsetUnits / 16777216.0; break; + case 32: offset = ctx->Polygon.OffsetUnits / 4294967296.0; break; + default: offset = ctx->Polygon.OffsetUnits / 65536.0; break; + } +#endif + +#if (IND & (R128_TWOSIDE_BIT | R128_OFFSET_BIT)) + { + GLfloat ex = v0->x - v2->x; + GLfloat ey = v0->y - v2->y; + GLfloat fx = v1->x - v2->x; + GLfloat fy = v1->y - v2->y; + GLfloat c = ex*fy - ey*fx; + +#if (IND & R128_TWOSIDE_BIT) + { + GLuint facing = (c > 0.0) ^ ctx->Polygon.FrontBit; + GLubyte (*vbcolor)[4] = VB->Color[facing]->data; + if (IND & R128_FLAT_BIT) { + R128_COLOR((char *)&c0, vbcolor[pv]); + c2 = c1 = c0; + } else { + R128_COLOR((char *)&c0, vbcolor[e0]); + R128_COLOR((char *)&c1, vbcolor[e1]); + R128_COLOR((char *)&c2, vbcolor[e2]); + } + } +#endif + +#if (IND & R128_OFFSET_BIT) + { + if (c * c > 1e-16) { + GLfloat factor = ctx->Polygon.OffsetFactor; + GLfloat ez = v0->z - v2->z; + GLfloat fz = v1->z - v2->z; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / c; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if (ac < 0.0f) ac = -ac; + if (bc < 0.0f) bc = -bc; + offset += MAX2(ac, bc) * factor; + } + } +#endif + } +#endif + + LOCK_HARDWARE(r128ctx); + if (r128ctx->regs.tex_cntl_c & (R128_TEXMAP_ENABLE | + R128_SEC_TEXMAP_ENABLE)) { + BEGIN_CLIP_LOOP(r128ctx); + +#if USE_RHW2 + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 34); +#else + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 31); +#endif + R128CCE(R128_FULL_VERTEX_FORMAT); + R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST | + R128_CCE_VC_CNTL_PRIM_WALK_RING | + (3 << R128_CCE_VC_CNTL_NUM_SHIFT)); + + R128CCEF(v0->x); + R128CCEF(v0->y); +#if (IND & R128_OFFSET_BIT) + R128CCEF(v0->z + offset); +#else + R128CCEF(v0->z); +#endif + R128CCEF(v0->rhw); + +#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT)) + R128CCE(c0); +#else + R128CCE(*(int *)&v0->dif_argb); +#endif + R128CCE(*(int *)&v0->spec_frgb); + + R128CCEF(v0->tu0); + R128CCEF(v0->tv0); + R128CCEF(v0->tu1); + R128CCEF(v0->tv1); +#if USE_RHW2 + R128CCEF(v0->rhw2); +#endif + + R128CCEF(v1->x); + R128CCEF(v1->y); +#if (IND & R128_OFFSET_BIT) + R128CCEF(v1->z + offset); +#else + R128CCEF(v1->z); +#endif + R128CCEF(v1->rhw); + +#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT)) + R128CCE(c1); +#else + R128CCE(*(int *)&v1->dif_argb); +#endif + R128CCE(*(int *)&v1->spec_frgb); + + R128CCEF(v1->tu0); + R128CCEF(v1->tv0); + R128CCEF(v1->tu1); + R128CCEF(v1->tv1); +#if USE_RHW2 + R128CCEF(v1->rhw2); +#endif + + R128CCEF(v2->x); + R128CCEF(v2->y); +#if (IND & R128_OFFSET_BIT) + R128CCEF(v2->z + offset); +#else + R128CCEF(v2->z); +#endif + R128CCEF(v2->rhw); + +#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT)) + R128CCE(c2); +#else + R128CCE(*(int *)&v2->dif_argb); +#endif + R128CCE(*(int *)&v2->spec_frgb); + + R128CCEF(v2->tu0); + R128CCEF(v2->tv0); + R128CCEF(v2->tu1); + R128CCEF(v2->tv1); +#if USE_RHW2 + R128CCEF(v2->rhw2); +#endif + + R128CCE_SUBMIT_PACKETS(); + + END_CLIP_LOOP(r128ctx); + } else { + BEGIN_CLIP_LOOP(r128ctx); + + R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 13); + R128CCE(R128_CCE_VC_FRMT_DIFFUSE_ARGB); + R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST | + R128_CCE_VC_CNTL_PRIM_WALK_RING | + (3 << R128_CCE_VC_CNTL_NUM_SHIFT)); + + R128CCEF(v0->x); + R128CCEF(v0->y); +#if (IND & R128_OFFSET_BIT) + R128CCEF(v0->z + offset); +#else + R128CCEF(v0->z); +#endif + +#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT)) + R128CCE(c0); +#else + R128CCE(*(int *)&v0->dif_argb); +#endif + + R128CCEF(v1->x); + R128CCEF(v1->y); +#if (IND & R128_OFFSET_BIT) + R128CCEF(v1->z + offset); +#else + R128CCEF(v1->z); +#endif + +#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT)) + R128CCE(c1); +#else + R128CCE(*(int *)&v1->dif_argb); +#endif + + R128CCEF(v2->x); + R128CCEF(v2->y); +#if (IND & R128_OFFSET_BIT) + R128CCEF(v2->z + offset); +#else + R128CCEF(v2->z); +#endif + +#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT)) + R128CCE(c2); +#else + R128CCE(*(int *)&v2->dif_argb); +#endif + + R128CCE_SUBMIT_PACKETS(); + + END_CLIP_LOOP(r128ctx); + } + UNLOCK_HARDWARE(r128ctx); +} + +static void TAG(quad)(GLcontext *ctx, + GLuint v0, GLuint v1, GLuint v2, GLuint v3, + GLuint pv) +{ + TAG(triangle)(ctx, v0, v1, v3, pv); + TAG(triangle)(ctx, v1, v2, v3, pv); +} + +#if ((IND & ~R128_FLAT_BIT) == 0) + +/* Draw a single line. Note that the device-dependent vertex data might + need to be changed based on the render state. */ +static void TAG(line)(GLcontext *ctx, + GLuint v0, GLuint v1, + GLuint pv) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128VertexPtr r128verts = R128_DRIVER_DATA(ctx->VB)->verts; + r128_vertex tmp0 = r128verts[v0].v; + r128_vertex tmp1 = r128verts[v1].v; + float width = ctx->Line.Width; + + if (IND & R128_FLAT_BIT) { + *(int *)&tmp1.dif_argb = + *(int *)&tmp0.dif_argb = + *(int *)&r128verts[pv].v.dif_argb; + } + + r128DrawLine(r128ctx, &tmp0, &tmp1, width); +} + +/* Draw a set of points. Note that the device-dependent vertex data + might need to be changed based on the render state. */ +static void TAG(points)(GLcontext *ctx, + GLuint first, GLuint last) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; + GLfloat size = ctx->Point.Size * 0.5; + int i; + + for(i = first; i <= last; i++) { + if(VB->ClipMask[i] == 0) { + r128_vertex *tmp = &r128verts[i].v; + r128DrawPoint(r128ctx, tmp, size); + } + } +} + +#endif + +/* Initialize the table of primitives to render. */ +static void TAG(init)(void) +{ + tri_tab[IND] = TAG(triangle); + quad_tab[IND] = TAG(quad); + +#if ((IND & ~R128_FLAT_BIT) == 0) + line_tab[IND] = TAG(line); + points_tab[IND] = TAG(points); +#endif +} + +#undef IND +#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c new file mode 100644 index 000000000..f14ec21bd --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c @@ -0,0 +1,470 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#include "r128_init.h" +#include "r128_mesa.h" +#include "r128_xmesa.h" +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_reg.h" +#include "r128_cce.h" +#include "r128_state.h" +#include "r128_vb.h" + +#include "stages.h" + +#define TEX0 \ +do { \ + v->v.tu0 = tc0[i][0]; \ + v->v.tv0 = tc0[i][1]; \ +} while (0) + +#define TEX1 \ +do { \ + v->v.tu1 = tc1[i][0]; \ + v->v.tv1 = tc1[i][1]; \ +} while (0) + +#define SPC \ +do { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.spec_frgb.r = spec[0]; \ + v->v.spec_frgb.g = spec[1]; \ + v->v.spec_frgb.b = spec[2]; \ +} while (0) + +#define FOG \ +do { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.spec_frgb.a = spec[3]; \ +} while (0) + +#define COL \ +do { \ + GLubyte *col = &(VB->Color[0]->data[i][0]); \ + v->v.dif_argb.a = col[3]; \ + v->v.dif_argb.r = col[0]; \ + v->v.dif_argb.g = col[1]; \ + v->v.dif_argb.b = col[2]; \ +} while (0) + +#if 1 +/* FIXME: These are handled by the Rage 128 */ +#define TEX0_4 +#define TEX1_4 +#else +#define TEX0_4 \ +do { \ + if (VB->TexCoordPtr[0]->size == 4) { \ + GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ + v = &(R128_DRIVER_DATA(VB)->verts[start]); \ + for (i = start; i < end; i++, v++) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw *= tc[i][3]; \ + v->v.tu0 *= oow; \ + v->v.tv0 *= oow; \ + } \ + } \ +} while (0) + +#if USE_RHW2 +#define TEX1_4 \ +do { \ + if (VB->TexCoordPtr[1]->size == 4) { \ + GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \ + v = &(R128_DRIVER_DATA(VB)->verts[start]); \ + for (i = start; i < end; i++, v++) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw2 *= tc[i][3]; \ + v->v.tu1 *= oow; \ + v->v.tv1 *= oow; \ + } \ + } \ +} while (0) +#else +#define TEX1_4 +#endif +#endif + +#if USE_RHW2 +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = r128height - win[1]; \ + v->v.z = scale * win[2]; \ + v->v.rhw = v->v.rhw2 = win[3]; \ +} while (0) +#else +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = r128height - win[1]; \ + v->v.z = scale * win[2]; \ + v->v.rhw = win[3]; \ +} while (0) +#endif + +#define NOP + +/* Setup the r128 vertex buffer entries */ +#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \ +static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ +{ \ + r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \ + __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ + r128VertexPtr v; \ + GLfloat (*tc0)[4]; \ + GLfloat (*tc1)[4]; \ + GLfloat r128height = dPriv->h; \ + GLfloat scale; \ + int i; \ + \ + (void) r128height; (void) r128ctx; \ + \ + gl_import_client_data(VB, VB->ctx->RenderFlags, \ + (VB->ClipOrMask \ + ? VEC_WRITABLE | VEC_GOOD_STRIDE \ + : VEC_GOOD_STRIDE)); \ + \ + switch (VB->ctx->Visual->DepthBits) { \ + case 16: scale = 1.0 / 65536.0; break; \ + case 24: scale = 1.0 / 16777216.0; break; \ + case 32: scale = 1.0 / 4294967296.0; break; \ + default: scale = 1.0 / 65536.0; break; \ + } \ + \ + tc0 = VB->TexCoordPtr[0]->data; \ + tc1 = VB->TexCoordPtr[1]->data; \ + \ + v = &(R128_DRIVER_DATA(VB)->verts[start]); \ + \ + if (VB->ClipOrMask == 0) \ + for (i = start; i < end; i++, v++) { \ + win; \ + col; \ + spec; \ + fog; \ + tex0; \ + tex1; \ + } \ + else \ + for (i = start; i < end; i++, v++) { \ + if (VB->ClipMask[i] == 0) { \ + win; \ + spec; \ + fog; \ + tex0; \ + tex1; \ + } \ + col; \ + } \ + tex0_4; \ + tex1_4; \ +} + + +SETUPFUNC(rs_wt0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_wt1, COORD, NOP, NOP, TEX1, NOP, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wt0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wft0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_wft1, COORD, NOP, NOP, TEX1, NOP, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wft0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wg, COORD, COL, NOP, NOP, NOP, NOP, NOP, NOP) +SETUPFUNC(rs_wgs, COORD, COL, NOP, NOP, NOP, NOP, SPC, NOP) +SETUPFUNC(rs_wgt0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_wgt1, COORD, COL, NOP, TEX1, NOP, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wgt0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wgst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP) +SETUPFUNC(rs_wgst1, COORD, COL, NOP, TEX1, NOP, TEX1_4, SPC, NOP) +SETUPFUNC(rs_wgst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP) +SETUPFUNC(rs_wgf, COORD, COL, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_wgfs, COORD, COL, NOP, NOP, NOP, NOP, SPC, FOG) +SETUPFUNC(rs_wgft0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_wgft1, COORD, COL, NOP, TEX1, NOP, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wgft0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wgfst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG) +SETUPFUNC(rs_wgfst1 , COORD, COL, NOP, TEX1, NOP, TEX1_4, SPC, FOG) +SETUPFUNC(rs_wgfst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) + +SETUPFUNC(rs_t0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_t1, NOP, NOP, NOP, TEX1, NOP, TEX1_4, NOP, NOP) +SETUPFUNC(rs_t0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_f, NOP, NOP, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_ft0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_ft1, NOP, NOP, NOP, TEX1, NOP, TEX1_4, NOP, FOG) +SETUPFUNC(rs_ft0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_g, NOP, COL, NOP, NOP, NOP, NOP, NOP, NOP) +SETUPFUNC(rs_gs, NOP, COL, NOP, NOP, NOP, NOP, SPC, NOP) +SETUPFUNC(rs_gt0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_gt1, NOP, COL, NOP, TEX1, NOP, TEX1_4, NOP, NOP) +SETUPFUNC(rs_gt0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_gst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP) +SETUPFUNC(rs_gst1, NOP, COL, NOP, TEX1, NOP, TEX1_4, SPC, NOP) +SETUPFUNC(rs_gst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP) +SETUPFUNC(rs_gf, NOP, COL, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_gfs, NOP, COL, NOP, NOP, NOP, NOP, SPC, FOG) +SETUPFUNC(rs_gft0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_gft1, NOP, COL, NOP, TEX1, NOP, TEX1_4, NOP, FOG) +SETUPFUNC(rs_gft0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_gfst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG) +SETUPFUNC(rs_gfst1, NOP, COL, NOP, TEX1, NOP, TEX1_4, SPC, FOG) +SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) + +static void rs_invalid(struct vertex_buffer *VB, GLuint start, GLuint end) +{ + fprintf(stderr, "r128RasterSetup(): invalid setup function\n"); +} + +typedef void (*setupFunc)(struct vertex_buffer *, GLuint, GLuint); +static setupFunc setup_func[0x80]; + +/* Initialize the table of vertex buffer setup functions */ +void r128SetupInit(void) +{ + int i; + + for (i = 0; i < 0x80; i++) setup_func[i] = rs_invalid; + + /* Funcs to build vertices from scratch */ + setup_func[R128_WIN_BIT|R128_TEX0_BIT] = rs_wt0; + setup_func[R128_WIN_BIT|R128_TEX1_BIT] = rs_wt1; + setup_func[R128_WIN_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wt0t1; + setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wft0; + setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_wft1; + setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wft0t1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT] = rs_wg; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT] = rs_wgs; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT] = rs_wgt0; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX1_BIT] = rs_wgt1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgt0t1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgst0; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_wgst1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgst0t1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT] = rs_wgf; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_wgfs; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wgft0; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_wgft1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgft0t1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgfst0; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_wgfst1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgfst0t1; + + /* Funcs to repair vertices */ + setup_func[R128_TEX0_BIT] = rs_t0; + setup_func[R128_TEX1_BIT] = rs_t1; + setup_func[R128_TEX0_BIT|R128_TEX1_BIT] = rs_t0t1; + setup_func[R128_FOG_BIT] = rs_f; + setup_func[R128_FOG_BIT|R128_TEX0_BIT] = rs_ft0; + setup_func[R128_FOG_BIT|R128_TEX1_BIT] = rs_ft1; + setup_func[R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_ft0t1; + setup_func[R128_RGBA_BIT] = rs_g; + setup_func[R128_RGBA_BIT|R128_SPEC_BIT] = rs_gs; + setup_func[R128_RGBA_BIT|R128_TEX0_BIT] = rs_gt0; + setup_func[R128_RGBA_BIT|R128_TEX1_BIT] = rs_gt1; + setup_func[R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gt0t1; + setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gst0; + setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_gst1; + setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gst0t1; + setup_func[R128_RGBA_BIT|R128_FOG_BIT] = rs_gf; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_gfs; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_gft0; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_gft1; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gft0t1; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gfst0; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_gfst1; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gfst0t1; +} + +/* Initialize the vertex buffer setup functions based on the current + rendering state */ +void r128ChooseRasterSetupFunc(GLcontext *ctx) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + int funcIndex = R128_WIN_BIT | R128_RGBA_BIT; + + if (ctx->Texture.Enabled & 0xf) { + if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE) + funcIndex &= ~R128_RGBA_BIT; + funcIndex |= R128_TEX0_BIT; + } + + if (ctx->Texture.Enabled & 0xf0) + funcIndex |= R128_TEX1_BIT; + + /* FIXME: Verify this works properly */ + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + funcIndex |= R128_SPEC_BIT; + + if (ctx->FogMode == FOG_FRAGMENT) + funcIndex |= R128_FOG_BIT; + + r128ctx->SetupIndex = funcIndex; + ctx->Driver.RasterSetup = setup_func[funcIndex]; +} + +/* Check to see if any updates of the vertex buffer entries are needed */ +void r128CheckPartialRasterSetup(GLcontext *ctx, + struct gl_pipeline_stage *s) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + int tmp = r128ctx->SetupDone; + + s->type = 0; + r128ctx->SetupDone = GL_FALSE; + + if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) return; + if (ctx->IndirectTriangles) return; + + r128ctx->SetupDone = tmp; +} + +/* Update the vertex buffer entries, if necessary */ +void r128PartialRasterSetup(struct vertex_buffer *VB) +{ + r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); + int new = VB->pipeline->new_outputs; + int available = VB->pipeline->outputs; + int index = 0; + + if (new & VERT_WIN) { + new = available; + index |= R128_WIN_BIT | R128_FOG_BIT; + } + + if (new & VERT_RGBA) index |= R128_RGBA_BIT | R128_SPEC_BIT; + if (new & VERT_TEX0_ANY) index |= R128_TEX0_BIT; + if (new & VERT_TEX1_ANY) index |= R128_TEX1_BIT; +#if 0 + /* FIXME */ + if (new & VERT_FOG_COORD) index |= R128_FOG_BIT; +#endif + + r128ctx->SetupDone &= ~index; + index &= r128ctx->SetupIndex; + r128ctx->SetupDone |= index; + + if (index) setup_func[index & ~R128_ALPHA_BIT](VB, VB->Start, VB->Count); +} + +/* Perform the raster setup for the fast path, if using CVA */ +void r128DoRasterSetup(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + + if (VB->Type == VB_CVA_PRECALC) r128PartialRasterSetup(VB); + else if (ctx->Driver.RasterSetup) ctx->Driver.RasterSetup(VB, + VB->CopyStart, + VB->Count); +} + +/* Resize an existing vertex buffer */ +void r128ResizeVB(struct vertex_buffer *VB, GLuint size) +{ + r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); + + while (r128vb->size < size) + r128vb->size *= 2; + + free(r128vb->vert_store); + r128vb->vert_store = malloc(sizeof(r128Vertex) * r128vb->size + 31); + if (!r128vb->vert_store) { + fprintf(stderr, "Cannot allocate vertex store! Exiting...\n"); + exit(1); + } + + r128vb->verts = (r128VertexPtr)(((CARD32)r128vb->vert_store + 31) & ~31); + + gl_vector1ui_free(&r128vb->clipped_elements); + gl_vector1ui_alloc(&r128vb->clipped_elements, + VEC_WRITABLE, r128vb->size, 32); + if (!r128vb->clipped_elements.start) { + fprintf(stderr, "Cannot allocate clipped elements! Exiting...\n"); + exit(1); + } + + free(VB->ClipMask); + VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * r128vb->size); + if (!VB->ClipMask) { + fprintf(stderr, "Cannot allocate clipmask! Exiting...\n"); + exit(1); + } +} + +/* Create a new device-dependent vertex buffer */ +void r128DDRegisterVB(struct vertex_buffer *VB) +{ + r128VertexBufferPtr r128vb; + + r128vb = (r128VertexBufferPtr)calloc(1, sizeof(*r128vb)); + + r128vb->size = VB->Size * 2; + r128vb->vert_store = malloc(sizeof(r128Vertex) * r128vb->size + 31); + if (!r128vb->vert_store) { + fprintf(stderr, "Cannot allocate vertex store! Exiting...\n"); + exit(1); + } + + r128vb->verts = (r128VertexPtr)(((CARD32)r128vb->vert_store + 31) & ~31); + + gl_vector1ui_alloc(&r128vb->clipped_elements, + VEC_WRITABLE, r128vb->size, 32); + if (!r128vb->clipped_elements.start) { + fprintf(stderr, "Cannot allocate clipped elements! Exiting...\n"); + exit(1); + } + + free(VB->ClipMask); + VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * r128vb->size); + if (!VB->ClipMask) { + fprintf(stderr, "Cannot allocate clipmask! Exiting...\n"); + exit(1); + } + + VB->driver_data = r128vb; +} + +/* Destroy a device-dependent vertex buffer */ +void r128DDUnregisterVB(struct vertex_buffer *VB) +{ + r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); + + if (r128vb) { + if (r128vb->vert_store) free(r128vb->vert_store); + gl_vector1ui_free(&r128vb->clipped_elements); + free(r128vb); + VB->driver_data = 0; + } +} diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h new file mode 100644 index 000000000..4f7c11d7f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h @@ -0,0 +1,150 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_VB_H_ +#define _R128_VB_H_ + +#ifdef GLX_DIRECT_RENDERING + +#define USE_RHW2 0 + +/* FIXME: This is endian-specific */ +typedef struct { + GLubyte b; + GLubyte g; + GLubyte r; + GLubyte a; +} r128Color; + +typedef struct { + GLfloat x, y, z; /* Coordinates in screen space */ + GLfloat rhw; /* Reciprocal homogeneous w */ + r128Color dif_argb; /* Diffuse color */ + r128Color spec_frgb; /* Specular color (alpha is fog) */ + GLfloat tu0, tv0; /* Texture 0 coordinates */ + GLfloat tu1, tv1; /* Texture 1 coordinates */ +#if USE_RHW2 + GLfloat rhw2; /* Reciprocal homogeneous w */ +#endif +} r128_vertex; + +#if USE_RHW2 +/* Format of vertices in r128_vertex struct */ +#define R128_FULL_VERTEX_FORMAT \ + R128_CCE_VC_FRMT_RHW | \ + R128_CCE_VC_FRMT_DIFFUSE_ARGB | \ + R128_CCE_VC_FRMT_SPEC_FRGB | \ + R128_CCE_VC_FRMT_S_T | \ + R128_CCE_VC_FRMT_S2_T2 | \ + R128_CCE_VC_FRMT_RHW2 + +/* Send a single vertex to the ring buffer */ +#define R128CCE_SEND_VERTEX(v) \ + do { \ + R128CCEF((v)->x); \ + R128CCEF((v)->y); \ + R128CCEF((v)->z); \ + R128CCEF((v)->rhw); \ + R128CCE(*(int *)&(v)->dif_argb); \ + R128CCE(*(int *)&(v)->spec_frgb); \ + R128CCEF((v)->tu0); \ + R128CCEF((v)->tv0); \ + R128CCEF((v)->tu1); \ + R128CCEF((v)->tv1); \ + R128CCEF((v)->rhw2); \ + } while (0) + +#else /* !USE_RHW2 */ + +/* Format of vertices in r128_vertex struct */ +#define R128_FULL_VERTEX_FORMAT \ + R128_CCE_VC_FRMT_RHW | \ + R128_CCE_VC_FRMT_DIFFUSE_ARGB | \ + R128_CCE_VC_FRMT_SPEC_FRGB | \ + R128_CCE_VC_FRMT_S_T | \ + R128_CCE_VC_FRMT_S2_T2 + +/* Send a single vertex to the ring buffer */ +#define R128CCE_SEND_VERTEX(v) \ + do { \ + R128CCEF((v)->x); \ + R128CCEF((v)->y); \ + R128CCEF((v)->z); \ + R128CCEF((v)->rhw); \ + R128CCE(*(int *)&(v)->dif_argb); \ + R128CCE(*(int *)&(v)->spec_frgb); \ + R128CCEF((v)->tu0); \ + R128CCEF((v)->tv0); \ + R128CCEF((v)->tu1); \ + R128CCEF((v)->tv1); \ + } while (0) +#endif + +/* FIXME: We currently only have assembly for 16-stride vertices */ +typedef union { + r128_vertex v; + float f[16]; +} r128Vertex, *r128VertexPtr; + +/* Vertex buffer for use when on the fast path */ +typedef struct { + GLuint size; /* Number of vertices in store */ + void *vert_store; /* Storage for vertex buffer */ + r128VertexPtr verts; /* Aligned start of verts in storage */ + int last_vert; /* Index of last vertex used */ + GLvector1ui clipped_elements; /* List of clipped elements */ +} *r128VertexBufferPtr; + +#define R128_DRIVER_DATA(vb) ((r128VertexBufferPtr)((vb)->driver_data)) + +#define R128_SPEC_BIT 0x01 +#define R128_FOG_BIT 0x02 +#define R128_ALPHA_BIT 0x04 /* GL_BLEND, not used */ +#define R128_TEX1_BIT 0x08 +#define R128_TEX0_BIT 0x10 +#define R128_RGBA_BIT 0x20 +#define R128_WIN_BIT 0x40 + +extern void r128SetupInit(void); +extern void r128ChooseRasterSetupFunc(GLcontext *ctx); +extern void r128CheckPartialRasterSetup(GLcontext *ctx, + struct gl_pipeline_stage *s); +extern void r128PartialRasterSetup(struct vertex_buffer *VB); +extern void r128DoRasterSetup(struct vertex_buffer *VB); +extern void r128ResizeVB(struct vertex_buffer *VB, GLuint size); +extern void r128DDRegisterVB(struct vertex_buffer *VB); +extern void r128DDUnregisterVB(struct vertex_buffer *VB); + +#endif +#endif /* _R128_VB_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c new file mode 100644 index 000000000..60d528813 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c @@ -0,0 +1,257 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifdef GLX_DIRECT_RENDERING + +/* r128 Mesa driver includes */ +#include "r128_init.h" +#include "r128_context.h" +#include "r128_xmesa.h" +#include "r128_state.h" +#include "r128_tex.h" +#include "r128_swap.h" + +/* Mesa src includes */ +#include "context.h" +#include "simple_list.h" +#include "mmath.h" + +#ifndef R128_DEBUG_FLAGS +int R128_DEBUG_FLAGS = (0 +#if 0 + | DEBUG_ALWAYS_SYNC + | DEBUG_VERBOSE_CCE + | 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 + ); +#endif + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#endif + +static r128ContextPtr r128Context = NULL; + + +/* Initialize the driver specific screen private data */ +GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) +{ + sPriv->private = (void *)r128CreateScreen(sPriv); + if (!sPriv->private) { + r128DestroyScreen(sPriv); + return GL_FALSE; + } + + return GL_TRUE; +} + +/* Reset the driver specific screen private data */ +void XMesaResetDriver(__DRIscreenPrivate *sPriv) +{ + r128DestroyScreen(sPriv); +} + +/* Create and initialize the Mesa and driver specific visual data */ +GLvisual *XMesaCreateVisual(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config) +{ + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual(config->rgba, + config->doubleBuffer, + config->stereo, + _mesa_bitcount(visinfo->red_mask), + _mesa_bitcount(visinfo->green_mask), + _mesa_bitcount(visinfo->blue_mask), + config->alphaSize, + 0, /* index bits */ + config->depthSize, + config->stencilSize, + config->accumRedSize, + config->accumGreenSize, + config->accumBlueSize, + config->accumAlphaSize, + 0 /* num samples */); +} + +/* Create and initialize the Mesa and driver specific context data */ +GLboolean XMesaCreateContext(Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv) +{ + return r128CreateContext(dpy, mesaVis, driContextPriv); +} + +/* Destroy the Mesa and driver specific context data */ +void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) +{ + r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate; + + if (r128ctx == (void *)r128Context) r128Context = NULL; + r128DestroyContext(r128ctx); +} + +/* Create and initialize the Mesa and driver specific pixmap buffer data */ +GLframebuffer *XMesaCreateWindowBuffer(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) +{ + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); +} + +/* Create and initialize the Mesa and driver specific pixmap buffer data */ +GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) +{ +#if 0 + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0); +#else + return NULL; /* not implemented yet */ +#endif +} + +/* Copy the back color buffer to the front color buffer */ +void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) +{ + /* FIXME: This assumes buffer is currently bound to a context. This + needs to be able to swap buffers when not currently bound. Also, + this needs to swap according to buffer, and NOT according to + context! */ + if (r128Context == NULL) return; + + /* Only swap buffers when a back buffer exists */ + if (R128_MESACTX(r128Context)->Visual->DBflag) { + FLUSH_VB(R128_MESACTX(r128Context), "swap buffers"); + r128SwapBuffers(r128Context); + } +} + +/* Force the context `c' to be the current context and associate with it + buffer `b' */ +GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + if (driContextPriv) { + r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate; + + if (r128Context && + r128ctx == (void *)r128Context && + driDrawPriv == R128_DRIDRAWABLE(r128Context)) + return GL_TRUE; + + r128Context = r128MakeCurrent(r128Context, r128ctx, driDrawPriv); + + gl_make_current2(R128_MESACTX(r128Context), + driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer); + + if (!R128_MESACTX(r128Context)->Viewport.Width) { + gl_Viewport(R128_MESACTX(r128Context), 0, 0, + driDrawPriv->w, driDrawPriv->h); + } + } else { + gl_make_current(0,0); + r128Context = NULL; + } + + return GL_TRUE; +} + +/* Force the context `c' to be unbound from its buffer */ +GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) +{ + return GL_TRUE; +} + +/* Update the hardware state. This is called if another context has + grabbed the hardware lock, which includes the X server. This + function also updates the driver's window state after the X server + moves, resizes or restacks a window -- the change will be reflected + in the drawable position and clip rects. Since the X server grabs + the hardware lock when it changes the window state, this routine will + automatically be called after such a change. */ +/* NOTE: This routine is only called while holding the hardware lock. */ +void XMesaUpdateState(__DRIcontextPrivate *driContextPriv) +{ + r128ContextPtr r128ctx = driContextPriv->driverPrivate; + __DRIscreenPrivate *sPriv = R128_DRISCREEN(r128ctx); + __DRIdrawablePrivate *dPriv = R128_DRIDRAWABLE(r128ctx); + int stamp = dPriv->lastStamp; + + /* The window might have moved, so we might need to get new clip + rects. + + NOTE: This releases and regrabs the hw lock to allow the X server + to respond to the DRI protocol request for new drawable info. + Since the hardware state depends on having the latest drawable + clip rects, all state checking must be done _after_ this call. */ + XMESA_VALIDATE_DRAWABLE_INFO(r128ctx->display, sPriv, dPriv); + + r128UpdateState(r128ctx, (stamp != dPriv->lastStamp)); +} + +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we'd register new extension functions with the dispatcher. + */ +void __driRegisterExtensions(void) +{ +} + +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h new file mode 100644 index 000000000..ca6fc127b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h @@ -0,0 +1,44 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and 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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_XMESA_H_ +#define _R128_XMESA_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void XMesaUpdateState(__DRIcontextPrivate *driContextPriv); +extern void __driRegisterExtensions(void); + +#endif +#endif /* _R128_XMESA_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile index c159a8e76..4a6a8e0ff 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile +++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile @@ -79,7 +79,8 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX) fxglidew.o fxpipeline.o fxrender.o fxsanity.o fxsetup.o \ fxtexman.o fxtrifuncs.o fxvsetup.o - MESASRCS = ../../accum.c \ + MESASRCS = ../../aatriangle.c \ + ../../accum.c \ ../../alpha.c \ ../../alphabuf.c \ ../../attrib.c \ @@ -109,7 +110,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX) ../../glthread.c \ ../../hash.c \ ../../image.c \ - ../../imaging.o \ + ../../imaging.c \ ../../light.c \ ../../lines.c \ ../../logic.c \ @@ -120,6 +121,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX) ../../pb.c \ ../../pipeline.c \ ../../pixel.c \ + ../../pixeltex.c \ ../../points.c \ ../../polygon.c \ ../../quads.c \ @@ -136,6 +138,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX) ../../texobj.c \ ../../texstate.c \ ../../texture.c \ + ../../texutil.c \ ../../translate.c \ ../../triangle.c \ ../../varray.c \ @@ -152,7 +155,8 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX) ../../zoom.c \ ../../X86/common_x86.c - MESAOBJS = ../../accum.o \ + MESAOBJS = ../../aatriangle.o \ + ../../accum.o \ ../../alpha.o \ ../../alphabuf.o \ ../../attrib.o \ @@ -191,6 +195,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX) ../../pb.o \ ../../pipeline.o \ ../../pixel.o \ + ../../pixeltex.o \ ../../points.o \ ../../polygon.o \ ../../quads.o \ @@ -207,6 +212,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX) ../../texobj.o \ ../../texstate.o \ ../../texture.o \ + ../../texutil.o \ ../../translate.o \ ../../triangle.o \ ../../varray.o \ @@ -239,8 +245,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX) MMX_OBJS = ../../X86/mmx_blend.o -XCOMM Disabling 3Dnow code for the time being. -#if 0 +#if MesaUse3DNow 3DNOW_SRCS = ../../X86/3dnow.c \ ../../X86/3dnow_norm_raw.S \ ../../X86/3dnow_xform_masked1.S \ @@ -271,10 +276,14 @@ XCOMM Disabling 3Dnow code for the time being. ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) - SRCS = $(DRISRCS) $(DRMSRCS) $(TDFXSRCS) $(MESASRCS) $(ASMSRCS) - OBJS = $(DRIOBJS) $(DRMOBJS) $(TDFXOBJS) $(MESAOBJS) $(ASMOBJS) + SRCS = $(DRISRCS) $(DRMSRCS) $(TDFXSRCS) $(MESASRCS) $(ASMSRCS) + OBJS = $(DRIOBJS) $(DRMOBJS) $(TDFXOBJS) $(MESAOBJS) $(ASMOBJS) + +REQUIREDLIBS = -lglide3x -lm +#if !GlxBuiltInTdfx +REQUIREDLIBS += -L../../../.. -lGL +#endif -REQUIREDLIBS += -lglide3x #if !GlxUseBuiltInDRIDriver #undef DoNormalLib NormalLibGlx diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.h index 3759512ee..251992d00 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_init.h @@ -41,9 +41,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri_tmm.h" #include "dri_mesaint.h" #include "dri_mesa.h" -#include "types.h" -#include "xmesaP.h" -/* #include "fxdrv.h" */ +#include "dri_xmesaapi.h" + typedef struct { drmHandle handle; @@ -98,7 +97,8 @@ typedef struct tfxMesaContext tdfxContextPrivate; extern GLboolean tdfxMapAllRegions(__DRIscreenPrivate *driScrnPriv); extern void tdfxUnmapAllRegions(__DRIscreenPrivate *driScrnPriv); -extern GLboolean tdfxInitHW(XMesaContext c); +extern GLboolean tdfxInitHW(__DRIdrawablePrivate *driDrawPrivate, + tdfxContextPrivate *cPriv); extern void XMesaWindowMoved(void); extern void XMesaUpdateState(int windowMoved); @@ -119,8 +119,8 @@ extern void grDRIImportFifo(int fifoPtr, int fifoRead); extern void grDRIInvalidateAll(void); extern void grDRIResetSAREA(void); -extern XMesaContext gCC; -extern tdfxContextPrivate *gCCPriv; +extern __DRIcontextPrivate *gCC; +/*000extern tdfxContextPrivate *gCCPriv;*/ /* You can turn this on to find locking conflicts. #define DEBUG_LOCKING @@ -167,7 +167,7 @@ extern int prevLockLine; #define LOCK_HARDWARE() \ do { \ char __ret=0; \ - __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \ + __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; \ __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; \ DEBUG_CHECK_LOCK(); \ DRM_CAS(&sPriv->pSAREA->lock, dPriv->driContextPriv->hHWContext, \ @@ -186,7 +186,7 @@ extern int prevLockLine; /* Unlock the hardware using the global current context */ #define UNLOCK_HARDWARE() \ do { \ - __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \ + __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; \ __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; \ XMesaSetSAREA(); \ DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, \ @@ -202,24 +202,26 @@ extern int prevLockLine; 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; \ - LOCK_HARDWARE(); \ - _nc = dPriv->numClipRects; \ - while (_nc--) { \ - if (gCCPriv->needClip) { \ - gCCPriv->clipMinX=dPriv->pClipRects[_nc].x1; \ - gCCPriv->clipMaxX=dPriv->pClipRects[_nc].x2; \ - gCCPriv->clipMinY=dPriv->pClipRects[_nc].y1; \ - gCCPriv->clipMaxY=dPriv->pClipRects[_nc].y2; \ - fxSetScissorValues(gCCPriv->glCtx); \ +#define BEGIN_CLIP_LOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; \ + int _nc; \ + LOCK_HARDWARE(); \ + _nc = dPriv->numClipRects; \ + while (_nc--) { \ + tdfxContextPrivate *gCCPriv = \ + (tdfxContextPrivate *) gCC->driverPrivate; \ + if (gCCPriv->needClip) { \ + gCCPriv->clipMinX=dPriv->pClipRects[_nc].x1; \ + gCCPriv->clipMaxX=dPriv->pClipRects[_nc].x2; \ + gCCPriv->clipMinY=dPriv->pClipRects[_nc].y1; \ + gCCPriv->clipMaxY=dPriv->pClipRects[_nc].y2; \ + fxSetScissorValues(gCCPriv->glCtx); \ } -#define END_CLIP_LOOP() \ - } \ - UNLOCK_HARDWARE(); \ +#define END_CLIP_LOOP() \ + } \ + UNLOCK_HARDWARE(); \ } while (0) #endif diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c index 044f30a67..0bafa3190 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_inithw.c @@ -36,13 +36,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tdfx_init.h" #include <glide.h> -GLboolean tdfxInitHW(XMesaContext c) +GLboolean tdfxInitHW(__DRIdrawablePrivate *driDrawPriv, + tdfxContextPrivate *fxMesa) { /* KW: Would be nice to make one of these a member of the other. */ - tdfxContextPrivate *cPriv = (tdfxContextPrivate*)c->private; - tdfxContextPrivate *fxMesa = cPriv; - __DRIdrawablePrivate *driDrawPriv = c->driContextPriv->driDrawablePriv; __DRIscreenPrivate *driScrnPriv = driDrawPriv->driScreenPriv; tdfxScreenPrivate *sPriv = (tdfxScreenPrivate*)driScrnPriv->private; @@ -50,10 +48,10 @@ GLboolean tdfxInitHW(XMesaContext c) fprintf(stderr, "Debug locking enabled\n"); #endif - if (cPriv->initDone) return GL_TRUE; + if (fxMesa->initDone) return GL_TRUE; - cPriv->width=driDrawPriv->w; - cPriv->height=driDrawPriv->h; + fxMesa->width=driDrawPriv->w; + fxMesa->height=driDrawPriv->h; /* We have to use a light lock here, because we can't do any glide operations yet. No use of FX_* functions in this function. */ @@ -89,7 +87,7 @@ GLboolean tdfxInitHW(XMesaContext c) fxInitPixelTables(fxMesa, GL_FALSE); /* Load tables of pixel colors */ - cPriv->initDone=GL_TRUE; + fxMesa->initDone=GL_TRUE; return GL_TRUE; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c index a3973a8ab..505f4bb99 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c @@ -28,7 +28,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Daryll Strauss <daryll@precisioninsight.com> - * + * Brian E. Paul <brian@precisioninsight.com> */ #ifdef GLX_DIRECT_RENDERING @@ -37,23 +37,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <glide.h> #include "tdfx_init.h" #include "context.h" -#include "vbxform.h" #include "matrix.h" +#include "mmath.h" +#include "vbxform.h" -XMesaContext nullCC = 0; -XMesaContext gCC = 0; -tdfxContextPrivate *gCCPriv = 0; -static int count_bits(unsigned int n) -{ - int bits = 0; +__DRIcontextPrivate *gCC = 0; - while (n > 0) { - if (n & 1) bits++; - n >>= 1; - } - return bits; -} GLboolean XMesaInitDriver(__DRIscreenPrivate *driScrnPriv) { @@ -81,99 +71,44 @@ void XMesaResetDriver(__DRIscreenPrivate *driScrnPriv) Xfree(driScrnPriv->private); } -XMesaVisual XMesaCreateVisual(XMesaDisplay *display, - XMesaVisualInfo visinfo, - GLboolean rgb_flag, - GLboolean alpha_flag, - GLboolean db_flag, - GLboolean stereo_flag, - GLboolean ximage_flag, - GLint depth_size, - GLint stencil_size, - GLint accum_red_size, - GLint accum_green_size, - GLint accum_blue_size, - GLint accum_alpha_size, - GLint num_samples, - GLint level, - GLint visualCaveat ) +GLvisual *XMesaCreateVisual(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config) { - XMesaVisual v; - GLint redBits, greenBits, blueBits, alphaBits; - - /* Only RGB visuals are supported on the TDFX boards */ - if (!rgb_flag) return 0; - - v = (XMesaVisual)Xmalloc(sizeof(struct xmesa_visual)); - if (!v) return 0; - - v->visinfo = (XVisualInfo *)Xmalloc(sizeof(*visinfo)); - if(!v->visinfo) { - Xfree(v); - return 0; - } - memcpy(v->visinfo, visinfo, sizeof(*visinfo)); - - redBits = count_bits(visinfo->red_mask); - greenBits = count_bits(visinfo->green_mask); - blueBits = count_bits(visinfo->blue_mask); - alphaBits = (redBits == 8 && greenBits == 8 && blueBits == 8 && alpha_flag) ? 8 : 0; - - v->display = display; - v->level = level; - v->VisualCaveat = visualCaveat; - v->gl_visual = _mesa_create_visual(rgb_flag, - GL_FALSE, /* alpha flag */ - db_flag, - stereo_flag, - redBits, greenBits, blueBits, alphaBits, - 0, /* index bits */ - depth_size, - stencil_size, - accum_red_size, - accum_green_size, - accum_blue_size, - accum_alpha_size, - 0 /* num samples */ ); - if (!v->gl_visual) { - Xfree(v->visinfo); - Xfree(v); - return NULL; - } - else - return v; + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual( config->rgba, + config->doubleBuffer, + config->stereo, + _mesa_bitcount(visinfo->red_mask), + _mesa_bitcount(visinfo->green_mask), + _mesa_bitcount(visinfo->blue_mask), + config->alphaSize, + 0, /* index bits */ + config->depthSize, + config->stencilSize, + config->accumRedSize, + config->accumGreenSize, + config->accumBlueSize, + config->accumAlphaSize, + 0 /* num samples */ ); } -void XMesaDestroyVisual(XMesaVisual v) -{ - _mesa_destroy_visual(v->gl_visual); - Xfree(v->visinfo); - Xfree(v); -} -XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, - __DRIcontextPrivate *driContextPriv) +GLboolean XMesaCreateContext(Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv) { - XMesaContext c; tdfxContextPrivate *cPriv; __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; tdfxScreenPrivate *sPriv = (tdfxScreenPrivate *)driScrnPriv->private; TDFXSAREAPriv *saPriv; - GLcontext *shareCtx; /*int **fifoPtr;*/ - c = (XMesaContext)Xmalloc(sizeof(struct xmesa_context)); - if (!c) return 0; - - c->driContextPriv = driContextPriv; - c->xm_visual = v; - c->xm_buffer = 0; /* Set by MakeCurrent */ - c->display = v->display; - cPriv = (tdfxContextPrivate *)Xmalloc(sizeof(tdfxContextPrivate)); if (!cPriv) { - Xfree(c); - return NULL; + return GL_FALSE; } cPriv->hHWContext = driContextPriv->hHWContext; @@ -181,26 +116,12 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, /* deviceID = 0x05 = Voodoo3 */ /* deviceID = 0x09 = Voodoo5 (and Voodoo5?) */ cPriv->haveHwStencil = sPriv->deviceID == 0x9 && sPriv->cpp == 4; - c->private = (void *)cPriv; - - cPriv->glVis=v->gl_visual; - cPriv->glBuffer=gl_create_framebuffer(v->gl_visual, - GL_FALSE, /* software depth buffer? */ - v->gl_visual->StencilBits > 0 && !cPriv->haveHwStencil, - v->gl_visual->AccumRedBits > 0, - GL_FALSE /* software alpha channel */ - ); cPriv->screen_width=sPriv->width; cPriv->screen_height=sPriv->height; - cPriv->new_state = ~0; - if (share_list) - shareCtx=((tdfxContextPrivate*)(share_list->private))->glCtx; - else - shareCtx=0; - cPriv->glCtx=gl_create_context(v->gl_visual, shareCtx, (void*)cPriv, GL_TRUE); + cPriv->glCtx = driContextPriv->mesaContext; cPriv->initDone=GL_FALSE; saPriv=(TDFXSAREAPriv*)((char*)driScrnPriv->pSAREA+sizeof(XF86DRISAREARec)); @@ -210,41 +131,63 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list, sPriv->backOffset, sPriv->depthOffset, sPriv->textureOffset, sPriv->textureSize, &saPriv->fifoPtr, &saPriv->fifoRead); - return c; + driContextPriv->driverPrivate = (void *) cPriv; + + return GL_TRUE; } -void XMesaDestroyContext(XMesaContext c) +void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) { tdfxContextPrivate *cPriv; - cPriv=(tdfxContextPrivate*)c->private; + cPriv = (tdfxContextPrivate *) driContextPriv->driverPrivate; if (cPriv) { - gl_destroy_context(cPriv->glCtx); - gl_destroy_framebuffer(cPriv->glBuffer); + /* XXX XFree the tdfxContextPrivate struct? */ + driContextPriv->driverPrivate = NULL; } - if (c==gCC) { - gCC=0; - gCCPriv=0; + + if (driContextPriv == gCC) { + gCC = 0; } } -XMesaBuffer XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w, - __DRIdrawablePrivate *driDrawPriv) -{ - return (XMesaBuffer)1; -} -XMesaBuffer XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, - XMesaColormap c, __DRIdrawablePrivate *driDrawPriv) +GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) { - return (XMesaBuffer)1; + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); } -void XMesaDestroyBuffer(XMesaBuffer b) + +GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) { +#if 0 + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); +#else + return NULL; /* not implemented yet */ +#endif } -void XMesaSwapBuffers(XMesaBuffer b) + +void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) { FxI32 result; #ifdef STATS @@ -252,15 +195,20 @@ void XMesaSwapBuffers(XMesaBuffer b) extern int texSwaps; static int prevStalls=0; #endif + tdfxContextPrivate *gCCPriv; + /* ** NOT_DONE: This assumes buffer is currently bound to a context. ** This needs to be able to swap buffers when not currently bound. */ - if (gCC == NULL || gCCPriv == NULL) return; + if (gCC == NULL) + return; + + gCCPriv = (tdfxContextPrivate *) gCC->driverPrivate; FLUSH_VB( gCCPriv->glCtx, "swap buffers" ); - if (gCCPriv->glVis->DBflag) { + if (gCC->mesaContext->Visual->DBflag) { #ifdef STATS stalls=grFifoGetStalls(); if (stalls!=prevStalls) { @@ -277,56 +225,62 @@ void XMesaSwapBuffers(XMesaBuffer b) result=FX_grGetInteger(FX_PENDING_BUFFERSWAPS); } while (result>gCCPriv->maxPendingSwapBuffers); gCCPriv->stats.swapBuffer++; - } else { - fprintf(stderr, "No double buffer\n"); } } -GLboolean XMesaUnbindContext(XMesaContext c) +GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) { - if (c && c==gCC && gCCPriv) FX_grGlideGetState((GrState*)gCCPriv->state); - return GL_TRUE; + if (driContextPriv && driContextPriv == gCC) { + tdfxContextPrivate *gCCPriv; + gCCPriv = (tdfxContextPrivate *) gCC->driverPrivate; + FX_grGlideGetState((GrState*)gCCPriv->state); + } + return GL_TRUE; } -GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b) +GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) { - __DRIdrawablePrivate *driDrawPriv; + if (driContextPriv) { + tdfxContextPrivate *gCCPriv; - if (c) { - if (c==gCC) return GL_TRUE; - gCC = c; - gCCPriv = (tdfxContextPrivate *)c->private; + gCC = driContextPriv; + gCCPriv = (tdfxContextPrivate *)driContextPriv->driverPrivate; - driDrawPriv = gCC->driContextPriv->driDrawablePriv; if (!gCCPriv->initDone) { - if (!tdfxInitHW(c)) return GL_FALSE; + if (!tdfxInitHW(driDrawPriv, gCCPriv)) + return GL_FALSE; gCCPriv->width=0; XMesaWindowMoved(); FX_grGlideGetState((GrState*)gCCPriv->state); - } else { + } + else { FX_grSstSelect(gCCPriv->board); FX_grGlideSetState((GrState*)gCCPriv->state); XMesaWindowMoved(); } - gl_make_current(gCCPriv->glCtx, gCCPriv->glBuffer); + gl_make_current2(gCCPriv->glCtx, driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer); + fxSetupDDPointers(gCCPriv->glCtx); if (!gCCPriv->glCtx->Viewport.Width) gl_Viewport(gCCPriv->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h); - } else { + } + else { gl_make_current(0,0); - gCC = NULL; - gCCPriv = NULL; + gCC = NULL; } return GL_TRUE; } -void -XMesaWindowMoved() { - __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; - GLcontext *ctx; - - ctx=gCCPriv->glCtx; + +void XMesaWindowMoved(void) +{ + __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; + tdfxContextPrivate *gCCPriv = (tdfxContextPrivate *) gCC->driverPrivate; + GLcontext *ctx = gCCPriv->glCtx; + grDRIPosition(dPriv->x, dPriv->y, dPriv->w, dPriv->h, dPriv->numClipRects, dPriv->pClipRects); gCCPriv->numClipRects=dPriv->numClipRects; @@ -362,9 +316,11 @@ XMesaWindowMoved() { } /* This is called from within the LOCK_HARDWARE routine */ -void XMesaUpdateState(int windowMoved) { - __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; +void XMesaUpdateState(int windowMoved) +{ + __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; + tdfxContextPrivate *gCCPriv = (tdfxContextPrivate *) gCC->driverPrivate; TDFXSAREAPriv *saPriv=(TDFXSAREAPriv*)(((char*)sPriv->pSAREA)+sizeof(XF86DRISAREARec)); /* fprintf(stderr, "In FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */ @@ -389,8 +345,9 @@ void XMesaUpdateState(int windowMoved) { XMesaWindowMoved(); } -void XMesaSetSAREA() { - __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; +void XMesaSetSAREA(void) +{ + __DRIdrawablePrivate *dPriv = gCC->driDrawablePriv; __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; TDFXSAREAPriv *saPriv=(TDFXSAREAPriv*)(((char*)sPriv->pSAREA)+sizeof(XF86DRISAREARec)); |