? Makefile ? i810.4.html ? i810._man Index: i830.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h,v retrieving revision 1.12 diff -u -r1.12 i830.h --- i830.h 31 Jul 2005 17:19:29 -0000 1.12 +++ i830.h 14 Aug 2005 20:12:54 -0000 @@ -68,6 +68,12 @@ #include "i830_dri.h" #endif +#if 1 /* XF86EXA */ +#define I830_USE_EXA +#include "../../exa/exa.h" +#endif + +#define I830_USE_XAA #include "common.h" /* I830 Video BIOS support */ @@ -264,13 +270,20 @@ I830RegRec SavedReg; I830RegRec ModeReg; + Bool useEXA; Bool noAccel; Bool SWCursor; Bool cursorOn; +#ifdef I830_USE_XAA XAAInfoRecPtr AccelInfoRec; +#endif xf86CursorInfoPtr CursorInfoRec; CloseScreenProcPtr CloseScreen; +#ifdef I830_USE_EXA + ExaDriverPtr EXADriverPtr; +#endif + I830WriteIndexedByteFunc writeControl; I830ReadIndexedByteFunc readControl; I830WriteByteFunc writeStandard; Index: i830_accel.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c,v retrieving revision 1.5 diff -u -r1.5 i830_accel.c --- i830_accel.c 11 Jul 2005 02:29:51 -0000 1.5 +++ i830_accel.c 14 Aug 2005 20:12:54 -0000 @@ -112,7 +112,9 @@ DRICloseScreen(screenInfo.screens[pScrn->scrnIndex]); } #endif +#ifdef I830_USE_XAA pI830->AccelInfoRec = NULL; /* Stops recursive behavior */ +#endif FatalError("lockup\n"); } @@ -211,13 +213,14 @@ pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); if (pI830->LpRing->space < 0) pI830->LpRing->space += pI830->LpRing->mem.Size; - +#ifdef I830_USE_XAA if (pI830->AccelInfoRec) pI830->AccelInfoRec->NeedToSync = TRUE; +#endif } +#ifdef I830_USE_XAA /* I830 Accel Functions */ - static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty, int fg, int bg, int rop, @@ -250,143 +253,500 @@ static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno); #endif static void I830RestoreAccelState(ScrnInfoPtr pScrn); +#endif /* I830_USE_XAA */ + +#ifdef I830_USE_EXA +void i830ScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area); +Bool i830UploadToScreen(PixmapPtr pDst, char *src, int src_pitch); +Bool i830UploadToScratch(PixmapPtr pSrc, PixmapPtr pDst); +Bool i830DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch); + +/** + * I830EXASync - wait for a command to finish + * @pScreen: current screen + * @marker: marker command to wait for + * + * Wait for the command specified by @marker to finish, then return. + */ +static void +I830EXASync(ScreenPtr pScreen, int marker) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); +#ifdef XF86DRI + /* VT switching tries to do this. */ + if (!pI830->LockHeld && pI830->directRenderingEnabled) + return; +#endif -/* The following function sets up the supported acceleration. Call it - * from the FbInit() function in the SVGA driver, or before ScreenInit - * in a monolithic server. + if (pI830->entityPrivate && !pI830->entityPrivate->RingRunning) + return; + + /* Send a flush instruction and then wait till the ring is empty. + * This is stronger than waiting for the blitter to finish as it also + * flushes the internal graphics caches. + */ + { + BEGIN_LP_RING(2); + OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); + OUT_RING(MI_NOOP); /* pad to quadword */ + ADVANCE_LP_RING(); + } + + I830WaitLpRing(pScrn, pI830->LpRing->mem.Size - 8, 0); + + pI830->LpRing->space = pI830->LpRing->mem.Size - 8; + pI830->nextColorExpandBuf = 0; +} + +/** + * I830EXAPrepareSolid - prepare for a Solid operation, if possible + * + * TODO: + * - fix booger at origin + * - support planemask */ -Bool -I830AccelInit(ScreenPtr pScreen) +static Bool +I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) { - XAAInfoRecPtr infoPtr; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - int i; - int width = 0; - int nr_buffers = 0; - unsigned char *ptr = NULL; + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830AccelInit\n"); + if (planemask != (Pixel)~0) + return FALSE; - pI830->AccelInfoRec = infoPtr = XAACreateInfoRec(); - if (!infoPtr) - return FALSE; + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + pI830->BR[13] |= (XAAGetPatternROP(alu) << 16); - pI830->bufferOffset = 0; - infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; + pI830->BR[16] = fg; + + /* + * Depth: 00 - 8 bit, 01 - 16 bit, 10 - 24 bit, 11 - 32 bit + */ + switch (pScrn->bitsPerPixel) { + case 8: + pI830->BR[13] |= ((0 << 25) | (0 << 24)); + break; + case 16: + pI830->BR[13] |= ((0 << 25) | (1 << 24)); + break; + case 32: + pI830->BR[13] |= ((1 << 25) | (1 << 24)); + break; + } + return TRUE; +} - /* Use the same sync function as the I830. - */ - infoPtr->Sync = I830Sync; +static void +I830EXASolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + int h, w; + + h = y2 - y1; + w = x2 - x1; + + { + BEGIN_LP_RING(6); + + if (pScrn->bitsPerPixel == 32) + OUT_RING(COLOR_BLT_CMD | COLOR_BLT_WRITE_ALPHA | + COLOR_BLT_WRITE_RGB); + else + OUT_RING(COLOR_BLT_CMD); + + OUT_RING(pI830->BR[13]); + OUT_RING((h << 16) | (w * pI830->cpp)); + OUT_RING(pI830->bufferOffset + (y1 * pScrn->displayWidth + x1) * + pI830->cpp); + OUT_RING(pI830->BR[16]); + OUT_RING(0); - /* Everything else is different enough to justify different functions */ - { - infoPtr->SolidFillFlags = NO_PLANEMASK; - infoPtr->SetupForSolidFill = I830SetupForSolidFill; - infoPtr->SubsequentSolidFillRect = I830SubsequentSolidFillRect; - } + ADVANCE_LP_RING(); + } +} - { - infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY); +static void +I830EXADoneSolid(PixmapPtr pPixmap) +{ + return; +} - infoPtr->SetupForScreenToScreenCopy = I830SetupForScreenToScreenCopy; - infoPtr->SubsequentScreenToScreenCopy = - I830SubsequentScreenToScreenCopy; - } +/** + * TODO: + * - support negative x + * - support planemask + */ +static Bool +I830EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, + int ydir, int alu, Pixel planemask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); - { - infoPtr->SetupForMono8x8PatternFill = I830SetupForMono8x8PatternFill; - infoPtr->SubsequentMono8x8PatternFillRect = - I830SubsequentMono8x8PatternFillRect; + if (xdir < 0 || planemask != (Pixel)~0) + return FALSE; - infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS | - HARDWARE_PATTERN_SCREEN_ORIGIN | - HARDWARE_PATTERN_PROGRAMMED_ORIGIN | - BIT_ORDER_IN_BYTE_MSBFIRST | - NO_PLANEMASK); + pI830->BR[13] = pScrn->displayWidth * pI830->cpp; + pI830->BR[13] |= XAAGetCopyROP(alu) << 16; - } + switch (pScrn->bitsPerPixel) { + case 8: + break; + case 16: + pI830->BR[13] |= (1 << 24); + break; + case 32: + pI830->BR[13] |= ((1 << 25) | (1 << 24)); + break; + } + return TRUE; +} - /* On the primary screen */ - if (pI830->init == 0) { - if (pI830->Scratch.Size != 0) { - width = ((pScrn->displayWidth + 31) & ~31) / 8; - nr_buffers = pI830->Scratch.Size / width; - ptr = pI830->FbBase + pI830->Scratch.Start; - } - } else { - /* On the secondary screen */ - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - if (pI8301->Scratch2.Size != 0) { - width = ((pScrn->displayWidth + 31) & ~31) / 8; - nr_buffers = pI8301->Scratch2.Size / width; - /* We have to use the primary screen's FbBase, as that's where - * we allocated Scratch2, so we get the correct pointer */ - ptr = pI8301->FbBase + pI8301->Scratch2.Start; - } - } +static void +I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1, + int dst_y1, int w, int h) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + int dst_x2, dst_y2; + + dst_x2 = dst_x1 + w; + dst_y2 = dst_y1 + h; + + { + BEGIN_LP_RING(8); + + if (pScrn->bitsPerPixel == 32) + OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + else + OUT_RING(XY_SRC_COPY_BLT_CMD); + + OUT_RING(pI830->BR[13]); + OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff)); + OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff)); + OUT_RING(pI830->bufferOffset); + OUT_RING((src_y1 << 16) | (src_x1 & 0xffff)); + OUT_RING(pI830->BR[13] & 0xFFFF); + OUT_RING(pI830->bufferOffset); - if (nr_buffers) { - pI830->NumScanlineColorExpandBuffers = nr_buffers; - pI830->ScanlineColorExpandBuffers = (unsigned char **) + ADVANCE_LP_RING(); + } +} + +static void +I830EXADoneCopy(PixmapPtr pDstPixmap) +{ + return; +} + +#if 0 /* Not done (or even started for that matter) */ +static Bool +I830EXAUploadToScreen(PixmapPtr pDst, char *src, int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + unsigned char *dst = pDst->devPrivate.ptr; + int dst_pitch = pDst->devKind; + int size = src_pitch < dst_pitch ? src_pitch : dst_pitch; + int h = pDst->drawable.height; + + I830Sync(pScrn); + + while(h--) { + i830MemCopyToVideoRam(pI830, dst, (unsigned char *)src, size); + src += src_pitch; + dst += dst_pitch; + } + + return TRUE; +} + +static Bool +I830EXADownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + unsigned char *src = pSrc->devPrivate.ptr; + int src_pitch = pSrc->devKind; + int size = src_pitch < dst_pitch ? src_pitch : dst_pitch; + + I830Sync(pScrn); + + while(h--) { + i830MemCopyFromVideoRam(pI830, (unsigned char *)dst, src, size); + src += src_pitch; + dst += dst_pitch; + } + + return TRUE; +} + +static Bool +I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture) +{ + return FALSE; /* no Composite yet */ +} + +static Bool +I830EXAPrepareComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ + return FALSE; /* no Composite yet */ +} + +static void +I830EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + return; /* no Composite yet */ +} + +static void +I830EXADoneComposite(PixmapPtr pDst) +{ + return; /* no Composite yet */ +} +#endif + +/* + * TODO: + * - verify offscreen base, pitch, alignment, etc. + * - Dual head somehow? + * - Upload/Download + * - Composite + */ +static Bool +I830EXAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + if(pI830->useEXA) { + if(!(pI830->EXADriverPtr = xnfcalloc(sizeof(ExaDriverRec), 1))) { + pI830->noAccel = TRUE; + return FALSE; + } + } + + pI830->bufferOffset = 0; + pI830->EXADriverPtr->card.memoryBase = pI830->FbBase; + /* FIXME: this is a total kludge, we double the allocation in memory.c */ + pI830->EXADriverPtr->card.offScreenBase = pI830->FrontBuffer.Size / 2; + pI830->EXADriverPtr->card.memorySize = pI830->FrontBuffer.Size; + + if(pI830->EXADriverPtr->card.memorySize > + pI830->EXADriverPtr->card.offScreenBase) + pI830->EXADriverPtr->card.flags = EXA_OFFSCREEN_PIXMAPS; + else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Not enough video RAM for " + "offscreen memory manager. Xv disabled\n"); + /* disable Xv here... */ + } + + /* Uhh... yes. */ + pI830->EXADriverPtr->card.offscreenByteAlign = 256; + pI830->EXADriverPtr->card.offscreenPitch = 32; + pI830->EXADriverPtr->card.maxX = 4095; + pI830->EXADriverPtr->card.maxY = 4095; + + /* Sync */ + pI830->EXADriverPtr->accel.WaitMarker = I830EXASync; + + /* Solid fill */ + pI830->EXADriverPtr->accel.PrepareSolid = I830EXAPrepareSolid; + pI830->EXADriverPtr->accel.Solid = I830EXASolid; + pI830->EXADriverPtr->accel.DoneSolid = I830EXADoneSolid; + + /* Copy */ + pI830->EXADriverPtr->accel.PrepareCopy = I830EXAPrepareCopy; + pI830->EXADriverPtr->accel.Copy = I830EXACopy; + pI830->EXADriverPtr->accel.DoneCopy = I830EXADoneCopy; +#if 0 + /* Upload, download to/from Screen */ + pI830->EXADriverPtr->accel.UploadToScreen = I830EXAUploadToScreen; + pI830->EXADriverPtr->accel.DownloadFromScreen = I830EXADownloadFromScreen; + + /* Composite */ + pI830->EXADriverPtr->accel.CheckComposite = I830EXACheckComposite; + pI830->EXADriverPtr->accel.PrepareComposite = I830EXAPrepareComposite; + pI830->EXADriverPtr->accel.Composite = I830EXAComposite; + pI830->EXADriverPtr->accel.DoneComposite = I830EXADoneComposite; +#endif + + if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) { + pI830->noAccel = TRUE; + return FALSE; + } + + I830SelectBuffer(pScrn, I830_SELECT_FRONT); + + /* Dual head? */ + return TRUE; +} +#endif /* I830_USE_EXA */ + +#ifdef I830_USE_XAA +static Bool I830XAAInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + int i; + int width = 0; + int nr_buffers = 0; + unsigned char *ptr = NULL; + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830XAAInit\n"); + + pI830->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) + return FALSE; + + pI830->bufferOffset = 0; + infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; + + /* Use the same sync function as the I830. + */ + infoPtr->Sync = I830Sync; + + /* Everything else is different enough to justify different functions */ + { + infoPtr->SolidFillFlags = NO_PLANEMASK; + infoPtr->SetupForSolidFill = I830SetupForSolidFill; + infoPtr->SubsequentSolidFillRect = I830SubsequentSolidFillRect; + } + + { + infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY); + + infoPtr->SetupForScreenToScreenCopy = I830SetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + I830SubsequentScreenToScreenCopy; + } + + { + infoPtr->SetupForMono8x8PatternFill = I830SetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + I830SubsequentMono8x8PatternFillRect; + + infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN| + BIT_ORDER_IN_BYTE_MSBFIRST | + NO_PLANEMASK); + + } + + /* On the primary screen */ + if (pI830->init == 0) { + if (pI830->Scratch.Size != 0) { + width = ((pScrn->displayWidth + 31) & ~31) / 8; + nr_buffers = pI830->Scratch.Size / width; + ptr = pI830->FbBase + pI830->Scratch.Start; + } + } else { + /* On the secondary screen */ + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + if (pI8301->Scratch2.Size != 0) { + width = ((pScrn->displayWidth + 31) & ~31) / 8; + nr_buffers = pI8301->Scratch2.Size / width; + /* We have to use the primary screen's FbBase, as that's where + * we allocated Scratch2, so we get the correct pointer */ + ptr = pI8301->FbBase + pI8301->Scratch2.Start; + } + } + + if (nr_buffers) { + pI830->NumScanlineColorExpandBuffers = nr_buffers; + pI830->ScanlineColorExpandBuffers = (unsigned char **) xnfcalloc(nr_buffers, sizeof(unsigned char *)); - for (i = 0; i < nr_buffers; i++, ptr += width) - pI830->ScanlineColorExpandBuffers[i] = ptr; + for (i = 0; i < nr_buffers; i++, ptr += width) + pI830->ScanlineColorExpandBuffers[i] = ptr; - infoPtr->ScanlineCPUToScreenColorExpandFillFlags = + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = (NO_PLANEMASK | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST); - infoPtr->ScanlineColorExpandBuffers = (unsigned char **) + infoPtr->ScanlineColorExpandBuffers = (unsigned char **) xnfcalloc(1, sizeof(unsigned char *)); - infoPtr->NumScanlineColorExpandBuffers = 1; + infoPtr->NumScanlineColorExpandBuffers = 1; - infoPtr->ScanlineColorExpandBuffers[0] = + infoPtr->ScanlineColorExpandBuffers[0] = pI830->ScanlineColorExpandBuffers[0]; - pI830->nextColorExpandBuf = 0; + pI830->nextColorExpandBuf = 0; - infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = I830SetupForScanlineCPUToScreenColorExpandFill; - infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = I830SubsequentScanlineCPUToScreenColorExpandFill; - infoPtr->SubsequentColorExpandScanline = + infoPtr->SubsequentColorExpandScanline = I830SubsequentColorExpandScanline; #if DO_SCANLINE_IMAGE_WRITE - infoPtr->NumScanlineImageWriteBuffers = 1; - infoPtr->ScanlineImageWriteBuffers = infoPtr->ScanlineColorExpandBuffers; - infoPtr->SetupForScanlineImageWrite = I830SetupForScanlineImageWrite; - infoPtr->SubsequentScanlineImageWriteRect = + infoPtr->NumScanlineImageWriteBuffers = 1; + infoPtr->ScanlineImageWriteBuffers = + infoPtr->ScanlineColorExpandBuffers; + infoPtr->SetupForScanlineImageWrite = I830SetupForScanlineImageWrite; + infoPtr->SubsequentScanlineImageWriteRect = I830SubsequentScanlineImageWriteRect; - infoPtr->SubsequentImageWriteScanline = I830SubsequentImageWriteScanline; - infoPtr->ScanlineImageWriteFlags = NO_GXCOPY | - NO_PLANEMASK | - ROP_NEEDS_SOURCE | - SCANLINE_PAD_DWORD; + infoPtr->SubsequentImageWriteScanline = + I830SubsequentImageWriteScanline; + infoPtr->ScanlineImageWriteFlags = NO_GXCOPY | + NO_PLANEMASK | + ROP_NEEDS_SOURCE | + SCANLINE_PAD_DWORD; #endif - } + } - { - Bool shared_accel = FALSE; - int i; + { + Bool shared_accel = FALSE; + int i; + + for(i = 0; i < pScrn->numEntities; i++) { + if(xf86IsEntityShared(pScrn->entityList[i])) + shared_accel = TRUE; + } + if(shared_accel == TRUE) + infoPtr->RestoreAccelState = I830RestoreAccelState; + } - for(i = 0; i < pScrn->numEntities; i++) { - if(xf86IsEntityShared(pScrn->entityList[i])) - shared_accel = TRUE; - } - if(shared_accel == TRUE) - infoPtr->RestoreAccelState = I830RestoreAccelState; - } + I830SelectBuffer(pScrn, I830_SELECT_FRONT); - I830SelectBuffer(pScrn, I830_SELECT_FRONT); + return XAAInit(pScreen, infoPtr); +} +#endif /* I830_USE_XAA */ - return XAAInit(pScreen, infoPtr); +/* The following function sets up the supported acceleration. Call it + * from the FbInit() function in the SVGA driver, or before ScreenInit + * in a monolithic server. + */ +Bool +I830AccelInit(ScreenPtr pScreen) +{ +#ifdef I830_USE_EXA + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->useEXA) + return I830EXAInit(pScreen); +#endif +#ifdef I830_USE_XAA + return I830XAAInit(pScreen); +#endif + return FALSE; } +#ifdef I830_USE_XAA void I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) @@ -784,7 +1144,8 @@ pI830->BR[9] += pScrn->displayWidth * pI830->cpp; I830GetNextScanlineColorExpandBuffer(pScrn); } -#endif +#endif /* DO_SCANLINE_IMAGE_WRITE */ +#endif /* I830_USE_XAA */ /* Support for multiscreen */ static void Index: i830_dga.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c,v retrieving revision 1.4 diff -u -r1.4 i830_dga.c --- i830_dga.c 11 Jul 2005 02:29:51 -0000 1.4 +++ i830_dga.c 14 Aug 2005 20:12:55 -0000 @@ -217,37 +217,39 @@ I830_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color) { +#ifdef I830_USE_XAA I830Ptr pI830 = I830PTR(pScrn); MARKER(); - if (pI830->AccelInfoRec) { (*pI830->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0); (*pI830->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); SET_SYNC_FLAG(pI830->AccelInfoRec); } +#endif } static void I830_Sync(ScrnInfoPtr pScrn) { +#ifdef I830_USE_XAA I830Ptr pI830 = I830PTR(pScrn); MARKER(); - if (pI830->AccelInfoRec) { (*pI830->AccelInfoRec->Sync) (pScrn); } +#endif } static void I830_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h, int dstx, int dsty) { +#ifdef I830_USE_XAA I830Ptr pI830 = I830PTR(pScrn); MARKER(); - if (pI830->AccelInfoRec) { int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; int ydir = (srcy < dsty) ? -1 : 1; @@ -258,6 +260,7 @@ dstx, dsty, w, h); SET_SYNC_FLAG(pI830->AccelInfoRec); } +#endif } #if 0 Index: i830_dri.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c,v retrieving revision 1.10 diff -u -r1.10 i830_dri.c --- i830_dri.c 11 Jul 2005 02:29:51 -0000 1.10 +++ i830_dri.c 14 Aug 2005 20:12:55 -0000 @@ -477,8 +477,8 @@ pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION; pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION; pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL; - pDRIInfo->frameBufferPhysicalAddress = pI830->LinearAddr + - pI830->FrontBuffer.Start; + pDRIInfo->frameBufferPhysicalAddress = (pointer)(pI830->LinearAddr + + pI830->FrontBuffer.Start); pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp; @@ -952,7 +952,9 @@ } I830SelectBuffer(pScrn, I830_SELECT_FRONT); +#ifdef I830_USE_XAA pI830->AccelInfoRec->NeedToSync = TRUE; +#endif } /* This routine is a modified form of XAADoBitBlt with the calls to @@ -1108,8 +1110,9 @@ DEALLOCATE_LOCAL(pptNew1); DEALLOCATE_LOCAL(pboxNew1); } - +#ifdef I830_USE_XAA pI830->AccelInfoRec->NeedToSync = TRUE; +#endif } /* Initialize the first context */ Index: i830_driver.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c,v retrieving revision 1.28 diff -u -r1.28 i830_driver.c --- i830_driver.c 2 Aug 2005 16:22:42 -0000 1.28 +++ i830_driver.c 14 Aug 2005 20:12:59 -0000 @@ -182,6 +182,17 @@ #include "dri.h" #endif +#ifdef I830_USE_EXA +const char *I830exaSymbols[] = { + "exaGetVersion", + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + NULL +}; +#endif + #define BIT(x) (1 << (x)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define NB_OF(x) (sizeof (x) / sizeof (*x)) @@ -218,6 +229,9 @@ */ typedef enum { +#if defined(I830_USE_XAA) && defined(I830_USE_EXA) + OPTION_ACCELMETHOD, +#endif OPTION_NOACCEL, OPTION_SW_CURSOR, OPTION_CACHE_LINES, @@ -239,6 +253,9 @@ } I830Opts; static OptionInfoRec I830BIOSOptions[] = { +#if defined(I830_USE_XAA) && defined(I830_USE_EXA) + {OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE}, +#endif {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_CACHE_LINES, "CacheLines", OPTV_INTEGER, {0}, FALSE}, @@ -2280,6 +2297,42 @@ if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { pI830->noAccel = TRUE; } + + /* + * The ugliness below: + * If either XAA or EXA (exclusive) is compiled in, default to it. + * + * If both are compiled in, and the user didn't specify noAccel, use the + * config option AccelMethod to determine which to use, defaulting to XAA + * if none is specified, or if the string was unrecognized. + * + * All this *could* go away if we removed XAA support from this driver, + * for example. :) + */ + if (!pI830->noAccel) { +#if (defined(I830_USE_EXA) && defined(I830_USE_XAA)) || !defined(I830_USE_EXA) + pI830->useEXA = FALSE; +#else + pI830->useEXA = TRUE; +#endif +#if defined(I830_USE_XAA) && defined(I830_USE_EXA) + int from = X_DEFAULT; + if ((s = (char *)xf86GetOptValString(pI830->Options, + OPTION_ACCELMETHOD))) { + if (!xf86NameCmp(s, "EXA")) { + from = X_CONFIG; + pI830->useEXA = TRUE; + } + else if (!xf86NameCmp(s, "XAA")) { + from = X_CONFIG; + pI830->useEXA = FALSE; + } + } +#endif + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n", + pI830->useEXA ? "EXA" : "XAA"); + } + if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { pI830->SWCursor = TRUE; } @@ -3297,6 +3350,7 @@ xf86LoaderReqSymLists(I810fbSymbols, NULL); + /* EXA always needs e.g. XAAGetPatternROP */ if (!pI830->noAccel) { if (!xf86LoadSubModule(pScrn, "xaa")) { PreInitCleanup(pScrn); @@ -3305,6 +3359,15 @@ xf86LoaderReqSymLists(I810xaaSymbols, NULL); } +#ifdef I830_USE_EXA + if (!pI830->noAccel && pI830->useEXA) { + if (!xf86LoadSubModule(pScrn, "exa")) { + PreInitCleanup(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(I830exaSymbols, NULL); + } +#endif if (!pI830->SWCursor) { if (!xf86LoadSubModule(pScrn, "ramdac")) { PreInitCleanup(pScrn); @@ -3441,7 +3504,7 @@ /* Reset the fence registers to 0 */ for (i = 0; i < 8; i++) OUTREG(FENCE + i * 4, 0); - +#ifdef I830_USE_XAA /* Flush the ring buffer (if enabled), then disable it. */ if (pI830->AccelInfoRec != NULL && flush) { temp = INREG(LP_RING + RING_LEN); @@ -3451,6 +3514,7 @@ DO_RING_IDLE(); } } +#endif /* I830_USE_XAA */ OUTREG(LP_RING + RING_LEN, 0); OUTREG(LP_RING + RING_HEAD, 0); OUTREG(LP_RING + RING_TAIL, 0); @@ -5005,8 +5069,10 @@ RestoreBIOSMemSize(pScrn); if (IsPrimary(pScrn)) I830UnbindGARTMemory(pScrn); +#ifdef I830_USE_XAA if (pI830->AccelInfoRec) pI830->AccelInfoRec->NeedToSync = FALSE; +#endif /* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */ if (IsPrimary(pScrn)) { @@ -5322,10 +5388,11 @@ int ret = TRUE; DPRINTF(PFX, "I830BIOSSwitchMode: mode == %p\n", mode); - +#ifdef I830_USE_XAA /* Stops head pointer freezes for 845G */ if (!pI830->noAccel) (*pI830->AccelInfoRec->Sync)(pScrn); +#endif #ifndef BINDUNBIND #define BINDUNBIND 0 @@ -5458,7 +5525,9 @@ { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); +#ifdef I830_USE_XAA XAAInfoRecPtr infoPtr = pI830->AccelInfoRec; +#endif pI830->closing = TRUE; #ifdef XF86DRI @@ -5484,14 +5553,21 @@ xfree(pI830->ScanlineColorExpandBuffers); pI830->ScanlineColorExpandBuffers = 0; } - +#ifdef I830_USE_XAA if (infoPtr) { if (infoPtr->ScanlineColorExpandBuffers) xfree(infoPtr->ScanlineColorExpandBuffers); XAADestroyInfoRec(infoPtr); pI830->AccelInfoRec = NULL; } - +#endif +#ifdef I830_USE_EXA + if (pI830->useEXA) { + exaDriverFini(pScreen); + xfree(pI830->EXADriverPtr); + pI830->EXADriverPtr = NULL; + } +#endif if (pI830->CursorInfoRec) { xf86DestroyCursorInfoRec(pI830->CursorInfoRec); pI830->CursorInfoRec = 0; Index: i830_memory.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c,v retrieving revision 1.10 diff -u -r1.10 i830_memory.c --- i830_memory.c 11 Jul 2005 02:29:51 -0000 1.10 +++ i830_memory.c 14 Aug 2005 20:13:01 -0000 @@ -601,6 +601,9 @@ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%sInitial framebuffer allocation size: %ld kByte\n", s, size / 1024); +#ifdef I830_USE_EXA + size *= 2; /* FIXME: integrate memory management with EXA better */ +#endif alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), &(pI830->StolenPool), size, align, flags | alignflags | Index: i830_video.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c,v retrieving revision 1.18 diff -u -r1.18 i830_video.c --- i830_video.c 11 Jul 2005 02:29:51 -0000 1.18 +++ i830_video.c 14 Aug 2005 20:13:02 -0000 @@ -1489,10 +1489,10 @@ I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) { ScreenPtr pScreen; - FBLinearPtr new_linear; DPRINTF(PFX, "I830AllocateMemory\n"); - +#ifdef I830_USE_XAA + FBLinearPtr new_linear; if (linear) { if (linear->size >= size) return linear; @@ -1523,6 +1523,32 @@ } return new_linear; +#endif /* I830_USE_XAA */ +#ifdef I830_USE_EXA + { + ExaOffscreenArea *area = (ExaOffscreenArea *)(linear); + + if (area) { + if(area->size >= size) + return linear; + + exaOffscreenFree(pScreen, area); + linear = NULL; + } + + if (!(area = exaOffscreenAlloc(pScreen, size, 4, TRUE, NULL, + NULL))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Xv: Failed to allocate %d bytes of video memory\n", + size); + return 0; + } + else { + linear = (void *)area; + return linear; + } + } +#endif /* I830_USE_EXA */ } static int