103b705cfSriastradh#ifdef HAVE_CONFIG_H 203b705cfSriastradh#include "config.h" 303b705cfSriastradh#endif 403b705cfSriastradh 503b705cfSriastradh#include <errno.h> 603b705cfSriastradh#include <stdio.h> 703b705cfSriastradh#include <string.h> 803b705cfSriastradh#include <assert.h> 903b705cfSriastradh 109a906b70Schristos#include "xorg-server.h" 1103b705cfSriastradh#include "xf86.h" 1203b705cfSriastradh#include "xf86_OSproc.h" 1303b705cfSriastradh 1403b705cfSriastradh#include "xf86Pci.h" 1503b705cfSriastradh 1603b705cfSriastradh#include "windowstr.h" 1703b705cfSriastradh#include "shadow.h" 1803b705cfSriastradh#include "shadowfb.h" 1903b705cfSriastradh 2003b705cfSriastradh#include "i810.h" 2103b705cfSriastradh#include "i810_dri.h" 2203b705cfSriastradh 2303b705cfSriastradhstatic char I810KernelDriverName[] = "i810"; 2403b705cfSriastradhstatic char I810ClientDriverName[] = "i810"; 2503b705cfSriastradh 2603b705cfSriastradhstatic Bool I810CreateContext(ScreenPtr pScreen, VisualPtr visual, 2703b705cfSriastradh drm_context_t hwContext, void *pVisualConfigPriv, 2803b705cfSriastradh DRIContextType contextStore); 2903b705cfSriastradhstatic void I810DestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 3003b705cfSriastradh DRIContextType contextStore); 3103b705cfSriastradhstatic void I810DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 3203b705cfSriastradh DRIContextType readContextType, 3303b705cfSriastradh void *readContextStore, 3403b705cfSriastradh DRIContextType writeContextType, 3503b705cfSriastradh void *writeContextStore); 3603b705cfSriastradhstatic void I810DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); 3703b705cfSriastradhstatic void I810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 3803b705cfSriastradh RegionPtr prgnSrc, CARD32 index); 3903b705cfSriastradh 4003b705cfSriastradh 4103b705cfSriastradhstatic void I810EnablePageFlip(ScreenPtr pScreen); 4203b705cfSriastradhstatic void I810DisablePageFlip(ScreenPtr pScreen); 4303b705cfSriastradhstatic void I810DRITransitionSingleToMulti3d(ScreenPtr pScreen); 4403b705cfSriastradhstatic void I810DRITransitionMultiToSingle3d(ScreenPtr pScreen); 4503b705cfSriastradhstatic void I810DRITransitionTo3d(ScreenPtr pScreen); 4603b705cfSriastradhstatic void I810DRITransitionTo2d(ScreenPtr pScreen); 4703b705cfSriastradh 4803b705cfSriastradhstatic void I810DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 4903b705cfSriastradh 5003b705cfSriastradhstatic int i810_pitches[] = { 5103b705cfSriastradh 512, 5203b705cfSriastradh 1024, 5303b705cfSriastradh 2048, 5403b705cfSriastradh 4096, 5503b705cfSriastradh 0 5603b705cfSriastradh}; 5703b705cfSriastradh 5803b705cfSriastradhstatic int i810_pitch_flags[] = { 5903b705cfSriastradh 0x0, 6003b705cfSriastradh 0x1, 6103b705cfSriastradh 0x2, 6203b705cfSriastradh 0x3, 6303b705cfSriastradh 0 6403b705cfSriastradh}; 6503b705cfSriastradh 6603b705cfSriastradhstatic unsigned int i810_drm_version = 0; 6703b705cfSriastradh 6803b705cfSriastradhBool 6903b705cfSriastradhI810CleanupDma(ScrnInfoPtr pScrn) 7003b705cfSriastradh{ 7103b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 7203b705cfSriastradh drmI810Init info; 7303b705cfSriastradh 7403b705cfSriastradh memset(&info, 0, sizeof(drmI810Init)); 7503b705cfSriastradh info.func = I810_CLEANUP_DMA; 7603b705cfSriastradh 7703b705cfSriastradh if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT, 7803b705cfSriastradh &info, sizeof(drmI810Init))) { 7903b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 8003b705cfSriastradh "[dri] I810 Dma Cleanup Failed\n"); 8103b705cfSriastradh return FALSE; 8203b705cfSriastradh } 8303b705cfSriastradh 8403b705cfSriastradh return TRUE; 8503b705cfSriastradh} 8603b705cfSriastradh 8703b705cfSriastradhBool 8803b705cfSriastradhI810InitDma(ScrnInfoPtr pScrn) 8903b705cfSriastradh{ 9003b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 9103b705cfSriastradh I810RingBuffer *ring = pI810->LpRing; 9203b705cfSriastradh I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate; 9303b705cfSriastradh drmI810Init info; 9403b705cfSriastradh 9503b705cfSriastradh memset(&info, 0, sizeof(drmI810Init)); 9603b705cfSriastradh 9703b705cfSriastradh info.ring_start = ring->mem.Start; 9803b705cfSriastradh info.ring_end = ring->mem.End; 9903b705cfSriastradh info.ring_size = ring->mem.Size; 10003b705cfSriastradh info.mmio_offset = (unsigned int)pI810DRI->regs; 10103b705cfSriastradh info.buffers_offset = (unsigned int)pI810->buffer_map; 10203b705cfSriastradh info.sarea_priv_offset = sizeof(XF86DRISAREARec); 10303b705cfSriastradh 10403b705cfSriastradh info.front_offset = 0; 10503b705cfSriastradh info.back_offset = pI810->BackBuffer.Start; 10603b705cfSriastradh info.depth_offset = pI810->DepthBuffer.Start; 10703b705cfSriastradh info.overlay_offset = pI810->OverlayStart; 10803b705cfSriastradh info.overlay_physical = pI810->OverlayPhysical; 10903b705cfSriastradh info.w = pScrn->virtualX; 11003b705cfSriastradh info.h = pScrn->virtualY; 11103b705cfSriastradh info.pitch = pI810->auxPitch; 11203b705cfSriastradh info.pitch_bits = pI810->auxPitchBits; 11303b705cfSriastradh 11403b705cfSriastradh /* We require DRM v1.2 or greater. Since DRM v1.2 broke compatibility 11503b705cfSriastradh * we created a new v1.4 that supports a new init function. Eventually the 11603b705cfSriastradh * old init function will go away. If you change the drm interface, make a 11703b705cfSriastradh * new init type too so that we can detect the new client. 11803b705cfSriastradh */ 11903b705cfSriastradh switch(i810_drm_version) { 12003b705cfSriastradh case ((1<<16) | 0): 12103b705cfSriastradh case ((1<<16) | 1): 12203b705cfSriastradh case ((1<<16) | 2): 12303b705cfSriastradh case ((1<<16) | 3): 12403b705cfSriastradh /* Use OLD drm < 1.4 init */ 12503b705cfSriastradh info.func = I810_INIT_DMA; 12603b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Init PRE v1.4 interface.\n"); 12703b705cfSriastradh break; 12803b705cfSriastradh default: 12903b705cfSriastradh case ((1<<16) | 4): 13003b705cfSriastradh /* DRM version 1.3 or greater init */ 13103b705cfSriastradh info.func = I810_INIT_DMA_1_4; 13203b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Init v1.4 interface.\n"); 13303b705cfSriastradh break; 13403b705cfSriastradh } 13503b705cfSriastradh 13603b705cfSriastradh if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT, 13703b705cfSriastradh &info, sizeof(drmI810Init))) { 13803b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 13903b705cfSriastradh "[drm] I810 Dma Initialization failed.\n"); 14003b705cfSriastradh return FALSE; 14103b705cfSriastradh } 14203b705cfSriastradh 14303b705cfSriastradh return TRUE; 14403b705cfSriastradh} 14503b705cfSriastradh 14603b705cfSriastradhstatic unsigned int 14703b705cfSriastradhmylog2(unsigned int n) 14803b705cfSriastradh{ 14903b705cfSriastradh unsigned int log2 = 1; 15003b705cfSriastradh 15103b705cfSriastradh while (n > 1) 15203b705cfSriastradh n >>= 1, log2++; 15303b705cfSriastradh return log2; 15403b705cfSriastradh} 15503b705cfSriastradh 15603b705cfSriastradhBool 15703b705cfSriastradhI810DRIScreenInit(ScreenPtr pScreen) 15803b705cfSriastradh{ 15903b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 16003b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 16103b705cfSriastradh DRIInfoPtr pDRIInfo; 16203b705cfSriastradh I810DRIPtr pI810DRI; 16303b705cfSriastradh unsigned long tom; 16403b705cfSriastradh drm_handle_t agpHandle; 16503b705cfSriastradh drm_handle_t dcacheHandle; 16603b705cfSriastradh int sysmem_size = 0; 16703b705cfSriastradh int back_size = 0; 16803b705cfSriastradh unsigned int pitch_idx = 0; 16903b705cfSriastradh int bufs; 17003b705cfSriastradh int width = pScrn->displayWidth * pI810->cpp; 17103b705cfSriastradh int i; 17203b705cfSriastradh 17303b705cfSriastradh /* Hardware 3D rendering only implemented for 16bpp */ 17403b705cfSriastradh /* And it only works for 5:6:5 (Mark) */ 17503b705cfSriastradh if (pScrn->depth != 16) 17603b705cfSriastradh return FALSE; 17703b705cfSriastradh 17803b705cfSriastradh /* Check that the DRI, and DRM modules have been loaded by testing 17903b705cfSriastradh * for known symbols in each module. */ 18003b705cfSriastradh if (!xf86LoaderCheckSymbol("drmAvailable")) 18103b705cfSriastradh return FALSE; 18203b705cfSriastradh if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { 18303b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 18403b705cfSriastradh "[dri] I810DRIScreenInit failed (libdri.a too old)\n"); 18503b705cfSriastradh return FALSE; 18603b705cfSriastradh } 18703b705cfSriastradh 18803b705cfSriastradh /* adjust width first */ 18903b705cfSriastradh#define Elements(x) sizeof(x)/sizeof(*x) 19003b705cfSriastradh for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++) 19103b705cfSriastradh if (width <= i810_pitches[pitch_idx]) 19203b705cfSriastradh break; 19303b705cfSriastradh 19403b705cfSriastradh if (pitch_idx == Elements(i810_pitches)) { 19503b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 19603b705cfSriastradh "[dri] Couldn't find depth/back buffer pitch"); 19703b705cfSriastradh DRICloseScreen(pScreen); 19803b705cfSriastradh return FALSE; 19903b705cfSriastradh } else { 20003b705cfSriastradh /* for tiled memory to work, the buffer needs to have the 20103b705cfSriastradh * number of lines as a multiple of 16 (the tile size), 20203b705cfSriastradh * - airlied */ 20303b705cfSriastradh int lines = (pScrn->virtualY + 15) / 16 * 16; 20403b705cfSriastradh back_size = i810_pitches[pitch_idx] * lines; 20503b705cfSriastradh back_size = ((back_size + 4096 - 1) / 4096) * 4096; 20603b705cfSriastradh } 20703b705cfSriastradh 20803b705cfSriastradh pScrn->displayWidth = i810_pitches[pitch_idx] / pI810->cpp; 20903b705cfSriastradh 21003b705cfSriastradh /* Check the DRI version */ 21103b705cfSriastradh { 21203b705cfSriastradh int major, minor, patch; 21303b705cfSriastradh 21403b705cfSriastradh DRIQueryVersion(&major, &minor, &patch); 21503b705cfSriastradh if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { 21603b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 21703b705cfSriastradh "[dri] I810DRIScreenInit failed because of a version mismatch.\n" 21803b705cfSriastradh "[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n" 21903b705cfSriastradh "[dri] Disabling DRI.\n", major, minor, patch, 22003b705cfSriastradh DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); 22103b705cfSriastradh return FALSE; 22203b705cfSriastradh } 22303b705cfSriastradh } 22403b705cfSriastradh 22503b705cfSriastradh pDRIInfo = DRICreateInfoRec(); 22603b705cfSriastradh if (!pDRIInfo) { 22703b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 22803b705cfSriastradh "[dri] DRICreateInfoRec failed. Disabling DRI.\n"); 22903b705cfSriastradh return FALSE; 23003b705cfSriastradh } 23103b705cfSriastradh 23203b705cfSriastradh/* pDRIInfo->wrap.ValidateTree = 0; */ 23303b705cfSriastradh/* pDRIInfo->wrap.PostValidateTree = 0; */ 23403b705cfSriastradh 23503b705cfSriastradh pI810->pDRIInfo = pDRIInfo; 23603b705cfSriastradh pI810->LockHeld = 0; 23703b705cfSriastradh 23803b705cfSriastradh pDRIInfo->drmDriverName = I810KernelDriverName; 23903b705cfSriastradh pDRIInfo->clientDriverName = I810ClientDriverName; 24003b705cfSriastradh if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 24103b705cfSriastradh pDRIInfo->busIdString = DRICreatePCIBusID(pI810->PciInfo); 24203b705cfSriastradh } else { 24303b705cfSriastradh pDRIInfo->busIdString = malloc(64); 24403b705cfSriastradh if (pDRIInfo->busIdString) 24503b705cfSriastradh sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", 24603b705cfSriastradh ((pI810->PciInfo->domain << 8) | pI810->PciInfo->bus), 24703b705cfSriastradh pI810->PciInfo->dev, pI810->PciInfo->func 24803b705cfSriastradh ); 24903b705cfSriastradh } 25003b705cfSriastradh if (!pDRIInfo->busIdString) { 25103b705cfSriastradh DRIDestroyInfoRec(pI810->pDRIInfo); 25203b705cfSriastradh pI810->pDRIInfo = NULL; 25303b705cfSriastradh return FALSE; 25403b705cfSriastradh } 25503b705cfSriastradh pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION; 25603b705cfSriastradh pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION; 25703b705cfSriastradh pDRIInfo->ddxDriverPatchVersion = I810_PATCHLEVEL; 25803b705cfSriastradh pDRIInfo->frameBufferPhysicalAddress = (pointer) pI810->LinearAddr; 25903b705cfSriastradh pDRIInfo->frameBufferSize = (((pScrn->displayWidth * 26003b705cfSriastradh pScrn->virtualY * pI810->cpp) + 26103b705cfSriastradh 4096 - 1) / 4096) * 4096; 26203b705cfSriastradh 26303b705cfSriastradh pDRIInfo->frameBufferStride = pScrn->displayWidth * pI810->cpp; 26403b705cfSriastradh pDRIInfo->ddxDrawableTableEntry = I810_MAX_DRAWABLES; 26503b705cfSriastradh 26603b705cfSriastradh if (SAREA_MAX_DRAWABLES < I810_MAX_DRAWABLES) 26703b705cfSriastradh pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; 26803b705cfSriastradh else 26903b705cfSriastradh pDRIInfo->maxDrawableTableEntry = I810_MAX_DRAWABLES; 27003b705cfSriastradh 27103b705cfSriastradh /* For now the mapping works by using a fixed size defined 27203b705cfSriastradh * in the SAREA header 27303b705cfSriastradh */ 27403b705cfSriastradh if (sizeof(XF86DRISAREARec) + sizeof(I810SAREARec) > SAREA_MAX) { 27503b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 27603b705cfSriastradh "[dri] Data does not fit in SAREA\n"); 27703b705cfSriastradh return FALSE; 27803b705cfSriastradh } 27903b705cfSriastradh pDRIInfo->SAREASize = SAREA_MAX; 28003b705cfSriastradh 28103b705cfSriastradh if (!(pI810DRI = (I810DRIPtr) calloc(sizeof(I810DRIRec), 1))) { 28203b705cfSriastradh DRIDestroyInfoRec(pI810->pDRIInfo); 28303b705cfSriastradh pI810->pDRIInfo = NULL; 28403b705cfSriastradh return FALSE; 28503b705cfSriastradh } 28603b705cfSriastradh pDRIInfo->devPrivate = pI810DRI; 28703b705cfSriastradh pDRIInfo->devPrivateSize = sizeof(I810DRIRec); 28803b705cfSriastradh pDRIInfo->contextSize = sizeof(I810DRIContextRec); 28903b705cfSriastradh 29003b705cfSriastradh pDRIInfo->CreateContext = I810CreateContext; 29103b705cfSriastradh pDRIInfo->DestroyContext = I810DestroyContext; 29203b705cfSriastradh pDRIInfo->SwapContext = I810DRISwapContext; 29303b705cfSriastradh pDRIInfo->InitBuffers = I810DRIInitBuffers; 29403b705cfSriastradh pDRIInfo->MoveBuffers = I810DRIMoveBuffers; 29503b705cfSriastradh pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 29603b705cfSriastradh pDRIInfo->TransitionTo2d = I810DRITransitionTo2d; 29703b705cfSriastradh pDRIInfo->TransitionTo3d = I810DRITransitionTo3d; 29803b705cfSriastradh pDRIInfo->TransitionSingleToMulti3D = I810DRITransitionSingleToMulti3d; 29903b705cfSriastradh pDRIInfo->TransitionMultiToSingle3D = I810DRITransitionMultiToSingle3d; 30003b705cfSriastradh 30103b705cfSriastradh pDRIInfo->createDummyCtx = TRUE; 30203b705cfSriastradh pDRIInfo->createDummyCtxPriv = FALSE; 30303b705cfSriastradh 30403b705cfSriastradh /* This adds the framebuffer as a drm map *before* we have asked agp 30503b705cfSriastradh * to allocate it. Scary stuff, hold on... 30603b705cfSriastradh */ 30703b705cfSriastradh if (!DRIScreenInit(pScreen, pDRIInfo, &pI810->drmSubFD)) { 30803b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 30903b705cfSriastradh "[dri] DRIScreenInit failed. Disabling DRI.\n"); 31003b705cfSriastradh free(pDRIInfo->devPrivate); 31103b705cfSriastradh pDRIInfo->devPrivate = NULL; 31203b705cfSriastradh DRIDestroyInfoRec(pI810->pDRIInfo); 31303b705cfSriastradh pI810->pDRIInfo = NULL; 31403b705cfSriastradh return FALSE; 31503b705cfSriastradh } 31603b705cfSriastradh 31703b705cfSriastradh /* Check the i810 DRM versioning */ 31803b705cfSriastradh { 31903b705cfSriastradh drmVersionPtr version; 32003b705cfSriastradh 32103b705cfSriastradh /* Check the DRM lib version. 32203b705cfSriastradh * drmGetLibVersion was not supported in version 1.0, so check for 32303b705cfSriastradh * symbol first to avoid possible crash or hang. 32403b705cfSriastradh */ 32503b705cfSriastradh if (xf86LoaderCheckSymbol("drmGetLibVersion")) { 32603b705cfSriastradh version = drmGetLibVersion(pI810->drmSubFD); 32703b705cfSriastradh } else 32803b705cfSriastradh { 32903b705cfSriastradh /* drmlib version 1.0.0 didn't have the drmGetLibVersion 33003b705cfSriastradh * entry point. Fake it by allocating a version record 33103b705cfSriastradh * via drmGetVersion and changing it to version 1.0.0 33203b705cfSriastradh */ 33303b705cfSriastradh version = drmGetVersion(pI810->drmSubFD); 33403b705cfSriastradh version->version_major = 1; 33503b705cfSriastradh version->version_minor = 0; 33603b705cfSriastradh version->version_patchlevel = 0; 33703b705cfSriastradh } 33803b705cfSriastradh 33903b705cfSriastradh#define REQ_MAJ 1 34003b705cfSriastradh#define REQ_MIN 1 34103b705cfSriastradh if (version) { 34203b705cfSriastradh if (version->version_major != REQ_MAJ || 34303b705cfSriastradh version->version_minor < REQ_MIN) { 34403b705cfSriastradh /* incompatible drm library version */ 34503b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 34603b705cfSriastradh "[dri] I810DRIScreenInit failed because of a version mismatch.\n" 34703b705cfSriastradh "[dri] libdrm.a module version is %d.%d.%d but version %d.%d.x is needed.\n" 34803b705cfSriastradh "[dri] Disabling DRI.\n", 34903b705cfSriastradh version->version_major, 35003b705cfSriastradh version->version_minor, version->version_patchlevel, 35103b705cfSriastradh REQ_MAJ, REQ_MIN); 35203b705cfSriastradh drmFreeVersion(version); 35303b705cfSriastradh I810DRICloseScreen(pScreen); 35403b705cfSriastradh return FALSE; 35503b705cfSriastradh } 35603b705cfSriastradh drmFreeVersion(version); 35703b705cfSriastradh } 35803b705cfSriastradh 35903b705cfSriastradh /* Check the i810 DRM version */ 36003b705cfSriastradh version = drmGetVersion(pI810->drmSubFD); 36103b705cfSriastradh if (version) { 36203b705cfSriastradh i810_drm_version = (version->version_major<<16) | 36303b705cfSriastradh version->version_minor; 36403b705cfSriastradh if (version->version_major != 1 || version->version_minor < 2) { 36503b705cfSriastradh /* incompatible drm version */ 36603b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 36703b705cfSriastradh "[dri] I810DRIScreenInit failed because of a version mismatch.\n" 36803b705cfSriastradh "[dri] i810.o kernel module version is %d.%d.%d but version 1.2.0 or greater is needed.\n" 36903b705cfSriastradh "[dri] Disabling DRI.\n", 37003b705cfSriastradh version->version_major, 37103b705cfSriastradh version->version_minor, version->version_patchlevel); 37203b705cfSriastradh I810DRICloseScreen(pScreen); 37303b705cfSriastradh drmFreeVersion(version); 37403b705cfSriastradh return FALSE; 37503b705cfSriastradh } 37603b705cfSriastradh pI810->drmMinor = version->version_minor; 37703b705cfSriastradh drmFreeVersion(version); 37803b705cfSriastradh } 37903b705cfSriastradh } 38003b705cfSriastradh 38103b705cfSriastradh pI810DRI->regsSize = I810_REG_SIZE; 38203b705cfSriastradh if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->MMIOAddr, 38303b705cfSriastradh pI810DRI->regsSize, DRM_REGISTERS, 0, 38403b705cfSriastradh (drmAddress) &pI810DRI->regs) < 0) { 38503b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n"); 38603b705cfSriastradh DRICloseScreen(pScreen); 38703b705cfSriastradh return FALSE; 38803b705cfSriastradh } 38903b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", 39003b705cfSriastradh (int)pI810DRI->regs); 39103b705cfSriastradh 39203b705cfSriastradh pI810->backHandle = DRM_AGP_NO_HANDLE; 39303b705cfSriastradh pI810->zHandle = DRM_AGP_NO_HANDLE; 39403b705cfSriastradh pI810->cursorHandle = DRM_AGP_NO_HANDLE; 39503b705cfSriastradh pI810->xvmcHandle = DRM_AGP_NO_HANDLE; 39603b705cfSriastradh pI810->sysmemHandle = DRM_AGP_NO_HANDLE; 39703b705cfSriastradh pI810->agpAcquired = FALSE; 39803b705cfSriastradh pI810->dcacheHandle = DRM_AGP_NO_HANDLE; 39903b705cfSriastradh 40003b705cfSriastradh /* Agp Support - Need this just to get the framebuffer. 40103b705cfSriastradh */ 40203b705cfSriastradh if (drmAgpAcquire(pI810->drmSubFD) < 0) { 40303b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpAquire failed\n"); 40403b705cfSriastradh DRICloseScreen(pScreen); 40503b705cfSriastradh return FALSE; 40603b705cfSriastradh } 40703b705cfSriastradh pI810->agpAcquired = TRUE; 40803b705cfSriastradh 40903b705cfSriastradh if (drmAgpEnable(pI810->drmSubFD, 0) < 0) { 41003b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpEnable failed\n"); 41103b705cfSriastradh DRICloseScreen(pScreen); 41203b705cfSriastradh return FALSE; 41303b705cfSriastradh } 41403b705cfSriastradh 41503b705cfSriastradh memset(&pI810->DcacheMem, 0, sizeof(I810MemRange)); 41603b705cfSriastradh memset(&pI810->BackBuffer, 0, sizeof(I810MemRange)); 41703b705cfSriastradh memset(&pI810->DepthBuffer, 0, sizeof(I810MemRange)); 41803b705cfSriastradh pI810->CursorPhysical = 0; 41903b705cfSriastradh pI810->CursorARGBPhysical = 0; 42003b705cfSriastradh 42103b705cfSriastradh /* Dcache - half the speed of normal ram, but has use as a Z buffer 42203b705cfSriastradh * under the DRI. 42303b705cfSriastradh */ 42403b705cfSriastradh 42503b705cfSriastradh drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, 42603b705cfSriastradh (drmAddress) &dcacheHandle); 42703b705cfSriastradh pI810->dcacheHandle = dcacheHandle; 42803b705cfSriastradh 42903b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] dcacheHandle : 0x%x\n", 43003b705cfSriastradh (int)dcacheHandle); 43103b705cfSriastradh 43203b705cfSriastradh sysmem_size = pScrn->videoRam * 1024; 43303b705cfSriastradh if (dcacheHandle != DRM_AGP_NO_HANDLE) { 43403b705cfSriastradh if (back_size > 4 * 1024 * 1024) { 43503b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_INFO, 43603b705cfSriastradh "[dri] Backsize is larger then 4 meg\n"); 43703b705cfSriastradh sysmem_size = sysmem_size - 2 * back_size; 43803b705cfSriastradh drmAgpFree(pI810->drmSubFD, dcacheHandle); 43903b705cfSriastradh pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; 44003b705cfSriastradh } else { 44103b705cfSriastradh sysmem_size = sysmem_size - back_size; 44203b705cfSriastradh } 44303b705cfSriastradh } else { 44403b705cfSriastradh sysmem_size = sysmem_size - 2 * back_size; 44503b705cfSriastradh } 44603b705cfSriastradh 44703b705cfSriastradh /* Max size is 48 without XvMC, 41 with 6 surfaces, 40 with 7 surfaces */ 44803b705cfSriastradh if (pI810->numSurfaces && (pI810->numSurfaces == 6)) { 44903b705cfSriastradh if (sysmem_size > (pI810->FbMapSize - 7 * 1024 * 1024)) { 45003b705cfSriastradh sysmem_size = (pI810->FbMapSize - 7 * 1024 * 1024); 45103b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 45203b705cfSriastradh "User requested more memory then fits in the agp aperture\n" 45303b705cfSriastradh "Truncating to %d bytes of memory\n", sysmem_size); 45403b705cfSriastradh } 45503b705cfSriastradh } 45603b705cfSriastradh if (pI810->numSurfaces && (pI810->numSurfaces == 7)) { 45703b705cfSriastradh if (sysmem_size > (pI810->FbMapSize - 8 * 1024 * 1024)) { 45803b705cfSriastradh sysmem_size = (pI810->FbMapSize - 8 * 1024 * 1024); 45903b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 46003b705cfSriastradh "User requested more memory then fits in the agp aperture\n" 46103b705cfSriastradh "Truncating to %d bytes of memory\n", sysmem_size); 46203b705cfSriastradh } 46303b705cfSriastradh } 46403b705cfSriastradh 46503b705cfSriastradh if (sysmem_size > pI810->FbMapSize) { 46603b705cfSriastradh sysmem_size = pI810->FbMapSize; 46703b705cfSriastradh 46803b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 46903b705cfSriastradh "[dri] User requested more memory then fits in the agp" 47003b705cfSriastradh " aperture\n\tTruncating to %d bytes of memory\n", 47103b705cfSriastradh sysmem_size); 47203b705cfSriastradh } 47303b705cfSriastradh 47403b705cfSriastradh sysmem_size -= 4096; /* remove 4k for the hw cursor */ 47503b705cfSriastradh sysmem_size -= 16384; /* remove 16k for the ARGB hw cursor */ 47603b705cfSriastradh 47703b705cfSriastradh pI810->SysMem.Start = 0; 47803b705cfSriastradh pI810->SysMem.Size = sysmem_size; 47903b705cfSriastradh pI810->SysMem.End = sysmem_size; 48003b705cfSriastradh tom = sysmem_size; 48103b705cfSriastradh 48203b705cfSriastradh pI810->SavedSysMem = pI810->SysMem; 48303b705cfSriastradh 48403b705cfSriastradh if (dcacheHandle != DRM_AGP_NO_HANDLE) { 48503b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, dcacheHandle, pI810->DepthOffset) == 0) { 48603b705cfSriastradh memset(&pI810->DcacheMem, 0, sizeof(I810MemRange)); 48703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 48803b705cfSriastradh "[agp] GART: Found 4096K Z buffer memory\n"); 48903b705cfSriastradh pI810->DcacheMem.Start = pI810->DepthOffset; 49003b705cfSriastradh pI810->DcacheMem.Size = 1024 * 4096; 49103b705cfSriastradh pI810->DcacheMem.End = 49203b705cfSriastradh pI810->DcacheMem.Start + pI810->DcacheMem.Size; 49303b705cfSriastradh if (!I810AllocLow 49403b705cfSriastradh (&(pI810->DepthBuffer), &(pI810->DcacheMem), back_size)) { 49503b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 49603b705cfSriastradh "[agp] Depth buffer allocation failed\n"); 49703b705cfSriastradh DRICloseScreen(pScreen); 49803b705cfSriastradh return FALSE; 49903b705cfSriastradh } 50003b705cfSriastradh } else { 50103b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 50203b705cfSriastradh "[agp] GART: dcache bind failed\n"); 50303b705cfSriastradh drmAgpFree(pI810->drmSubFD, dcacheHandle); 50403b705cfSriastradh pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; 50503b705cfSriastradh } 50603b705cfSriastradh } else { 50703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 50803b705cfSriastradh "[agp] GART: no dcache memory found\n"); 50903b705cfSriastradh } 51003b705cfSriastradh 51103b705cfSriastradh drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, 51203b705cfSriastradh (drmAddress) &agpHandle); 51303b705cfSriastradh pI810->backHandle = agpHandle; 51403b705cfSriastradh 51503b705cfSriastradh if (agpHandle != DRM_AGP_NO_HANDLE) { 51603b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->BackOffset) == 0) { 51703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 51803b705cfSriastradh "[agp] Bound backbuffer memory\n"); 51903b705cfSriastradh 52003b705cfSriastradh pI810->BackBuffer.Start = pI810->BackOffset; 52103b705cfSriastradh pI810->BackBuffer.Size = back_size; 52203b705cfSriastradh pI810->BackBuffer.End = (pI810->BackBuffer.Start + 52303b705cfSriastradh pI810->BackBuffer.Size); 52403b705cfSriastradh } else { 52503b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 52603b705cfSriastradh "[agp] Unable to bind backbuffer. Disabling DRI.\n"); 52703b705cfSriastradh DRICloseScreen(pScreen); 52803b705cfSriastradh return FALSE; 52903b705cfSriastradh } 53003b705cfSriastradh } else { 53103b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 53203b705cfSriastradh "[dri] Unable to allocate backbuffer memory. Disabling DRI.\n"); 53303b705cfSriastradh DRICloseScreen(pScreen); 53403b705cfSriastradh return FALSE; 53503b705cfSriastradh } 53603b705cfSriastradh 53703b705cfSriastradh if (dcacheHandle == DRM_AGP_NO_HANDLE) { 53803b705cfSriastradh drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, 53903b705cfSriastradh (drmAddress) &agpHandle); 54003b705cfSriastradh 54103b705cfSriastradh pI810->zHandle = agpHandle; 54203b705cfSriastradh 54303b705cfSriastradh if (agpHandle != DRM_AGP_NO_HANDLE) { 54403b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->DepthOffset) == 0) { 54503b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 54603b705cfSriastradh "[agp] Bound depthbuffer memory\n"); 54703b705cfSriastradh pI810->DepthBuffer.Start = pI810->DepthOffset; 54803b705cfSriastradh pI810->DepthBuffer.Size = back_size; 54903b705cfSriastradh pI810->DepthBuffer.End = (pI810->DepthBuffer.Start + 55003b705cfSriastradh pI810->DepthBuffer.Size); 55103b705cfSriastradh } else { 55203b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 55303b705cfSriastradh "[agp] Unable to bind depthbuffer. Disabling DRI.\n"); 55403b705cfSriastradh DRICloseScreen(pScreen); 55503b705cfSriastradh return FALSE; 55603b705cfSriastradh } 55703b705cfSriastradh } else { 55803b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 55903b705cfSriastradh "[agp] Unable to allocate depthbuffer memory. Disabling DRI.\n"); 56003b705cfSriastradh DRICloseScreen(pScreen); 56103b705cfSriastradh return FALSE; 56203b705cfSriastradh } 56303b705cfSriastradh } 56403b705cfSriastradh 56503b705cfSriastradh /* Now allocate and bind the agp space. This memory will include the 56603b705cfSriastradh * regular framebuffer as well as texture memory. 56703b705cfSriastradh */ 56803b705cfSriastradh drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, 56903b705cfSriastradh (drmAddress)&agpHandle); 57003b705cfSriastradh pI810->sysmemHandle = agpHandle; 57103b705cfSriastradh 57203b705cfSriastradh if (agpHandle != DRM_AGP_NO_HANDLE) { 57303b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, agpHandle, 0) == 0) { 57403b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 57503b705cfSriastradh "[agp] Bound System Texture Memory\n"); 57603b705cfSriastradh } else { 57703b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to bind system texture memory. Disabling DRI.\n"); 57803b705cfSriastradh DRICloseScreen(pScreen); 57903b705cfSriastradh return FALSE; 58003b705cfSriastradh } 58103b705cfSriastradh } else { 58203b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to allocate system texture memory. Disabling DRI.\n"); 58303b705cfSriastradh DRICloseScreen(pScreen); 58403b705cfSriastradh return FALSE; 58503b705cfSriastradh } 58603b705cfSriastradh 58703b705cfSriastradh/* Allocate 7 or 8MB for XvMC this is setup as follows to best use tiled 58803b705cfSriastradh regions and required surface pitches. (Numbers are adjusted if the 58903b705cfSriastradh AGP region is only 32MB 59003b705cfSriastradh For numSurfaces == 6 59103b705cfSriastradh 44 - 48MB = 4MB Fence, 8 Tiles wide 59203b705cfSriastradh 43 - 44MB = 1MB Fence, 8 Tiles wide 59303b705cfSriastradh 42 - 43MB = 1MB Fence, 4 Tiles wide 59403b705cfSriastradh 41 - 42MB = 1MB Fence, 4 Tiles wide 59503b705cfSriastradh For numSurfaces == 7 59603b705cfSriastradh 44 - 48MB = 4MB Fence, 8 Tiles wide 59703b705cfSriastradh 43 - 44MB = 1MB Fence, 8 Tiles wide 59803b705cfSriastradh 42.5 - 43MB = 0.5MB Fence, 8 Tiles wide 59903b705cfSriastradh 42 - 42.5MB = 0.5MB Fence, 4 Tiles wide 60003b705cfSriastradh 40 - 42MB = 2MB Fence, 4 Tiles wide 60103b705cfSriastradh */ 60203b705cfSriastradh if (pI810->numSurfaces) { 60303b705cfSriastradh if (pI810->numSurfaces == 6) { 60403b705cfSriastradh pI810->MC.Size = 7 * 1024 * 1024; 60503b705cfSriastradh pI810->MC.Start = pI810->FbMapSize - 7 * 1024 * 1024; 60603b705cfSriastradh 60703b705cfSriastradh } 60803b705cfSriastradh if (pI810->numSurfaces == 7) { 60903b705cfSriastradh pI810->MC.Size = 8 * 1024 * 1024; 61003b705cfSriastradh pI810->MC.Start = pI810->FbMapSize - 8 * 1024 * 1024; 61103b705cfSriastradh } 61203b705cfSriastradh drmAgpAlloc(pI810->drmSubFD, pI810->MC.Size, 0, NULL, 61303b705cfSriastradh (drmAddress) &agpHandle); 61403b705cfSriastradh 61503b705cfSriastradh pI810->xvmcHandle = agpHandle; 61603b705cfSriastradh 61703b705cfSriastradh if (agpHandle != DRM_AGP_NO_HANDLE) { 61803b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->MC.Start) == 0) { 61903b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 62003b705cfSriastradh "GART: Allocated 7MB for HWMC\n"); 62103b705cfSriastradh pI810->MC.End = pI810->MC.Start + pI810->MC.Size; 62203b705cfSriastradh } else { 62303b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC bind failed\n"); 62403b705cfSriastradh pI810->MC.Start = 0; 62503b705cfSriastradh pI810->MC.Size = 0; 62603b705cfSriastradh pI810->MC.End = 0; 62703b705cfSriastradh } 62803b705cfSriastradh } else { 62903b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC alloc failed\n"); 63003b705cfSriastradh pI810->MC.Start = 0; 63103b705cfSriastradh pI810->MC.Size = 0; 63203b705cfSriastradh pI810->MC.End = 0; 63303b705cfSriastradh } 63403b705cfSriastradh pI810->xvmcContext = 0; 63503b705cfSriastradh } 63603b705cfSriastradh 63703b705cfSriastradh drmAgpAlloc(pI810->drmSubFD, 4096, 2, 63803b705cfSriastradh (unsigned long *)&pI810->CursorPhysical, 63903b705cfSriastradh (drmAddress) &agpHandle); 64003b705cfSriastradh 64103b705cfSriastradh pI810->cursorHandle = agpHandle; 64203b705cfSriastradh 64303b705cfSriastradh if (agpHandle != DRM_AGP_NO_HANDLE) { 64403b705cfSriastradh tom = sysmem_size; 64503b705cfSriastradh 64603b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) { 64703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 64803b705cfSriastradh "[agp] GART: Allocated 4K for mouse cursor image\n"); 64903b705cfSriastradh pI810->CursorStart = tom; 65003b705cfSriastradh tom += 4096; 65103b705cfSriastradh } else { 65203b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 65303b705cfSriastradh "[agp] GART: cursor bind failed\n"); 65403b705cfSriastradh pI810->CursorPhysical = 0; 65503b705cfSriastradh } 65603b705cfSriastradh } else { 65703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 65803b705cfSriastradh "[agp] GART: cursor alloc failed\n"); 65903b705cfSriastradh pI810->CursorPhysical = 0; 66003b705cfSriastradh } 66103b705cfSriastradh 66203b705cfSriastradh drmAgpAlloc(pI810->drmSubFD, 16384, 2, 66303b705cfSriastradh (unsigned long *)&pI810->CursorARGBPhysical, 66403b705cfSriastradh (drmAddress) &agpHandle); 66503b705cfSriastradh 66603b705cfSriastradh pI810->cursorARGBHandle = agpHandle; 66703b705cfSriastradh 66803b705cfSriastradh if (agpHandle != DRM_AGP_NO_HANDLE) { 66903b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) { 67003b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 67103b705cfSriastradh "[agp] GART: Allocated 16K for ARGB mouse cursor image\n"); 67203b705cfSriastradh pI810->CursorARGBStart = tom; 67303b705cfSriastradh tom += 16384; 67403b705cfSriastradh } else { 67503b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 67603b705cfSriastradh "[agp] GART: ARGB cursor bind failed\n"); 67703b705cfSriastradh pI810->CursorARGBPhysical = 0; 67803b705cfSriastradh } 67903b705cfSriastradh } else { 68003b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 68103b705cfSriastradh "[agp] GART: ARGB cursor alloc failed\n"); 68203b705cfSriastradh pI810->CursorARGBPhysical = 0; 68303b705cfSriastradh } 68403b705cfSriastradh 68503b705cfSriastradh /* Steal some of the excess cursor space for the overlay regs. 68603b705cfSriastradh */ 68703b705cfSriastradh pI810->OverlayPhysical = pI810->CursorPhysical + 1024; 68803b705cfSriastradh pI810->OverlayStart = pI810->CursorStart + 1024; 68903b705cfSriastradh 69003b705cfSriastradh I810SetTiledMemory(pScrn, 1, 69103b705cfSriastradh pI810->DepthBuffer.Start, 69203b705cfSriastradh i810_pitches[pitch_idx], 8 * 1024 * 1024); 69303b705cfSriastradh 69403b705cfSriastradh I810SetTiledMemory(pScrn, 2, 69503b705cfSriastradh pI810->BackBuffer.Start, 69603b705cfSriastradh i810_pitches[pitch_idx], 8 * 1024 * 1024); 69703b705cfSriastradh 69803b705cfSriastradh /* These are for HWMC surfaces */ 69903b705cfSriastradh if (pI810->numSurfaces == 6) { 70003b705cfSriastradh I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 1024 * 1024); 70103b705cfSriastradh 70203b705cfSriastradh I810SetTiledMemory(pScrn, 4, 70303b705cfSriastradh pI810->MC.Start + 1024 * 1024, 512, 1024 * 1024); 70403b705cfSriastradh 70503b705cfSriastradh I810SetTiledMemory(pScrn, 5, 70603b705cfSriastradh pI810->MC.Start + 1024 * 1024 * 2, 70703b705cfSriastradh 1024, 1024 * 1024); 70803b705cfSriastradh 70903b705cfSriastradh I810SetTiledMemory(pScrn, 6, 71003b705cfSriastradh pI810->MC.Start + 1024 * 1024 * 3, 71103b705cfSriastradh 1024, 4 * 1024 * 1024); 71203b705cfSriastradh } 71303b705cfSriastradh if (pI810->numSurfaces == 7) { 71403b705cfSriastradh I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 2 * 1024 * 1024); 71503b705cfSriastradh 71603b705cfSriastradh I810SetTiledMemory(pScrn, 4, 71703b705cfSriastradh pI810->MC.Start + 2 * 1024 * 1024, 512, 512 * 1024); 71803b705cfSriastradh 71903b705cfSriastradh I810SetTiledMemory(pScrn, 5, 72003b705cfSriastradh pI810->MC.Start + 2 * 1024 * 1024 + 512 * 1024, 72103b705cfSriastradh 1024, 512 * 1024); 72203b705cfSriastradh 72303b705cfSriastradh I810SetTiledMemory(pScrn, 6, 72403b705cfSriastradh pI810->MC.Start + 3 * 1024 * 1024, 72503b705cfSriastradh 1024, 1 * 1024 * 1024); 72603b705cfSriastradh 72703b705cfSriastradh I810SetTiledMemory(pScrn, 7, 72803b705cfSriastradh pI810->MC.Start + 4 * 1024 * 1024, 72903b705cfSriastradh 1024, 4 * 1024 * 1024); 73003b705cfSriastradh 73103b705cfSriastradh } 73203b705cfSriastradh 73303b705cfSriastradh pI810->auxPitch = i810_pitches[pitch_idx]; 73403b705cfSriastradh pI810->auxPitchBits = i810_pitch_flags[pitch_idx]; 73503b705cfSriastradh pI810->SavedDcacheMem = pI810->DcacheMem; 73603b705cfSriastradh pI810DRI->backbufferSize = pI810->BackBuffer.Size; 73703b705cfSriastradh 73803b705cfSriastradh if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BackBuffer.Start, 73903b705cfSriastradh pI810->BackBuffer.Size, DRM_AGP, 0, 74003b705cfSriastradh (drmAddress) &pI810DRI->backbuffer) < 0) { 74103b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 74203b705cfSriastradh "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n"); 74303b705cfSriastradh DRICloseScreen(pScreen); 74403b705cfSriastradh return FALSE; 74503b705cfSriastradh } 74603b705cfSriastradh 74703b705cfSriastradh pI810DRI->depthbufferSize = pI810->DepthBuffer.Size; 74803b705cfSriastradh if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->DepthBuffer.Start, 74903b705cfSriastradh pI810->DepthBuffer.Size, DRM_AGP, 0, 75003b705cfSriastradh (drmAddress) &pI810DRI->depthbuffer) < 0) { 75103b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 75203b705cfSriastradh "[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n"); 75303b705cfSriastradh DRICloseScreen(pScreen); 75403b705cfSriastradh return FALSE; 75503b705cfSriastradh } 75603b705cfSriastradh 75703b705cfSriastradh /* Allocate FrontBuffer etc. */ 75803b705cfSriastradh if (!I810AllocateFront(pScrn)) { 75903b705cfSriastradh DRICloseScreen(pScreen); 76003b705cfSriastradh return FALSE; 76103b705cfSriastradh } 76203b705cfSriastradh 76303b705cfSriastradh /* Allocate buffer memory */ 76403b705cfSriastradh I810AllocHigh(&(pI810->BufferMem), &(pI810->SysMem), 76503b705cfSriastradh I810_DMA_BUF_NR * I810_DMA_BUF_SZ); 76603b705cfSriastradh 76703b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] Buffer map : %lx\n", 76803b705cfSriastradh pI810->BufferMem.Start); 76903b705cfSriastradh 77003b705cfSriastradh if (pI810->BufferMem.Start == 0 || 77103b705cfSriastradh pI810->BufferMem.End - pI810->BufferMem.Start > 77203b705cfSriastradh I810_DMA_BUF_NR * I810_DMA_BUF_SZ) { 77303b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 77403b705cfSriastradh "[dri] Not enough memory for dma buffers. Disabling DRI.\n"); 77503b705cfSriastradh DRICloseScreen(pScreen); 77603b705cfSriastradh return FALSE; 77703b705cfSriastradh } 77803b705cfSriastradh if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BufferMem.Start, 77903b705cfSriastradh pI810->BufferMem.Size, DRM_AGP, 0, 78003b705cfSriastradh (drmAddress) &pI810->buffer_map) < 0) { 78103b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 78203b705cfSriastradh "[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n"); 78303b705cfSriastradh DRICloseScreen(pScreen); 78403b705cfSriastradh return FALSE; 78503b705cfSriastradh } 78603b705cfSriastradh 78703b705cfSriastradh pI810DRI->agp_buffers = pI810->buffer_map; 78803b705cfSriastradh pI810DRI->agp_buf_size = pI810->BufferMem.Size; 78903b705cfSriastradh 79003b705cfSriastradh if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing->mem.Start, 79103b705cfSriastradh pI810->LpRing->mem.Size, DRM_AGP, 0, 79203b705cfSriastradh (drmAddress) &pI810->ring_map) < 0) { 79303b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 79403b705cfSriastradh "[drm] drmAddMap(ring_map) failed. Disabling DRI.\n"); 79503b705cfSriastradh DRICloseScreen(pScreen); 79603b705cfSriastradh return FALSE; 79703b705cfSriastradh } 79803b705cfSriastradh 79903b705cfSriastradh /* Use the rest of memory for textures. */ 80003b705cfSriastradh pI810DRI->textureSize = pI810->SysMem.Size; 80103b705cfSriastradh 80203b705cfSriastradh i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS); 80303b705cfSriastradh 80403b705cfSriastradh if (i < I810_LOG_MIN_TEX_REGION_SIZE) 80503b705cfSriastradh i = I810_LOG_MIN_TEX_REGION_SIZE; 80603b705cfSriastradh 80703b705cfSriastradh pI810DRI->logTextureGranularity = i; 80803b705cfSriastradh pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i; /* truncate */ 80903b705cfSriastradh 81003b705cfSriastradh if (pI810DRI->textureSize < 512 * 1024) { 81103b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 81203b705cfSriastradh "[drm] Less then 512k memory left for textures. Disabling DRI.\n"); 81303b705cfSriastradh DRICloseScreen(pScreen); 81403b705cfSriastradh return FALSE; 81503b705cfSriastradh } 81603b705cfSriastradh 81703b705cfSriastradh if (!I810AllocLow(&(pI810->TexMem), &(pI810->SysMem), pI810DRI->textureSize)) { 81803b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 81903b705cfSriastradh "[agp] Texure memory allocation failed\n"); 82003b705cfSriastradh DRICloseScreen(pScreen); 82103b705cfSriastradh return FALSE; 82203b705cfSriastradh } 82303b705cfSriastradh 82403b705cfSriastradh if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->TexMem.Start, 82503b705cfSriastradh pI810->TexMem.Size, DRM_AGP, 0, 82603b705cfSriastradh (drmAddress) &pI810DRI->textures) < 0) { 82703b705cfSriastradh xf86DrvMsg(pScreen->myNum, X_ERROR, 82803b705cfSriastradh "[drm] drmAddMap(textures) failed. Disabling DRI.\n"); 82903b705cfSriastradh DRICloseScreen(pScreen); 83003b705cfSriastradh return FALSE; 83103b705cfSriastradh } 83203b705cfSriastradh 83303b705cfSriastradh if ((bufs = drmAddBufs(pI810->drmSubFD, 83403b705cfSriastradh I810_DMA_BUF_NR, 83503b705cfSriastradh I810_DMA_BUF_SZ, 83603b705cfSriastradh DRM_AGP_BUFFER, pI810->BufferMem.Start)) <= 0) { 83703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 83803b705cfSriastradh "[drm] failure adding %d %d byte DMA buffers. Disabling DRI.\n", 83903b705cfSriastradh I810_DMA_BUF_NR, I810_DMA_BUF_SZ); 84003b705cfSriastradh DRICloseScreen(pScreen); 84103b705cfSriastradh return FALSE; 84203b705cfSriastradh } 84303b705cfSriastradh 84403b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 84503b705cfSriastradh "[drm] added %d %d byte DMA buffers\n", bufs, I810_DMA_BUF_SZ); 84603b705cfSriastradh 84703b705cfSriastradh I810InitDma(pScrn); 84803b705cfSriastradh 84903b705cfSriastradh /* Okay now initialize the dma engine */ 85003b705cfSriastradh 85103b705cfSriastradh if (!pI810DRI->irq) { 85203b705cfSriastradh pI810DRI->irq = drmGetInterruptFromBusID(pI810->drmSubFD, 85303b705cfSriastradh ((pI810->PciInfo->domain << 8) | 85403b705cfSriastradh pI810->PciInfo->bus), 85503b705cfSriastradh pI810->PciInfo->dev, 85603b705cfSriastradh pI810->PciInfo->func 85703b705cfSriastradh ); 85803b705cfSriastradh if ((drmCtlInstHandler(pI810->drmSubFD, pI810DRI->irq)) != 0) { 85903b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 86003b705cfSriastradh "[drm] failure adding irq handler, there is a device " 86103b705cfSriastradh "already using that irq\n Consider rearranging your " 86203b705cfSriastradh "PCI cards. Disabling DRI.\n"); 86303b705cfSriastradh DRICloseScreen(pScreen); 86403b705cfSriastradh return FALSE; 86503b705cfSriastradh } 86603b705cfSriastradh } 86703b705cfSriastradh 86803b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 86903b705cfSriastradh "[drm] dma control initialized, using IRQ %d\n", pI810DRI->irq); 87003b705cfSriastradh 87103b705cfSriastradh pI810DRI->deviceID = pI810->PciInfo->device_id; 87203b705cfSriastradh pI810DRI->width = pScrn->virtualX; 87303b705cfSriastradh pI810DRI->height = pScrn->virtualY; 87403b705cfSriastradh pI810DRI->mem = pScrn->videoRam * 1024; 87503b705cfSriastradh pI810DRI->cpp = pI810->cpp; 87603b705cfSriastradh 87703b705cfSriastradh pI810DRI->fbOffset = pI810->FrontBuffer.Start; 87803b705cfSriastradh pI810DRI->fbStride = pI810->auxPitch; 87903b705cfSriastradh 88003b705cfSriastradh pI810DRI->bitsPerPixel = pScrn->bitsPerPixel; 88103b705cfSriastradh 88203b705cfSriastradh pI810DRI->textureOffset = pI810->TexMem.Start; 88303b705cfSriastradh 88403b705cfSriastradh pI810DRI->backOffset = pI810->BackBuffer.Start; 88503b705cfSriastradh pI810DRI->depthOffset = pI810->DepthBuffer.Start; 88603b705cfSriastradh 88703b705cfSriastradh pI810DRI->ringOffset = pI810->LpRing->mem.Start; 88803b705cfSriastradh pI810DRI->ringSize = pI810->LpRing->mem.Size; 88903b705cfSriastradh 89003b705cfSriastradh pI810DRI->auxPitch = pI810->auxPitch; 89103b705cfSriastradh pI810DRI->auxPitchBits = pI810->auxPitchBits; 89203b705cfSriastradh pI810DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); 89303b705cfSriastradh 89403b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_INFO, 89503b705cfSriastradh "[dri] visual configs initialized.\n"); 89603b705cfSriastradh pI810->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; 89703b705cfSriastradh 89803b705cfSriastradh return TRUE; 89903b705cfSriastradh} 90003b705cfSriastradh 90103b705cfSriastradhvoid 90203b705cfSriastradhI810DRICloseScreen(ScreenPtr pScreen) 90303b705cfSriastradh{ 90403b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 90503b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 90603b705cfSriastradh 90703b705cfSriastradh if (pI810->pDRIInfo) { 90803b705cfSriastradh I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate; 90903b705cfSriastradh 91003b705cfSriastradh if (pI810DRI) { 91103b705cfSriastradh if (pI810DRI->irq) { 91203b705cfSriastradh drmCtlUninstHandler(pI810->drmSubFD); 91303b705cfSriastradh pI810DRI->irq = 0; 91403b705cfSriastradh } 91503b705cfSriastradh 91603b705cfSriastradh free(pI810->pDRIInfo->devPrivate); 91703b705cfSriastradh pI810->pDRIInfo->devPrivate = NULL; 91803b705cfSriastradh } 91903b705cfSriastradh 92003b705cfSriastradh I810CleanupDma(pScrn); 92103b705cfSriastradh 92203b705cfSriastradh DRICloseScreen(pScreen); 92303b705cfSriastradh DRIDestroyInfoRec(pI810->pDRIInfo); 92403b705cfSriastradh pI810->pDRIInfo = NULL; 92503b705cfSriastradh } 92603b705cfSriastradh 92703b705cfSriastradh if (pI810->dcacheHandle!=DRM_AGP_NO_HANDLE) 92803b705cfSriastradh drmAgpFree(pI810->drmSubFD, pI810->dcacheHandle); 92903b705cfSriastradh if (pI810->backHandle!=DRM_AGP_NO_HANDLE) 93003b705cfSriastradh drmAgpFree(pI810->drmSubFD, pI810->backHandle); 93103b705cfSriastradh if (pI810->zHandle!=DRM_AGP_NO_HANDLE) 93203b705cfSriastradh drmAgpFree(pI810->drmSubFD, pI810->zHandle); 93303b705cfSriastradh if (pI810->cursorHandle!=DRM_AGP_NO_HANDLE) 93403b705cfSriastradh drmAgpFree(pI810->drmSubFD, pI810->cursorHandle); 93503b705cfSriastradh if (pI810->xvmcHandle!=DRM_AGP_NO_HANDLE) 93603b705cfSriastradh drmAgpFree(pI810->drmSubFD, pI810->xvmcHandle); 93703b705cfSriastradh if (pI810->sysmemHandle!=DRM_AGP_NO_HANDLE) 93803b705cfSriastradh drmAgpFree(pI810->drmSubFD, pI810->sysmemHandle); 93903b705cfSriastradh 94003b705cfSriastradh if (pI810->agpAcquired == TRUE) 94103b705cfSriastradh drmAgpRelease(pI810->drmSubFD); 94203b705cfSriastradh 94303b705cfSriastradh pI810->backHandle = DRM_AGP_NO_HANDLE; 94403b705cfSriastradh pI810->zHandle = DRM_AGP_NO_HANDLE; 94503b705cfSriastradh pI810->cursorHandle = DRM_AGP_NO_HANDLE; 94603b705cfSriastradh pI810->xvmcHandle = DRM_AGP_NO_HANDLE; 94703b705cfSriastradh pI810->sysmemHandle = DRM_AGP_NO_HANDLE; 94803b705cfSriastradh pI810->agpAcquired = FALSE; 94903b705cfSriastradh pI810->dcacheHandle = DRM_AGP_NO_HANDLE; 95003b705cfSriastradh} 95103b705cfSriastradh 95203b705cfSriastradhstatic Bool 95303b705cfSriastradhI810CreateContext(ScreenPtr pScreen, VisualPtr visual, 95403b705cfSriastradh drm_context_t hwContext, void *pVisualConfigPriv, 95503b705cfSriastradh DRIContextType contextStore) 95603b705cfSriastradh{ 95703b705cfSriastradh return TRUE; 95803b705cfSriastradh} 95903b705cfSriastradh 96003b705cfSriastradhstatic void 96103b705cfSriastradhI810DestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 96203b705cfSriastradh DRIContextType contextStore) 96303b705cfSriastradh{ 96403b705cfSriastradh} 96503b705cfSriastradh 96603b705cfSriastradhBool 96703b705cfSriastradhI810DRIFinishScreenInit(ScreenPtr pScreen) 96803b705cfSriastradh{ 96903b705cfSriastradh I810SAREARec *sPriv = (I810SAREARec *) DRIGetSAREAPrivate(pScreen); 97003b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 97103b705cfSriastradh I810Ptr info = I810PTR(pScrn); 97203b705cfSriastradh 97303b705cfSriastradh memset(sPriv, 0, sizeof(*sPriv)); 97403b705cfSriastradh 97503b705cfSriastradh /* Have shadow run only while there is 3d active. 97603b705cfSriastradh */ 97703b705cfSriastradh if (info->allowPageFlip && info->drmMinor >= 3) { 97803b705cfSriastradh ShadowFBInit( pScreen, I810DRIRefreshArea ); 97903b705cfSriastradh } 98003b705cfSriastradh else 98103b705cfSriastradh info->allowPageFlip = 0; 98203b705cfSriastradh return DRIFinishScreenInit(pScreen); 98303b705cfSriastradh} 98403b705cfSriastradh 98503b705cfSriastradhvoid 98603b705cfSriastradhI810DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 98703b705cfSriastradh DRIContextType oldContextType, void *oldContext, 98803b705cfSriastradh DRIContextType newContextType, void *newContext) 98903b705cfSriastradh{ 99003b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 99103b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 99203b705cfSriastradh 99303b705cfSriastradh if (syncType == DRI_3D_SYNC && 99403b705cfSriastradh oldContextType == DRI_2D_CONTEXT && newContextType == DRI_2D_CONTEXT) { 99503b705cfSriastradh if (I810_DEBUG & DEBUG_VERBOSE_DRI) 99603b705cfSriastradh ErrorF("I810DRISwapContext (in)\n"); 99703b705cfSriastradh 99803b705cfSriastradh if (!pScrn->vtSema) 99903b705cfSriastradh return; 100003b705cfSriastradh pI810->LockHeld = 1; 100103b705cfSriastradh I810RefreshRing(pScrn); 100203b705cfSriastradh } else if (syncType == DRI_2D_SYNC && 100303b705cfSriastradh oldContextType == DRI_NO_CONTEXT && 100403b705cfSriastradh newContextType == DRI_2D_CONTEXT) { 100503b705cfSriastradh pI810->LockHeld = 0; 100603b705cfSriastradh if (I810_DEBUG & DEBUG_VERBOSE_DRI) 100703b705cfSriastradh ErrorF("I810DRISwapContext (out)\n"); 100803b705cfSriastradh } else if (I810_DEBUG & DEBUG_VERBOSE_DRI) 100903b705cfSriastradh ErrorF("I810DRISwapContext (other)\n"); 101003b705cfSriastradh} 101103b705cfSriastradh 101203b705cfSriastradhstatic void 101303b705cfSriastradhI810DRISetNeedSync(ScrnInfoPtr pScrn) 101403b705cfSriastradh{ 101503b705cfSriastradh#ifdef HAVE_XAA_H 101603b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 101703b705cfSriastradh if (pI810->AccelInfoRec) 101803b705cfSriastradh pI810->AccelInfoRec->NeedToSync = TRUE; 101903b705cfSriastradh#endif 102003b705cfSriastradh} 102103b705cfSriastradh 102203b705cfSriastradhstatic void 102303b705cfSriastradhI810DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) 102403b705cfSriastradh{ 102503b705cfSriastradh ScreenPtr pScreen = pWin->drawable.pScreen; 102603b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 102703b705cfSriastradh BoxPtr pbox = REGION_RECTS(prgn); 102803b705cfSriastradh int nbox = REGION_NUM_RECTS(prgn); 102903b705cfSriastradh 103003b705cfSriastradh if (I810_DEBUG & DEBUG_VERBOSE_DRI) 103103b705cfSriastradh ErrorF("I810DRIInitBuffers\n"); 103203b705cfSriastradh 103303b705cfSriastradh I810SetupForSolidFill(pScrn, 0, GXcopy, -1); 103403b705cfSriastradh while (nbox--) { 103503b705cfSriastradh I810SelectBuffer(pScrn, I810_SELECT_BACK); 103603b705cfSriastradh I810SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, 103703b705cfSriastradh pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 103803b705cfSriastradh pbox++; 103903b705cfSriastradh } 104003b705cfSriastradh 104103b705cfSriastradh /* Clear the depth buffer - uses 0xffff rather than 0. 104203b705cfSriastradh */ 104303b705cfSriastradh pbox = REGION_RECTS(prgn); 104403b705cfSriastradh nbox = REGION_NUM_RECTS(prgn); 104503b705cfSriastradh I810SelectBuffer(pScrn, I810_SELECT_DEPTH); 104603b705cfSriastradh I810SetupForSolidFill(pScrn, 0xffff, GXcopy, -1); 104703b705cfSriastradh while (nbox--) { 104803b705cfSriastradh I810SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, 104903b705cfSriastradh pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 105003b705cfSriastradh pbox++; 105103b705cfSriastradh } 105203b705cfSriastradh I810SelectBuffer(pScrn, I810_SELECT_FRONT); 105303b705cfSriastradh 105403b705cfSriastradh I810DRISetNeedSync(pScrn); 105503b705cfSriastradh} 105603b705cfSriastradh 105703b705cfSriastradh/* This routine is a modified form of XAADoBitBlt with the calls to 105803b705cfSriastradh * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source 105903b705cfSriastradh * instead of destination. My origin is upside down so the ydir cases 106003b705cfSriastradh * are reversed. 106103b705cfSriastradh * 106203b705cfSriastradh * KW: can you believe that this is called even when a 2d window moves? 106303b705cfSriastradh */ 106403b705cfSriastradhstatic void 106503b705cfSriastradhI810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 106603b705cfSriastradh RegionPtr prgnSrc, CARD32 index) 106703b705cfSriastradh{ 106803b705cfSriastradh ScreenPtr pScreen = pParent->drawable.pScreen; 106903b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 107003b705cfSriastradh BoxPtr pboxTmp, pboxNext, pboxBase; 107103b705cfSriastradh DDXPointPtr pptTmp, pptNew2 = NULL; 107203b705cfSriastradh int xdir, ydir; 107303b705cfSriastradh 107403b705cfSriastradh int screenwidth = pScrn->virtualX; 107503b705cfSriastradh int screenheight = pScrn->virtualY; 107603b705cfSriastradh 107703b705cfSriastradh BoxPtr pbox = REGION_RECTS(prgnSrc); 107803b705cfSriastradh int nbox = REGION_NUM_RECTS(prgnSrc); 107903b705cfSriastradh 108003b705cfSriastradh BoxPtr pboxNew1 = NULL; 108103b705cfSriastradh BoxPtr pboxNew2 = NULL; 108203b705cfSriastradh DDXPointPtr pptNew1 = NULL; 108303b705cfSriastradh DDXPointPtr pptSrc = &ptOldOrg; 108403b705cfSriastradh 108503b705cfSriastradh int dx = pParent->drawable.x - ptOldOrg.x; 108603b705cfSriastradh int dy = pParent->drawable.y - ptOldOrg.y; 108703b705cfSriastradh 108803b705cfSriastradh /* If the copy will overlap in Y, reverse the order */ 108903b705cfSriastradh if (dy > 0) { 109003b705cfSriastradh ydir = -1; 109103b705cfSriastradh 109203b705cfSriastradh if (nbox > 1) { 109303b705cfSriastradh /* Keep ordering in each band, reverse order of bands */ 109403b705cfSriastradh pboxNew1 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); 109503b705cfSriastradh if (!pboxNew1) 109603b705cfSriastradh return; 109703b705cfSriastradh pptNew1 = (DDXPointPtr) malloc(sizeof(DDXPointRec) * nbox); 109803b705cfSriastradh if (!pptNew1) { 109903b705cfSriastradh free(pboxNew1); 110003b705cfSriastradh return; 110103b705cfSriastradh } 110203b705cfSriastradh pboxBase = pboxNext = pbox + nbox - 1; 110303b705cfSriastradh while (pboxBase >= pbox) { 110403b705cfSriastradh while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) 110503b705cfSriastradh pboxNext--; 110603b705cfSriastradh pboxTmp = pboxNext + 1; 110764b81f0aSriastradh if (pptSrc == &ptOldOrg) { 110864b81f0aSriastradh if (pboxTmp <= pboxBase) { 110964b81f0aSriastradh *pboxNew1++ = *pboxTmp; 111064b81f0aSriastradh *pptNew1++ = *pptSrc; 111164b81f0aSriastradh } 111264b81f0aSriastradh } else { 111364b81f0aSriastradh pptTmp = pptSrc + (pboxTmp - pbox); 111464b81f0aSriastradh while (pboxTmp <= pboxBase) { 111564b81f0aSriastradh *pboxNew1++ = *pboxTmp++; 111664b81f0aSriastradh *pptNew1++ = *pptTmp++; 111764b81f0aSriastradh } 111803b705cfSriastradh } 111903b705cfSriastradh pboxBase = pboxNext; 112003b705cfSriastradh } 112103b705cfSriastradh pboxNew1 -= nbox; 112203b705cfSriastradh pbox = pboxNew1; 112303b705cfSriastradh pptNew1 -= nbox; 112403b705cfSriastradh pptSrc = pptNew1; 112503b705cfSriastradh } 112603b705cfSriastradh } else { 112703b705cfSriastradh /* No changes required */ 112803b705cfSriastradh ydir = 1; 112903b705cfSriastradh } 113003b705cfSriastradh 113103b705cfSriastradh /* If the regions will overlap in X, reverse the order */ 113203b705cfSriastradh if (dx > 0) { 113303b705cfSriastradh xdir = -1; 113403b705cfSriastradh 113503b705cfSriastradh if (nbox > 1) { 113603b705cfSriastradh /*reverse orderof rects in each band */ 113703b705cfSriastradh pboxNew2 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); 113803b705cfSriastradh pptNew2 = (DDXPointPtr) malloc(sizeof(DDXPointRec) * nbox); 113903b705cfSriastradh if (!pboxNew2 || !pptNew2) { 114003b705cfSriastradh if (pptNew2) 114103b705cfSriastradh free(pptNew2); 114203b705cfSriastradh if (pboxNew2) 114303b705cfSriastradh free(pboxNew2); 114403b705cfSriastradh if (pboxNew1) { 114503b705cfSriastradh free(pptNew1); 114603b705cfSriastradh free(pboxNew1); 114703b705cfSriastradh } 114803b705cfSriastradh return; 114903b705cfSriastradh } 115003b705cfSriastradh pboxBase = pboxNext = pbox; 115103b705cfSriastradh while (pboxBase < pbox + nbox) { 115203b705cfSriastradh while ((pboxNext < pbox + nbox) && (pboxNext->y1 == pboxBase->y1)) 115303b705cfSriastradh pboxNext++; 115403b705cfSriastradh pboxTmp = pboxNext; 115503b705cfSriastradh pptTmp = pptSrc + (pboxTmp - pbox); 115603b705cfSriastradh while (pboxTmp != pboxBase) { 115703b705cfSriastradh *pboxNew2++ = *--pboxTmp; 115803b705cfSriastradh *pptNew2++ = *--pptTmp; 115903b705cfSriastradh } 116003b705cfSriastradh pboxBase = pboxNext; 116103b705cfSriastradh } 116203b705cfSriastradh pboxNew2 -= nbox; 116303b705cfSriastradh pbox = pboxNew2; 116403b705cfSriastradh pptNew2 -= nbox; 116503b705cfSriastradh pptSrc = pptNew2; 116603b705cfSriastradh } 116703b705cfSriastradh } else { 116803b705cfSriastradh /* No changes are needed */ 116903b705cfSriastradh xdir = 1; 117003b705cfSriastradh } 117103b705cfSriastradh 117203b705cfSriastradh /* SelectBuffer isn't really a good concept for the i810. 117303b705cfSriastradh */ 117403b705cfSriastradh I810EmitFlush(pScrn); 117503b705cfSriastradh I810SetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1); 117603b705cfSriastradh for (; nbox--; pbox++) { 117703b705cfSriastradh 117803b705cfSriastradh int x1 = pbox->x1; 117903b705cfSriastradh int y1 = pbox->y1; 118003b705cfSriastradh int destx = x1 + dx; 118103b705cfSriastradh int desty = y1 + dy; 118203b705cfSriastradh int w = pbox->x2 - x1 + 1; 118303b705cfSriastradh int h = pbox->y2 - y1 + 1; 118403b705cfSriastradh 118503b705cfSriastradh if (destx < 0) 118603b705cfSriastradh x1 -= destx, w += destx, destx = 0; 118703b705cfSriastradh if (desty < 0) 118803b705cfSriastradh y1 -= desty, h += desty, desty = 0; 118903b705cfSriastradh if (destx + w > screenwidth) 119003b705cfSriastradh w = screenwidth - destx; 119103b705cfSriastradh if (desty + h > screenheight) 119203b705cfSriastradh h = screenheight - desty; 119303b705cfSriastradh if (w <= 0) 119403b705cfSriastradh continue; 119503b705cfSriastradh if (h <= 0) 119603b705cfSriastradh continue; 119703b705cfSriastradh 119803b705cfSriastradh if (I810_DEBUG & DEBUG_VERBOSE_DRI) 119903b705cfSriastradh ErrorF("MoveBuffers %d,%d %dx%d dx: %d dy: %d\n", 120003b705cfSriastradh x1, y1, w, h, dx, dy); 120103b705cfSriastradh 120203b705cfSriastradh I810SelectBuffer(pScrn, I810_SELECT_BACK); 120303b705cfSriastradh I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); 120403b705cfSriastradh I810SelectBuffer(pScrn, I810_SELECT_DEPTH); 120503b705cfSriastradh I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); 120603b705cfSriastradh } 120703b705cfSriastradh I810SelectBuffer(pScrn, I810_SELECT_FRONT); 120803b705cfSriastradh I810EmitFlush(pScrn); 120903b705cfSriastradh 121003b705cfSriastradh if (pboxNew2) { 121103b705cfSriastradh free(pptNew2); 121203b705cfSriastradh free(pboxNew2); 121303b705cfSriastradh } 121403b705cfSriastradh if (pboxNew1) { 121503b705cfSriastradh free(pptNew1); 121603b705cfSriastradh free(pboxNew1); 121703b705cfSriastradh } 121803b705cfSriastradh 121903b705cfSriastradh I810DRISetNeedSync(pScrn); 122003b705cfSriastradh} 122103b705cfSriastradh 122203b705cfSriastradh 122303b705cfSriastradh/* Use the miext/shadow module to maintain a list of dirty rectangles. 122403b705cfSriastradh * These are blitted to the back buffer to keep both buffers clean 122503b705cfSriastradh * during page-flipping when the 3d application isn't fullscreen. 122603b705cfSriastradh * 122703b705cfSriastradh * Unlike most use of the shadow code, both buffers are in video memory. 122803b705cfSriastradh * 122903b705cfSriastradh * An alternative to this would be to organize for all on-screen drawing 123003b705cfSriastradh * operations to be duplicated for the two buffers. That might be 123103b705cfSriastradh * faster, but seems like a lot more work... 123203b705cfSriastradh */ 123303b705cfSriastradh 123403b705cfSriastradh 123503b705cfSriastradh/* This should be done *before* XAA syncs or fires its buffer. 123603b705cfSriastradh * Otherwise will have to fire it again??? 123703b705cfSriastradh */ 123803b705cfSriastradhstatic void I810DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 123903b705cfSriastradh{ 124003b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 124103b705cfSriastradh int i; 124203b705cfSriastradh I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); 124303b705cfSriastradh unsigned int br13; 124403b705cfSriastradh int cpp=2; 124503b705cfSriastradh 124603b705cfSriastradh 124703b705cfSriastradh /* Don't want to do this when no 3d is active and pages are 124803b705cfSriastradh * right-way-round 124903b705cfSriastradh */ 125003b705cfSriastradh if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) 125103b705cfSriastradh return; 125203b705cfSriastradh 125303b705cfSriastradh br13 = (pI810->auxPitch) | (0xcc << 16); 125403b705cfSriastradh 125503b705cfSriastradh for (i = 0 ; i < num ; i++, pbox++) { 125603b705cfSriastradh unsigned int w = min(pbox->y2, pScrn->virtualY-1) - max(pbox->y1, 0) + 1; 125703b705cfSriastradh unsigned int h = min(pbox->x2, pScrn->virtualX-1) - max(pbox->x1, 0) + 1; 125803b705cfSriastradh unsigned int dst = max(pbox->x1, 0)*cpp + (max(pbox->y1, 0)*pI810->auxPitch); 125903b705cfSriastradh 126003b705cfSriastradh BEGIN_LP_RING(6); 126103b705cfSriastradh 126203b705cfSriastradh OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); 126303b705cfSriastradh OUT_RING(br13); 126403b705cfSriastradh OUT_RING( (h<<16) | (w*cpp) ); 126503b705cfSriastradh OUT_RING(pI810->BackBuffer.Start + dst); 126603b705cfSriastradh OUT_RING(br13 & 0xffff); 126703b705cfSriastradh OUT_RING(dst); 126803b705cfSriastradh 126903b705cfSriastradh ADVANCE_LP_RING(); 127003b705cfSriastradh } 127103b705cfSriastradh 127203b705cfSriastradh} 127303b705cfSriastradh 127403b705cfSriastradhstatic void I810EnablePageFlip(ScreenPtr pScreen) 127503b705cfSriastradh{ 127603b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 127703b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 127803b705cfSriastradh I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); 127903b705cfSriastradh int cpp=2; 128003b705cfSriastradh pSAREAPriv->pf_enabled = pI810->allowPageFlip; 128103b705cfSriastradh pSAREAPriv->pf_active = 0; 128203b705cfSriastradh 128303b705cfSriastradh if (pI810->allowPageFlip) { 128403b705cfSriastradh unsigned int br13 = pI810->auxPitch | (0xcc << 16); 128503b705cfSriastradh 128603b705cfSriastradh BEGIN_LP_RING(6); 128703b705cfSriastradh 128803b705cfSriastradh OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); 128903b705cfSriastradh OUT_RING(br13); 129003b705cfSriastradh OUT_RING((pScrn->virtualY << 16) | (pScrn->virtualX*cpp)); 129103b705cfSriastradh OUT_RING(pI810->BackBuffer.Start); 129203b705cfSriastradh OUT_RING(br13 & 0xFFFF); 129303b705cfSriastradh OUT_RING(0); 129403b705cfSriastradh ADVANCE_LP_RING(); 129503b705cfSriastradh 129603b705cfSriastradh pSAREAPriv->pf_active = 1; 129703b705cfSriastradh } 129803b705cfSriastradh 129903b705cfSriastradh} 130003b705cfSriastradh 130103b705cfSriastradhstatic void I810DisablePageFlip(ScreenPtr pScreen) 130203b705cfSriastradh{ 130303b705cfSriastradh I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); 130403b705cfSriastradh 130503b705cfSriastradh pSAREAPriv->pf_active=0; 130603b705cfSriastradh} 130703b705cfSriastradh 130803b705cfSriastradhstatic void I810DRITransitionSingleToMulti3d(ScreenPtr pScreen) 130903b705cfSriastradh{ 131003b705cfSriastradh /* Tell the clients not to pageflip. How? 131103b705cfSriastradh * -- Field in sarea, plus bumping the window counters. 131203b705cfSriastradh * -- DRM needs to cope with Front-to-Back swapbuffers. 131303b705cfSriastradh */ 131403b705cfSriastradh I810DisablePageFlip(pScreen); 131503b705cfSriastradh} 131603b705cfSriastradh 131703b705cfSriastradhstatic void I810DRITransitionMultiToSingle3d(ScreenPtr pScreen) 131803b705cfSriastradh{ 131903b705cfSriastradh /* Let the remaining 3d app start page flipping again */ 132003b705cfSriastradh I810EnablePageFlip(pScreen); 132103b705cfSriastradh} 132203b705cfSriastradh 132303b705cfSriastradhstatic void I810DRITransitionTo3d(ScreenPtr pScreen) 132403b705cfSriastradh{ 132503b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 132603b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 132703b705cfSriastradh 132803b705cfSriastradh I810EnablePageFlip(pScreen); 132903b705cfSriastradh pI810->have3DWindows = 1; 133003b705cfSriastradh} 133103b705cfSriastradh 133203b705cfSriastradhstatic void I810DRITransitionTo2d(ScreenPtr pScreen) 133303b705cfSriastradh{ 133403b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 133503b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 133603b705cfSriastradh I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); 133703b705cfSriastradh 133803b705cfSriastradh /* Try flipping back to the front page if necessary */ 133903b705cfSriastradh if (pSAREAPriv->pf_current_page == 1) 134003b705cfSriastradh drmCommandNone(pI810->drmSubFD, DRM_I810_FLIP); 134103b705cfSriastradh 134203b705cfSriastradh /* Shut down shadowing if we've made it back to the front page */ 134303b705cfSriastradh if (pSAREAPriv->pf_current_page == 0) { 134403b705cfSriastradh I810DisablePageFlip(pScreen); 134503b705cfSriastradh } 134603b705cfSriastradh pI810->have3DWindows = 0; 134703b705cfSriastradh} 134803b705cfSriastradh 134903b705cfSriastradhBool 135003b705cfSriastradhI810DRILeave(ScrnInfoPtr pScrn) 135103b705cfSriastradh{ 135203b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 135303b705cfSriastradh 135403b705cfSriastradh if (pI810->directRenderingEnabled) { 135503b705cfSriastradh if (pI810->dcacheHandle != 0) 135603b705cfSriastradh if (drmAgpUnbind(pI810->drmSubFD, pI810->dcacheHandle) != 0) { 135703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 135803b705cfSriastradh return FALSE; 135903b705cfSriastradh } 136003b705cfSriastradh if (pI810->backHandle != 0) 136103b705cfSriastradh if (drmAgpUnbind(pI810->drmSubFD, pI810->backHandle) != 0) { 136203b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 136303b705cfSriastradh return FALSE; 136403b705cfSriastradh } 136503b705cfSriastradh if (pI810->zHandle != 0) 136603b705cfSriastradh if (drmAgpUnbind(pI810->drmSubFD, pI810->zHandle) != 0) { 136703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 136803b705cfSriastradh return FALSE; 136903b705cfSriastradh } 137003b705cfSriastradh if (pI810->sysmemHandle != 0) 137103b705cfSriastradh if (drmAgpUnbind(pI810->drmSubFD, pI810->sysmemHandle) != 0) { 137203b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 137303b705cfSriastradh return FALSE; 137403b705cfSriastradh } 137503b705cfSriastradh if (pI810->xvmcHandle != 0) 137603b705cfSriastradh if (drmAgpUnbind(pI810->drmSubFD, pI810->xvmcHandle) != 0) { 137703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 137803b705cfSriastradh return FALSE; 137903b705cfSriastradh } 138003b705cfSriastradh if (pI810->cursorHandle != 0) 138103b705cfSriastradh if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorHandle) != 0) { 138203b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 138303b705cfSriastradh return FALSE; 138403b705cfSriastradh } 138503b705cfSriastradh if (pI810->cursorARGBHandle != 0) 138603b705cfSriastradh if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorARGBHandle) != 0) { 138703b705cfSriastradh xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 138803b705cfSriastradh return FALSE; 138903b705cfSriastradh } 139003b705cfSriastradh if (pI810->agpAcquired == TRUE) 139103b705cfSriastradh drmAgpRelease(pI810->drmSubFD); 139203b705cfSriastradh pI810->agpAcquired = FALSE; 139303b705cfSriastradh } 139403b705cfSriastradh return TRUE; 139503b705cfSriastradh} 139603b705cfSriastradh 139703b705cfSriastradhBool 139803b705cfSriastradhI810DRIEnter(ScrnInfoPtr pScrn) 139903b705cfSriastradh{ 140003b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 140103b705cfSriastradh 140203b705cfSriastradh if (pI810->directRenderingEnabled) { 140303b705cfSriastradh 140403b705cfSriastradh if (pI810->agpAcquired == FALSE) 140503b705cfSriastradh drmAgpAcquire(pI810->drmSubFD); 140603b705cfSriastradh pI810->agpAcquired = TRUE; 140703b705cfSriastradh if (pI810->dcacheHandle != 0) 140803b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, pI810->dcacheHandle, 140903b705cfSriastradh pI810->DepthOffset) != 0) 141003b705cfSriastradh return FALSE; 141103b705cfSriastradh if (pI810->backHandle != 0) 141203b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, pI810->backHandle, 141303b705cfSriastradh pI810->BackOffset) != 0) 141403b705cfSriastradh return FALSE; 141503b705cfSriastradh if (pI810->zHandle != 0) 141603b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, pI810->zHandle, 141703b705cfSriastradh pI810->DepthOffset) != 0) 141803b705cfSriastradh return FALSE; 141903b705cfSriastradh if (pI810->sysmemHandle != 0) 142003b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, pI810->sysmemHandle, 0) != 0) 142103b705cfSriastradh return FALSE; 142203b705cfSriastradh if (pI810->xvmcHandle != 0) 142303b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, pI810->xvmcHandle, 142403b705cfSriastradh pI810->MC.Start) != 0) 142503b705cfSriastradh return FALSE; 142603b705cfSriastradh if (pI810->cursorHandle != 0) 142703b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, pI810->cursorHandle, 142803b705cfSriastradh pI810->CursorStart) != 0) 142903b705cfSriastradh return FALSE; 143003b705cfSriastradh if (pI810->cursorARGBHandle != 0) 143103b705cfSriastradh if (drmAgpBind(pI810->drmSubFD, pI810->cursorARGBHandle, 143203b705cfSriastradh pI810->CursorARGBStart) != 0) 143303b705cfSriastradh return FALSE; 143403b705cfSriastradh } 143503b705cfSriastradh 143603b705cfSriastradh I810SelectBuffer(pScrn, I810_SELECT_FRONT); 143703b705cfSriastradh return TRUE; 143803b705cfSriastradh} 1439