atiscreen.c revision 1b12faf6
132b578d3Smrg/* 232b578d3Smrg * Copyright 1999 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 332b578d3Smrg * 432b578d3Smrg * Permission to use, copy, modify, distribute, and sell this software and its 532b578d3Smrg * documentation for any purpose is hereby granted without fee, provided that 632b578d3Smrg * the above copyright notice appear in all copies and that both that copyright 732b578d3Smrg * notice and this permission notice appear in supporting documentation, and 832b578d3Smrg * that the name of Marc Aurele La France not be used in advertising or 932b578d3Smrg * publicity pertaining to distribution of the software without specific, 1032b578d3Smrg * written prior permission. Marc Aurele La France makes no representations 1132b578d3Smrg * about the suitability of this software for any purpose. It is provided 1232b578d3Smrg * "as-is" without express or implied warranty. 1332b578d3Smrg * 1432b578d3Smrg * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1532b578d3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 1632b578d3Smrg * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1732b578d3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1832b578d3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1932b578d3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2032b578d3Smrg * PERFORMANCE OF THIS SOFTWARE. 2132b578d3Smrg * 2232b578d3Smrg * DRI support by: 2332b578d3Smrg * Gareth Hughes <gareth@valinux.com> 2432b578d3Smrg * José Fonseca <j_r_fonseca@yahoo.co.uk> 2532b578d3Smrg * Leif Delgass <ldelgass@retinalburn.net> 2632b578d3Smrg */ 2732b578d3Smrg 2832b578d3Smrg#ifdef HAVE_CONFIG_H 2932b578d3Smrg#include "config.h" 3032b578d3Smrg#endif 3132b578d3Smrg 3232b578d3Smrg#include <string.h> 3332b578d3Smrg 3432b578d3Smrg#include "ati.h" 3532b578d3Smrg#include "atibus.h" 3632b578d3Smrg#include "atichip.h" 3732b578d3Smrg#include "aticonsole.h" 3832b578d3Smrg#include "aticursor.h" 3932b578d3Smrg#include "atidac.h" 4032b578d3Smrg#include "atidga.h" 4132b578d3Smrg#include "atidri.h" 4232b578d3Smrg#include "atimach64.h" 4332b578d3Smrg#include "atimode.h" 4432b578d3Smrg#include "atiscreen.h" 4532b578d3Smrg#include "atistruct.h" 4632b578d3Smrg#include "atixv.h" 4732b578d3Smrg#include "atimach64accel.h" 4832b578d3Smrg 4932b578d3Smrg#ifdef XF86DRI_DEVEL 5032b578d3Smrg#include "mach64_dri.h" 5132b578d3Smrg#include "mach64_sarea.h" 5232b578d3Smrg#endif 5332b578d3Smrg 5432b578d3Smrg#ifdef TV_OUT 5532b578d3Smrg 5632b578d3Smrg#include "atichip.h" 5732b578d3Smrg 5832b578d3Smrg#endif /* TV_OUT */ 5932b578d3Smrg 6032b578d3Smrg#include "shadowfb.h" 6132b578d3Smrg#include "xf86cmap.h" 6232b578d3Smrg 6332b578d3Smrg#include "fb.h" 6432b578d3Smrg 6532b578d3Smrg#include "micmap.h" 6632b578d3Smrg#include "mipointer.h" 6732b578d3Smrg 6832b578d3Smrg/* 6932b578d3Smrg * ATIRefreshArea -- 7032b578d3Smrg * 7132b578d3Smrg * This function is called by the shadow frame buffer code to refresh the 7232b578d3Smrg * hardware frame buffer. 7332b578d3Smrg */ 7432b578d3Smrgstatic void 7532b578d3SmrgATIRefreshArea 7632b578d3Smrg( 7732b578d3Smrg ScrnInfoPtr pScreenInfo, 7832b578d3Smrg int nBox, 7932b578d3Smrg BoxPtr pBox 8032b578d3Smrg) 8132b578d3Smrg{ 8232b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 8332b578d3Smrg pointer pSrc, pDst; 8432b578d3Smrg int offset, w, h; 8532b578d3Smrg 8632b578d3Smrg while (nBox-- > 0) 8732b578d3Smrg { 8832b578d3Smrg w = (pBox->x2 - pBox->x1) * pATI->AdjustDepth; 8932b578d3Smrg h = pBox->y2 - pBox->y1; 9032b578d3Smrg offset = (pBox->y1 * pATI->FBPitch) + (pBox->x1 * pATI->AdjustDepth); 9132b578d3Smrg pSrc = (char *)pATI->pShadow + offset; 9232b578d3Smrg pDst = (char *)pATI->pMemory + offset; 9332b578d3Smrg 9432b578d3Smrg while (h-- > 0) 9532b578d3Smrg { 9632b578d3Smrg (void)memcpy(pDst, pSrc, w); 9732b578d3Smrg pSrc = (char *)pSrc + pATI->FBPitch; 9832b578d3Smrg pDst = (char *)pDst + pATI->FBPitch; 9932b578d3Smrg } 10032b578d3Smrg 10132b578d3Smrg pBox++; 10232b578d3Smrg } 10332b578d3Smrg} 10432b578d3Smrg 10532b578d3Smrg/* 10632b578d3Smrg * ATIMinBits -- 10732b578d3Smrg * 10832b578d3Smrg * Compute log base 2 of val. 10932b578d3Smrg */ 11032b578d3Smrgstatic int 11132b578d3SmrgATIMinBits 11232b578d3Smrg( 11332b578d3Smrg int val 11432b578d3Smrg) 11532b578d3Smrg{ 11632b578d3Smrg int bits; 11732b578d3Smrg 11832b578d3Smrg if (!val) return 1; 11932b578d3Smrg for (bits = 0; val; val >>= 1, ++bits); 12032b578d3Smrg return bits; 12132b578d3Smrg} 12232b578d3Smrg 12332b578d3Smrg#ifdef USE_XAA 12432b578d3Smrgstatic Bool 12532b578d3SmrgATIMach64SetupMemXAA_NoDRI 12632b578d3Smrg( 12732b578d3Smrg int iScreen, 12832b578d3Smrg ScreenPtr pScreen 12932b578d3Smrg) 13032b578d3Smrg{ 13132b578d3Smrg ScrnInfoPtr pScreenInfo = xf86Screens[iScreen]; 13232b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 13332b578d3Smrg 13432b578d3Smrg int maxScanlines = ATIMach64MaxY; 13532b578d3Smrg int maxPixelArea, PixelArea; 13632b578d3Smrg 13732b578d3Smrg { 13832b578d3Smrg /* 13932b578d3Smrg * Note: If PixelArea exceeds the engine's maximum, the excess is 14032b578d3Smrg * never used, even though it would be useful for such things 14132b578d3Smrg * as XVideo buffers. 14232b578d3Smrg */ 14332b578d3Smrg maxPixelArea = maxScanlines * pScreenInfo->displayWidth; 14432b578d3Smrg PixelArea = pScreenInfo->videoRam * 1024 * 8 / pATI->bitsPerPixel; 14532b578d3Smrg if (PixelArea > maxPixelArea) 14632b578d3Smrg PixelArea = maxPixelArea; 14732b578d3Smrg xf86InitFBManagerArea(pScreen, PixelArea, 2); 14832b578d3Smrg } 14932b578d3Smrg 15032b578d3Smrg return TRUE; 15132b578d3Smrg} 15232b578d3Smrg 15332b578d3Smrg#ifdef XF86DRI_DEVEL 15432b578d3Smrg/* 15532b578d3Smrg * Memory layour for XAA with DRI (no local_textures): 15632b578d3Smrg * | front | pixmaps, xv | back | depth | textures | c | 15732b578d3Smrg * 15832b578d3Smrg * 1024x768@16bpp with 8 MB: 15932b578d3Smrg * | 1.5 MB | ~3.5 MB | 1.5 MB | 1.5 MB | 0 | c | 16032b578d3Smrg * 16132b578d3Smrg * 1024x768@32bpp with 8 MB: 16232b578d3Smrg * | 3.0 MB | ~0.5 MB | 3.0 MB | 1.5 MB | 0 | c | 16332b578d3Smrg * 16432b578d3Smrg * "c" is the hw cursor which occupies 1KB 16532b578d3Smrg */ 16632b578d3Smrgstatic Bool 16732b578d3SmrgATIMach64SetupMemXAA 16832b578d3Smrg( 16932b578d3Smrg int iScreen, 17032b578d3Smrg ScreenPtr pScreen 17132b578d3Smrg) 17232b578d3Smrg{ 17332b578d3Smrg ScrnInfoPtr pScreenInfo = xf86Screens[iScreen]; 17432b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 17532b578d3Smrg 17632b578d3Smrg ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; 17732b578d3Smrg int cpp = pATI->bitsPerPixel >> 3; 17832b578d3Smrg int widthBytes = pScreenInfo->displayWidth * cpp; 17932b578d3Smrg int zWidthBytes = pScreenInfo->displayWidth * 2; /* always 16-bit z-buffer */ 18032b578d3Smrg int fbSize = pScreenInfo->videoRam * 1024; 18132b578d3Smrg int bufferSize = pScreenInfo->virtualY * widthBytes; 18232b578d3Smrg int zBufferSize = pScreenInfo->virtualY * zWidthBytes; 18332b578d3Smrg int offscreenBytes, total, scanlines; 18432b578d3Smrg 18532b578d3Smrg pATIDRIServer->fbX = 0; 18632b578d3Smrg pATIDRIServer->fbY = 0; 18732b578d3Smrg pATIDRIServer->frontOffset = 0; 18832b578d3Smrg pATIDRIServer->frontPitch = pScreenInfo->displayWidth; 18932b578d3Smrg 19032b578d3Smrg /* Calculate memory remaining for pixcache and textures after 19132b578d3Smrg * front, back, and depth buffers 19232b578d3Smrg */ 19332b578d3Smrg offscreenBytes = fbSize - ( 2 * bufferSize + zBufferSize ); 19432b578d3Smrg 19532b578d3Smrg if ( !pATIDRIServer->IsPCI && !pATI->OptionLocalTextures ) { 19632b578d3Smrg /* Don't allocate a local texture heap for AGP unless requested */ 19732b578d3Smrg pATIDRIServer->textureSize = 0; 19832b578d3Smrg } else { 19932b578d3Smrg int l, maxPixcache; 20032b578d3Smrg 20132b578d3Smrg#ifdef XvExtension 20232b578d3Smrg 20332b578d3Smrg int xvBytes; 20432b578d3Smrg 20532b578d3Smrg /* Try for enough pixmap cache for DVD and a full viewport 20632b578d3Smrg */ 20732b578d3Smrg xvBytes = 720*480*cpp; /* enough for single-buffered DVD */ 20832b578d3Smrg maxPixcache = xvBytes > bufferSize ? xvBytes : bufferSize; 20932b578d3Smrg 21032b578d3Smrg#else /* XvExtension */ 21132b578d3Smrg 21232b578d3Smrg /* Try for one viewport */ 21332b578d3Smrg maxPixcache = bufferSize; 21432b578d3Smrg 21532b578d3Smrg#endif /* XvExtension */ 21632b578d3Smrg 21732b578d3Smrg pATIDRIServer->textureSize = offscreenBytes - maxPixcache; 21832b578d3Smrg 21932b578d3Smrg /* If that gives us less than half the offscreen mem available for textures, split 22032b578d3Smrg * the available mem between textures and pixmap cache 22132b578d3Smrg */ 22232b578d3Smrg if (pATIDRIServer->textureSize < (offscreenBytes/2)) { 22332b578d3Smrg pATIDRIServer->textureSize = offscreenBytes/2; 22432b578d3Smrg } 22532b578d3Smrg 22632b578d3Smrg if (pATIDRIServer->textureSize <= 0) 22732b578d3Smrg pATIDRIServer->textureSize = 0; 22832b578d3Smrg 22932b578d3Smrg l = ATIMinBits((pATIDRIServer->textureSize-1) / MACH64_NR_TEX_REGIONS); 23032b578d3Smrg if (l < MACH64_LOG_TEX_GRANULARITY) l = MACH64_LOG_TEX_GRANULARITY; 23132b578d3Smrg 23232b578d3Smrg /* Round the texture size up to the nearest whole number of 23332b578d3Smrg * texture regions. Again, be greedy about this, don't round 23432b578d3Smrg * down. 23532b578d3Smrg */ 23632b578d3Smrg pATIDRIServer->logTextureGranularity = l; 23732b578d3Smrg pATIDRIServer->textureSize = 23832b578d3Smrg (pATIDRIServer->textureSize >> l) << l; 23932b578d3Smrg } 24032b578d3Smrg 24132b578d3Smrg total = fbSize - pATIDRIServer->textureSize; 24232b578d3Smrg scanlines = total / widthBytes; 24332b578d3Smrg if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY; 24432b578d3Smrg 24532b578d3Smrg /* Recalculate the texture offset and size to accomodate any 24632b578d3Smrg * rounding to a whole number of scanlines. 24732b578d3Smrg * FIXME: Is this actually needed? 24832b578d3Smrg */ 24932b578d3Smrg pATIDRIServer->textureOffset = scanlines * widthBytes; 25032b578d3Smrg pATIDRIServer->textureSize = fbSize - pATIDRIServer->textureOffset; 25132b578d3Smrg 25232b578d3Smrg /* Set a minimum usable local texture heap size. This will fit 25332b578d3Smrg * two 256x256 textures. We check this after any rounding of 25432b578d3Smrg * the texture area. 25532b578d3Smrg */ 25632b578d3Smrg if (pATIDRIServer->textureSize < 256*256 * cpp * 2) { 25732b578d3Smrg pATIDRIServer->textureOffset = 0; 25832b578d3Smrg pATIDRIServer->textureSize = 0; 25932b578d3Smrg scanlines = fbSize / widthBytes; 26032b578d3Smrg if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY; 26132b578d3Smrg } 26232b578d3Smrg 26332b578d3Smrg pATIDRIServer->depthOffset = scanlines * widthBytes - zBufferSize; 26432b578d3Smrg pATIDRIServer->depthPitch = pScreenInfo->displayWidth; 26532b578d3Smrg pATIDRIServer->depthY = pATIDRIServer->depthOffset/widthBytes; 26632b578d3Smrg pATIDRIServer->depthX = (pATIDRIServer->depthOffset - 26732b578d3Smrg (pATIDRIServer->depthY * widthBytes)) / cpp; 26832b578d3Smrg 26932b578d3Smrg pATIDRIServer->backOffset = pATIDRIServer->depthOffset - bufferSize; 27032b578d3Smrg pATIDRIServer->backPitch = pScreenInfo->displayWidth; 27132b578d3Smrg pATIDRIServer->backY = pATIDRIServer->backOffset/widthBytes; 27232b578d3Smrg pATIDRIServer->backX = (pATIDRIServer->backOffset - 27332b578d3Smrg (pATIDRIServer->backY * widthBytes)) / cpp; 27432b578d3Smrg 27532b578d3Smrg scanlines = fbSize / widthBytes; 27632b578d3Smrg if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY; 27732b578d3Smrg 27832b578d3Smrg if ( pATIDRIServer->IsPCI && pATIDRIServer->textureSize == 0 ) { 27932b578d3Smrg xf86DrvMsg(iScreen, X_WARNING, 28032b578d3Smrg "Not enough memory for local textures, disabling DRI\n"); 28132b578d3Smrg ATIDRICloseScreen(pScreen); 28232b578d3Smrg pATI->directRenderingEnabled = FALSE; 28332b578d3Smrg } else { 28432b578d3Smrg BoxRec ScreenArea; 28532b578d3Smrg 28632b578d3Smrg ScreenArea.x1 = 0; 28732b578d3Smrg ScreenArea.y1 = 0; 28832b578d3Smrg ScreenArea.x2 = pATI->displayWidth; 28932b578d3Smrg ScreenArea.y2 = scanlines; 29032b578d3Smrg 29132b578d3Smrg if (!xf86InitFBManager(pScreen, &ScreenArea)) { 29232b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 29332b578d3Smrg "Memory manager initialization to (%d,%d) (%d,%d) failed\n", 29432b578d3Smrg ScreenArea.x1, ScreenArea.y1, 29532b578d3Smrg ScreenArea.x2, ScreenArea.y2); 29632b578d3Smrg return FALSE; 29732b578d3Smrg } else { 29832b578d3Smrg int width, height; 29932b578d3Smrg 30032b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 30132b578d3Smrg "Memory manager initialized to (%d,%d) (%d,%d)\n", 30232b578d3Smrg ScreenArea.x1, ScreenArea.y1, ScreenArea.x2, ScreenArea.y2); 30332b578d3Smrg 30432b578d3Smrg if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) { 30532b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 30632b578d3Smrg "Largest offscreen area available: %d x %d\n", 30732b578d3Smrg width, height); 30832b578d3Smrg 30932b578d3Smrg /* lines in offscreen area needed for depth buffer and textures */ 31032b578d3Smrg pATI->depthTexLines = scanlines 31132b578d3Smrg - pATIDRIServer->depthOffset / widthBytes; 31232b578d3Smrg pATI->backLines = scanlines 31332b578d3Smrg - pATIDRIServer->backOffset / widthBytes 31432b578d3Smrg - pATI->depthTexLines; 31532b578d3Smrg pATI->depthTexArea = NULL; 31632b578d3Smrg pATI->backArea = NULL; 31732b578d3Smrg } else { 31832b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 31932b578d3Smrg "Unable to determine largest offscreen area available\n"); 32032b578d3Smrg return FALSE; 32132b578d3Smrg } 32232b578d3Smrg 32332b578d3Smrg } 32432b578d3Smrg 32532b578d3Smrg xf86DrvMsg(iScreen, X_INFO, "Will use %d kB of offscreen memory for XAA\n", 32632b578d3Smrg (offscreenBytes - pATIDRIServer->textureSize)/1024); 32732b578d3Smrg 32832b578d3Smrg xf86DrvMsg(iScreen, X_INFO, "Will use back buffer at offset 0x%x\n", 32932b578d3Smrg pATIDRIServer->backOffset); 33032b578d3Smrg 33132b578d3Smrg xf86DrvMsg(iScreen, X_INFO, "Will use depth buffer at offset 0x%x\n", 33232b578d3Smrg pATIDRIServer->depthOffset); 33332b578d3Smrg 33432b578d3Smrg if (pATIDRIServer->textureSize > 0) { 33532b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 33632b578d3Smrg "Will use %d kB for local textures at offset 0x%x\n", 33732b578d3Smrg pATIDRIServer->textureSize/1024, 33832b578d3Smrg pATIDRIServer->textureOffset); 33932b578d3Smrg } 34032b578d3Smrg } 34132b578d3Smrg 34232b578d3Smrg return TRUE; 34332b578d3Smrg} 34432b578d3Smrg#endif /* XF86DRI_DEVEL */ 34532b578d3Smrg#endif /* USE_XAA */ 34632b578d3Smrg 34732b578d3Smrg/* 34832b578d3Smrg * ATIScreenInit -- 34932b578d3Smrg * 35032b578d3Smrg * This function is called by DIX to initialise the screen. 35132b578d3Smrg */ 35232b578d3SmrgBool 35332b578d3SmrgATIScreenInit 35432b578d3Smrg( 35532b578d3Smrg int iScreen, 35632b578d3Smrg ScreenPtr pScreen, 35732b578d3Smrg int argc, 35832b578d3Smrg char **argv 35932b578d3Smrg) 36032b578d3Smrg{ 36132b578d3Smrg ScrnInfoPtr pScreenInfo = xf86Screens[iScreen]; 36232b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 36332b578d3Smrg pointer pFB; 36432b578d3Smrg int VisualMask; 36532b578d3Smrg 36632b578d3Smrg /* Set video hardware state */ 36732b578d3Smrg if (!ATIEnterGraphics(pScreen, pScreenInfo, pATI)) 36832b578d3Smrg return FALSE; 36932b578d3Smrg 37032b578d3Smrg /* Re-initialise mi's visual list */ 37132b578d3Smrg miClearVisualTypes(); 37232b578d3Smrg 37332b578d3Smrg if ((pATI->depth > 8) && (pATI->DAC == ATI_DAC_INTERNAL)) 37432b578d3Smrg VisualMask = TrueColorMask; 37532b578d3Smrg else 37632b578d3Smrg VisualMask = miGetDefaultVisualMask(pATI->depth); 37732b578d3Smrg 37832b578d3Smrg if (!miSetVisualTypes(pATI->depth, VisualMask, pATI->rgbBits, 37932b578d3Smrg pScreenInfo->defaultVisual)) 38032b578d3Smrg return FALSE; 38132b578d3Smrg 38232b578d3Smrg if (!miSetPixmapDepths()) 38332b578d3Smrg return FALSE; 38432b578d3Smrg 38532b578d3Smrg pFB = pATI->pMemory; 38632b578d3Smrg pATI->FBPitch = PixmapBytePad(pATI->displayWidth, pATI->depth); 38732b578d3Smrg if (pATI->OptionShadowFB) 38832b578d3Smrg { 38932b578d3Smrg pATI->FBBytesPerPixel = pATI->bitsPerPixel >> 3; 39032b578d3Smrg pATI->FBPitch = PixmapBytePad(pATI->displayWidth, pATI->depth); 3911b12faf6Smrg if ((pATI->pShadow = malloc(pATI->FBPitch * pScreenInfo->virtualY))) 39232b578d3Smrg { 39332b578d3Smrg pFB = pATI->pShadow; 39432b578d3Smrg } 39532b578d3Smrg else 39632b578d3Smrg { 39732b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 39832b578d3Smrg "Insufficient virtual memory for shadow frame buffer.\n"); 39932b578d3Smrg pATI->OptionShadowFB = FALSE; 40032b578d3Smrg } 40132b578d3Smrg } 40232b578d3Smrg 40332b578d3Smrg#ifdef XF86DRI_DEVEL 40432b578d3Smrg 40532b578d3Smrg /* Setup DRI after visuals have been established, but before 40632b578d3Smrg * fbScreenInit is called. fbScreenInit will eventually call the 40732b578d3Smrg * driver's InitGLXVisuals call back. 40832b578d3Smrg */ 40932b578d3Smrg 41032b578d3Smrg /* According to atiregs.h, GTPro (3D Rage Pro) is the first chip type with 41132b578d3Smrg * 3D triangle setup (the VERTEX_* registers) 41232b578d3Smrg */ 41332b578d3Smrg if (pATI->Chip < ATI_CHIP_264GTPRO) { 41432b578d3Smrg xf86DrvMsg(iScreen, X_WARNING, 41532b578d3Smrg "Direct rendering is not supported for ATI chips earlier than " 41632b578d3Smrg "the ATI 3D Rage Pro.\n"); 41732b578d3Smrg pATI->directRenderingEnabled = FALSE; 41832b578d3Smrg } else { 41932b578d3Smrg /* FIXME: When we move to dynamic allocation of back and depth 42032b578d3Smrg * buffers, we will want to revisit the following check for 3 42132b578d3Smrg * times the virtual size (or 2.5 times for 24-bit depth) of the screen below. 42232b578d3Smrg */ 42332b578d3Smrg int cpp = pATI->bitsPerPixel >> 3; 42432b578d3Smrg int maxY = pScreenInfo->videoRam * 1024 / (pATI->displayWidth * cpp); 42532b578d3Smrg int requiredY; 42632b578d3Smrg 42732b578d3Smrg requiredY = pScreenInfo->virtualY * 2 /* front, back buffers */ 42832b578d3Smrg + (pScreenInfo->virtualY * 2 / cpp); /* depth buffer (always 16-bit) */ 42932b578d3Smrg 43032b578d3Smrg if (!pATI->OptionAccel) { 43132b578d3Smrg xf86DrvMsg(iScreen, X_WARNING, 43232b578d3Smrg "Acceleration disabled, not initializing the DRI\n"); 43332b578d3Smrg pATI->directRenderingEnabled = FALSE; 43432b578d3Smrg } else if ( maxY > requiredY ) { 43532b578d3Smrg pATI->directRenderingEnabled = ATIDRIScreenInit(pScreen); 43632b578d3Smrg } else { 43732b578d3Smrg xf86DrvMsg(iScreen, X_WARNING, 43832b578d3Smrg "DRI static buffer allocation failed -- " 43932b578d3Smrg "need at least %d kB video memory\n", 44032b578d3Smrg (pScreenInfo->displayWidth * requiredY * cpp ) / 1024); 44132b578d3Smrg pATI->directRenderingEnabled = FALSE; 44232b578d3Smrg } 44332b578d3Smrg } 44432b578d3Smrg 44532b578d3Smrg#endif /* XF86DRI_DEVEL */ 44632b578d3Smrg 44732b578d3Smrg /* Initialise framebuffer layer */ 44832b578d3Smrg switch (pATI->bitsPerPixel) 44932b578d3Smrg { 45032b578d3Smrg case 8: 45132b578d3Smrg case 16: 45232b578d3Smrg case 24: 45332b578d3Smrg case 32: 45432b578d3Smrg pATI->Closeable = fbScreenInit(pScreen, pFB, 45532b578d3Smrg pScreenInfo->virtualX, pScreenInfo->virtualY, 45632b578d3Smrg pScreenInfo->xDpi, pScreenInfo->yDpi, pATI->displayWidth, 45732b578d3Smrg pATI->bitsPerPixel); 45832b578d3Smrg break; 45932b578d3Smrg 46032b578d3Smrg default: 46132b578d3Smrg return FALSE; 46232b578d3Smrg } 46332b578d3Smrg 46432b578d3Smrg if (!pATI->Closeable) 46532b578d3Smrg return FALSE; 46632b578d3Smrg 46732b578d3Smrg /* Fixup RGB ordering */ 46832b578d3Smrg if (pATI->depth > 8) 46932b578d3Smrg { 47032b578d3Smrg VisualPtr pVisual = pScreen->visuals + pScreen->numVisuals; 47132b578d3Smrg 47232b578d3Smrg while (--pVisual >= pScreen->visuals) 47332b578d3Smrg { 47432b578d3Smrg if ((pVisual->class | DynamicClass) != DirectColor) 47532b578d3Smrg continue; 47632b578d3Smrg 47732b578d3Smrg pVisual->offsetRed = pScreenInfo->offset.red; 47832b578d3Smrg pVisual->offsetGreen = pScreenInfo->offset.green; 47932b578d3Smrg pVisual->offsetBlue = pScreenInfo->offset.blue; 48032b578d3Smrg 48132b578d3Smrg pVisual->redMask = pScreenInfo->mask.red; 48232b578d3Smrg pVisual->greenMask = pScreenInfo->mask.green; 48332b578d3Smrg pVisual->blueMask = pScreenInfo->mask.blue; 48432b578d3Smrg } 48532b578d3Smrg } 48632b578d3Smrg 48732b578d3Smrg /* If applicable, initialise RENDER extension */ 48832b578d3Smrg { 48932b578d3Smrg if (pATI->OptionShadowFB) 49032b578d3Smrg { 49132b578d3Smrg if (serverGeneration == 1) 49232b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 49332b578d3Smrg "RENDER extension not supported with a shadowed" 49432b578d3Smrg " framebuffer.\n"); 49532b578d3Smrg } 49632b578d3Smrg else if (!fbPictureInit(pScreen, NULL, 0) && 49732b578d3Smrg (serverGeneration == 1)) 49832b578d3Smrg { 49932b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 50032b578d3Smrg "RENDER extension initialisation failed.\n"); 50132b578d3Smrg } 50232b578d3Smrg } 50332b578d3Smrg 50432b578d3Smrg xf86SetBlackWhitePixels(pScreen); 50532b578d3Smrg 50632b578d3Smrg#ifdef USE_XAA 50732b578d3Smrg 50832b578d3Smrg if (!pATI->useEXA) { 50932b578d3Smrg 51032b578d3Smrg /* Memory manager setup */ 51132b578d3Smrg 51232b578d3Smrg#ifdef XF86DRI_DEVEL 51332b578d3Smrg if (pATI->directRenderingEnabled) 51432b578d3Smrg { 51532b578d3Smrg if (!ATIMach64SetupMemXAA(iScreen, pScreen)) 51632b578d3Smrg return FALSE; 51732b578d3Smrg } 51832b578d3Smrg else 51932b578d3Smrg#endif /* XF86DRI_DEVEL */ 52032b578d3Smrg { 52132b578d3Smrg if (!ATIMach64SetupMemXAA_NoDRI(iScreen, pScreen)) 52232b578d3Smrg return FALSE; 52332b578d3Smrg } 52432b578d3Smrg 52532b578d3Smrg /* Setup acceleration */ 52632b578d3Smrg 52732b578d3Smrg if (pATI->OptionAccel && !ATIMach64AccelInit(pScreen)) 52832b578d3Smrg return FALSE; 52932b578d3Smrg 53032b578d3Smrg } 53132b578d3Smrg 53232b578d3Smrg#endif /* USE_XAA */ 53332b578d3Smrg 53432b578d3Smrg#ifdef USE_EXA 53532b578d3Smrg 53632b578d3Smrg if (pATI->useEXA) { 53732b578d3Smrg /* EXA setups both memory manager and acceleration here */ 53832b578d3Smrg 53932b578d3Smrg if (pATI->OptionAccel && !ATIMach64ExaInit(pScreen)) 54032b578d3Smrg return FALSE; 54132b578d3Smrg } 54232b578d3Smrg 54332b578d3Smrg#endif /* USE_EXA */ 54432b578d3Smrg 54532b578d3Smrg#ifndef AVOID_DGA 54632b578d3Smrg 54732b578d3Smrg /* Initialise DGA support */ 54832b578d3Smrg (void)ATIDGAInit(pScreen, pScreenInfo, pATI); 54932b578d3Smrg 55032b578d3Smrg#endif /* AVOID_DGA */ 55132b578d3Smrg 55232b578d3Smrg /* Initialise backing store */ 55332b578d3Smrg miInitializeBackingStore(pScreen); 55432b578d3Smrg xf86SetBackingStore(pScreen); 55532b578d3Smrg 55632b578d3Smrg /* Initialise cursor */ 55732b578d3Smrg if (!ATIMach64CursorInit(pScreen)) 55832b578d3Smrg return FALSE; 55932b578d3Smrg 56032b578d3Smrg /* Create default colourmap */ 56132b578d3Smrg if (!miCreateDefColormap(pScreen)) 56232b578d3Smrg return FALSE; 56332b578d3Smrg 56432b578d3Smrg if (!xf86HandleColormaps(pScreen, 256, pATI->rgbBits, ATILoadPalette, NULL, 56532b578d3Smrg CMAP_PALETTED_TRUECOLOR | 56632b578d3Smrg CMAP_LOAD_EVEN_IF_OFFSCREEN)) 56732b578d3Smrg return FALSE; 56832b578d3Smrg 56932b578d3Smrg /* Initialise shadow framebuffer */ 57032b578d3Smrg if (pATI->OptionShadowFB && 57132b578d3Smrg !ShadowFBInit(pScreen, ATIRefreshArea)) 57232b578d3Smrg return FALSE; 57332b578d3Smrg 57432b578d3Smrg /* Initialise DPMS support */ 57532b578d3Smrg (void)xf86DPMSInit(pScreen, ATISetDPMSMode, 0); 57632b578d3Smrg 57732b578d3Smrg /* Initialise XVideo support */ 57832b578d3Smrg (void)ATIInitializeXVideo(pScreen, pScreenInfo, pATI); 57932b578d3Smrg 58032b578d3Smrg /* Set pScreen->SaveScreen and wrap CloseScreen vector */ 58132b578d3Smrg pScreen->SaveScreen = ATISaveScreen; 58232b578d3Smrg pATI->CloseScreen = pScreen->CloseScreen; 58332b578d3Smrg pScreen->CloseScreen = ATICloseScreen; 58432b578d3Smrg 58532b578d3Smrg if (serverGeneration == 1) 58632b578d3Smrg xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options); 58732b578d3Smrg 58832b578d3Smrg#ifdef TV_OUT 58932b578d3Smrg /* Fix-up TV out after ImpacTV probe */ 59032b578d3Smrg if (pATI->OptionTvOut && pATI->Chip < ATI_CHIP_264GTPRO) 59132b578d3Smrg ATISwitchMode(0, pScreenInfo->currentMode, 0); 59232b578d3Smrg#endif /* TV_OUT */ 59332b578d3Smrg 59432b578d3Smrg#ifdef XF86DRI_DEVEL 59532b578d3Smrg 59632b578d3Smrg /* DRI finalization */ 59732b578d3Smrg if (pATI->directRenderingEnabled) { 59832b578d3Smrg /* Now that mi, fb, drm and others have done their thing, 59932b578d3Smrg * complete the DRI setup. 60032b578d3Smrg */ 60132b578d3Smrg pATI->directRenderingEnabled = ATIDRIFinishScreenInit(pScreen); 60232b578d3Smrg } 60332b578d3Smrg if (pATI->directRenderingEnabled) { 60432b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 60532b578d3Smrg "Direct rendering enabled\n"); 60632b578d3Smrg } else { 60732b578d3Smrg /* FIXME: Release unused offscreen mem here? */ 60832b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, 60932b578d3Smrg "Direct rendering disabled\n"); 61032b578d3Smrg } 61132b578d3Smrg 61232b578d3Smrg#endif /* XF86DRI_DEVEL */ 61332b578d3Smrg 61432b578d3Smrg return TRUE; 61532b578d3Smrg} 61632b578d3Smrg 61732b578d3Smrg/* 61832b578d3Smrg * ATICloseScreen -- 61932b578d3Smrg * 62032b578d3Smrg * This function is called by DIX to close the screen. 62132b578d3Smrg */ 62232b578d3SmrgBool 62332b578d3SmrgATICloseScreen 62432b578d3Smrg( 62532b578d3Smrg int iScreen, 62632b578d3Smrg ScreenPtr pScreen 62732b578d3Smrg) 62832b578d3Smrg{ 62932b578d3Smrg ScrnInfoPtr pScreenInfo = xf86Screens[iScreen]; 63032b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 63132b578d3Smrg 63232b578d3Smrg#ifdef XF86DRI_DEVEL 63332b578d3Smrg 63432b578d3Smrg /* Disable direct rendering */ 63532b578d3Smrg if (pATI->directRenderingEnabled) 63632b578d3Smrg { 63732b578d3Smrg ATIDRICloseScreen(pScreen); 63832b578d3Smrg pATI->directRenderingEnabled = FALSE; 63932b578d3Smrg } 64032b578d3Smrg 64132b578d3Smrg#endif /* XF86DRI_DEVEL */ 64232b578d3Smrg 64332b578d3Smrg ATICloseXVideo(pScreen, pScreenInfo, pATI); 64432b578d3Smrg 64532b578d3Smrg#ifdef USE_EXA 64632b578d3Smrg if (pATI->pExa) 64732b578d3Smrg { 64832b578d3Smrg exaDriverFini(pScreen); 6491b12faf6Smrg free(pATI->pExa); 65032b578d3Smrg pATI->pExa = NULL; 65132b578d3Smrg } 65232b578d3Smrg#endif 65332b578d3Smrg#ifdef USE_XAA 65432b578d3Smrg if (pATI->pXAAInfo) 65532b578d3Smrg { 65632b578d3Smrg XAADestroyInfoRec(pATI->pXAAInfo); 65732b578d3Smrg pATI->pXAAInfo = NULL; 65832b578d3Smrg } 65932b578d3Smrg#endif 66032b578d3Smrg if (pATI->pCursorInfo) 66132b578d3Smrg { 66232b578d3Smrg xf86DestroyCursorInfoRec(pATI->pCursorInfo); 66332b578d3Smrg pATI->pCursorInfo = NULL; 66432b578d3Smrg } 66532b578d3Smrg 6661b12faf6Smrg pATI->Closeable = FALSE; 66732b578d3Smrg ATILeaveGraphics(pScreenInfo, pATI); 66832b578d3Smrg 66932b578d3Smrg#ifdef USE_XAA 67032b578d3Smrg if (!pATI->useEXA) 67132b578d3Smrg { 6721b12faf6Smrg free(pATI->ExpansionBitmapScanlinePtr[1]); 67332b578d3Smrg pATI->ExpansionBitmapScanlinePtr[0] = NULL; 67432b578d3Smrg pATI->ExpansionBitmapScanlinePtr[1] = NULL; 67532b578d3Smrg } 67632b578d3Smrg#endif 67732b578d3Smrg 6781b12faf6Smrg free(pATI->pShadow); 67932b578d3Smrg pATI->pShadow = NULL; 68032b578d3Smrg pScreenInfo->pScreen = NULL; 68132b578d3Smrg 6821b12faf6Smrg pScreen->CloseScreen = pATI->CloseScreen; 6831b12faf6Smrg return (*pScreen->CloseScreen)(iScreen, pScreen); 68432b578d3Smrg} 685