summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/savage_dri.c2172
-rw-r--r--src/savage_dri.h184
-rw-r--r--src/savage_dripriv.h46
-rw-r--r--src/savage_drm.h248
-rw-r--r--src/savage_hwmc.c403
-rw-r--r--src/savage_sarea.h57
6 files changed, 3110 insertions, 0 deletions
diff --git a/src/savage_dri.c b/src/savage_dri.c
new file mode 100644
index 0000000..de3b073
--- /dev/null
+++ b/src/savage_dri.c
@@ -0,0 +1,2172 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef XF86DRI
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Priv.h"
+
+#include "xaalocal.h"
+#include "xaarop.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+
+#if 0
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb32.h"
+#endif
+
+#include "miline.h"
+
+
+/*#include "savage_vbe.h"*/
+#include "savage_regs.h"
+#include "savage_driver.h"
+#include "savage_bci.h"
+
+#define _XF86DRI_SERVER_
+#include "GL/glxtokens.h"
+#include "sarea.h"
+#include "savage_dri.h"
+#include "savage_sarea.h"
+
+static char SAVAGEKernelDriverName[] = "savage";
+static char SAVAGEClientDriverName[] = "savage";
+
+static Bool SAVAGEDRIOpenFullScreen(ScreenPtr pScreen);
+static Bool SAVAGEDRICloseFullScreen(ScreenPtr pScreen);
+/* DRI buffer management
+ */
+void SAVAGEDRIInitBuffers( WindowPtr pWin, RegionPtr prgn,
+ CARD32 index );
+void SAVAGEDRIMoveBuffers( WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index );
+
+/* almost the same besides set src/desc to */
+/* Primary Bitmap Description */
+
+static void
+SAVAGEDRISetupForScreenToScreenCopy(
+ ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned planemask, int transparency_color);
+
+
+static void
+SAVAGEDRISubsequentScreenToScreenCopy(
+ ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
+ int w, int h);
+
+
+static void
+SAVAGEDRISetupForSolidFill(
+ ScrnInfoPtr pScrn, int color, int rop, unsigned planemask);
+
+
+static void
+SAVAGEDRISubsequentSolidFillRect(
+ ScrnInfoPtr pScrn, int x, int y, int w, int h);
+
+#if 0
+extern int
+SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg,int pm,int *rop);
+#endif
+unsigned long SAVAGEDRIGetPhyAddress(ScrnInfoPtr pScrn,void * pointer);
+
+/* Initialize the visual configs that are supported by the hardware.
+ * These are combined with the visual configs that the indirect
+ * rendering core supports, and the intersection is exported to the
+ * client.
+ */
+static Bool SAVAGEInitVisualConfigs( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ int numConfigs = 0;
+ __GLXvisualConfig *pConfigs = 0;
+ SAVAGEConfigPrivPtr pSAVAGEConfigs = 0;
+ SAVAGEConfigPrivPtr *pSAVAGEConfigPtrs = 0;
+ int i, db, depth, stencil, accum;
+
+ switch ( pScrn->bitsPerPixel ) {
+ case 8:
+ case 24:
+ break;
+
+ case 16:
+ numConfigs = 8;
+
+ pConfigs = (__GLXvisualConfig*)xcalloc( sizeof(__GLXvisualConfig),
+ numConfigs );
+ if ( !pConfigs ) {
+ return FALSE;
+ }
+
+ pSAVAGEConfigs = (SAVAGEConfigPrivPtr)xcalloc( sizeof(SAVAGEConfigPrivRec),
+ numConfigs );
+ if ( !pSAVAGEConfigs ) {
+ xfree( pConfigs );
+ return FALSE;
+ }
+
+ pSAVAGEConfigPtrs = (SAVAGEConfigPrivPtr*)xcalloc( sizeof(SAVAGEConfigPrivPtr),
+ numConfigs );
+ if ( !pSAVAGEConfigPtrs ) {
+ xfree( pConfigs );
+ xfree( pSAVAGEConfigs );
+ return FALSE;
+ }
+
+ for ( i = 0 ; i < numConfigs ; i++ ) {
+ pSAVAGEConfigPtrs[i] = &pSAVAGEConfigs[i];
+ }
+
+ 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 = 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 ( accum || stencil ) {
+ 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,
+ "[drm] Incorrect initialization of visuals\n" );
+ return FALSE;
+ }
+ break;
+
+ case 32:
+ numConfigs = 8;
+
+ pConfigs = (__GLXvisualConfig*)xcalloc( sizeof(__GLXvisualConfig),
+ numConfigs );
+ if ( !pConfigs ) {
+ return FALSE;
+ }
+
+ pSAVAGEConfigs = (SAVAGEConfigPrivPtr)xcalloc( sizeof(SAVAGEConfigPrivRec),
+ numConfigs );
+ if ( !pSAVAGEConfigs ) {
+ xfree( pConfigs );
+ return FALSE;
+ }
+
+ pSAVAGEConfigPtrs = (SAVAGEConfigPrivPtr*)xcalloc( sizeof(SAVAGEConfigPrivPtr),
+ numConfigs );
+ if ( !pSAVAGEConfigPtrs ) {
+ xfree( pConfigs );
+ xfree( pSAVAGEConfigs );
+ return FALSE;
+ }
+
+ for ( i = 0 ; i < numConfigs ; i++ ) {
+ pSAVAGEConfigPtrs[i] = &pSAVAGEConfigs[i];
+ }
+
+ i = 0;
+ for ( accum = 0 ; accum <= 1 ; accum++ ) {
+ for ( depth = 0 ; depth <= 1 ; depth++ ) { /* and 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 = 8;
+ 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 ) {
+ pConfigs[i].depthSize = 24;
+ pConfigs[i].stencilSize = 8;
+ }
+ else {
+ pConfigs[i].depthSize = 0;
+ 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,
+ "[drm] Incorrect initialization of visuals\n" );
+ return FALSE;
+ }
+ break;
+
+ default:
+ /* Unexpected bits/pixels */
+ break;
+ }
+
+ psav->numVisualConfigs = numConfigs;
+ psav->pVisualConfigs = pConfigs;
+ psav->pVisualConfigsPriv = pSAVAGEConfigs;
+
+ GlxSetVisualConfigs( numConfigs, pConfigs, (void **)pSAVAGEConfigPtrs );
+
+ return TRUE;
+}
+
+static Bool SAVAGECreateContext( ScreenPtr pScreen, VisualPtr visual,
+ drm_context_t hwContext, void *pVisualConfigPriv,
+ DRIContextType contextStore )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+ savageAgpBufferPtr pAgp;
+
+ int ret,size,i;
+ unsigned long handle,map_handle;
+ drm_savage_sarea_t * pShare;
+ unsigned long offset;
+
+ if(psav->xvmcContext)
+ return FALSE;
+ else
+ {
+ psav->DRIrunning++;
+ }
+ /* alloc agp memory to dma */
+ pShare = (drm_savage_sarea_ptr)DRIGetSAREAPrivate(pScreen);
+ pShare->agp_offset=0;
+ /* find the available buffer*/
+ for (i=0,pAgp = pSAVAGEDRIServer->agpBuffer;i<pSAVAGEDRIServer->numBuffer;i++,pAgp++)
+ {
+ if (pAgp->flags==0)
+ break;
+ }
+ if (i >= pSAVAGEDRIServer->numBuffer)
+ {
+ return TRUE;
+ }
+
+ offset=pAgp->agp_offset;
+ size = DRM_SAVAGE_DMA_AGP_SIZE;
+ if (size <=0)
+ return TRUE;
+ ret=drmAgpAlloc( psav->drmFD,size,0,NULL,&handle);
+ if ( ret<0)
+ {
+ return TRUE;
+ }
+ ret=drmAgpBind( psav->drmFD,handle,offset);
+ if (ret<0)
+ {
+ return TRUE;
+ }
+ if (drmAddMap(psav->drmFD,
+ offset,
+ DRM_SAVAGE_DMA_AGP_SIZE,
+ DRM_AGP,
+ 0,
+ &map_handle)<0)
+ {
+ return TRUE;
+ }
+ pAgp->ctxOwner = hwContext;
+ pAgp->flags = 1;
+ pAgp->agp_handle = handle;
+ pAgp->map_handle = map_handle;
+ pShare->agp_offset=map_handle;
+
+ return TRUE;
+
+}
+
+static void SAVAGEDestroyContext( ScreenPtr pScreen, drm_context_t hwContext,
+ DRIContextType contextStore )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+ savageAgpBufferPtr pAgp;
+ drm_savage_sarea_t * pShare;
+ int i;
+ unsigned long handle,map_handle;
+
+ psav->DRIrunning--;
+
+ pShare = (drm_savage_sarea_ptr)DRIGetSAREAPrivate(pScreen);
+
+ for (i=0,pAgp = pSAVAGEDRIServer->agpBuffer;i<pSAVAGEDRIServer->numBuffer;i++,pAgp++)
+ {
+ if (pAgp->ctxOwner == hwContext)
+ break;
+ }
+ if (i >= pSAVAGEDRIServer->numBuffer || !pAgp->flags || !pAgp->agp_handle)
+ {
+ return;
+ }
+ handle = pAgp->agp_handle;
+ map_handle = pAgp->map_handle;
+ drmRmMap(psav->drmFD,map_handle);
+ drmAgpUnbind(psav->drmFD,handle);
+ drmAgpFree(psav->drmFD,handle);
+ pAgp->flags=0;
+ pAgp->ctxOwner=0;
+}
+
+#if 0
+/* Quiescence, locking
+ */
+#define SAVAGE_TIMEOUT 2048
+
+static void SAVAGEWaitForIdleDMA( ScrnInfoPtr pScrn )
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ int ret;
+ int i = 0;
+
+ for (;;) {
+ do {
+ ret = drmSAVAGEFlushDMA( psav->drmFD,
+ DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH );
+ } while ( ( ret == -EBUSY ) && ( i++ < SAVAGE_TIMEOUT ) );
+
+ if ( ret == 0 )
+ return;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
+ "[dri] Idle timed out, resetting engine...\n" );
+
+ drmSAVAGEEngineReset( psav->drmFD );
+ }
+}
+
+
+void SAVAGEGetQuiescence( ScrnInfoPtr pScrn )
+{
+ SavagePtr psav = SAVPTR(pScrn);
+
+ DRILock( screenInfo.screens[pScrn->scrnIndex], 0 );
+ psav->haveQuiescense = 1;
+
+ if ( psav->directRenderingEnabled ) {
+ SAVAGEFBLayout *pLayout = &psav->CurrentLayout;
+
+ SAVAGEWaitForIdleDMA( pScrn );
+
+ WAITFIFO( 11 );
+ OUTREG( SAVAGEREG_MACCESS, psav->MAccess );
+ OUTREG( SAVAGEREG_PITCH, pLayout->displayWidth );
+
+ psav->PlaneMask = ~0;
+ OUTREG( SAVAGEREG_PLNWT, psav->PlaneMask );
+
+ psav->BgColor = 0;
+ psav->FgColor = 0;
+ OUTREG( SAVAGEREG_BCOL, psav->BgColor );
+ OUTREG( SAVAGEREG_FCOL, psav->FgColor );
+ OUTREG( SAVAGEREG_SRCORG, psav->realSrcOrg );
+
+ psav->SrcOrg = 0;
+ OUTREG( SAVAGEREG_DSTORG, psav->DstOrg );
+ OUTREG( SAVAGEREG_OPMODE, SAVAGEOPM_DMA_BLIT );
+ OUTREG( SAVAGEREG_CXBNDRY, 0xFFFF0000 ); /* (maxX << 16) | minX */
+ OUTREG( SAVAGEREG_YTOP, 0x00000000 ); /* minPixelPointer */
+ OUTREG( SAVAGEREG_YBOT, 0x007FFFFF ); /* maxPixelPointer */
+
+ psav->AccelFlags &= ~CLIPPER_ON;
+ }
+}
+
+void SAVAGEGetQuiescenceShared( ScrnInfoPtr pScrn )
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEEntPtr pSAVAGEEnt = psav->entityPrivate;
+ SavagePtr pSAVAGE2 = SAVPTR(pSAVAGEEnt->pScrn_2);
+
+ DRILock( screenInfo.screens[pSAVAGEEnt->pScrn_1->scrnIndex], 0 );
+
+ psav = SAVPTR(pSAVAGEEnt->pScrn_1);
+ psav->haveQuiescense = 1;
+ pSAVAGE2->haveQuiescense = 1;
+
+ if ( pSAVAGEEnt->directRenderingEnabled ) {
+ SAVAGEWaitForIdleDMA( pSAVAGEEnt->pScrn_1 );
+ psav->RestoreAccelState( pScrn );
+ xf86SetLastScrnFlag( pScrn->entityList[0], pScrn->scrnIndex );
+ }
+}
+
+#endif
+
+/* move in SAVAGEDRISwapContext() */
+#if 0
+static void SAVAGESwapContext( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+
+ /* Arrange for dma_quiescence and xaa sync to be called as
+ * appropriate.
+ */
+ psav->LockHeld = 1; /* port as pMGA->haveQuiescense*/
+ psav->AccelInfoRec->NeedToSync = TRUE;
+}
+#endif
+
+/* no double-head */
+#if 0
+static void SAVAGESwapContextShared( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEEntPtr pSAVAGEEnt = psav->entityPrivate;
+ SavagePtr pSAVAGE2 = SAVPTR(pSAVAGEEnt->pScrn_2);
+
+ psav = SAVPTR(pSAVAGEEnt->pScrn_1);
+
+ psav->haveQuiescense = 0;
+ psav->AccelInfoRec->NeedToSync = TRUE;
+
+ pSAVAGE2->haveQuiescense = 0;
+ pSAVAGE2->AccelInfoRec->NeedToSync = TRUE;
+}
+#endif
+
+/* This is really only called from validate/postvalidate as we
+ * override the dri lock/unlock. Want to remove validate/postvalidate
+ * processing, but need to remove all client-side use of drawable lock
+ * first (otherwise there is noone recover when a client dies holding
+ * the drawable lock).
+ *
+ * What does this mean?
+ *
+ * - The above code gets executed every time a
+ * window changes shape or the focus changes, which isn't really
+ * optimal.
+ * - The X server therefore believes it needs to do an XAA sync
+ * *and* a dma quiescense ioctl each time that happens.
+ *
+ * We don't wrap wakeuphandler any longer, so at least we can say that
+ * this doesn't happen *every time the mouse moves*...
+ */
+static void
+SAVAGEDRISwapContext( ScreenPtr pScreen, DRISyncType syncType,
+ DRIContextType oldContextType, void *oldContext,
+ DRIContextType newContextType, void *newContext )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+
+#if 1
+ /* this case call from DRIDoWakeupandler, */
+ /* swap context in */
+ if ( syncType == DRI_3D_SYNC &&
+ oldContextType == DRI_2D_CONTEXT &&
+ newContextType == DRI_2D_CONTEXT )
+ {
+ psav->LockHeld = 1; /* port as pMGA->haveQuiescense*/
+ psav->AccelInfoRec->NeedToSync = TRUE;
+ }
+ /* this case call from DRIDoBlockHandler, */
+ /* swap context out */
+ else if (syncType == DRI_2D_SYNC &&
+ oldContextType == DRI_NO_CONTEXT &&
+ newContextType == DRI_2D_CONTEXT)
+ {
+ psav->LockHeld = 0;
+ psav->AccelInfoRec->NeedToSync = TRUE;
+ }
+#endif
+}
+
+/* no Double-Head */
+#if 0
+static void
+SAVAGEDRISwapContextShared( ScreenPtr pScreen, DRISyncType syncType,
+ DRIContextType oldContextType, void *oldContext,
+ DRIContextType newContextType, void *newContext )
+{
+#if 0
+ if ( syncType == DRI_3D_SYNC &&
+ oldContextType == DRI_2D_CONTEXT &&
+ newContextType == DRI_2D_CONTEXT )
+ {
+ SAVAGESwapContextShared( pScreen );
+ }
+#endif
+}
+#endif
+
+/* following I810 and R128 swaping method */
+/* MGA swaping method is for their double head */
+#if 0
+static void SAVAGEWakeupHandler( int screenNum, pointer wakeupData,
+ unsigned long result, pointer pReadmask )
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if ( xf86IsEntityShared( pScrn->entityList[0] ) ) {
+ SAVAGESwapContextShared( pScreen );
+ } else {
+ SAVAGESwapContext( pScreen );
+ }
+}
+
+static void SAVAGEBlockHandler( int screenNum, pointer blockData,
+ pointer pTimeout, pointer pReadmask )
+
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEEntPtr pSAVAGEEnt;
+
+ if ( psav->haveQuiescense ) {
+ if ( xf86IsEntityShared( pScrn->entityList[0] ) ) {
+ /* Restore to first screen */
+ psav->RestoreAccelState( pScrn );
+ xf86SetLastScrnFlag( pScrn->entityList[0], pScrn->scrnIndex );
+ pSAVAGEEnt = psav->entityPrivate;
+
+ if ( pSAVAGEEnt->directRenderingEnabled ) {
+ DRIUnlock( screenInfo.screens[pSAVAGEEnt->pScrn_1->scrnIndex] );
+ }
+ } else {
+ if ( psav->directRenderingEnabled ) {
+ DRIUnlock( pScreen );
+ }
+ }
+ psav->haveQuiescense = 0;
+ }
+}
+#endif
+
+void SAVAGESelectBuffer( ScrnInfoPtr pScrn, int which )
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
+
+ psav->WaitIdleEmpty(psav);
+
+ OUTREG(0x48C18,INREG(0x48C18)&(~0x00000008));
+
+ switch ( which ) {
+ case SAVAGE_BACK:
+ OUTREG( 0x8170, pSAVAGEDRI->backOffset );
+ OUTREG( 0x8174, pSAVAGEDRI->backBitmapDesc );
+ break;
+ case SAVAGE_DEPTH:
+ OUTREG( 0x8170, pSAVAGEDRI->depthOffset );
+ OUTREG( 0x8174, pSAVAGEDRI->depthBitmapDesc );
+ break;
+ default:
+ case SAVAGE_FRONT:
+ OUTREG( 0x8170, pSAVAGEDRI->frontOffset );
+ OUTREG( 0x8174, pSAVAGEDRI->frontBitmapDesc );
+ break;
+ }
+ OUTREG(0x48C18,INREG(0x48C18)|(0x00000008));
+ psav->WaitIdleEmpty(psav);
+
+}
+
+
+static unsigned int mylog2( unsigned int n )
+{
+ unsigned int log2 = 1;
+
+ n--;
+ while ( n > 1 ) n >>= 1, log2++;
+
+ return log2;
+}
+
+static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+ unsigned long mode;
+ unsigned int vendor, device;
+ int ret;
+ int size,numbuffer,i;
+ savageAgpBufferPtr agpbuffer;
+
+ /* FIXME: Make these configurable...
+ */
+ /*pSAVAGEDRIServer->agp.size = 16 * 1024 * 1024;*/
+ pSAVAGEDRIServer->agp.size = psav->agpSize * 1024 * 1024;
+ pSAVAGEDRIServer->agp.offset = pSAVAGEDRIServer->agp.size;
+
+ pSAVAGEDRIServer->agpTextures.offset = 0;
+ /*pSAVAGEDRIServer->agpTextures.size = 16*1024*1024;*/
+ pSAVAGEDRIServer->agpTextures.size = psav->agpSize * 1024 * 1024;
+ pSAVAGEDRIServer->logAgpTextureGranularity = 10;
+
+ if ( drmAgpAcquire( psav->drmFD ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not available\n" );
+ return FALSE;
+ }
+
+ mode = drmAgpGetMode( psav->drmFD ); /* Default mode */
+ vendor = drmAgpVendorId( psav->drmFD );
+ device = drmAgpDeviceId( psav->drmFD );
+
+ mode &= ~SAVAGE_AGP_MODE_MASK;
+
+ switch ( psav->agpMode ) {
+ case 4:
+ mode |= SAVAGE_AGP_4X_MODE;
+ case 2:
+ mode |= SAVAGE_AGP_2X_MODE;
+ case 1:
+ default:
+ mode |= SAVAGE_AGP_1X_MODE;
+ }
+
+ /* mode |= SAVAGE_AGP_1X_MODE;*/
+
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
+ mode, vendor, device,
+ psav->PciInfo->vendor,
+ psav->PciInfo->chipType );
+
+ if ( drmAgpEnable( psav->drmFD, mode ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" );
+ drmAgpRelease( psav->drmFD );
+ return FALSE;
+ }
+
+ ret = drmAgpAlloc( psav->drmFD, pSAVAGEDRIServer->agp.size,
+ 0, NULL, &pSAVAGEDRIServer->agp.handle );
+ if ( ret < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret );
+ drmAgpRelease( psav->drmFD );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] %d kB allocated with handle 0x%08x\n",
+ pSAVAGEDRIServer->agp.size/1024, pSAVAGEDRIServer->agp.handle );
+
+ if ( drmAgpBind( psav->drmFD, pSAVAGEDRIServer->agp.handle, 0 ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind memory\n" );
+ drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle );
+ drmAgpRelease( psav->drmFD );
+ return FALSE;
+ }
+
+ if ( drmAddMap( psav->drmFD,
+ pSAVAGEDRIServer->agpTextures.offset,
+ pSAVAGEDRIServer->agpTextures.size,
+ DRM_AGP, 0,
+ &pSAVAGEDRIServer->agpTextures.handle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not add agpTextures \n" );
+ return FALSE;
+ }
+ /* pSAVAGEDRIServer->agp_offset=pSAVAGEDRIServer->agpTexture.size;*/
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] agpTextures microcode handle = 0x%08lx\n",
+ pSAVAGEDRIServer->agpTextures.handle );
+
+ /*if ( drmMap( psav->drmFD,
+ pSAVAGEDRIServer->agpTextures.handle,
+ pSAVAGEDRIServer->agpTextures.size,
+ &pSAVAGEDRIServer->agpTextures.map ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not map agpTextures \n" );
+ return FALSE;
+ }*/
+
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] agpTextures mapped at 0x%08lx\n",
+ (unsigned long)pSAVAGEDRIServer->agpTextures.map );
+
+ /* for agp dma buffer*/
+ size = drmAgpSize(psav->drmFD);
+ size -= pSAVAGEDRIServer->agpTextures.size;/*sub texture size*/
+ numbuffer = size / DRM_SAVAGE_DMA_AGP_SIZE;
+ agpbuffer = (savageAgpBufferPtr)xcalloc(sizeof(savageAgpBuffer),numbuffer);
+ for (i=0;i<numbuffer;i++)
+ {
+ agpbuffer[i].ctxOwner = 0;
+ agpbuffer[i].agp_offset =
+ pSAVAGEDRIServer->agpTextures.size + i* DRM_SAVAGE_DMA_AGP_SIZE;
+ agpbuffer[i].flags = 0;
+ agpbuffer[i].agp_handle = 0;
+ }
+ pSAVAGEDRIServer->numBuffer = numbuffer;
+ pSAVAGEDRIServer->agpBuffer = agpbuffer;
+
+ return TRUE;
+}
+
+static Bool SAVAGEDRIMapInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+
+ pSAVAGEDRIServer->registers.size = SAVAGEIOMAPSIZE;
+
+ if ( drmAddMap( psav->drmFD,
+ (drm_handle_t)psav->MmioBase,
+ pSAVAGEDRIServer->registers.size,
+ DRM_REGISTERS,0,
+ &pSAVAGEDRIServer->registers.handle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Could not add MMIO registers mapping\n" );
+ return FALSE;
+ }
+
+ pSAVAGEDRIServer->aperture.size = 5 * 0x01000000;
+
+ if ( drmAddMap( psav->drmFD,
+ (drm_handle_t)(psav->ApertureBase),
+ pSAVAGEDRIServer->aperture.size,
+ DRM_FRAME_BUFFER,0,
+ &pSAVAGEDRIServer->aperture.handle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Could not add aperture mapping\n" );
+ return FALSE;
+ }
+
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] aperture handle = 0x%08lx\n",
+ pSAVAGEDRIServer->aperture.handle );
+
+ /*if(drmMap(psav->drmFD,
+ pSAVAGEDRIServer->registers.handle,
+ pSAVAGEDRIServer->registers.size,
+ &pSAVAGEDRIServer->registers.map)<0)
+ {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Could not map MMIO registers region to virtual\n" );
+ return FALSE;
+
+ }*/
+
+ pSAVAGEDRIServer->status.size = SAREA_MAX;
+
+ if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->status.size,
+ DRM_SHM, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL,
+ &pSAVAGEDRIServer->status.handle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Could not add status page mapping\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] Status handle = 0x%08lx\n",
+ pSAVAGEDRIServer->status.handle );
+
+ if ( drmMap( psav->drmFD,
+ pSAVAGEDRIServer->status.handle,
+ pSAVAGEDRIServer->status.size,
+ &pSAVAGEDRIServer->status.map ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not map status page\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] Status page mapped at 0x%08lx\n",
+ (unsigned long)pSAVAGEDRIServer->status.map );
+
+ return TRUE;
+}
+
+/* no need DMA */
+#if 0
+static Bool SAVAGEDRIKernelInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+ drmSAVAGEInit init;
+ int ret;
+
+ memset( &init, 0, sizeof(drmSAVAGEInit) );
+
+ init.sarea_priv_offset = sizeof(XF86DRISAREARec);
+
+ switch ( psav->Chipset ) {
+ case PCI_CHIP_SAVAGEG400:
+ init.chipset = SAVAGE_CARD_TYPE_G400;
+ break;
+ case PCI_CHIP_SAVAGEG200:
+ case PCI_CHIP_SAVAGEG200_PCI:
+ init.chipset = SAVAGE_CARD_TYPE_G200;
+ break;
+ default:
+ return FALSE;
+ }
+ init.sgram = !psav->HasSDRAM;
+
+ init.maccess = psav->MAccess;
+
+ init.fb_cpp = pScrn->bitsPerPixel / 8;
+ init.front_offset = pSAVAGEDRIServer->frontOffset;
+ init.front_pitch = pSAVAGEDRIServer->frontPitch / init.fb_cpp;
+ init.back_offset = pSAVAGEDRIServer->backOffset;
+ init.back_pitch = pSAVAGEDRIServer->backPitch / init.fb_cpp;
+
+ init.depth_cpp = pScrn->bitsPerPixel / 8;
+ init.depth_offset = pSAVAGEDRIServer->depthOffset;
+ init.depth_pitch = pSAVAGEDRIServer->depthPitch / init.depth_cpp;
+
+ init.texture_offset[0] = pSAVAGEDRIServer->textureOffset;
+ init.texture_size[0] = pSAVAGEDRIServer->textureSize;
+
+ init.fb_offset = psav->FbAddress;
+ init.mmio_offset = pSAVAGEDRIServer->registers.handle;
+ init.status_offset = pSAVAGEDRIServer->status.handle;
+
+ init.warp_offset = pSAVAGEDRIServer->warp.handle;
+ init.primary_offset = pSAVAGEDRIServer->primary.handle;
+ init.buffers_offset = pSAVAGEDRIServer->buffers.handle;
+
+ ret = drmSAVAGEInitDMA( psav->drmFD, &init );
+ if ( ret < 0 ) {
+ xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
+ "[drm] Failed to initialize DMA! (%d)\n", ret );
+ return FALSE;
+ }
+
+#if 0
+ /* FIXME: This is just here to clean up after the engine reset test
+ * in the kernel module. Please remove it later...
+ */
+ psav->GetQuiescence( pScrn );
+#endif
+
+ return TRUE;
+}
+
+static Bool SAVAGEDRIBuffersInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+
+
+ pSAVAGEDRIServer->drmBuffers = drmMapBufs( psav->drmFD );
+ if ( !pSAVAGEDRIServer->drmBuffers ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Failed to map DMA buffers list\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] Mapped %d DMA buffers\n",
+ pSAVAGEDRIServer->drmBuffers->count );
+
+ return TRUE;
+}
+#endif
+
+Bool SAVAGEDRIScreenInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ DRIInfoPtr pDRIInfo;
+ SAVAGEDRIPtr pSAVAGEDRI;
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer;
+
+/* disable first....*/
+#if 0
+ switch ( psav->Chipset ) {
+ case PCI_CHIP_SAVAGEG400:
+ case PCI_CHIP_SAVAGEG200:
+#if 0
+ case PCI_CHIP_SAVAGEG200_PCI:
+#endif
+ break;
+ default:
+ xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
+ "[drm] Direct rendering only supported with AGP G200/G400 cards!\n" );
+ return FALSE;
+ }
+#endif
+
+ /* Check that the GLX, DRI, and DRM modules have been loaded by testing
+ * for canonical symbols in each module.
+ */
+ if ( !xf86LoaderCheckSymbol( "GlxSetVisualConfigs" ) ) return FALSE;
+ if ( !xf86LoaderCheckSymbol( "DRIScreenInit" ) ) return FALSE;
+ if ( !xf86LoaderCheckSymbol( "drmAvailable" ) ) return FALSE;
+ if ( !xf86LoaderCheckSymbol( "DRIQueryVersion" ) ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] SAVAGEDRIScreenInit failed (libdri.a too old)\n" );
+ return FALSE;
+ }
+
+/* disable first */
+#if 1
+ /* Check the DRI version */
+ {
+ int major, minor, patch;
+ DRIQueryVersion( &major, &minor, &patch );
+ if ( major != 4 || minor < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n"
+ "[dri] libDRI version = %d.%d.%d but version 4.0.x is needed.\n"
+ "[dri] Disabling the DRI.\n",
+ major, minor, patch );
+ return FALSE;
+ }
+ }
+#endif
+
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] bpp: %d depth: %d\n",
+ pScrn->bitsPerPixel, pScrn->depth );
+
+ if ( (pScrn->bitsPerPixel / 8) != 2 &&
+ (pScrn->bitsPerPixel / 8) != 4 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" );
+ return FALSE;
+ }
+
+ pDRIInfo = DRICreateInfoRec();
+ if ( !pDRIInfo ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] DRICreateInfoRec() failed\n" );
+ return FALSE;
+ }
+ psav->pDRIInfo = pDRIInfo;
+
+ pDRIInfo->drmDriverName = SAVAGEKernelDriverName;
+ pDRIInfo->clientDriverName = SAVAGEClientDriverName;
+ if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
+ pDRIInfo->busIdString = DRICreatePCIBusID(psav->PciInfo);
+ } else {
+ pDRIInfo->busIdString = xalloc(64);
+ sprintf(pDRIInfo->busIdString,
+ "PCI:%d:%d:%d",
+ psav->PciInfo->bus,
+ psav->PciInfo->device,
+ psav->PciInfo->func);
+ }
+ pDRIInfo->ddxDriverMajorVersion = 1/*SAVAGE_MAJOR_VERSION*/;
+ pDRIInfo->ddxDriverMinorVersion = 1/*SAVAGE_MINOR_VERSION*/;
+ pDRIInfo->ddxDriverPatchVersion = 16/*SAVAGE_PATCHLEVEL*/;
+ pDRIInfo->frameBufferPhysicalAddress = psav->FrameBufferBase;
+ pDRIInfo->frameBufferSize = psav->videoRambytes;
+ pDRIInfo->frameBufferStride = pScrn->displayWidth*(pScrn->bitsPerPixel/8);
+ pDRIInfo->ddxDrawableTableEntry = SAVAGE_MAX_DRAWABLES;
+
+/* mark off these... we use default */
+#if 0
+ pDRIInfo->wrap.BlockHandler = SAVAGEBlockHandler;
+ pDRIInfo->wrap.WakeupHandler = SAVAGEWakeupHandler;
+#endif
+
+ pDRIInfo->wrap.ValidateTree = NULL;
+ pDRIInfo->wrap.PostValidateTree = NULL;
+
+ pDRIInfo->createDummyCtx = TRUE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
+
+ if ( SAREA_MAX_DRAWABLES < SAVAGE_MAX_DRAWABLES ) {
+ pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
+ } else {
+ pDRIInfo->maxDrawableTableEntry = SAVAGE_MAX_DRAWABLES;
+ }
+
+ /* For now the mapping works by using a fixed size defined
+ * in the SAREA header.
+ */
+ if ( sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec) > SAREA_MAX ) {
+ xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
+ "[drm] Data does not fit in SAREA\n" );
+ return FALSE;
+ }
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "[drm] Sarea %d+%d: %d\n",
+ sizeof(XF86DRISAREARec), sizeof(SAVAGESAREAPrivRec),
+ sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec) );
+
+ pDRIInfo->SAREASize = SAREA_MAX;
+
+ pSAVAGEDRI = (SAVAGEDRIPtr)xcalloc( sizeof(SAVAGEDRIRec), 1 );
+ if ( !pSAVAGEDRI ) {
+ DRIDestroyInfoRec( psav->pDRIInfo );
+ psav->pDRIInfo = 0;
+ xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
+ "[drm] Failed to allocate memory for private record\n" );
+ return FALSE;
+ }
+
+ pSAVAGEDRIServer = (SAVAGEDRIServerPrivatePtr)
+ xcalloc( sizeof(SAVAGEDRIServerPrivateRec), 1 );
+ if ( !pSAVAGEDRIServer ) {
+ xfree( pSAVAGEDRI );
+ DRIDestroyInfoRec( psav->pDRIInfo );
+ psav->pDRIInfo = 0;
+ xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
+ "[drm] Failed to allocate memory for private record\n" );
+ return FALSE;
+ }
+ psav->DRIServerInfo = pSAVAGEDRIServer;
+
+ pDRIInfo->devPrivate = pSAVAGEDRI;
+ pDRIInfo->devPrivateSize = sizeof(SAVAGEDRIRec);
+ pDRIInfo->contextSize = sizeof(SAVAGEDRIContextRec);
+
+ pDRIInfo->CreateContext = SAVAGECreateContext;
+ pDRIInfo->DestroyContext = SAVAGEDestroyContext;
+
+/* we don't have double head */
+#if 0
+ if ( xf86IsEntityShared( pScrn->entityList[0] ) ) {
+ pDRIInfo->SwapContext = SAVAGEDRISwapContextShared;
+ } else
+#endif
+
+ {
+ pDRIInfo->SwapContext = SAVAGEDRISwapContext;
+ }
+
+#if 0
+ switch( pScrn->bitsPerPixel ) {
+ case 8:
+ pDRIInfo->InitBuffers = Savage8DRIInitBuffers;
+ pDRIInfo->MoveBuffers = Savage8DRIMoveBuffers;
+ case 16:
+ pDRIInfo->InitBuffers = Savage16DRIInitBuffers;
+ pDRIInfo->MoveBuffers = Savage16DRIMoveBuffers;
+ case 24:
+ pDRIInfo->InitBuffers = Savage24DRIInitBuffers;
+ pDRIInfo->MoveBuffers = Savage24DRIMoveBuffers;
+ case 32:
+ pDRIInfo->InitBuffers = Savage32DRIInitBuffers;
+ pDRIInfo->MoveBuffers = Savage32DRIMoveBuffers;
+ }
+#endif
+
+ pDRIInfo->InitBuffers = SAVAGEDRIInitBuffers;
+ pDRIInfo->MoveBuffers = SAVAGEDRIMoveBuffers;
+ pDRIInfo->OpenFullScreen = SAVAGEDRIOpenFullScreen;
+ pDRIInfo->CloseFullScreen = SAVAGEDRICloseFullScreen;
+ pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+
+ if ( !DRIScreenInit( pScreen, pDRIInfo, &psav->drmFD ) ) {
+ xfree( pSAVAGEDRIServer );
+ psav->DRIServerInfo = 0;
+ xfree( pDRIInfo->devPrivate );
+ pDRIInfo->devPrivate = 0;
+ DRIDestroyInfoRec( psav->pDRIInfo );
+ psav->pDRIInfo = 0;
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] DRIScreenInit failed. Disabling DRI.\n" );
+ return FALSE;
+ }
+
+/* Disable these */
+#if 1
+ /* Check the SAVAGE DRM version */
+ {
+ drmVersionPtr version = drmGetVersion(psav->drmFD);
+ if ( version ) {
+ if ( version->version_major != 1 ||
+ version->version_minor < 0 ) {
+ /* incompatible drm version */
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n"
+ "[dri] savage.o kernel module version is %d.%d.%d but version 3.0.x is needed.\n"
+ "[dri] Disabling DRI.\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel );
+ drmFreeVersion( version );
+ SAVAGEDRICloseScreen( pScreen ); /* FIXME: ??? */
+ return FALSE;
+ }
+ drmFreeVersion( version );
+ }
+ }
+#endif
+
+#if 0
+ /* Calculate texture constants for AGP texture space.
+ * FIXME: move!
+ */
+ {
+ CARD32 agpTextureOffset = SAVAGE_DMA_BUF_SZ * SAVAGE_DMA_BUF_NR;
+ CARD32 agpTextureSize = pSAVAGEDRI->agp.size - agpTextureOffset;
+
+ i = mylog2(agpTextureSize / SAVAGE_NR_TEX_REGIONS);
+ if (i < SAVAGE_LOG_MIN_TEX_REGION_SIZE)
+ i = SAVAGE_LOG_MIN_TEX_REGION_SIZE;
+
+ pSAVAGEDRI->logAgpTextureGranularity = i;
+ pSAVAGEDRI->agpTextureSize = (agpTextureSize >> i) << i;
+ pSAVAGEDRI->agpTextureOffset = agpTextureOffset;
+ }
+#endif
+
+ if ( !SAVAGEDRIAgpInit( pScreen ) ) {
+ DRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ if ( !SAVAGEDRIMapInit( pScreen ) ) {
+ DRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ if ( !SAVAGEInitVisualConfigs( pScreen ) ) {
+ DRICloseScreen( pScreen );
+ return FALSE;
+ }
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized\n" );
+
+ return TRUE;
+}
+
+
+Bool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+ SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
+ int i;
+ unsigned int TileStride;
+
+
+ if ( !psav->pDRIInfo )
+ return FALSE;
+
+ psav->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
+
+ /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit
+ * because *DRIKernelInit requires that the hardware lock is held by
+ * the X server, and the first time the hardware lock is grabbed is
+ * in DRIFinishScreenInit.
+ */
+ if ( !DRIFinishScreenInit( pScreen ) ) {
+ SAVAGEDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+/* no dma...... */
+#if 0
+ if ( !SAVAGEDRIKernelInit( pScreen ) ) {
+ SAVAGEDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ if ( !SAVAGEDRIBuffersInit( pScreen ) ) {
+ SAVAGEDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ switch ( psav->Chipset ) {
+ case PCI_CHIP_SAVAGEG400:
+ pSAVAGEDRI->chipset = SAVAGE_CARD_TYPE_G400;
+ break;
+ case PCI_CHIP_SAVAGEG200:
+ case PCI_CHIP_SAVAGEG200_PCI:
+ pSAVAGEDRI->chipset = SAVAGE_CARD_TYPE_G200;
+ break;
+ default:
+ return FALSE;
+ }
+#endif
+
+ pSAVAGEDRI->chipset = psav->Chipset;
+ pSAVAGEDRI->width = pScrn->virtualX;
+ pSAVAGEDRI->height = pScrn->virtualY;
+ pSAVAGEDRI->mem = pScrn->videoRam * 1024;
+ pSAVAGEDRI->cpp = pScrn->bitsPerPixel / 8;
+ pSAVAGEDRI->zpp =pSAVAGEDRI->cpp;
+ pSAVAGEDRI->agpMode = psav->agpMode;
+
+ pSAVAGEDRI->frontOffset = pSAVAGEDRIServer->frontOffset;
+ pSAVAGEDRI->frontbufferSize = pSAVAGEDRIServer->frontbufferSize;
+ pSAVAGEDRI->frontbuffer = psav->FrameBufferBase +
+ pSAVAGEDRI->frontOffset;
+ pSAVAGEDRI->frontPitch = pSAVAGEDRIServer->frontPitch;
+ pSAVAGEDRI->IsfrontTiled = psav->bTiled; /* AGD: was 0 */
+
+ if(pSAVAGEDRI->IsfrontTiled)
+ {
+ if(pSAVAGEDRI->cpp==2)
+ TileStride = (pSAVAGEDRI->width+63)&(~63);
+ else
+ TileStride = (pSAVAGEDRI->width+31)&(~31);
+
+ if ((psav->Chipset == S3_TWISTER)
+ || (psav->Chipset == S3_PROSAVAGE)
+ || (psav->Chipset == S3_PROSAVAGEDDR)
+ || (psav->Chipset == S3_SUPERSAVAGE))
+ {
+ pSAVAGEDRI->frontBitmapDesc = 0x10000000 | /* block write disabled */
+ (1<<24) | /* destination tile format */
+ (pScrn->bitsPerPixel<<16) | /* bpp */
+ TileStride; /* stride */
+ } else {
+ pSAVAGEDRI->frontBitmapDesc = 0x10000000 | /* block write disabled */
+ ((pSAVAGEDRI->cpp==2)?
+ BCI_BD_TILE_16:BCI_BD_TILE_32) | /*16/32 bpp tile format */
+ (pScrn->bitsPerPixel<<16) | /* bpp */
+ TileStride; /* stride */
+ pSAVAGEDRI->frontPitch = TileStride;
+ }
+ }
+ else
+ {
+ pSAVAGEDRI->frontBitmapDesc = 0x10000000 | /* AGD: block write should be disabled: was 0x00000000 */
+ pScrn->bitsPerPixel<<16 |
+ pSAVAGEDRI->width;
+ }
+
+ pSAVAGEDRI->backOffset = pSAVAGEDRIServer->backOffset;
+ pSAVAGEDRI->backbufferSize = pSAVAGEDRIServer->backbufferSize;
+ pSAVAGEDRI->backbuffer = psav->FrameBufferBase +
+ pSAVAGEDRI->backOffset;
+ pSAVAGEDRI->backPitch = pSAVAGEDRIServer->backPitch;
+
+ {
+ if(pSAVAGEDRI->cpp==2)
+ TileStride = (pSAVAGEDRI->width+63)&(~63);
+ else
+ TileStride = (pSAVAGEDRI->width+31)&(~31);
+
+ if ((psav->Chipset == S3_TWISTER)
+ || (psav->Chipset == S3_PROSAVAGE)
+ || (psav->Chipset == S3_PROSAVAGEDDR)
+ || (psav->Chipset == S3_SUPERSAVAGE)) /* AGD: supersavage may work like savage4/MX/IX, I just don't know. */
+ { /* It's here since the 2D driver sets it up like prosavage */
+ pSAVAGEDRI->backBitmapDesc = 0x10000000 |
+ (1<<24) |
+ (pScrn->bitsPerPixel<<16) |
+ TileStride;
+ } else {
+ pSAVAGEDRI->backBitmapDesc = 0x10000000 |
+ ((pSAVAGEDRI->cpp==2)?
+ BCI_BD_TILE_16:BCI_BD_TILE_32) |
+ (pScrn->bitsPerPixel<<16) |
+ TileStride;
+ }
+ }
+
+ pSAVAGEDRI->depthOffset = pSAVAGEDRIServer->depthOffset;
+ pSAVAGEDRI->depthbufferSize = pSAVAGEDRIServer->depthbufferSize;
+ pSAVAGEDRI->depthbuffer = psav->FrameBufferBase +
+ pSAVAGEDRI->depthOffset;
+ pSAVAGEDRI->depthPitch = pSAVAGEDRIServer->depthPitch;
+
+ {
+ if(pSAVAGEDRI->zpp==2)
+ TileStride = (pSAVAGEDRI->width+63)&(~63);
+ else
+ TileStride = (pSAVAGEDRI->width+31)&(~31);
+
+ if ((psav->Chipset == S3_TWISTER)
+ || (psav->Chipset == S3_PROSAVAGE)
+ || (psav->Chipset == S3_PROSAVAGEDDR)
+ || (psav->Chipset == S3_SUPERSAVAGE))
+ {
+ pSAVAGEDRI->depthBitmapDesc = 0x10000000 |
+ (1<<24) |
+ (pScrn->bitsPerPixel<<16) |
+ TileStride;
+ } else {
+ pSAVAGEDRI->depthBitmapDesc = 0x10000000 |
+ ((pSAVAGEDRI->zpp==2)?
+ BCI_BD_TILE_16:BCI_BD_TILE_32) |
+ (pScrn->bitsPerPixel<<16) |
+ TileStride;
+ }
+ }
+
+ pSAVAGEDRI->textureOffset = pSAVAGEDRIServer->textureOffset;
+ pSAVAGEDRI->textures = psav->FrameBufferBase +
+ pSAVAGEDRI->textureOffset;
+ pSAVAGEDRI->textureSize = pSAVAGEDRIServer->textureSize;
+
+ i = mylog2( pSAVAGEDRI->textureSize / SAVAGE_NR_TEX_REGIONS );
+ if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE )
+ i = SAVAGE_LOG_MIN_TEX_REGION_SIZE;
+
+ pSAVAGEDRI->logTextureGranularity = i;
+ pSAVAGEDRI->textureSize = (pSAVAGEDRI->textureSize >> i) << i; /* truncate */
+
+ pSAVAGEDRI->agpTextures.handle = pSAVAGEDRIServer->agpTextures.handle;
+ pSAVAGEDRI->agpTextures.offset = pSAVAGEDRIServer->agpTextures.offset;
+ pSAVAGEDRI->agpTextures.size = pSAVAGEDRIServer->agpTextures.size;
+ pSAVAGEDRI->agpTextures.map = pSAVAGEDRIServer->agpTextures.map;
+
+ i = mylog2( pSAVAGEDRI->agpTextures.size / SAVAGE_NR_TEX_REGIONS );
+ if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE )
+ i = SAVAGE_LOG_MIN_TEX_REGION_SIZE;
+
+ pSAVAGEDRI->logAgpTextureGranularity = i;
+ pSAVAGEDRI->agpTextures.size = (pSAVAGEDRI->agpTextures.size >> i) << i; /* truncate */
+
+ pSAVAGEDRI->aperture.handle = pSAVAGEDRIServer->aperture.handle;
+ pSAVAGEDRI->aperture.size = pSAVAGEDRIServer->aperture.size;
+ pSAVAGEDRI->aperture.map = pSAVAGEDRIServer->aperture.map;
+ {
+ unsigned int shift = 0;
+
+ if(pSAVAGEDRI->width > 1024)
+ shift = 1;
+
+ /* pSAVAGEDRI->aperturePitch = psav->ulAperturePitch; */
+ pSAVAGEDRI->aperturePitch = psav->ul3DAperturePitch;
+ }
+
+ {
+ unsigned int value = 0;
+
+ OUTREG(0x850C,(INREG(0x850C) | 0x00008000)); /* AGD: I don't think this does anything on 3D/MX/IX */
+ /* maybe savage4 too... */
+ /* we don't use Y range flag,so comment it */
+ /*
+ if(pSAVAGEDRI->width <= 1024)
+ value |= (1<<29);
+ */
+ if ((psav->Chipset == S3_SAVAGE_MX) /* 3D/MX/IX seem to set up the tile stride differently */
+ || (psav->Chipset == S3_SAVAGE3D)) {
+ if(pSAVAGEDRI->cpp == 2)
+ {
+ value |= ((psav->l3DDelta / 4) >> 5) << 24; /* I assume psav->l3DDelta for 3D */
+ value |= 2<<30;
+ } else {
+ value |= ((psav->l3DDelta / 4) >> 5) << 24; /* I assume psav->l3DDelta for 3D */
+ value |= 3<<30;
+ }
+
+ OUTREG(0x48C40, value|(pSAVAGEDRI->frontOffset) ); /* front */
+ OUTREG(0x48C44, value|(pSAVAGEDRI->backOffset) ); /* back */
+ OUTREG(0x48C48, value|(pSAVAGEDRI->depthOffset) ); /* depth */
+ } else {
+ if(pSAVAGEDRI->cpp == 2)
+ {
+ value |= (((pSAVAGEDRI->width + 0x3F) & 0xFFC0) >> 6) << 20;
+ value |= 2<<30;
+ } else {
+ value |= (((pSAVAGEDRI->width + 0x1F) & 0xFFE0) >> 5) << 20;
+ value |= 3<<30;
+ }
+
+ OUTREG(0x48C40, value|(pSAVAGEDRI->frontOffset >> 5) ); /* front */
+ OUTREG(0x48C44, value|(pSAVAGEDRI->backOffset >> 5) ); /* back */
+ OUTREG(0x48C48, value|(pSAVAGEDRI->depthOffset >> 5) ); /* depth */
+ }
+ }
+
+ pSAVAGEDRI->registers.handle = pSAVAGEDRIServer->registers.handle;
+ pSAVAGEDRI->registers.size = pSAVAGEDRIServer->registers.size;
+ pSAVAGEDRI->registers.map = pSAVAGEDRIServer->registers.map;
+
+ pSAVAGEDRI->BCIcmdBuf.handle = pSAVAGEDRIServer->registers.handle+0x00010000;
+ pSAVAGEDRI->BCIcmdBuf.size = 0x00020000;
+ pSAVAGEDRI->BCIcmdBuf.map = (drmAddress)( (unsigned int)
+ pSAVAGEDRIServer->registers.map +
+ 0x00010000);
+
+ pSAVAGEDRI->status.handle = pSAVAGEDRIServer->status.handle;
+ pSAVAGEDRI->status.size = pSAVAGEDRIServer->status.size;
+ pSAVAGEDRI->shadowStatus = psav->ShadowStatus;
+
+/* no DMA now ....*/
+#if 0
+ pSAVAGEDRI->primary.handle = pSAVAGEDRIServer->primary.handle;
+ pSAVAGEDRI->primary.size = pSAVAGEDRIServer->primary.size;
+ pSAVAGEDRI->buffers.handle = pSAVAGEDRIServer->buffers.handle;
+ pSAVAGEDRI->buffers.size = pSAVAGEDRIServer->buffers.size;
+#endif
+
+ pSAVAGEDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRIServer:\n" );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] reserved_map_agpstart:0x%08x\n",pSAVAGEDRIServer->reserved_map_agpstart);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] reserved_map_idx:0x%08x\n",pSAVAGEDRIServer->reserved_map_idx);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] sarea_priv_offset:0x%08lx\n",pSAVAGEDRIServer->sarea_priv_offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] chipset:0x%08x\n",pSAVAGEDRIServer->chipset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] sgram:0x%08x\n",pSAVAGEDRIServer->sgram);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontbufferSize:0x%08x\n",pSAVAGEDRIServer->frontbufferSize);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontOffset:0x%08x\n",pSAVAGEDRIServer->frontOffset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontPitch:0x%08x\n",pSAVAGEDRIServer->frontPitch);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backbufferSize:0x%08x\n",pSAVAGEDRIServer->backbufferSize);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backOffset:0x%08x\n",pSAVAGEDRIServer->backOffset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backPitch:0x%08x\n",pSAVAGEDRIServer->backPitch);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthbufferSize:0x%08x\n",pSAVAGEDRIServer->depthbufferSize);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthOffset:0x%08x\n",pSAVAGEDRIServer->depthOffset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthPitch:0x%08x\n",pSAVAGEDRIServer->depthPitch);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureOffset:0x%08x\n",pSAVAGEDRIServer->textureOffset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logTextureGranularity);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:handle:0x%08lx\n",pSAVAGEDRIServer->agp.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:offset:0x%08lx\n",pSAVAGEDRIServer->agp.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:size:0x%08lx\n",pSAVAGEDRIServer->agp.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agp.map);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:handle:0x%08lx\n",pSAVAGEDRIServer->registers.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:offset:0x%08lx\n",pSAVAGEDRIServer->registers.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:size:0x%08lx\n",pSAVAGEDRIServer->registers.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->registers.map);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:handle:0x%08lx\n",pSAVAGEDRIServer->status.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:offset:0x%08lx\n",pSAVAGEDRIServer->status.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:size:0x%08lx\n",pSAVAGEDRIServer->status.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->status.map);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:handle:0x%08lx\n",pSAVAGEDRIServer->agpTextures.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:offset:0x%08lx\n",pSAVAGEDRIServer->agpTextures.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:size:0x%08lx\n",pSAVAGEDRIServer->agpTextures.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] apgTextures:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agpTextures.map);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logAgpTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logAgpTextureGranularity);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRI:\n" );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] chipset:0x%08x\n",pSAVAGEDRI->chipset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] width:0x%08x\n",pSAVAGEDRI->width );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] height:0x%08x\n",pSAVAGEDRI->height );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] mem:0x%08lx\n",pSAVAGEDRI->mem );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cpp:%d\n",pSAVAGEDRI->cpp );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] zpp:%d\n",pSAVAGEDRI->zpp );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpMode:%d\n",pSAVAGEDRI->agpMode );
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontbuffer:0x%08lx\n",pSAVAGEDRI->frontbuffer);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontbufferSize:0x%08x\n",pSAVAGEDRI->frontbufferSize);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontOffset:0x%08x\n",pSAVAGEDRI->frontOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontPitch:0x%08x\n",pSAVAGEDRI->frontPitch );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontBitmapDesc:0x%08lx\n",pSAVAGEDRI->frontBitmapDesc );
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backbuffer:0x%08lx\n",pSAVAGEDRI->backbuffer);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backbufferSize:0x%08x\n",pSAVAGEDRI->backbufferSize);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backOffset:0x%08x\n",pSAVAGEDRI->backOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backPitch:0x%08x\n",pSAVAGEDRI->backPitch );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backBitmapDesc:0x%08lx\n",pSAVAGEDRI->backBitmapDesc );
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthbuffer:0x%08lx\n",pSAVAGEDRI->depthbuffer);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthbufferSize:0x%08x\n",pSAVAGEDRI->depthbufferSize);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthOffset:0x%08x\n",pSAVAGEDRI->depthOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthPitch:0x%08x\n",pSAVAGEDRI->depthPitch );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthBitmapDesc:0x%08lx\n",pSAVAGEDRI->depthBitmapDesc );
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textures:0x%08lx\n",pSAVAGEDRI->textures );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureOffset:0x%08x\n",pSAVAGEDRI->textureOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureSize:0x%08x\n",pSAVAGEDRI->textureSize );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logTextureGranularity:0x%08x\n",pSAVAGEDRI->logTextureGranularity );
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpBufferOffset:0x%08x\n",pSAVAGEDRI->agpBufferOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextureOffset:0x%08x\n",pSAVAGEDRI->agpTextureOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextureSize:0x%08x\n",pSAVAGEDRI->agpTextureSize );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logAgpTextureGranularity:0x%08x\n",pSAVAGEDRI->logAgpTextureGranularity );
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:handle:0x%08lx\n",pSAVAGEDRI->agpTextures.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:offset:0x%08lx\n",pSAVAGEDRI->agpTextures.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:size:0x%08lx\n",pSAVAGEDRI->agpTextures.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] apgTextures:map:0x%08lx\n",(unsigned long)pSAVAGEDRI->agpTextures.map);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:handle:0x%08lx\n",pSAVAGEDRI->registers.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:offset:0x%08lx\n",pSAVAGEDRI->registers.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:size:0x%08lx\n",pSAVAGEDRI->registers.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:map:0x%08lx\n",(unsigned long)pSAVAGEDRI->registers.map);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] aperture:handle:0x%08lx\n",pSAVAGEDRI->aperture.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] aperture:offset:0x%08lx\n",pSAVAGEDRI->aperture.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] aperture:size:0x%08lx\n",pSAVAGEDRI->aperture.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] aperture:map:0x%08lx\n",(unsigned long)pSAVAGEDRI->aperture.map);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] aperturePitch:0x%08x\n",pSAVAGEDRI->aperturePitch);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] BCIcmdBuf:handle:0x%08lx\n",pSAVAGEDRI->BCIcmdBuf.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] BCIcmdBuf:offset:0x%08lx\n",pSAVAGEDRI->BCIcmdBuf.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] BCIcmdBuf:size:0x%08lx\n",pSAVAGEDRI->BCIcmdBuf.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] BCIcmdBuf:map:0x%08lx\n",(unsigned long)pSAVAGEDRI->BCIcmdBuf.map);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:handle:0x%08lx\n",pSAVAGEDRI->status.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:offset:0x%08lx\n",pSAVAGEDRI->status.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:size:0x%08lx\n",pSAVAGEDRI->status.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:map:0x%08lx\n",(unsigned long)pSAVAGEDRI->status.map);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] sarea_priv_offset:0x%08lx\n",pSAVAGEDRI->sarea_priv_offset);
+
+ return TRUE;
+}
+
+
+void SAVAGEDRICloseScreen( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+
+/* no DMA now..... */
+#if 0
+ if ( pSAVAGEDRIServer->drmBuffers ) {
+ drmUnmapBufs( pSAVAGEDRIServer->drmBuffers );
+ pSAVAGEDRIServer->drmBuffers = NULL;
+ }
+
+ drmSAVAGECleanupDMA( psav->drmFD );
+#endif
+
+ if ( pSAVAGEDRIServer->status.map ) {
+ drmUnmap( pSAVAGEDRIServer->status.map, pSAVAGEDRIServer->status.size );
+ pSAVAGEDRIServer->status.map = NULL;
+ }
+
+ if ( pSAVAGEDRIServer->registers.map ) {
+ drmUnmap( pSAVAGEDRIServer->registers.map, pSAVAGEDRIServer->registers.size );
+ pSAVAGEDRIServer->registers.map = NULL;
+ }
+
+
+ if ( pSAVAGEDRIServer->agpTextures.map ) {
+ drmUnmap( pSAVAGEDRIServer->agpTextures.map,
+ pSAVAGEDRIServer->agpTextures.size );
+ pSAVAGEDRIServer->agpTextures.map = NULL;
+ }
+
+ if (pSAVAGEDRIServer->status.handle)
+ drmRmMap(psav->drmFD,pSAVAGEDRIServer->status.handle);
+
+ if (pSAVAGEDRIServer->registers.handle)
+ drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle);
+
+ if (pSAVAGEDRIServer->agpTextures.handle)
+ drmRmMap(psav->drmFD,pSAVAGEDRIServer->agpTextures.handle);
+
+/* no DMA now.... */
+#if 0
+ if ( pSAVAGEDRIServer->buffers.map ) {
+ drmUnmap( pSAVAGEDRIServer->buffers.map, pSAVAGEDRIServer->buffers.size );
+ pSAVAGEDRIServer->buffers.map = NULL;
+ }
+ if ( pSAVAGEDRIServer->primary.map ) {
+ drmUnmap( pSAVAGEDRIServer->primary.map, pSAVAGEDRIServer->primary.size );
+ pSAVAGEDRIServer->primary.map = NULL;
+ }
+ if ( pSAVAGEDRIServer->warp.map ) {
+ drmUnmap( pSAVAGEDRIServer->warp.map, pSAVAGEDRIServer->warp.size );
+ pSAVAGEDRIServer->warp.map = NULL;
+ }
+#endif
+
+ if ( pSAVAGEDRIServer->agp.handle ) {
+ drmAgpUnbind( psav->drmFD, pSAVAGEDRIServer->agp.handle );
+ drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle );
+ pSAVAGEDRIServer->agp.handle = 0;
+ drmAgpRelease( psav->drmFD );
+ }
+
+ DRICloseScreen( pScreen );
+
+ /*Don't use shadow status any more*/
+ psav->ShadowVirtual = NULL;
+ psav->ShadowPhysical = 0;
+
+ if(psav->reserved)
+ xf86FreeOffscreenLinear(psav->reserved);
+
+ if ( psav->pDRIInfo ) {
+ if ( psav->pDRIInfo->devPrivate ) {
+ xfree( psav->pDRIInfo->devPrivate );
+ psav->pDRIInfo->devPrivate = 0;
+ }
+ DRIDestroyInfoRec( psav->pDRIInfo );
+ psav->pDRIInfo = 0;
+ }
+ if ( psav->DRIServerInfo ) {
+ xfree( psav->DRIServerInfo );
+ psav->DRIServerInfo = 0;
+ }
+ if ( psav->pVisualConfigs ) {
+ xfree( psav->pVisualConfigs );
+ }
+ if ( psav->pVisualConfigsPriv ) {
+ xfree( psav->pVisualConfigsPriv );
+ }
+}
+
+void
+SAVAGEDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ BoxPtr pbox = REGION_RECTS(prgn);
+ int nbox = REGION_NUM_RECTS(prgn);
+
+
+#if 0
+ CHECK_DMA_QUIESCENT(SAVPTR(pScrn), pScrn);
+#endif
+#if 0
+ if(!psav->LockHeld)
+ psav->LockHeld = 1;
+ SAVAGEDRISetupForSolidFill(pScrn, 0, GXcopy, -1);
+ while (nbox--) {
+ SAVAGESelectBuffer(pScrn, SAVAGE_BACK);
+ SAVAGEDRISubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
+ pbox->x2-pbox->x1, pbox->y2-pbox->y1);
+ SAVAGESelectBuffer(pScrn, SAVAGE_DEPTH);
+ SAVAGEDRISubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
+ pbox->x2-pbox->x1, pbox->y2-pbox->y1);
+ pbox++;
+ }
+#endif
+#if 0
+ {
+ SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
+ unsigned int *bcicmd;
+ BCI_GET_PTR;
+ /*bcicmd = (unsigned int *) psav->BciMem;
+ *(bcicmd) = 0x4BCC8000;
+ *(bcicmd) = 0x00F80000;
+ *(bcicmd) = 0x02000200;
+ *(bcicmd) = 0x01000100;*/
+ BCI_SEND(0x4BCC8000);
+ BCI_SEND(0x00F80000);
+ BCI_SEND(0x02000200);
+ BCI_SEND(0x01000100);
+ sleep(5);
+ }
+#endif
+#if 0
+ SAVAGESelectBuffer(pScrn, SAVAGE_FRONT);
+ psav->AccelInfoRec->NeedToSync = TRUE;
+#endif
+}
+
+/*
+ This routine is a modified form of XAADoBitBlt with the calls to
+ ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
+ instead of destination. My origin is upside down so the ydir cases
+ are reversed.
+*/
+
+void
+SAVAGEDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index)
+{
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ int nbox;
+ BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ int xdir, ydir;
+ int dx, dy;
+ DDXPointPtr pptSrc;
+ int screenwidth = pScrn->virtualX;
+ int screenheight = pScrn->virtualY;
+
+#if 1
+#if 0
+ CHECK_DMA_QUIESCENT(SAVPTR(pScrn), pScrn);
+#endif
+ if(!psav->LockHeld)
+ psav->LockHeld = 1;
+
+ pbox = REGION_RECTS(prgnSrc);
+ nbox = REGION_NUM_RECTS(prgnSrc);
+ pboxNew1 = 0;
+ pptNew1 = 0;
+ pboxNew2 = 0;
+ pboxNew2 = 0;
+ pptSrc = &ptOldOrg;
+
+ dx = pParent->drawable.x - ptOldOrg.x;
+ dy = pParent->drawable.y - ptOldOrg.y;
+
+ /* If the copy will overlap in Y, reverse the order */
+ if (dy>0) {
+ ydir = -1;
+
+ if (nbox>1) {
+ /* Keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
+ if (!pboxNew1) return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
+ if (!pptNew1) {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* No changes required */
+ ydir = 1;
+ }
+
+ /* If the regions will overlap in X, reverse the order */
+ if (dx>0) {
+ xdir = -1;
+
+ if (nbox > 1) {
+ /*reverse orderof rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
+ if (!pboxNew2 || !pptNew2) {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* No changes are needed */
+ xdir = 1;
+ }
+#if 0
+ SAVAGEDRISetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1);
+ for ( ; nbox-- ; pbox++)
+ {
+ int x1 = pbox->x1;
+ int y1 = pbox->y1;
+ int destx = x1 + dx;
+ int desty = y1 + dy;
+ int w = pbox->x2 - x1 + 1;
+ int h = pbox->y2 - y1 + 1;
+
+ if ( destx < 0 ) x1 -= destx, w += destx, destx = 0;
+ if ( desty < 0 ) y1 -= desty, h += desty, desty = 0;
+ if ( destx + w > screenwidth ) w = screenwidth - destx;
+ if ( desty + h > screenheight ) h = screenheight - desty;
+ if ( w <= 0 ) continue;
+ if ( h <= 0 ) continue;
+
+ SAVAGESelectBuffer(pScrn, SAVAGE_BACK);
+ SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1, y1,
+ destx,desty, w, h);
+ SAVAGESelectBuffer(pScrn, SAVAGE_DEPTH);
+ SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1,y1,
+ destx,desty, w, h);
+ }
+ SAVAGESelectBuffer(pScrn, SAVAGE_FRONT);
+
+ if (pboxNew2) {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+
+ psav->AccelInfoRec->NeedToSync = TRUE;
+#endif
+#endif
+}
+
+static void
+SAVAGEDRISetupForScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int xdir,
+ int ydir,
+ int rop,
+ unsigned planemask,
+ int transparency_color)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ int cmd =0;
+
+ cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD | BCI_CMD_SRC_PBD_COLOR;
+ BCI_CMD_SET_ROP( cmd, XAACopyROP[rop] );
+ if (transparency_color != -1)
+ cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT;
+
+ if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP;
+ if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP;
+
+ psav->SavedBciCmd = cmd;
+ psav->SavedBgColor = transparency_color;
+
+}
+
+static void
+SAVAGEDRISubsequentScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ int w,
+ int h)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ BCI_GET_PTR;
+
+ if (!w || !h) return;
+ if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) {
+ w --;
+ x1 += w;
+ x2 += w;
+ w ++;
+ }
+ if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) {
+ h --;
+ y1 += h;
+ y2 += h;
+ h ++;
+ }
+
+ psav->WaitQueue(psav,6);
+ BCI_SEND(psav->SavedBciCmd);
+ if (psav->SavedBgColor != -1)
+ BCI_SEND(psav->SavedBgColor);
+ BCI_SEND(BCI_X_Y(x1, y1));
+ BCI_SEND(BCI_X_Y(x2, y2));
+ BCI_SEND(BCI_W_H(w, h));
+
+}
+
+
+/*
+ * SetupForSolidFill is also called to set up for lines.
+ */
+#if 0
+static void
+SAVAGEDRISetupForSolidFill(
+ ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned planemask)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ XAAInfoRecPtr xaaptr = GET_XAAINFORECPTR_FROM_SCRNINFOPTR( pScrn );
+ int cmd;
+ int mix;
+
+ cmd = BCI_CMD_RECT
+ | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
+ | BCI_CMD_DEST_PBD | BCI_CMD_SRC_SOLID;
+
+ /* Don't send a color if we don't have to. */
+
+ if( rop == GXcopy )
+ {
+ if( color == 0 )
+ rop = GXclear;
+ else if( color == xaaptr->FullPlanemask )
+ rop = GXset;
+ }
+
+#if 1
+ mix = SavageHelpSolidROP( pScrn, &color, planemask, &rop );
+#endif
+ if( mix & ROP_PAT )
+ cmd |= BCI_CMD_SEND_COLOR;
+
+ BCI_CMD_SET_ROP( cmd, rop );
+
+ psav->SavedBciCmd = cmd;
+ psav->SavedFgColor = color;
+}
+#endif
+
+static void
+SAVAGEDRISubsequentSolidFillRect(
+ ScrnInfoPtr pScrn,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ BCI_GET_PTR;
+
+ if( !w || !h )
+ return;
+
+ psav->WaitQueue(psav,5);
+
+ BCI_SEND(psav->SavedBciCmd);
+ if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR )
+ BCI_SEND(psav->SavedFgColor);
+ BCI_SEND(BCI_X_Y(x, y));
+ BCI_SEND(BCI_W_H(w, h));
+}
+
+
+static Bool
+SAVAGEDRIOpenFullScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ SavagePtr psav = SAVPTR(pScrn);
+ unsigned int vgaCRIndex = hwp->IOBase + 4;
+ unsigned int vgaCRReg = hwp->IOBase + 5;
+ SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
+ unsigned int TileStride;
+ unsigned int WidthinTiles;
+ unsigned int depth;
+
+ OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7);
+ /*VGAOUT8(vgaCRIndex,0x66);
+ VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg)|0x10);*/
+ VGAOUT8(vgaCRIndex,0x69);
+ VGAOUT8(vgaCRReg, 0x80);
+
+ depth = pScrn->bitsPerPixel;
+
+ if(depth == 16)
+ {
+ WidthinTiles = (pSAVAGEDRI->width+63)>>6;
+ TileStride = (pSAVAGEDRI->width+63)&(~63);
+
+ }
+ else
+ {
+ WidthinTiles = (pSAVAGEDRI->width+31)>>5;
+ TileStride = (pSAVAGEDRI->width+31)&(~31);
+
+ }
+
+
+ /* set primary stream stride */
+ {
+ unsigned int value;
+
+ /*value = 0x80000000|(WidthinTiles<<24)|(TileStride*depth/8);*/
+ value = 0x80000000|(WidthinTiles<<24);
+ if(depth == 32)
+ value |= 0x40000000;
+
+ OUTREG(PRI_STREAM_STRIDE, value);
+
+ }
+
+ /* set global bitmap descriptor */
+ {
+ unsigned int value;
+ value = 0x10000000|
+ 0x00000009|
+ 0x01000000|
+ (depth<<16) | TileStride;
+
+ OUTREG(0x816C,value);
+
+ }
+
+ OUTREG(0x48C18, INREG(0x48C18) | 0x8);
+
+ return TRUE;
+}
+
+static Bool
+SAVAGEDRICloseFullScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
+ unsigned int depth = pScrn->bitsPerPixel;
+ BCI_GET_PTR;
+
+ BCI_SEND(0xC0FF0000);
+ psav->WaitIdleEmpty(psav);
+ OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7);
+ /* set primary stream stride */
+ {
+ /* MM81C0 and 81C4 are used to control primary stream. */
+ OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000);
+ OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000);
+
+ /* FIFO control */
+ OUTREG32(0X81EC,0Xffffffff);
+
+ if (!psav->bTiled) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
+ (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+
+
+ }
+
+ /* set global bitmap descriptor */
+ {
+ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
+ OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | BCI_ENABLE | S3_LITTLE_ENDIAN | S3_BD64);
+
+ }
+
+ OUTREG(0x48C18, INREG(0x48C18) | 0x8);
+ return TRUE;
+}
+/* get the physics address (for shadow status)*/
+unsigned long SAVAGEDRIGetPhyAddress(ScrnInfoPtr pScrn,void * pointer)
+{
+
+ SavagePtr psav = SAVPTR(pScrn);
+
+ drm_savage_get_physcis_address_t req;
+ int ret;
+
+ req.v_address = (unsigned long )pointer;
+ ret = ioctl(psav->drmFD, DRM_IOCTL_SAVAGE_GET_PHYSICS_ADDRESS,&req);
+ if (ret != 1)
+ fprintf(stderr,"[GetPhyAddress],Wrong virtual address.\n");
+ return req.p_address;
+}
+
+#endif
diff --git a/src/savage_dri.h b/src/savage_dri.h
new file mode 100644
index 0000000..af62e76
--- /dev/null
+++ b/src/savage_dri.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef __SAVAGE_DRI_H__
+#define __SAVAGE_DRI_H__
+
+#include "xf86drm.h"
+#include "drm.h"
+
+#define SAVAGE_DEFAULT_AGP_MODE 1
+#define SAVAGE_MAX_AGP_MODE 4
+
+/* Buffer are aligned on 4096 byte boundaries.
+ */
+/* this is used for backbuffer, depthbuffer, etc..*/
+/* alignment */
+
+#define SAVAGE_BUFFER_ALIGN 0x00000fff
+
+typedef struct{
+ drm_context_t ctxOwner;
+ unsigned long agp_offset;
+ unsigned long agp_handle;
+ unsigned long map_handle;
+ int flags;
+} savageAgpBuffer , *savageAgpBufferPtr;
+
+typedef struct _server{
+ int reserved_map_agpstart;
+ int reserved_map_idx;
+
+#if 0
+ int buffer_map_idx;
+#endif
+
+ int sarea_priv_offset;
+
+#if 0
+ int primary_size;
+ int warp_ucode_size;
+#endif
+
+ int chipset;
+ int sgram; /* seems no use */
+
+ unsigned int frontOffset;
+ unsigned int frontPitch;
+ unsigned int frontbufferSize;
+
+ unsigned int backOffset;
+ unsigned int backPitch;
+ unsigned int backbufferSize;
+
+ unsigned int depthOffset;
+ unsigned int depthPitch;
+ unsigned int depthbufferSize;
+
+ unsigned int textureOffset;
+ int textureSize;
+ int logTextureGranularity;
+
+ drmRegion agp;
+
+ /* PCI mappings */
+ drmRegion aperture;
+ drmRegion registers;
+ drmRegion status;
+
+ /* AGP mappings */
+#if 0
+ drmRegion warp;
+ drmRegion primary;
+ drmRegion buffers;
+#endif
+
+ drmRegion agpTextures;
+ int logAgpTextureGranularity;
+
+#if 0
+ drmBufMapPtr drmBuffers;
+#endif
+ /*for agp*/
+ int numBuffer;
+ savageAgpBufferPtr agpBuffer;
+} SAVAGEDRIServerPrivateRec, *SAVAGEDRIServerPrivatePtr;
+
+typedef struct {
+ int chipset;
+ int width;
+ int height;
+ int mem;
+ int cpp;
+ int zpp;
+
+ int agpMode;
+
+ drm_handle_t frontbuffer;
+ unsigned int frontbufferSize;
+ unsigned int frontOffset;
+ unsigned int frontPitch;
+ unsigned int frontBitmapDesc; /*Bitmap Descriptior*/
+ unsigned int IsfrontTiled;
+
+ drm_handle_t backbuffer;
+ unsigned int backbufferSize;
+ unsigned int backOffset;
+ unsigned int backPitch;
+ unsigned int backBitmapDesc; /*Bitmap Descriptior*/
+
+ drm_handle_t depthbuffer;
+ unsigned int depthbufferSize;
+ unsigned int depthOffset;
+ unsigned int depthPitch;
+ unsigned int depthBitmapDesc; /*Bitmap Descriptior*/
+
+
+
+ drm_handle_t textures;
+ drm_handle_t xvmcSurfHandle;
+ unsigned int textureOffset;
+ unsigned int textureSize;
+ int logTextureGranularity;
+
+ /* Allow calculation of setup dma addresses.
+ */
+ unsigned int agpBufferOffset;
+
+ unsigned int agpTextureOffset;
+ unsigned int agpTextureSize;
+ drmRegion agpTextures;
+ int logAgpTextureGranularity;
+
+/* unsigned int mAccess;*/
+
+ drmRegion aperture;
+ unsigned int aperturePitch; /* in byte */
+
+
+ drmRegion registers;
+ drmRegion BCIcmdBuf;
+ drmRegion status;
+
+#if 0
+ drmRegion primary;
+ drmRegion buffers;
+#endif
+ /*For shadow status*/
+ unsigned long sareaPhysAddr;
+
+ unsigned int sarea_priv_offset;
+ int shadowStatus;
+} SAVAGEDRIRec, *SAVAGEDRIPtr;
+
+#endif
+
+
+
+
+
+
+
+
diff --git a/src/savage_dripriv.h b/src/savage_dripriv.h
new file mode 100644
index 0000000..19e4487
--- /dev/null
+++ b/src/savage_dripriv.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __SAVAGE_DRIPRIV_H__
+#define __SAVAGE_DRIPRIV_H__
+
+#include "GL/glxint.h"
+
+#define SAVAGE_MAX_DRAWABLES 256
+
+extern void GlxSetVisualConfigs( int nconfigs,
+ __GLXvisualConfig *configs,
+ void **configprivs );
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} SAVAGEConfigPrivRec, *SAVAGEConfigPrivPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} SAVAGEDRIContextRec, *SAVAGEDRIContextPtr;
+
+#endif
diff --git a/src/savage_drm.h b/src/savage_drm.h
new file mode 100644
index 0000000..62bd49b
--- /dev/null
+++ b/src/savage_drm.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __SAVAGE_DRM_H__
+#define __SAVAGE_DRM_H__
+
+#ifndef __SAVAGE_SAREA_DEFINES__
+#define __SAVAGE_SAREA_DEFINES__
+
+#define DRM_SAVAGE_MEM_PAGE (1UL<<12)
+#define DRM_SAVAGE_MEM_WORK 32
+#define DRM_SAVAGE_MEM_LOCATION_PCI 1
+#define DRM_SAVAGE_MEM_LOCATION_AGP 2
+#define DRM_SAVAGE_DMA_AGP_SIZE (16*1024*1024)
+
+typedef struct drm_savage_alloc_cont_mem
+{
+ size_t size; /*size of buffer*/
+ unsigned long type; /*4k page or word*/
+ unsigned long alignment;
+ unsigned long location; /*agp or pci*/
+
+ unsigned long phyaddress;
+ unsigned long linear;
+} drm_savage_alloc_cont_mem_t;
+
+typedef struct drm_savage_get_physcis_address
+{
+ unsigned long v_address;
+ unsigned long p_address;
+}drm_savage_get_physcis_address_t;
+
+/*ioctl number*/
+#define DRM_IOCTL_SAVAGE_ALLOC_CONTINUOUS_MEM \
+ DRM_IOWR(0x40,drm_savage_alloc_cont_mem_t)
+#define DRM_IOCTL_SAVAGE_GET_PHYSICS_ADDRESS \
+ DRM_IOWR(0x41, drm_savage_get_physcis_address_t)
+#define DRM_IOCTL_SAVAGE_FREE_CONTINUOUS_MEM \
+ DRM_IOWR(0x42, drm_savage_alloc_cont_mem_t)
+
+#define SAVAGE_FRONT 0x1
+#define SAVAGE_BACK 0x2
+#define SAVAGE_DEPTH 0x4
+#define SAVAGE_STENCIL 0x8
+
+/* What needs to be changed for the current vertex dma buffer?
+ */
+#define SAVAGE_UPLOAD_CTX 0x1
+#define SAVAGE_UPLOAD_TEX0 0x2
+#define SAVAGE_UPLOAD_TEX1 0x4
+#define SAVAGE_UPLOAD_PIPE 0x8 /* <- seems should be removed, Jiayo Hsu */
+#define SAVAGE_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */
+#define SAVAGE_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */
+#define SAVAGE_UPLOAD_2D 0x40
+#define SAVAGE_WAIT_AGE 0x80 /* handled client-side */
+#define SAVAGE_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
+/*frank:add Buffer state 2001/11/15*/
+#define SAVAGE_UPLOAD_BUFFERS 0x200
+/* original marked off in MGA drivers , Jiayo Hsu Oct.23,2001 */
+
+/* Keep these small for testing.
+ */
+#define SAVAGE_NR_SAREA_CLIPRECTS 8
+
+/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+ * regions, subject to a minimum region size of (1<<16) == 64k.
+ *
+ * Clients may subdivide regions internally, but when sharing between
+ * clients, the region size is the minimum granularity.
+ */
+
+#define SAVAGE_CARD_HEAP 0
+#define SAVAGE_AGP_HEAP 1
+#define SAVAGE_NR_TEX_HEAPS 2
+#define SAVAGE_NR_TEX_REGIONS 16 /* num. of global texture manage list element*/
+#define SAVAGE_LOG_MIN_TEX_REGION_SIZE 16 /* each region 64K, Jiayo Hsu */
+
+#endif /* __SAVAGE_SAREA_DEFINES__ */
+
+/* drm_tex_region_t define in drm.h */
+
+typedef drm_tex_region_t drm_savage_tex_region_t;
+
+/* Setup registers for 2D, X server
+ */
+typedef struct {
+ unsigned int pitch;
+} drm_savage_server_regs_t;
+
+
+typedef struct _drm_savage_sarea {
+ /* The channel for communication of state information to the kernel
+ * on firing a vertex dma buffer.
+ */
+ unsigned int setup[28]; /* 3D context registers */
+ drm_savage_server_regs_t server_state;
+
+ unsigned int dirty;
+
+ unsigned int vertsize; /* vertext size */
+
+ /* The current cliprects, or a subset thereof.
+ */
+ drm_clip_rect_t boxes[SAVAGE_NR_SAREA_CLIPRECTS];
+ unsigned int nbox;
+
+ /* Information about the most recently used 3d drawable. The
+ * client fills in the req_* fields, the server fills in the
+ * exported_ fields and puts the cliprects into boxes, above.
+ *
+ * The client clears the exported_drawable field before
+ * clobbering the boxes data.
+ */
+ unsigned int req_drawable; /* the X drawable id */
+ unsigned int req_draw_buffer; /* SAVAGE_FRONT or SAVAGE_BACK */
+
+ unsigned int exported_drawable;
+ unsigned int exported_index;
+ unsigned int exported_stamp;
+ unsigned int exported_buffers;
+ unsigned int exported_nfront;
+ unsigned int exported_nback;
+ int exported_back_x, exported_front_x, exported_w;
+ int exported_back_y, exported_front_y, exported_h;
+ drm_clip_rect_t exported_boxes[SAVAGE_NR_SAREA_CLIPRECTS];
+
+ /* Counters for aging textures and for client-side throttling.
+ */
+ unsigned int status[4];
+
+
+ /* LRU lists for texture memory in agp space and on the card.
+ */
+ drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1];
+ unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
+
+ /* Mechanism to validate card state.
+ */
+ int ctxOwner;
+ unsigned long shadow_status[64];/*too big?*/
+
+ /*agp offset*/
+ unsigned long agp_offset;
+} drm_savage_sarea_t,*drm_savage_sarea_ptr;
+
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (xf86drmMga.h)
+ */
+
+typedef struct drm_savage_init {
+
+ unsigned long sarea_priv_offset;
+
+ int chipset;
+ int sgram;
+
+ unsigned int maccess;
+
+ unsigned int fb_cpp;
+ unsigned int front_offset, front_pitch;
+ unsigned int back_offset, back_pitch;
+
+ unsigned int depth_cpp;
+ unsigned int depth_offset, depth_pitch;
+
+ unsigned int texture_offset[SAVAGE_NR_TEX_HEAPS];
+ unsigned int texture_size[SAVAGE_NR_TEX_HEAPS];
+
+ unsigned long fb_offset;
+ unsigned long mmio_offset;
+ unsigned long status_offset;
+#if 0
+/*============================================================*/
+ unsigned long warp_offset;
+ unsigned long primary_offset;
+ unsigned long buffers_offset;
+/*============================================================*/
+#endif /*end #if 0 */
+} drm_savage_init_t;
+
+typedef struct drm_savage_fullscreen {
+ enum {
+ SAVAGE_INIT_FULLSCREEN = 0x01,
+ SAVAGE_CLEANUP_FULLSCREEN = 0x02
+ } func;
+} drm_savage_fullscreen_t;
+
+typedef struct drm_savage_clear {
+ unsigned int flags;
+ unsigned int clear_color;
+ unsigned int clear_depth;
+ unsigned int color_mask;
+ unsigned int depth_mask;
+} drm_savage_clear_t;
+
+typedef struct drm_savage_vertex {
+ int idx; /* buffer to queue */
+ int used; /* bytes in use */
+ int discard; /* client finished with buffer? */
+} drm_savage_vertex_t;
+
+typedef struct drm_savage_indices {
+ int idx; /* buffer to queue */
+ unsigned int start;
+ unsigned int end;
+ int discard; /* client finished with buffer? */
+} drm_savage_indices_t;
+
+typedef struct drm_savage_iload {
+ int idx;
+ unsigned int dstorg;
+ unsigned int length;
+} drm_savage_iload_t;
+
+typedef struct _drm_savage_blit {
+ unsigned int planemask;
+ unsigned int srcorg;
+ unsigned int dstorg;
+ int src_pitch, dst_pitch;
+ int delta_sx, delta_sy;
+ int delta_dx, delta_dy;
+ int height, ydir; /* flip image vertically */
+ int source_pitch, dest_pitch;
+} drm_savage_blit_t;
+
+#endif
diff --git a/src/savage_hwmc.c b/src/savage_hwmc.c
new file mode 100644
index 0000000..37d314d
--- /dev/null
+++ b/src/savage_hwmc.c
@@ -0,0 +1,403 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+#include "regionstr.h"
+
+#include "savage_driver.h"
+#include "savage_dri.h"
+
+#include "xf86xv.h"
+#include "xf86xvmc.h"
+#include "Xv.h"
+#include "XvMC.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#define SAVAGE_MAX_SURFACES 5
+#define SAVAGE_MAX_SUBPICTURES 1
+
+#define XVMC_IDCT_8BIT 0x80000000
+
+
+int SAVAGEXvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
+ int *num_priv, long **priv );
+void SAVAGEXvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext);
+
+int SAVAGEXvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
+ int *num_priv, long **priv );
+void SAVAGEXvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf);
+
+int SAVAGEXvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf,
+ int *num_priv, long **priv );
+void SAVAGEXvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf);
+
+
+typedef struct {
+ drm_context_t drmcontext;
+ unsigned int fbBase;
+ unsigned int MMIOHandle;
+ unsigned int MMIOSize;
+ unsigned int SurfaceHandle;
+ unsigned int SurfaceOffset;
+ unsigned int SurfaceSize;
+ unsigned int DCTBlockHandle;
+ unsigned int DCTBlockOffset;
+ unsigned int DCTBlockSize;
+ unsigned int ApertureHandle;
+ unsigned int ApertureSize;
+ unsigned int bitsPerPixel;
+ unsigned int frameX0;
+ unsigned int frameY0;
+ unsigned int IOBase;
+ unsigned int displayWidth;
+ char busIdString[10];
+ char pad[2];
+} SAVAGEXvMCCreateContextRec;
+
+
+static int yv12_subpicture_index_list[1] =
+{
+ FOURCC_IA44
+};
+
+static XF86MCImageIDList yv12_subpicture_list =
+{
+ 1,
+ yv12_subpicture_index_list
+};
+
+static XF86MCSurfaceInfoRec savage_YV12_mpg2_surface =
+{
+ FOURCC_YV12,
+ XVMC_CHROMA_FORMAT_420,
+ 0,
+ 720,
+ 576,
+ 720,
+ 576,
+ XVMC_MPEG_2,
+ XVMC_OVERLAID_SURFACE | XVMC_INTRA_UNSIGNED | XVMC_BACKEND_SUBPICTURE | XVMC_IDCT_8BIT,
+ &yv12_subpicture_list
+};
+
+static XF86MCSurfaceInfoPtr ppSI[1] =
+{
+ (XF86MCSurfaceInfoPtr)&savage_YV12_mpg2_surface,
+};
+
+/* List of subpicture types that we support */
+static XF86ImageRec ia44_subpicture = XVIMAGE_IA44;
+
+static XF86ImagePtr savage_subpicture_list[1] =
+{
+ (XF86ImagePtr)&ia44_subpicture,
+};
+
+/* Fill in the device dependent adaptor record.
+ * This is named "SAVAGE Video Overlay" because this code falls under the
+ * XV extenstion, the name must match or it won't be used.
+ *
+ * Surface and Subpicture - see above
+ * Function pointers to functions below
+ */
+static XF86MCAdaptorRec pAdapt =
+{
+ "Savage Streams Engine", /* name */
+ 1, /* num_surfaces */
+ ppSI, /* surfaces */
+ 1, /* num_subpictures */
+ savage_subpicture_list, /* subpictures */
+ (xf86XvMCCreateContextProcPtr)SAVAGEXvMCCreateContext,
+ (xf86XvMCDestroyContextProcPtr)SAVAGEXvMCDestroyContext,
+ (xf86XvMCCreateSurfaceProcPtr)SAVAGEXvMCCreateSurface,
+ (xf86XvMCDestroySurfaceProcPtr)SAVAGEXvMCDestroySurface,
+ (xf86XvMCCreateSubpictureProcPtr)SAVAGEXvMCCreateSubpicture,
+ (xf86XvMCDestroySubpictureProcPtr)SAVAGEXvMCDestroySubpicture
+};
+
+static XF86MCAdaptorPtr ppAdapt[1] =
+{
+ (XF86MCAdaptorPtr)&pAdapt
+};
+
+/**************************************************************************
+ *
+ * SAVAGEInitMC
+ *
+ * Initialize the hardware motion compenstation extention for this
+ * hardware. The initialization routines want the address of the pointers
+ * to the structures, not the address of the structures. This means we
+ * allocate (or create static?) the pointer memory and pass that
+ * address. This seems a little convoluted.
+ *
+ * We need to allocate memory for the device depended adaptor record.
+ * This is what holds the pointers to all our device functions.
+ *
+ * We need to map the overlay registers into the drm.
+ *
+ * We need to map the surfaces into the drm.
+ *
+ * Inputs:
+ * Screen pointer
+ *
+ * Outputs:
+ * None, this calls the device independent screen initialization
+ * function.
+ *
+ * Revisions:
+ *
+ **************************************************************************/
+Bool SAVAGEInitMC(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr pSAVAGE = SAVPTR(pScrn);
+ DRIInfoPtr pDRIInfo = pSAVAGE->pDRIInfo;
+ SAVAGEDRIPtr pSAVAGEDriPriv = (SAVAGEDRIPtr)pDRIInfo->devPrivate;
+ int i;
+ unsigned int offset;
+
+ /* Clear the Surface Allocation */
+ for(i=0; i<SAVAGE_MAX_SURFACES; i++) {
+ pSAVAGE->surfaceAllocation[i] = 0;
+ }
+
+ if(pSAVAGE->hwmcSize == 0)
+ {
+ xf86DrvMsg(X_ERROR, pScrn->scrnIndex,
+ "SAVAGEInitMC: There is not enough memory!\n");
+ return FALSE;
+ }
+
+ offset = pSAVAGE->hwmcOffset + pSAVAGE->FrameBufferBase;
+
+ if(drmAddMap(pSAVAGE->drmFD, offset, pSAVAGE->hwmcSize,
+ DRM_FRAME_BUFFER, 0, &pSAVAGEDriPriv->xvmcSurfHandle) < 0)
+ {
+
+ xf86DrvMsg(X_ERROR, pScrn->scrnIndex,
+ "SAVAGEInitMC: Cannot add map to drm!\n");
+ return FALSE;
+ }
+
+ return xf86XvMCScreenInit(pScreen, 1, ppAdapt);
+}
+
+/**************************************************************************
+ *
+ * SAVAGEXvMCCreateContext
+ *
+ * Some info about the private data:
+ *
+ * Set *num_priv to the number of 32bit words that make up the size of
+ * of the data that priv will point to.
+ *
+ * *priv = (long *) xcalloc (elements, sizeof(element))
+ * *num_priv = (elements * sizeof(element)) >> 2;
+ *
+ **************************************************************************/
+
+int SAVAGEXvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
+ int *num_priv, long **priv )
+{
+ SavagePtr pSAVAGE = SAVPTR(pScrn);
+ DRIInfoPtr pDRIInfo = pSAVAGE->pDRIInfo;
+ SAVAGEDRIPtr pSAVAGEDriPriv = (SAVAGEDRIPtr)pDRIInfo->devPrivate;
+ SAVAGEXvMCCreateContextRec *contextRec;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+
+ if(!pSAVAGE->directRenderingEnabled) {
+ xf86DrvMsg(X_ERROR, pScrn->scrnIndex,
+ "SAVAGEXvMCCreateContext: Cannot use XvMC without DRI!\n");
+ return BadAlloc;
+ }
+
+ /* Context Already in use! */
+ if(pSAVAGE->xvmcContext) {
+ xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
+ "SAVAGEXvMCCreateContext: 2 XvMC Contexts Attempted, not supported.\n");
+ return BadAlloc;
+ }
+
+ *priv = xcalloc(1,sizeof(SAVAGEXvMCCreateContextRec));
+ contextRec = (SAVAGEXvMCCreateContextRec *)*priv;
+
+ if(!*priv) {
+ *num_priv = 0;
+ return(BadAlloc);
+ }
+
+ *num_priv = sizeof(SAVAGEXvMCCreateContextRec) >> 2;
+
+ if(drmCreateContext(pSAVAGE->drmFD, &(contextRec->drmcontext) ) < 0) {
+ xf86DrvMsg(X_ERROR, pScrn->scrnIndex,
+ "SAVAGEXvMCCreateContext: Unable to create DRMContext!\n");
+ xfree(*priv);
+ return(BadAlloc);
+ }
+
+ drmAuthMagic(pSAVAGE->drmFD, pContext->flags);
+
+ pSAVAGE->xvmcContext = contextRec->drmcontext;
+ contextRec->fbBase = pScrn->memPhysBase;
+
+ contextRec->MMIOHandle = pSAVAGEDriPriv->registers.handle;
+ contextRec->MMIOSize = pSAVAGEDriPriv->registers.size;
+
+ contextRec->DCTBlockHandle = pSAVAGEDriPriv->agpTextures.handle;
+ contextRec->DCTBlockOffset = pSAVAGEDriPriv->agpTextures.offset;
+ contextRec->DCTBlockSize = pSAVAGEDriPriv->agpTextures.size;
+
+ contextRec->SurfaceHandle = pSAVAGEDriPriv->xvmcSurfHandle;
+ contextRec->SurfaceOffset = pSAVAGE->hwmcOffset;
+ contextRec->SurfaceSize = pSAVAGE->hwmcSize;
+
+ contextRec->ApertureHandle = pSAVAGEDriPriv->aperture.handle;
+ contextRec->ApertureSize = pSAVAGEDriPriv->aperture.size;
+
+ contextRec->bitsPerPixel = pScrn->bitsPerPixel;
+ contextRec->frameX0 = pScrn->frameX0;
+ contextRec->frameY0 = pScrn->frameY0;
+ contextRec->IOBase = hwp->IOBase;
+ contextRec->displayWidth = pScrn->displayWidth;
+
+
+ strncpy (contextRec->busIdString, pDRIInfo->busIdString, 9);
+
+ return Success;
+}
+
+
+int SAVAGEXvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
+ int *num_priv, long **priv )
+{
+ SavagePtr pSAVAGE = SAVPTR(pScrn);
+ int i;
+ /* This size is used for flip, mixer, subpicture and palette buffers*/
+ unsigned int offset = ((786*576*2 + 2048)*5 + 2048) & 0xfffff800;
+
+ *priv = (long *)xcalloc(2,sizeof(long));
+
+ if(!*priv) {
+ xf86DrvMsg(X_ERROR, pScrn->scrnIndex,
+ "SAVAGEXvMCCreateSurface: Unable to allocate memory!\n");
+ *num_priv = 0;
+ return (BadAlloc);
+ }
+ *num_priv = 1;
+
+ /* Surface Arrangement is different based on 6 or 7 Surfaces */
+ for(i = 0; i < SAVAGE_MAX_SURFACES; i++) {
+ if(!pSAVAGE->surfaceAllocation[i]) {
+ pSAVAGE->surfaceAllocation[i] = pSurf->surface_id;
+ (*priv)[0] = offset + (576 * 786 * 2 + 2048) * i;
+ /* UV data starts at 0 offset, each set is 288k * */
+ return Success;
+ }
+ }
+
+ (*priv)[0] = 0;
+ return BadAlloc;
+}
+
+int SAVAGEXvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
+ int *num_priv, long **priv )
+{
+ SavagePtr pSAVAGE = SAVPTR(pScrn);
+ int i;
+
+ *priv = (long *)xcalloc(1,sizeof(long));
+
+ if(!*priv) {
+ xf86DrvMsg(X_ERROR, pScrn->scrnIndex,
+ "SAVAGEXvMCCreateSubpicture: Unable to allocate memory!\n");
+ *num_priv = 0;
+ return (BadAlloc);
+ }
+
+ *num_priv = 1;
+
+ for(i = SAVAGE_MAX_SURFACES; i < SAVAGE_MAX_SURFACES + SAVAGE_MAX_SUBPICTURES; i++) {
+ if(!pSAVAGE->surfaceAllocation[i]) {
+ pSAVAGE->surfaceAllocation[i] = pSubp->subpicture_id;
+ (*priv)[0] = ( 576*1024 * i);
+ return Success;
+ }
+ }
+
+ (*priv)[0] = 0;
+ return BadAlloc;
+}
+
+void SAVAGEXvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext)
+{
+ SavagePtr pSAVAGE = SAVPTR(pScrn);
+
+ drmDestroyContext(pSAVAGE->drmFD,pSAVAGE->xvmcContext);
+ pSAVAGE->xvmcContext = 0;
+}
+
+void SAVAGEXvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
+{
+ SavagePtr pSAVAGE = SAVPTR(pScrn);
+ int i;
+
+ for(i=0; i<SAVAGE_MAX_SURFACES; i++) {
+ if(pSAVAGE->surfaceAllocation[i] == pSurf->surface_id) {
+ pSAVAGE->surfaceAllocation[i] = 0;
+ return;
+ }
+ }
+ return;
+}
+
+void SAVAGEXvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp)
+{
+ SavagePtr pSAVAGE = SAVPTR(pScrn);
+ int i;
+
+ for(i = SAVAGE_MAX_SURFACES; i < SAVAGE_MAX_SURFACES + SAVAGE_MAX_SUBPICTURES; i++) {
+ if(pSAVAGE->surfaceAllocation[i] == pSubp->subpicture_id) {
+ pSAVAGE->surfaceAllocation[i] = 0;
+ return;
+ }
+ }
+ return;
+}
+
+
+
+
+
+
diff --git a/src/savage_sarea.h b/src/savage_sarea.h
new file mode 100644
index 0000000..d4287cf
--- /dev/null
+++ b/src/savage_sarea.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef __SAVAGE_SAREA_H__
+#define __SAVAGE_SAREA_H__
+
+#include "drm.h"
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (savage_drm.h)
+ */
+#ifndef __SAVAGE_SAREA_DEFINES__
+#define __SAVAGE_SAREA_DEFINES__
+#endif
+typedef drm_savage_sarea_t SAVAGESAREAPrivRec;
+typedef drm_savage_sarea_t *SAVAGESAREAPrivPtr;
+
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+