1ab47cfaaSmrg/* 2ab47cfaaSmrg * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 3ab47cfaaSmrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 4ab47cfaaSmrg * 5ab47cfaaSmrg * Permission is hereby granted, free of charge, to any person obtaining a 6ab47cfaaSmrg * copy of this software and associated documentation files (the "Software"), 7ab47cfaaSmrg * to deal in the Software without restriction, including without limitation 8ab47cfaaSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 9ab47cfaaSmrg * and/or sell copies of the Software, and to permit persons to whom the 10ab47cfaaSmrg * Software is furnished to do so, subject to the following conditions: 11ab47cfaaSmrg * 12ab47cfaaSmrg * The above copyright notice and this permission notice (including the 13ab47cfaaSmrg * next paragraph) shall be included in all copies or substantial portions 14ab47cfaaSmrg * of the Software. 15ab47cfaaSmrg * 16ab47cfaaSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17ab47cfaaSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18ab47cfaaSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19ab47cfaaSmrg * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20ab47cfaaSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21ab47cfaaSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22ab47cfaaSmrg * DEALINGS IN THE SOFTWARE. 23ab47cfaaSmrg */ 24ab47cfaaSmrg 25ab47cfaaSmrg#ifdef HAVE_CONFIG_H 26ab47cfaaSmrg#include "config.h" 27ab47cfaaSmrg#endif 28ab47cfaaSmrg 295788ca14Smrg#ifdef SAVAGEDRI 30ab47cfaaSmrg 31ab47cfaaSmrg#include "xf86.h" 32ab47cfaaSmrg#include "xf86_OSproc.h" 33ab47cfaaSmrg 345788ca14Smrg#ifdef HAVE_XAA_H 35ab47cfaaSmrg#include "xaalocal.h" 36ab47cfaaSmrg#include "xaarop.h" 375788ca14Smrg#endif 38ab47cfaaSmrg 39ab47cfaaSmrg#include "xf86Pci.h" 40ab47cfaaSmrg#include "xf86fbman.h" 41ab47cfaaSmrg 42ab47cfaaSmrg#include "miline.h" 43ab47cfaaSmrg 44ab47cfaaSmrg 45ab47cfaaSmrg/*#include "savage_vbe.h"*/ 46ab47cfaaSmrg#include "savage_regs.h" 47ab47cfaaSmrg#include "savage_driver.h" 48ab47cfaaSmrg#include "savage_bci.h" 49ab47cfaaSmrg#include "savage_streams.h" 50ab47cfaaSmrg#include "savage_common.h" 51ab47cfaaSmrg 52ab47cfaaSmrg#define _XF86DRI_SERVER_ 53ab47cfaaSmrg#include "sarea.h" 54ab47cfaaSmrg#include "savage_dri.h" 55ab47cfaaSmrg#include "savage_sarea.h" 56ab47cfaaSmrg 57ab47cfaaSmrgstatic char SAVAGEKernelDriverName[] = "savage"; 58ab47cfaaSmrgstatic char SAVAGEClientDriverName[] = "savage"; 59ab47cfaaSmrg 60ab47cfaaSmrgstatic Bool SAVAGEDRIOpenFullScreen(ScreenPtr pScreen); 61ab47cfaaSmrgstatic Bool SAVAGEDRICloseFullScreen(ScreenPtr pScreen); 62ab47cfaaSmrg/* DRI buffer management 63ab47cfaaSmrg */ 64ab47cfaaSmrgvoid SAVAGEDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, 65ab47cfaaSmrg CARD32 index ); 66ab47cfaaSmrgvoid SAVAGEDRIMoveBuffers( WindowPtr pParent, DDXPointRec ptOldOrg, 67ab47cfaaSmrg RegionPtr prgnSrc, CARD32 index ); 68ab47cfaaSmrg 69ab47cfaaSmrg/* almost the same besides set src/desc to */ 70ab47cfaaSmrg/* Primary Bitmap Description */ 71ab47cfaaSmrg 72ab47cfaaSmrgstatic void 73ab47cfaaSmrgSAVAGEDRISetupForScreenToScreenCopy( 74ab47cfaaSmrg ScrnInfoPtr pScrn, int xdir, int ydir, 75ab47cfaaSmrg int rop, unsigned planemask, int transparency_color); 76ab47cfaaSmrg 77ab47cfaaSmrg 78ab47cfaaSmrgstatic void 79ab47cfaaSmrgSAVAGEDRISubsequentScreenToScreenCopy( 80ab47cfaaSmrg ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, 81ab47cfaaSmrg int w, int h); 82ab47cfaaSmrg 83ab47cfaaSmrgstatic Bool SAVAGECreateContext( ScreenPtr pScreen, VisualPtr visual, 84ab47cfaaSmrg drm_context_t hwContext, void *pVisualConfigPriv, 85ab47cfaaSmrg DRIContextType contextStore ) 86ab47cfaaSmrg{ 875788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 88ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 89ab47cfaaSmrg 90ab47cfaaSmrg if(psav->xvmcContext) 91ab47cfaaSmrg return FALSE; 92ab47cfaaSmrg else 93ab47cfaaSmrg { 94ab47cfaaSmrg psav->DRIrunning++; 95ab47cfaaSmrg } 96ab47cfaaSmrg 97ab47cfaaSmrg return TRUE; 98ab47cfaaSmrg} 99ab47cfaaSmrg 100ab47cfaaSmrgstatic void SAVAGEDestroyContext( ScreenPtr pScreen, drm_context_t hwContext, 101ab47cfaaSmrg DRIContextType contextStore ) 102ab47cfaaSmrg{ 1035788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 104ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 105ab47cfaaSmrg 106ab47cfaaSmrg psav->DRIrunning--; 107ab47cfaaSmrg} 108ab47cfaaSmrg 1095788ca14Smrgstatic void SAVAGEWakeupHandler(WAKEUPHANDLER_ARGS_DECL) 110ab47cfaaSmrg{ 1115788ca14Smrg SCREEN_PTR(arg); 1125788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 113ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 114ab47cfaaSmrg 115ab47cfaaSmrg psav->pDRIInfo->wrap.WakeupHandler = psav->coreWakeupHandler; 1165788ca14Smrg (*psav->pDRIInfo->wrap.WakeupHandler) (WAKEUPHANDLER_ARGS); 117ab47cfaaSmrg psav->pDRIInfo->wrap.WakeupHandler = SAVAGEWakeupHandler; 118ab47cfaaSmrg psav->LockHeld = 1; 119ab47cfaaSmrg if (psav->ShadowStatus) { 120ab47cfaaSmrg /* fetch the global shadow counter */ 121ab47cfaaSmrg#if 0 122ab47cfaaSmrg if (psav->ShadowCounter != (psav->ShadowVirtual[1023] & 0xffff)) 123ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, 124ab47cfaaSmrg "[dri] WakeupHandler: shadowCounter adjusted from %04x to %04lx\n", 125ab47cfaaSmrg psav->ShadowCounter, psav->ShadowVirtual[1023] & 0xffff); 126ab47cfaaSmrg#endif 127ab47cfaaSmrg psav->ShadowCounter = psav->ShadowVirtual[1023] & 0xffff; 128ab47cfaaSmrg } 129ab47cfaaSmrg if (psav->useEXA) 130ab47cfaaSmrg exaMarkSync(pScreen); 1315788ca14Smrg#ifdef HAVE_XAA_H 132ab47cfaaSmrg else 133ab47cfaaSmrg psav->AccelInfoRec->NeedToSync = TRUE; 1345788ca14Smrg#endif 135ab47cfaaSmrg /* FK: this flag doesn't seem to be used. */ 136ab47cfaaSmrg} 137ab47cfaaSmrg 1385788ca14Smrgstatic void SAVAGEBlockHandler(BLOCKHANDLER_ARGS_DECL) 139ab47cfaaSmrg{ 1405788ca14Smrg SCREEN_PTR(arg); 1415788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 142ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 143ab47cfaaSmrg 144ab47cfaaSmrg if (psav->ShadowStatus) { 145ab47cfaaSmrg /* update the global shadow counter */ 146ab47cfaaSmrg CARD32 globalShadowCounter = psav->ShadowVirtual[1023]; 147ab47cfaaSmrg globalShadowCounter = (globalShadowCounter & 0xffff0000) | 148ab47cfaaSmrg ((CARD32)psav->ShadowCounter & 0x0000ffff); 149ab47cfaaSmrg 150ab47cfaaSmrg#if 0 151ab47cfaaSmrg if (globalShadowCounter != psav->ShadowVirtual[1023]) 152ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, 153ab47cfaaSmrg "[dri] BlockHandler: shadowCounter adjusted from %08lx to %08x\n", 154ab47cfaaSmrg psav->ShadowVirtual[1023], globalShadowCounter); 155ab47cfaaSmrg#endif 156ab47cfaaSmrg psav->ShadowVirtual[1023] = globalShadowCounter; 157ab47cfaaSmrg } 158ab47cfaaSmrg psav->LockHeld = 0; 159ab47cfaaSmrg psav->pDRIInfo->wrap.BlockHandler = psav->coreBlockHandler; 1605788ca14Smrg (*psav->pDRIInfo->wrap.BlockHandler) (BLOCKHANDLER_ARGS); 161ab47cfaaSmrg psav->pDRIInfo->wrap.BlockHandler = SAVAGEBlockHandler; 162ab47cfaaSmrg} 163ab47cfaaSmrg 1645788ca14Smrgstatic void SAVAGESelectBuffer( ScrnInfoPtr pScrn, int which ) 165ab47cfaaSmrg{ 166ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 167ab47cfaaSmrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 168ab47cfaaSmrg 169ab47cfaaSmrg psav->WaitIdleEmpty(psav); 170ab47cfaaSmrg 171ab47cfaaSmrg OUTREG(0x48C18,INREG(0x48C18)&(~0x00000008)); 172ab47cfaaSmrg 173ab47cfaaSmrg switch ( which ) { 174ab47cfaaSmrg case SAVAGE_BACK: 175ab47cfaaSmrg OUTREG( 0x8170, pSAVAGEDRIServer->backOffset ); 176ab47cfaaSmrg OUTREG( 0x8174, pSAVAGEDRIServer->backBitmapDesc ); 177ab47cfaaSmrg break; 178ab47cfaaSmrg case SAVAGE_DEPTH: 179ab47cfaaSmrg OUTREG( 0x8170, pSAVAGEDRIServer->depthOffset ); 180ab47cfaaSmrg OUTREG( 0x8174, pSAVAGEDRIServer->depthBitmapDesc ); 181ab47cfaaSmrg break; 182ab47cfaaSmrg default: 183ab47cfaaSmrg case SAVAGE_FRONT: 184ab47cfaaSmrg OUTREG( 0x8170, pSAVAGEDRIServer->frontOffset ); 185ab47cfaaSmrg OUTREG( 0x8174, pSAVAGEDRIServer->frontBitmapDesc ); 186ab47cfaaSmrg break; 187ab47cfaaSmrg } 188ab47cfaaSmrg OUTREG(0x48C18,INREG(0x48C18)|(0x00000008)); 189ab47cfaaSmrg psav->WaitIdleEmpty(psav); 190ab47cfaaSmrg 191ab47cfaaSmrg} 192ab47cfaaSmrg 193ab47cfaaSmrg 194ab47cfaaSmrgstatic unsigned int mylog2( unsigned int n ) 195ab47cfaaSmrg{ 196ab47cfaaSmrg unsigned int log2 = 1; 197ab47cfaaSmrg 198ab47cfaaSmrg n--; 199ab47cfaaSmrg while ( n > 1 ) n >>= 1, log2++; 200ab47cfaaSmrg 201ab47cfaaSmrg return log2; 202ab47cfaaSmrg} 203ab47cfaaSmrg 2045788ca14Smrgstatic Bool SAVAGESetAgpMode(SavagePtr psav, ScreenPtr pScreen) 205ab47cfaaSmrg{ 2065788ca14Smrg unsigned long mode = drmAgpGetMode( psav->drmFD ); /* Default mode */ 2075788ca14Smrg unsigned int vendor = drmAgpVendorId( psav->drmFD ); 2085788ca14Smrg unsigned int device = drmAgpDeviceId( psav->drmFD ); 209ab47cfaaSmrg 210ab47cfaaSmrg mode &= ~SAVAGE_AGP_MODE_MASK; 211ab47cfaaSmrg 212ab47cfaaSmrg switch ( psav->agpMode ) { 213ab47cfaaSmrg case 4: 214ab47cfaaSmrg mode |= SAVAGE_AGP_4X_MODE; 215ab47cfaaSmrg case 2: 216ab47cfaaSmrg mode |= SAVAGE_AGP_2X_MODE; 217ab47cfaaSmrg case 1: 218ab47cfaaSmrg default: 219ab47cfaaSmrg mode |= SAVAGE_AGP_1X_MODE; 220ab47cfaaSmrg } 221ab47cfaaSmrg 222ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 223ab47cfaaSmrg "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", 224ab47cfaaSmrg mode, vendor, device, 2258697ee19Smrg VENDOR_ID(psav->PciInfo), 2268697ee19Smrg DEVICE_ID(psav->PciInfo)); 227ab47cfaaSmrg 228ab47cfaaSmrg if ( drmAgpEnable( psav->drmFD, mode ) < 0 ) { 229ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" ); 230ab47cfaaSmrg drmAgpRelease( psav->drmFD ); 2315788ca14Smrg return FALSE; 2325788ca14Smrg } 2335788ca14Smrg 2345788ca14Smrg return TRUE; 2355788ca14Smrg} 2365788ca14Smrg 2375788ca14Smrgstatic Bool SAVAGEDRIAgpInit(ScreenPtr pScreen) 2385788ca14Smrg{ 2395788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2405788ca14Smrg SavagePtr psav = SAVPTR(pScrn); 2415788ca14Smrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 2425788ca14Smrg unsigned int offset; 2435788ca14Smrg int ret; 2445788ca14Smrg 2455788ca14Smrg if (psav->agpSize < 2) 2465788ca14Smrg psav->agpSize = 2; /* at least 2MB for DMA buffers */ 2475788ca14Smrg 2485788ca14Smrg pSAVAGEDRIServer->agp.size = psav->agpSize * 1024 * 1024; 2495788ca14Smrg pSAVAGEDRIServer->agp.offset = pSAVAGEDRIServer->agp.size; /* ? */ 2505788ca14Smrg 2515788ca14Smrg if ( drmAgpAcquire( psav->drmFD ) < 0 ) { 2525788ca14Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not available\n" ); 2535788ca14Smrg return FALSE; 2545788ca14Smrg } 2555788ca14Smrg 2565788ca14Smrg if (!SAVAGESetAgpMode(psav, pScreen)) { 257ab47cfaaSmrg pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */ 258ab47cfaaSmrg return FALSE; 259ab47cfaaSmrg } 260ab47cfaaSmrg 261ab47cfaaSmrg ret = drmAgpAlloc( psav->drmFD, pSAVAGEDRIServer->agp.size, 262ab47cfaaSmrg 0, NULL, &pSAVAGEDRIServer->agp.handle ); 263ab47cfaaSmrg if ( ret < 0 ) { 264ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret ); 265ab47cfaaSmrg drmAgpRelease( psav->drmFD ); 266ab47cfaaSmrg pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */ 267ab47cfaaSmrg return FALSE; 268ab47cfaaSmrg } 269ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 270ab47cfaaSmrg "[agp] %d kB allocated with handle 0x%08lx\n", 2715788ca14Smrg pSAVAGEDRIServer->agp.size/1024, 2725788ca14Smrg (unsigned long)pSAVAGEDRIServer->agp.handle ); 273ab47cfaaSmrg 274ab47cfaaSmrg if ( drmAgpBind( psav->drmFD, pSAVAGEDRIServer->agp.handle, 0 ) < 0 ) { 275ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind memory\n" ); 276ab47cfaaSmrg drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle ); 277ab47cfaaSmrg drmAgpRelease( psav->drmFD ); 278ab47cfaaSmrg pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */ 279ab47cfaaSmrg return FALSE; 280ab47cfaaSmrg } 281ab47cfaaSmrg 282ab47cfaaSmrg /* AGP initialization failures above are not fatal, we can fall 283ab47cfaaSmrg * back to PCI mode. Failures while adding AGP mappings below are 284ab47cfaaSmrg * fatal though. DRI must be disabled in that case. 285ab47cfaaSmrg * pSAVAGEDRIServer->agp.handle can be used to distinguish these 286ab47cfaaSmrg * two cases. 287ab47cfaaSmrg */ 288ab47cfaaSmrg 289ab47cfaaSmrg /* AGP memory layout 290ab47cfaaSmrg */ 291ab47cfaaSmrg offset = 0; 292ab47cfaaSmrg 293ab47cfaaSmrg if ( psav->AgpDMA ) { 294ab47cfaaSmrg if ( psav->CommandDMA ) { 295ab47cfaaSmrg pSAVAGEDRIServer->cmdDma.offset = offset; 296ab47cfaaSmrg pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE; 297ab47cfaaSmrg offset += pSAVAGEDRIServer->cmdDma.size; 298ab47cfaaSmrg } else if ( psav->VertexDMA ) { 299ab47cfaaSmrg pSAVAGEDRIServer->buffers.offset = 0; 300ab47cfaaSmrg pSAVAGEDRIServer->buffers.size = SAVAGE_NUM_BUFFERS * SAVAGE_BUFFER_SIZE; 301ab47cfaaSmrg offset += pSAVAGEDRIServer->buffers.size; 302ab47cfaaSmrg } 303ab47cfaaSmrg } 304ab47cfaaSmrg 3051c79cd07Smrg if (psav->AGPforXv) { 3061c79cd07Smrg pSAVAGEDRIServer->agpXVideo.offset = offset; 3071c79cd07Smrg pSAVAGEDRIServer->agpXVideo.size = 2 * 1024 * 1024; /* Max XV image is 1024x1024x16bpp */ 3081c79cd07Smrg offset += pSAVAGEDRIServer->agpXVideo.size; 3091c79cd07Smrg } else { 3101c79cd07Smrg pSAVAGEDRIServer->agpXVideo.offset = 0; 3111c79cd07Smrg pSAVAGEDRIServer->agpXVideo.size = 0; 3121c79cd07Smrg } 3131c79cd07Smrg 314ab47cfaaSmrg pSAVAGEDRIServer->agpTextures.offset = offset; 315ab47cfaaSmrg pSAVAGEDRIServer->agpTextures.size = (pSAVAGEDRIServer->agp.size - offset); 316ab47cfaaSmrg 317ab47cfaaSmrg /* DMA buffers 318ab47cfaaSmrg */ 319ab47cfaaSmrg if ( psav->AgpDMA ) { 320ab47cfaaSmrg if ( psav->CommandDMA ) { 321ab47cfaaSmrg if ( drmAddMap( psav->drmFD, 322ab47cfaaSmrg pSAVAGEDRIServer->cmdDma.offset, 323ab47cfaaSmrg pSAVAGEDRIServer->cmdDma.size, 324ab47cfaaSmrg DRM_AGP, DRM_RESTRICTED | DRM_KERNEL, 325ab47cfaaSmrg &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) { 326ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 327ab47cfaaSmrg "[agp] Could not add command DMA mapping\n" ); 328ab47cfaaSmrg return FALSE; 329ab47cfaaSmrg } 330ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 331ab47cfaaSmrg "[agp] command DMA handle = 0x%08lx\n", 3325788ca14Smrg (unsigned long)pSAVAGEDRIServer->cmdDma.handle ); 333ab47cfaaSmrg /* not needed in the server 334ab47cfaaSmrg if ( drmMap( psav->drmFD, 335ab47cfaaSmrg pSAVAGEDRIServer->cmdDma.handle, 336ab47cfaaSmrg pSAVAGEDRIServer->cmdDma.size, 337ab47cfaaSmrg &pSAVAGEDRIServer->cmdDma.map ) < 0 ) { 338ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 339ab47cfaaSmrg "[agp] Could not map command DMA\n" ); 340ab47cfaaSmrg return FALSE; 341ab47cfaaSmrg } 342ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 343ab47cfaaSmrg "[agp] command DMA mapped at 0x%08lx\n", 344ab47cfaaSmrg (unsigned long)pSAVAGEDRIServer->cmdDma.map ); 345ab47cfaaSmrg */ 346ab47cfaaSmrg } else if ( psav->VertexDMA ) { 347ab47cfaaSmrg if ( drmAddMap( psav->drmFD, 348ab47cfaaSmrg pSAVAGEDRIServer->buffers.offset, 349ab47cfaaSmrg pSAVAGEDRIServer->buffers.size, 350ab47cfaaSmrg DRM_AGP, 0, 351ab47cfaaSmrg &pSAVAGEDRIServer->buffers.handle ) < 0 ) { 352ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 353ab47cfaaSmrg "[agp] Could not add DMA buffers mapping\n" ); 354ab47cfaaSmrg return FALSE; 355ab47cfaaSmrg } 356ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 357ab47cfaaSmrg "[agp] DMA buffers handle = 0x%08lx\n", 3585788ca14Smrg (unsigned long)pSAVAGEDRIServer->buffers.handle ); 359ab47cfaaSmrg /* not needed in the server 360ab47cfaaSmrg if ( drmMap( psav->drmFD, 361ab47cfaaSmrg pSAVAGEDRIServer->buffers.handle, 362ab47cfaaSmrg pSAVAGEDRIServer->buffers.size, 363ab47cfaaSmrg &pSAVAGEDRIServer->buffers.map ) < 0 ) { 364ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 365ab47cfaaSmrg "[agp] Could not map DMA buffers\n" ); 366ab47cfaaSmrg return FALSE; 367ab47cfaaSmrg } 368ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 369ab47cfaaSmrg "[agp] DMA buffers mapped at 0x%08lx\n", 370ab47cfaaSmrg (unsigned long)pSAVAGEDRIServer->buffers.map ); 371ab47cfaaSmrg */ 372ab47cfaaSmrg } 373ab47cfaaSmrg } 374ab47cfaaSmrg 3751c79cd07Smrg /* XVideo buffer 3761c79cd07Smrg */ 3771c79cd07Smrg if (pSAVAGEDRIServer->agpXVideo.size != 0) { 3781c79cd07Smrg if ( drmAddMap( psav->drmFD, 3791c79cd07Smrg pSAVAGEDRIServer->agpXVideo.offset, 3801c79cd07Smrg pSAVAGEDRIServer->agpXVideo.size, 3811c79cd07Smrg DRM_AGP, 0, 3821c79cd07Smrg &pSAVAGEDRIServer->agpXVideo.handle ) < 0 ) { 3831c79cd07Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 3841c79cd07Smrg "[agp] Could not add agpXVideo, will use framebuffer upload (slower) \n" ); 3851c79cd07Smrg pSAVAGEDRIServer->agpXVideo.size = 0; 3861c79cd07Smrg pSAVAGEDRIServer->agpXVideo.handle = 0; 3871c79cd07Smrg } else { 3881c79cd07Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 3891c79cd07Smrg "[agp] agpXVideo handle = 0x%08lx\n", 3905788ca14Smrg (unsigned long)pSAVAGEDRIServer->agpXVideo.handle ); 3911c79cd07Smrg } 3921c79cd07Smrg } 3931c79cd07Smrg 394ab47cfaaSmrg /* AGP textures 395ab47cfaaSmrg */ 396ab47cfaaSmrg if ( drmAddMap( psav->drmFD, 397ab47cfaaSmrg pSAVAGEDRIServer->agpTextures.offset, 398ab47cfaaSmrg pSAVAGEDRIServer->agpTextures.size, 399ab47cfaaSmrg DRM_AGP, 0, 400ab47cfaaSmrg &pSAVAGEDRIServer->agpTextures.handle ) < 0 ) { 401ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 402ab47cfaaSmrg "[agp] Could not add agpTextures \n" ); 403ab47cfaaSmrg return FALSE; 404ab47cfaaSmrg } 405ab47cfaaSmrg /* pSAVAGEDRIServer->agp_offset=pSAVAGEDRIServer->agpTexture.size;*/ 406ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 407ab47cfaaSmrg "[agp] agpTextures handle = 0x%08lx\n", 4085788ca14Smrg (unsigned long)pSAVAGEDRIServer->agpTextures.handle ); 409ab47cfaaSmrg 410ab47cfaaSmrg /* not needed in the server 411ab47cfaaSmrg if ( drmMap( psav->drmFD, 412ab47cfaaSmrg pSAVAGEDRIServer->agpTextures.handle, 413ab47cfaaSmrg pSAVAGEDRIServer->agpTextures.size, 414ab47cfaaSmrg &pSAVAGEDRIServer->agpTextures.map ) < 0 ) { 415ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 416ab47cfaaSmrg "[agp] Could not map agpTextures \n" ); 417ab47cfaaSmrg return FALSE; 418ab47cfaaSmrg } 419ab47cfaaSmrg 420ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 421ab47cfaaSmrg "[agp] agpTextures mapped at 0x%08lx\n", 422ab47cfaaSmrg (unsigned long)pSAVAGEDRIServer->agpTextures.map ); 423ab47cfaaSmrg */ 424ab47cfaaSmrg 425ab47cfaaSmrg return TRUE; 426ab47cfaaSmrg} 427ab47cfaaSmrg 428ab47cfaaSmrgstatic Bool SAVAGEDRIMapInit( ScreenPtr pScreen ) 429ab47cfaaSmrg{ 4305788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 431ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 432ab47cfaaSmrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 433ab47cfaaSmrg 434ab47cfaaSmrg pSAVAGEDRIServer->registers.size = SAVAGEIOMAPSIZE; 435ab47cfaaSmrg 436ab47cfaaSmrg if ( drmAddMap( psav->drmFD, 4378697ee19Smrg (drm_handle_t)psav->MmioRegion.base, 438ab47cfaaSmrg pSAVAGEDRIServer->registers.size, 439ab47cfaaSmrg DRM_REGISTERS,0, 440ab47cfaaSmrg &pSAVAGEDRIServer->registers.handle ) < 0 ) { 441ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 442ab47cfaaSmrg "[drm] Could not add MMIO registers mapping\n" ); 443ab47cfaaSmrg return FALSE; 444ab47cfaaSmrg } 445ab47cfaaSmrg 446ab47cfaaSmrg pSAVAGEDRIServer->aperture.size = 5 * 0x01000000; 447ab47cfaaSmrg 448ab47cfaaSmrg if ( drmAddMap( psav->drmFD, 4498697ee19Smrg (drm_handle_t)(psav->ApertureRegion.base), 450ab47cfaaSmrg pSAVAGEDRIServer->aperture.size, 451ab47cfaaSmrg DRM_FRAME_BUFFER,0, 452ab47cfaaSmrg &pSAVAGEDRIServer->aperture.handle ) < 0 ) { 453ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 454ab47cfaaSmrg "[drm] Could not add aperture mapping\n" ); 455ab47cfaaSmrg return FALSE; 456ab47cfaaSmrg } 457ab47cfaaSmrg 458ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 459ab47cfaaSmrg "[drm] aperture handle = 0x%08lx\n", 4605788ca14Smrg (unsigned long)pSAVAGEDRIServer->aperture.handle ); 461ab47cfaaSmrg 462ab47cfaaSmrg /*if(drmMap(psav->drmFD, 463ab47cfaaSmrg pSAVAGEDRIServer->registers.handle, 464ab47cfaaSmrg pSAVAGEDRIServer->registers.size, 465ab47cfaaSmrg &pSAVAGEDRIServer->registers.map)<0) 466ab47cfaaSmrg { 467ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 468ab47cfaaSmrg "[drm] Could not map MMIO registers region to virtual\n" ); 469ab47cfaaSmrg return FALSE; 470ab47cfaaSmrg 471ab47cfaaSmrg }*/ 472ab47cfaaSmrg 473ab47cfaaSmrg if ( !psav->AgpDMA && psav->CommandDMA ) { 474ab47cfaaSmrg pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE; 475ab47cfaaSmrg if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->cmdDma.size, 476ab47cfaaSmrg DRM_CONSISTENT, DRM_RESTRICTED | DRM_LOCKED | 477ab47cfaaSmrg DRM_KERNEL | DRM_WRITE_COMBINING, 478ab47cfaaSmrg &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) { 479ab47cfaaSmrg psav->CommandDMA = FALSE; 480ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_WARNING, 481ab47cfaaSmrg "[drm] Could not add PCI command DMA mapping\n" ); 482ab47cfaaSmrg } else 483ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 484ab47cfaaSmrg "[drm] PCI command DMA handle = 0x%08lx\n", 4855788ca14Smrg (unsigned long)pSAVAGEDRIServer->cmdDma.handle ); 486ab47cfaaSmrg } 487ab47cfaaSmrg 488ab47cfaaSmrg /* Enable ShadowStatus by default for direct rendering. */ 489ab47cfaaSmrg if ( !psav->ShadowStatus && !psav->ForceShadowStatus ) { 490ab47cfaaSmrg psav->ShadowStatus = TRUE; 491ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 492ab47cfaaSmrg "[drm] Enabling ShadowStatus for DRI.\n" ); 493ab47cfaaSmrg } 494ab47cfaaSmrg 495ab47cfaaSmrg /* If shadow status is manually or automatically enabled, use a 496ab47cfaaSmrg * page in system memory. */ 497ab47cfaaSmrg if ( psav->ShadowStatus ) { 498ab47cfaaSmrg pSAVAGEDRIServer->status.size = 4096; /* 1 page */ 499ab47cfaaSmrg 500ab47cfaaSmrg if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->status.size, 501ab47cfaaSmrg DRM_CONSISTENT, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL, 502ab47cfaaSmrg &pSAVAGEDRIServer->status.handle ) < 0 ) { 503ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 504ab47cfaaSmrg "[drm] Could not add status page mapping\n" ); 505ab47cfaaSmrg return FALSE; 506ab47cfaaSmrg } 507ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 508ab47cfaaSmrg "[drm] Status handle = 0x%08lx\n", 5095788ca14Smrg (unsigned long)pSAVAGEDRIServer->status.handle ); 510ab47cfaaSmrg 511ab47cfaaSmrg if ( drmMap( psav->drmFD, 512ab47cfaaSmrg pSAVAGEDRIServer->status.handle, 513ab47cfaaSmrg pSAVAGEDRIServer->status.size, 514ab47cfaaSmrg &pSAVAGEDRIServer->status.map ) < 0 ) { 515ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 516ab47cfaaSmrg "[drm] Could not map status page\n" ); 517ab47cfaaSmrg return FALSE; 518ab47cfaaSmrg } 519ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 520ab47cfaaSmrg "[drm] Status page mapped at 0x%08lx\n", 521ab47cfaaSmrg (unsigned long)pSAVAGEDRIServer->status.map ); 522ab47cfaaSmrg 523ab47cfaaSmrg psav->ShadowPhysical = pSAVAGEDRIServer->status.handle; 524ab47cfaaSmrg psav->ShadowVirtual = pSAVAGEDRIServer->status.map; 525ab47cfaaSmrg } 526ab47cfaaSmrg 527ab47cfaaSmrg return TRUE; 528ab47cfaaSmrg} 529ab47cfaaSmrg 530ab47cfaaSmrgstatic Bool SAVAGEDRIBuffersInit( ScreenPtr pScreen ) 531ab47cfaaSmrg{ 5325788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 533ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 534ab47cfaaSmrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 535ab47cfaaSmrg int count; 536ab47cfaaSmrg 537ab47cfaaSmrg if ( !psav->VertexDMA || psav->CommandDMA ) { 538ab47cfaaSmrg /* At this point psav->CommandDMA == TRUE means that CommandDMA 539ab47cfaaSmrg * allocation was actually successful. */ 540ab47cfaaSmrg psav->VertexDMA = FALSE; 541ab47cfaaSmrg return TRUE; 542ab47cfaaSmrg } 543ab47cfaaSmrg 544ab47cfaaSmrg if ( psav->AgpDMA ) { 545ab47cfaaSmrg count = drmAddBufs( psav->drmFD, 546ab47cfaaSmrg SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, 547ab47cfaaSmrg DRM_AGP_BUFFER, pSAVAGEDRIServer->buffers.offset ); 548ab47cfaaSmrg } else { 549ab47cfaaSmrg count = drmAddBufs( psav->drmFD, 550ab47cfaaSmrg SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, 551ab47cfaaSmrg 0, 0 ); 552ab47cfaaSmrg } 553ab47cfaaSmrg if ( count <= 0 ) { 554ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, 555ab47cfaaSmrg "[drm] failure adding %d %d byte DMA buffers (%d)\n", 556ab47cfaaSmrg SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, count ); 557ab47cfaaSmrg return FALSE; 558ab47cfaaSmrg } 559ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 560ab47cfaaSmrg "[drm] Added %d %d byte DMA buffers\n", 561ab47cfaaSmrg count, SAVAGE_BUFFER_SIZE ); 562ab47cfaaSmrg 563ab47cfaaSmrg /* not needed in the server 564ab47cfaaSmrg pSAVAGEDRIServer->drmBuffers = drmMapBufs( psav->drmFD ); 565ab47cfaaSmrg if ( !pSAVAGEDRIServer->drmBuffers ) { 566ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 567ab47cfaaSmrg "[drm] Failed to map DMA buffers list\n" ); 568ab47cfaaSmrg return FALSE; 569ab47cfaaSmrg } 570ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 571ab47cfaaSmrg "[drm] Mapped %d DMA buffers\n", 572ab47cfaaSmrg pSAVAGEDRIServer->drmBuffers->count ); 573ab47cfaaSmrg */ 574ab47cfaaSmrg 575ab47cfaaSmrg return TRUE; 576ab47cfaaSmrg} 577ab47cfaaSmrg 578ab47cfaaSmrgstatic Bool SAVAGEDRIKernelInit( ScreenPtr pScreen ) 579ab47cfaaSmrg{ 5805788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 581ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 582ab47cfaaSmrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 583ab47cfaaSmrg drmSAVAGEInit init; 584ab47cfaaSmrg int ret; 585ab47cfaaSmrg 586ab47cfaaSmrg memset( &init, 0, sizeof(drmSAVAGEInit) ); 587ab47cfaaSmrg 588ab47cfaaSmrg init.func = SAVAGE_INIT_BCI; 589ab47cfaaSmrg init.sarea_priv_offset = sizeof(XF86DRISAREARec); 590ab47cfaaSmrg 591ab47cfaaSmrg init.cob_size = psav->cobSize/4; /* size in 32-bit entries */ 592ab47cfaaSmrg init.bci_threshold_lo = psav->bciThresholdLo; 593ab47cfaaSmrg init.bci_threshold_hi = psav->bciThresholdHi; 594ab47cfaaSmrg init.dma_type = psav->AgpDMA ? SAVAGE_DMA_AGP : SAVAGE_DMA_PCI; 595ab47cfaaSmrg 596ab47cfaaSmrg init.fb_bpp = pScrn->bitsPerPixel; 597ab47cfaaSmrg init.front_offset = pSAVAGEDRIServer->frontOffset; 598ab47cfaaSmrg init.front_pitch = pSAVAGEDRIServer->frontPitch; 599ab47cfaaSmrg init.back_offset = pSAVAGEDRIServer->backOffset; 600ab47cfaaSmrg init.back_pitch = pSAVAGEDRIServer->backPitch; 601ab47cfaaSmrg 602ab47cfaaSmrg init.depth_bpp = pScrn->bitsPerPixel; 603ab47cfaaSmrg init.depth_offset = pSAVAGEDRIServer->depthOffset; 604ab47cfaaSmrg init.depth_pitch = pSAVAGEDRIServer->depthPitch; 605ab47cfaaSmrg 606ab47cfaaSmrg init.texture_offset = pSAVAGEDRIServer->textureOffset; 607ab47cfaaSmrg init.texture_size = pSAVAGEDRIServer->textureSize; 608ab47cfaaSmrg 609ab47cfaaSmrg init.status_offset = pSAVAGEDRIServer->status.handle; 610ab47cfaaSmrg init.agp_textures_offset = pSAVAGEDRIServer->agpTextures.handle; 611ab47cfaaSmrg 612ab47cfaaSmrg /* Savage4-based chips with DRM version >= 2.4 support command DMA, 613ab47cfaaSmrg * which is preferred because it works with all vertex 614ab47cfaaSmrg * formats. Command DMA and vertex DMA don't work at the same 615ab47cfaaSmrg * time. */ 616ab47cfaaSmrg init.buffers_offset = 0; 617ab47cfaaSmrg init.cmd_dma_offset = 0; 618ab47cfaaSmrg if ( psav->CommandDMA ) 619ab47cfaaSmrg init.cmd_dma_offset = pSAVAGEDRIServer->cmdDma.handle; 620ab47cfaaSmrg else if ( psav->VertexDMA ) 621ab47cfaaSmrg init.buffers_offset = pSAVAGEDRIServer->buffers.handle; 622ab47cfaaSmrg 623ab47cfaaSmrg ret = drmCommandWrite( psav->drmFD, DRM_SAVAGE_BCI_INIT, &init, sizeof(init) ); 624ab47cfaaSmrg if ( ret < 0 ) { 625ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 626ab47cfaaSmrg "[drm] Failed to initialize BCI! (%d)\n", ret ); 627ab47cfaaSmrg return FALSE; 628ab47cfaaSmrg } 629ab47cfaaSmrg 630ab47cfaaSmrg return TRUE; 631ab47cfaaSmrg} 632ab47cfaaSmrg 633ab47cfaaSmrgBool SAVAGEDRIScreenInit( ScreenPtr pScreen ) 634ab47cfaaSmrg{ 6355788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 636ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 637ab47cfaaSmrg DRIInfoPtr pDRIInfo; 638ab47cfaaSmrg SAVAGEDRIPtr pSAVAGEDRI; 639ab47cfaaSmrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer; 640ab47cfaaSmrg 641c744f008Smrg /* Check that the DRI, and DRM modules have been loaded by testing 642ab47cfaaSmrg * for canonical symbols in each module. 643ab47cfaaSmrg */ 644ab47cfaaSmrg if ( !xf86LoaderCheckSymbol( "drmAvailable" ) ) return FALSE; 645ab47cfaaSmrg if ( !xf86LoaderCheckSymbol( "DRIQueryVersion" ) ) { 646ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 647ab47cfaaSmrg "[dri] SAVAGEDRIScreenInit failed (libdri.a too old)\n" ); 648ab47cfaaSmrg return FALSE; 649ab47cfaaSmrg } 650ab47cfaaSmrg 651ab47cfaaSmrg /* Check the DRI version */ 652ab47cfaaSmrg { 653ab47cfaaSmrg int major, minor, patch; 654ab47cfaaSmrg DRIQueryVersion( &major, &minor, &patch ); 655ab47cfaaSmrg if ( major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION ) { 656ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 657ab47cfaaSmrg "[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n" 658ab47cfaaSmrg "[dri] libdri version = %d.%d.%d but version %d.%d.x is needed.\n" 659ab47cfaaSmrg "[dri] Disabling the DRI.\n", 660ab47cfaaSmrg major, minor, patch, 661ab47cfaaSmrg DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION ); 662ab47cfaaSmrg return FALSE; 663ab47cfaaSmrg } 664ab47cfaaSmrg } 665ab47cfaaSmrg 666ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_INFO, 667ab47cfaaSmrg "[drm] bpp: %d depth: %d\n", 668ab47cfaaSmrg pScrn->bitsPerPixel, pScrn->depth ); 669ab47cfaaSmrg 670ab47cfaaSmrg if ( (pScrn->bitsPerPixel / 8) != 2 && 671ab47cfaaSmrg (pScrn->bitsPerPixel / 8) != 4 ) { 672ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 673ab47cfaaSmrg "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" ); 674ab47cfaaSmrg return FALSE; 675ab47cfaaSmrg } 676ab47cfaaSmrg 677ab47cfaaSmrg pDRIInfo = DRICreateInfoRec(); 678ab47cfaaSmrg if ( !pDRIInfo ) { 679ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 680ab47cfaaSmrg "[dri] DRICreateInfoRec() failed\n" ); 681ab47cfaaSmrg return FALSE; 682ab47cfaaSmrg } 683ab47cfaaSmrg psav->pDRIInfo = pDRIInfo; 684ab47cfaaSmrg 685ab47cfaaSmrg pDRIInfo->drmDriverName = SAVAGEKernelDriverName; 686ab47cfaaSmrg pDRIInfo->clientDriverName = SAVAGEClientDriverName; 687ab47cfaaSmrg if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 688ab47cfaaSmrg pDRIInfo->busIdString = DRICreatePCIBusID(psav->PciInfo); 689ab47cfaaSmrg } else { 6905788ca14Smrg pDRIInfo->busIdString = malloc(64); 691ab47cfaaSmrg sprintf(pDRIInfo->busIdString, 692ab47cfaaSmrg "PCI:%d:%d:%d", 693ab47cfaaSmrg psav->PciInfo->bus, 6948697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 6958697ee19Smrg psav->PciInfo->dev, 6968697ee19Smrg#else 697ab47cfaaSmrg psav->PciInfo->device, 6988697ee19Smrg#endif 699ab47cfaaSmrg psav->PciInfo->func); 700ab47cfaaSmrg } 701ab47cfaaSmrg pDRIInfo->ddxDriverMajorVersion = SAVAGE_VERSION_MAJOR; 702ab47cfaaSmrg pDRIInfo->ddxDriverMinorVersion = SAVAGE_VERSION_MINOR; 703ab47cfaaSmrg pDRIInfo->ddxDriverPatchVersion = SAVAGE_PATCHLEVEL; 704ab47cfaaSmrg 7052c9fd100Smrg pDRIInfo->frameBufferPhysicalAddress = (pointer)(uintptr_t) psav->FbRegion.base; 706ab47cfaaSmrg pDRIInfo->frameBufferSize = psav->videoRambytes; 707ab47cfaaSmrg pDRIInfo->frameBufferStride = pScrn->displayWidth*(pScrn->bitsPerPixel/8); 708ab47cfaaSmrg pDRIInfo->ddxDrawableTableEntry = SAVAGE_MAX_DRAWABLES; 709ab47cfaaSmrg 710ab47cfaaSmrg /* override default DRI block and wakeup handler */ 711ab47cfaaSmrg psav->coreBlockHandler = pDRIInfo->wrap.BlockHandler; 712ab47cfaaSmrg pDRIInfo->wrap.BlockHandler = SAVAGEBlockHandler; 713ab47cfaaSmrg psav->coreWakeupHandler = pDRIInfo->wrap.WakeupHandler; 714ab47cfaaSmrg pDRIInfo->wrap.WakeupHandler = SAVAGEWakeupHandler; 715ab47cfaaSmrg 716ab47cfaaSmrg pDRIInfo->createDummyCtx = TRUE; 717ab47cfaaSmrg pDRIInfo->createDummyCtxPriv = FALSE; 718ab47cfaaSmrg 719ab47cfaaSmrg if ( SAREA_MAX_DRAWABLES < SAVAGE_MAX_DRAWABLES ) { 720ab47cfaaSmrg pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; 721ab47cfaaSmrg } else { 722ab47cfaaSmrg pDRIInfo->maxDrawableTableEntry = SAVAGE_MAX_DRAWABLES; 723ab47cfaaSmrg } 724ab47cfaaSmrg 725ab47cfaaSmrg /* For now the mapping works by using a fixed size defined 726ab47cfaaSmrg * in the SAREA header. 727ab47cfaaSmrg */ 728ab47cfaaSmrg if ( sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec) > SAREA_MAX ) { 729ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 730ab47cfaaSmrg "[drm] Data does not fit in SAREA\n" ); 731ab47cfaaSmrg return FALSE; 732ab47cfaaSmrg } 733ab47cfaaSmrg 734ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, 735ab47cfaaSmrg "[drm] Sarea %d+%d: %d\n", 736c744f008Smrg (int) sizeof(XF86DRISAREARec), (int) sizeof(SAVAGESAREAPrivRec), 737c744f008Smrg (int) (sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec)) ); 738ab47cfaaSmrg 739ab47cfaaSmrg pDRIInfo->SAREASize = SAREA_MAX; 740ab47cfaaSmrg 7415788ca14Smrg pSAVAGEDRI = (SAVAGEDRIPtr)calloc( sizeof(SAVAGEDRIRec), 1 ); 742ab47cfaaSmrg if ( !pSAVAGEDRI ) { 743ab47cfaaSmrg DRIDestroyInfoRec( psav->pDRIInfo ); 744ab47cfaaSmrg psav->pDRIInfo = 0; 745ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 746ab47cfaaSmrg "[drm] Failed to allocate memory for private record\n" ); 747ab47cfaaSmrg return FALSE; 748ab47cfaaSmrg } 749ab47cfaaSmrg 750ab47cfaaSmrg pSAVAGEDRIServer = (SAVAGEDRIServerPrivatePtr) 7515788ca14Smrg calloc( sizeof(SAVAGEDRIServerPrivateRec), 1 ); 752ab47cfaaSmrg if ( !pSAVAGEDRIServer ) { 7535788ca14Smrg free( pSAVAGEDRI ); 754ab47cfaaSmrg DRIDestroyInfoRec( psav->pDRIInfo ); 755ab47cfaaSmrg psav->pDRIInfo = 0; 756ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 757ab47cfaaSmrg "[drm] Failed to allocate memory for private record\n" ); 758ab47cfaaSmrg return FALSE; 759ab47cfaaSmrg } 760ab47cfaaSmrg psav->DRIServerInfo = pSAVAGEDRIServer; 761ab47cfaaSmrg 762ab47cfaaSmrg pDRIInfo->devPrivate = pSAVAGEDRI; 763ab47cfaaSmrg pDRIInfo->devPrivateSize = sizeof(SAVAGEDRIRec); 764ab47cfaaSmrg pDRIInfo->contextSize = sizeof(SAVAGEDRIContextRec); 765ab47cfaaSmrg 766ab47cfaaSmrg pDRIInfo->CreateContext = SAVAGECreateContext; 767ab47cfaaSmrg pDRIInfo->DestroyContext = SAVAGEDestroyContext; 768ab47cfaaSmrg 769ab47cfaaSmrg /* FK: SwapContext is not used with KERNEL_SWAP. */ 770ab47cfaaSmrg pDRIInfo->SwapContext = NULL; 771ab47cfaaSmrg 772ab47cfaaSmrg pDRIInfo->InitBuffers = SAVAGEDRIInitBuffers; 773ab47cfaaSmrg pDRIInfo->MoveBuffers = SAVAGEDRIMoveBuffers; 774ab47cfaaSmrg pDRIInfo->OpenFullScreen = SAVAGEDRIOpenFullScreen; 775ab47cfaaSmrg pDRIInfo->CloseFullScreen = SAVAGEDRICloseFullScreen; 776ab47cfaaSmrg pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 777ab47cfaaSmrg 778ab47cfaaSmrg if ( !DRIScreenInit( pScreen, pDRIInfo, &psav->drmFD ) ) { 7795788ca14Smrg free( pSAVAGEDRIServer ); 780ab47cfaaSmrg psav->DRIServerInfo = 0; 7815788ca14Smrg free( pDRIInfo->devPrivate ); 782ab47cfaaSmrg pDRIInfo->devPrivate = 0; 783ab47cfaaSmrg DRIDestroyInfoRec( psav->pDRIInfo ); 784ab47cfaaSmrg psav->pDRIInfo = 0; 785ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 786ab47cfaaSmrg "[drm] DRIScreenInit failed. Disabling DRI.\n" ); 787ab47cfaaSmrg return FALSE; 788ab47cfaaSmrg } 789ab47cfaaSmrg 790ab47cfaaSmrg /* Check the SAVAGE DRM version */ 791ab47cfaaSmrg { 792ab47cfaaSmrg drmVersionPtr version = drmGetVersion(psav->drmFD); 793ab47cfaaSmrg if ( version ) { 794ab47cfaaSmrg if ( version->version_major != 2 || 795ab47cfaaSmrg version->version_minor < 0 ) { 796ab47cfaaSmrg /* incompatible drm version */ 797ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 798ab47cfaaSmrg "[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n" 799ab47cfaaSmrg "[dri] savage.ko kernel module version is %d.%d.%d but version 2.0.x is needed.\n" 800ab47cfaaSmrg "[dri] Disabling DRI.\n", 801ab47cfaaSmrg version->version_major, 802ab47cfaaSmrg version->version_minor, 803ab47cfaaSmrg version->version_patchlevel ); 804ab47cfaaSmrg drmFreeVersion( version ); 805ab47cfaaSmrg SAVAGEDRICloseScreen( pScreen ); /* FIXME: ??? */ 806ab47cfaaSmrg return FALSE; 807ab47cfaaSmrg } 808ab47cfaaSmrg if ( psav->CommandDMA && version->version_minor < 4 ) { 809ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_WARNING, 810ab47cfaaSmrg "[drm] DRM version < 2.4.0 does not support command DMA.\n"); 811ab47cfaaSmrg psav->CommandDMA = FALSE; 812ab47cfaaSmrg } 813ab47cfaaSmrg if ( !psav->VertexDMA && version->version_minor < 4 ) { 814ab47cfaaSmrg xf86DrvMsg( pScreen->myNum, X_ERROR, 815ab47cfaaSmrg "[drm] DRM version < 2.4.0 requires vertex DMA.\n"); 816ab47cfaaSmrg drmFreeVersion( version ); 817ab47cfaaSmrg SAVAGEDRICloseScreen( pScreen ); 818ab47cfaaSmrg return FALSE; 819ab47cfaaSmrg } 820ab47cfaaSmrg drmFreeVersion( version ); 821ab47cfaaSmrg } 822ab47cfaaSmrg } 823ab47cfaaSmrg 824ab47cfaaSmrg if ( !psav->IsPCI && !SAVAGEDRIAgpInit( pScreen ) ) { 825ab47cfaaSmrg if (pSAVAGEDRIServer->agp.handle != 0) { 826ab47cfaaSmrg /* AGP initialization succeeded, but adding AGP mappings failed. */ 827ab47cfaaSmrg SAVAGEDRICloseScreen( pScreen ); 828ab47cfaaSmrg return FALSE; 829ab47cfaaSmrg } 830ab47cfaaSmrg /* AGP initialization failed, fall back to PCI mode. */ 831ab47cfaaSmrg psav->IsPCI = TRUE; 832ab47cfaaSmrg psav->AgpDMA = FALSE; 833ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_WARNING, 834ab47cfaaSmrg "[agp] AGP failed to initialize -- falling back to PCI mode.\n"); 835ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_WARNING, 836ab47cfaaSmrg "[agp] Make sure you have the agpgart kernel module loaded.\n"); 837ab47cfaaSmrg } 838ab47cfaaSmrg 839ab47cfaaSmrg if ( !SAVAGEDRIMapInit( pScreen ) ) { 840ab47cfaaSmrg SAVAGEDRICloseScreen( pScreen ); 841ab47cfaaSmrg return FALSE; 842ab47cfaaSmrg } 843ab47cfaaSmrg 8445788ca14Smrg /* Linux kernel DRM broken in 2.6.30 through 2.6.39 */ 8455788ca14Smrg if (pDRIInfo->hFrameBuffer == pSAVAGEDRIServer->aperture.handle) 8465788ca14Smrg xf86DrvMsg( pScrn->scrnIndex, X_WARNING, 8475788ca14Smrg "[drm] Detected broken drm maps. Please upgrade to linux kernel 3.x\n"); 8485788ca14Smrg 849ab47cfaaSmrg if ( !SAVAGEDRIBuffersInit( pScreen ) ) { 850ab47cfaaSmrg SAVAGEDRICloseScreen( pScreen ); 851ab47cfaaSmrg return FALSE; 852ab47cfaaSmrg } 853ab47cfaaSmrg 854ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized\n" ); 855ab47cfaaSmrg 856ab47cfaaSmrg return TRUE; 857ab47cfaaSmrg} 858ab47cfaaSmrg 8595788ca14Smrgstatic void SAVAGEDRISetupTiledSurfaceRegs( SavagePtr psav ) 8605788ca14Smrg{ 8615788ca14Smrg SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate; 8625788ca14Smrg unsigned int value = 0; 8635788ca14Smrg 8645788ca14Smrg OUTREG(0x850C,(INREG(0x850C) | 0x00008000)); /* AGD: I don't think this does anything on 3D/MX/IX */ 8655788ca14Smrg /* maybe savage4 too... */ 8665788ca14Smrg /* we don't use Y range flag,so comment it */ 8675788ca14Smrg /* 8685788ca14Smrg if(pSAVAGEDRI->width <= 1024) 8695788ca14Smrg value |= (1<<29); 8705788ca14Smrg */ 8715788ca14Smrg if ((psav->Chipset == S3_SAVAGE_MX) /* 3D/MX/IX seem to set up the tile stride differently */ 8725788ca14Smrg || (psav->Chipset == S3_SAVAGE3D)) { 8735788ca14Smrg if(pSAVAGEDRI->cpp == 2) 8745788ca14Smrg { 8755788ca14Smrg value |= ((psav->lDelta / 4) >> 5) << 24; 8765788ca14Smrg value |= 2<<30; 8775788ca14Smrg } else { 8785788ca14Smrg value |= ((psav->lDelta / 4) >> 5) << 24; 8795788ca14Smrg value |= 3<<30; 8805788ca14Smrg } 8815788ca14Smrg 8825788ca14Smrg OUTREG(TILED_SURFACE_REGISTER_0, value|(pSAVAGEDRI->frontOffset) ); /* front */ 8835788ca14Smrg OUTREG(TILED_SURFACE_REGISTER_1, value|(pSAVAGEDRI->backOffset) ); /* back */ 8845788ca14Smrg OUTREG(TILED_SURFACE_REGISTER_2, value|(pSAVAGEDRI->depthOffset) ); /* depth */ 8855788ca14Smrg } else { 8865788ca14Smrg int offset_shift = 5; 8875788ca14Smrg if(pSAVAGEDRI->cpp == 2) 8885788ca14Smrg { 8895788ca14Smrg value |= (((pSAVAGEDRI->width + 0x3F) & 0xFFC0) >> 6) << 20; 8905788ca14Smrg value |= 2<<30; 8915788ca14Smrg } else { 8925788ca14Smrg value |= (((pSAVAGEDRI->width + 0x1F) & 0xFFE0) >> 5) << 20; 8935788ca14Smrg value |= 3<<30; 8945788ca14Smrg } 8955788ca14Smrg if (psav->Chipset == S3_SUPERSAVAGE) /* supersavages have a different shift */ 8965788ca14Smrg offset_shift = 6; 8975788ca14Smrg OUTREG(TILED_SURFACE_REGISTER_0, value|(pSAVAGEDRI->frontOffset >> offset_shift) ); /* front */ 8985788ca14Smrg OUTREG(TILED_SURFACE_REGISTER_1, value|(pSAVAGEDRI->backOffset >> offset_shift) ); /* back */ 8995788ca14Smrg OUTREG(TILED_SURFACE_REGISTER_2, value|(pSAVAGEDRI->depthOffset >> offset_shift) ); /* depth */ 9005788ca14Smrg } 9015788ca14Smrg} 902ab47cfaaSmrg 903ab47cfaaSmrgBool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen ) 904ab47cfaaSmrg{ 9055788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 906ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 907ab47cfaaSmrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 908ab47cfaaSmrg SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate; 909ab47cfaaSmrg int i; 910ab47cfaaSmrg 911ab47cfaaSmrg if ( !psav->pDRIInfo ) 912ab47cfaaSmrg return FALSE; 913ab47cfaaSmrg 914ab47cfaaSmrg psav->pDRIInfo->driverSwapMethod = DRI_KERNEL_SWAP; 915ab47cfaaSmrg 916ab47cfaaSmrg /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit 917ab47cfaaSmrg * because *DRIKernelInit requires that the hardware lock is held by 918ab47cfaaSmrg * the X server, and the first time the hardware lock is grabbed is 919ab47cfaaSmrg * in DRIFinishScreenInit. 920ab47cfaaSmrg */ 921ab47cfaaSmrg if ( !DRIFinishScreenInit( pScreen ) ) { 922ab47cfaaSmrg SAVAGEDRICloseScreen( pScreen ); 923ab47cfaaSmrg return FALSE; 924ab47cfaaSmrg } 925ab47cfaaSmrg psav->LockHeld = 1; 926ab47cfaaSmrg 927ab47cfaaSmrg if ( !SAVAGEDRIKernelInit( pScreen ) ) { 928ab47cfaaSmrg SAVAGEDRICloseScreen( pScreen ); 929ab47cfaaSmrg return FALSE; 930ab47cfaaSmrg } 931ab47cfaaSmrg 932ab47cfaaSmrg pSAVAGEDRI->chipset = psav->Chipset; 933ab47cfaaSmrg pSAVAGEDRI->width = pScrn->virtualX; 934ab47cfaaSmrg pSAVAGEDRI->height = pScrn->virtualY; 935ab47cfaaSmrg pSAVAGEDRI->mem = pScrn->videoRam * 1024; 936ab47cfaaSmrg pSAVAGEDRI->cpp = pScrn->bitsPerPixel / 8; 937ab47cfaaSmrg pSAVAGEDRI->zpp = pSAVAGEDRI->cpp; 938ab47cfaaSmrg 939ab47cfaaSmrg pSAVAGEDRI->agpMode = psav->IsPCI ? 0 : psav->agpMode; 940ab47cfaaSmrg 941ab47cfaaSmrg pSAVAGEDRI->bufferSize = SAVAGE_BUFFER_SIZE; 942ab47cfaaSmrg 943ab47cfaaSmrg pSAVAGEDRI->frontOffset = pSAVAGEDRIServer->frontOffset; 944ab47cfaaSmrg pSAVAGEDRI->frontbufferSize = pSAVAGEDRIServer->frontbufferSize; 945ab47cfaaSmrg 946ab47cfaaSmrg pSAVAGEDRI->backOffset = pSAVAGEDRIServer->backOffset; 947ab47cfaaSmrg pSAVAGEDRI->backbufferSize = pSAVAGEDRIServer->backbufferSize; 948ab47cfaaSmrg 949ab47cfaaSmrg pSAVAGEDRI->depthOffset = pSAVAGEDRIServer->depthOffset; 950ab47cfaaSmrg pSAVAGEDRI->depthbufferSize = pSAVAGEDRIServer->depthbufferSize; 951ab47cfaaSmrg 952ab47cfaaSmrg pSAVAGEDRI->textureOffset = pSAVAGEDRIServer->textureOffset; 953ab47cfaaSmrg 954ab47cfaaSmrg i = mylog2( pSAVAGEDRIServer->textureSize / SAVAGE_NR_TEX_REGIONS ); 955ab47cfaaSmrg if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE ) 956ab47cfaaSmrg i = SAVAGE_LOG_MIN_TEX_REGION_SIZE; 957ab47cfaaSmrg 958ab47cfaaSmrg pSAVAGEDRI->logTextureGranularity = i; 959ab47cfaaSmrg pSAVAGEDRI->textureSize = (pSAVAGEDRIServer->textureSize >> i) << i; /* truncate */ 960ab47cfaaSmrg 961ab47cfaaSmrg pSAVAGEDRI->agpTextureHandle = pSAVAGEDRIServer->agpTextures.handle; 962ab47cfaaSmrg 963ab47cfaaSmrg i = mylog2( pSAVAGEDRIServer->agpTextures.size / SAVAGE_NR_TEX_REGIONS ); 964ab47cfaaSmrg if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE ) 965ab47cfaaSmrg i = SAVAGE_LOG_MIN_TEX_REGION_SIZE; 966ab47cfaaSmrg 967ab47cfaaSmrg pSAVAGEDRI->logAgpTextureGranularity = i; 968ab47cfaaSmrg pSAVAGEDRI->agpTextureSize = (pSAVAGEDRIServer->agpTextures.size >> i) << i; /* truncate */ 969ab47cfaaSmrg 970ab47cfaaSmrg pSAVAGEDRI->apertureHandle = pSAVAGEDRIServer->aperture.handle; 971ab47cfaaSmrg pSAVAGEDRI->apertureSize = pSAVAGEDRIServer->aperture.size; 9728697ee19Smrg pSAVAGEDRI->aperturePitch = psav->ulAperturePitch; 973ab47cfaaSmrg 974ab47cfaaSmrg pSAVAGEDRI->statusHandle = pSAVAGEDRIServer->status.handle; 975ab47cfaaSmrg pSAVAGEDRI->statusSize = pSAVAGEDRIServer->status.size; 976ab47cfaaSmrg 977ab47cfaaSmrg pSAVAGEDRI->sarea_priv_offset = sizeof(XF86DRISAREARec); 978ab47cfaaSmrg 979ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRIServer:\n" ); 980ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] reserved_map_agpstart:0x%08x\n",pSAVAGEDRIServer->reserved_map_agpstart); 981ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] reserved_map_idx:0x%08x\n",pSAVAGEDRIServer->reserved_map_idx); 982ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] sarea_priv_offset:0x%08x\n",pSAVAGEDRIServer->sarea_priv_offset); 983ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] chipset:0x%08x\n",pSAVAGEDRIServer->chipset); 984ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] sgram:0x%08x\n",pSAVAGEDRIServer->sgram); 985ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontbufferSize:0x%08x\n",pSAVAGEDRIServer->frontbufferSize); 986ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontOffset:0x%08x\n",pSAVAGEDRIServer->frontOffset); 987ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontPitch:0x%08x\n",pSAVAGEDRIServer->frontPitch); 988ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backbufferSize:0x%08x\n",pSAVAGEDRIServer->backbufferSize); 989ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backOffset:0x%08x\n",pSAVAGEDRIServer->backOffset); 990ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backPitch:0x%08x\n",pSAVAGEDRIServer->backPitch); 991ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthbufferSize:0x%08x\n",pSAVAGEDRIServer->depthbufferSize); 992ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthOffset:0x%08x\n",pSAVAGEDRIServer->depthOffset); 993ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthPitch:0x%08x\n",pSAVAGEDRIServer->depthPitch); 994ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureOffset:0x%08x\n",pSAVAGEDRIServer->textureOffset); 995ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize); 996ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize); 997ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logTextureGranularity); 998ab47cfaaSmrg 9995788ca14Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agp.handle); 1000ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:offset:0x%08x\n",pSAVAGEDRIServer->agp.offset); 1001ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:size:0x%08x\n",pSAVAGEDRIServer->agp.size); 1002ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agp.map); 1003ab47cfaaSmrg 10045788ca14Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->registers.handle); 1005ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:offset:0x%08x\n",pSAVAGEDRIServer->registers.offset); 1006ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:size:0x%08x\n",pSAVAGEDRIServer->registers.size); 1007ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->registers.map); 1008ab47cfaaSmrg 10095788ca14Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->status.handle); 1010ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:offset:0x%08x\n",pSAVAGEDRIServer->status.offset); 1011ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:size:0x%08x\n",pSAVAGEDRIServer->status.size); 1012ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->status.map); 1013ab47cfaaSmrg 10145788ca14Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agpTextures.handle); 1015ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:offset:0x%08x\n",pSAVAGEDRIServer->agpTextures.offset); 1016ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:size:0x%08x\n",pSAVAGEDRIServer->agpTextures.size); 1017ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] apgTextures:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agpTextures.map); 1018ab47cfaaSmrg 1019ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logAgpTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logAgpTextureGranularity); 1020ab47cfaaSmrg 10215788ca14Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->cmdDma.handle); 1022ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:offset:0x%08x\n",pSAVAGEDRIServer->cmdDma.offset); 1023ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:size:0x%08x\n",pSAVAGEDRIServer->cmdDma.size); 1024ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->cmdDma.map); 1025ab47cfaaSmrg 1026ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRI:\n" ); 1027ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] chipset:0x%08x\n",pSAVAGEDRI->chipset ); 1028ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] width:0x%08x\n",pSAVAGEDRI->width ); 1029ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] height:0x%08x\n",pSAVAGEDRI->height ); 1030ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] mem:0x%08x\n",pSAVAGEDRI->mem ); 1031ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cpp:%d\n",pSAVAGEDRI->cpp ); 1032ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] zpp:%d\n",pSAVAGEDRI->zpp ); 1033ab47cfaaSmrg 1034ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpMode:%d\n",pSAVAGEDRI->agpMode ); 1035ab47cfaaSmrg 1036ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] bufferSize:%u\n",pSAVAGEDRI->bufferSize ); 1037ab47cfaaSmrg 1038ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontbufferSize:0x%08x\n",pSAVAGEDRI->frontbufferSize); 1039ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontOffset:0x%08x\n",pSAVAGEDRI->frontOffset ); 1040ab47cfaaSmrg 1041ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backbufferSize:0x%08x\n",pSAVAGEDRI->backbufferSize); 1042ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backOffset:0x%08x\n",pSAVAGEDRI->backOffset ); 1043ab47cfaaSmrg 1044ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthbufferSize:0x%08x\n",pSAVAGEDRI->depthbufferSize); 1045ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthOffset:0x%08x\n",pSAVAGEDRI->depthOffset ); 1046ab47cfaaSmrg 1047ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureOffset:0x%08x\n",pSAVAGEDRI->textureOffset ); 1048ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureSize:0x%08x\n",pSAVAGEDRI->textureSize ); 1049ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logTextureGranularity:0x%08x\n",pSAVAGEDRI->logTextureGranularity ); 1050ab47cfaaSmrg 10515788ca14Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextureHandle:0x%08lx\n",(unsigned long)pSAVAGEDRI->agpTextureHandle ); 1052ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextureSize:0x%08x\n",pSAVAGEDRI->agpTextureSize ); 1053ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logAgpTextureGranularity:0x%08x\n",pSAVAGEDRI->logAgpTextureGranularity ); 1054ab47cfaaSmrg 10555788ca14Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] apertureHandle:0x%08lx\n",(unsigned long)pSAVAGEDRI->apertureHandle); 1056ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] apertureSize:0x%08x\n",pSAVAGEDRI->apertureSize); 1057ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] aperturePitch:0x%08x\n",pSAVAGEDRI->aperturePitch); 1058ab47cfaaSmrg 10595788ca14Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] statusHandle:0x%08lx\n",(unsigned long)pSAVAGEDRI->statusHandle); 1060ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] statusSize:0x%08x\n",pSAVAGEDRI->statusSize); 1061ab47cfaaSmrg 1062ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] sarea_priv_offset:0x%08x\n",pSAVAGEDRI->sarea_priv_offset); 1063ab47cfaaSmrg 10645788ca14Smrg SAVAGEDRISetupTiledSurfaceRegs( psav ); 1065ab47cfaaSmrg return TRUE; 1066ab47cfaaSmrg} 1067ab47cfaaSmrg 10685788ca14Smrgvoid SAVAGEDRIResume(ScreenPtr pScreen) 10695788ca14Smrg{ 10705788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 10715788ca14Smrg SavagePtr psav = SAVPTR(pScrn); 10725788ca14Smrg SAVAGESAREAPrivPtr pSAREAPriv = 10735788ca14Smrg (SAVAGESAREAPrivPtr)DRIGetSAREAPrivate(pScreen); 10745788ca14Smrg 10755788ca14Smrg if (!psav->IsPCI) { 10765788ca14Smrg SAVAGESetAgpMode(psav, pScreen); 10775788ca14Smrg } 10785788ca14Smrg SAVAGEDRISetupTiledSurfaceRegs(psav); 10795788ca14Smrg /* Assume that 3D state was clobbered, invalidate it by 10805788ca14Smrg * changing ctxOwner in the sarea. */ 10815788ca14Smrg pSAREAPriv->ctxOwner = DRIGetContext(pScreen); 10825788ca14Smrg} 1083ab47cfaaSmrg 1084ab47cfaaSmrgvoid SAVAGEDRICloseScreen( ScreenPtr pScreen ) 1085ab47cfaaSmrg{ 10865788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1087ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1088ab47cfaaSmrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 1089ab47cfaaSmrg 1090ab47cfaaSmrg if ( pSAVAGEDRIServer->status.map ) { 1091ab47cfaaSmrg drmUnmap( pSAVAGEDRIServer->status.map, pSAVAGEDRIServer->status.size ); 1092ab47cfaaSmrg pSAVAGEDRIServer->status.map = NULL; 1093ab47cfaaSmrg } 1094ab47cfaaSmrg 1095ab47cfaaSmrg if ( pSAVAGEDRIServer->registers.map ) { 1096ab47cfaaSmrg drmUnmap( pSAVAGEDRIServer->registers.map, pSAVAGEDRIServer->registers.size ); 1097ab47cfaaSmrg pSAVAGEDRIServer->registers.map = NULL; 1098ab47cfaaSmrg } 1099ab47cfaaSmrg 1100ab47cfaaSmrg if ( pSAVAGEDRIServer->aperture.map ) { 1101ab47cfaaSmrg drmUnmap( pSAVAGEDRIServer->aperture.map, pSAVAGEDRIServer->aperture.size ); 1102ab47cfaaSmrg pSAVAGEDRIServer->aperture.map = NULL; 1103ab47cfaaSmrg } 1104ab47cfaaSmrg 11051c79cd07Smrg if ( pSAVAGEDRIServer->agpXVideo.map ) { 11061c79cd07Smrg drmUnmap( pSAVAGEDRIServer->agpXVideo.map, 11071c79cd07Smrg pSAVAGEDRIServer->agpXVideo.size ); 11081c79cd07Smrg pSAVAGEDRIServer->agpXVideo.map = NULL; 11091c79cd07Smrg } 11101c79cd07Smrg 1111ab47cfaaSmrg if ( pSAVAGEDRIServer->agpTextures.map ) { 1112ab47cfaaSmrg drmUnmap( pSAVAGEDRIServer->agpTextures.map, 1113ab47cfaaSmrg pSAVAGEDRIServer->agpTextures.size ); 1114ab47cfaaSmrg pSAVAGEDRIServer->agpTextures.map = NULL; 1115ab47cfaaSmrg } 1116ab47cfaaSmrg 1117ab47cfaaSmrg if (pSAVAGEDRIServer->status.handle) 1118ab47cfaaSmrg drmRmMap(psav->drmFD,pSAVAGEDRIServer->status.handle); 1119ab47cfaaSmrg 1120ab47cfaaSmrg if (pSAVAGEDRIServer->registers.handle) 1121ab47cfaaSmrg drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle); 1122ab47cfaaSmrg 1123ab47cfaaSmrg if (pSAVAGEDRIServer->aperture.handle) 1124ab47cfaaSmrg drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle); 1125ab47cfaaSmrg 11261c79cd07Smrg if (pSAVAGEDRIServer->agpXVideo.handle) 11271c79cd07Smrg drmRmMap(psav->drmFD,pSAVAGEDRIServer->agpXVideo.handle); 11281c79cd07Smrg 1129ab47cfaaSmrg if (pSAVAGEDRIServer->agpTextures.handle) 1130ab47cfaaSmrg drmRmMap(psav->drmFD,pSAVAGEDRIServer->agpTextures.handle); 1131ab47cfaaSmrg 1132ab47cfaaSmrg if (pSAVAGEDRIServer->cmdDma.handle) 1133ab47cfaaSmrg drmRmMap(psav->drmFD,pSAVAGEDRIServer->cmdDma.handle); 1134ab47cfaaSmrg 1135ab47cfaaSmrg if ( pSAVAGEDRIServer->buffers.map ) { 1136ab47cfaaSmrg drmUnmap( pSAVAGEDRIServer->buffers.map, pSAVAGEDRIServer->buffers.size ); 1137ab47cfaaSmrg pSAVAGEDRIServer->buffers.map = NULL; 1138ab47cfaaSmrg } 1139ab47cfaaSmrg 1140ab47cfaaSmrg if ( pSAVAGEDRIServer->agp.handle ) { 1141ab47cfaaSmrg drmAgpUnbind( psav->drmFD, pSAVAGEDRIServer->agp.handle ); 1142ab47cfaaSmrg drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle ); 1143ab47cfaaSmrg pSAVAGEDRIServer->agp.handle = 0; 1144ab47cfaaSmrg drmAgpRelease( psav->drmFD ); 1145ab47cfaaSmrg } 1146ab47cfaaSmrg 1147ab47cfaaSmrg DRICloseScreen( pScreen ); 1148ab47cfaaSmrg 1149ab47cfaaSmrg /* Don't use shadow status any more. If this happens due to failed 1150ab47cfaaSmrg * DRI initialization then SavageScreenInit will do the real 1151ab47cfaaSmrg * cleanup and restore ShadowStatus to sane settings. */ 1152ab47cfaaSmrg psav->ShadowVirtual = NULL; 1153ab47cfaaSmrg psav->ShadowPhysical = 0; 1154ab47cfaaSmrg 1155ab47cfaaSmrg if(psav->reserved) 1156ab47cfaaSmrg xf86FreeOffscreenLinear(psav->reserved); 1157ab47cfaaSmrg 1158ab47cfaaSmrg if ( psav->pDRIInfo ) { 1159ab47cfaaSmrg if ( psav->pDRIInfo->devPrivate ) { 11605788ca14Smrg free( psav->pDRIInfo->devPrivate ); 1161ab47cfaaSmrg psav->pDRIInfo->devPrivate = 0; 1162ab47cfaaSmrg } 1163ab47cfaaSmrg DRIDestroyInfoRec( psav->pDRIInfo ); 1164ab47cfaaSmrg psav->pDRIInfo = 0; 1165ab47cfaaSmrg } 1166ab47cfaaSmrg if ( psav->DRIServerInfo ) { 11675788ca14Smrg free( psav->DRIServerInfo ); 1168ab47cfaaSmrg psav->DRIServerInfo = 0; 1169ab47cfaaSmrg } 1170ab47cfaaSmrg} 1171ab47cfaaSmrg 1172ab47cfaaSmrgvoid 1173ab47cfaaSmrgSAVAGEDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) 1174ab47cfaaSmrg{ 1175ab47cfaaSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 11765788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1177ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1178ab47cfaaSmrg BoxPtr pbox = REGION_RECTS(prgn); 1179ab47cfaaSmrg int nbox = REGION_NUM_RECTS(prgn); 1180ab47cfaaSmrg drmSAVAGECmdHeader cmd[2]; 1181ab47cfaaSmrg drmSAVAGECmdbuf cmdBuf; 1182ab47cfaaSmrg int ret; 1183ab47cfaaSmrg 1184ab47cfaaSmrg if (!psav->LockHeld) { 1185ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_WARNING, 1186ab47cfaaSmrg "Not holding the lock in InitBuffers.\n"); 1187ab47cfaaSmrg return; 1188ab47cfaaSmrg } 1189ab47cfaaSmrg 1190ab47cfaaSmrg cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR; 1191ab47cfaaSmrg cmd[0].clear0.flags = SAVAGE_BACK|SAVAGE_DEPTH; 1192ab47cfaaSmrg cmd[1].clear1.mask = 0xffffffff; 1193ab47cfaaSmrg cmd[1].clear1.value = 0; 1194ab47cfaaSmrg 1195ab47cfaaSmrg cmdBuf.cmd_addr = cmd; 1196ab47cfaaSmrg cmdBuf.size = 2; 1197ab47cfaaSmrg cmdBuf.dma_idx = 0; 1198ab47cfaaSmrg cmdBuf.discard = 0; 1199ab47cfaaSmrg cmdBuf.vb_addr = NULL; 1200ab47cfaaSmrg cmdBuf.vb_size = 0; 1201ab47cfaaSmrg cmdBuf.vb_stride = 0; 1202ab47cfaaSmrg cmdBuf.box_addr = (drm_clip_rect_t*)pbox; 1203ab47cfaaSmrg cmdBuf.nbox = nbox; 1204ab47cfaaSmrg 1205ab47cfaaSmrg ret = drmCommandWrite(psav->drmFD, DRM_SAVAGE_BCI_CMDBUF, 1206ab47cfaaSmrg &cmdBuf, sizeof(cmdBuf)); 1207ab47cfaaSmrg if (ret < 0) { 1208ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 1209ab47cfaaSmrg "SAVAGEDRIInitBuffers: drmCommandWrite returned %d.\n", 1210ab47cfaaSmrg ret); 1211ab47cfaaSmrg } 1212ab47cfaaSmrg} 1213ab47cfaaSmrg 1214ab47cfaaSmrg/* 1215ab47cfaaSmrg This routine is a modified form of XAADoBitBlt with the calls to 1216ab47cfaaSmrg ScreenToScreenBitBlt built in. My routine has the prgnSrc as source 1217ab47cfaaSmrg instead of destination. My origin is upside down so the ydir cases 1218ab47cfaaSmrg are reversed. 1219ab47cfaaSmrg*/ 1220ab47cfaaSmrg 1221ab47cfaaSmrgvoid 1222ab47cfaaSmrgSAVAGEDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 1223ab47cfaaSmrg RegionPtr prgnSrc, CARD32 index) 1224ab47cfaaSmrg{ 1225ab47cfaaSmrg ScreenPtr pScreen = pParent->drawable.pScreen; 12265788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1227ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1228ab47cfaaSmrg int nbox; 1229ab47cfaaSmrg BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2; 1230ab47cfaaSmrg DDXPointPtr pptTmp, pptNew1, pptNew2; 1231ab47cfaaSmrg int xdir, ydir; 1232ab47cfaaSmrg int dx, dy; 1233ab47cfaaSmrg DDXPointPtr pptSrc; 1234ab47cfaaSmrg int screenwidth = pScrn->virtualX; 1235ab47cfaaSmrg int screenheight = pScrn->virtualY; 1236ab47cfaaSmrg BCI_GET_PTR; 1237ab47cfaaSmrg 1238ab47cfaaSmrg if (!psav->LockHeld) { 1239ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "Not holding lock in MoveBuffers\n"); 1240ab47cfaaSmrg } 1241ab47cfaaSmrg 1242ab47cfaaSmrg pbox = REGION_RECTS(prgnSrc); 1243ab47cfaaSmrg nbox = REGION_NUM_RECTS(prgnSrc); 1244ab47cfaaSmrg pboxNew1 = 0; 1245ab47cfaaSmrg pptNew1 = 0; 1246ab47cfaaSmrg pboxNew2 = 0; 12475788ca14Smrg pptNew2 = 0; 1248ab47cfaaSmrg pptSrc = &ptOldOrg; 1249ab47cfaaSmrg 1250ab47cfaaSmrg dx = pParent->drawable.x - ptOldOrg.x; 1251ab47cfaaSmrg dy = pParent->drawable.y - ptOldOrg.y; 1252ab47cfaaSmrg 1253ab47cfaaSmrg /* If the copy will overlap in Y, reverse the order */ 1254ab47cfaaSmrg if (dy>0) { 1255ab47cfaaSmrg ydir = -1; 1256ab47cfaaSmrg 1257ab47cfaaSmrg if (nbox>1) { 1258ab47cfaaSmrg /* Keep ordering in each band, reverse order of bands */ 12595788ca14Smrg pboxNew1 = malloc(sizeof(BoxRec)*nbox); 1260ab47cfaaSmrg if (!pboxNew1) return; 12615788ca14Smrg pptNew1 = malloc(sizeof(DDXPointRec)*nbox); 1262ab47cfaaSmrg if (!pptNew1) { 12635788ca14Smrg free(pboxNew1); 1264ab47cfaaSmrg return; 1265ab47cfaaSmrg } 1266ab47cfaaSmrg pboxBase = pboxNext = pbox+nbox-1; 1267ab47cfaaSmrg while (pboxBase >= pbox) { 1268ab47cfaaSmrg while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) 1269ab47cfaaSmrg pboxNext--; 1270ab47cfaaSmrg pboxTmp = pboxNext+1; 1271ab47cfaaSmrg pptTmp = pptSrc + (pboxTmp - pbox); 1272ab47cfaaSmrg while (pboxTmp <= pboxBase) { 1273ab47cfaaSmrg *pboxNew1++ = *pboxTmp++; 1274ab47cfaaSmrg *pptNew1++ = *pptTmp++; 1275ab47cfaaSmrg } 1276ab47cfaaSmrg pboxBase = pboxNext; 1277ab47cfaaSmrg } 1278ab47cfaaSmrg pboxNew1 -= nbox; 1279ab47cfaaSmrg pbox = pboxNew1; 1280ab47cfaaSmrg pptNew1 -= nbox; 1281ab47cfaaSmrg pptSrc = pptNew1; 1282ab47cfaaSmrg } 1283ab47cfaaSmrg } else { 1284ab47cfaaSmrg /* No changes required */ 1285ab47cfaaSmrg ydir = 1; 1286ab47cfaaSmrg } 1287ab47cfaaSmrg 1288ab47cfaaSmrg /* If the regions will overlap in X, reverse the order */ 1289ab47cfaaSmrg if (dx>0) { 1290ab47cfaaSmrg xdir = -1; 1291ab47cfaaSmrg 1292ab47cfaaSmrg if (nbox > 1) { 1293ab47cfaaSmrg /*reverse orderof rects in each band */ 12945788ca14Smrg pboxNew2 = malloc(sizeof(BoxRec)*nbox); 12955788ca14Smrg pptNew2 = malloc(sizeof(DDXPointRec)*nbox); 1296ab47cfaaSmrg if (!pboxNew2 || !pptNew2) { 12975788ca14Smrg if (pptNew2) free(pptNew2); 12985788ca14Smrg if (pboxNew2) free(pboxNew2); 1299ab47cfaaSmrg if (pboxNew1) { 13005788ca14Smrg free(pptNew1); 13015788ca14Smrg free(pboxNew1); 1302ab47cfaaSmrg } 1303ab47cfaaSmrg return; 1304ab47cfaaSmrg } 1305ab47cfaaSmrg pboxBase = pboxNext = pbox; 1306ab47cfaaSmrg while (pboxBase < pbox+nbox) { 1307ab47cfaaSmrg while ((pboxNext < pbox+nbox) && 1308ab47cfaaSmrg (pboxNext->y1 == pboxBase->y1)) 1309ab47cfaaSmrg pboxNext++; 1310ab47cfaaSmrg pboxTmp = pboxNext; 1311ab47cfaaSmrg pptTmp = pptSrc + (pboxTmp - pbox); 1312ab47cfaaSmrg while (pboxTmp != pboxBase) { 1313ab47cfaaSmrg *pboxNew2++ = *--pboxTmp; 1314ab47cfaaSmrg *pptNew2++ = *--pptTmp; 1315ab47cfaaSmrg } 1316ab47cfaaSmrg pboxBase = pboxNext; 1317ab47cfaaSmrg } 1318ab47cfaaSmrg pboxNew2 -= nbox; 1319ab47cfaaSmrg pbox = pboxNew2; 1320ab47cfaaSmrg pptNew2 -= nbox; 1321ab47cfaaSmrg pptSrc = pptNew2; 1322ab47cfaaSmrg } 1323ab47cfaaSmrg } else { 1324ab47cfaaSmrg /* No changes are needed */ 1325ab47cfaaSmrg xdir = 1; 1326ab47cfaaSmrg } 1327ab47cfaaSmrg 1328ab47cfaaSmrg BCI_SEND(0xc0030000); /* wait for 2D+3D idle */ 1329ab47cfaaSmrg SAVAGEDRISetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1); 1330ab47cfaaSmrg for ( ; nbox-- ; pbox++) 1331ab47cfaaSmrg { 1332ab47cfaaSmrg int x1 = pbox->x1; 1333ab47cfaaSmrg int y1 = pbox->y1; 1334ab47cfaaSmrg int destx = x1 + dx; 1335ab47cfaaSmrg int desty = y1 + dy; 1336ab47cfaaSmrg int w = pbox->x2 - x1 + 1; 1337ab47cfaaSmrg int h = pbox->y2 - y1 + 1; 1338ab47cfaaSmrg 1339ab47cfaaSmrg if ( destx < 0 ) x1 -= destx, w += destx, destx = 0; 1340ab47cfaaSmrg if ( desty < 0 ) y1 -= desty, h += desty, desty = 0; 1341ab47cfaaSmrg if ( destx + w > screenwidth ) w = screenwidth - destx; 1342ab47cfaaSmrg if ( desty + h > screenheight ) h = screenheight - desty; 1343ab47cfaaSmrg if ( w <= 0 ) continue; 1344ab47cfaaSmrg if ( h <= 0 ) continue; 1345ab47cfaaSmrg 1346ab47cfaaSmrg SAVAGESelectBuffer(pScrn, SAVAGE_BACK); 1347ab47cfaaSmrg SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1, y1, 1348ab47cfaaSmrg destx,desty, w, h); 1349ab47cfaaSmrg SAVAGESelectBuffer(pScrn, SAVAGE_DEPTH); 1350ab47cfaaSmrg SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1,y1, 1351ab47cfaaSmrg destx,desty, w, h); 1352ab47cfaaSmrg } 1353ab47cfaaSmrg SAVAGESelectBuffer(pScrn, SAVAGE_FRONT); 1354ab47cfaaSmrg 1355ab47cfaaSmrg if (pboxNew2) { 13565788ca14Smrg free(pptNew2); 13575788ca14Smrg free(pboxNew2); 1358ab47cfaaSmrg } 1359ab47cfaaSmrg if (pboxNew1) { 13605788ca14Smrg free(pptNew1); 13615788ca14Smrg free(pboxNew1); 1362ab47cfaaSmrg } 1363ab47cfaaSmrg 1364ab47cfaaSmrg BCI_SEND(0xc0020000); /* wait for 2D idle */ 1365ab47cfaaSmrg if (psav->useEXA) 1366ab47cfaaSmrg exaMarkSync(pScreen); 13675788ca14Smrg#ifdef HAVE_XAA_H 1368ab47cfaaSmrg else 1369ab47cfaaSmrg psav->AccelInfoRec->NeedToSync = TRUE; 13705788ca14Smrg#endif 1371ab47cfaaSmrg} 1372ab47cfaaSmrg 1373ab47cfaaSmrgstatic void 1374ab47cfaaSmrgSAVAGEDRISetupForScreenToScreenCopy( 1375ab47cfaaSmrg ScrnInfoPtr pScrn, 1376ab47cfaaSmrg int xdir, 1377ab47cfaaSmrg int ydir, 1378ab47cfaaSmrg int rop, 1379ab47cfaaSmrg unsigned planemask, 1380ab47cfaaSmrg int transparency_color) 1381ab47cfaaSmrg{ 1382ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1383ab47cfaaSmrg int cmd =0; 1384ab47cfaaSmrg 1385ab47cfaaSmrg cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD | BCI_CMD_SRC_PBD_COLOR; 13861c79cd07Smrg BCI_CMD_SET_ROP( cmd, SavageGetCopyROP(rop) ); 1387ab47cfaaSmrg if (transparency_color != -1) 1388ab47cfaaSmrg cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT; 1389ab47cfaaSmrg 1390ab47cfaaSmrg if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP; 1391ab47cfaaSmrg if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP; 1392ab47cfaaSmrg 1393ab47cfaaSmrg psav->SavedBciCmd = cmd; 1394ab47cfaaSmrg psav->SavedBgColor = transparency_color; 1395ab47cfaaSmrg 1396ab47cfaaSmrg} 1397ab47cfaaSmrg 1398ab47cfaaSmrgstatic void 1399ab47cfaaSmrgSAVAGEDRISubsequentScreenToScreenCopy( 1400ab47cfaaSmrg ScrnInfoPtr pScrn, 1401ab47cfaaSmrg int x1, 1402ab47cfaaSmrg int y1, 1403ab47cfaaSmrg int x2, 1404ab47cfaaSmrg int y2, 1405ab47cfaaSmrg int w, 1406ab47cfaaSmrg int h) 1407ab47cfaaSmrg{ 1408ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1409ab47cfaaSmrg BCI_GET_PTR; 1410ab47cfaaSmrg 1411ab47cfaaSmrg if (!w || !h) return; 1412ab47cfaaSmrg if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) { 1413ab47cfaaSmrg w --; 1414ab47cfaaSmrg x1 += w; 1415ab47cfaaSmrg x2 += w; 1416ab47cfaaSmrg w ++; 1417ab47cfaaSmrg } 1418ab47cfaaSmrg if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) { 1419ab47cfaaSmrg h --; 1420ab47cfaaSmrg y1 += h; 1421ab47cfaaSmrg y2 += h; 1422ab47cfaaSmrg h ++; 1423ab47cfaaSmrg } 1424ab47cfaaSmrg 1425ab47cfaaSmrg psav->WaitQueue(psav,6); 1426ab47cfaaSmrg BCI_SEND(psav->SavedBciCmd); 1427ab47cfaaSmrg if (psav->SavedBgColor != -1) 1428ab47cfaaSmrg BCI_SEND(psav->SavedBgColor); 1429ab47cfaaSmrg BCI_SEND(BCI_X_Y(x1, y1)); 1430ab47cfaaSmrg BCI_SEND(BCI_X_Y(x2, y2)); 1431ab47cfaaSmrg BCI_SEND(BCI_W_H(w, h)); 1432ab47cfaaSmrg 1433ab47cfaaSmrg} 1434ab47cfaaSmrg 1435ab47cfaaSmrg/* 1436ab47cfaaSmrg * the FullScreen DRI code is dead, this is just left in place to show how 1437ab47cfaaSmrg * to set up pageflipping. 1438ab47cfaaSmrg */ 1439ab47cfaaSmrgstatic Bool 1440ab47cfaaSmrgSAVAGEDRIOpenFullScreen(ScreenPtr pScreen) 1441ab47cfaaSmrg{ 14425788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1443ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1444ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1445ab47cfaaSmrg unsigned int vgaCRIndex = hwp->IOBase + 4; 1446ab47cfaaSmrg unsigned int vgaCRReg = hwp->IOBase + 5; 1447ab47cfaaSmrg SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate; 1448ab47cfaaSmrg unsigned int TileStride; 1449ab47cfaaSmrg unsigned int WidthinTiles; 1450ab47cfaaSmrg unsigned int depth; 1451ab47cfaaSmrg 1452ab47cfaaSmrg OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7); 1453ab47cfaaSmrg /*VGAOUT8(vgaCRIndex,0x66); 1454ab47cfaaSmrg VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg)|0x10);*/ 1455ab47cfaaSmrg VGAOUT8(vgaCRIndex,0x69); 1456ab47cfaaSmrg VGAOUT8(vgaCRReg, 0x80); 1457ab47cfaaSmrg 1458ab47cfaaSmrg depth = pScrn->bitsPerPixel; 1459ab47cfaaSmrg 1460ab47cfaaSmrg if(depth == 16) 1461ab47cfaaSmrg { 1462ab47cfaaSmrg WidthinTiles = (pSAVAGEDRI->width+63)>>6; 1463ab47cfaaSmrg TileStride = (pSAVAGEDRI->width+63)&(~63); 1464ab47cfaaSmrg 1465ab47cfaaSmrg } 1466ab47cfaaSmrg else 1467ab47cfaaSmrg { 1468ab47cfaaSmrg WidthinTiles = (pSAVAGEDRI->width+31)>>5; 1469ab47cfaaSmrg TileStride = (pSAVAGEDRI->width+31)&(~31); 1470ab47cfaaSmrg 1471ab47cfaaSmrg } 1472ab47cfaaSmrg 1473ab47cfaaSmrg 1474ab47cfaaSmrg /* set primary stream stride */ 1475ab47cfaaSmrg { 1476ab47cfaaSmrg unsigned int value; 1477ab47cfaaSmrg 1478ab47cfaaSmrg /*value = 0x80000000|(WidthinTiles<<24)|(TileStride*depth/8);*/ 1479ab47cfaaSmrg value = 0x80000000|(WidthinTiles<<24); 1480ab47cfaaSmrg if(depth == 32) 1481ab47cfaaSmrg value |= 0x40000000; 1482ab47cfaaSmrg 1483ab47cfaaSmrg OUTREG(PRI_STREAM_STRIDE, value); 1484ab47cfaaSmrg 1485ab47cfaaSmrg } 1486ab47cfaaSmrg 1487ab47cfaaSmrg /* set global bitmap descriptor */ 1488ab47cfaaSmrg { 1489ab47cfaaSmrg unsigned int value; 1490ab47cfaaSmrg value = 0x10000000| 1491ab47cfaaSmrg 0x00000009| 1492ab47cfaaSmrg 0x01000000| 1493ab47cfaaSmrg (depth<<16) | TileStride; 1494ab47cfaaSmrg 1495ab47cfaaSmrg OUTREG(0x816C,value); 1496ab47cfaaSmrg 1497ab47cfaaSmrg } 1498ab47cfaaSmrg 1499ab47cfaaSmrg OUTREG(0x48C18, INREG(0x48C18) | 0x8); 1500ab47cfaaSmrg 1501ab47cfaaSmrg return TRUE; 1502ab47cfaaSmrg} 1503ab47cfaaSmrg 1504ab47cfaaSmrgstatic Bool 1505ab47cfaaSmrgSAVAGEDRICloseFullScreen(ScreenPtr pScreen) 1506ab47cfaaSmrg{ 15075788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1508ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1509ab47cfaaSmrg BCI_GET_PTR; 1510ab47cfaaSmrg 1511ab47cfaaSmrg BCI_SEND(0xC0FF0000); 1512ab47cfaaSmrg psav->WaitIdleEmpty(psav); 1513ab47cfaaSmrg OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7); 1514ab47cfaaSmrg /* set primary stream stride */ 1515ab47cfaaSmrg { 1516ab47cfaaSmrg /* MM81C0 and 81C4 are used to control primary stream. */ 1517ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000); 1518ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000); 1519ab47cfaaSmrg 1520ab47cfaaSmrg /* FIFO control */ 1521ab47cfaaSmrg OUTREG32(0X81EC,0Xffffffff); 1522ab47cfaaSmrg 1523ab47cfaaSmrg if (!psav->bTiled) { 1524ab47cfaaSmrg OUTREG32(PRI_STREAM_STRIDE, 1525ab47cfaaSmrg (((psav->lDelta * 2) << 16) & 0x3FFFE000) | 1526ab47cfaaSmrg (psav->lDelta & 0x00001fff)); 1527ab47cfaaSmrg } 1528ab47cfaaSmrg else if (pScrn->bitsPerPixel == 16) { 1529ab47cfaaSmrg /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */ 1530ab47cfaaSmrg OUTREG32(PRI_STREAM_STRIDE, 1531ab47cfaaSmrg (((psav->lDelta * 2) << 16) & 0x3FFFE000) 1532ab47cfaaSmrg | 0x80000000 | (psav->lDelta & 0x00001fff)); 1533ab47cfaaSmrg } 1534ab47cfaaSmrg else if (pScrn->bitsPerPixel == 32) { 1535ab47cfaaSmrg OUTREG32(PRI_STREAM_STRIDE, 1536ab47cfaaSmrg (((psav->lDelta * 2) << 16) & 0x3FFFE000) 1537ab47cfaaSmrg | 0xC0000000 | (psav->lDelta & 0x00001fff)); 1538ab47cfaaSmrg } 1539ab47cfaaSmrg 1540ab47cfaaSmrg 1541ab47cfaaSmrg } 1542ab47cfaaSmrg 1543ab47cfaaSmrg /* set global bitmap descriptor */ 1544ab47cfaaSmrg { 1545ab47cfaaSmrg OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart ); 1546ab47cfaaSmrg OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | BCI_ENABLE | S3_LITTLE_ENDIAN | S3_BD64); 1547ab47cfaaSmrg 1548ab47cfaaSmrg } 1549ab47cfaaSmrg 1550ab47cfaaSmrg OUTREG(0x48C18, INREG(0x48C18) | 0x8); 1551ab47cfaaSmrg return TRUE; 1552ab47cfaaSmrg} 1553ab47cfaaSmrg 1554ab47cfaaSmrg#endif 1555