? 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