Index: xc/config/cf/xfree86.cf =================================================================== RCS file: /cvsroot/dri/xc/xc/config/cf/xfree86.cf,v retrieving revision 1.16 diff -u -r1.16 xfree86.cf --- xc/config/cf/xfree86.cf 2000/11/08 03:12:28 1.16 +++ xc/config/cf/xfree86.cf 2000/11/30 22:17:47 @@ -114,6 +114,10 @@ # ifndef XFShadowFB # define XFShadowFB YES # endif +/* stereo module */ +# ifndef XFStereo +# define XFStereo YES +# endif /* vgahw module */ # ifndef XF86VgaHw # define XF86VgaHw YES @@ -216,6 +220,10 @@ # ifndef XFShadowFB # define XFShadowFB YES # endif +/* stereo module */ +# ifndef XFStereo +# define XFStereo YES +# endif /* fbdevhw module */ # ifndef XF86FBDevHw # define XF86FBDevHw YES @@ -264,6 +272,10 @@ # ifndef XFShadowFB # define XFShadowFB YES # endif +/* stereo module */ +# ifndef XFStereo +# define XFStereo YES +# endif /* XAA module */ # ifndef XF86XAA # define XF86XAA YES @@ -318,6 +330,10 @@ # ifndef XFShadowFB # define XFShadowFB YES # endif +/* stereo module */ +# ifndef XFStereo +# define XFStereo YES +# endif /* vgahw module */ # ifndef XF86VgaHw # define XF86VgaHw YES @@ -402,6 +418,10 @@ /* shadow fb module */ # ifndef XFShadowFB # define XFShadowFB YES +# endif +/* stereo module */ +# ifndef XFStereo +# define XFStereo YES # endif /* vgahw module */ # ifndef XF86VgaHw Index: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v retrieving revision 1.17 diff -u -r1.17 mga_xmesa.c --- xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c 2000/11/08 00:06:45 1.17 +++ xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c 2000/11/30 22:17:53 @@ -157,8 +157,10 @@ mgaScreen->mem = serverInfo->mem; mgaScreen->cpp = serverInfo->cpp; mgaScreen->frontPitch = serverInfo->frontPitch; - mgaScreen->frontOffset = serverInfo->frontOffset; - mgaScreen->backOffset = serverInfo->backOffset; + mgaScreen->frontleftOffset = serverInfo->frontleftOffset; + mgaScreen->frontrightOffset = serverInfo->frontrightOffset; + mgaScreen->backleftOffset = serverInfo->backleftOffset; + mgaScreen->backrightOffset = serverInfo->backrightOffset; mgaScreen->backPitch = serverInfo->backPitch; mgaScreen->depthOffset = serverInfo->depthOffset; mgaScreen->depthPitch = serverInfo->depthPitch; @@ -493,7 +495,7 @@ if (mgaCtx->driDrawable != driDrawPriv) { mgaCtx->driDrawable = driDrawPriv; mgaCtx->dirty = ~0; - mgaCtx->dirty_cliprects = (MGA_FRONT|MGA_BACK); + mgaCtx->dirty_cliprects = (MGA_FRONT_LEFT|MGA_BACK_LEFT); } if (!mgaCtx->glCtx->Viewport.Width) @@ -520,8 +522,8 @@ if (*(dPriv->pStamp) != dPriv->lastStamp) { mmesa->setupdone = 0; - mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); - mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) ); + mmesa->dirty_cliprects = (MGA_FRONT_LEFT|MGA_BACK_LEFT); + mgaUpdateRects( mmesa, (MGA_FRONT_LEFT|MGA_BACK_LEFT) ); } mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_CLIPRECTS; Index: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v retrieving revision 1.10 diff -u -r1.10 mga_xmesa.h --- xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h 2000/11/08 00:06:45 1.10 +++ xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h 2000/11/30 22:17:53 @@ -61,9 +61,11 @@ unsigned int mAccess; - unsigned int frontOffset; + unsigned int frontleftOffset; + unsigned int frontrightOffset; unsigned int frontPitch; - unsigned int backOffset; + unsigned int backleftOffset; + unsigned int backrightOffset; unsigned int backPitch; unsigned int depthOffset; Index: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v retrieving revision 1.8 diff -u -r1.8 mgabuffers.c --- xc/lib/GL/mesa/src/drv/mga/mgabuffers.c 2000/11/08 00:06:45 1.8 +++ xc/lib/GL/mesa/src/drv/mga/mgabuffers.c 2000/11/30 22:17:53 @@ -87,7 +87,7 @@ int i = 0, top = 0; - if (sarea->exported_buffers & MGA_BACK) { + if (sarea->exported_buffers & MGA_BACK_LEFT) { driDrawable->numBackClipRects = sarea->exported_nback; driDrawable->pBackClipRects = mmesa->tmp_boxes[0]; @@ -99,7 +99,7 @@ } - if (sarea->exported_buffers & MGA_FRONT) + if (sarea->exported_buffers & MGA_FRONT_LEFT) { int start = top; @@ -126,7 +126,7 @@ driDrawable->pStamp = &(driScreen->pSAREA->drawableTable[driDrawable->index].stamp); - mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK) & ~(sarea->exported_buffers); + mmesa->dirty_cliprects = (MGA_FRONT_LEFT|MGA_BACK_LEFT) & ~(sarea->exported_buffers); } @@ -151,13 +151,13 @@ fprintf(stderr, "sarea->exported_nback: %d\n", sarea->exported_nback); i = 0; - if (sarea->exported_buffers & MGA_BACK) + if (sarea->exported_buffers & MGA_BACK_LEFT) for ( ; i < sarea->exported_nback ; i++) fprintf(stderr, "back %d: %d,%d-%d,%d\n", i, sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1, sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2); - if (sarea->exported_buffers & MGA_FRONT) { + if (sarea->exported_buffers & MGA_FRONT_LEFT) { int start = i; int top = i + sarea->exported_nfront; for ( ; i < top ; i++) @@ -233,7 +233,7 @@ mmesa->dirty_cliprects = 0; } - if (mmesa->draw_buffer == MGA_FRONT) + if (mmesa->draw_buffer == MGA_FRONT_LEFT) mgaXMesaSetFrontClipRects( mmesa ); else mgaXMesaSetBackClipRects( mmesa ); @@ -262,24 +262,44 @@ if (mode == GL_FRONT_LEFT) { - mmesa->drawOffset = mmesa->mgaScreen->frontOffset; - mmesa->readOffset = mmesa->mgaScreen->frontOffset; - mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->frontOffset; + mmesa->drawOffset = mmesa->mgaScreen->frontleftOffset; + mmesa->readOffset = mmesa->mgaScreen->frontleftOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->frontleftOffset; mmesa->dirty |= MGA_UPLOAD_CTX; - mmesa->draw_buffer = MGA_FRONT; + mmesa->draw_buffer = MGA_FRONT_LEFT; mgaXMesaSetFrontClipRects( mmesa ); return GL_TRUE; } + else if (mode == GL_FRONT_RIGHT) + { + mmesa->drawOffset = mmesa->mgaScreen->frontrightOffset; + mmesa->readOffset = mmesa->mgaScreen->frontrightOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->frontrightOffset; + mmesa->dirty |= MGA_UPLOAD_CTX; + mmesa->draw_buffer = MGA_FRONT_RIGHT; + mgaXMesaSetFrontClipRects( mmesa ); + return GL_TRUE; + } else if (mode == GL_BACK_LEFT) { - mmesa->drawOffset = mmesa->mgaScreen->backOffset; - mmesa->readOffset = mmesa->mgaScreen->backOffset; - mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->backOffset; - mmesa->draw_buffer = MGA_BACK; + mmesa->drawOffset = mmesa->mgaScreen->backleftOffset; + mmesa->readOffset = mmesa->mgaScreen->backleftOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->backleftOffset; + mmesa->draw_buffer = MGA_BACK_LEFT; mmesa->dirty |= MGA_UPLOAD_CTX; mgaXMesaSetBackClipRects( mmesa ); return GL_TRUE; } + else if (mode == GL_BACK_RIGHT) + { + mmesa->drawOffset = mmesa->mgaScreen->backrightOffset; + mmesa->readOffset = mmesa->mgaScreen->backrightOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->backrightOffset; + mmesa->draw_buffer = MGA_BACK_RIGHT; + mmesa->dirty |= MGA_UPLOAD_CTX; + mgaXMesaSetBackClipRects( mmesa ); + return GL_TRUE; + } else { mmesa->Fallback |= MGA_FALLBACK_BUFFER; @@ -294,12 +314,23 @@ if (mode == GL_FRONT_LEFT) { - mmesa->readOffset = mmesa->mgaScreen->frontOffset; - mmesa->read_buffer = MGA_FRONT; + mmesa->readOffset = mmesa->mgaScreen->frontleftOffset; + mmesa->read_buffer = MGA_FRONT_LEFT; } - else + else if (mode == GL_FRONT_RIGHT) + { + mmesa->readOffset = mmesa->mgaScreen->frontleftOffset; + mmesa->read_buffer = MGA_FRONT_LEFT; + } + else if (mode == GL_BACK_LEFT) { - mmesa->readOffset = mmesa->mgaScreen->backOffset; - mmesa->read_buffer = MGA_BACK; + mmesa->readOffset = mmesa->mgaScreen->backleftOffset; + mmesa->read_buffer = MGA_BACK_LEFT; } + else + { + mmesa->readOffset = mmesa->mgaScreen->backleftOffset; + mmesa->read_buffer = MGA_BACK_RIGHT; + } } + Index: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v retrieving revision 1.13 diff -u -r1.13 mgaioctl.c --- xc/lib/GL/mesa/src/drv/mga/mgaioctl.c 2000/11/08 00:06:46 1.13 +++ xc/lib/GL/mesa/src/drv/mga/mgaioctl.c 2000/11/30 22:17:54 @@ -172,17 +172,29 @@ FLUSH_BATCH( mmesa ); if (mask & DD_FRONT_LEFT_BIT) { - clear.flags |= MGA_FRONT; + clear.flags |= MGA_FRONT_LEFT; clear.clear_color_mask = mmesa->Setup[MGA_CTXREG_PLNWT]; mask &= ~DD_FRONT_LEFT_BIT; } + if (mask & DD_FRONT_RIGHT_BIT) { + clear.flags |= MGA_FRONT_RIGHT; + clear.clear_color_mask = mmesa->Setup[MGA_CTXREG_PLNWT]; + mask &= ~DD_FRONT_RIGHT_BIT; + } + if (mask & DD_BACK_LEFT_BIT) { - clear.flags |= MGA_BACK; + clear.flags |= MGA_BACK_LEFT; clear.clear_color_mask = mmesa->Setup[MGA_CTXREG_PLNWT]; mask &= ~DD_BACK_LEFT_BIT; } + if (mask & DD_BACK_RIGHT_BIT) { + clear.flags |= MGA_BACK_RIGHT; + clear.clear_color_mask = mmesa->Setup[MGA_CTXREG_PLNWT]; + mask &= ~DD_BACK_RIGHT_BIT; + } + if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) { clear.flags |= MGA_DEPTH; clear.clear_depth_mask |= mmesa->depth_clear_mask; @@ -205,7 +217,7 @@ LOCK_HARDWARE( mmesa ); if (mmesa->dirty_cliprects) - mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK)); + mgaUpdateRects( mmesa, (MGA_FRONT_LEFT|MGA_BACK_LEFT)); /* flip top to bottom */ cy = dPriv->h-cy-ch; @@ -301,8 +313,8 @@ /* Use the frontbuffer cliprects */ - if (mmesa->dirty_cliprects & MGA_FRONT) - mgaUpdateRects( mmesa, MGA_FRONT ); + if (mmesa->dirty_cliprects & MGA_FRONT_LEFT) + mgaUpdateRects( mmesa, MGA_FRONT_LEFT ); pbox = dPriv->pClipRects; @@ -324,6 +336,8 @@ fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n"); #if 1 + /* FIXME -- better way of indicating this? */ + swap.stereo = mmesa->glCtx->Visual->StereoFlag; if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) { printf("send swap retcode = %d\n", retcode); exit(1); Index: xc/lib/GL/mesa/src/drv/mga/mgastate.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgastate.c,v retrieving revision 1.13 diff -u -r1.13 mgastate.c --- xc/lib/GL/mesa/src/drv/mga/mgastate.c 2000/11/08 00:06:46 1.13 +++ xc/lib/GL/mesa/src/drv/mga/mgastate.c 2000/11/30 22:17:54 @@ -1073,17 +1073,29 @@ 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; + mmesa->draw_buffer = MGA_BACK_LEFT; + mmesa->read_buffer = MGA_BACK_LEFT; + mmesa->drawOffset = mmesa->mgaScreen->backleftOffset; + mmesa->readOffset = mmesa->mgaScreen->backleftOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->backleftOffset; + } else if (ctx->Color.DriverDrawBuffer == GL_BACK_RIGHT) { + mmesa->draw_buffer = MGA_BACK_RIGHT; + mmesa->read_buffer = MGA_BACK_RIGHT; + mmesa->drawOffset = mmesa->mgaScreen->backrightOffset; + mmesa->readOffset = mmesa->mgaScreen->backrightOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->backrightOffset; + } else if (ctx->Color.DriverDrawBuffer == GL_FRONT_RIGHT) { + mmesa->draw_buffer = MGA_FRONT_RIGHT; + mmesa->read_buffer = MGA_FRONT_RIGHT; + mmesa->drawOffset = mmesa->mgaScreen->frontrightOffset; + mmesa->readOffset = mmesa->mgaScreen->frontrightOffset; + mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->frontrightOffset; } 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->drawOffset = mmesa->mgaScreen->frontleftOffset; + mmesa->readOffset = mmesa->mgaScreen->frontleftOffset; + mmesa->draw_buffer = MGA_FRONT_LEFT; + mmesa->read_buffer = MGA_FRONT_LEFT; + mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->frontleftOffset; } switch (mmesa->glCtx->Visual->DepthBits) { Index: xc/programs/Xserver/hw/xfree86/Imakefile =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/Imakefile,v retrieving revision 1.1.1.8 diff -u -r1.1.1.8 Imakefile --- xc/programs/Xserver/hw/xfree86/Imakefile 2000/11/07 22:10:38 1.1.1.8 +++ xc/programs/Xserver/hw/xfree86/Imakefile 2000/11/30 22:18:01 @@ -47,6 +47,10 @@ SHADOWFBDIR = shadowfb #endif +#if XFStereo +STEREODIR = stereo +#endif + #if XF86I2C I2CDIR = i2c #endif @@ -98,7 +102,7 @@ drivers $(LOADERDIR) $(VGAHWDIR) $(FBDEVHWDIR) $(RAMDACDIR) \ $(RACDIR) $(I2CDIR) $(DDCDIR) $(INPUTDIR) $(INT10DIR) parser \ scanpci doc xf86config dummylib $(XF86CFGDIR) $(XF86SETUPDIR) etc \ - $(SUPERPROBE) $(DRIVERSDK) $(XF8_32WIDDIR) + $(SUPERPROBE) $(DRIVERSDK) $(XF8_32WIDDIR) $(STEREODIR) #if !defined(OS2Architecture) && !defined(cygwinArchitecture) XF86CONFIG = XF86Config Index: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v retrieving revision 1.8 diff -u -r1.8 Imakefile --- xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile 2000/11/08 00:06:54 1.8 +++ xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile 2000/11/30 22:18:03 @@ -51,7 +51,7 @@ -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb -I$(EXTINCSRC) \ - -I$(SERVERSRC)/render \ + -I$(SERVERSRC)/render -I$(XF86SRC)/stereo \ -I$(XF86OSSRC)/vbe $(DRIINCLUDES) #endif Index: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.cpp =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.cpp,v retrieving revision 1.1.1.6 diff -u -r1.1.1.6 mga.cpp --- xc/programs/Xserver/hw/xfree86/drivers/mga/mga.cpp 2000/09/23 21:20:26 1.1.1.6 +++ xc/programs/Xserver/hw/xfree86/drivers/mga/mga.cpp 2000/11/30 22:18:03 @@ -130,6 +130,11 @@ This option is only supported by the G200 and G400, and only in 16 and 32 bits per pixel. Default: off. +.TP +.BI "Option \*qStereo\*q \*q" boolean \*q +This will enable stereoscopic support in the DRI driver. The card will pageflip +between the left and right frontbuffer so you will need hardware capable of +understanding this. .SH "SEE ALSO" XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__) .SH AUTHORS Index: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v retrieving revision 1.13 diff -u -r1.13 mga.h --- xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h 2000/11/14 20:22:23 1.13 +++ xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h 2000/11/30 22:18:03 @@ -270,6 +270,7 @@ int expandHeight; int expandY; #ifdef XF86DRI + Bool StereoEnabled; int agp_mode; Bool ReallyUseIrqZero; Bool have_quiescense; @@ -329,9 +330,11 @@ #define TRANSPARENCY_KEY 255 #define KEY_COLOR 0 -#define MGA_FRONT 0x1 -#define MGA_BACK 0x2 +#define MGA_FRONT_LEFT 0x1 +#define MGA_BACK_LEFT 0x2 #define MGA_DEPTH 0x4 +#define MGA_BACK_RIGHT 0x8 +#define MGA_FRONT_RIGHT 0x10 /* Prototypes */ @@ -376,6 +379,7 @@ Bool MgaLockUpdate(ScrnInfoPtr pScrn, drmLockFlags flags); void mgaGetQuiescence(ScrnInfoPtr pScrn); void mgaGetQuiescence_shared(ScrnInfoPtr pScrn); +void MGAChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer); #endif void MGARefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); void MGARefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); Index: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v retrieving revision 1.21 diff -u -r1.21 mga_dri.c --- xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c 2000/11/14 20:22:24 1.21 +++ xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c 2000/11/30 22:18:04 @@ -108,8 +108,10 @@ return FALSE; } - init.frontOffset = pMGADRI->frontOffset; - init.backOffset = pMGADRI->backOffset; + init.frontleftOffset = pMGADRI->frontleftOffset; + init.frontrightOffset = pMGADRI->frontrightOffset; + init.backleftOffset = pMGADRI->backleftOffset; + init.backrightOffset = pMGADRI->backrightOffset; init.depthOffset = pMGADRI->depthOffset; init.textureOffset = pMGADRI->textureOffset; init.textureSize = pMGADRI->textureSize; @@ -141,7 +143,7 @@ __GLXvisualConfig *pConfigs = 0; MGAConfigPrivPtr pMGAConfigs = 0; MGAConfigPrivPtr *pMGAConfigPtrs = 0; - int i, db, depth, stencil, accum; + int i, db, depth, stencil, accum, stereo; switch (pScrn->bitsPerPixel) { case 8: @@ -149,6 +151,8 @@ break; case 16: numConfigs = 8; + if (pMGA->StereoEnabled) + numConfigs = numConfigs * 2; if (!(pConfigs = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), numConfigs))) { @@ -170,60 +174,67 @@ i = 0; depth = 1; - for (accum = 0; accum <= 1; accum++) { - for (stencil = 0; stencil <= 1; stencil++) { /* no stencil for now */ - for (db=1; db>=0; db--) { - pConfigs[i].vid = -1; - pConfigs[i].class = -1; - pConfigs[i].rgba = TRUE; - pConfigs[i].redSize = 5; - pConfigs[i].greenSize = 6; - pConfigs[i].blueSize = 5; - pConfigs[i].alphaSize = 0; - pConfigs[i].redMask = 0x0000F800; - pConfigs[i].greenMask = 0x000007E0; - pConfigs[i].blueMask = 0x0000001F; - pConfigs[i].alphaMask = 0; - if (accum) { - pConfigs[i].accumRedSize = 16; - pConfigs[i].accumGreenSize = 16; - pConfigs[i].accumBlueSize = 16; - pConfigs[i].accumAlphaSize = 0; - } else { - pConfigs[i].accumRedSize = 0; - pConfigs[i].accumGreenSize = 0; - pConfigs[i].accumBlueSize = 0; - pConfigs[i].accumAlphaSize = 0; - } - if (db) - pConfigs[i].doubleBuffer = TRUE; - else - pConfigs[i].doubleBuffer = FALSE; - pConfigs[i].stereo = FALSE; - pConfigs[i].bufferSize = 16; - if (depth) - pConfigs[i].depthSize = 16; - else - pConfigs[i].depthSize = 0; - if (stencil) - pConfigs[i].stencilSize = 8; - else - pConfigs[i].stencilSize = 0; - pConfigs[i].auxBuffers = 0; - pConfigs[i].level = 0; - if (stencil || accum) - pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; - else - pConfigs[i].visualRating = GLX_NONE_EXT; - pConfigs[i].transparentPixel = 0; - pConfigs[i].transparentRed = 0; - pConfigs[i].transparentGreen = 0; - pConfigs[i].transparentBlue = 0; - pConfigs[i].transparentAlpha = 0; - pConfigs[i].transparentIndex = 0; - i++; - } - } + for (stereo = 0; stereo <= pMGA->StereoEnabled; stereo++) { + for (accum = 0; accum <= 1; accum++) { + for (stencil = 0; stencil <= 1; stencil++) { + for (db=1; db>=0; db--) { + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 5; + pConfigs[i].greenSize = 6; + pConfigs[i].blueSize = 5; + pConfigs[i].alphaSize = 0; + pConfigs[i].redMask = 0x0000F800; + pConfigs[i].greenMask = 0x000007E0; + pConfigs[i].blueMask = 0x0000001F; + pConfigs[i].alphaMask = 0; + if (accum) { + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 0; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + if (db) + pConfigs[i].doubleBuffer = TRUE; + else + pConfigs[i].doubleBuffer = FALSE; + + if(stereo) + pConfigs[i].stereo = TRUE; + else + pConfigs[i].stereo = FALSE; + + pConfigs[i].bufferSize = 16; + if (depth) + pConfigs[i].depthSize = 16; + else + pConfigs[i].depthSize = 0; + if (stencil) + pConfigs[i].stencilSize = 8; + else + pConfigs[i].stencilSize = 0; + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if (stencil || accum) + pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; + else + pConfigs[i].visualRating = GLX_NONE_EXT; + pConfigs[i].transparentPixel = 0; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + } } if (i != numConfigs) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -234,6 +245,8 @@ case 32: numConfigs = 8; + if (pMGA->StereoEnabled) + numConfigs = numConfigs * 2; if (!(pConfigs = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), numConfigs))) { @@ -255,63 +268,70 @@ i = 0; depth = 1; - for (accum = 0; accum <= 1; accum++) { - for (stencil = 0; stencil <= 1; stencil++) { - for (db=1; db>=0; db--) { - pConfigs[i].vid = -1; - pConfigs[i].class = -1; - pConfigs[i].rgba = TRUE; - pConfigs[i].redSize = 8; - pConfigs[i].greenSize = 8; - pConfigs[i].blueSize = 8; - pConfigs[i].alphaSize = 0; - pConfigs[i].redMask = 0x00FF0000; - pConfigs[i].greenMask = 0x0000FF00; - pConfigs[i].blueMask = 0x000000FF; - pConfigs[i].alphaMask = 0; - if (accum) { - pConfigs[i].accumRedSize = 16; - pConfigs[i].accumGreenSize = 16; - pConfigs[i].accumBlueSize = 16; - pConfigs[i].accumAlphaSize = 0; - } else { - pConfigs[i].accumRedSize = 0; - pConfigs[i].accumGreenSize = 0; - pConfigs[i].accumBlueSize = 0; - pConfigs[i].accumAlphaSize = 0; - } - if (db) - pConfigs[i].doubleBuffer = TRUE; - else - pConfigs[i].doubleBuffer = FALSE; - pConfigs[i].stereo = FALSE; - pConfigs[i].bufferSize = 32; - if (depth) - if (stencil) - pConfigs[i].depthSize = 24; + for (stereo = 0; stereo <= pMGA->StereoEnabled; stereo++) { + for (accum = 0; accum <= 1; accum++) { + for (stencil = 0; stencil <= 1; stencil++) { + for (db=1; db>=0; db--) { + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 8; + pConfigs[i].greenSize = 8; + pConfigs[i].blueSize = 8; + pConfigs[i].alphaSize = 0; + pConfigs[i].redMask = 0x00FF0000; + pConfigs[i].greenMask = 0x0000FF00; + pConfigs[i].blueMask = 0x000000FF; + pConfigs[i].alphaMask = 0; + if (accum) { + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 0; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + if (db) + pConfigs[i].doubleBuffer = TRUE; else - pConfigs[i].depthSize = 32; - else - pConfigs[i].depthSize = 0; - if (stencil) - pConfigs[i].stencilSize = 8; - else - pConfigs[i].stencilSize = 0; - pConfigs[i].auxBuffers = 0; - pConfigs[i].level = 0; - if (accum) - pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; - else - pConfigs[i].visualRating = GLX_NONE_EXT; - pConfigs[i].transparentPixel = 0; - pConfigs[i].transparentRed = 0; - pConfigs[i].transparentGreen = 0; - pConfigs[i].transparentBlue = 0; - pConfigs[i].transparentAlpha = 0; - pConfigs[i].transparentIndex = 0; - i++; - } - } + pConfigs[i].doubleBuffer = FALSE; + + if(stereo) + pConfigs[i].stereo = TRUE; + else + pConfigs[i].stereo = FALSE; + + pConfigs[i].bufferSize = 32; + if (depth) + if (stencil) + pConfigs[i].depthSize = 24; + else + pConfigs[i].depthSize = 32; + else + pConfigs[i].depthSize = 0; + if (stencil) + pConfigs[i].stencilSize = 8; + else + pConfigs[i].stencilSize = 0; + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if (accum) + pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; + else + pConfigs[i].visualRating = GLX_NONE_EXT; + pConfigs[i].transparentPixel = 0; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + } } if (i != numConfigs) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -497,7 +517,6 @@ pDRIInfo->SwapContext = MGADRISwapContext_shared; else pDRIInfo->SwapContext = MGADRISwapContext; - switch( pScrn->bitsPerPixel ) { case 8: pDRIInfo->InitBuffers = Mga8DRIInitBuffers; @@ -665,22 +684,42 @@ pMGADRI->frontPitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8); - pMGADRI->frontOffset = 0; /* pMGA->YDstOrg * (pScrn->bitsPerPixel / 8) */ - pMGADRI->backOffset = ((pScrn->virtualY + pMGA->numXAALines + 1) * - pScrn->displayWidth * - pMGADRI->cpp + 4095) & ~0xFFF; + pMGADRI->frontleftOffset = 0; /* pMGA->YDstOrg * (pScrn->bitsPerPixel / 8) */ + if (pMGA->StereoEnabled) { + /* FIXME -- Should check that the right buffer is inside the viewable + * area of the framebuffer. */ + pMGADRI->frontrightOffset = ((pScrn->virtualY + pMGA->numXAALines + 1) * + pScrn->displayWidth * + pMGADRI->cpp + 4095) & ~0xFFF; + pMGADRI->backleftOffset = (pMGADRI->frontrightOffset + pScrn->virtualY * + pScrn->displayWidth * pMGADRI->cpp + 4095) & ~0xFFF; + pMGADRI->backrightOffset = (pMGADRI->backleftOffset + pScrn->virtualY * + pScrn->displayWidth * pMGADRI->cpp + 4095) & ~0xFFF; + + }else{ + pMGADRI->backleftOffset = ((pScrn->virtualY + pMGA->numXAALines + 1) * + pScrn->displayWidth * + pMGADRI->cpp + 4095) & ~0xFFF; + pMGADRI->frontrightOffset = pMGADRI->frontleftOffset; + pMGADRI->backrightOffset = pMGADRI->backleftOffset; + } - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] calced backoffset: 0x%x\n", - pMGADRI->backOffset); + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] calced backoffset: 0x%x/0x%x\n", + pMGADRI->backleftOffset,pMGADRI->backrightOffset); + size = pMGADRI->cpp * pScrn->virtualX * pScrn->virtualY; size += 4095; size &= ~4095; pMGADRI->depthOffset = pMGA->FbUsableSize - size; pMGADRI->depthOffset &= ~4095; - pMGADRI->textureOffset = pMGADRI->backOffset + size; + if (pMGA->StereoEnabled) + pMGADRI->textureOffset = pMGADRI->backrightOffset + size; + else + pMGADRI->textureOffset = pMGADRI->backleftOffset + size; + pMGADRI->textureSize = pMGADRI->depthOffset - pMGADRI->textureOffset; if (pMGADRI->depthOffset < pMGADRI->textureOffset + 512*1024) { @@ -995,18 +1034,26 @@ MGADRIPtr pMGADRI = (MGADRIPtr)pMga->pDRIInfo->devPrivate; switch (which) { - case MGA_BACK: - OUTREG(MGAREG_DSTORG, pMGADRI->backOffset); - OUTREG(MGAREG_SRCORG, pMGADRI->backOffset); + case MGA_BACK_LEFT: + OUTREG(MGAREG_DSTORG, pMGADRI->backleftOffset); + OUTREG(MGAREG_SRCORG, pMGADRI->backleftOffset); + break; + case MGA_BACK_RIGHT: + OUTREG(MGAREG_DSTORG, pMGADRI->backrightOffset); + OUTREG(MGAREG_SRCORG, pMGADRI->backrightOffset); break; case MGA_DEPTH: OUTREG(MGAREG_DSTORG, pMGADRI->depthOffset); OUTREG(MGAREG_SRCORG, pMGADRI->depthOffset); break; + case MGA_FRONT_RIGHT: + OUTREG(MGAREG_DSTORG, pMGADRI->frontrightOffset); + OUTREG(MGAREG_SRCORG, pMGADRI->frontrightOffset); + break; default: - case MGA_FRONT: - OUTREG(MGAREG_DSTORG, pMGADRI->frontOffset); - OUTREG(MGAREG_SRCORG, pMGADRI->frontOffset); + case MGA_FRONT_LEFT: + OUTREG(MGAREG_DSTORG, pMGADRI->frontleftOffset); + OUTREG(MGAREG_SRCORG, pMGADRI->frontleftOffset); break; } } Index: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h,v retrieving revision 1.5 diff -u -r1.5 mga_dri.h --- xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h 2000/07/11 11:41:05 1.5 +++ xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h 2000/11/30 22:18:04 @@ -38,10 +38,12 @@ int height; int mem; int cpp; - unsigned int frontOffset; + unsigned int frontleftOffset; + unsigned int frontrightOffset; unsigned int frontPitch; - unsigned int backOffset; + unsigned int backleftOffset; + unsigned int backrightOffset; unsigned int backPitch; unsigned int depthOffset; @@ -92,7 +94,12 @@ unsigned int nbox; XF86DRIClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS]; + + /* This one is used to communicate the current offset of the viewable + * area. */ + unsigned int frame_offset; + /* Information about the most recently used 3d drawable. The * client fills in the req_* fields, the server fills in the * exported_ fields and puts the cliprects into boxes, above. Index: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v retrieving revision 1.15 diff -u -r1.15 mga_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c 2000/11/14 20:22:24 1.15 +++ xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c 2000/11/30 22:18:05 @@ -90,6 +90,7 @@ #include "xaa.h" #include "xf86cmap.h" #include "shadowfb.h" +#include "stereo.h" #include "fbdevhw.h" #ifdef XF86DRI @@ -220,7 +221,8 @@ OPTION_TV, OPTION_TVSTANDARD, OPTION_CABLETYPE, - OPTION_USEIRQZERO + OPTION_USEIRQZERO, + OPTION_STEREO } MGAOpts; static OptionInfoRec MGAOptions[] = { @@ -250,6 +252,7 @@ { OPTION_TVSTANDARD, "TVStandard", OPTV_ANYSTR, {0}, FALSE }, { OPTION_CABLETYPE, "CableType", OPTV_ANYSTR, {0}, FALSE }, { OPTION_USEIRQZERO, "UseIrqZero", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_STEREO, "Stereo", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -379,6 +382,11 @@ NULL }; +static const char *stereoSymbols[] = { + "StereoInit", + NULL +}; + static const char *vbeSymbols[] = { "VBEInit", "vbeDoEDID", @@ -1470,6 +1478,12 @@ "Zero (Dangerous)\n"); } + pMga->StereoEnabled = FALSE; + if (xf86GetOptValBool(MGAOptions, OPTION_STEREO, + &temp)) { + pMga->StereoEnabled = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Stereo enabled\n"); + } } #endif @@ -2265,6 +2279,14 @@ xf86LoaderReqSymLists(shadowSymbols, NULL); } + if (pMga->StereoEnabled) { + if (!xf86LoadSubModule(pScrn, "stereo")) { + MGAFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(stereoSymbols, NULL); + } + pMga->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; pMga->CurrentLayout.depth = pScrn->depth; pMga->CurrentLayout.displayWidth = pScrn->displayWidth; @@ -2899,7 +2921,6 @@ height = pScrn->virtualX; width = pScrn->virtualY; } - if(pMga->ShadowFB) { pMga->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height); @@ -2920,9 +2941,9 @@ if (!pMga->NoAccel && pMga->TexturedVideo != TRUE && pMga->SecondCrtc == FALSE) - pMga->directRenderingEnabled = MGADRIScreenInit(pScreen); + pMga->directRenderingEnabled = MGADRIScreenInit(pScreen); else - pMga->directRenderingEnabled = FALSE; + pMga->directRenderingEnabled = FALSE; #endif @@ -2971,6 +2992,7 @@ if (!pMga->NoAccel) MGAStormAccelInit(pScreen); + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); @@ -3008,7 +3030,6 @@ if(pMga->ShadowFB) { RefreshAreaFuncPtr refreshArea = MGARefreshArea; - if(pMga->Rotate) { if (!pMga->PointerMoved) { pMga->PointerMoved = pScrn->PointerMoved; @@ -3031,6 +3052,9 @@ #endif #ifdef XF86DRI + if (pMga->StereoEnabled && pMga->directRenderingEnabled) { + StereoInit(pScreen,(ChangeBufferPtr)MGAChangeFrontbuffer); + } /* Initialize the Warp engine */ if (pMga->directRenderingEnabled) { pMga->directRenderingEnabled = mgaConfigureWarp(pScrn); @@ -3117,6 +3141,19 @@ Base &= ~1; /* Not sure why */ Base *= 3; } + +#if XF86DRI + /* If we want the kernel to change between two offsets + * in the vblank interrupt handler we can't go around changing + * this offset without involving the kernel. + * This should also improve performance since we don't have + * to busywait for the vertical blank. */ + if (pMga->directRenderingEnabled) { + MGASAREAPtr sa = (MGASAREAPtr)DRIGetSAREAPrivate(pScrn->pScreen); + sa->frame_offset = (y*pLayout->displayWidth + x) * pLayout->bitsPerPixel / 8; + return; + } +#endif /* find start of retrace */ while (INREG8(0x1FDA) & 0x08); Index: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h,v retrieving revision 1.3 diff -u -r1.3 mga_reg.h --- xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h 2000/11/08 03:12:29 1.3 +++ xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h 2000/11/30 22:18:05 @@ -225,7 +225,7 @@ #define MGAREG_CRTC_DATA 0x1fd5 #define MGAREG_CRTCEXT_INDEX 0x1fde #define MGAREG_CRTCEXT_DATA 0x1fdf - +#define MGAREG_CACHEFLUSH 0x1fff /* MGA bits for registers PCI_OPTION_REG */ #define MGA1064_OPT_SYS_CLK_PCI ( 0x00 << 0 ) Index: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v retrieving revision 1.9 diff -u -r1.9 mga_storm.c --- xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c 2000/11/08 03:12:29 1.9 +++ xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c 2000/11/30 22:18:07 @@ -967,7 +967,18 @@ while(MGAISBUSY()); /* flush cache before a read (mga-1064g 5.1.6) */ - OUTREG8(MGAREG_CRTC_INDEX, 0); + +#if XF86DRI + if (pMga->directRenderingEnabled) { + /* Don't clobber CRTC_INDEX since the kernel module + * uses that for pageflipping. */ + OUTREG8(MGAREG_CACHEFLUSH,0); + }else{ +#else + { +#endif + OUTREG8(MGAREG_CRTC_INDEX, 0); + } if(pMga->AccelFlags & CLIPPER_ON) { pMga->AccelFlags &= ~CLIPPER_ON; OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); @@ -1083,6 +1094,44 @@ pMga->AccelFlags &= ~CLIPPER_ON; } +#ifdef XF86DRI +void MGAChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer) +{ + MGAPtr pMga = MGAPTR(pScrn); + MGADRIPtr pMGADRI = (MGADRIPtr)pMga->pDRIInfo->devPrivate; + + /* Now, this is quite ugly, but I'm not sure if there is any + * better way of doing this. + * Used to redirect software fallbacks to the correct buffer. + * XXX - Does this really catch all possible sw fallbacks? */ + + PixmapPtr pPixmap = (PixmapPtr) pScrn->pScreen->devPrivate; + + switch(buffer){ + case 0: + pMga->realSrcOrg = pMGADRI->frontleftOffset; + pMga->DstOrg = pMGADRI->frontleftOffset; + MGASelectBuffer(pScrn,MGA_FRONT_LEFT); + if (pPixmap->devPrivate.ptr != pMga->FbStart+pMGADRI->frontrightOffset + && pPixmap->devPrivate.ptr != pMga->FbStart) + FatalError("pPixmap->devPrivate.ptr doesn't point to fb\n"); + pPixmap->devPrivate.ptr = pMga->FbStart; + + break; + case 1: + pMga->realSrcOrg = pMGADRI->frontrightOffset; + pMga->DstOrg = pMGADRI->frontrightOffset; + MGASelectBuffer(pScrn,MGA_FRONT_RIGHT); + if (pPixmap->devPrivate.ptr != pMga->FbStart+pMGADRI->frontrightOffset + && pPixmap->devPrivate.ptr != pMga->FbStart) + FatalError("pPixmap->devPrivate.ptr doesn't point to fb\n"); + pPixmap->devPrivate.ptr = pMga->FbStart+pMGADRI->frontrightOffset; + + break; + } +} +#endif + #endif @@ -1142,6 +1191,17 @@ int start, end, SrcOrg = 0, DstOrg = 0; MGAPtr pMga = MGAPTR(pScrn); + + /* FIXME -- Ugly hack. This will make sure that we will access the + * Pixmap Cache even if the right frontbuffer has been selected. + * Will break dual-head I think. + * I'll try to move this into XAA during the next revision */ + + if (srcY >= pScrn->virtualY) { + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,0); + } + if (pMga->AccelFlags & LARGE_ADDRESSES) { SrcOrg = ((srcY & ~1023) * pMga->CurrentLayout.displayWidth * PSZ) >> 9; DstOrg = ((dstY & ~1023) * pMga->CurrentLayout.displayWidth * PSZ) >> 9; @@ -1185,6 +1245,11 @@ OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); } + /* FIXME -- UGLY HACK, see above. */ + if (srcY >= pScrn->virtualY) { + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,pMga->realSrcOrg); + } } @@ -1197,6 +1262,12 @@ int start, end; MGAPtr pMga = MGAPTR(pScrn); + + if (srcY >= pScrn->virtualY) { + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,0); + } + if(pMga->BltScanDirection & BLIT_UP) { srcY += h - 1; dstY += h - 1; @@ -1256,10 +1327,14 @@ OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] | MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL); OUTREG(MGAREG_CXRIGHT, 0xFFFF); + if (srcY >= pScrn->virtualY) { + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,pMga->realSrcOrg); + } return; } /* } } } (preserve pairs for pair matching) */ } - + WAITFIFO(6); OUTREG(MGAREG_DWGCTL, 0x040A400C); OUTREG(MGAREG_AR0, end); @@ -1268,16 +1343,24 @@ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] | MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL); + if (srcY >= pScrn->virtualY) { + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,pMga->realSrcOrg); + } return; } FASTBLIT_BAILOUT: - + WAITFIFO(4); OUTREG(MGAREG_AR0, end); OUTREG(MGAREG_AR3, start); OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); + if (srcY >= pScrn->virtualY) { /* Ugly hack */ + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,pMga->realSrcOrg); + } } @@ -1575,6 +1658,7 @@ ){ MGAPtr pMga = MGAPTR(pScrn); + pMga->AccelFlags |= CLIPPER_ON; pMga->expandDWORDs = (w + 31) >> 5; if((pMga->expandDWORDs * h) > pMga->MaxBlitDWORDS) { @@ -1619,7 +1703,7 @@ MGAPtr pMga = MGAPTR(pScrn); int dwords = pMga->expandDWORDs; CARD32 *src = (CARD32*)(pMga->ScratchBuffer); - + while(dwords > pMga->FifoSize) { WAITFIFO(pMga->FifoSize); XAAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, pMga->FifoSize); @@ -1892,6 +1976,10 @@ int start, end; w--; + if (srcy >= pScrn->virtualY) { + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,0); + } start = XYADDRESS(srcx, srcy) + skipleft; end = start + w; @@ -1900,6 +1988,10 @@ OUTREG(MGAREG_AR0, end); OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); + if (srcy >= pScrn->virtualY) { /* Ugly hack */ + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,pMga->realSrcOrg); + } } #endif @@ -1962,6 +2054,10 @@ int start, end, next, num; Bool resetDstOrg = FALSE; + if (srcy >= pScrn->virtualY) { + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,0); + } if (pMga->AccelFlags & LARGE_ADDRESSES) { int DstOrg = ((y & ~1023) * pScrn->displayWidth * PSZ) >> 9; int SrcOrg = ((srcy & ~1023) * pScrn->displayWidth * PSZ) >> 9; @@ -2029,6 +2125,10 @@ WAITFIFO(1); OUTREG(MGAREG_DSTORG, pMga->DstOrg); } + if (srcy >= pScrn->virtualY) { /* Ugly hack */ + WAITFIFO(1); + OUTREG(MGAREG_SRCORG,pMga->realSrcOrg); + } } @@ -2406,15 +2506,21 @@ MGANAME(SetupForSolidFill)(pScrn, 0, GXcopy, -1); while (nbox--) { - MGASelectBuffer(pScrn, MGA_BACK); + MGASelectBuffer(pScrn, MGA_BACK_LEFT); MGANAME(SubsequentSolidFillRect)(pScrn, pbox->x1, pbox->y1, pbox->x2-pbox->x1, pbox->y2-pbox->y1); + if (pMGA->StereoEnabled) { + MGASelectBuffer(pScrn, MGA_BACK_RIGHT); + MGANAME(SubsequentSolidFillRect)(pScrn, pbox->x1, pbox->y1, + pbox->x2-pbox->x1, pbox->y2-pbox->y1); + } + MGASelectBuffer(pScrn, MGA_DEPTH); MGANAME(SubsequentSolidFillRect)(pScrn, pbox->x1, pbox->y1, pbox->x2-pbox->x1, pbox->y2-pbox->y1); pbox++; } - MGASelectBuffer(pScrn, MGA_FRONT); + MGASelectBuffer(pScrn, MGA_FRONT_LEFT); pMGA->AccelInfoRec->NeedToSync = TRUE; } @@ -2547,14 +2653,20 @@ if ( w <= 0 ) continue; if ( h <= 0 ) continue; - MGASelectBuffer(pScrn, MGA_BACK); + MGASelectBuffer(pScrn, MGA_BACK_LEFT); MGANAME(SubsequentScreenToScreenCopy)(pScrn, x1, y1, destx,desty, w, h); + if (pMGA->StereoEnabled) { + MGASelectBuffer(pScrn, MGA_BACK_RIGHT); + MGANAME(SubsequentScreenToScreenCopy)(pScrn, x1, y1, + destx,desty, w, h); + } + MGASelectBuffer(pScrn, MGA_DEPTH); MGANAME(SubsequentScreenToScreenCopy)(pScrn, x1,y1, destx,desty, w, h); } - MGASelectBuffer(pScrn, MGA_FRONT); + MGASelectBuffer(pScrn, MGA_FRONT_LEFT); if (pboxNew2) { DEALLOCATE_LOCAL(pptNew2); @@ -2567,6 +2679,7 @@ pMGA->AccelInfoRec->NeedToSync = TRUE; } + #endif /* XF86DRI */ Index: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c,v retrieving revision 1.7 diff -u -r1.7 mga_wrap.c --- xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c 2000/11/08 00:06:55 1.7 +++ xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c 2000/11/30 22:18:07 @@ -154,26 +154,26 @@ * fit the current draw buffer. Otherwise return. */ - sa->exported_buffers = MGA_FRONT | MGA_BACK; + sa->exported_buffers = MGA_FRONT_LEFT | MGA_BACK_LEFT; if (sa->exported_nback + sa->exported_nfront >= MGA_NR_SAREA_CLIPRECTS) { - if (sa->req_draw_buffer == MGA_FRONT) { - sa->exported_buffers = MGA_FRONT; + if (sa->req_draw_buffer == MGA_FRONT_LEFT) { + sa->exported_buffers = MGA_FRONT_LEFT; if (sa->exported_nfront >= MGA_NR_SAREA_CLIPRECTS) goto finished; } else { - sa->exported_buffers = MGA_BACK; + sa->exported_buffers = MGA_BACK_LEFT; if (sa->exported_nback >= MGA_NR_SAREA_CLIPRECTS) goto finished; } } - if (sa->exported_buffers & MGA_BACK) { + if (sa->exported_buffers & MGA_BACK_LEFT) { for (i = 0 ; i < sa->exported_nback ; i++) *boxes++ = backboxes[i]; } - if (sa->exported_buffers & MGA_FRONT) { + if (sa->exported_buffers & MGA_FRONT_LEFT) { for (i = 0 ; i < sa->exported_nfront ; i++) *boxes++ = frontboxes[i]; } Index: xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h,v retrieving revision 1.5 diff -u -r1.5 xf86drmMga.h --- xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h 2000/11/08 00:07:16 1.5 +++ xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h 2000/11/30 22:18:09 @@ -38,9 +38,11 @@ #define MGA_CARD_TYPE_G200 1 #define MGA_CARD_TYPE_G400 2 -#define MGA_FRONT 0x1 -#define MGA_BACK 0x2 -#define MGA_DEPTH 0x4 +#define MGA_FRONT_LEFT 0x1 +#define MGA_BACK_LEFT 0x2 +#define MGA_DEPTH 0x4 +#define MGA_BACK_RIGHT 0x8 +#define MGA_FRONT_RIGHT 0x10 /* 3d state excluding texture units: */ @@ -129,8 +131,10 @@ int sarea_priv_offset; int primary_size; int warp_ucode_size; - unsigned int frontOffset; - unsigned int backOffset; + unsigned int frontleftOffset; + unsigned int frontrightOffset; + unsigned int backleftOffset; + unsigned int backrightOffset; unsigned int depthOffset; unsigned int textureOffset; unsigned int textureSize; Index: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c,v retrieving revision 1.3 diff -u -r1.3 xf86drmMga.c --- xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c 2000/09/24 09:34:06 1.3 +++ xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c 2000/11/30 22:18:09 @@ -91,8 +91,10 @@ init.sarea_priv_offset = info->sarea_priv_offset; init.primary_size = info->primary_size; init.warp_ucode_size = info->warp_ucode_size; - init.frontOffset = info->frontOffset; - init.backOffset = info->backOffset; + init.frontleftOffset = info->frontleftOffset; + init.frontrightOffset = info->frontrightOffset; + init.backleftOffset = info->backleftOffset; + init.backrightOffset = info->backrightOffset; init.depthOffset = info->depthOffset; init.textureOffset = info->textureOffset; init.textureSize = info->textureSize; Index: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c,v retrieving revision 1.24 diff -u -r1.24 mga_dma.c --- xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c 2000/09/29 01:47:11 1.24 +++ xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c 2000/11/30 22:18:10 @@ -41,8 +41,17 @@ ((drm_device_t *)dev)->maplist[MGA_REG(reg)]->handle) #define MGA_ADDR(reg) (MGA_BASE(reg) + reg) #define MGA_DEREF(reg) *(__volatile__ int *)MGA_ADDR(reg) +/* Won't work on alpha out of the box? */ +#define MGA_DEREF8(reg) *(__volatile__ u8 *)MGA_ADDR(reg) +#define MGA_DEREF16(reg) *(__volatile__ u16 *)MGA_ADDR(reg) + #define MGA_READ(reg) MGA_DEREF(reg) +#define MGA_READ8(reg) MGA_DEREF8(reg) +#define MGA_READ16(reg) MGA_DEREF16(reg) + #define MGA_WRITE(reg,val) do { MGA_DEREF(reg) = val; } while (0) +#define MGA_WRITE8(reg,val) do { MGA_DEREF8(reg) = val; } while (0) +#define MGA_WRITE16(reg,val) do { MGA_DEREF16(reg) = val; } while (0) #define PDEA_pagpxfer_enable 0x2 @@ -593,6 +602,45 @@ return retval; } + +static void mga_vsync_service(int irq, void *device, struct pt_regs *regs) +{ + static unsigned int lastoffset = 0; + + drm_device_t *dev = (drm_device_t *)device; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + unsigned int frameoffset = dev_priv->sarea_priv->frame_offset; + int tmp; + + MGA_WRITE(MGAREG_ICLEAR, 0x00000020); + + /* Check wether we are page flipping due to stereo support + * or if MGAAdjustFrame() have changed the offset. */ + if (( lastoffset != frameoffset + dev_priv->frontleftOffset && + lastoffset != frameoffset + dev_priv->frontrightOffset) || + dev_priv->frontleftOffset != dev_priv->frontrightOffset) { + + if (lastoffset >= dev_priv->frontrightOffset) { + lastoffset = frameoffset + dev_priv->frontleftOffset; + } else { + lastoffset = frameoffset + dev_priv->frontrightOffset; + } + + + + + lastoffset = lastoffset / 8; /* No go for 24 bpp? */ + + MGA_WRITE16(MGAREG_CRTC_INDEX, (lastoffset & 0x00FF00) | 0x0C); + MGA_WRITE16(MGAREG_CRTC_INDEX, ((lastoffset & 0x0000FF) << 8) | 0x0D); + MGA_WRITE8(MGAREG_CRTCEXT_INDEX, 0x00); + tmp = MGA_READ8(MGAREG_CRTCEXT_DATA); /* This should be cached somehow */ + MGA_WRITE8(MGAREG_CRTCEXT_DATA, (tmp & 0xF0) | ((lastoffset & 0x0F0000) >> 16)); + lastoffset = lastoffset * 8; + } +} + + static void mga_dma_service(int irq, void *device, struct pt_regs *regs) { drm_device_t *dev = (drm_device_t *)device; @@ -600,7 +648,9 @@ drm_mga_prim_buf_t *last_prim_buffer; atomic_inc(&dev->total_irq); - if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return; + + + MGA_WRITE(MGAREG_ICLEAR, 0x00000001); last_prim_buffer = dev_priv->last_prim; last_prim_buffer->num_dwords = 0; @@ -616,6 +666,16 @@ wake_up_interruptible(&dev_priv->wait_queue); } +static void mga_service_irq(int irq, void *device, struct pt_regs *regs) +{ + drm_device_t *dev = (drm_device_t *)device; + u32 status; + status = MGA_READ(MGAREG_STATUS); + + if(status & 0x00000001) mga_dma_service(irq,device,regs); + if(status & 0x00000020) mga_vsync_service(irq,device,regs); +} + static void mga_dma_task_queue(void *device) { mga_dma_schedule((drm_device_t *)device, 0); @@ -694,8 +754,10 @@ /* Scale primary size to the next page */ dev_priv->chipset = init->chipset; - dev_priv->frontOffset = init->frontOffset; - dev_priv->backOffset = init->backOffset; + dev_priv->frontleftOffset = init->frontleftOffset; + dev_priv->frontrightOffset = init->frontrightOffset; + dev_priv->backleftOffset = init->backleftOffset; + dev_priv->backrightOffset = init->backrightOffset; dev_priv->depthOffset = init->depthOffset; dev_priv->textureOffset = init->textureOffset; dev_priv->textureSize = init->textureSize; @@ -709,9 +771,10 @@ dev_priv->WarpPipe = 0xff000000; dev_priv->vertexsize = 0; - DRM_DEBUG("chipset=%d ucode_size=%d backOffset=%x depthOffset=%x\n", + DRM_DEBUG("chipset=%d ucode_size=%d backOffset=%x/%x depthOffset=%x\n", dev_priv->chipset, dev_priv->warp_ucode_size, - dev_priv->backOffset, dev_priv->depthOffset); + dev_priv->backleftOffset, dev_priv->backrightOffset, + dev_priv->depthOffset); DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %x\n", dev_priv->cpp, dev_priv->sgram, dev_priv->stride, dev_priv->mAccess); @@ -827,7 +890,7 @@ MGA_WRITE(MGAREG_IEN, 0); /* Install handler */ if ((retcode = request_irq(dev->irq, - mga_dma_service, + mga_service_irq, SA_SHIRQ, dev->devname, dev))) { @@ -837,8 +900,8 @@ return retcode; } /* After installing handler */ - MGA_WRITE(MGAREG_ICLEAR, 0x00000001); - MGA_WRITE(MGAREG_IEN, 0x00000001); + MGA_WRITE(MGAREG_ICLEAR, 0x00000021); + MGA_WRITE(MGAREG_IEN, 0x00000021); return 0; } Index: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h,v retrieving revision 1.5 diff -u -r1.5 mga_drm.h --- xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h 2000/08/30 22:34:28 1.5 +++ xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h 2000/11/30 22:18:10 @@ -67,9 +67,11 @@ #define MGA_CARD_TYPE_G200 1 #define MGA_CARD_TYPE_G400 2 -#define MGA_FRONT 0x1 -#define MGA_BACK 0x2 -#define MGA_DEPTH 0x4 +#define MGA_FRONT_LEFT 0x1 +#define MGA_BACK_LEFT 0x2 +#define MGA_DEPTH 0x4 +#define MGA_BACK_RIGHT 0x8 +#define MGA_FRONT_RIGHT 0x10 /* 3d state excluding texture units: */ @@ -162,8 +164,10 @@ int sarea_priv_offset; int primary_size; int warp_ucode_size; - unsigned int frontOffset; - unsigned int backOffset; + unsigned int frontleftOffset; + unsigned int frontrightOffset; + unsigned int backleftOffset; + unsigned int backrightOffset; unsigned int depthOffset; unsigned int textureOffset; unsigned int textureSize; @@ -199,6 +203,9 @@ unsigned int nbox; drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS]; + /* This one is used to communicate the current offset of the viewable + * area. */ + unsigned int frame_offset; /* Information about the most recently used 3d drawable. The * client fills in the req_* fields, the server fills in the @@ -208,7 +215,7 @@ * clobbering the boxes data. */ unsigned int req_drawable; /* the X drawable id */ - unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */ + unsigned int req_draw_buffer; /* MGA_FRONT_LEFT, MGA_BACK_LEFT, etc */ unsigned int exported_drawable; unsigned int exported_index; @@ -250,6 +257,7 @@ typedef struct _drm_mga_swap { int dummy; + int stereo; /* FIXME -- Any better way of indicating this? */ } drm_mga_swap_t; typedef struct _drm_mga_iload { Index: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h,v retrieving revision 1.15 diff -u -r1.15 mga_drv.h --- xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h 2000/09/29 01:47:11 1.15 +++ xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h 2000/11/30 22:18:10 @@ -71,8 +71,10 @@ int primary_size; int warp_ucode_size; int chipset; - unsigned int frontOffset; - unsigned int backOffset; + unsigned int frontleftOffset; + unsigned int frontrightOffset; + unsigned int backleftOffset; + unsigned int backrightOffset; unsigned int depthOffset; unsigned int textureOffset; unsigned int textureSize; @@ -376,6 +378,13 @@ #define MGAREG_YDSTORG 0x1c94 #define MGAREG_YTOP 0x1c98 #define MGAREG_ZORG 0x1c0c + +/* CRTC registers. Needed for pageflipping */ +#define MGAREG_CRTC_INDEX 0x1fd4 +#define MGAREG_CRTC_DATA 0x1fd5 +#define MGAREG_CRTCEXT_INDEX 0x1fde +#define MGAREG_CRTCEXT_DATA 0x1fdf + /* Warp registers */ #define MGAREG_WR0 0x2d00 Index: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c,v retrieving revision 1.21 diff -u -r1.21 mga_state.c --- xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c 2000/11/01 19:00:45 1.21 +++ xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c 2000/11/30 22:18:11 @@ -410,11 +410,13 @@ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; - if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset && - regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) { - DRM_DEBUG("BAD DSTORG: %x (front %x, back %x)\n\n", - regs[MGA_CTXREG_DSTORG], dev_priv->frontOffset, - dev_priv->backOffset); + if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontleftOffset && + regs[MGA_CTXREG_DSTORG] != dev_priv->frontrightOffset && + regs[MGA_CTXREG_DSTORG] != dev_priv->backleftOffset && + regs[MGA_CTXREG_DSTORG] != dev_priv->backrightOffset) { + DRM_DEBUG("BAD DSTORG: %x (front %x, back %x/%x)\n\n", + regs[MGA_CTXREG_DSTORG], dev_priv->frontleftOffset, + dev_priv->backleftOffset, dev_priv->backrightOffset); regs[MGA_CTXREG_DSTORG] = 0; return -1; } @@ -645,7 +647,7 @@ for (i = 0; i < nbox; i++) { unsigned int height = pbox[i].y2 - pbox[i].y1; - if (flags & MGA_FRONT) { + if (flags & MGA_FRONT_LEFT) { PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_PLNWT, clear_colormask); PRIMOUTREG(MGAREG_YDSTLEN, @@ -655,11 +657,11 @@ PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_FCOL, clear_color); - PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontleftOffset); PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd); } - if (flags & MGA_BACK) { + if (flags & MGA_FRONT_RIGHT) { PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_PLNWT, clear_colormask); PRIMOUTREG(MGAREG_YDSTLEN, @@ -669,10 +671,38 @@ PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_FCOL, clear_color); - PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontrightOffset); PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd); } + if (flags & MGA_BACK_LEFT) { + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_PLNWT, clear_colormask); + PRIMOUTREG(MGAREG_YDSTLEN, + (pbox[i].y1 << 16) | height); + PRIMOUTREG(MGAREG_FXBNDRY, + (pbox[i].x2 << 16) | pbox[i].x1); + + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_FCOL, clear_color); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->backleftOffset); + PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd); + } + + if (flags & MGA_BACK_RIGHT) { + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_PLNWT, clear_colormask); + PRIMOUTREG(MGAREG_YDSTLEN, + (pbox[i].y1 << 16) | height); + PRIMOUTREG(MGAREG_FXBNDRY, + (pbox[i].x2 << 16) | pbox[i].x1); + + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_FCOL, clear_color); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->backrightOffset); + PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd); + } + if (flags & MGA_DEPTH) { PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_PLNWT, clear_depthmask); @@ -696,8 +726,9 @@ PRIMADVANCE(dev_priv); } -static void mga_dma_dispatch_swap(drm_device_t * dev) +static void mga_dma_dispatch_swap(drm_device_t * dev, int stereo) { + /* XXX - the stereo parameter should be moved to the context? */ drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; @@ -714,21 +745,20 @@ PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DWGSYNC, 0x7100); PRIMOUTREG(MGAREG_DWGSYNC, 0x7000); - - PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontleftOffset); PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess); - PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset); + PRIMOUTREG(MGAREG_SRCORG, dev_priv->backleftOffset); PRIMOUTREG(MGAREG_AR5, pixel_stride); - + PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD); - + for (i = 0; i < nbox; i++) { unsigned int h = pbox[i].y2 - pbox[i].y1; unsigned int start = pbox[i].y1 * pixel_stride; - + PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1); PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1); PRIMOUTREG(MGAREG_FXBNDRY, @@ -736,13 +766,40 @@ PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, (pbox[i].y1 << 16) | h); } - + if (dev_priv->frontrightOffset != dev_priv->frontleftOffset) { + PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontrightOffset); + PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess); + if(stereo){ + PRIMOUTREG(MGAREG_SRCORG, dev_priv->backrightOffset); + }else{ + /* Need to copy the left buffer to both the left and + * right frontbuffer. Without this the screen looks + * very weird :) + */ + PRIMOUTREG(MGAREG_SRCORG, dev_priv->backleftOffset); + } + PRIMOUTREG(MGAREG_AR5, pixel_stride); + + for (i = 0; i < nbox; i++) { + unsigned int h = pbox[i].y2 - pbox[i].y1; + unsigned int start = pbox[i].y1 * pixel_stride; + + PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1); + PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1); + PRIMOUTREG(MGAREG_FXBNDRY, + pbox[i].x1 | ((pbox[i].x2 - 1) << 16)); + PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, + (pbox[i].y1 << 16) | h); + } + } + /* Force reset of DWGCTL */ PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_SRCORG, 0); PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); - + + PRIMADVANCE(dev_priv); } @@ -789,19 +846,24 @@ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_swap_t swap; + + if(copy_from_user(&swap, (drm_mga_swap_t *) arg, sizeof(swap))) + return -EFAULT; if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("mga_swap_bufs called without lock held\n"); return -EINVAL; } + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - + /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX; - mga_dma_dispatch_swap(dev); + mga_dma_dispatch_swap(dev,swap.stereo); PRIMUPDATE(dev_priv); set_bit(MGA_BUF_SWAP_PENDING, &dev_priv->current_prim->buffer_status);