Index: programs/Xserver/hw/xfree86/drivers/i810/i810.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h,v retrieving revision 1.6 diff -u -r1.6 i810.h --- programs/Xserver/hw/xfree86/drivers/i810/i810.h 4 Dec 2004 00:43:09 -0000 1.6 +++ programs/Xserver/hw/xfree86/drivers/i810/i810.h 20 Jul 2005 19:05:00 -0000 @@ -61,6 +61,11 @@ #include "i810_dri.h" #endif +#define I810_USE_EXA + +#ifdef I810_USE_EXA +#include "exa.h" +#endif #include "common.h" #define I810_VERSION 4000 @@ -221,6 +226,20 @@ xf86CursorInfoPtr CursorInfoRec; CloseScreenProcPtr CloseScreen; ScreenBlockHandlerProcPtr BlockHandler; +#ifdef I810_USE_EXA + ExaDriverPtr EXADriverPtr; + int fillPitch, fillBpp, fillXoffs; + CARD32 fillDstBase; + int copySXoffs, copyDXoffs, copyBpp; + int copySPitch, copyDPitch; + CARD32 copySrcBase, copyDstBase; + int copyXdir, copyYdir; + ExaOffscreenArea * exa_scratch; + unsigned int exa_scratch_next; + void * ExaRenderCallback; + void (*ExaRenderCallback)(ScrnInfoPtr); + Time ExaRenderTime; +#endif I810WriteIndexedByteFunc writeControl; I810ReadIndexedByteFunc readControl; @@ -260,6 +279,7 @@ Bool showCache; Bool noAccel; + Bool useEXA; Bool allowPageFlip; Bool have3DWindows; int drmMinor; Index: programs/Xserver/hw/xfree86/drivers/i810/i830.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h,v retrieving revision 1.11 diff -u -r1.11 i830.h --- programs/Xserver/hw/xfree86/drivers/i810/i830.h 20 May 2005 15:24:02 -0000 1.11 +++ programs/Xserver/hw/xfree86/drivers/i810/i830.h 20 Jul 2005 19:05:00 -0000 @@ -154,6 +154,7 @@ #ifdef I830_XV int XvInUse; #endif + Bool useEXA; } I830EntRec, *I830EntPtr; typedef struct _I830Rec { @@ -272,6 +273,18 @@ xf86CursorInfoPtr CursorInfoRec; CloseScreenProcPtr CloseScreen; +#ifdef I810_USE_EXA + ExaDriverPtr EXADriverPtr; + int fillPitch, fillBpp, fillXoffs; + CARD32 fillDstBase; + int copySXoffs, copyDXoffs, copyBpp; + int copySPitch, copyDPitch; + CARD32 copySrcBase, copyDstBase; + int copyXdir, copyYdir; + ExaOffscreenArea * exa_scratch; + unsigned int exa_scratch_next; +#endif + I830WriteIndexedByteFunc writeControl; I830ReadIndexedByteFunc readControl; I830WriteByteFunc writeStandard; @@ -374,7 +387,7 @@ #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) #define I830REGPTR(p) (&(I830PTR(p)->ModeReg)) -#define I830_SELECT_FRONT 0 +#DEFINE I830_SELECT_FRONT 0 #define I830_SELECT_BACK 1 #define I830_SELECT_DEPTH 2 Index: programs/Xserver/hw/xfree86/drivers/i810/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 --- programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c 11 Jul 2005 02:29:51 -0000 1.5 +++ programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c 20 Jul 2005 19:05:01 -0000 @@ -64,6 +64,276 @@ #include "i830.h" #include "i810_reg.h" +#ifdef I810_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); +#endif + +#ifdef I810_USE_EXA + +static void +i830EXASync(ScreenPtr pScreen, int marker) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC)) + ErrorF("I830EXASync\n"); + +#ifdef XF86DRI + /* VT switching tries to do this. + */ + if (!pI830->LockHeld && pI830->directRenderingEnabled) { + return; + } +#endif + + 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; +} + +static Bool +i830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); +#if 0 + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830EXAPrepareSolid: %x alu: %x mask: %x\n", + color, rop, planemask); +#endif + pI830->BR[13] = ((XAAGetPatternROP(alu) << 16) | + (pScrn->displayWidth * pI830->cpp)); + + pI830->BR[16] = color; + + switch (pScrn->bitsPerPixel) { + case 8: + break; + case 16: + pI830->BR[13] |= (1 << 24); + break; + case 32: + pI830->BR[13] |= ((1 << 25) | (1 << 24)); + break; + } +} + +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 = y2 - y1, w = x2 - x1; /* assumes x2 > x1 && y2 > y1 */ + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830EXASolid (%d, %d)->(%d, %d)\n", x, y, x2, y2); + + { + 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 + (y * pScrn->displayWidth + x) * + pI830->cpp); + OUT_RING(pI830->BR[16]); + OUT_RING(0); + + ADVANCE_LP_RING(); + } +} + +static void +i830EXADoneSolid(PixmapPtr pPixmap) +{ +} + +static Bool +i830EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, + int alu, Pixel planemask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + I810Ptr pI830 = I810PTR(pScrn); + CARD32 srcbase, dstbase; + + /* Planemask not supported */ + if((planemask & ((1 << pSrcPixmap->drawable.depth) - 1)) != + (1 << pSrcPixmap->drawable.depth) - 1) { + return FALSE; + } + + if((pDstPixmap->drawable.bitsPerPixel != 8) && + (pDstPixmap->drawable.bitsPerPixel != 16) && + (pDstPixmap->drawable.bitsPerPixel != 32)) + return FALSE; + + srcbase = (CARD32)((unsigned long)pSrcPixmap->devPrivate.ptr - + (unsigned long)pI830->FbBase + FBOFFSET); + /* TODO: If srcbase is not aligned, need to align it and fix x coordinates */ + if(srcbase & 0x0f) xf86DrvMsg(0, 0, "Copy: Bad source\n"); + pI830->copySXoffs = 0; + + dstbase = (CARD32)((unsigned long)pDstPixmap->devPrivate.ptr - + (unsigned long)pI830->FbBase + FBOFFSET); + /* TODO: If dstbase is not aligned, need to align it and fix x coordinates */ + if(dstbase & 0x0f) xf86DrvMsg(0, 0, "Copy: Bad dest\n"); + pI830->copyDXoffs = 0; + + /* TODO: Will there eventually be overlapping blits? + * If so, good night. Then we must calculate new base addresses + * which are identical for source and dest, otherwise + * the chips direction-logic will fail. Certainly funny + * to re-calculate x and y then... + */ + + i830SetupDSTColorDepth((pDstPixmap->drawable.bitsPerPixel >> 4) << 16); + i830CheckQueue(16 * 3); + i830SetupSRCPitchDSTRect((pSrcPixmap->devKind + 3) & ~3, (pDstPixmap->devKind + 3) & ~3, DEV_HEIGHT) + i830SetupROP(i830GetCopyROP(alu)) + i830SetupSRCDSTBase(srcbase, dstbase) + i830SyncWP + + return TRUE; +} + +static void +i830EXACopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + I810Ptr pI830 = I810PTR(pScrn); + + srcX += pI830->copySXoffs; + dstX += pI830->copyDXoffs; + + i830CheckQueue(16 * 2); + i830SetupSRCDSTXY(srcX, srcY, dstX, dstY) + i830SetRectDoCMD(width, height) +} + +static void +i830EXADoneCopy(PixmapPtr pDstPixmap) +{ +} + +Bool +i830EXAUploadToScreen(PixmapPtr pDst, char *src, int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + I810Ptr pI830 = I810PTR(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; + + (pI830->SyncAccel)(pScrn); + + while(h--) { + i830MemCopyToVideoRam(pI830, dst, (unsigned char *)src, size); + src += src_pitch; + dst += dst_pitch; + } + + return TRUE; +} + +Bool +i830EXAUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst) +{ + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + I810Ptr pI830 = I810PTR(pScrn); + unsigned char *src, *dst; + int src_pitch = pSrc->devKind; + int dst_pitch, size, w, h, bytes; + + w = pSrc->drawable.width; + + dst_pitch = ((w * (pSrc->drawable.bitsPerPixel >> 3)) + + pI830->EXADriverPtr->card.offscreenPitch - 1) & + ~(pI830->EXADriverPtr->card.offscreenPitch - 1); + + size = dst_pitch * pSrc->drawable.height; + + if(size > pI830->exa_scratch->size) + return FALSE; + + pI830->exa_scratch_next = (pI830->exa_scratch_next + + pI830->EXADriverPtr->card.offscreenByteAlign - 1) & + ~(pI830->EXADriverPtr->card.offscreenByteAlign - 1); + + if(pI830->exa_scratch_next + size > + pI830->exa_scratch->offset + pI830->exa_scratch->size) { + (pI830->EXADriverPtr->accel.WaitMarker)(pSrc->drawable.pScreen, 0); + pI830->exa_scratch_next = pI830->exa_scratch->offset; + } + + memcpy(pDst, pSrc, sizeof(*pDst)); + pDst->devKind = dst_pitch; + pDst->devPrivate.ptr = pI830->EXADriverPtr->card.memoryBase + pI830->exa_scratch_next; + + pI830->exa_scratch_next += size; + + src = pSrc->devPrivate.ptr; + src_pitch = pSrc->devKind; + dst = pDst->devPrivate.ptr; + + bytes = (src_pitch < dst_pitch) ? src_pitch : dst_pitch; + + h = pSrc->drawable.height; + + (pI830->SyncAccel)(pScrn); + + while(h--) { + i830MemCopyToVideoRam(pI830, dst, src, size); + src += src_pitch; + dst += dst_pitch; + } + + return TRUE; +} + +Bool +i830EXADownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + I810Ptr pI830 = I810PTR(pScrn); + unsigned char *src = pSrc->devPrivate.ptr; + int src_pitch = pSrc->devKind; + int size = src_pitch < dst_pitch ? src_pitch : dst_pitch; + + (pI830->SyncAccel)(pScrn); + + while(h--) { + i830MemCopyFromVideoRam(pI830, (unsigned char *)dst, src, size); + src += src_pitch; + dst += dst_pitch; + } + + return TRUE; +} +#endif /* EXA */ + int I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis) { @@ -270,9 +540,20 @@ if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I830AccelInit\n"); - pI830->AccelInfoRec = infoPtr = XAACreateInfoRec(); - if (!infoPtr) - return FALSE; +#ifdef I810_USE_EXA + if(pI830->useEXA) { + if(!(pI830->EXADriverPtr = xnfcalloc(sizeof(ExaDriverRec), 1))) { + pI830->NoAccel = TRUE; + pI830->NoXvideo = TRUE; /* No fbmem manager -> no xv */ + } + } +#else + if (!pI810->useEXA) { + pI830->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) + return FALSE; + } +#endif pI830->bufferOffset = 0; infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;