1428d7b3dSmrg#ifdef HAVE_CONFIG_H 2428d7b3dSmrg#include "config.h" 3428d7b3dSmrg#endif 4428d7b3dSmrg 5428d7b3dSmrg#include <errno.h> 6428d7b3dSmrg#include <stdio.h> 7428d7b3dSmrg#include <string.h> 8428d7b3dSmrg#include <assert.h> 9428d7b3dSmrg 10428d7b3dSmrg#include "xorg-server.h" 11428d7b3dSmrg#include "xf86.h" 12428d7b3dSmrg#include "xf86_OSproc.h" 13428d7b3dSmrg 14428d7b3dSmrg#include "xf86Pci.h" 15428d7b3dSmrg 16428d7b3dSmrg#include "windowstr.h" 17428d7b3dSmrg#include "shadow.h" 18428d7b3dSmrg#include "shadowfb.h" 19428d7b3dSmrg 20428d7b3dSmrg#include "i810.h" 21428d7b3dSmrg#include "i810_dri.h" 22428d7b3dSmrg 23428d7b3dSmrgstatic char I810KernelDriverName[] = "i810"; 24428d7b3dSmrgstatic char I810ClientDriverName[] = "i810"; 25428d7b3dSmrg 26428d7b3dSmrgstatic Bool I810CreateContext(ScreenPtr pScreen, VisualPtr visual, 27428d7b3dSmrg drm_context_t hwContext, void *pVisualConfigPriv, 28428d7b3dSmrg DRIContextType contextStore); 29428d7b3dSmrgstatic void I810DestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 30428d7b3dSmrg DRIContextType contextStore); 31428d7b3dSmrgstatic void I810DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 32428d7b3dSmrg DRIContextType readContextType, 33428d7b3dSmrg void *readContextStore, 34428d7b3dSmrg DRIContextType writeContextType, 35428d7b3dSmrg void *writeContextStore); 36428d7b3dSmrgstatic void I810DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); 37428d7b3dSmrgstatic void I810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 38428d7b3dSmrg RegionPtr prgnSrc, CARD32 index); 39428d7b3dSmrg 40428d7b3dSmrg 41428d7b3dSmrgstatic void I810EnablePageFlip(ScreenPtr pScreen); 42428d7b3dSmrgstatic void I810DisablePageFlip(ScreenPtr pScreen); 43428d7b3dSmrgstatic void I810DRITransitionSingleToMulti3d(ScreenPtr pScreen); 44428d7b3dSmrgstatic void I810DRITransitionMultiToSingle3d(ScreenPtr pScreen); 45428d7b3dSmrgstatic void I810DRITransitionTo3d(ScreenPtr pScreen); 46428d7b3dSmrgstatic void I810DRITransitionTo2d(ScreenPtr pScreen); 47428d7b3dSmrg 48428d7b3dSmrgstatic void I810DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 49428d7b3dSmrg 50428d7b3dSmrgstatic int i810_pitches[] = { 51428d7b3dSmrg 512, 52428d7b3dSmrg 1024, 53428d7b3dSmrg 2048, 54428d7b3dSmrg 4096, 55428d7b3dSmrg 0 56428d7b3dSmrg}; 57428d7b3dSmrg 58428d7b3dSmrgstatic int i810_pitch_flags[] = { 59428d7b3dSmrg 0x0, 60428d7b3dSmrg 0x1, 61428d7b3dSmrg 0x2, 62428d7b3dSmrg 0x3, 63428d7b3dSmrg 0 64428d7b3dSmrg}; 65428d7b3dSmrg 66428d7b3dSmrgstatic unsigned int i810_drm_version = 0; 67428d7b3dSmrg 68428d7b3dSmrgBool 69428d7b3dSmrgI810CleanupDma(ScrnInfoPtr pScrn) 70428d7b3dSmrg{ 71428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 72428d7b3dSmrg drmI810Init info; 73428d7b3dSmrg 74428d7b3dSmrg memset(&info, 0, sizeof(drmI810Init)); 75428d7b3dSmrg info.func = I810_CLEANUP_DMA; 76428d7b3dSmrg 77428d7b3dSmrg if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT, 78428d7b3dSmrg &info, sizeof(drmI810Init))) { 79428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 80428d7b3dSmrg "[dri] I810 Dma Cleanup Failed\n"); 81428d7b3dSmrg return FALSE; 82428d7b3dSmrg } 83428d7b3dSmrg 84428d7b3dSmrg return TRUE; 85428d7b3dSmrg} 86428d7b3dSmrg 87428d7b3dSmrgBool 88428d7b3dSmrgI810InitDma(ScrnInfoPtr pScrn) 89428d7b3dSmrg{ 90428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 91428d7b3dSmrg I810RingBuffer *ring = pI810->LpRing; 92428d7b3dSmrg I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate; 93428d7b3dSmrg drmI810Init info; 94428d7b3dSmrg 95428d7b3dSmrg memset(&info, 0, sizeof(drmI810Init)); 96428d7b3dSmrg 97428d7b3dSmrg info.ring_start = ring->mem.Start; 98428d7b3dSmrg info.ring_end = ring->mem.End; 99428d7b3dSmrg info.ring_size = ring->mem.Size; 100428d7b3dSmrg info.mmio_offset = (unsigned int)pI810DRI->regs; 101428d7b3dSmrg info.buffers_offset = (unsigned int)pI810->buffer_map; 102428d7b3dSmrg info.sarea_priv_offset = sizeof(XF86DRISAREARec); 103428d7b3dSmrg 104428d7b3dSmrg info.front_offset = 0; 105428d7b3dSmrg info.back_offset = pI810->BackBuffer.Start; 106428d7b3dSmrg info.depth_offset = pI810->DepthBuffer.Start; 107428d7b3dSmrg info.overlay_offset = pI810->OverlayStart; 108428d7b3dSmrg info.overlay_physical = pI810->OverlayPhysical; 109428d7b3dSmrg info.w = pScrn->virtualX; 110428d7b3dSmrg info.h = pScrn->virtualY; 111428d7b3dSmrg info.pitch = pI810->auxPitch; 112428d7b3dSmrg info.pitch_bits = pI810->auxPitchBits; 113428d7b3dSmrg 114428d7b3dSmrg /* We require DRM v1.2 or greater. Since DRM v1.2 broke compatibility 115428d7b3dSmrg * we created a new v1.4 that supports a new init function. Eventually the 116428d7b3dSmrg * old init function will go away. If you change the drm interface, make a 117428d7b3dSmrg * new init type too so that we can detect the new client. 118428d7b3dSmrg */ 119428d7b3dSmrg switch(i810_drm_version) { 120428d7b3dSmrg case ((1<<16) | 0): 121428d7b3dSmrg case ((1<<16) | 1): 122428d7b3dSmrg case ((1<<16) | 2): 123428d7b3dSmrg case ((1<<16) | 3): 124428d7b3dSmrg /* Use OLD drm < 1.4 init */ 125428d7b3dSmrg info.func = I810_INIT_DMA; 126428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Init PRE v1.4 interface.\n"); 127428d7b3dSmrg break; 128428d7b3dSmrg default: 129428d7b3dSmrg case ((1<<16) | 4): 130428d7b3dSmrg /* DRM version 1.3 or greater init */ 131428d7b3dSmrg info.func = I810_INIT_DMA_1_4; 132428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Init v1.4 interface.\n"); 133428d7b3dSmrg break; 134428d7b3dSmrg } 135428d7b3dSmrg 136428d7b3dSmrg if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT, 137428d7b3dSmrg &info, sizeof(drmI810Init))) { 138428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 139428d7b3dSmrg "[drm] I810 Dma Initialization failed.\n"); 140428d7b3dSmrg return FALSE; 141428d7b3dSmrg } 142428d7b3dSmrg 143428d7b3dSmrg return TRUE; 144428d7b3dSmrg} 145428d7b3dSmrg 146428d7b3dSmrgstatic unsigned int 147428d7b3dSmrgmylog2(unsigned int n) 148428d7b3dSmrg{ 149428d7b3dSmrg unsigned int log2 = 1; 150428d7b3dSmrg 151428d7b3dSmrg while (n > 1) 152428d7b3dSmrg n >>= 1, log2++; 153428d7b3dSmrg return log2; 154428d7b3dSmrg} 155428d7b3dSmrg 156428d7b3dSmrgBool 157428d7b3dSmrgI810DRIScreenInit(ScreenPtr pScreen) 158428d7b3dSmrg{ 159428d7b3dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 160428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 161428d7b3dSmrg DRIInfoPtr pDRIInfo; 162428d7b3dSmrg I810DRIPtr pI810DRI; 163428d7b3dSmrg unsigned long tom; 164428d7b3dSmrg drm_handle_t agpHandle; 165428d7b3dSmrg drm_handle_t dcacheHandle; 166428d7b3dSmrg int sysmem_size = 0; 167428d7b3dSmrg int back_size = 0; 168428d7b3dSmrg unsigned int pitch_idx = 0; 169428d7b3dSmrg int bufs; 170428d7b3dSmrg int width = pScrn->displayWidth * pI810->cpp; 171428d7b3dSmrg int i; 172428d7b3dSmrg 173428d7b3dSmrg /* Hardware 3D rendering only implemented for 16bpp */ 174428d7b3dSmrg /* And it only works for 5:6:5 (Mark) */ 175428d7b3dSmrg if (pScrn->depth != 16) 176428d7b3dSmrg return FALSE; 177428d7b3dSmrg 178428d7b3dSmrg /* Check that the DRI, and DRM modules have been loaded by testing 179428d7b3dSmrg * for known symbols in each module. */ 180428d7b3dSmrg if (!xf86LoaderCheckSymbol("drmAvailable")) 181428d7b3dSmrg return FALSE; 182428d7b3dSmrg if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { 183428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 184428d7b3dSmrg "[dri] I810DRIScreenInit failed (libdri.a too old)\n"); 185428d7b3dSmrg return FALSE; 186428d7b3dSmrg } 187428d7b3dSmrg 188428d7b3dSmrg /* adjust width first */ 189428d7b3dSmrg#define Elements(x) sizeof(x)/sizeof(*x) 190428d7b3dSmrg for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++) 191428d7b3dSmrg if (width <= i810_pitches[pitch_idx]) 192428d7b3dSmrg break; 193428d7b3dSmrg 194428d7b3dSmrg if (pitch_idx == Elements(i810_pitches)) { 195428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 196428d7b3dSmrg "[dri] Couldn't find depth/back buffer pitch"); 197428d7b3dSmrg DRICloseScreen(pScreen); 198428d7b3dSmrg return FALSE; 199428d7b3dSmrg } else { 200428d7b3dSmrg /* for tiled memory to work, the buffer needs to have the 201428d7b3dSmrg * number of lines as a multiple of 16 (the tile size), 202428d7b3dSmrg * - airlied */ 203428d7b3dSmrg int lines = (pScrn->virtualY + 15) / 16 * 16; 204428d7b3dSmrg back_size = i810_pitches[pitch_idx] * lines; 205428d7b3dSmrg back_size = ((back_size + 4096 - 1) / 4096) * 4096; 206428d7b3dSmrg } 207428d7b3dSmrg 208428d7b3dSmrg pScrn->displayWidth = i810_pitches[pitch_idx] / pI810->cpp; 209428d7b3dSmrg 210428d7b3dSmrg /* Check the DRI version */ 211428d7b3dSmrg { 212428d7b3dSmrg int major, minor, patch; 213428d7b3dSmrg 214428d7b3dSmrg DRIQueryVersion(&major, &minor, &patch); 215428d7b3dSmrg if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { 216428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 217428d7b3dSmrg "[dri] I810DRIScreenInit failed because of a version mismatch.\n" 218428d7b3dSmrg "[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n" 219428d7b3dSmrg "[dri] Disabling DRI.\n", major, minor, patch, 220428d7b3dSmrg DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); 221428d7b3dSmrg return FALSE; 222428d7b3dSmrg } 223428d7b3dSmrg } 224428d7b3dSmrg 225428d7b3dSmrg pDRIInfo = DRICreateInfoRec(); 226428d7b3dSmrg if (!pDRIInfo) { 227428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 228428d7b3dSmrg "[dri] DRICreateInfoRec failed. Disabling DRI.\n"); 229428d7b3dSmrg return FALSE; 230428d7b3dSmrg } 231428d7b3dSmrg 232428d7b3dSmrg/* pDRIInfo->wrap.ValidateTree = 0; */ 233428d7b3dSmrg/* pDRIInfo->wrap.PostValidateTree = 0; */ 234428d7b3dSmrg 235428d7b3dSmrg pI810->pDRIInfo = pDRIInfo; 236428d7b3dSmrg pI810->LockHeld = 0; 237428d7b3dSmrg 238428d7b3dSmrg pDRIInfo->drmDriverName = I810KernelDriverName; 239428d7b3dSmrg pDRIInfo->clientDriverName = I810ClientDriverName; 240428d7b3dSmrg if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 241428d7b3dSmrg pDRIInfo->busIdString = DRICreatePCIBusID(pI810->PciInfo); 242428d7b3dSmrg } else { 243428d7b3dSmrg pDRIInfo->busIdString = malloc(64); 244428d7b3dSmrg if (pDRIInfo->busIdString) 245428d7b3dSmrg sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", 246428d7b3dSmrg ((pI810->PciInfo->domain << 8) | pI810->PciInfo->bus), 247428d7b3dSmrg pI810->PciInfo->dev, pI810->PciInfo->func 248428d7b3dSmrg ); 249428d7b3dSmrg } 250428d7b3dSmrg if (!pDRIInfo->busIdString) { 251428d7b3dSmrg DRIDestroyInfoRec(pI810->pDRIInfo); 252428d7b3dSmrg pI810->pDRIInfo = NULL; 253428d7b3dSmrg return FALSE; 254428d7b3dSmrg } 255428d7b3dSmrg pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION; 256428d7b3dSmrg pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION; 257428d7b3dSmrg pDRIInfo->ddxDriverPatchVersion = I810_PATCHLEVEL; 258428d7b3dSmrg pDRIInfo->frameBufferPhysicalAddress = (pointer) pI810->LinearAddr; 259428d7b3dSmrg pDRIInfo->frameBufferSize = (((pScrn->displayWidth * 260428d7b3dSmrg pScrn->virtualY * pI810->cpp) + 261428d7b3dSmrg 4096 - 1) / 4096) * 4096; 262428d7b3dSmrg 263428d7b3dSmrg pDRIInfo->frameBufferStride = pScrn->displayWidth * pI810->cpp; 264428d7b3dSmrg pDRIInfo->ddxDrawableTableEntry = I810_MAX_DRAWABLES; 265428d7b3dSmrg 266428d7b3dSmrg if (SAREA_MAX_DRAWABLES < I810_MAX_DRAWABLES) 267428d7b3dSmrg pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; 268428d7b3dSmrg else 269428d7b3dSmrg pDRIInfo->maxDrawableTableEntry = I810_MAX_DRAWABLES; 270428d7b3dSmrg 271428d7b3dSmrg /* For now the mapping works by using a fixed size defined 272428d7b3dSmrg * in the SAREA header 273428d7b3dSmrg */ 274428d7b3dSmrg if (sizeof(XF86DRISAREARec) + sizeof(I810SAREARec) > SAREA_MAX) { 275428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 276428d7b3dSmrg "[dri] Data does not fit in SAREA\n"); 277428d7b3dSmrg return FALSE; 278428d7b3dSmrg } 279428d7b3dSmrg pDRIInfo->SAREASize = SAREA_MAX; 280428d7b3dSmrg 281428d7b3dSmrg if (!(pI810DRI = (I810DRIPtr) calloc(sizeof(I810DRIRec), 1))) { 282428d7b3dSmrg DRIDestroyInfoRec(pI810->pDRIInfo); 283428d7b3dSmrg pI810->pDRIInfo = NULL; 284428d7b3dSmrg return FALSE; 285428d7b3dSmrg } 286428d7b3dSmrg pDRIInfo->devPrivate = pI810DRI; 287428d7b3dSmrg pDRIInfo->devPrivateSize = sizeof(I810DRIRec); 288428d7b3dSmrg pDRIInfo->contextSize = sizeof(I810DRIContextRec); 289428d7b3dSmrg 290428d7b3dSmrg pDRIInfo->CreateContext = I810CreateContext; 291428d7b3dSmrg pDRIInfo->DestroyContext = I810DestroyContext; 292428d7b3dSmrg pDRIInfo->SwapContext = I810DRISwapContext; 293428d7b3dSmrg pDRIInfo->InitBuffers = I810DRIInitBuffers; 294428d7b3dSmrg pDRIInfo->MoveBuffers = I810DRIMoveBuffers; 295428d7b3dSmrg pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 296428d7b3dSmrg pDRIInfo->TransitionTo2d = I810DRITransitionTo2d; 297428d7b3dSmrg pDRIInfo->TransitionTo3d = I810DRITransitionTo3d; 298428d7b3dSmrg pDRIInfo->TransitionSingleToMulti3D = I810DRITransitionSingleToMulti3d; 299428d7b3dSmrg pDRIInfo->TransitionMultiToSingle3D = I810DRITransitionMultiToSingle3d; 300428d7b3dSmrg 301428d7b3dSmrg pDRIInfo->createDummyCtx = TRUE; 302428d7b3dSmrg pDRIInfo->createDummyCtxPriv = FALSE; 303428d7b3dSmrg 304428d7b3dSmrg /* This adds the framebuffer as a drm map *before* we have asked agp 305428d7b3dSmrg * to allocate it. Scary stuff, hold on... 306428d7b3dSmrg */ 307428d7b3dSmrg if (!DRIScreenInit(pScreen, pDRIInfo, &pI810->drmSubFD)) { 308428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 309428d7b3dSmrg "[dri] DRIScreenInit failed. Disabling DRI.\n"); 310428d7b3dSmrg free(pDRIInfo->devPrivate); 311428d7b3dSmrg pDRIInfo->devPrivate = NULL; 312428d7b3dSmrg DRIDestroyInfoRec(pI810->pDRIInfo); 313428d7b3dSmrg pI810->pDRIInfo = NULL; 314428d7b3dSmrg return FALSE; 315428d7b3dSmrg } 316428d7b3dSmrg 317428d7b3dSmrg /* Check the i810 DRM versioning */ 318428d7b3dSmrg { 319428d7b3dSmrg drmVersionPtr version; 320428d7b3dSmrg 321428d7b3dSmrg /* Check the DRM lib version. 322428d7b3dSmrg * drmGetLibVersion was not supported in version 1.0, so check for 323428d7b3dSmrg * symbol first to avoid possible crash or hang. 324428d7b3dSmrg */ 325428d7b3dSmrg if (xf86LoaderCheckSymbol("drmGetLibVersion")) { 326428d7b3dSmrg version = drmGetLibVersion(pI810->drmSubFD); 327428d7b3dSmrg } else 328428d7b3dSmrg { 329428d7b3dSmrg /* drmlib version 1.0.0 didn't have the drmGetLibVersion 330428d7b3dSmrg * entry point. Fake it by allocating a version record 331428d7b3dSmrg * via drmGetVersion and changing it to version 1.0.0 332428d7b3dSmrg */ 333428d7b3dSmrg version = drmGetVersion(pI810->drmSubFD); 334428d7b3dSmrg version->version_major = 1; 335428d7b3dSmrg version->version_minor = 0; 336428d7b3dSmrg version->version_patchlevel = 0; 337428d7b3dSmrg } 338428d7b3dSmrg 339428d7b3dSmrg#define REQ_MAJ 1 340428d7b3dSmrg#define REQ_MIN 1 341428d7b3dSmrg if (version) { 342428d7b3dSmrg if (version->version_major != REQ_MAJ || 343428d7b3dSmrg version->version_minor < REQ_MIN) { 344428d7b3dSmrg /* incompatible drm library version */ 345428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 346428d7b3dSmrg "[dri] I810DRIScreenInit failed because of a version mismatch.\n" 347428d7b3dSmrg "[dri] libdrm.a module version is %d.%d.%d but version %d.%d.x is needed.\n" 348428d7b3dSmrg "[dri] Disabling DRI.\n", 349428d7b3dSmrg version->version_major, 350428d7b3dSmrg version->version_minor, version->version_patchlevel, 351428d7b3dSmrg REQ_MAJ, REQ_MIN); 352428d7b3dSmrg drmFreeVersion(version); 353428d7b3dSmrg I810DRICloseScreen(pScreen); 354428d7b3dSmrg return FALSE; 355428d7b3dSmrg } 356428d7b3dSmrg drmFreeVersion(version); 357428d7b3dSmrg } 358428d7b3dSmrg 359428d7b3dSmrg /* Check the i810 DRM version */ 360428d7b3dSmrg version = drmGetVersion(pI810->drmSubFD); 361428d7b3dSmrg if (version) { 362428d7b3dSmrg i810_drm_version = (version->version_major<<16) | 363428d7b3dSmrg version->version_minor; 364428d7b3dSmrg if (version->version_major != 1 || version->version_minor < 2) { 365428d7b3dSmrg /* incompatible drm version */ 366428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 367428d7b3dSmrg "[dri] I810DRIScreenInit failed because of a version mismatch.\n" 368428d7b3dSmrg "[dri] i810.o kernel module version is %d.%d.%d but version 1.2.0 or greater is needed.\n" 369428d7b3dSmrg "[dri] Disabling DRI.\n", 370428d7b3dSmrg version->version_major, 371428d7b3dSmrg version->version_minor, version->version_patchlevel); 372428d7b3dSmrg I810DRICloseScreen(pScreen); 373428d7b3dSmrg drmFreeVersion(version); 374428d7b3dSmrg return FALSE; 375428d7b3dSmrg } 376428d7b3dSmrg pI810->drmMinor = version->version_minor; 377428d7b3dSmrg drmFreeVersion(version); 378428d7b3dSmrg } 379428d7b3dSmrg } 380428d7b3dSmrg 381428d7b3dSmrg pI810DRI->regsSize = I810_REG_SIZE; 382428d7b3dSmrg if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->MMIOAddr, 383428d7b3dSmrg pI810DRI->regsSize, DRM_REGISTERS, 0, 384428d7b3dSmrg (drmAddress) &pI810DRI->regs) < 0) { 385428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n"); 386428d7b3dSmrg DRICloseScreen(pScreen); 387428d7b3dSmrg return FALSE; 388428d7b3dSmrg } 389428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", 390428d7b3dSmrg (int)pI810DRI->regs); 391428d7b3dSmrg 392428d7b3dSmrg pI810->backHandle = DRM_AGP_NO_HANDLE; 393428d7b3dSmrg pI810->zHandle = DRM_AGP_NO_HANDLE; 394428d7b3dSmrg pI810->cursorHandle = DRM_AGP_NO_HANDLE; 395428d7b3dSmrg pI810->xvmcHandle = DRM_AGP_NO_HANDLE; 396428d7b3dSmrg pI810->sysmemHandle = DRM_AGP_NO_HANDLE; 397428d7b3dSmrg pI810->agpAcquired = FALSE; 398428d7b3dSmrg pI810->dcacheHandle = DRM_AGP_NO_HANDLE; 399428d7b3dSmrg 400428d7b3dSmrg /* Agp Support - Need this just to get the framebuffer. 401428d7b3dSmrg */ 402428d7b3dSmrg if (drmAgpAcquire(pI810->drmSubFD) < 0) { 403428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpAquire failed\n"); 404428d7b3dSmrg DRICloseScreen(pScreen); 405428d7b3dSmrg return FALSE; 406428d7b3dSmrg } 407428d7b3dSmrg pI810->agpAcquired = TRUE; 408428d7b3dSmrg 409428d7b3dSmrg if (drmAgpEnable(pI810->drmSubFD, 0) < 0) { 410428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpEnable failed\n"); 411428d7b3dSmrg DRICloseScreen(pScreen); 412428d7b3dSmrg return FALSE; 413428d7b3dSmrg } 414428d7b3dSmrg 415428d7b3dSmrg memset(&pI810->DcacheMem, 0, sizeof(I810MemRange)); 416428d7b3dSmrg memset(&pI810->BackBuffer, 0, sizeof(I810MemRange)); 417428d7b3dSmrg memset(&pI810->DepthBuffer, 0, sizeof(I810MemRange)); 418428d7b3dSmrg pI810->CursorPhysical = 0; 419428d7b3dSmrg pI810->CursorARGBPhysical = 0; 420428d7b3dSmrg 421428d7b3dSmrg /* Dcache - half the speed of normal ram, but has use as a Z buffer 422428d7b3dSmrg * under the DRI. 423428d7b3dSmrg */ 424428d7b3dSmrg 425428d7b3dSmrg drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, 426428d7b3dSmrg (drmAddress) &dcacheHandle); 427428d7b3dSmrg pI810->dcacheHandle = dcacheHandle; 428428d7b3dSmrg 429428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] dcacheHandle : 0x%x\n", 430428d7b3dSmrg (int)dcacheHandle); 431428d7b3dSmrg 432428d7b3dSmrg sysmem_size = pScrn->videoRam * 1024; 433428d7b3dSmrg if (dcacheHandle != DRM_AGP_NO_HANDLE) { 434428d7b3dSmrg if (back_size > 4 * 1024 * 1024) { 435428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_INFO, 436428d7b3dSmrg "[dri] Backsize is larger then 4 meg\n"); 437428d7b3dSmrg sysmem_size = sysmem_size - 2 * back_size; 438428d7b3dSmrg drmAgpFree(pI810->drmSubFD, dcacheHandle); 439428d7b3dSmrg pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; 440428d7b3dSmrg } else { 441428d7b3dSmrg sysmem_size = sysmem_size - back_size; 442428d7b3dSmrg } 443428d7b3dSmrg } else { 444428d7b3dSmrg sysmem_size = sysmem_size - 2 * back_size; 445428d7b3dSmrg } 446428d7b3dSmrg 447428d7b3dSmrg /* Max size is 48 without XvMC, 41 with 6 surfaces, 40 with 7 surfaces */ 448428d7b3dSmrg if (pI810->numSurfaces && (pI810->numSurfaces == 6)) { 449428d7b3dSmrg if (sysmem_size > (pI810->FbMapSize - 7 * 1024 * 1024)) { 450428d7b3dSmrg sysmem_size = (pI810->FbMapSize - 7 * 1024 * 1024); 451428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 452428d7b3dSmrg "User requested more memory then fits in the agp aperture\n" 453428d7b3dSmrg "Truncating to %d bytes of memory\n", sysmem_size); 454428d7b3dSmrg } 455428d7b3dSmrg } 456428d7b3dSmrg if (pI810->numSurfaces && (pI810->numSurfaces == 7)) { 457428d7b3dSmrg if (sysmem_size > (pI810->FbMapSize - 8 * 1024 * 1024)) { 458428d7b3dSmrg sysmem_size = (pI810->FbMapSize - 8 * 1024 * 1024); 459428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 460428d7b3dSmrg "User requested more memory then fits in the agp aperture\n" 461428d7b3dSmrg "Truncating to %d bytes of memory\n", sysmem_size); 462428d7b3dSmrg } 463428d7b3dSmrg } 464428d7b3dSmrg 465428d7b3dSmrg if (sysmem_size > pI810->FbMapSize) { 466428d7b3dSmrg sysmem_size = pI810->FbMapSize; 467428d7b3dSmrg 468428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 469428d7b3dSmrg "[dri] User requested more memory then fits in the agp" 470428d7b3dSmrg " aperture\n\tTruncating to %d bytes of memory\n", 471428d7b3dSmrg sysmem_size); 472428d7b3dSmrg } 473428d7b3dSmrg 474428d7b3dSmrg sysmem_size -= 4096; /* remove 4k for the hw cursor */ 475428d7b3dSmrg sysmem_size -= 16384; /* remove 16k for the ARGB hw cursor */ 476428d7b3dSmrg 477428d7b3dSmrg pI810->SysMem.Start = 0; 478428d7b3dSmrg pI810->SysMem.Size = sysmem_size; 479428d7b3dSmrg pI810->SysMem.End = sysmem_size; 480428d7b3dSmrg tom = sysmem_size; 481428d7b3dSmrg 482428d7b3dSmrg pI810->SavedSysMem = pI810->SysMem; 483428d7b3dSmrg 484428d7b3dSmrg if (dcacheHandle != DRM_AGP_NO_HANDLE) { 485428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, dcacheHandle, pI810->DepthOffset) == 0) { 486428d7b3dSmrg memset(&pI810->DcacheMem, 0, sizeof(I810MemRange)); 487428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 488428d7b3dSmrg "[agp] GART: Found 4096K Z buffer memory\n"); 489428d7b3dSmrg pI810->DcacheMem.Start = pI810->DepthOffset; 490428d7b3dSmrg pI810->DcacheMem.Size = 1024 * 4096; 491428d7b3dSmrg pI810->DcacheMem.End = 492428d7b3dSmrg pI810->DcacheMem.Start + pI810->DcacheMem.Size; 493428d7b3dSmrg if (!I810AllocLow 494428d7b3dSmrg (&(pI810->DepthBuffer), &(pI810->DcacheMem), back_size)) { 495428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 496428d7b3dSmrg "[agp] Depth buffer allocation failed\n"); 497428d7b3dSmrg DRICloseScreen(pScreen); 498428d7b3dSmrg return FALSE; 499428d7b3dSmrg } 500428d7b3dSmrg } else { 501428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 502428d7b3dSmrg "[agp] GART: dcache bind failed\n"); 503428d7b3dSmrg drmAgpFree(pI810->drmSubFD, dcacheHandle); 504428d7b3dSmrg pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; 505428d7b3dSmrg } 506428d7b3dSmrg } else { 507428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 508428d7b3dSmrg "[agp] GART: no dcache memory found\n"); 509428d7b3dSmrg } 510428d7b3dSmrg 511428d7b3dSmrg drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, 512428d7b3dSmrg (drmAddress) &agpHandle); 513428d7b3dSmrg pI810->backHandle = agpHandle; 514428d7b3dSmrg 515428d7b3dSmrg if (agpHandle != DRM_AGP_NO_HANDLE) { 516428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->BackOffset) == 0) { 517428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 518428d7b3dSmrg "[agp] Bound backbuffer memory\n"); 519428d7b3dSmrg 520428d7b3dSmrg pI810->BackBuffer.Start = pI810->BackOffset; 521428d7b3dSmrg pI810->BackBuffer.Size = back_size; 522428d7b3dSmrg pI810->BackBuffer.End = (pI810->BackBuffer.Start + 523428d7b3dSmrg pI810->BackBuffer.Size); 524428d7b3dSmrg } else { 525428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 526428d7b3dSmrg "[agp] Unable to bind backbuffer. Disabling DRI.\n"); 527428d7b3dSmrg DRICloseScreen(pScreen); 528428d7b3dSmrg return FALSE; 529428d7b3dSmrg } 530428d7b3dSmrg } else { 531428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 532428d7b3dSmrg "[dri] Unable to allocate backbuffer memory. Disabling DRI.\n"); 533428d7b3dSmrg DRICloseScreen(pScreen); 534428d7b3dSmrg return FALSE; 535428d7b3dSmrg } 536428d7b3dSmrg 537428d7b3dSmrg if (dcacheHandle == DRM_AGP_NO_HANDLE) { 538428d7b3dSmrg drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, 539428d7b3dSmrg (drmAddress) &agpHandle); 540428d7b3dSmrg 541428d7b3dSmrg pI810->zHandle = agpHandle; 542428d7b3dSmrg 543428d7b3dSmrg if (agpHandle != DRM_AGP_NO_HANDLE) { 544428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->DepthOffset) == 0) { 545428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 546428d7b3dSmrg "[agp] Bound depthbuffer memory\n"); 547428d7b3dSmrg pI810->DepthBuffer.Start = pI810->DepthOffset; 548428d7b3dSmrg pI810->DepthBuffer.Size = back_size; 549428d7b3dSmrg pI810->DepthBuffer.End = (pI810->DepthBuffer.Start + 550428d7b3dSmrg pI810->DepthBuffer.Size); 551428d7b3dSmrg } else { 552428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 553428d7b3dSmrg "[agp] Unable to bind depthbuffer. Disabling DRI.\n"); 554428d7b3dSmrg DRICloseScreen(pScreen); 555428d7b3dSmrg return FALSE; 556428d7b3dSmrg } 557428d7b3dSmrg } else { 558428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 559428d7b3dSmrg "[agp] Unable to allocate depthbuffer memory. Disabling DRI.\n"); 560428d7b3dSmrg DRICloseScreen(pScreen); 561428d7b3dSmrg return FALSE; 562428d7b3dSmrg } 563428d7b3dSmrg } 564428d7b3dSmrg 565428d7b3dSmrg /* Now allocate and bind the agp space. This memory will include the 566428d7b3dSmrg * regular framebuffer as well as texture memory. 567428d7b3dSmrg */ 568428d7b3dSmrg drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, 569428d7b3dSmrg (drmAddress)&agpHandle); 570428d7b3dSmrg pI810->sysmemHandle = agpHandle; 571428d7b3dSmrg 572428d7b3dSmrg if (agpHandle != DRM_AGP_NO_HANDLE) { 573428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, agpHandle, 0) == 0) { 574428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 575428d7b3dSmrg "[agp] Bound System Texture Memory\n"); 576428d7b3dSmrg } else { 577428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to bind system texture memory. Disabling DRI.\n"); 578428d7b3dSmrg DRICloseScreen(pScreen); 579428d7b3dSmrg return FALSE; 580428d7b3dSmrg } 581428d7b3dSmrg } else { 582428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to allocate system texture memory. Disabling DRI.\n"); 583428d7b3dSmrg DRICloseScreen(pScreen); 584428d7b3dSmrg return FALSE; 585428d7b3dSmrg } 586428d7b3dSmrg 587428d7b3dSmrg/* Allocate 7 or 8MB for XvMC this is setup as follows to best use tiled 588428d7b3dSmrg regions and required surface pitches. (Numbers are adjusted if the 589428d7b3dSmrg AGP region is only 32MB 590428d7b3dSmrg For numSurfaces == 6 591428d7b3dSmrg 44 - 48MB = 4MB Fence, 8 Tiles wide 592428d7b3dSmrg 43 - 44MB = 1MB Fence, 8 Tiles wide 593428d7b3dSmrg 42 - 43MB = 1MB Fence, 4 Tiles wide 594428d7b3dSmrg 41 - 42MB = 1MB Fence, 4 Tiles wide 595428d7b3dSmrg For numSurfaces == 7 596428d7b3dSmrg 44 - 48MB = 4MB Fence, 8 Tiles wide 597428d7b3dSmrg 43 - 44MB = 1MB Fence, 8 Tiles wide 598428d7b3dSmrg 42.5 - 43MB = 0.5MB Fence, 8 Tiles wide 599428d7b3dSmrg 42 - 42.5MB = 0.5MB Fence, 4 Tiles wide 600428d7b3dSmrg 40 - 42MB = 2MB Fence, 4 Tiles wide 601428d7b3dSmrg */ 602428d7b3dSmrg if (pI810->numSurfaces) { 603428d7b3dSmrg if (pI810->numSurfaces == 6) { 604428d7b3dSmrg pI810->MC.Size = 7 * 1024 * 1024; 605428d7b3dSmrg pI810->MC.Start = pI810->FbMapSize - 7 * 1024 * 1024; 606428d7b3dSmrg 607428d7b3dSmrg } 608428d7b3dSmrg if (pI810->numSurfaces == 7) { 609428d7b3dSmrg pI810->MC.Size = 8 * 1024 * 1024; 610428d7b3dSmrg pI810->MC.Start = pI810->FbMapSize - 8 * 1024 * 1024; 611428d7b3dSmrg } 612428d7b3dSmrg drmAgpAlloc(pI810->drmSubFD, pI810->MC.Size, 0, NULL, 613428d7b3dSmrg (drmAddress) &agpHandle); 614428d7b3dSmrg 615428d7b3dSmrg pI810->xvmcHandle = agpHandle; 616428d7b3dSmrg 617428d7b3dSmrg if (agpHandle != DRM_AGP_NO_HANDLE) { 618428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->MC.Start) == 0) { 619428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 620428d7b3dSmrg "GART: Allocated 7MB for HWMC\n"); 621428d7b3dSmrg pI810->MC.End = pI810->MC.Start + pI810->MC.Size; 622428d7b3dSmrg } else { 623428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC bind failed\n"); 624428d7b3dSmrg pI810->MC.Start = 0; 625428d7b3dSmrg pI810->MC.Size = 0; 626428d7b3dSmrg pI810->MC.End = 0; 627428d7b3dSmrg } 628428d7b3dSmrg } else { 629428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC alloc failed\n"); 630428d7b3dSmrg pI810->MC.Start = 0; 631428d7b3dSmrg pI810->MC.Size = 0; 632428d7b3dSmrg pI810->MC.End = 0; 633428d7b3dSmrg } 634428d7b3dSmrg pI810->xvmcContext = 0; 635428d7b3dSmrg } 636428d7b3dSmrg 637428d7b3dSmrg drmAgpAlloc(pI810->drmSubFD, 4096, 2, 638428d7b3dSmrg (unsigned long *)&pI810->CursorPhysical, 639428d7b3dSmrg (drmAddress) &agpHandle); 640428d7b3dSmrg 641428d7b3dSmrg pI810->cursorHandle = agpHandle; 642428d7b3dSmrg 643428d7b3dSmrg if (agpHandle != DRM_AGP_NO_HANDLE) { 644428d7b3dSmrg tom = sysmem_size; 645428d7b3dSmrg 646428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) { 647428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 648428d7b3dSmrg "[agp] GART: Allocated 4K for mouse cursor image\n"); 649428d7b3dSmrg pI810->CursorStart = tom; 650428d7b3dSmrg tom += 4096; 651428d7b3dSmrg } else { 652428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 653428d7b3dSmrg "[agp] GART: cursor bind failed\n"); 654428d7b3dSmrg pI810->CursorPhysical = 0; 655428d7b3dSmrg } 656428d7b3dSmrg } else { 657428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 658428d7b3dSmrg "[agp] GART: cursor alloc failed\n"); 659428d7b3dSmrg pI810->CursorPhysical = 0; 660428d7b3dSmrg } 661428d7b3dSmrg 662428d7b3dSmrg drmAgpAlloc(pI810->drmSubFD, 16384, 2, 663428d7b3dSmrg (unsigned long *)&pI810->CursorARGBPhysical, 664428d7b3dSmrg (drmAddress) &agpHandle); 665428d7b3dSmrg 666428d7b3dSmrg pI810->cursorARGBHandle = agpHandle; 667428d7b3dSmrg 668428d7b3dSmrg if (agpHandle != DRM_AGP_NO_HANDLE) { 669428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) { 670428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 671428d7b3dSmrg "[agp] GART: Allocated 16K for ARGB mouse cursor image\n"); 672428d7b3dSmrg pI810->CursorARGBStart = tom; 673428d7b3dSmrg tom += 16384; 674428d7b3dSmrg } else { 675428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 676428d7b3dSmrg "[agp] GART: ARGB cursor bind failed\n"); 677428d7b3dSmrg pI810->CursorARGBPhysical = 0; 678428d7b3dSmrg } 679428d7b3dSmrg } else { 680428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 681428d7b3dSmrg "[agp] GART: ARGB cursor alloc failed\n"); 682428d7b3dSmrg pI810->CursorARGBPhysical = 0; 683428d7b3dSmrg } 684428d7b3dSmrg 685428d7b3dSmrg /* Steal some of the excess cursor space for the overlay regs. 686428d7b3dSmrg */ 687428d7b3dSmrg pI810->OverlayPhysical = pI810->CursorPhysical + 1024; 688428d7b3dSmrg pI810->OverlayStart = pI810->CursorStart + 1024; 689428d7b3dSmrg 690428d7b3dSmrg I810SetTiledMemory(pScrn, 1, 691428d7b3dSmrg pI810->DepthBuffer.Start, 692428d7b3dSmrg i810_pitches[pitch_idx], 8 * 1024 * 1024); 693428d7b3dSmrg 694428d7b3dSmrg I810SetTiledMemory(pScrn, 2, 695428d7b3dSmrg pI810->BackBuffer.Start, 696428d7b3dSmrg i810_pitches[pitch_idx], 8 * 1024 * 1024); 697428d7b3dSmrg 698428d7b3dSmrg /* These are for HWMC surfaces */ 699428d7b3dSmrg if (pI810->numSurfaces == 6) { 700428d7b3dSmrg I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 1024 * 1024); 701428d7b3dSmrg 702428d7b3dSmrg I810SetTiledMemory(pScrn, 4, 703428d7b3dSmrg pI810->MC.Start + 1024 * 1024, 512, 1024 * 1024); 704428d7b3dSmrg 705428d7b3dSmrg I810SetTiledMemory(pScrn, 5, 706428d7b3dSmrg pI810->MC.Start + 1024 * 1024 * 2, 707428d7b3dSmrg 1024, 1024 * 1024); 708428d7b3dSmrg 709428d7b3dSmrg I810SetTiledMemory(pScrn, 6, 710428d7b3dSmrg pI810->MC.Start + 1024 * 1024 * 3, 711428d7b3dSmrg 1024, 4 * 1024 * 1024); 712428d7b3dSmrg } 713428d7b3dSmrg if (pI810->numSurfaces == 7) { 714428d7b3dSmrg I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 2 * 1024 * 1024); 715428d7b3dSmrg 716428d7b3dSmrg I810SetTiledMemory(pScrn, 4, 717428d7b3dSmrg pI810->MC.Start + 2 * 1024 * 1024, 512, 512 * 1024); 718428d7b3dSmrg 719428d7b3dSmrg I810SetTiledMemory(pScrn, 5, 720428d7b3dSmrg pI810->MC.Start + 2 * 1024 * 1024 + 512 * 1024, 721428d7b3dSmrg 1024, 512 * 1024); 722428d7b3dSmrg 723428d7b3dSmrg I810SetTiledMemory(pScrn, 6, 724428d7b3dSmrg pI810->MC.Start + 3 * 1024 * 1024, 725428d7b3dSmrg 1024, 1 * 1024 * 1024); 726428d7b3dSmrg 727428d7b3dSmrg I810SetTiledMemory(pScrn, 7, 728428d7b3dSmrg pI810->MC.Start + 4 * 1024 * 1024, 729428d7b3dSmrg 1024, 4 * 1024 * 1024); 730428d7b3dSmrg 731428d7b3dSmrg } 732428d7b3dSmrg 733428d7b3dSmrg pI810->auxPitch = i810_pitches[pitch_idx]; 734428d7b3dSmrg pI810->auxPitchBits = i810_pitch_flags[pitch_idx]; 735428d7b3dSmrg pI810->SavedDcacheMem = pI810->DcacheMem; 736428d7b3dSmrg pI810DRI->backbufferSize = pI810->BackBuffer.Size; 737428d7b3dSmrg 738428d7b3dSmrg if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BackBuffer.Start, 739428d7b3dSmrg pI810->BackBuffer.Size, DRM_AGP, 0, 740428d7b3dSmrg (drmAddress) &pI810DRI->backbuffer) < 0) { 741428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 742428d7b3dSmrg "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n"); 743428d7b3dSmrg DRICloseScreen(pScreen); 744428d7b3dSmrg return FALSE; 745428d7b3dSmrg } 746428d7b3dSmrg 747428d7b3dSmrg pI810DRI->depthbufferSize = pI810->DepthBuffer.Size; 748428d7b3dSmrg if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->DepthBuffer.Start, 749428d7b3dSmrg pI810->DepthBuffer.Size, DRM_AGP, 0, 750428d7b3dSmrg (drmAddress) &pI810DRI->depthbuffer) < 0) { 751428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 752428d7b3dSmrg "[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n"); 753428d7b3dSmrg DRICloseScreen(pScreen); 754428d7b3dSmrg return FALSE; 755428d7b3dSmrg } 756428d7b3dSmrg 757428d7b3dSmrg /* Allocate FrontBuffer etc. */ 758428d7b3dSmrg if (!I810AllocateFront(pScrn)) { 759428d7b3dSmrg DRICloseScreen(pScreen); 760428d7b3dSmrg return FALSE; 761428d7b3dSmrg } 762428d7b3dSmrg 763428d7b3dSmrg /* Allocate buffer memory */ 764428d7b3dSmrg I810AllocHigh(&(pI810->BufferMem), &(pI810->SysMem), 765428d7b3dSmrg I810_DMA_BUF_NR * I810_DMA_BUF_SZ); 766428d7b3dSmrg 767428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] Buffer map : %lx\n", 768428d7b3dSmrg pI810->BufferMem.Start); 769428d7b3dSmrg 770428d7b3dSmrg if (pI810->BufferMem.Start == 0 || 771428d7b3dSmrg pI810->BufferMem.End - pI810->BufferMem.Start > 772428d7b3dSmrg I810_DMA_BUF_NR * I810_DMA_BUF_SZ) { 773428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 774428d7b3dSmrg "[dri] Not enough memory for dma buffers. Disabling DRI.\n"); 775428d7b3dSmrg DRICloseScreen(pScreen); 776428d7b3dSmrg return FALSE; 777428d7b3dSmrg } 778428d7b3dSmrg if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BufferMem.Start, 779428d7b3dSmrg pI810->BufferMem.Size, DRM_AGP, 0, 780428d7b3dSmrg (drmAddress) &pI810->buffer_map) < 0) { 781428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 782428d7b3dSmrg "[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n"); 783428d7b3dSmrg DRICloseScreen(pScreen); 784428d7b3dSmrg return FALSE; 785428d7b3dSmrg } 786428d7b3dSmrg 787428d7b3dSmrg pI810DRI->agp_buffers = pI810->buffer_map; 788428d7b3dSmrg pI810DRI->agp_buf_size = pI810->BufferMem.Size; 789428d7b3dSmrg 790428d7b3dSmrg if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing->mem.Start, 791428d7b3dSmrg pI810->LpRing->mem.Size, DRM_AGP, 0, 792428d7b3dSmrg (drmAddress) &pI810->ring_map) < 0) { 793428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 794428d7b3dSmrg "[drm] drmAddMap(ring_map) failed. Disabling DRI.\n"); 795428d7b3dSmrg DRICloseScreen(pScreen); 796428d7b3dSmrg return FALSE; 797428d7b3dSmrg } 798428d7b3dSmrg 799428d7b3dSmrg /* Use the rest of memory for textures. */ 800428d7b3dSmrg pI810DRI->textureSize = pI810->SysMem.Size; 801428d7b3dSmrg 802428d7b3dSmrg i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS); 803428d7b3dSmrg 804428d7b3dSmrg if (i < I810_LOG_MIN_TEX_REGION_SIZE) 805428d7b3dSmrg i = I810_LOG_MIN_TEX_REGION_SIZE; 806428d7b3dSmrg 807428d7b3dSmrg pI810DRI->logTextureGranularity = i; 808428d7b3dSmrg pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i; /* truncate */ 809428d7b3dSmrg 810428d7b3dSmrg if (pI810DRI->textureSize < 512 * 1024) { 811428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 812428d7b3dSmrg "[drm] Less then 512k memory left for textures. Disabling DRI.\n"); 813428d7b3dSmrg DRICloseScreen(pScreen); 814428d7b3dSmrg return FALSE; 815428d7b3dSmrg } 816428d7b3dSmrg 817428d7b3dSmrg if (!I810AllocLow(&(pI810->TexMem), &(pI810->SysMem), pI810DRI->textureSize)) { 818428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 819428d7b3dSmrg "[agp] Texure memory allocation failed\n"); 820428d7b3dSmrg DRICloseScreen(pScreen); 821428d7b3dSmrg return FALSE; 822428d7b3dSmrg } 823428d7b3dSmrg 824428d7b3dSmrg if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->TexMem.Start, 825428d7b3dSmrg pI810->TexMem.Size, DRM_AGP, 0, 826428d7b3dSmrg (drmAddress) &pI810DRI->textures) < 0) { 827428d7b3dSmrg xf86DrvMsg(pScreen->myNum, X_ERROR, 828428d7b3dSmrg "[drm] drmAddMap(textures) failed. Disabling DRI.\n"); 829428d7b3dSmrg DRICloseScreen(pScreen); 830428d7b3dSmrg return FALSE; 831428d7b3dSmrg } 832428d7b3dSmrg 833428d7b3dSmrg if ((bufs = drmAddBufs(pI810->drmSubFD, 834428d7b3dSmrg I810_DMA_BUF_NR, 835428d7b3dSmrg I810_DMA_BUF_SZ, 836428d7b3dSmrg DRM_AGP_BUFFER, pI810->BufferMem.Start)) <= 0) { 837428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 838428d7b3dSmrg "[drm] failure adding %d %d byte DMA buffers. Disabling DRI.\n", 839428d7b3dSmrg I810_DMA_BUF_NR, I810_DMA_BUF_SZ); 840428d7b3dSmrg DRICloseScreen(pScreen); 841428d7b3dSmrg return FALSE; 842428d7b3dSmrg } 843428d7b3dSmrg 844428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 845428d7b3dSmrg "[drm] added %d %d byte DMA buffers\n", bufs, I810_DMA_BUF_SZ); 846428d7b3dSmrg 847428d7b3dSmrg I810InitDma(pScrn); 848428d7b3dSmrg 849428d7b3dSmrg /* Okay now initialize the dma engine */ 850428d7b3dSmrg 851428d7b3dSmrg if (!pI810DRI->irq) { 852428d7b3dSmrg pI810DRI->irq = drmGetInterruptFromBusID(pI810->drmSubFD, 853428d7b3dSmrg ((pI810->PciInfo->domain << 8) | 854428d7b3dSmrg pI810->PciInfo->bus), 855428d7b3dSmrg pI810->PciInfo->dev, 856428d7b3dSmrg pI810->PciInfo->func 857428d7b3dSmrg ); 858428d7b3dSmrg if ((drmCtlInstHandler(pI810->drmSubFD, pI810DRI->irq)) != 0) { 859428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 860428d7b3dSmrg "[drm] failure adding irq handler, there is a device " 861428d7b3dSmrg "already using that irq\n Consider rearranging your " 862428d7b3dSmrg "PCI cards. Disabling DRI.\n"); 863428d7b3dSmrg DRICloseScreen(pScreen); 864428d7b3dSmrg return FALSE; 865428d7b3dSmrg } 866428d7b3dSmrg } 867428d7b3dSmrg 868428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 869428d7b3dSmrg "[drm] dma control initialized, using IRQ %d\n", pI810DRI->irq); 870428d7b3dSmrg 871428d7b3dSmrg pI810DRI->deviceID = pI810->PciInfo->device_id; 872428d7b3dSmrg pI810DRI->width = pScrn->virtualX; 873428d7b3dSmrg pI810DRI->height = pScrn->virtualY; 874428d7b3dSmrg pI810DRI->mem = pScrn->videoRam * 1024; 875428d7b3dSmrg pI810DRI->cpp = pI810->cpp; 876428d7b3dSmrg 877428d7b3dSmrg pI810DRI->fbOffset = pI810->FrontBuffer.Start; 878428d7b3dSmrg pI810DRI->fbStride = pI810->auxPitch; 879428d7b3dSmrg 880428d7b3dSmrg pI810DRI->bitsPerPixel = pScrn->bitsPerPixel; 881428d7b3dSmrg 882428d7b3dSmrg pI810DRI->textureOffset = pI810->TexMem.Start; 883428d7b3dSmrg 884428d7b3dSmrg pI810DRI->backOffset = pI810->BackBuffer.Start; 885428d7b3dSmrg pI810DRI->depthOffset = pI810->DepthBuffer.Start; 886428d7b3dSmrg 887428d7b3dSmrg pI810DRI->ringOffset = pI810->LpRing->mem.Start; 888428d7b3dSmrg pI810DRI->ringSize = pI810->LpRing->mem.Size; 889428d7b3dSmrg 890428d7b3dSmrg pI810DRI->auxPitch = pI810->auxPitch; 891428d7b3dSmrg pI810DRI->auxPitchBits = pI810->auxPitchBits; 892428d7b3dSmrg pI810DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); 893428d7b3dSmrg 894428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 895428d7b3dSmrg "[dri] visual configs initialized.\n"); 896428d7b3dSmrg pI810->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; 897428d7b3dSmrg 898428d7b3dSmrg return TRUE; 899428d7b3dSmrg} 900428d7b3dSmrg 901428d7b3dSmrgvoid 902428d7b3dSmrgI810DRICloseScreen(ScreenPtr pScreen) 903428d7b3dSmrg{ 904428d7b3dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 905428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 906428d7b3dSmrg 907428d7b3dSmrg if (pI810->pDRIInfo) { 908428d7b3dSmrg I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate; 909428d7b3dSmrg 910428d7b3dSmrg if (pI810DRI) { 911428d7b3dSmrg if (pI810DRI->irq) { 912428d7b3dSmrg drmCtlUninstHandler(pI810->drmSubFD); 913428d7b3dSmrg pI810DRI->irq = 0; 914428d7b3dSmrg } 915428d7b3dSmrg 916428d7b3dSmrg free(pI810->pDRIInfo->devPrivate); 917428d7b3dSmrg pI810->pDRIInfo->devPrivate = NULL; 918428d7b3dSmrg } 919428d7b3dSmrg 920428d7b3dSmrg I810CleanupDma(pScrn); 921428d7b3dSmrg 922428d7b3dSmrg DRICloseScreen(pScreen); 923428d7b3dSmrg DRIDestroyInfoRec(pI810->pDRIInfo); 924428d7b3dSmrg pI810->pDRIInfo = NULL; 925428d7b3dSmrg } 926428d7b3dSmrg 927428d7b3dSmrg if (pI810->dcacheHandle!=DRM_AGP_NO_HANDLE) 928428d7b3dSmrg drmAgpFree(pI810->drmSubFD, pI810->dcacheHandle); 929428d7b3dSmrg if (pI810->backHandle!=DRM_AGP_NO_HANDLE) 930428d7b3dSmrg drmAgpFree(pI810->drmSubFD, pI810->backHandle); 931428d7b3dSmrg if (pI810->zHandle!=DRM_AGP_NO_HANDLE) 932428d7b3dSmrg drmAgpFree(pI810->drmSubFD, pI810->zHandle); 933428d7b3dSmrg if (pI810->cursorHandle!=DRM_AGP_NO_HANDLE) 934428d7b3dSmrg drmAgpFree(pI810->drmSubFD, pI810->cursorHandle); 935428d7b3dSmrg if (pI810->xvmcHandle!=DRM_AGP_NO_HANDLE) 936428d7b3dSmrg drmAgpFree(pI810->drmSubFD, pI810->xvmcHandle); 937428d7b3dSmrg if (pI810->sysmemHandle!=DRM_AGP_NO_HANDLE) 938428d7b3dSmrg drmAgpFree(pI810->drmSubFD, pI810->sysmemHandle); 939428d7b3dSmrg 940428d7b3dSmrg if (pI810->agpAcquired == TRUE) 941428d7b3dSmrg drmAgpRelease(pI810->drmSubFD); 942428d7b3dSmrg 943428d7b3dSmrg pI810->backHandle = DRM_AGP_NO_HANDLE; 944428d7b3dSmrg pI810->zHandle = DRM_AGP_NO_HANDLE; 945428d7b3dSmrg pI810->cursorHandle = DRM_AGP_NO_HANDLE; 946428d7b3dSmrg pI810->xvmcHandle = DRM_AGP_NO_HANDLE; 947428d7b3dSmrg pI810->sysmemHandle = DRM_AGP_NO_HANDLE; 948428d7b3dSmrg pI810->agpAcquired = FALSE; 949428d7b3dSmrg pI810->dcacheHandle = DRM_AGP_NO_HANDLE; 950428d7b3dSmrg} 951428d7b3dSmrg 952428d7b3dSmrgstatic Bool 953428d7b3dSmrgI810CreateContext(ScreenPtr pScreen, VisualPtr visual, 954428d7b3dSmrg drm_context_t hwContext, void *pVisualConfigPriv, 955428d7b3dSmrg DRIContextType contextStore) 956428d7b3dSmrg{ 957428d7b3dSmrg return TRUE; 958428d7b3dSmrg} 959428d7b3dSmrg 960428d7b3dSmrgstatic void 961428d7b3dSmrgI810DestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 962428d7b3dSmrg DRIContextType contextStore) 963428d7b3dSmrg{ 964428d7b3dSmrg} 965428d7b3dSmrg 966428d7b3dSmrgBool 967428d7b3dSmrgI810DRIFinishScreenInit(ScreenPtr pScreen) 968428d7b3dSmrg{ 969428d7b3dSmrg I810SAREARec *sPriv = (I810SAREARec *) DRIGetSAREAPrivate(pScreen); 970428d7b3dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 971428d7b3dSmrg I810Ptr info = I810PTR(pScrn); 972428d7b3dSmrg 973428d7b3dSmrg memset(sPriv, 0, sizeof(*sPriv)); 974428d7b3dSmrg 975428d7b3dSmrg /* Have shadow run only while there is 3d active. 976428d7b3dSmrg */ 977428d7b3dSmrg if (info->allowPageFlip && info->drmMinor >= 3) { 978428d7b3dSmrg ShadowFBInit( pScreen, I810DRIRefreshArea ); 979428d7b3dSmrg } 980428d7b3dSmrg else 981428d7b3dSmrg info->allowPageFlip = 0; 982428d7b3dSmrg return DRIFinishScreenInit(pScreen); 983428d7b3dSmrg} 984428d7b3dSmrg 985428d7b3dSmrgvoid 986428d7b3dSmrgI810DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 987428d7b3dSmrg DRIContextType oldContextType, void *oldContext, 988428d7b3dSmrg DRIContextType newContextType, void *newContext) 989428d7b3dSmrg{ 990428d7b3dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 991428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 992428d7b3dSmrg 993428d7b3dSmrg if (syncType == DRI_3D_SYNC && 994428d7b3dSmrg oldContextType == DRI_2D_CONTEXT && newContextType == DRI_2D_CONTEXT) { 995428d7b3dSmrg if (I810_DEBUG & DEBUG_VERBOSE_DRI) 996428d7b3dSmrg ErrorF("I810DRISwapContext (in)\n"); 997428d7b3dSmrg 998428d7b3dSmrg if (!pScrn->vtSema) 999428d7b3dSmrg return; 1000428d7b3dSmrg pI810->LockHeld = 1; 1001428d7b3dSmrg I810RefreshRing(pScrn); 1002428d7b3dSmrg } else if (syncType == DRI_2D_SYNC && 1003428d7b3dSmrg oldContextType == DRI_NO_CONTEXT && 1004428d7b3dSmrg newContextType == DRI_2D_CONTEXT) { 1005428d7b3dSmrg pI810->LockHeld = 0; 1006428d7b3dSmrg if (I810_DEBUG & DEBUG_VERBOSE_DRI) 1007428d7b3dSmrg ErrorF("I810DRISwapContext (out)\n"); 1008428d7b3dSmrg } else if (I810_DEBUG & DEBUG_VERBOSE_DRI) 1009428d7b3dSmrg ErrorF("I810DRISwapContext (other)\n"); 1010428d7b3dSmrg} 1011428d7b3dSmrg 1012428d7b3dSmrgstatic void 1013428d7b3dSmrgI810DRISetNeedSync(ScrnInfoPtr pScrn) 1014428d7b3dSmrg{ 1015428d7b3dSmrg#ifdef HAVE_XAA_H 1016428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 1017428d7b3dSmrg if (pI810->AccelInfoRec) 1018428d7b3dSmrg pI810->AccelInfoRec->NeedToSync = TRUE; 1019428d7b3dSmrg#endif 1020428d7b3dSmrg} 1021428d7b3dSmrg 1022428d7b3dSmrgstatic void 1023428d7b3dSmrgI810DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) 1024428d7b3dSmrg{ 1025428d7b3dSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 1026428d7b3dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1027428d7b3dSmrg BoxPtr pbox = REGION_RECTS(prgn); 1028428d7b3dSmrg int nbox = REGION_NUM_RECTS(prgn); 1029428d7b3dSmrg 1030428d7b3dSmrg if (I810_DEBUG & DEBUG_VERBOSE_DRI) 1031428d7b3dSmrg ErrorF("I810DRIInitBuffers\n"); 1032428d7b3dSmrg 1033428d7b3dSmrg I810SetupForSolidFill(pScrn, 0, GXcopy, -1); 1034428d7b3dSmrg while (nbox--) { 1035428d7b3dSmrg I810SelectBuffer(pScrn, I810_SELECT_BACK); 1036428d7b3dSmrg I810SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, 1037428d7b3dSmrg pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 1038428d7b3dSmrg pbox++; 1039428d7b3dSmrg } 1040428d7b3dSmrg 1041428d7b3dSmrg /* Clear the depth buffer - uses 0xffff rather than 0. 1042428d7b3dSmrg */ 1043428d7b3dSmrg pbox = REGION_RECTS(prgn); 1044428d7b3dSmrg nbox = REGION_NUM_RECTS(prgn); 1045428d7b3dSmrg I810SelectBuffer(pScrn, I810_SELECT_DEPTH); 1046428d7b3dSmrg I810SetupForSolidFill(pScrn, 0xffff, GXcopy, -1); 1047428d7b3dSmrg while (nbox--) { 1048428d7b3dSmrg I810SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, 1049428d7b3dSmrg pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 1050428d7b3dSmrg pbox++; 1051428d7b3dSmrg } 1052428d7b3dSmrg I810SelectBuffer(pScrn, I810_SELECT_FRONT); 1053428d7b3dSmrg 1054428d7b3dSmrg I810DRISetNeedSync(pScrn); 1055428d7b3dSmrg} 1056428d7b3dSmrg 1057428d7b3dSmrg/* This routine is a modified form of XAADoBitBlt with the calls to 1058428d7b3dSmrg * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source 1059428d7b3dSmrg * instead of destination. My origin is upside down so the ydir cases 1060428d7b3dSmrg * are reversed. 1061428d7b3dSmrg * 1062428d7b3dSmrg * KW: can you believe that this is called even when a 2d window moves? 1063428d7b3dSmrg */ 1064428d7b3dSmrgstatic void 1065428d7b3dSmrgI810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 1066428d7b3dSmrg RegionPtr prgnSrc, CARD32 index) 1067428d7b3dSmrg{ 1068428d7b3dSmrg ScreenPtr pScreen = pParent->drawable.pScreen; 1069428d7b3dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1070428d7b3dSmrg BoxPtr pboxTmp, pboxNext, pboxBase; 1071428d7b3dSmrg DDXPointPtr pptTmp, pptNew2 = NULL; 1072428d7b3dSmrg int xdir, ydir; 1073428d7b3dSmrg 1074428d7b3dSmrg int screenwidth = pScrn->virtualX; 1075428d7b3dSmrg int screenheight = pScrn->virtualY; 1076428d7b3dSmrg 1077428d7b3dSmrg BoxPtr pbox = REGION_RECTS(prgnSrc); 1078428d7b3dSmrg int nbox = REGION_NUM_RECTS(prgnSrc); 1079428d7b3dSmrg 1080428d7b3dSmrg BoxPtr pboxNew1 = NULL; 1081428d7b3dSmrg BoxPtr pboxNew2 = NULL; 1082428d7b3dSmrg DDXPointPtr pptNew1 = NULL; 1083428d7b3dSmrg DDXPointPtr pptSrc = &ptOldOrg; 1084428d7b3dSmrg 1085428d7b3dSmrg int dx = pParent->drawable.x - ptOldOrg.x; 1086428d7b3dSmrg int dy = pParent->drawable.y - ptOldOrg.y; 1087428d7b3dSmrg 1088428d7b3dSmrg /* If the copy will overlap in Y, reverse the order */ 1089428d7b3dSmrg if (dy > 0) { 1090428d7b3dSmrg ydir = -1; 1091428d7b3dSmrg 1092428d7b3dSmrg if (nbox > 1) { 1093428d7b3dSmrg /* Keep ordering in each band, reverse order of bands */ 1094428d7b3dSmrg pboxNew1 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); 1095428d7b3dSmrg if (!pboxNew1) 1096428d7b3dSmrg return; 1097428d7b3dSmrg pptNew1 = (DDXPointPtr) malloc(sizeof(DDXPointRec) * nbox); 1098428d7b3dSmrg if (!pptNew1) { 1099428d7b3dSmrg free(pboxNew1); 1100428d7b3dSmrg return; 1101428d7b3dSmrg } 1102428d7b3dSmrg pboxBase = pboxNext = pbox + nbox - 1; 1103428d7b3dSmrg while (pboxBase >= pbox) { 1104428d7b3dSmrg while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) 1105428d7b3dSmrg pboxNext--; 1106428d7b3dSmrg pboxTmp = pboxNext + 1; 1107428d7b3dSmrg if (pptSrc == &ptOldOrg) { 1108428d7b3dSmrg if (pboxTmp <= pboxBase) { 1109428d7b3dSmrg *pboxNew1++ = *pboxTmp; 1110428d7b3dSmrg *pptNew1++ = *pptSrc; 1111428d7b3dSmrg } 1112428d7b3dSmrg } else { 1113428d7b3dSmrg pptTmp = pptSrc + (pboxTmp - pbox); 1114428d7b3dSmrg while (pboxTmp <= pboxBase) { 1115428d7b3dSmrg *pboxNew1++ = *pboxTmp++; 1116428d7b3dSmrg *pptNew1++ = *pptTmp++; 1117428d7b3dSmrg } 1118428d7b3dSmrg } 1119428d7b3dSmrg pboxBase = pboxNext; 1120428d7b3dSmrg } 1121428d7b3dSmrg pboxNew1 -= nbox; 1122428d7b3dSmrg pbox = pboxNew1; 1123428d7b3dSmrg pptNew1 -= nbox; 1124428d7b3dSmrg pptSrc = pptNew1; 1125428d7b3dSmrg } 1126428d7b3dSmrg } else { 1127428d7b3dSmrg /* No changes required */ 1128428d7b3dSmrg ydir = 1; 1129428d7b3dSmrg } 1130428d7b3dSmrg 1131428d7b3dSmrg /* If the regions will overlap in X, reverse the order */ 1132428d7b3dSmrg if (dx > 0) { 1133428d7b3dSmrg xdir = -1; 1134428d7b3dSmrg 1135428d7b3dSmrg if (nbox > 1) { 1136428d7b3dSmrg /*reverse orderof rects in each band */ 1137428d7b3dSmrg pboxNew2 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); 1138428d7b3dSmrg pptNew2 = (DDXPointPtr) malloc(sizeof(DDXPointRec) * nbox); 1139428d7b3dSmrg if (!pboxNew2 || !pptNew2) { 1140428d7b3dSmrg if (pptNew2) 1141428d7b3dSmrg free(pptNew2); 1142428d7b3dSmrg if (pboxNew2) 1143428d7b3dSmrg free(pboxNew2); 1144428d7b3dSmrg if (pboxNew1) { 1145428d7b3dSmrg free(pptNew1); 1146428d7b3dSmrg free(pboxNew1); 1147428d7b3dSmrg } 1148428d7b3dSmrg return; 1149428d7b3dSmrg } 1150428d7b3dSmrg pboxBase = pboxNext = pbox; 1151428d7b3dSmrg while (pboxBase < pbox + nbox) { 1152428d7b3dSmrg while ((pboxNext < pbox + nbox) && (pboxNext->y1 == pboxBase->y1)) 1153428d7b3dSmrg pboxNext++; 1154428d7b3dSmrg pboxTmp = pboxNext; 1155428d7b3dSmrg pptTmp = pptSrc + (pboxTmp - pbox); 1156428d7b3dSmrg while (pboxTmp != pboxBase) { 1157428d7b3dSmrg *pboxNew2++ = *--pboxTmp; 1158428d7b3dSmrg *pptNew2++ = *--pptTmp; 1159428d7b3dSmrg } 1160428d7b3dSmrg pboxBase = pboxNext; 1161428d7b3dSmrg } 1162428d7b3dSmrg pboxNew2 -= nbox; 1163428d7b3dSmrg pbox = pboxNew2; 1164428d7b3dSmrg pptNew2 -= nbox; 1165428d7b3dSmrg pptSrc = pptNew2; 1166428d7b3dSmrg } 1167428d7b3dSmrg } else { 1168428d7b3dSmrg /* No changes are needed */ 1169428d7b3dSmrg xdir = 1; 1170428d7b3dSmrg } 1171428d7b3dSmrg 1172428d7b3dSmrg /* SelectBuffer isn't really a good concept for the i810. 1173428d7b3dSmrg */ 1174428d7b3dSmrg I810EmitFlush(pScrn); 1175428d7b3dSmrg I810SetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1); 1176428d7b3dSmrg for (; nbox--; pbox++) { 1177428d7b3dSmrg 1178428d7b3dSmrg int x1 = pbox->x1; 1179428d7b3dSmrg int y1 = pbox->y1; 1180428d7b3dSmrg int destx = x1 + dx; 1181428d7b3dSmrg int desty = y1 + dy; 1182428d7b3dSmrg int w = pbox->x2 - x1 + 1; 1183428d7b3dSmrg int h = pbox->y2 - y1 + 1; 1184428d7b3dSmrg 1185428d7b3dSmrg if (destx < 0) 1186428d7b3dSmrg x1 -= destx, w += destx, destx = 0; 1187428d7b3dSmrg if (desty < 0) 1188428d7b3dSmrg y1 -= desty, h += desty, desty = 0; 1189428d7b3dSmrg if (destx + w > screenwidth) 1190428d7b3dSmrg w = screenwidth - destx; 1191428d7b3dSmrg if (desty + h > screenheight) 1192428d7b3dSmrg h = screenheight - desty; 1193428d7b3dSmrg if (w <= 0) 1194428d7b3dSmrg continue; 1195428d7b3dSmrg if (h <= 0) 1196428d7b3dSmrg continue; 1197428d7b3dSmrg 1198428d7b3dSmrg if (I810_DEBUG & DEBUG_VERBOSE_DRI) 1199428d7b3dSmrg ErrorF("MoveBuffers %d,%d %dx%d dx: %d dy: %d\n", 1200428d7b3dSmrg x1, y1, w, h, dx, dy); 1201428d7b3dSmrg 1202428d7b3dSmrg I810SelectBuffer(pScrn, I810_SELECT_BACK); 1203428d7b3dSmrg I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); 1204428d7b3dSmrg I810SelectBuffer(pScrn, I810_SELECT_DEPTH); 1205428d7b3dSmrg I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); 1206428d7b3dSmrg } 1207428d7b3dSmrg I810SelectBuffer(pScrn, I810_SELECT_FRONT); 1208428d7b3dSmrg I810EmitFlush(pScrn); 1209428d7b3dSmrg 1210428d7b3dSmrg if (pboxNew2) { 1211428d7b3dSmrg free(pptNew2); 1212428d7b3dSmrg free(pboxNew2); 1213428d7b3dSmrg } 1214428d7b3dSmrg if (pboxNew1) { 1215428d7b3dSmrg free(pptNew1); 1216428d7b3dSmrg free(pboxNew1); 1217428d7b3dSmrg } 1218428d7b3dSmrg 1219428d7b3dSmrg I810DRISetNeedSync(pScrn); 1220428d7b3dSmrg} 1221428d7b3dSmrg 1222428d7b3dSmrg 1223428d7b3dSmrg/* Use the miext/shadow module to maintain a list of dirty rectangles. 1224428d7b3dSmrg * These are blitted to the back buffer to keep both buffers clean 1225428d7b3dSmrg * during page-flipping when the 3d application isn't fullscreen. 1226428d7b3dSmrg * 1227428d7b3dSmrg * Unlike most use of the shadow code, both buffers are in video memory. 1228428d7b3dSmrg * 1229428d7b3dSmrg * An alternative to this would be to organize for all on-screen drawing 1230428d7b3dSmrg * operations to be duplicated for the two buffers. That might be 1231428d7b3dSmrg * faster, but seems like a lot more work... 1232428d7b3dSmrg */ 1233428d7b3dSmrg 1234428d7b3dSmrg 1235428d7b3dSmrg/* This should be done *before* XAA syncs or fires its buffer. 1236428d7b3dSmrg * Otherwise will have to fire it again??? 1237428d7b3dSmrg */ 1238428d7b3dSmrgstatic void I810DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 1239428d7b3dSmrg{ 1240428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 1241428d7b3dSmrg int i; 1242428d7b3dSmrg I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); 1243428d7b3dSmrg unsigned int br13; 1244428d7b3dSmrg int cpp=2; 1245428d7b3dSmrg 1246428d7b3dSmrg 1247428d7b3dSmrg /* Don't want to do this when no 3d is active and pages are 1248428d7b3dSmrg * right-way-round 1249428d7b3dSmrg */ 1250428d7b3dSmrg if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) 1251428d7b3dSmrg return; 1252428d7b3dSmrg 1253428d7b3dSmrg br13 = (pI810->auxPitch) | (0xcc << 16); 1254428d7b3dSmrg 1255428d7b3dSmrg for (i = 0 ; i < num ; i++, pbox++) { 1256428d7b3dSmrg unsigned int w = min(pbox->y2, pScrn->virtualY-1) - max(pbox->y1, 0) + 1; 1257428d7b3dSmrg unsigned int h = min(pbox->x2, pScrn->virtualX-1) - max(pbox->x1, 0) + 1; 1258428d7b3dSmrg unsigned int dst = max(pbox->x1, 0)*cpp + (max(pbox->y1, 0)*pI810->auxPitch); 1259428d7b3dSmrg 1260428d7b3dSmrg BEGIN_LP_RING(6); 1261428d7b3dSmrg 1262428d7b3dSmrg OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); 1263428d7b3dSmrg OUT_RING(br13); 1264428d7b3dSmrg OUT_RING( (h<<16) | (w*cpp) ); 1265428d7b3dSmrg OUT_RING(pI810->BackBuffer.Start + dst); 1266428d7b3dSmrg OUT_RING(br13 & 0xffff); 1267428d7b3dSmrg OUT_RING(dst); 1268428d7b3dSmrg 1269428d7b3dSmrg ADVANCE_LP_RING(); 1270428d7b3dSmrg } 1271428d7b3dSmrg 1272428d7b3dSmrg} 1273428d7b3dSmrg 1274428d7b3dSmrgstatic void I810EnablePageFlip(ScreenPtr pScreen) 1275428d7b3dSmrg{ 1276428d7b3dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1277428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 1278428d7b3dSmrg I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); 1279428d7b3dSmrg int cpp=2; 1280428d7b3dSmrg pSAREAPriv->pf_enabled = pI810->allowPageFlip; 1281428d7b3dSmrg pSAREAPriv->pf_active = 0; 1282428d7b3dSmrg 1283428d7b3dSmrg if (pI810->allowPageFlip) { 1284428d7b3dSmrg unsigned int br13 = pI810->auxPitch | (0xcc << 16); 1285428d7b3dSmrg 1286428d7b3dSmrg BEGIN_LP_RING(6); 1287428d7b3dSmrg 1288428d7b3dSmrg OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); 1289428d7b3dSmrg OUT_RING(br13); 1290428d7b3dSmrg OUT_RING((pScrn->virtualY << 16) | (pScrn->virtualX*cpp)); 1291428d7b3dSmrg OUT_RING(pI810->BackBuffer.Start); 1292428d7b3dSmrg OUT_RING(br13 & 0xFFFF); 1293428d7b3dSmrg OUT_RING(0); 1294428d7b3dSmrg ADVANCE_LP_RING(); 1295428d7b3dSmrg 1296428d7b3dSmrg pSAREAPriv->pf_active = 1; 1297428d7b3dSmrg } 1298428d7b3dSmrg 1299428d7b3dSmrg} 1300428d7b3dSmrg 1301428d7b3dSmrgstatic void I810DisablePageFlip(ScreenPtr pScreen) 1302428d7b3dSmrg{ 1303428d7b3dSmrg I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); 1304428d7b3dSmrg 1305428d7b3dSmrg pSAREAPriv->pf_active=0; 1306428d7b3dSmrg} 1307428d7b3dSmrg 1308428d7b3dSmrgstatic void I810DRITransitionSingleToMulti3d(ScreenPtr pScreen) 1309428d7b3dSmrg{ 1310428d7b3dSmrg /* Tell the clients not to pageflip. How? 1311428d7b3dSmrg * -- Field in sarea, plus bumping the window counters. 1312428d7b3dSmrg * -- DRM needs to cope with Front-to-Back swapbuffers. 1313428d7b3dSmrg */ 1314428d7b3dSmrg I810DisablePageFlip(pScreen); 1315428d7b3dSmrg} 1316428d7b3dSmrg 1317428d7b3dSmrgstatic void I810DRITransitionMultiToSingle3d(ScreenPtr pScreen) 1318428d7b3dSmrg{ 1319428d7b3dSmrg /* Let the remaining 3d app start page flipping again */ 1320428d7b3dSmrg I810EnablePageFlip(pScreen); 1321428d7b3dSmrg} 1322428d7b3dSmrg 1323428d7b3dSmrgstatic void I810DRITransitionTo3d(ScreenPtr pScreen) 1324428d7b3dSmrg{ 1325428d7b3dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1326428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 1327428d7b3dSmrg 1328428d7b3dSmrg I810EnablePageFlip(pScreen); 1329428d7b3dSmrg pI810->have3DWindows = 1; 1330428d7b3dSmrg} 1331428d7b3dSmrg 1332428d7b3dSmrgstatic void I810DRITransitionTo2d(ScreenPtr pScreen) 1333428d7b3dSmrg{ 1334428d7b3dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1335428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 1336428d7b3dSmrg I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); 1337428d7b3dSmrg 1338428d7b3dSmrg /* Try flipping back to the front page if necessary */ 1339428d7b3dSmrg if (pSAREAPriv->pf_current_page == 1) 1340428d7b3dSmrg drmCommandNone(pI810->drmSubFD, DRM_I810_FLIP); 1341428d7b3dSmrg 1342428d7b3dSmrg /* Shut down shadowing if we've made it back to the front page */ 1343428d7b3dSmrg if (pSAREAPriv->pf_current_page == 0) { 1344428d7b3dSmrg I810DisablePageFlip(pScreen); 1345428d7b3dSmrg } 1346428d7b3dSmrg pI810->have3DWindows = 0; 1347428d7b3dSmrg} 1348428d7b3dSmrg 1349428d7b3dSmrgBool 1350428d7b3dSmrgI810DRILeave(ScrnInfoPtr pScrn) 1351428d7b3dSmrg{ 1352428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 1353428d7b3dSmrg 1354428d7b3dSmrg if (pI810->directRenderingEnabled) { 1355428d7b3dSmrg if (pI810->dcacheHandle != 0) 1356428d7b3dSmrg if (drmAgpUnbind(pI810->drmSubFD, pI810->dcacheHandle) != 0) { 1357428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 1358428d7b3dSmrg return FALSE; 1359428d7b3dSmrg } 1360428d7b3dSmrg if (pI810->backHandle != 0) 1361428d7b3dSmrg if (drmAgpUnbind(pI810->drmSubFD, pI810->backHandle) != 0) { 1362428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 1363428d7b3dSmrg return FALSE; 1364428d7b3dSmrg } 1365428d7b3dSmrg if (pI810->zHandle != 0) 1366428d7b3dSmrg if (drmAgpUnbind(pI810->drmSubFD, pI810->zHandle) != 0) { 1367428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 1368428d7b3dSmrg return FALSE; 1369428d7b3dSmrg } 1370428d7b3dSmrg if (pI810->sysmemHandle != 0) 1371428d7b3dSmrg if (drmAgpUnbind(pI810->drmSubFD, pI810->sysmemHandle) != 0) { 1372428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 1373428d7b3dSmrg return FALSE; 1374428d7b3dSmrg } 1375428d7b3dSmrg if (pI810->xvmcHandle != 0) 1376428d7b3dSmrg if (drmAgpUnbind(pI810->drmSubFD, pI810->xvmcHandle) != 0) { 1377428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 1378428d7b3dSmrg return FALSE; 1379428d7b3dSmrg } 1380428d7b3dSmrg if (pI810->cursorHandle != 0) 1381428d7b3dSmrg if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorHandle) != 0) { 1382428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 1383428d7b3dSmrg return FALSE; 1384428d7b3dSmrg } 1385428d7b3dSmrg if (pI810->cursorARGBHandle != 0) 1386428d7b3dSmrg if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorARGBHandle) != 0) { 1387428d7b3dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); 1388428d7b3dSmrg return FALSE; 1389428d7b3dSmrg } 1390428d7b3dSmrg if (pI810->agpAcquired == TRUE) 1391428d7b3dSmrg drmAgpRelease(pI810->drmSubFD); 1392428d7b3dSmrg pI810->agpAcquired = FALSE; 1393428d7b3dSmrg } 1394428d7b3dSmrg return TRUE; 1395428d7b3dSmrg} 1396428d7b3dSmrg 1397428d7b3dSmrgBool 1398428d7b3dSmrgI810DRIEnter(ScrnInfoPtr pScrn) 1399428d7b3dSmrg{ 1400428d7b3dSmrg I810Ptr pI810 = I810PTR(pScrn); 1401428d7b3dSmrg 1402428d7b3dSmrg if (pI810->directRenderingEnabled) { 1403428d7b3dSmrg 1404428d7b3dSmrg if (pI810->agpAcquired == FALSE) 1405428d7b3dSmrg drmAgpAcquire(pI810->drmSubFD); 1406428d7b3dSmrg pI810->agpAcquired = TRUE; 1407428d7b3dSmrg if (pI810->dcacheHandle != 0) 1408428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, pI810->dcacheHandle, 1409428d7b3dSmrg pI810->DepthOffset) != 0) 1410428d7b3dSmrg return FALSE; 1411428d7b3dSmrg if (pI810->backHandle != 0) 1412428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, pI810->backHandle, 1413428d7b3dSmrg pI810->BackOffset) != 0) 1414428d7b3dSmrg return FALSE; 1415428d7b3dSmrg if (pI810->zHandle != 0) 1416428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, pI810->zHandle, 1417428d7b3dSmrg pI810->DepthOffset) != 0) 1418428d7b3dSmrg return FALSE; 1419428d7b3dSmrg if (pI810->sysmemHandle != 0) 1420428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, pI810->sysmemHandle, 0) != 0) 1421428d7b3dSmrg return FALSE; 1422428d7b3dSmrg if (pI810->xvmcHandle != 0) 1423428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, pI810->xvmcHandle, 1424428d7b3dSmrg pI810->MC.Start) != 0) 1425428d7b3dSmrg return FALSE; 1426428d7b3dSmrg if (pI810->cursorHandle != 0) 1427428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, pI810->cursorHandle, 1428428d7b3dSmrg pI810->CursorStart) != 0) 1429428d7b3dSmrg return FALSE; 1430428d7b3dSmrg if (pI810->cursorARGBHandle != 0) 1431428d7b3dSmrg if (drmAgpBind(pI810->drmSubFD, pI810->cursorARGBHandle, 1432428d7b3dSmrg pI810->CursorARGBStart) != 0) 1433428d7b3dSmrg return FALSE; 1434428d7b3dSmrg } 1435428d7b3dSmrg 1436428d7b3dSmrg I810SelectBuffer(pScrn, I810_SELECT_FRONT); 1437428d7b3dSmrg return TRUE; 1438428d7b3dSmrg} 1439