diff options
Diffstat (limited to 'src/atidri.c')
-rw-r--r-- | src/atidri.c | 1508 |
1 files changed, 0 insertions, 1508 deletions
diff --git a/src/atidri.c b/src/atidri.c deleted file mode 100644 index d5e1c898..00000000 --- a/src/atidri.c +++ /dev/null @@ -1,1508 +0,0 @@ -/* $XFree86$ */ /* -*- mode: c; c-basic-offset: 3 -*- */ -/* - * Copyright 2000 Gareth Hughes - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Leif Delgass <ldelgass@retinalburn.net> - */ - -/* Driver data structures */ -#include "ati.h" -#include "atibus.h" -#include "atidri.h" -#include "atiregs.h" -#include "atistruct.h" -#include "ativersion.h" - -#include "atimach64io.h" -#include "mach64_dri.h" -#include "mach64_common.h" -#include "mach64_sarea.h" - -/* X and server generic header files */ -#include "xf86.h" -#include "windowstr.h" - -/* GLX/DRI/DRM definitions */ -#define _XF86DRI_SERVER_ -#include "GL/glxtokens.h" -#include "sarea.h" - -static char ATIKernelDriverName[] = "mach64"; -static char ATIClientDriverName[] = "mach64"; - -/* 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 ATIInitVisualConfigs( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - int numConfigs = 0; - __GLXvisualConfig *pConfigs = NULL; - ATIConfigPrivPtr pATIConfigs = NULL; - ATIConfigPrivPtr *pATIConfigPtrs = NULL; - int i, accum, stencil, db; - - switch ( pATI->bitsPerPixel ) { - case 8: /* 8bpp mode is not support */ - case 15: /* FIXME */ - case 24: /* FIXME */ - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[dri] ATIInitVisualConfigs failed (%d bpp not supported). " - "Disabling DRI.\n", pATI->bitsPerPixel); - return FALSE; - -#define ATI_USE_ACCUM 1 -#define ATI_USE_STENCIL 1 - - case 16: - - if ( pATI->depth != 16) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[dri] ATIInitVisualConfigs failed (depth %d at 16 bpp not supported). " - "Disabling DRI.\n", pATI->depth); - return FALSE; - } - - numConfigs = 1; - if ( ATI_USE_ACCUM ) numConfigs *= 2; - if ( ATI_USE_STENCIL ) numConfigs *= 2; - numConfigs *= 2; /* single- and double-buffered */ - - pConfigs = (__GLXvisualConfig*) - xnfcalloc( sizeof(__GLXvisualConfig), numConfigs ); - if ( !pConfigs ) { - return FALSE; - } - pATIConfigs = (ATIConfigPrivPtr) - xnfcalloc( sizeof(ATIConfigPrivRec), numConfigs ); - if ( !pATIConfigs ) { - xfree( pConfigs ); - return FALSE; - } - pATIConfigPtrs = (ATIConfigPrivPtr*) - xnfcalloc( sizeof(ATIConfigPrivPtr), numConfigs ); - if ( !pATIConfigPtrs ) { - xfree( pConfigs ); - xfree( pATIConfigs ); - return FALSE; - } - - i = 0; - for (db = 0; db <= 1; db++) { - for ( accum = 0 ; accum <= ATI_USE_ACCUM ; accum++ ) { - for ( stencil = 0 ; stencil <= ATI_USE_STENCIL ; stencil++ ) { - pATIConfigPtrs[i] = &pATIConfigs[i]; - - 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 = 0x00000000; - if ( accum ) { /* Simulated in software */ - 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; - } - pConfigs[i].doubleBuffer = db ? TRUE : FALSE; - pConfigs[i].stereo = FALSE; - pConfigs[i].bufferSize = 16; - pConfigs[i].depthSize = 16; - if ( stencil ) { /* Simulated in software */ - 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_CONFIG; - } else { - pConfigs[i].visualRating = GLX_NONE; - } - pConfigs[i].transparentPixel = GLX_NONE; - pConfigs[i].transparentRed = 0; - pConfigs[i].transparentGreen = 0; - pConfigs[i].transparentBlue = 0; - pConfigs[i].transparentAlpha = 0; - pConfigs[i].transparentIndex = 0; - i++; - } - } - } - break; - - case 32: - numConfigs = 1; - if ( ATI_USE_ACCUM ) numConfigs *= 2; - if ( ATI_USE_STENCIL ) numConfigs *= 2; - numConfigs *= 2; /* single- and double-buffered */ - - pConfigs = (__GLXvisualConfig*) - xnfcalloc( sizeof(__GLXvisualConfig), numConfigs ); - if ( !pConfigs ) { - return FALSE; - } - pATIConfigs = (ATIConfigPrivPtr) - xnfcalloc( sizeof(ATIConfigPrivRec), numConfigs ); - if ( !pATIConfigs ) { - xfree( pConfigs ); - return FALSE; - } - pATIConfigPtrs = (ATIConfigPrivPtr*) - xnfcalloc( sizeof(ATIConfigPrivPtr), numConfigs ); - if ( !pATIConfigPtrs ) { - xfree( pConfigs ); - xfree( pATIConfigs ); - return FALSE; - } - - i = 0; - for (db = 0; db <= 1; db++) { - for ( accum = 0 ; accum <= ATI_USE_ACCUM ; accum++ ) { - for ( stencil = 0 ; stencil <= ATI_USE_STENCIL ; stencil++ ) { - pATIConfigPtrs[i] = &pATIConfigs[i]; - - pConfigs[i].vid = -1; - pConfigs[i].class = -1; - pConfigs[i].rgba = TRUE; - pConfigs[i].redSize = 8; - pConfigs[i].greenSize = 8; - pConfigs[i].blueSize = 8; - pConfigs[i].alphaSize = 0; - pConfigs[i].redMask = 0x00FF0000; - pConfigs[i].greenMask = 0x0000FF00; - pConfigs[i].blueMask = 0x000000FF; - pConfigs[i].alphaMask = 0x00000000; - if ( accum ) { /* Simulated in software */ - 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; - } - pConfigs[i].doubleBuffer = db ? TRUE : FALSE; - pConfigs[i].stereo = FALSE; - pConfigs[i].bufferSize = 24; - if ( stencil ) { /* Simulated in software */ - pConfigs[i].depthSize = 16; - pConfigs[i].stencilSize = 8; - } else { - pConfigs[i].depthSize = 16; - pConfigs[i].stencilSize = 0; - } - pConfigs[i].auxBuffers = 0; - pConfigs[i].level = 0; - if ( accum || stencil ) { - pConfigs[i].visualRating = GLX_SLOW_CONFIG; - } else { - pConfigs[i].visualRating = GLX_NONE; - } - pConfigs[i].transparentPixel = GLX_NONE; - pConfigs[i].transparentRed = 0; - pConfigs[i].transparentGreen = 0; - pConfigs[i].transparentBlue = 0; - pConfigs[i].transparentAlpha = 0; - pConfigs[i].transparentIndex = 0; - i++; - } - } - } - break; - } - - pATI->numVisualConfigs = numConfigs; - pATI->pVisualConfigs = pConfigs; - pATI->pVisualConfigsPriv = pATIConfigs; - GlxSetVisualConfigs( numConfigs, pConfigs, (void**)pATIConfigPtrs ); - return TRUE; -} - -/* Create the ATI-specific context information */ -static Bool ATICreateContext( ScreenPtr pScreen, VisualPtr visual, - drm_context_t hwContext, void *pVisualConfigPriv, - DRIContextType contextStore ) -{ - /* Nothing yet */ - return TRUE; -} - -/* Destroy the ATI-specific context information */ -static void ATIDestroyContext( ScreenPtr pScreen, drm_context_t hwContext, - DRIContextType contextStore ) -{ - /* Nothing yet */ -} - -/* Called when the X server is woken up to allow the last client's - * context to be saved and the X server's context to be loaded. - * The client detects when it's context is not currently loaded and - * then loads it itself. The X server's context is loaded in the - * XAA Sync callback if NeedDRISync is set. - */ -static void ATIEnterServer( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - - if ( pATI->directRenderingEnabled && pATI->pXAAInfo ) { - pATI->pXAAInfo->NeedToSync = TRUE; - pATI->NeedDRISync = TRUE; - } -} - -/* Called when the X server goes to sleep to allow the X server's - * context to be saved and the last client's context to be loaded. - * The client detects when it's context is not currently loaded and - * then loads it itself. The X server keeps track of it's own state. - */ -static void ATILeaveServer( ScreenPtr pScreen ) -{ - /* Nothing yet */ -} - -/* Contexts can be swapped by the X server if necessary. This callback - * is currently only used to perform any functions necessary when - * entering or leaving the X server, and in the future might not be - * necessary. - */ -static void ATIDRISwapContext( ScreenPtr pScreen, - DRISyncType syncType, - DRIContextType oldContextType, - void *oldContext, - DRIContextType newContextType, - void *newContext ) -{ - if ( ( syncType == DRI_3D_SYNC ) && ( oldContextType == DRI_2D_CONTEXT ) && - ( newContextType == DRI_2D_CONTEXT ) ) { - /* Entering from Wakeup */ - ATIEnterServer( pScreen ); - } - if ( ( syncType == DRI_2D_SYNC ) && ( oldContextType == DRI_NO_CONTEXT ) && - ( newContextType == DRI_2D_CONTEXT ) ) { - /* Exiting from Block Handler */ - ATILeaveServer( pScreen ); - } -} - -static void ATIDRITransitionTo2d(ScreenPtr pScreen) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - - if (pATI->backArea) { - xf86FreeOffscreenArea(pATI->backArea); - pATI->backArea = NULL; - } - if (pATI->depthTexArea) { - xf86FreeOffscreenArea(pATI->depthTexArea); - pATI->depthTexArea = NULL; - } - pATI->have3DWindows = FALSE; -} - -static void ATIDRITransitionTo3d(ScreenPtr pScreen) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - FBAreaPtr fbArea; - int width, height; - - xf86PurgeUnlockedOffscreenAreas(pScreen); - - xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0); - - xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - - fbArea = xf86AllocateOffscreenArea(pScreen, pScreenInfo->displayWidth, - height - pATI->depthTexLines - - pATI->backLines, - pScreenInfo->displayWidth, NULL, NULL, NULL); - - if (!fbArea) - xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve placeholder " - "offscreen area, you might experience screen corruption\n"); - - if (!pATI->backArea) { - pATI->backArea = - xf86AllocateOffscreenArea(pScreen, pScreenInfo->displayWidth, - pATI->backLines, - pScreenInfo->displayWidth, - NULL, NULL, NULL); - } - if (!pATI->backArea) - xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen area " - "for back buffer, you might experience screen corruption\n"); - - if (!pATI->depthTexArea) { - pATI->depthTexArea = - xf86AllocateOffscreenArea(pScreen, pScreenInfo->displayWidth, - pATI->depthTexLines, - pScreenInfo->displayWidth, - NULL, NULL, NULL); - } - if (!pATI->depthTexArea) - xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen area " - "for depth buffer and textures, you might experience screen corruption\n"); - - if (fbArea) - xf86FreeOffscreenArea(fbArea); - - pATI->have3DWindows = TRUE; -} - -/* Initialize the state of the back and depth buffers. */ -static void ATIDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 indx ) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; - XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo; - BoxPtr pbox, pboxSave; - int nbox, nboxSave; - int depth; - - depth = 0x0000ffff; - - if (!pXAAInfo) - return; - - if (!pXAAInfo->SetupForSolidFill) - return; - - /* FIXME: Only initialize the back and depth buffers for contexts - that request them */ - - /* FIXME: Use drm clear? (see Radeon driver) */ - - pboxSave = pbox = REGION_RECTS(prgn); - nboxSave = nbox = REGION_NUM_RECTS(prgn); - - (*pXAAInfo->SetupForSolidFill)(pScreenInfo, 0, GXcopy, (CARD32)(-1)); - for (; nbox; nbox--, pbox++) { - (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo, - pbox->x1 + pATIDRIServer->fbX, - pbox->y1 + pATIDRIServer->fbY, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo, - pbox->x1 + pATIDRIServer->backX, - pbox->y1 + pATIDRIServer->backY, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - } - - pbox = pboxSave; - nbox = nboxSave; - - (*pXAAInfo->SetupForSolidFill)(pScreenInfo, depth, GXcopy, (CARD32)(-1)); - for (; nbox; nbox--, pbox++) - (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo, - pbox->x1 + pATIDRIServer->depthX, - pbox->y1 + pATIDRIServer->depthY, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - - pXAAInfo->NeedToSync = TRUE; -} - -/* Copy the back and depth buffers when the X server moves a window. - * - * Note: this function was copied from the Radeon driver... - * - * 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. - */ -static void ATIDRIMoveBuffers( WindowPtr pWin, DDXPointRec ptOldOrg, - RegionPtr prgnSrc, CARD32 indx ) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo; - - int backOffsetPitch = (((pATI->pDRIServerInfo->backPitch/8) << 22) | - (pATI->pDRIServerInfo->backOffset >> 3)); -#if 0 - int depthOffsetPitch = (((pATI->pDRIServerInfo->depthPitch/8) << 22) | - (pATI->pDRIServerInfo->depthOffset >> 3)); -#endif - BoxPtr pboxTmp, pboxNext, pboxBase; - DDXPointPtr pptTmp; - int xdir, ydir; - - int screenwidth = pScreenInfo->virtualX; - int screenheight = pScreenInfo->virtualY; - - BoxPtr pbox = REGION_RECTS(prgnSrc); - int nbox = REGION_NUM_RECTS(prgnSrc); - - BoxPtr pboxNew1 = NULL; - BoxPtr pboxNew2 = NULL; - DDXPointPtr pptNew1 = NULL; - DDXPointPtr pptNew2 = NULL; - DDXPointPtr pptSrc = &ptOldOrg; - - int dx = pWin->drawable.x - ptOldOrg.x; - int dy = pWin->drawable.y - ptOldOrg.y; - - if (!pXAAInfo) - return; - - if (!pXAAInfo->SetupForScreenToScreenCopy) - return; - - /* FIXME: Only move the back and depth buffers for contexts - * that request them. - */ - - /* 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 order of rects in each band */ - pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); - pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); - if (!pboxNew2 || !pptNew2) { - DEALLOCATE_LOCAL(pptNew2); - DEALLOCATE_LOCAL(pboxNew2); - 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; - } - - (*pXAAInfo->SetupForScreenToScreenCopy)(pScreenInfo, xdir, ydir, GXcopy, - (CARD32)(-1), -1); - - for (; nbox-- ; pbox++) { - int xa = pbox->x1; - int ya = pbox->y1; - int destx = xa + dx; - int desty = ya + dy; - int w = pbox->x2 - xa + 1; - int h = pbox->y2 - ya + 1; - - if (destx < 0) xa -= destx, w += destx, destx = 0; - if (desty < 0) ya -= 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; - - ATIMach64WaitForFIFO(pATI, 2); - outf(SRC_OFF_PITCH, backOffsetPitch); - outf(DST_OFF_PITCH, backOffsetPitch); - - (*pXAAInfo->SubsequentScreenToScreenCopy)(pScreenInfo, - xa, ya, - destx, desty, - w, h); -#if 0 - /* FIXME: Move depth buffers? */ - ATIMach64WaitForFIFO(pATI, 2); - outf(SRC_OFF_PITCH, depthOffsetPitch); - outf(DST_OFF_PITCH, depthOffsetPitch); - - if (pATI->depthMoves) - ATIScreenToScreenCopyDepth(pScreenInfo, - xa, ya, - destx, desty, - w, h); -#endif - } - - ATIMach64WaitForFIFO(pATI, 2); - outf(SRC_OFF_PITCH, pATI->NewHW.dst_off_pitch); - outf(DST_OFF_PITCH, pATI->NewHW.src_off_pitch); - - DEALLOCATE_LOCAL(pptNew2); - DEALLOCATE_LOCAL(pboxNew2); - DEALLOCATE_LOCAL(pptNew1); - DEALLOCATE_LOCAL(pboxNew1); - - pXAAInfo->NeedToSync = TRUE; -} - -/* Compute log base 2 of val. */ -static int Mach64MinBits(int val) -{ - int bits; - - if (!val) return 1; - for (bits = 0; val; val >>= 1, ++bits); - return bits; -} - -/* Initialize the AGP state. Request memory for use in AGP space, and - * initialize the Rage Pro registers to point to that memory. - */ -static Bool ATIDRIAgpInit( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; - - unsigned long mode; - unsigned int vendor, device; - int ret; - unsigned long cntl; - int s, l; - - pATIDRIServer->agpSize = ATI_DEFAULT_AGP_SIZE; - pATIDRIServer->agpMode = ATI_DEFAULT_AGP_MODE; - pATIDRIServer->bufferSize = ATI_DEFAULT_BUFFER_SIZE; - pATIDRIServer->ringSize = 16; /* 16 kB ring */ - - if ( drmAgpAcquire( pATI->drmFD ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] AGP not available\n" ); - return FALSE; - } - - mode = drmAgpGetMode( pATI->drmFD ); /* Default mode */ - vendor = drmAgpVendorId( pATI->drmFD ); - device = drmAgpDeviceId( pATI->drmFD ); - - if (pATI->OptionAGPMode > 0 && pATI->OptionAGPMode <= ATI_AGP_MAX_MODE) { - pATIDRIServer->agpMode = pATI->OptionAGPMode; - xf86DrvMsg( pScreen->myNum, X_CONFIG, "[agp] Using AGP %dx Mode\n", - pATIDRIServer->agpMode ); - } else if (pATI->OptionAGPMode > 0) { - xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Illegal AGP Mode: %d\n", - pATI->OptionAGPMode ); - return FALSE; - } else { - /* If no mode configured, use the default mode obtained from agpgart */ - if ( mode & AGP_MODE_2X ) { - pATIDRIServer->agpMode = 2; - } else if ( mode & AGP_MODE_1X ) { - pATIDRIServer->agpMode = 1; - } - xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[agp] Using AGP %dx Mode\n", - pATIDRIServer->agpMode ); - } - - mode &= ~AGP_MODE_MASK; - switch ( pATIDRIServer->agpMode ) { - case 2: mode |= AGP_MODE_2X; - case 1: default: mode |= AGP_MODE_1X; - } - - if (pATI->OptionAGPSize) { - switch (pATI->OptionAGPSize) { - case 256: - case 128: - case 64: - case 32: - case 16: - case 8: - case 4: - pATIDRIServer->agpSize = pATI->OptionAGPSize; - xf86DrvMsg( pScreen->myNum, X_CONFIG, "[agp] Using %d MB AGP aperture\n", - pATIDRIServer->agpSize ); - break; - default: - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[agp] Illegal aperture size %d MB\n", pATI->OptionAGPSize ); - return FALSE; - } - } else { - xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[agp] Using %d MB AGP aperture\n", - pATIDRIServer->agpSize ); - } - - xf86DrvMsg( pScreen->myNum, X_INFO, - "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", - mode, vendor, device, - pATI->PCIInfo->vendor, - pATI->PCIInfo->chipType ); - - if ( drmAgpEnable( pATI->drmFD, mode ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" ); - drmAgpRelease( pATI->drmFD ); - return FALSE; - } - - pATIDRIServer->agpOffset = 0; - - ret = drmAgpAlloc( pATI->drmFD, pATIDRIServer->agpSize*1024*1024, - 0, NULL, &pATIDRIServer->agpHandle ); - if ( ret < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret ); - drmAgpRelease( pATI->drmFD ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[agp] %d kB allocated with handle 0x%08x\n", - pATIDRIServer->agpSize*1024, pATIDRIServer->agpHandle ); - - if ( drmAgpBind( pATI->drmFD, pATIDRIServer->agpHandle, pATIDRIServer->agpOffset) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind\n" ); - drmAgpFree( pATI->drmFD, pATIDRIServer->agpHandle ); - drmAgpRelease( pATI->drmFD ); - return FALSE; - } - - xf86DrvMsg(pScreen->myNum, X_INFO, - "[agp] Using %d kB for DMA descriptor ring\n", pATIDRIServer->ringSize); - - if (pATI->OptionBufferSize) { - if (pATI->OptionBufferSize < 1 || pATI->OptionBufferSize > pATIDRIServer->agpSize ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Illegal DMA buffers size: %d MB\n", - pATI->OptionBufferSize ); - return FALSE; - } - if (pATI->OptionBufferSize > 2) { - xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] Illegal DMA buffers size: %d MB\n", - pATI->OptionBufferSize ); - xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] Clamping DMA buffers size to 2 MB\n", - pATI->OptionBufferSize ); - pATIDRIServer->bufferSize = 2; - } else { - pATIDRIServer->bufferSize = pATI->OptionBufferSize; - xf86DrvMsg( pScreen->myNum, X_CONFIG, "[agp] Using %d MB for DMA buffers\n", - pATIDRIServer->bufferSize ); - } - } else { - xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[agp] Using %d MB for DMA buffers\n", - pATIDRIServer->bufferSize ); - } - - pATIDRIServer->agpTexSize = pATIDRIServer->agpSize - pATIDRIServer->bufferSize; - - /* Reserve space for the DMA descriptor ring */ - pATIDRIServer->ringStart = pATIDRIServer->agpOffset; - pATIDRIServer->ringMapSize = pATIDRIServer->ringSize*1024; /* ringSize is in kB */ - - /* Reserve space for the vertex buffer */ - pATIDRIServer->bufferStart = pATIDRIServer->ringStart + pATIDRIServer->ringMapSize; - pATIDRIServer->bufferMapSize = pATIDRIServer->bufferSize*1024*1024; - - /* Reserve the rest for AGP textures */ - pATIDRIServer->agpTexStart = pATIDRIServer->bufferStart + pATIDRIServer->bufferMapSize; - s = (pATIDRIServer->agpSize*1024*1024 - pATIDRIServer->agpTexStart); - l = Mach64MinBits((s-1) / MACH64_NR_TEX_REGIONS); - if (l < MACH64_LOG_TEX_GRANULARITY) l = MACH64_LOG_TEX_GRANULARITY; - pATIDRIServer->agpTexMapSize = (s >> l) << l; - pATIDRIServer->log2AGPTexGran = l; - - xf86DrvMsg(pScreen->myNum, X_INFO, - "[agp] Using %d kB for AGP textures\n", pATIDRIServer->agpTexMapSize/1024); - - /* Map DMA descriptor ring */ - if ( drmAddMap( pATI->drmFD, pATIDRIServer->ringStart, pATIDRIServer->ringMapSize, - DRM_AGP, DRM_RESTRICTED, &pATIDRIServer->ringHandle ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[agp] Could not add ring mapping\n" ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[agp] ring handle = 0x%08lx\n", - pATIDRIServer->ringHandle ); - - if ( drmMap( pATI->drmFD, pATIDRIServer->ringHandle, - pATIDRIServer->ringMapSize, &pATIDRIServer->ringMap ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[agp] Could not map ring\n" ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[agp] Ring mapped at 0x%08lx\n", - (unsigned long)pATIDRIServer->ringMap ); - - /* Map vertex buffers */ - if ( drmAddMap( pATI->drmFD, pATIDRIServer->bufferStart, pATIDRIServer->bufferMapSize, - DRM_AGP, 0, &pATIDRIServer->bufferHandle ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[agp] Could not add vertex buffers mapping\n" ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[agp] vertex buffers handle = 0x%08lx\n", - pATIDRIServer->bufferHandle ); - - if ( drmMap( pATI->drmFD, pATIDRIServer->bufferHandle, - pATIDRIServer->bufferMapSize, &pATIDRIServer->bufferMap ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[agp] Could not map vertex buffers\n" ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[agp] Vertex buffers mapped at 0x%08lx\n", - (unsigned long)pATIDRIServer->bufferMap ); - - /* Map AGP Textures */ - if (drmAddMap(pATI->drmFD, pATIDRIServer->agpTexStart, pATIDRIServer->agpTexMapSize, - DRM_AGP, 0, &pATIDRIServer->agpTexHandle) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[agp] Could not add AGP texture region mapping\n"); - return FALSE; - } - xf86DrvMsg(pScreen->myNum, X_INFO, - "[agp] AGP texture region handle = 0x%08lx\n", - pATIDRIServer->agpTexHandle); - - if (drmMap(pATI->drmFD, pATIDRIServer->agpTexHandle, pATIDRIServer->agpTexMapSize, - &pATIDRIServer->agpTexMap) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[agp] Could not map AGP texture region\n"); - return FALSE; - } - xf86DrvMsg(pScreen->myNum, X_INFO, - "[agp] AGP Texture region mapped at 0x%08lx\n", - (unsigned long)pATIDRIServer->agpTexMap); - - /* Initialize Mach64's AGP registers */ - cntl = inm( AGP_CNTL ); - cntl &= ~AGP_APER_SIZE_MASK; - switch ( pATIDRIServer->agpSize ) { - case 256: cntl |= AGP_APER_SIZE_256MB; break; - case 128: cntl |= AGP_APER_SIZE_128MB; break; - case 64: cntl |= AGP_APER_SIZE_64MB; break; - case 32: cntl |= AGP_APER_SIZE_32MB; break; - case 16: cntl |= AGP_APER_SIZE_16MB; break; - case 8: cntl |= AGP_APER_SIZE_8MB; break; - case 4: cntl |= AGP_APER_SIZE_4MB; break; - default: - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[agp] Illegal aperture size %d kB\n", - pATIDRIServer->agpSize*1024 ); - return FALSE; - } - - /* 1 = DATA comes in clock in which TRDY sampled (default) */ - /* 0 = DATA comes in clock after TRDY sampled */ - cntl |= AGP_TRDY_MODE; - - /* 1 = generate all reads as high priority */ - /* 0 = generate all reads as their default priority (default) */ - /* Setting this only works for me at AGP 1x mode (LLD) */ - if (pATIDRIServer->agpMode == 1) { - cntl |= HIGH_PRIORITY_READ_EN; - } else { - cntl &= ~HIGH_PRIORITY_READ_EN; - } - - outm( AGP_BASE, drmAgpBase(pATI->drmFD) ); - outm( AGP_CNTL, cntl ); - - return TRUE; -} - -/* Add a map for the MMIO registers that will be accessed by any - * DRI-based clients. - */ -static Bool ATIDRIMapInit( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; - - pATIDRIServer->regsSize = getpagesize(); - if ( drmAddMap( pATI->drmFD, pATI->Block1Base, - pATIDRIServer->regsSize, - DRM_REGISTERS, DRM_READ_ONLY, - &pATIDRIServer->regsHandle ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[drm] failed to map registers\n" ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[drm] register handle = 0x%08lx\n", - pATIDRIServer->regsHandle ); - - return TRUE; -} - -/* Initialize the kernel data structures. */ -static Bool ATIDRIKernelInit( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; - drmMach64Init info; - - memset( &info, 0, sizeof(drmMach64Init) ); - - info.func = DRM_MACH64_INIT_DMA; - info.sarea_priv_offset = sizeof(XF86DRISAREARec); - info.is_pci = pATIDRIServer->IsPCI; - info.dma_mode = pATI->OptionDMAMode; - - info.fb_bpp = pATI->bitsPerPixel; - info.front_offset = pATIDRIServer->frontOffset; - info.front_pitch = pATIDRIServer->frontPitch; - info.back_offset = pATIDRIServer->backOffset; - info.back_pitch = pATIDRIServer->backPitch; - - info.depth_bpp = 16; - info.depth_offset = pATIDRIServer->depthOffset; - info.depth_pitch = pATIDRIServer->depthPitch; - - info.fb_offset = pATI->LinearBase; - info.mmio_offset = pATIDRIServer->regsHandle; - info.ring_offset = pATIDRIServer->ringHandle; - info.buffers_offset = pATIDRIServer->bufferHandle; - info.agp_textures_offset = pATIDRIServer->agpTexHandle; - - if ( drmCommandWrite( pATI->drmFD, DRM_MACH64_INIT, - &info, sizeof(drmMach64Init) ) < 0 ) { - return FALSE; - } else { - return TRUE; - } -} - -/* Add a map for the DMA buffers that will be accessed by any - * DRI-based clients. - */ -static Bool ATIDRIAddBuffers( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; - - /* Initialize vertex buffers */ - if ( pATIDRIServer->IsPCI ) { - pATIDRIServer->numBuffers = drmAddBufs( pATI->drmFD, - (pATIDRIServer->bufferSize*1024*1024)/MACH64_BUFFER_SIZE, - MACH64_BUFFER_SIZE, - 0, - 0 ); - } else { - pATIDRIServer->numBuffers = drmAddBufs( pATI->drmFD, - pATIDRIServer->bufferMapSize/MACH64_BUFFER_SIZE, - MACH64_BUFFER_SIZE, - DRM_AGP_BUFFER, - pATIDRIServer->bufferStart ); - } - if ( pATIDRIServer->numBuffers <= 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[drm] Could not create DMA buffers list\n" ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[drm] Added %d %d byte DMA buffers\n", - pATIDRIServer->numBuffers, MACH64_BUFFER_SIZE ); - - return TRUE; -} - -static Bool ATIDRIMapBuffers( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; - - pATIDRIServer->drmBuffers = drmMapBufs( pATI->drmFD ); - if ( !pATIDRIServer->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 at 0x%08lx\n", - pATIDRIServer->drmBuffers->count, - pATIDRIServer->drmBuffers->list->address ); - - return TRUE; -} - -static Bool ATIDRIIrqInit( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - - if ( pATI->irq <= 0 ) { - pATI->irq = drmGetInterruptFromBusID(pATI->drmFD, - ((pciConfigPtr)pATI->PCIInfo - ->thisCard)->busnum, - ((pciConfigPtr)pATI->PCIInfo - ->thisCard)->devnum, - ((pciConfigPtr)pATI->PCIInfo - ->thisCard)->funcnum); - if ( pATI->irq <= 0 ) { - xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, - "[drm] Couldn't find IRQ for bus id %d:%d:%d\n", - ((pciConfigPtr)pATI->PCIInfo->thisCard)->busnum, - ((pciConfigPtr)pATI->PCIInfo->thisCard)->devnum, - ((pciConfigPtr)pATI->PCIInfo->thisCard)->funcnum); - pATI->irq = 0; - } else if ((drmCtlInstHandler(pATI->drmFD, pATI->irq)) != 0) { - xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, - "[drm] Failed to initialize interrupt handler with IRQ %d\n", - pATI->irq); - pATI->irq = 0; - } - - if (pATI->irq) - xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, - "[drm] Installed interrupt handler, using IRQ %d\n", - pATI->irq); - else { - xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, - "[drm] Falling back to irq-free operation\n", - pATI->irq); - return FALSE; - } - } - - return TRUE; - -} - -/* Initialize the screen-specific data structures for the DRI and the - * Rage Pro. This is the main entry point to the device-specific - * initialization code. It calls device-independent DRI functions to - * create the DRI data structures and initialize the DRI state. - */ -Bool ATIDRIScreenInit( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - DRIInfoPtr pDRIInfo; - ATIDRIPtr pATIDRI; - ATIDRIServerInfoPtr pATIDRIServer; - drmVersionPtr version; - int major, minor, patch; - - /* Check that the GLX, DRI, and DRM modules have been loaded by testing - * for known 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] ATIDRIScreenInit failed (libdri.a too old)\n" ); - return FALSE; - } - - /* Check the DRI version */ - DRIQueryVersion( &major, &minor, &patch ); - if ( major != 4 || minor < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[dri] ATIDRIScreenInit failed because of a version mismatch.\n" - "[dri] libDRI version is %d.%d.%d but version 4.0.x is needed.\n" - "[dri] Disabling the DRI.\n", - major, minor, patch ); - return FALSE; - } - - switch ( pATI->bitsPerPixel ) { - case 8: - /* These modes are not supported (yet). */ - case 15: - case 24: - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[dri] Direct rendering only supported in 16 and 32 bpp modes\n"); - return FALSE; - - /* Only 16 and 32 color depths are supported currently. */ - case 16: - if ( pATI->depth != 16) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[dri] Direct rendering not supported for depth %d at fbbpp 16.\n", pATI->depth ); - return FALSE; - } - break; - case 32: - break; - } - - /* Create the DRI data structure, and fill it in before calling the - * DRIScreenInit(). - */ - pDRIInfo = DRICreateInfoRec(); - if ( !pDRIInfo ) return FALSE; - - pATI->pDRIInfo = pDRIInfo; - pDRIInfo->drmDriverName = ATIKernelDriverName; - pDRIInfo->clientDriverName = ATIClientDriverName; - if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { - pDRIInfo->busIdString = DRICreatePCIBusID(pATI->PCIInfo); - } else { - pDRIInfo->busIdString = xalloc( 64 ); - sprintf( pDRIInfo->busIdString, - "PCI:%d:%d:%d", - pATI->PCIInfo->bus, - pATI->PCIInfo->device, - pATI->PCIInfo->func ); - } - pDRIInfo->ddxDriverMajorVersion = ATI_VERSION_MAJOR; - pDRIInfo->ddxDriverMinorVersion = ATI_VERSION_MINOR; - pDRIInfo->ddxDriverPatchVersion = ATI_VERSION_PATCH; - pDRIInfo->frameBufferPhysicalAddress = pATI->LinearBase; - pDRIInfo->frameBufferSize = pATI->LinearSize; - pDRIInfo->frameBufferStride = (pScreenInfo->displayWidth * - pATI->FBBytesPerPixel); - pDRIInfo->ddxDrawableTableEntry = ATI_MAX_DRAWABLES; - - if ( SAREA_MAX_DRAWABLES < ATI_MAX_DRAWABLES ) { - pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; - } else { - pDRIInfo->maxDrawableTableEntry = ATI_MAX_DRAWABLES; - } - - /* For now the mapping works by using a fixed size defined - * in the SAREA header - */ - if ( sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec) > SAREA_MAX ) { - ErrorF( "[dri] Data does not fit in SAREA\n" ); - return FALSE; - } - xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO, "[drm] SAREA %d+%d: %d\n", - sizeof(XF86DRISAREARec), sizeof(ATISAREAPrivRec), - sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec) ); - pDRIInfo->SAREASize = SAREA_MAX; - - pATIDRI = (ATIDRIPtr) xnfcalloc( sizeof(ATIDRIRec), 1 ); - if ( !pATIDRI ) { - DRIDestroyInfoRec( pATI->pDRIInfo ); - pATI->pDRIInfo = NULL; - xf86DrvMsg( pScreenInfo->scrnIndex, X_ERROR, - "[dri] Failed to allocate memory for private record\n" ); - return FALSE; - } - pATIDRIServer = (ATIDRIServerInfoPtr) - xnfcalloc( sizeof(ATIDRIServerInfoRec), 1 ); - if ( !pATIDRIServer ) { - xfree( pATIDRI ); - DRIDestroyInfoRec( pATI->pDRIInfo ); - pATI->pDRIInfo = NULL; - xf86DrvMsg( pScreenInfo->scrnIndex, X_ERROR, - "[dri] Failed to allocate memory for private record\n" ); - return FALSE; - } - - pATI->pDRIServerInfo = pATIDRIServer; - - pDRIInfo->devPrivate = pATIDRI; - pDRIInfo->devPrivateSize = sizeof(ATIDRIRec); - pDRIInfo->contextSize = sizeof(ATIDRIContextRec); - - pDRIInfo->CreateContext = ATICreateContext; - pDRIInfo->DestroyContext = ATIDestroyContext; - pDRIInfo->SwapContext = ATIDRISwapContext; - pDRIInfo->InitBuffers = ATIDRIInitBuffers; - pDRIInfo->MoveBuffers = ATIDRIMoveBuffers; - pDRIInfo->TransitionTo2d = ATIDRITransitionTo2d; - pDRIInfo->TransitionTo3d = ATIDRITransitionTo3d; - pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; - - pDRIInfo->createDummyCtx = TRUE; - pDRIInfo->createDummyCtxPriv = FALSE; - - pATI->have3DWindows = FALSE; - - if ( !DRIScreenInit( pScreen, pDRIInfo, &pATI->drmFD ) ) { - xfree( pATIDRIServer ); - pATI->pDRIServerInfo = NULL; - xfree( pDRIInfo->devPrivate ); - pDRIInfo->devPrivate = NULL; - DRIDestroyInfoRec( pDRIInfo ); - pDRIInfo = NULL; - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[dri] DRIScreenInit Failed\n" ); - return FALSE; - } - - /* Check the DRM lib version. - drmGetLibVersion was not supported in version 1.0, so check for - symbol first to avoid possible crash or hang. - */ - if (xf86LoaderCheckSymbol("drmGetLibVersion")) { - version = drmGetLibVersion(pATI->drmFD); - } else { - /* drmlib version 1.0.0 didn't have the drmGetLibVersion - entry point. Fake it by allocating a version record - via drmGetVersion and changing it to version 1.0.0 - */ - version = drmGetVersion(pATI->drmFD); - version->version_major = 1; - version->version_minor = 0; - version->version_patchlevel = 0; - } - - if (version) { - if (version->version_major != 1 || - version->version_minor < 1) { - /* incompatible drm library version */ - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[dri] ATIDRIScreenInit failed because of a version mismatch.\n" - "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel); - drmFreeVersion(version); - ATIDRICloseScreen(pScreen); - return FALSE; - } - drmFreeVersion(version); - } - - /* Check the mach64 DRM version */ - version = drmGetVersion( pATI->drmFD ); - if ( version ) { - if ( version->version_major != 1 || - version->version_minor < 0 ) { - /* Incompatible DRM version */ - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[dri] ATIDRIScreenInit failed because of a version mismatch.\n" - "[dri] mach64.o kernel module version is %d.%d.%d, but version 1.0 or greater is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel ); - drmFreeVersion( version ); - ATIDRICloseScreen( pScreen ); - return FALSE; - } - drmFreeVersion( version ); - } - - switch ( pATI->OptionDMAMode ) { - case MACH64_MODE_DMA_ASYNC: - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Will request asynchronous DMA mode\n"); - break; - case MACH64_MODE_DMA_SYNC: - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Will request synchronous DMA mode\n"); - break; - case MACH64_MODE_MMIO: - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Will request pseudo-DMA (MMIO) mode\n"); - break; - default: - xf86DrvMsg(pScreen->myNum, X_WARNING, "[drm] Unknown DMA mode\n"); - } - - pATIDRIServer->IsPCI = (pATI->BusType == ATI_BUS_PCI || pATI->OptionIsPCI) ? TRUE : FALSE; - - if ( pATI->BusType != ATI_BUS_PCI && pATI->OptionIsPCI ) { - outm( AGP_BASE, 0 ); - outm( AGP_CNTL, 0 ); - xf86DrvMsg(pScreen->myNum, X_CONFIG, "[dri] Forcing PCI mode\n"); - } - - /* Check buffer size option for PCI, since it won't be done in ATIDRIAgpInit */ - if ( pATIDRIServer->IsPCI) { - pATIDRIServer->bufferSize = ATI_DEFAULT_BUFFER_SIZE; - if (pATI->OptionBufferSize) { - if (pATI->OptionBufferSize < 1) { - xf86DrvMsg( pScreen->myNum, X_ERROR, "[pci] Illegal DMA buffers size: %d MB\n", - pATI->OptionBufferSize ); - ATIDRICloseScreen( pScreen ); - return FALSE; - } - if (pATI->OptionBufferSize > 2) { - xf86DrvMsg( pScreen->myNum, X_WARNING, "[pci] Illegal DMA buffers size: %d MB\n", - pATI->OptionBufferSize ); - xf86DrvMsg( pScreen->myNum, X_WARNING, "[pci] Clamping DMA buffers size to 2 MB\n", - pATI->OptionBufferSize ); - pATIDRIServer->bufferSize = 2; - } else { - pATIDRIServer->bufferSize = pATI->OptionBufferSize; - xf86DrvMsg( pScreen->myNum, X_CONFIG, "[pci] Using %d MB DMA buffer size\n", - pATIDRIServer->bufferSize ); - } - } else { - xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[pci] Using %d MB DMA buffer size\n", - pATIDRIServer->bufferSize ); - } - } - - /* Initialize AGP */ - if ( !pATIDRIServer->IsPCI && !ATIDRIAgpInit( pScreen ) ) { - pATIDRIServer->IsPCI = TRUE; - if ( pATI->BusType != ATI_BUS_PCI ) { - outm( AGP_BASE, 0 ); - outm( AGP_CNTL, 0 ); - } - xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] AGP failed to initialize -- falling back to PCI mode.\n" ); - xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] Make sure you have the agpgart kernel module loaded.\n" ); - } - - if ( !ATIDRIMapInit( pScreen ) ) { - ATIDRICloseScreen( pScreen ); - return FALSE; - } - - if ( !ATIInitVisualConfigs( pScreen ) ) { - ATIDRICloseScreen( pScreen ); - return FALSE; - } - xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO, - "[dri] Visual configs initialized\n" ); - - xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO, - "[dri] Block 0 base at 0x%08lx\n", pATI->Block0Base ); - - return TRUE; -} - -/* Finish initializing the device-dependent DRI state, and call - * DRIFinishScreenInit() to complete the device-independent DRI - * initialization. - */ -Bool ATIDRIFinishScreenInit( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - ATISAREAPrivPtr pSAREAPriv; - ATIDRIPtr pATIDRI; - ATIDRIServerInfoPtr pATIDRIServer; - - pATI->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 ) ) { - ATIDRICloseScreen( pScreen ); - return FALSE; - } - - /* Initialize the DMA buffer list */ - /* Need to do this before ATIDRIKernelInit so we can init the freelist */ - if ( !ATIDRIAddBuffers( pScreen ) ) { - ATIDRICloseScreen( pScreen ); - return FALSE; - } - - /* Initialize the kernel data structures */ - if ( !ATIDRIKernelInit( pScreen ) ) { - xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, - "[drm] Failed to initialize the mach64.o kernel module\n"); - xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, - "[drm] Check the system log for more information.\n"); - ATIDRICloseScreen( pScreen ); - return FALSE; - } - - if ( !ATIDRIMapBuffers( pScreen ) ) { - ATIDRICloseScreen( pScreen ); - return FALSE; - } - - /* Initialize IRQ */ - ATIDRIIrqInit( pScreen ); - - pSAREAPriv = (ATISAREAPrivPtr) DRIGetSAREAPrivate( pScreen ); - memset( pSAREAPriv, 0, sizeof(*pSAREAPriv) ); - - pATIDRI = (ATIDRIPtr)pATI->pDRIInfo->devPrivate; - pATIDRIServer = pATI->pDRIServerInfo; - - pATIDRI->width = pScreenInfo->virtualX; - pATIDRI->height = pScreenInfo->virtualY; - pATIDRI->mem = pScreenInfo->videoRam * 1024; - pATIDRI->cpp = pScreenInfo->bitsPerPixel / 8; - - pATIDRI->IsPCI = pATIDRIServer->IsPCI; - pATIDRI->AGPMode = pATIDRIServer->agpMode; - - pATIDRI->frontOffset = pATIDRIServer->frontOffset; - pATIDRI->frontPitch = pATIDRIServer->frontPitch; - - pATIDRI->backOffset = pATIDRIServer->backOffset; - pATIDRI->backPitch = pATIDRIServer->backPitch; - - pATIDRI->depthOffset = pATIDRIServer->depthOffset; - pATIDRI->depthPitch = pATIDRIServer->depthPitch; - - pATIDRI->textureOffset = pATIDRIServer->textureOffset; - pATIDRI->textureSize = pATIDRIServer->textureSize; - pATIDRI->logTextureGranularity = pATIDRIServer->logTextureGranularity; - - pATIDRI->regs = pATIDRIServer->regsHandle; - pATIDRI->regsSize = pATIDRIServer->regsSize; - - pATIDRI->agp = pATIDRIServer->agpTexHandle; - pATIDRI->agpSize = pATIDRIServer->agpTexMapSize; - pATIDRI->logAgpTextureGranularity = pATIDRIServer->log2AGPTexGran; - pATIDRI->agpTextureOffset = pATIDRIServer->agpTexStart; - - return TRUE; -} - -/* The screen is being closed, so clean up any state and free any - * resources used by the DRI. - */ -void ATIDRICloseScreen( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; - ATIPtr pATI = ATIPTR(pScreenInfo); - ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; - drmMach64Init info; - - /* Stop interrupt generation and handling if used */ - if ( pATI->irq > 0 ) { - if ( drmCtlUninstHandler(pATI->drmFD) != 0 ) { - xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, - "[drm] Error uninstalling interrupt handler for IRQ %d\n", pATI->irq); - } else { - xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, - "[drm] Uninstalled interrupt handler for IRQ %d\n", pATI->irq); - } - pATI->irq = 0; - } - - /* De-allocate DMA buffers */ - if ( pATIDRIServer->drmBuffers ) { - drmUnmapBufs( pATIDRIServer->drmBuffers ); - pATIDRIServer->drmBuffers = NULL; - } - - /* De-allocate all kernel resources */ - memset(&info, 0, sizeof(drmMach64Init)); - info.func = DRM_MACH64_CLEANUP_DMA; - drmCommandWrite( pATI->drmFD, DRM_MACH64_INIT, - &info, sizeof(drmMach64Init) ); - - /* De-allocate all AGP resources */ - if ( pATIDRIServer->agpTexMap ) { - drmUnmap( pATIDRIServer->agpTexMap, pATIDRIServer->agpTexMapSize ); - pATIDRIServer->agpTexMap = NULL; - } - if ( pATIDRIServer->bufferMap ) { - drmUnmap( pATIDRIServer->bufferMap, pATIDRIServer->bufferMapSize ); - pATIDRIServer->bufferMap = NULL; - } - if ( pATIDRIServer->agpHandle ) { - drmAgpUnbind( pATI->drmFD, pATIDRIServer->agpHandle ); - drmAgpFree( pATI->drmFD, pATIDRIServer->agpHandle ); - pATIDRIServer->agpHandle = 0; - drmAgpRelease( pATI->drmFD ); - } - - /* De-allocate all DRI resources */ - DRICloseScreen( pScreen ); - - /* De-allocate all DRI data structures */ - if ( pATI->pDRIInfo ) { - if ( pATI->pDRIInfo->devPrivate ) { - xfree( pATI->pDRIInfo->devPrivate ); - pATI->pDRIInfo->devPrivate = NULL; - } - DRIDestroyInfoRec( pATI->pDRIInfo ); - pATI->pDRIInfo = NULL; - } - if ( pATI->pDRIServerInfo ) { - xfree( pATI->pDRIServerInfo ); - pATI->pDRIServerInfo = NULL; - } - if ( pATI->pVisualConfigs ) { - xfree( pATI->pVisualConfigs ); - pATI->pVisualConfigs = NULL; - } - if ( pATI->pVisualConfigsPriv ) { - xfree( pATI->pVisualConfigsPriv ); - pATI->pVisualConfigsPriv = NULL; - } -} |