Index: Imakefile =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile,v retrieving revision 1.10 diff -u -r1.10 Imakefile --- Imakefile 23 Aug 2005 04:03:52 -0000 1.10 +++ Imakefile 29 Aug 2005 04:41:53 -0000 @@ -10,6 +10,8 @@ #define I830Only NO #endif +#define I830EXASupport YES +#define I830XAASupport YES #define I830XvSupport YES #ifndef I830XvSupport @@ -35,6 +37,15 @@ I830OBJS1 = i830_video.o #endif +#if I830EXASupport +I830SRCS3 = i830_exa.c +I830OBJS3 = i830_exa.o +#endif +#if I830XAASupport +I830SRCS4 = i830_xaa.c +I830OBJS4 = i830_xaa.o +#endif + #if !I830Only I810SRCS = i810_cursor.c i810_accel.c i810_memory.c i810_wmark.c i810_dga.c \ i810_video.c i810_io.c i830_modes.c @@ -42,9 +53,11 @@ i810_video.o i810_io.o i830_modes.o #endif I830SRCS = i830_driver.c i830_memory.c i830_cursor.c i830_accel.c i830_io.c \ - i830_dga.c i830_shadow.c $(I830SRCS1) $(I830SRCS2) + i830_dga.c i830_shadow.c $(I830SRCS1) $(I830SRCS2) $(I830SRCS3) \ + $(I830SRCS4) I830OBJS = i830_driver.o i830_memory.o i830_cursor.o i830_accel.o i830_io.o \ - i830_dga.o i830_shadow.o $(I830OBJS1) $(I830OBJS2) + i830_dga.o i830_shadow.o $(I830OBJS1) $(I830OBJS2) $(I830OBJS3) \ + $(I830OBJS4) SRCS = i810_driver.c \ $(I810SRCS) $(I830SRCS) $(DRISRCS) @@ -60,6 +73,14 @@ I830XVDEFINES = -DI830_XV #endif +#if I830EXASupport +I830EXADEFINES = -DI830_USE_EXA +#endif + +#if I830XAASupport +I830XAADEFINES = -DI830_USE_XAA +#endif + #if defined(XF86DriverSDK) INCLUDES = -I. -I../../include #else @@ -76,7 +97,8 @@ -I$(EXTINCSRC) -I$(SERVERSRC)/render \ $(DRIINCLUDES) #endif -DEFINES = $(DRIDEFINES) $(CHIPDEFINES) $(I830XVDEFINES) +DEFINES = $(DRIDEFINES) $(CHIPDEFINES) $(I830XVDEFINES) $(I830EXADEFINES) \ + $(I830XAADEFINES) ObjectFromSpecialSource(i830_io, i810_io, -DBUILD_FOR_I830) @@ -123,5 +145,11 @@ InstallDriverSDKNonExecFile(i830_memory.c,$(DRIVERSDKDIR)/drivers/i810) InstallDriverSDKNonExecFile(i830_shadow.c,$(DRIVERSDKDIR)/drivers/i810) InstallDriverSDKNonExecFile(i830_video.c,$(DRIVERSDKDIR)/drivers/i810) +#if I830EXASupport +InstallDriverSDKNonExecFile(i830_exa.c,$(DRIVERSDKDIR)/drivers/i810) +#endif +#if I830XAASupport +InstallDriverSDKNonExecFile(i830_xaa.c,$(DRIVERSDKDIR)/drivers/i810) +#endif InstallDriverSDKObjectModule(i810,$(DRIVERSDKMODULEDIR),drivers) Index: i810.man =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.man,v retrieving revision 1.5 diff -u -r1.5 i810.man --- i810.man 20 May 2005 15:24:02 -0000 1.5 +++ i810.man 29 Aug 2005 04:41:53 -0000 @@ -202,6 +202,12 @@ .BI "Option \*qShadowFB\*q \*q" boolean \*q Enable or disable use of the shadow framebuffer layer. This option disables acceleration. Default: off. +.TP +.BI "Option \*qAccelMethod\*q \*q" string \*q +Choose acceleration architecture, either "XAA" or "EXA". XAA is the old +(but stable) XFree86 based acceleration architecture. EXA is a newer and +simpler acceleration architecture designed to better accelerate the X Render +extension. Default: "XAA". .SH "SEE ALSO" __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) @@ -211,4 +217,5 @@ support reworked for XFree86 4.3 by David Dawes and Keith Whitwell. 852GM, 855GM, and 865G support added by David Dawes and Keith Whitwell. 915G and 915GM support added by Alan Hourihane and Keith Whitwell. -Dual Head, Clone and lid status support added by Alan Hourihane. +Dual Head, Clone and lid status support added by Alan Hourihane. EXA support +added by Jesse Barnes. 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 29 Aug 2005 04:41:53 -0000 @@ -68,6 +68,19 @@ #include "i830_dri.h" #endif +#ifdef I830_USE_EXA +#include "../../exa/exa.h" +Bool I830EXAInit(ScreenPtr pScreen); +FBLinearPtr I830EXAAllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, + int size); +#endif + +#ifdef I830_USE_XAA +Bool I830XAAInit(ScreenPtr pScreen); +FBLinearPtr I830XAAAllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, + int size); +#endif + #include "common.h" /* I830 Video BIOS support */ @@ -264,13 +277,22 @@ 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 + unsigned int copy_src_pitch; + unsigned int copy_src_off; + 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 29 Aug 2005 04:41:53 -0000 @@ -7,10 +7,6 @@ #include "config.h" #endif -#ifndef DO_SCANLINE_IMAGE_WRITE -#define DO_SCANLINE_IMAGE_WRITE 0 -#endif - /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -112,7 +108,9 @@ DRICloseScreen(screenInfo.screens[pScrn->scrnIndex]); } #endif +#ifdef I830_USE_XAA pI830->AccelInfoRec = NULL; /* Stops recursive behavior */ +#endif FatalError("lockup\n"); } @@ -211,46 +209,11 @@ 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; -} - -/* I830 Accel Functions */ - -static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, - int pattx, int patty, - int fg, int bg, int rop, - unsigned int planemask); -static void I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, - int pattx, int patty, - int x, int y, int w, int h); - -static void I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, - int fg, int bg, - int rop, - unsigned int mask); - -static void I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr - pScrn, int x, - int y, int w, - int h, - int skipleft); - -static void I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); - -#if DO_SCANLINE_IMAGE_WRITE -static void I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, - unsigned int planemask, - int trans_color, int bpp, - int depth); -static void I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, - int x, int y, int w, int h, - int skipleft); -static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno); #endif -static void I830RestoreAccelState(ScrnInfoPtr pScrn); - +} /* The following function sets up the supported acceleration. Call it * from the FbInit() function in the SVGA driver, or before ScreenInit @@ -259,539 +222,16 @@ Bool I830AccelInit(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("I830AccelInit\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); - - } +#ifdef I830_USE_EXA + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); - /* 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; - - infoPtr->ScanlineCPUToScreenColorExpandFillFlags = - (NO_PLANEMASK | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST); - - infoPtr->ScanlineColorExpandBuffers = (unsigned char **) - xnfcalloc(1, sizeof(unsigned char *)); - infoPtr->NumScanlineColorExpandBuffers = 1; - - infoPtr->ScanlineColorExpandBuffers[0] = - pI830->ScanlineColorExpandBuffers[0]; - pI830->nextColorExpandBuf = 0; - - infoPtr->SetupForScanlineCPUToScreenColorExpandFill = - I830SetupForScanlineCPUToScreenColorExpandFill; - - infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = - I830SubsequentScanlineCPUToScreenColorExpandFill; - - infoPtr->SubsequentColorExpandScanline = - I830SubsequentColorExpandScanline; - -#if DO_SCANLINE_IMAGE_WRITE - 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; + if (pI830->useEXA) + return I830EXAInit(pScreen); #endif - } - - { - 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; - } - - I830SelectBuffer(pScrn, I830_SELECT_FRONT); - - return XAAInit(pScreen, infoPtr); -} - -void -I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, - unsigned int planemask) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n", - color, rop, planemask); - - pI830->BR[13] = ((XAAGetPatternROP(rop) << 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; - } -} - -void -I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SubsequentFillRectSolid %d,%d %dx%d\n", x, y, w, h); - - { - 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(); - } -} - -void -I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, - unsigned int planemask, int transparency_color) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SetupForScreenToScreenCopy %d %d %x %x %d\n", - xdir, ydir, rop, planemask, transparency_color); - - pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); - pI830->BR[13] |= XAAGetCopyROP(rop) << 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; - } - -} - -void -I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1, - int dst_x1, int dst_y1, int w, int h) -{ - I830Ptr pI830 = I830PTR(pScrn); - int dst_x2, dst_y2; - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n", - src_x1, src_y1, dst_x1, dst_y1, w, h); - - 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); - - ADVANCE_LP_RING(); - } -} - -static void -I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty, - int fg, int bg, int rop, - unsigned int planemask) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SetupForMono8x8PatternFill\n"); - - pI830->BR[16] = pattx; - pI830->BR[17] = patty; - pI830->BR[18] = bg; - pI830->BR[19] = fg; - - pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); /* In bytes */ - pI830->BR[13] |= XAAGetPatternROP(rop) << 16; - if (bg == -1) - pI830->BR[13] |= (1 << 28); - - 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 -I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty, - int x, int y, int w, int h) -{ - I830Ptr pI830 = I830PTR(pScrn); - int x1, x2, y1, y2; - - x1 = x; - x2 = x + w; - y1 = y; - y2 = y + h; - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SubsequentMono8x8PatternFillRect\n"); - - { - BEGIN_LP_RING(10); - - if (pScrn->bitsPerPixel == 32) { - OUT_RING(XY_MONO_PAT_BLT_CMD | XY_MONO_PAT_BLT_WRITE_ALPHA | - XY_MONO_PAT_BLT_WRITE_RGB | - ((patty << 8) & XY_MONO_PAT_VERT_SEED) | - ((pattx << 12) & XY_MONO_PAT_HORT_SEED)); - } else { - OUT_RING(XY_MONO_PAT_BLT_CMD | - ((patty << 8) & XY_MONO_PAT_VERT_SEED) | - ((pattx << 12) & XY_MONO_PAT_HORT_SEED)); - } - OUT_RING(pI830->BR[13]); - OUT_RING((y1 << 16) | x1); - OUT_RING((y2 << 16) | x2); - OUT_RING(pI830->bufferOffset); - OUT_RING(pI830->BR[18]); /* bg */ - OUT_RING(pI830->BR[19]); /* fg */ - OUT_RING(pI830->BR[16]); /* pattern data */ - OUT_RING(pI830->BR[17]); - OUT_RING(0); - ADVANCE_LP_RING(); - } -} - -static void -I830GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - XAAInfoRecPtr infoPtr = pI830->AccelInfoRec; - - if (pI830->nextColorExpandBuf == pI830->NumScanlineColorExpandBuffers) - I830Sync(pScrn); - - infoPtr->ScanlineColorExpandBuffers[0] = - pI830->ScanlineColorExpandBuffers[pI830->nextColorExpandBuf]; - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("using color expand buffer %d\n", pI830->nextColorExpandBuf); - - pI830->nextColorExpandBuf++; -} - -static void -I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, - int fg, int bg, int rop, - unsigned int planemask) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n", - fg, bg, rop, planemask); - - /* Fill out register values */ - pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); - pI830->BR[13] |= XAAGetCopyROP(rop) << 16; - if (bg == -1) - pI830->BR[13] |= (1 << 29); - - switch (pScrn->bitsPerPixel) { - case 8: - break; - case 16: - pI830->BR[13] |= (1 << 24); - break; - case 32: - pI830->BR[13] |= ((1 << 25) | (1 << 24)); - break; - } - - pI830->BR[18] = bg; - pI830->BR[19] = fg; - - I830GetNextScanlineColorExpandBuffer(pScrn); -} - -static void -I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, - int x, int y, - int w, int h, int skipleft) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SubsequentScanlineCPUToScreenColorExpandFill " - "%d,%d %dx%x %d\n", x, y, w, h, skipleft); - - /* Fill out register values */ - pI830->BR[9] = (pI830->bufferOffset + - (y * pScrn->displayWidth + x) * pI830->cpp); - pI830->BR[11] = ((1 << 16) | w); -} - -static void -I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->init == 0) { - pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - - pI830->FbBase); - } else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - - /* We have to use the primary screen's FbBase, as that's where - * we allocated Scratch2, so we get the correct pointer */ - pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - - pI8301->FbBase); - } - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n", - bufno, pI830->BR[12]); - - { - BEGIN_LP_RING(8); - - if (pScrn->bitsPerPixel == 32) { - OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA | - XY_MONO_SRC_BLT_WRITE_RGB); - } else { - OUT_RING(XY_MONO_SRC_BLT_CMD); - } - OUT_RING(pI830->BR[13]); - OUT_RING(0); /* x1 = 0, y1 = 0 */ - OUT_RING(pI830->BR[11]); /* x2 = w, y2 = 1 */ - OUT_RING(pI830->BR[9]); /* dst addr */ - OUT_RING(pI830->BR[12]); /* src addr */ - OUT_RING(pI830->BR[18]); /* bg */ - OUT_RING(pI830->BR[19]); /* fg */ - - ADVANCE_LP_RING(); - } - - /* Advance to next scanline. - */ - pI830->BR[9] += pScrn->displayWidth * pI830->cpp; - I830GetNextScanlineColorExpandBuffer(pScrn); -} - -#if DO_SCANLINE_IMAGE_WRITE -static void -I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, - unsigned int planemask, int trans_color, - int bpp, int depth) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SetupForScanlineImageWrite %x %x\n", rop, planemask); - - /* Fill out register values */ - pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); - pI830->BR[13] |= XAAGetCopyROP(rop) << 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; - } - - I830GetNextScanlineColorExpandBuffer(pScrn); -} - -static void -I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y, - int w, int h, int skipleft) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SubsequentScanlineImageWriteRect " - "%d,%d %dx%x %d\n", x, y, w, h, skipleft); - - /* Fill out register values */ - pI830->BR[9] = (pI830->bufferOffset + - (y * pScrn->displayWidth + x) * pI830->cpp); - pI830->BR[11] = ((1 << 16) | w); -} - -static void -I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->init == 0) { - pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - - pI830->FbBase); - } else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - - /* We have to use the primary screen's FbBase, as that's where - * we allocated Scratch2, so we get the correct pointer */ - pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - - pI8301->FbBase); - } - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I830SubsequentImageWriteScanline %d (addr %x)\n", - bufno, pI830->BR[12]); - - { - 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(0); /* x1 = 0, y1 = 0 */ - OUT_RING(pI830->BR[11]); /* x2 = w, y2 = 1 */ - OUT_RING(pI830->BR[9]); /* dst addr */ - OUT_RING(0); /* source origin (0,0) */ - OUT_RING(pI830->BR[11] & 0xffff); /* source pitch */ - OUT_RING(pI830->BR[12]); /* src addr */ - - ADVANCE_LP_RING(); - } - - /* Advance to next scanline. - */ - pI830->BR[9] += pScrn->displayWidth * pI830->cpp; - I830GetNextScanlineColorExpandBuffer(pScrn); -} -#endif - -/* Support for multiscreen */ -static void -I830RestoreAccelState(ScrnInfoPtr pScrn) -{ -#if 0 - /* might be needed, but everything is on a ring, so I don't think so */ - I830Sync(pScrn); +#ifdef I830_USE_XAA + return I830XAAInit(pScreen); #endif + return FALSE; } + 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 29 Aug 2005 04:41:54 -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.11 diff -u -r1.11 i830_dri.c --- i830_dri.c 15 Aug 2005 07:30:05 -0000 1.11 +++ i830_dri.c 29 Aug 2005 04:41:54 -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.30 diff -u -r1.30 i830_driver.c --- i830_driver.c 21 Aug 2005 06:26:33 -0000 1.30 +++ i830_driver.c 29 Aug 2005 04:41:58 -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}, @@ -2276,6 +2293,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; } @@ -3293,14 +3346,25 @@ xf86LoaderReqSymLists(I810fbSymbols, NULL); - if (!pI830->noAccel) { +#ifdef I830_USE_XAA + if (!pI830->noAccel && !pI830->useEXA) { if (!xf86LoadSubModule(pScrn, "xaa")) { PreInitCleanup(pScrn); return FALSE; } xf86LoaderReqSymLists(I810xaaSymbols, NULL); } +#endif +#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); @@ -3437,9 +3501,12 @@ /* 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) { +#else + if (pI830->EXADriverPtr != NULL && flush) { +#endif temp = INREG(LP_RING + RING_LEN); if (temp & 1) { I830RefreshRing(pScrn); @@ -3447,6 +3514,7 @@ DO_RING_IDLE(); } } + OUTREG(LP_RING + RING_LEN, 0); OUTREG(LP_RING + RING_HEAD, 0); OUTREG(LP_RING + RING_TAIL, 0); @@ -5001,8 +5069,14 @@ RestoreBIOSMemSize(pScrn); if (IsPrimary(pScrn)) I830UnbindGARTMemory(pScrn); +#ifdef I830_USE_XAA if (pI830->AccelInfoRec) pI830->AccelInfoRec->NeedToSync = FALSE; +#endif +#ifdef I830_USE_EXA + if (pI830->EXADriverPtr) + pI830->EXADriverPtr->card.needsSync = TRUE; +#endif /* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */ if (IsPrimary(pScrn)) { @@ -5318,10 +5392,17 @@ int ret = TRUE; DPRINTF(PFX, "I830BIOSSwitchMode: mode == %p\n", mode); - /* Stops head pointer freezes for 845G */ - if (!pI830->noAccel) +#ifdef I830_USE_XAA + if (!pI830->noAccel && !pI830->useEXA) (*pI830->AccelInfoRec->Sync)(pScrn); +#endif +#ifdef I830_USE_EXA + if (!pI830->noAccel && pI830->useEXA) { + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + (*pI830->EXADriverPtr->accel.WaitMarker)(pScreen, 0); + } +#endif #ifndef BINDUNBIND #define BINDUNBIND 0 @@ -5454,7 +5535,9 @@ { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); +#ifdef I830_USE_XAA XAAInfoRecPtr infoPtr = pI830->AccelInfoRec; +#endif pI830->closing = TRUE; #ifdef XF86DRI @@ -5480,14 +5563,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.11 diff -u -r1.11 i830_memory.c --- i830_memory.c 15 Aug 2005 07:30:05 -0000 1.11 +++ i830_memory.c 29 Aug 2005 04:41:59 -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 29 Aug 2005 04:42:01 -0000 @@ -1485,14 +1485,13 @@ OVERLAY_UPDATE; } +#ifdef I830_USE_XAA static FBLinearPtr -I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) +I830XAAAllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) { ScreenPtr pScreen; FBLinearPtr new_linear; - DPRINTF(PFX, "I830AllocateMemory\n"); - if (linear) { if (linear->size >= size) return linear; @@ -1524,6 +1523,48 @@ return new_linear; } +#endif /* I830_USE_XAA */ + +#ifdef I830_USE_EXA +static FBLinearPtr +I830EXAAllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) +{ + ExaOffscreenArea *area = (ExaOffscreenArea *)(linear); + ScreenPtr pScreen; + + /* Return the existing allocation if possible */ + if (area && area->size >= size) + return linear; + + /* If not, free the old one and try to allocate a new region */ + pScreen = screenInfo.screens[pScrn->scrnIndex]; + exaOffscreenFree(pScreen, area); + + if (!(area = exaOffscreenAlloc(pScreen, size, 32, TRUE, NULL, NULL))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv: Failed to allocate %d bytes " + "of video memory\n", size); + return 0; + } + + linear = (void *)area; + return linear; +} +#endif /* I830_USE_EXA */ + +static FBLinearPtr +I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) +{ + I830Ptr pI830 = I830PTR(pScrn); + + DPRINTF(PFX, "I830AllocateMemory\n"); +#ifdef I830_USE_EXA + if (pI830->useEXA) + return I830EXAAllocateMemory(pScrn, linear, size); +#endif +#ifdef I830_USE_XAA + return I830XAAAllocateMemory(pScrn, linear, size); +#endif +} static int I830PutImage(ScrnInfoPtr pScrn, --- /dev/null 2005-08-28 14:36:59.832854224 -0700 +++ i830_xaa.c 2005-08-28 21:08:44.000000000 -0700 @@ -0,0 +1,674 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86_ansic.h" +#include "xf86.h" +#include "xaarop.h" +#include "i830.h" +#include "i810_reg.h" + +#ifndef DO_SCANLINE_IMAGE_WRITE +#define DO_SCANLINE_IMAGE_WRITE 0 +#endif + +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Reformatted with GNU indent (2.2.8), using the following options: + * + * -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78 + * -lp -npcs -psl -sob -ss -br -ce -sc -hnl + * + * This provides a good match with the original i810 code and preferred + * XFree86 formatting conventions. + * + * When editing this driver, please follow the existing formatting, and edit + * with characters expanded at 8-column intervals. + */ + +/* + * Authors: + * Keith Whitwell + * + */ + +/* I830 Accel Functions */ +static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int pattx, int patty, + int fg, int bg, int rop, + unsigned int planemask); +static void I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int pattx, int patty, + int x, int y, int w, int h); + +static void I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int mask); + +static void I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr + pScrn, int x, + int y, int w, + int h, + int skipleft); + +static void I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); + +#if DO_SCANLINE_IMAGE_WRITE +static void I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, + unsigned int planemask, + int trans_color, int bpp, + int depth); +static void I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft); +static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno); +#endif +static void I830RestoreAccelState(ScrnInfoPtr pScrn); + +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; + + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = + (NO_PLANEMASK | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST); + + infoPtr->ScanlineColorExpandBuffers = (unsigned char **) + xnfcalloc(1, sizeof(unsigned char *)); + infoPtr->NumScanlineColorExpandBuffers = 1; + + infoPtr->ScanlineColorExpandBuffers[0] = + pI830->ScanlineColorExpandBuffers[0]; + pI830->nextColorExpandBuf = 0; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + I830SetupForScanlineCPUToScreenColorExpandFill; + + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + I830SubsequentScanlineCPUToScreenColorExpandFill; + + infoPtr->SubsequentColorExpandScanline = + I830SubsequentColorExpandScanline; + +#if DO_SCANLINE_IMAGE_WRITE + 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; +#endif + } + + { + 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; + } + + I830SelectBuffer(pScrn, I830_SELECT_FRONT); + + return XAAInit(pScreen, infoPtr); +} + +void +I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n", + color, rop, planemask); + + pI830->BR[13] = ((XAAGetPatternROP(rop) << 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; + } +} + +void +I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SubsequentFillRectSolid %d,%d %dx%d\n", x, y, w, h); + + { + 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(); + } +} + +void +I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SetupForScreenToScreenCopy %d %d %x %x %d\n", + xdir, ydir, rop, planemask, transparency_color); + + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + pI830->BR[13] |= XAAGetCopyROP(rop) << 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; + } + +} + +void +I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1, + int dst_x1, int dst_y1, int w, int h) +{ + I830Ptr pI830 = I830PTR(pScrn); + int dst_x2, dst_y2; + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n", + src_x1, src_y1, dst_x1, dst_y1, w, h); + + 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); + + ADVANCE_LP_RING(); + } +} + +static void +I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty, + int fg, int bg, int rop, + unsigned int planemask) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SetupForMono8x8PatternFill\n"); + + pI830->BR[16] = pattx; + pI830->BR[17] = patty; + pI830->BR[18] = bg; + pI830->BR[19] = fg; + + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); /* In bytes */ + pI830->BR[13] |= XAAGetPatternROP(rop) << 16; + if (bg == -1) + pI830->BR[13] |= (1 << 28); + + 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 +I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty, + int x, int y, int w, int h) +{ + I830Ptr pI830 = I830PTR(pScrn); + int x1, x2, y1, y2; + + x1 = x; + x2 = x + w; + y1 = y; + y2 = y + h; + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SubsequentMono8x8PatternFillRect\n"); + + { + BEGIN_LP_RING(10); + + if (pScrn->bitsPerPixel == 32) { + OUT_RING(XY_MONO_PAT_BLT_CMD | XY_MONO_PAT_BLT_WRITE_ALPHA | + XY_MONO_PAT_BLT_WRITE_RGB | + ((patty << 8) & XY_MONO_PAT_VERT_SEED) | + ((pattx << 12) & XY_MONO_PAT_HORT_SEED)); + } else { + OUT_RING(XY_MONO_PAT_BLT_CMD | + ((patty << 8) & XY_MONO_PAT_VERT_SEED) | + ((pattx << 12) & XY_MONO_PAT_HORT_SEED)); + } + OUT_RING(pI830->BR[13]); + OUT_RING((y1 << 16) | x1); + OUT_RING((y2 << 16) | x2); + OUT_RING(pI830->bufferOffset); + OUT_RING(pI830->BR[18]); /* bg */ + OUT_RING(pI830->BR[19]); /* fg */ + OUT_RING(pI830->BR[16]); /* pattern data */ + OUT_RING(pI830->BR[17]); + OUT_RING(0); + ADVANCE_LP_RING(); + } +} + +static void +I830GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + XAAInfoRecPtr infoPtr = pI830->AccelInfoRec; + + if (pI830->nextColorExpandBuf == pI830->NumScanlineColorExpandBuffers) + I830Sync(pScrn); + + infoPtr->ScanlineColorExpandBuffers[0] = + pI830->ScanlineColorExpandBuffers[pI830->nextColorExpandBuf]; + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("using color expand buffer %d\n", pI830->nextColorExpandBuf); + + pI830->nextColorExpandBuf++; +} + +static void +I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n", + fg, bg, rop, planemask); + + /* Fill out register values */ + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + pI830->BR[13] |= XAAGetCopyROP(rop) << 16; + if (bg == -1) + pI830->BR[13] |= (1 << 29); + + switch (pScrn->bitsPerPixel) { + case 8: + break; + case 16: + pI830->BR[13] |= (1 << 24); + break; + case 32: + pI830->BR[13] |= ((1 << 25) | (1 << 24)); + break; + } + + pI830->BR[18] = bg; + pI830->BR[19] = fg; + + I830GetNextScanlineColorExpandBuffer(pScrn); +} + +static void +I830SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, int skipleft) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SubsequentScanlineCPUToScreenColorExpandFill " + "%d,%d %dx%x %d\n", x, y, w, h, skipleft); + + /* Fill out register values */ + pI830->BR[9] = (pI830->bufferOffset + + (y * pScrn->displayWidth + x) * pI830->cpp); + pI830->BR[11] = ((1 << 16) | w); +} + +static void +I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->init == 0) { + pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - + pI830->FbBase); + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + + /* We have to use the primary screen's FbBase, as that's where + * we allocated Scratch2, so we get the correct pointer */ + pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - + pI8301->FbBase); + } + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n", + bufno, pI830->BR[12]); + + { + BEGIN_LP_RING(8); + + if (pScrn->bitsPerPixel == 32) { + OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA | + XY_MONO_SRC_BLT_WRITE_RGB); + } else { + OUT_RING(XY_MONO_SRC_BLT_CMD); + } + OUT_RING(pI830->BR[13]); + OUT_RING(0); /* x1 = 0, y1 = 0 */ + OUT_RING(pI830->BR[11]); /* x2 = w, y2 = 1 */ + OUT_RING(pI830->BR[9]); /* dst addr */ + OUT_RING(pI830->BR[12]); /* src addr */ + OUT_RING(pI830->BR[18]); /* bg */ + OUT_RING(pI830->BR[19]); /* fg */ + + ADVANCE_LP_RING(); + } + + /* Advance to next scanline. + */ + pI830->BR[9] += pScrn->displayWidth * pI830->cpp; + I830GetNextScanlineColorExpandBuffer(pScrn); +} + +#if DO_SCANLINE_IMAGE_WRITE +static void +I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, + unsigned int planemask, int trans_color, + int bpp, int depth) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SetupForScanlineImageWrite %x %x\n", rop, planemask); + + /* Fill out register values */ + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + pI830->BR[13] |= XAAGetCopyROP(rop) << 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; + } + + I830GetNextScanlineColorExpandBuffer(pScrn); +} + +static void +I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y, + int w, int h, int skipleft) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SubsequentScanlineImageWriteRect " + "%d,%d %dx%x %d\n", x, y, w, h, skipleft); + + /* Fill out register values */ + pI830->BR[9] = (pI830->bufferOffset + + (y * pScrn->displayWidth + x) * pI830->cpp); + pI830->BR[11] = ((1 << 16) | w); +} + +static void +I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->init == 0) { + pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - + pI830->FbBase); + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + + /* We have to use the primary screen's FbBase, as that's where + * we allocated Scratch2, so we get the correct pointer */ + pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - + pI8301->FbBase); + } + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF("I830SubsequentImageWriteScanline %d (addr %x)\n", + bufno, pI830->BR[12]); + + { + 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(0); /* x1 = 0, y1 = 0 */ + OUT_RING(pI830->BR[11]); /* x2 = w, y2 = 1 */ + OUT_RING(pI830->BR[9]); /* dst addr */ + OUT_RING(0); /* source origin (0,0) */ + OUT_RING(pI830->BR[11] & 0xffff); /* source pitch */ + OUT_RING(pI830->BR[12]); /* src addr */ + + ADVANCE_LP_RING(); + } + + /* Advance to next scanline. + */ + pI830->BR[9] += pScrn->displayWidth * pI830->cpp; + I830GetNextScanlineColorExpandBuffer(pScrn); +} +#endif /* DO_SCANLINE_IMAGE_WRITE */ +/* Support for multiscreen */ + +static void +I830RestoreAccelState(ScrnInfoPtr pScrn) +{ +#if 0 + /* might be needed, but everything is on a ring, so I don't think so */ + I830Sync(pScrn); +#endif +} + +FBLinearPtr +I830XAAAllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) +{ + ScreenPtr pScreen; + FBLinearPtr new_linear; + + if (linear) { + if (linear->size >= size) + return linear; + + if (xf86ResizeOffscreenLinear(linear, size)) + return linear; + + xf86FreeOffscreenLinear(linear); + } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + + if (!new_linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, + PRIORITY_EXTREME); + + if (max_size < size) + return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + } + + return new_linear; +} + --- /dev/null 2005-08-28 14:36:59.832854224 -0700 +++ i830_exa.c 2005-08-28 21:40:12.000000000 -0700 @@ -0,0 +1,448 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. +Copyright (c) 2005 Jesse Barnes + Based on code from i830_xaa.c. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86_ansic.h" +#include "xf86.h" +#include "xaarop.h" +#include "i830.h" +#include "i810_reg.h" + +int I830CopyROP[16] = +{ + ROP_0, /* GXclear */ + ROP_DSa, /* GXand */ + ROP_SDna, /* GXandReverse */ + ROP_S, /* GXcopy */ + ROP_DSna, /* GXandInverted */ + ROP_D, /* GXnoop */ + ROP_DSx, /* GXxor */ + ROP_DSo, /* GXor */ + ROP_DSon, /* GXnor */ + ROP_DSxn, /* GXequiv */ + ROP_Dn, /* GXinvert*/ + ROP_SDno, /* GXorReverse */ + ROP_Sn, /* GXcopyInverted */ + ROP_DSno, /* GXorInverted */ + ROP_DSan, /* GXnand */ + ROP_1 /* GXset */ +}; + +static int I830PatternROP[16] = +{ + ROP_0, + ROP_DPa, + ROP_PDna, + ROP_P, + ROP_DPna, + ROP_D, + ROP_DPx, + ROP_DPo, + ROP_DPon, + ROP_PDxn, + ROP_Dn, + ROP_PDno, + ROP_Pn, + ROP_DPno, + ROP_DPan, + ROP_1 +}; + +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 + + 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: + * - support planemask using FILL_MONO_SRC_BLT_CMD? + */ +static Bool +I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + if (planemask != (Pixel)~0) + return FALSE; + + pI830->BR[13] = pPixmap->devKind; + pI830->BR[13] |= I830PatternROP[alu] << 16; + + 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; +} + +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; + unsigned int offset; + + offset = (unsigned long)pPixmap->devPrivate.ptr - + (unsigned long)pI830->EXADriverPtr->card.memoryBase; + + offset += y1 * pPixmap->devKind + + x1 * (pPixmap->drawable.bitsPerPixel / 8); + + 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 * (pPixmap->drawable.bitsPerPixel/8))); + OUT_RING(offset); + OUT_RING(pI830->BR[16]); + OUT_RING(0); + + ADVANCE_LP_RING(); + } +} + +static void +I830EXADoneSolid(PixmapPtr pPixmap) +{ + return; +} + +/** + * TODO: + * - support planemask using FULL_BLT_CMD? + */ +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); + + if (planemask != (Pixel)~0) + return FALSE; + + pI830->copy_src_pitch = pSrcPixmap->devKind; + pI830->copy_src_off = (unsigned long)pSrcPixmap->devPrivate.ptr - + (unsigned long)pI830->EXADriverPtr->card.memoryBase; + + pI830->BR[13] = pDstPixmap->devKind; + pI830->BR[13] |= I830CopyROP[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; +} + +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; + unsigned int src_off, dst_off; + + dst_x2 = dst_x1 + w; + dst_y2 = dst_y1 + h; + + src_off = pI830->copy_src_off; + dst_off = (unsigned long)pDstPixmap->devPrivate.ptr - + (unsigned long)pI830->EXADriverPtr->card.memoryBase; + + { + 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(dst_off); + OUT_RING((src_y1 << 16) | (src_x1 & 0xffff)); + OUT_RING(pI830->copy_src_pitch); + OUT_RING(src_off); + + 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: + * - Dual head? + * - Upload/Download + * - Composite + */ +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... */ + } + + pI830->EXADriverPtr->card.pixmapOffsetAlign = 256; + pI830->EXADriverPtr->card.pixmapPitchAlign = 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); + + return TRUE; +} + +FBLinearPtr +I830EXAAllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) +{ + ExaOffscreenArea *area = (ExaOffscreenArea *)(linear); + ScreenPtr pScreen; + + /* Return the existing allocation if possible */ + if (area && area->size >= size) + return linear; + + /* If not, free the old one and try to allocate a new region */ + pScreen = screenInfo.screens[pScrn->scrnIndex]; + exaOffscreenFree(pScreen, area); + + if (!(area = exaOffscreenAlloc(pScreen, size, 32, TRUE, NULL, NULL))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv: Failed to allocate %d bytes " + "of video memory\n", size); + return 0; + } + + linear = (void *)area; + return linear; +}