summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am8
-rw-r--r--src/i830.h25
-rw-r--r--src/i830_3d.c10
-rw-r--r--src/i830_accel.c647
-rw-r--r--src/i830_dga.c4
-rw-r--r--src/i830_dri.c6
-rw-r--r--src/i830_driver.c174
-rw-r--r--src/i830_exa.c594
-rw-r--r--src/i830_exa_render.c512
-rw-r--r--src/i830_memory.c28
-rw-r--r--src/i830_reg.h117
-rw-r--r--src/i830_rotate.c33
-rw-r--r--src/i830_video.c2
-rw-r--r--src/i830_xaa.c712
-rw-r--r--src/i915_3d.c4
-rw-r--r--src/i915_3d.h27
-rw-r--r--src/i915_exa_render.c501
-rw-r--r--src/i915_reg.h12
18 files changed, 2715 insertions, 701 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 63370ab9..e58350c9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,7 +24,7 @@ SUBDIRS = xvmc
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV -DI830_USE_XAA -DI830_USE_EXA
i810_drv_la_LTLIBRARIES = i810_drv.la
i810_drv_la_LDFLAGS = -module -avoid-version
@@ -64,7 +64,11 @@ i810_drv_la_SOURCES = \
i915_3d.c \
i915_3d.h \
i915_reg.h \
- i915_video.c
+ i915_video.c \
+ i830_exa.c \
+ i830_xaa.c \
+ i830_exa_render.c \
+ i915_exa_render.c
if DRI
i810_drv_la_SOURCES += \
diff --git a/src/i830.h b/src/i830.h
index 38a880fb..df1c171a 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -70,6 +70,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830_dri.h"
#endif
+#ifdef I830_USE_EXA
+#include "exa.h"
+Bool I830EXAInit(ScreenPtr pScreen);
+#endif
+
+#ifdef I830_USE_XAA
+Bool I830XAAInit(ScreenPtr pScreen);
+#endif
+
#include "common.h"
#define NEED_REPLIES /* ? */
@@ -232,7 +241,9 @@ typedef struct _I830Rec {
I830MemRange FrontBuffer2;
I830MemRange Scratch;
I830MemRange Scratch2;
-
+#ifdef I830_USE_EXA
+ I830MemRange Offscreen;
+#endif
/* Regions allocated either from the above pools, or from agpgart. */
I830MemRange *CursorMem;
I830MemRange *CursorMemARGB;
@@ -332,13 +343,22 @@ typedef struct _I830Rec {
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;
@@ -531,6 +551,9 @@ extern Bool I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode);
extern Bool I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode);
extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
+extern void i830MarkSync(ScrnInfoPtr pScrn);
+extern void i830WaitSync(ScrnInfoPtr pScrn);
+
/* i830_memory.c */
Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
diff --git a/src/i830_3d.c b/src/i830_3d.c
index debad7c9..563dcef7 100644
--- a/src/i830_3d.c
+++ b/src/i830_3d.c
@@ -34,13 +34,11 @@
#include "i830_reg.h"
-#define CMD_3D (0x3<<29)
-
void I830EmitInvarientState( ScrnInfoPtr pScrn )
{
I830Ptr pI830 = I830PTR(pScrn);
- BEGIN_LP_RING(38);
+ BEGIN_LP_RING(40);
OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(0));
OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(1));
@@ -99,6 +97,12 @@ void I830EmitInvarientState( ScrnInfoPtr pScrn )
OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
+ OUT_RING(_3DSTATE_MAP_COORD_SETBIND_CMD);
+ OUT_RING(TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
+ TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
+ TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
+ TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
+
OUT_RING(_3DSTATE_RASTER_RULES_CMD |
ENABLE_POINT_RASTER_RULE |
OGL_POINT_RASTER_RULE |
diff --git a/src/i830_accel.c b/src/i830_accel.c
index b029968e..6ad62d1f 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -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.
@@ -111,7 +107,12 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
DRICloseScreen(screenInfo.screens[pScrn->scrnIndex]);
}
#endif
+#ifdef I830_USE_XAA
pI830->AccelInfoRec = NULL; /* Stops recursive behavior */
+#endif
+#ifdef I830_USE_EXA
+ pI830->EXADriverPtr = NULL;
+#endif
FatalError("lockup\n");
}
@@ -219,47 +220,9 @@ I830RefreshRing(ScrnInfoPtr pScrn)
pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
if (pI830->LpRing->space < 0)
pI830->LpRing->space += pI830->LpRing->mem.Size;
-
- if (pI830->AccelInfoRec)
- pI830->AccelInfoRec->NeedToSync = TRUE;
+ i830MarkSync(pScrn);
}
-/* 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
* in a monolithic server.
@@ -267,597 +230,15 @@ static void I830RestoreAccelState(ScrnInfoPtr pScrn);
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;
+#ifdef I830_USE_EXA
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
- /* 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);
-}
-
-#ifdef XF86DRI
-static unsigned int
-CheckTiling(ScrnInfoPtr pScrn)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned int tiled = 0;
-
- /* Check tiling */
- if (IS_I965G(pI830)) {
- if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR)
- tiled = 1;
- if (pI830->bufferOffset == pI830->RotatedMem.Start && pI830->rotated_tiled == FENCE_XMAJOR)
- tiled = 1;
- if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR)
- tiled = 1;
- /* not really supported as it's always YMajor tiled */
- if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR)
- tiled = 1;
- }
-
- return tiled;
-}
-#else
-#define CheckTiling(pScrn) 0
+ if (pI830->useEXA)
+ return I830EXAInit(pScreen);
#endif
-
-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();
- }
-
- if (IS_I965G(pI830))
- I830EmitFlush(pScrn);
-}
-
-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;
- unsigned int tiled = CheckTiling(pScrn);
-
- 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;
-
- if (tiled)
- pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
- (pI830->BR[13] & 0xFFFF0000);
-
- {
- 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 | tiled << 15 | tiled << 11);
- } else {
- OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 15 | tiled << 11);
- }
- 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();
- }
-
- if (IS_I965G(pI830))
- I830EmitFlush(pScrn);
-}
-
-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;
- unsigned int tiled = CheckTiling(pScrn);
-
- x1 = x;
- x2 = x + w;
- y1 = y;
- y2 = y + h;
-
- if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
- ErrorF("I830SubsequentMono8x8PatternFillRect\n");
-
- if (tiled)
- pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
- (pI830->BR[13] & 0xFFFF0000);
-
- {
- 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 |
- tiled << 11 |
- ((patty << 8) & XY_MONO_PAT_VERT_SEED) |
- ((pattx << 12) & XY_MONO_PAT_HORT_SEED));
- } else {
- OUT_RING(XY_MONO_PAT_BLT_CMD |
- tiled << 11 |
- ((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();
- }
-
- if (IS_I965G(pI830))
- I830EmitFlush(pScrn);
-}
-
-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);
- unsigned int tiled = CheckTiling(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]);
-
- if (tiled)
- pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
- (pI830->BR[13] & 0xFFFF0000);
-
- {
- BEGIN_LP_RING(8);
-
- if (pScrn->bitsPerPixel == 32) {
- OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA |
- tiled << 11 |
- XY_MONO_SRC_BLT_WRITE_RGB);
- } else {
- OUT_RING(XY_MONO_SRC_BLT_CMD | tiled << 11);
- }
- 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 (IS_I965G(pI830))
- I830EmitFlush(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);
- unsigned int tiled = CheckTiling(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 |
- tiled << 11 |
- XY_SRC_COPY_BLT_WRITE_RGB);
- } else {
- OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 11);
- }
- 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;
}
diff --git a/src/i830_dga.c b/src/i830_dga.c
index bd45d61d..c78063e1 100644
--- a/src/i830_dga.c
+++ b/src/i830_dga.c
@@ -264,6 +264,7 @@ static void
I830_FillRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h, unsigned long color)
{
+#ifdef I830_USE_XAA
I830Ptr pI830 = I830PTR(pScrn);
MARKER();
@@ -273,6 +274,7 @@ I830_FillRect(ScrnInfoPtr pScrn,
(*pI830->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
SET_SYNC_FLAG(pI830->AccelInfoRec);
}
+#endif
}
static void
@@ -304,6 +306,7 @@ 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();
@@ -318,6 +321,7 @@ I830_BlitRect(ScrnInfoPtr pScrn,
dstx, dsty, w, h);
SET_SYNC_FLAG(pI830->AccelInfoRec);
}
+#endif
}
#if 0
diff --git a/src/i830_dri.c b/src/i830_dri.c
index c9b52c48..8a52750f 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1019,7 +1019,6 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- I830Ptr pI830 = I830PTR(pScrn);
BoxPtr pbox = REGION_RECTS(prgn);
int nbox = REGION_NUM_RECTS(prgn);
@@ -1057,7 +1056,7 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
}
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
- pI830->AccelInfoRec->NeedToSync = TRUE;
+ i830MarkSync(pScrn);
}
/* This routine is a modified form of XAADoBitBlt with the calls to
@@ -1220,8 +1219,7 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
DEALLOCATE_LOCAL(pptNew1);
DEALLOCATE_LOCAL(pboxNew1);
}
-
- pI830->AccelInfoRec->NeedToSync = TRUE;
+ i830MarkSync(pScrn);
}
/* Use callbacks from dri.c to support pageflipping mode for a single
diff --git a/src/i830_driver.c b/src/i830_driver.c
index c0d96725..10a329c9 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -199,6 +199,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "dri.h"
#endif
+#ifdef I830_USE_EXA
+const char *I830exaSymbols[] = {
+ "exaGetVersion",
+ "exaDriverInit",
+ "exaDriverFini",
+ "exaOffscreenAlloc",
+ "exaOffscreenFree",
+ "exaWaitSync",
+ NULL
+};
+#endif
+
#define BIT(x) (1 << (x))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define NB_OF(x) (sizeof (x) / sizeof (*x))
@@ -245,6 +257,9 @@ static PciChipsets I830BIOSPciChipsets[] = {
*/
typedef enum {
+#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
+ OPTION_ACCELMETHOD,
+#endif
OPTION_NOACCEL,
OPTION_SW_CURSOR,
OPTION_CACHE_LINES,
@@ -272,6 +287,9 @@ typedef enum {
} 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},
@@ -4202,6 +4220,42 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
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;
}
@@ -5482,14 +5536,33 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
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) {
+ XF86ModReqInfo req;
+ int errmaj, errmin;
+ memset(&req, 0, sizeof(req));
+ req.majorversion = 2;
+ req.minorversion = 0;
+ if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
+ &errmaj, &errmin)) {
+ LoaderErrorMsg(NULL, "exa", errmaj, errmin);
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(I830exaSymbols, NULL);
+ }
+#endif
if (!pI830->SWCursor) {
if (!xf86LoadSubModule(pScrn, "ramdac")) {
PreInitCleanup(pScrn);
@@ -5647,16 +5720,25 @@ ResetState(ScrnInfoPtr pScrn, Bool flush)
for (i = 0; i < FENCE_NR; i++)
OUTREG(FENCE + i * 4, 0);
}
-
/* Flush the ring buffer (if enabled), then disable it. */
- if (pI830->AccelInfoRec != NULL && flush) {
- temp = INREG(LP_RING + RING_LEN);
- if (temp & 1) {
- I830RefreshRing(pScrn);
- I830Sync(pScrn);
- DO_RING_IDLE();
- }
- }
+ /* God this is ugly */
+#define flush_ring() do { \
+ temp = INREG(LP_RING + RING_LEN); \
+ if (temp & 1) { \
+ I830RefreshRing(pScrn); \
+ I830Sync(pScrn); \
+ DO_RING_IDLE(); \
+ } \
+ } while(0)
+#ifdef I830_USE_XAA
+ if (!pI830->useEXA && flush && pI830->AccelInfoRec)
+ flush_ring();
+#endif
+#ifdef I830_USE_XAA
+ if (pI830->useEXA && flush && pI830->EXADriverPtr)
+ flush_ring();
+#endif
+
OUTREG(LP_RING + RING_LEN, 0);
OUTREG(LP_RING + RING_HEAD, 0);
OUTREG(LP_RING + RING_TAIL, 0);
@@ -7509,10 +7591,7 @@ I830AdjustFrame(int scrnIndex, int x, int y, int flags)
x, pI830->xoffset, y, pI830->yoffset);
/* Sync the engine before adjust frame */
- if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
- (*pI830->AccelInfoRec->Sync)(pScrn);
- pI830->AccelInfoRec->NeedToSync = FALSE;
- }
+ i830WaitSync(pScrn);
if (pI830->MergedFB) {
I830AdjustFrameMerged(scrnIndex, x, y, flags);
@@ -7678,8 +7757,11 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
RestoreBIOSMemSize(pScrn);
if (I830IsPrimary(pScrn))
I830UnbindAGPMemory(pScrn);
- if (pI830->AccelInfoRec)
+
+#ifdef I830_USE_XAA
+ if (!pI830->useEXA && pI830->AccelInfoRec)
pI830->AccelInfoRec->NeedToSync = FALSE;
+#endif
/* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */
if (I830IsPrimary(pScrn)) {
@@ -8133,10 +8215,7 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
#endif
/* Sync the engine before mode switch */
- if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
- (*pI830->AccelInfoRec->Sync)(pScrn);
- pI830->AccelInfoRec->NeedToSync = FALSE;
- }
+ i830WaitSync(pScrn);
/* Check if our currentmode is about to change. We do this so if we
* are rotating, we don't need to call the mode setup again.
@@ -8304,7 +8383,9 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
+#ifdef I830_USE_XAA
XAAInfoRecPtr infoPtr = pI830->AccelInfoRec;
+#endif
pI830->closing = TRUE;
#ifdef XF86DRI
@@ -8330,14 +8411,21 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen)
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 && pI830->EXADriverPtr) {
+ exaDriverFini(pScreen);
+ xfree(pI830->EXADriverPtr);
+ pI830->EXADriverPtr = NULL;
+ }
+#endif
if (pI830->CursorInfoRec) {
xf86DestroyCursorInfoRec(pI830->CursorInfoRec);
pI830->CursorInfoRec = 0;
@@ -8509,12 +8597,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Hotkey switch to 0x%lx.\n", (unsigned long) temp);
- if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
- (*pI830->AccelInfoRec->Sync)(pScrn);
- pI830->AccelInfoRec->NeedToSync = FALSE;
- if (xf86IsEntityShared(pScrn->entityList[0]))
- pI8302->AccelInfoRec->NeedToSync = FALSE;
- }
+ i830WaitSync(pScrn);
GetAttachableDisplayDeviceList(pScrn);
@@ -8791,6 +8874,43 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
}
void
+i830WaitSync(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+#ifdef I830_USE_XAA
+ if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec
+ && pI830->AccelInfoRec->NeedToSync) {
+ (*pI830->AccelInfoRec->Sync)(pScrn);
+ pI830->AccelInfoRec->NeedToSync = FALSE;
+ }
+#endif
+#ifdef I830_USE_EXA
+ if (!pI830->noAccel && pI830->useEXA && pI830->EXADriverPtr) {
+ ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+ exaWaitSync(pScreen);
+ }
+#endif
+}
+
+void
+i830MarkSync(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+#ifdef I830_USE_XAA
+ if (!pI830->useEXA && pI830->AccelInfoRec)
+ pI830->AccelInfoRec->NeedToSync = FALSE;
+#endif
+#ifdef I830_USE_EXA
+ if (pI830->useEXA && pI830->EXADriverPtr) {
+ ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+ exaMarkSync(pScreen);
+ }
+#endif
+}
+
+void
I830InitpScrn(ScrnInfoPtr pScrn)
{
pScrn->PreInit = I830BIOSPreInit;
diff --git a/src/i830_exa.c b/src/i830_exa.c
new file mode 100644
index 00000000..bb75b24a
--- /dev/null
+++ b/src/i830_exa.c
@@ -0,0 +1,594 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+Copyright (c) 2005 Jesse Barnes <jbarnes@virtuousgeek.org>
+ 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"
+#include "i830_reg.h"
+
+#ifdef I830DEBUG
+#define DEBUG_I830FALLBACK 1
+#endif
+
+#ifdef DEBUG_I830FALLBACK
+#define I830FALLBACK(s, arg...) \
+do { \
+ DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); \
+ return FALSE; \
+} while(0)
+#else
+#define I830FALLBACK(s, arg...) \
+do { \
+ return FALSE; \
+} while(0)
+#endif
+
+float scale_units[2][2];
+
+const 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 */
+};
+
+const 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
+};
+
+/* move to common.h */
+union intfloat {
+ float f;
+ unsigned int ui;
+};
+
+#define OUT_RING_F(x) do { \
+ union intfloat tmp; \
+ tmp.f = (float)(x); \
+ OUT_RING(tmp.ui); \
+} while(0)
+
+Bool is_transform[2];
+PictTransform *transform[2];
+
+Bool i830UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
+ char *src, int src_pitch);
+Bool i830DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
+ char *dst, int dst_pitch);
+
+extern Bool I830EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr);
+extern Bool I830EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr,
+ PixmapPtr, PixmapPtr, PixmapPtr);
+extern Bool I915EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr);
+extern Bool I915EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr,
+ PixmapPtr, PixmapPtr, PixmapPtr);
+
+/**
+ * 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);
+ unsigned long offset, pitch;
+
+ if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planemask))
+ I830FALLBACK("planemask is not solid");
+
+ offset = exaGetPixmapOffset(pPixmap);
+ pitch = exaGetPixmapPitch(pPixmap);
+
+ if ( offset % pI830->EXADriverPtr->pixmapOffsetAlign != 0)
+ I830FALLBACK("pixmap offset not aligned");
+ if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
+ I830FALLBACK("pixmap pitch not aligned");
+
+ pI830->BR[13] = pitch;
+ 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 long offset;
+
+ /* pixmap's offset and pitch is aligned,
+ otherwise it falls back in PrepareSolid */
+ offset = exaGetPixmapOffset(pPixmap) + y1 * exaGetPixmapPitch(pPixmap) +
+ 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 (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))
+ I830FALLBACK("planemask is not solid");
+
+ pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
+ pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
+
+ pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
+ 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 = exaGetPixmapOffset(pDstPixmap);
+
+ {
+ 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;
+}
+
+static Bool
+I830EXAUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
+ char *src, int src_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ int dst_pitch = exaGetPixmapPitch(pDst);
+ int dst_offset = exaGetPixmapOffset(pDst);
+ unsigned char *dst;
+
+ I830Sync(pScrn);
+
+#ifdef I830DEBUG
+ ErrorF("Up->Screen: dst offset 0x%x, dst pitch %d, x %d, y %d, src %p, src pitch %d\n",
+ dst_offset, dst_pitch, x, y, src, src_pitch);
+#endif
+ dst = pI830->FbBase + dst_offset + y*dst_pitch +
+ x* (pDst->drawable.bitsPerPixel/8);
+ w *= pDst->drawable.bitsPerPixel/8;
+ while(h--) {
+ memcpy(dst, src, w);
+ 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);
+ int src_pitch = exaGetPixmapPitch(pSrc);
+ int src_offset = exaGetPixmapOffset(pSrc);
+ unsigned char *src = pI830->FbBase + src_offset + y*src_pitch +
+ x*(pSrc->drawable.bitsPerPixel/8);
+
+ I830Sync(pScrn);
+
+#ifdef I830DEBUG
+ ErrorF("Screen->Mem: src offset 0x%x, src %p, src pitch %d, x %d, y %d, dst %p, dst_pitch %d\n",
+ src_offset, src, src_pitch, x, y, dst, dst_pitch);
+#endif
+ w *= pSrc->drawable.bitsPerPixel/8;
+ while(h--) {
+ memcpy(dst, src, w);
+ src += src_pitch;
+ dst += dst_pitch;
+ }
+
+ return TRUE;
+}
+
+static void
+IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int w, int h)
+{
+ /* should be same like I830Composite */
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ int srcXend, srcYend, maskXend, maskYend;
+ PictVector v;
+ int pMask = 1;
+
+ DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t"
+ "dstX %d, dstY %d\n\twidth %d, height %d\n\t"
+ "src_scale_x %f, src_scale_y %f, "
+ "mask_scale_x %f, mask_scale_y %f\n",
+ srcX, srcY, maskX, maskY, dstX, dstY, w, h,
+ scale_units[0][0], scale_units[0][1],
+ scale_units[1][0], scale_units[1][1]);
+
+ if (scale_units[1][0] == -1 || scale_units[1][1] == -1) {
+ ErrorF("mask is null\n");
+ pMask = 0;
+ }
+
+ srcXend = srcX + w;
+ srcYend = srcY + h;
+ maskXend = maskX + w;
+ maskYend = maskY + h;
+ if (is_transform[0]) {
+ v.vector[0] = IntToxFixed(srcX);
+ v.vector[1] = IntToxFixed(srcY);
+ v.vector[2] = xFixed1;
+ PictureTransformPoint(transform[0], &v);
+ srcX = xFixedToInt(v.vector[0]);
+ srcY = xFixedToInt(v.vector[1]);
+ v.vector[0] = IntToxFixed(srcXend);
+ v.vector[1] = IntToxFixed(srcYend);
+ v.vector[2] = xFixed1;
+ PictureTransformPoint(transform[0], &v);
+ srcXend = xFixedToInt(v.vector[0]);
+ srcYend = xFixedToInt(v.vector[1]);
+ }
+ if (is_transform[1]) {
+ v.vector[0] = IntToxFixed(maskX);
+ v.vector[1] = IntToxFixed(maskY);
+ v.vector[2] = xFixed1;
+ PictureTransformPoint(transform[1], &v);
+ maskX = xFixedToInt(v.vector[0]);
+ maskY = xFixedToInt(v.vector[1]);
+ v.vector[0] = IntToxFixed(maskXend);
+ v.vector[1] = IntToxFixed(maskYend);
+ v.vector[2] = xFixed1;
+ PictureTransformPoint(transform[1], &v);
+ maskXend = xFixedToInt(v.vector[0]);
+ maskYend = xFixedToInt(v.vector[1]);
+ }
+ DPRINTF(PFX, "After transform: srcX %d, srcY %d,srcXend %d, srcYend %d\n\t"
+ "maskX %d, maskY %d, maskXend %d, maskYend %d\n\t"
+ "dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend,
+ maskX, maskY, maskXend, maskYend, dstX, dstY);
+
+ {
+ int vertex_count;
+
+ if (pMask)
+ vertex_count = 4*6;
+ else
+ vertex_count = 4*4;
+
+ BEGIN_LP_RING(6+vertex_count);
+
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+
+ OUT_RING(PRIM3D_INLINE | PRIM3D_TRIFAN | (vertex_count-1));
+
+ OUT_RING_F(dstX);
+ OUT_RING_F(dstY);
+ OUT_RING_F(srcX / scale_units[0][0]);
+ OUT_RING_F(srcY / scale_units[0][1]);
+ if (pMask) {
+ OUT_RING_F(maskX / scale_units[1][0]);
+ OUT_RING_F(maskY / scale_units[1][1]);
+ }
+
+ OUT_RING_F(dstX);
+ OUT_RING_F(dstY + h);
+ OUT_RING_F(srcX / scale_units[0][0]);
+ OUT_RING_F(srcYend / scale_units[0][1]);
+ if (pMask) {
+ OUT_RING_F(maskX / scale_units[1][0]);
+ OUT_RING_F(maskYend / scale_units[1][1]);
+ }
+
+ OUT_RING_F(dstX + w);
+ OUT_RING_F(dstY + h);
+ OUT_RING_F(srcXend / scale_units[0][0]);
+ OUT_RING_F(srcYend / scale_units[0][1]);
+ if (pMask) {
+ OUT_RING_F(maskXend / scale_units[1][0]);
+ OUT_RING_F(maskYend / scale_units[1][1]);
+ }
+
+ OUT_RING_F(dstX + w);
+ OUT_RING_F(dstY);
+ OUT_RING_F(srcXend / scale_units[0][0]);
+ OUT_RING_F(srcY / scale_units[0][1]);
+ if (pMask) {
+ OUT_RING_F(maskXend / scale_units[1][0]);
+ OUT_RING_F(maskY / scale_units[1][1]);
+ }
+ ADVANCE_LP_RING();
+ }
+#ifdef I830DEBUG
+ ErrorF("sync after 3dprimitive");
+ I830Sync(pScrn);
+#endif
+
+}
+
+static void
+IntelEXADoneComposite(PixmapPtr pDst)
+{
+ return;
+}
+/*
+ * TODO:
+ * - Dual head?
+ */
+Bool
+I830EXAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ pI830->EXADriverPtr = exaDriverAlloc();
+ if (pI830->EXADriverPtr == NULL) {
+ pI830->noAccel = TRUE;
+ return FALSE;
+ }
+ memset(pI830->EXADriverPtr, 0, sizeof(*pI830->EXADriverPtr));
+
+ pI830->bufferOffset = 0;
+ pI830->EXADriverPtr->exa_major = 2;
+ pI830->EXADriverPtr->exa_minor = 0;
+ pI830->EXADriverPtr->memoryBase = pI830->FbBase;
+ pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
+ pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
+
+ DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
+ pI830->EXADriverPtr->memoryBase,
+ pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize,
+ pI830->EXADriverPtr->offScreenBase,
+ pI830->EXADriverPtr->memorySize);
+
+ if(pI830->EXADriverPtr->memorySize >
+ pI830->EXADriverPtr->offScreenBase)
+ pI830->EXADriverPtr->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->pixmapOffsetAlign = 256;
+ pI830->EXADriverPtr->pixmapPitchAlign = 64;
+ pI830->EXADriverPtr->maxX = 4095;
+ pI830->EXADriverPtr->maxY = 4095;
+
+ /* Sync */
+ pI830->EXADriverPtr->WaitMarker = I830EXASync;
+
+ /* Solid fill */
+ pI830->EXADriverPtr->PrepareSolid = I830EXAPrepareSolid;
+ pI830->EXADriverPtr->Solid = I830EXASolid;
+ pI830->EXADriverPtr->DoneSolid = I830EXADoneSolid;
+
+ /* Copy */
+ pI830->EXADriverPtr->PrepareCopy = I830EXAPrepareCopy;
+ pI830->EXADriverPtr->Copy = I830EXACopy;
+ pI830->EXADriverPtr->DoneCopy = I830EXADoneCopy;
+
+ /* Composite */
+ if (IS_I9XX(pI830)) {
+ pI830->EXADriverPtr->CheckComposite = I915EXACheckComposite;
+ pI830->EXADriverPtr->PrepareComposite = I915EXAPrepareComposite;
+ pI830->EXADriverPtr->Composite = IntelEXAComposite;
+ pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
+ } else if (IS_I865G(pI830) || IS_I855(pI830) || IS_845G(pI830) || IS_I830(pI830)) {
+ pI830->EXADriverPtr->CheckComposite = I830EXACheckComposite;
+ pI830->EXADriverPtr->PrepareComposite = I830EXAPrepareComposite;
+ pI830->EXADriverPtr->Composite = IntelEXAComposite;
+ pI830->EXADriverPtr->DoneComposite = IntelEXADoneComposite;
+ }
+
+ /* Upload, download to/from Screen, experimental!! */
+ pI830->EXADriverPtr->UploadToScreen = I830EXAUploadToScreen;
+ pI830->EXADriverPtr->DownloadFromScreen = I830EXADownloadFromScreen;
+
+ if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
+ xfree(pI830->EXADriverPtr);
+ pI830->noAccel = TRUE;
+ return FALSE;
+ }
+
+ I830SelectBuffer(pScrn, I830_SELECT_FRONT);
+
+ return TRUE;
+}
diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c
new file mode 100644
index 00000000..86e11d21
--- /dev/null
+++ b/src/i830_exa_render.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Wang Zhenyu <zhenyu.z.wang@intel.com>
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+#include "i830_reg.h"
+
+#ifdef I830DEBUG
+#define DEBUG_I830FALLBACK 1
+#endif
+
+#ifdef DEBUG_I830FALLBACK
+#define I830FALLBACK(s, arg...) \
+do { \
+ DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); \
+ return FALSE; \
+} while(0)
+#else
+#define I830FALLBACK(s, arg...) \
+do { \
+ return FALSE; \
+} while(0)
+#endif
+
+extern float scale_units[2][2];
+extern Bool is_transform[2];
+extern PictTransform *transform[2];
+
+struct blendinfo {
+ Bool dst_alpha;
+ Bool src_alpha;
+ CARD32 src_blend;
+ CARD32 dst_blend;
+};
+
+struct formatinfo {
+ int fmt;
+ CARD32 card_fmt;
+};
+
+extern Bool
+I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture);
+
+extern Bool
+I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
+
+
+#define TB0C_LAST_STAGE (1 << 31)
+#define TB0C_RESULT_SCALE_1X (0 << 29)
+#define TB0C_RESULT_SCALE_2X (1 << 29)
+#define TB0C_RESULT_SCALE_4X (2 << 29)
+#define TB0C_OP_MODULE (3 << 25)
+#define TB0C_OUTPUT_WRITE_CURRENT (0 << 24)
+#define TB0C_OUTPUT_WRITE_ACCUM (1 << 24)
+#define TB0C_ARG3_REPLICATE_ALPHA (1<<23)
+#define TB0C_ARG3_INVERT (1<<22)
+#define TB0C_ARG3_SEL_XXX
+#define TB0C_ARG2_REPLICATE_ALPHA (1<<17)
+#define TB0C_ARG2_INVERT (1<<16)
+#define TB0C_ARG2_SEL_ONE (0 << 12)
+#define TB0C_ARG2_SEL_FACTOR (1 << 12)
+#define TB0C_ARG2_SEL_TEXEL0 (6 << 12)
+#define TB0C_ARG2_SEL_TEXEL1 (7 << 12)
+#define TB0C_ARG2_SEL_TEXEL2 (8 << 12)
+#define TB0C_ARG2_SEL_TEXEL3 (9 << 12)
+#define TB0C_ARG1_REPLICATE_ALPHA (1<<11)
+#define TB0C_ARG1_INVERT (1<<10)
+#define TB0C_ARG1_SEL_TEXEL0 (6 << 6)
+#define TB0C_ARG1_SEL_TEXEL1 (7 << 6)
+#define TB0C_ARG1_SEL_TEXEL2 (8 << 6)
+#define TB0C_ARG1_SEL_TEXEL3 (9 << 6)
+#define TB0C_ARG0_REPLICATE_ALPHA (1<<5)
+#define TB0C_ARG0_SEL_XXX
+
+#define TB0A_CTR_STAGE_ENABLE (1<<31)
+#define TB0A_RESULT_SCALE_1X (0 << 29)
+#define TB0A_RESULT_SCALE_2X (1 << 29)
+#define TB0A_RESULT_SCALE_4X (2 << 29)
+#define TB0A_OP_MODULE (3 << 25)
+#define TB0A_OUTPUT_WRITE_CURRENT (0<<24)
+#define TB0A_OUTPUT_WRITE_ACCUM (1<<24)
+#define TB0A_CTR_STAGE_SEL_BITS_XXX
+#define TB0A_ARG3_SEL_XXX
+#define TB0A_ARG3_INVERT (1<<17)
+#define TB0A_ARG2_INVERT (1<<16)
+#define TB0A_ARG2_SEL_ONE (0 << 12)
+#define TB0A_ARG2_SEL_TEXEL0 (6 << 12)
+#define TB0A_ARG2_SEL_TEXEL1 (7 << 12)
+#define TB0A_ARG2_SEL_TEXEL2 (8 << 12)
+#define TB0A_ARG2_SEL_TEXEL3 (9 << 12)
+#define TB0A_ARG1_INVERT (1<<10)
+#define TB0A_ARG1_SEL_TEXEL0 (6 << 6)
+#define TB0A_ARG1_SEL_TEXEL1 (7 << 6)
+#define TB0A_ARG1_SEL_TEXEL2 (8 << 6)
+#define TB0A_ARG1_SEL_TEXEL3 (9 << 6)
+
+static struct blendinfo I830BlendOp[] = {
+ /* Clear */
+ {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ZERO},
+ /* Src */
+ {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ZERO},
+ /* Dst */
+ {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ONE},
+ /* Over */
+ {0, 1, BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA},
+ /* OverReverse */
+ {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ONE},
+ /* In */
+ {1, 0, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_ZERO},
+ /* InReverse */
+ {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_SRC_ALPHA},
+ /* Out */
+ {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ZERO},
+ /* OutReverse */
+ {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_INV_SRC_ALPHA},
+ /* Atop */
+ {1, 1, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA},
+ /* AtopReverse */
+ {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_SRC_ALPHA},
+ /* Xor */
+ {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA},
+ /* Add */
+ {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ONE},
+};
+
+
+static struct formatinfo I830TexFormats[] = {
+ {PICT_a8r8g8b8, MT_32BIT_ARGB8888 },
+ {PICT_x8r8g8b8, MT_32BIT_ARGB8888 },
+ {PICT_a8b8g8r8, MT_32BIT_ABGR8888 },
+ {PICT_x8b8g8r8, MT_32BIT_ABGR8888 },
+ {PICT_r5g6b5, MT_16BIT_RGB565 },
+ {PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
+ {PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
+ {PICT_a8, MT_8BIT_I8 },
+};
+
+static Bool I830GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
+{
+ /* XXX: color buffer format for i830 */
+ switch (pDstPicture->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ *dst_format = COLR_BUF_ARGB8888;
+ break;
+ case PICT_r5g6b5:
+ *dst_format = COLR_BUF_RGB565;
+ break;
+ case PICT_a1r5g5b5:
+ case PICT_x1r5g5b5:
+ *dst_format = COLR_BUF_ARGB1555;
+ break;
+ case PICT_a8:
+ *dst_format = COLR_BUF_8BIT;
+ break;
+ case PICT_a4r4g4b4:
+ case PICT_x4r4g4b4:
+ *dst_format = COLR_BUF_ARGB4444;
+ break;
+ default:
+ I830FALLBACK("Unsupported dest format 0x%x\n",
+ (int)pDstPicture->format);
+ }
+
+ return TRUE;
+}
+
+
+static CARD32 I830GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
+{
+ CARD32 sblend, dblend;
+
+ sblend = I830BlendOp[op].src_blend;
+ dblend = I830BlendOp[op].dst_blend;
+
+ /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+ * it as always 1.
+ */
+ if (PICT_FORMAT_A(dst_format) == 0 && I830BlendOp[op].dst_alpha) {
+ if (sblend == BLENDFACTOR_DST_ALPHA)
+ sblend = BLENDFACTOR_ONE;
+ else if (sblend == BLENDFACTOR_INV_DST_ALPHA)
+ sblend = BLENDFACTOR_ZERO;
+ }
+
+ /* If the source alpha is being used, then we should only be in a case where
+ * the source blend factor is 0, and the source blend value is the mask
+ * channels multiplied by the source picture's alpha.
+ */
+ if (pMask && pMask->componentAlpha && I830BlendOp[op].src_alpha) {
+ if (dblend == BLENDFACTOR_SRC_ALPHA) {
+ dblend = BLENDFACTOR_SRC_COLR;
+ } else if (dblend == BLENDFACTOR_INV_SRC_ALPHA) {
+ dblend = BLENDFACTOR_INV_SRC_COLR;
+ }
+ }
+
+ return (sblend << S8_SRC_BLEND_FACTOR_SHIFT) |
+ (dblend << S8_DST_BLEND_FACTOR_SHIFT);
+}
+
+static Bool I830CheckCompositeTexture(PicturePtr pPict, int unit)
+{
+ int w = pPict->pDrawable->width;
+ int h = pPict->pDrawable->height;
+ int i;
+
+ if ((w > 0x7ff) || (h > 0x7ff))
+ I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
+
+ for (i = 0; i < sizeof(I830TexFormats) / sizeof(I830TexFormats[0]); i++)
+ {
+ if (I830TexFormats[i].fmt == pPict->format)
+ break;
+ }
+ if (i == sizeof(I830TexFormats) / sizeof(I830TexFormats[0]))
+ I830FALLBACK("Unsupported picture format 0x%x\n",
+ (int)pPict->format);
+
+ /* FIXME: fix repeat support */
+ if (pPict->repeat)
+ I830FALLBACK("repeat unsupport now\n");
+
+ if (pPict->filter != PictFilterNearest &&
+ pPict->filter != PictFilterBilinear)
+ I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
+
+ return TRUE;
+}
+
+static Bool
+I830TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit)
+{
+
+ ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 format, offset, pitch, filter;
+ int w, h, i;
+ CARD32 wrap_mode = TEXCOORDMODE_CLAMP;
+
+ offset = exaGetPixmapOffset(pPix);
+ pitch = exaGetPixmapPitch(pPix);
+ w = pPict->pDrawable->width;
+ h = pPict->pDrawable->height;
+ scale_units[unit][0] = pPix->drawable.width;
+ scale_units[unit][1] = pPix->drawable.height;
+
+ for (i = 0; i < sizeof(I830TexFormats) / sizeof(I830TexFormats[0]); i++) {
+ if (I830TexFormats[i].fmt == pPict->format)
+ break;
+ }
+ if ( i == sizeof(I830TexFormats)/ sizeof(I830TexFormats[0]) )
+ I830FALLBACK("unknown texture format\n");
+ format = I830TexFormats[i].card_fmt;
+
+ if (pPict->repeat)
+ wrap_mode = TEXCOORDMODE_WRAP; /* XXX: correct ? */
+
+ switch (pPict->filter) {
+ case PictFilterNearest:
+ filter = ((FILTER_NEAREST<<TM0S3_MAG_FILTER_SHIFT) |
+ (FILTER_NEAREST<<TM0S3_MIN_FILTER_SHIFT));
+ break;
+ case PictFilterBilinear:
+ filter = ((FILTER_LINEAR<<TM0S3_MAG_FILTER_SHIFT) |
+ (FILTER_LINEAR<<TM0S3_MIN_FILTER_SHIFT));
+ break;
+ default:
+ filter = 0;
+ I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
+ }
+
+ {
+ if (pPix->drawable.bitsPerPixel == 8)
+ format |= MAP_SURFACE_8BIT;
+ else if (pPix->drawable.bitsPerPixel == 16)
+ format |= MAP_SURFACE_16BIT;
+ else
+ format |= MAP_SURFACE_32BIT;
+
+ BEGIN_LP_RING(6);
+ OUT_RING(_3DSTATE_MAP_INFO_CMD);
+ OUT_RING(format | TEXMAP_INDEX(unit) | MAP_FORMAT_2D);
+ OUT_RING(((pPix->drawable.height - 1) << 16) |
+ (pPix->drawable.width - 1)); /* height, width */
+ OUT_RING(offset); /* map address */
+ OUT_RING(((pitch / 4) - 1) << 2); /* map pitch */
+ OUT_RING(0);
+ ADVANCE_LP_RING();
+ }
+
+ {
+ BEGIN_LP_RING(2);
+ /* coord sets */
+ OUT_RING(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) |
+ ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL |
+ TEXCOORDTYPE_CARTESIAN | ENABLE_ADDR_V_CNTL |
+ TEXCOORD_ADDR_V_MODE(wrap_mode) |
+ ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode));
+ OUT_RING(MI_NOOP);
+
+ /* XXX: filter seems hang engine...*/
+#if 0
+ OUT_RING(I830_STATE3D_MAP_FILTER | FILTER_MAP_INDEX(unit) | ENABLE_KEYS| DISABLE_COLOR_KEY | DISABLE_CHROMA_KEY | DISABLE_KILL_PIXEL |ENABLE_MIP_MODE_FILTER | MIPFILTER_NONE | filter);
+ OUT_RING(0);
+#endif
+
+ /* max & min mip level ? or base mip level? */
+
+ ADVANCE_LP_RING();
+ }
+
+ /* XXX */
+ if (pPict->transform != 0) {
+ is_transform[unit] = TRUE;
+ transform[unit] = pPict->transform;
+ } else {
+ is_transform[unit] = FALSE;
+ }
+
+#ifdef I830DEBUG
+ ErrorF("try to sync to show any errors...");
+ I830Sync(pScrn);
+#endif
+
+ return TRUE;
+}
+
+Bool
+I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture)
+{
+ CARD32 tmp1;
+
+ /* Check for unsupported compositing operations. */
+ if (op >= sizeof(I830BlendOp) / sizeof(I830BlendOp[0]))
+ I830FALLBACK("Unsupported Composite op 0x%x\n", op);
+
+ if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
+ /* Check if it's component alpha that relies on a source alpha and on
+ * the source value. We can only get one of those into the single
+ * source value that we get to blend with.
+ */
+ if (I830BlendOp[op].src_alpha &&
+ (I830BlendOp[op].src_blend != BLENDFACTOR_ZERO))
+ I830FALLBACK("Component alpha not supported with source "
+ "alpha and source value blending.\n");
+ }
+
+ if (!I830CheckCompositeTexture(pSrcPicture, 0))
+ I830FALLBACK("Check Src picture texture\n");
+ if (pMaskPicture != NULL && !I830CheckCompositeTexture(pMaskPicture, 1))
+ I830FALLBACK("Check Mask picture texture\n");
+
+ if (!I830GetDestFormat(pDstPicture, &tmp1))
+ I830FALLBACK("Get Color buffer format\n");
+
+ return TRUE;
+}
+
+Bool
+I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+{
+/* XXX: setup texture map from pixmap, vertex format, blend cntl */
+ ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 dst_format, dst_offset, dst_pitch;
+
+ I830GetDestFormat(pDstPicture, &dst_format);
+ dst_offset = exaGetPixmapOffset(pDst);
+ dst_pitch = exaGetPixmapPitch(pDst);
+
+ if (!I830TextureSetup(pSrcPicture, pSrc, 0))
+ I830FALLBACK("fail to setup src texture\n");
+ if (pMask != NULL) {
+ if (!I830TextureSetup(pMaskPicture, pMask, 1))
+ I830FALLBACK("fail to setup mask texture\n");
+ } else {
+ is_transform[1] = FALSE;
+ scale_units[1][0] = -1;
+ scale_units[1][1] = -1;
+ }
+
+ {
+
+ CARD32 cblend, ablend, blendctl, vf2;
+
+ BEGIN_LP_RING(22+6);
+
+ /*color buffer*/
+ OUT_RING(_3DSTATE_BUF_INFO_CMD);
+ OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
+ OUT_RING(BUF_3D_ADDR(dst_offset));
+ OUT_RING(MI_NOOP);
+
+ OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
+ OUT_RING(dst_format);
+
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(MI_NOOP); /* pad to quadword */
+ /* defaults */
+ OUT_RING(_3DSTATE_DFLT_Z_CMD);
+ OUT_RING(0);
+
+ OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
+ OUT_RING(0);
+
+ OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
+ OUT_RING(0);
+
+ OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0);
+ OUT_RING((1 << S3_POINT_WIDTH_SHIFT) | (2 << S3_LINE_WIDTH_SHIFT) |
+ S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
+ OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 0);
+ if (pMask)
+ vf2 = 2 << 12; /* 2 texture coord sets */
+ else
+ vf2 = 1 << 12;
+ vf2 |= (TEXCOORDFMT_2D << 16);
+ if (pMask)
+ vf2 |= (TEXCOORDFMT_2D << 18);
+ else
+ vf2 |= (TEXCOORDFMT_1D << 18);
+
+ vf2 |= (TEXCOORDFMT_1D << 20);
+ vf2 |= (TEXCOORDFMT_1D << 22);
+ vf2 |= (TEXCOORDFMT_1D << 24);
+ vf2 |= (TEXCOORDFMT_1D << 26);
+ vf2 |= (TEXCOORDFMT_1D << 28);
+ vf2 |= (TEXCOORDFMT_1D << 30);
+ OUT_RING(vf2);
+
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(MI_NOOP); /* pad to quadword */
+ /* For (src In mask) operation */
+ /* IN operator: Multiply src by mask components or mask alpha.*/
+ /* TEXBLENDOP_MODULE: arg1*arg2 */
+ cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE |
+ TB0C_OUTPUT_WRITE_CURRENT;
+ ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE |
+ TB0A_OUTPUT_WRITE_CURRENT;
+
+ cblend |= TB0C_ARG1_SEL_TEXEL0;
+ ablend |= TB0A_ARG1_SEL_TEXEL0;
+ if (pMask) {
+ if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8)
+ cblend |= TB0C_ARG2_SEL_TEXEL1;
+ else
+ cblend |= (TB0C_ARG2_SEL_TEXEL1 | TB0C_ARG2_REPLICATE_ALPHA);
+ ablend |= TB0A_ARG2_SEL_TEXEL1;
+ } else {
+ cblend |= TB0C_ARG2_SEL_ONE;
+ ablend |= TB0A_ARG2_SEL_ONE;
+ }
+
+ OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0)|1);
+ OUT_RING(cblend);
+ OUT_RING(ablend);
+ OUT_RING(0);
+
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(MI_NOOP); /* pad to quadword */
+
+ blendctl = I830GetBlendCntl(op, pMaskPicture, pDstPicture->format);
+ OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0);
+ OUT_RING(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD |(blendctl<<4) |
+ S8_ENABLE_COLOR_BUFFER_WRITE);
+ ADVANCE_LP_RING();
+ }
+
+#ifdef I830DEBUG
+ Error("try to sync to show any errors...");
+ I830Sync(pScrn);
+#endif
+
+ return TRUE;
+}
+
diff --git a/src/i830_memory.c b/src/i830_memory.c
index f270a51e..88dc5acb 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -878,6 +878,34 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
}
return FALSE;
}
+#ifdef I830_USE_EXA
+ size = lineSize * pScrn->virtualY;
+ size = ROUND_TO_PAGE(size);
+
+ if (tileable) {
+ align = KB(512);
+ alignflags = ALIGN_BOTH_ENDS;
+ } else {
+ align = KB(64);
+ alignflags = 0;
+ }
+
+ alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen),
+ &(pI830->StolenPool), size, align,
+ flags | alignflags |
+ FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
+ if (alloced < size) {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
+ "offscreen memory. Not enough VRAM?\n");
+ }
+ return FALSE;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocate "
+ "offscreen memory at 0x%lx, size %ld KB\n",
+ pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
+ }
+#endif
} else {
long lineSize;
long extra = 0;
diff --git a/src/i830_reg.h b/src/i830_reg.h
index be12e760..f9c1df9f 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -31,6 +31,23 @@
#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
+#define CMD_3D (0x3<<29)
+
+#define PRIM3D_INLINE (CMD_3D | (0x1f<<24))
+#define PRIM3D_TRILIST (0x0<<18)
+#define PRIM3D_TRISTRIP (0x1<<18)
+#define PRIM3D_TRISTRIP_RVRSE (0x2<<18)
+#define PRIM3D_TRIFAN (0x3<<18)
+#define PRIM3D_POLY (0x4<<18)
+#define PRIM3D_LINELIST (0x5<<18)
+#define PRIM3D_LINESTRIP (0x6<<18)
+#define PRIM3D_RECTLIST (0x7<<18)
+#define PRIM3D_POINTLIST (0x8<<18)
+#define PRIM3D_DIB (0x9<<18)
+#define PRIM3D_CLEAR_RECT (0xa<<18)
+#define PRIM3D_ZONE_INIT (0xd<<18)
+#define PRIM3D_MASK (0x1f<<18)
+
#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24))
#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16)
#define AA_LINE_ECAAR_WIDTH_0_5 0
@@ -85,6 +102,8 @@
#define COLR_BUF_RGB555 (1<<8)
#define COLR_BUF_RGB565 (2<<8)
#define COLR_BUF_ARGB8888 (3<<8)
+#define COLR_BUF_ARGB4444 (8<<8)
+#define COLR_BUF_ARGB1555 (9<<8)
#define DEPTH_IS_Z 0
#define DEPTH_IS_W (1<<6)
#define DEPTH_FRMT_16_FIXED 0
@@ -202,6 +221,22 @@
#define ENABLE_DST_ABLEND_FACTOR (1<<5)
#define DST_ABLEND_FACT(x) (x)
+#define BLENDFACTOR_ZERO 0x01
+#define BLENDFACTOR_ONE 0x02
+#define BLENDFACTOR_SRC_COLR 0x03
+#define BLENDFACTOR_INV_SRC_COLR 0x04
+#define BLENDFACTOR_SRC_ALPHA 0x05
+#define BLENDFACTOR_INV_SRC_ALPHA 0x06
+#define BLENDFACTOR_DST_ALPHA 0x07
+#define BLENDFACTOR_INV_DST_ALPHA 0x08
+#define BLENDFACTOR_DST_COLR 0x09
+#define BLENDFACTOR_INV_DST_COLR 0x0a
+#define BLENDFACTOR_SRC_ALPHA_SATURATE 0x0b
+#define BLENDFACTOR_CONST_COLOR 0x0c
+#define BLENDFACTOR_INV_CONST_COLOR 0x0d
+#define BLENDFACTOR_CONST_ALPHA 0x0e
+#define BLENDFACTOR_INV_CONST_ALPHA 0x0f
+#define BLENDFACTOR_MASK 0x0f
/* _3DSTATE_MAP_BLEND_ARG, p152 */
#define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20))
@@ -301,6 +336,7 @@
/* _3DSTATE_MAP_COORD_SETS, p164 */
#define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19))
+#define TEXCOORD_SET(n) ((n)<<16)
#define ENABLE_TEXCOORD_PARAMS (1<<15)
#define TEXCOORDS_ARE_NORMAL (1<<14)
#define TEXCOORDS_ARE_IN_TEXELUNITS 0
@@ -329,6 +365,13 @@
#define CUBE_NEGZ_ENABLE (1<<1)
#define CUBE_POSZ_ENABLE (1<<0)
+#define _3DSTATE_MAP_INFO_CMD (CMD_3D|(0x1d<<24)|(0x0<<16)|3)
+#define TEXMAP_INDEX(x) ((x)<<28)
+#define MAP_SURFACE_8BIT (1<<24)
+#define MAP_SURFACE_16BIT (2<<24)
+#define MAP_SURFACE_32BIT (3<<24)
+#define MAP_FORMAT_2D (0)
+#define MAP_FORMAT_3D_CUBE (1<<11)
/* _3DSTATE_MODES_1, p190 */
#define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24))
@@ -523,14 +566,57 @@
/* Stipple command, carried over from the i810, apparently:
*/
-#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define _3DSTATE_STIPPLE (CMD_3D|(0x1d<<24)|(0x83<<16))
#define ST1_ENABLE (1<<16)
#define ST1_MASK (0xffff)
-
-
-#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16))
-#define LOAD_TEXTURE_MAP0 (1<<11)
+#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 (CMD_3D|(0x1d<<24)|(0x04<<16))
+#define I1_LOAD_S(n) (1<<((n)+4))
+#define S3_POINT_WIDTH_SHIFT 23
+#define S3_LINE_WIDTH_SHIFT 19
+#define S3_ALPHA_SHADE_MODE_SHIFT 18
+#define S3_FOG_SHADE_MODE_SHIFT 17
+#define S3_SPEC_SHADE_MODE_SHIFT 16
+#define S3_COLOR_SHADE_MODE_SHIFT 15
+#define S3_CULL_MODE_SHIFT 13
+#define S3_CULLMODE_BOTH (0)
+#define S3_CULLMODE_NONE (1<<13)
+#define S3_CULLMODE_CW (2<<13)
+#define S3_CULLMODE_CCW (3<<13)
+#define S3_POINT_WIDTH_PRESENT (1<<12)
+#define S3_SPEC_FOG_PRESENT (1<<11)
+#define S3_DIFFUSE_PRESENT (1<<10)
+#define S3_DEPTH_OFFSET_PRESENT (1<<9)
+#define S3_POSITION_SHIFT 6
+#define S3_VERTEXHAS_XYZ (1<<6)
+#define S3_VERTEXHAS_XYZW (2<<6)
+#define S3_VERTEXHAS_XY (3<<6)
+#define S3_VERTEXHAS_XYW (4<<6)
+#define S3_ENABLE_SPEC_ADD (1<<5)
+#define S3_ENABLE_FOG (1<<4)
+#define S3_ENABLE_LOCAL_DEPTH_BIAS (1<<3)
+#define S3_ENABLE_SPRITE_POINT (1<<1)
+#define S3_ENABLE_ANTIALIASING 1
+#define S8_ENABLE_ALPHA_TEST (1<<31)
+#define S8_ALPHA_TEST_FUNC_SHIFT 28
+#define S8_ALPHA_REFVALUE_SHIFT 20
+#define S8_ENABLE_DEPTH_TEST (1<<19)
+#define S8_DEPTH_TEST_FUNC_SHIFT 16
+#define S8_ENABLE_COLOR_BLEND (1<<15)
+#define S8_COLOR_BLEND_FUNC_SHIFT 12
+#define S8_BLENDFUNC_ADD (0)
+#define S8_BLENDFUNC_SUB (1<<12)
+#define S8_BLENDFUNC_RVRSE_SUB (2<<12)
+#define S8_BLENDFUNC_MIN (3<<12)
+#define S8_BLENDFUNC_MAX (4<<12)
+#define S8_SRC_BLEND_FACTOR_SHIFT 8
+#define S8_DST_BLEND_FACTOR_SHIFT 4
+#define S8_ENABLE_DEPTH_BUFFER_WRITE (1<<3)
+#define S8_ENABLE_COLOR_BUFFER_WRITE (1<<2)
+
+#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 (CMD_3D|(0x1d<<24)|(0x03<<16))
+#define LOAD_TEXTURE_MAP(x) (1<<((x)+11))
+#define LOAD_TEXTURE_BLEND_STAGE(x) (1<<((x)+7))
#define LOAD_GLOBAL_COLOR_FACTOR (1<<6)
#define TM0S0_ADDRESS_MASK 0xfffffffc
@@ -591,6 +677,8 @@
#define TM0S2_CUBE_FACE_ENA_SHIFT 15
#define TM0S2_CUBE_FACE_ENA_MASK (1<<15)
#define TM0S2_MAP_FORMAT (1<<14)
+#define TM0S2_MAP_2D (0<<14)
+#define TM0S2_MAP_3D_CUBE (1<<14)
#define TM0S2_VERTICAL_LINE_STRIDE (1<<13)
#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12)
#define TM0S2_OUTPUT_CHAN_SHIFT 10
@@ -634,4 +722,23 @@
#define FLUSH_MAP_CACHE (1<<0)
+#define _3DSTATE_MAP_FILTER_CMD (CMD_3D|(0x1c<<24)|(0x02<<19))
+#define FILTER_TEXMAP_INDEX(x) ((x) << 16)
+#define MAG_MODE_FILTER_ENABLE (1 << 5)
+#define MIN_MODE_FILTER_ENABLE (1 << 2)
+#define MAG_MAPFILTER_NEAREST (0 << 3)
+#define MAG_MAPFILTER_LINEAR (1 << 3)
+#define MAG_MAPFILTER_ANISOTROPIC (2 << 3)
+#define MIN_MAPFILTER_NEAREST (0)
+#define MIN_MAPFILTER_LINEAR (1)
+#define MIN_MAPFILTER_ANISOTROPIC (2)
+#define ENABLE_KEYS (1<<15)
+#define DISABLE_COLOR_KEY 0
+#define DISABLE_CHROMA_KEY 0
+#define DISABLE_KILL_PIXEL 0
+#define ENABLE_MIP_MODE_FILTER (1 << 9)
+#define MIPFILTER_NONE 0
+#define MIPFILTER_NEAREST 1
+#define MIPFILTER_LINEAR 3
+
#endif
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 020d7e61..76effa29 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -1016,21 +1016,26 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
}
- /* Don't allow pixmap cache or offscreen pixmaps when rotated */
- /* XAA needs some serious fixing for this to happen */
- if (pI830->rotation == RR_Rotate_0) {
- pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
- pI830->AccelInfoRec->UsingPixmapCache = TRUE;
- /* funny as it seems this will enable XAA's createpixmap */
- pI830->AccelInfoRec->maxOffPixWidth = 0;
- pI830->AccelInfoRec->maxOffPixHeight = 0;
- } else {
- pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
- pI830->AccelInfoRec->UsingPixmapCache = FALSE;
- /* funny as it seems this will disable XAA's createpixmap */
- pI830->AccelInfoRec->maxOffPixWidth = 1;
- pI830->AccelInfoRec->maxOffPixHeight = 1;
+#ifdef I830_USE_XAA
+ if (pI830->AccelInfoRec != NULL) {
+ /* Don't allow pixmap cache or offscreen pixmaps when rotated */
+ /* XAA needs some serious fixing for this to happen */
+ if (pI830->rotation == RR_Rotate_0) {
+ pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS |
+ PIXMAP_CACHE;
+ pI830->AccelInfoRec->UsingPixmapCache = TRUE;
+ /* funny as it seems this will enable XAA's createpixmap */
+ pI830->AccelInfoRec->maxOffPixWidth = 0;
+ pI830->AccelInfoRec->maxOffPixHeight = 0;
+ } else {
+ pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
+ pI830->AccelInfoRec->UsingPixmapCache = FALSE;
+ /* funny as it seems this will disable XAA's createpixmap */
+ pI830->AccelInfoRec->maxOffPixWidth = 1;
+ pI830->AccelInfoRec->maxOffPixHeight = 1;
+ }
}
+#endif
return TRUE;
diff --git a/src/i830_video.c b/src/i830_video.c
index 7f6eb80d..1c5bf4eb 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2922,8 +2922,6 @@ I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
ScreenPtr pScreen;
FBLinearPtr new_linear = NULL;
- DPRINTF(PFX, "I830AllocateMemory\n");
-
if (linear) {
if (linear->size >= size)
return linear;
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
new file mode 100644
index 00000000..6948be08
--- /dev/null
+++ b/src/i830_xaa.c
@@ -0,0 +1,712 @@
+#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 <TAB> characters expanded at 8-column intervals.
+ */
+
+/*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ *
+ */
+
+/* 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);
+
+#ifdef I830_USE_EXA
+extern const int I830PatternROP[16];
+extern const int I830CopyROP[16];
+#endif
+
+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);
+}
+
+#ifdef XF86DRI
+static unsigned int
+CheckTiling(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned int tiled = 0;
+
+ /* Check tiling */
+ if (IS_I965G(pI830)) {
+ if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR)
+ tiled = 1;
+ if (pI830->bufferOffset == pI830->RotatedMem.Start && pI830->rotated_tiled == FENCE_XMAJOR)
+ tiled = 1;
+ if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR)
+ tiled = 1;
+ /* not really supported as it's always YMajor tiled */
+ if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR)
+ tiled = 1;
+ }
+
+ return tiled;
+}
+#else
+#define CheckTiling(pScrn) 0
+#endif
+
+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);
+
+#ifdef I830_USE_EXA
+ /* This function gets used by I830DRIInitBuffers(), and we might not have
+ * XAAGetPatternROP() available. So just use the ROPs from our EXA code
+ * if available.
+ */
+ pI830->BR[13] = ((I830PatternROP[rop] << 16) |
+ (pScrn->displayWidth * pI830->cpp));
+#else
+ pI830->BR[13] = ((XAAGetPatternROP(rop) << 16) |
+ (pScrn->displayWidth * pI830->cpp));
+#endif
+
+ 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();
+ }
+
+ if (IS_I965G(pI830))
+ I830EmitFlush(pScrn);
+}
+
+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);
+#ifdef I830_USE_EXA
+ /* This function gets used by I830DRIInitBuffers(), and we might not have
+ * XAAGetCopyROP() available. So just use the ROPs from our EXA code
+ * if available.
+ */
+ pI830->BR[13] |= I830CopyROP[rop] << 16;
+#else
+ pI830->BR[13] |= XAAGetCopyROP(rop) << 16;
+#endif
+
+ 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;
+ unsigned int tiled = CheckTiling(pScrn);
+
+ 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;
+
+ if (tiled)
+ pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
+ (pI830->BR[13] & 0xFFFF0000);
+
+ {
+ 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 | tiled << 15 | tiled << 11);
+ } else {
+ OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 15 | tiled << 11);
+ }
+ 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();
+ }
+
+ if (IS_I965G(pI830))
+ I830EmitFlush(pScrn);
+}
+
+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;
+ unsigned int tiled = CheckTiling(pScrn);
+
+ x1 = x;
+ x2 = x + w;
+ y1 = y;
+ y2 = y + h;
+
+ if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
+ ErrorF("I830SubsequentMono8x8PatternFillRect\n");
+
+ if (tiled)
+ pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
+ (pI830->BR[13] & 0xFFFF0000);
+
+ {
+ 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 | tiled << 11 |
+ ((patty << 8) & XY_MONO_PAT_VERT_SEED) |
+ ((pattx << 12) & XY_MONO_PAT_HORT_SEED));
+ } else {
+ OUT_RING(XY_MONO_PAT_BLT_CMD | tiled << 11 |
+ ((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();
+ }
+
+ if (IS_I965G(pI830))
+ I830EmitFlush(pScrn);
+}
+
+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);
+ unsigned int tiled = CheckTiling(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]);
+
+ if (tiled)
+ pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
+ (pI830->BR[13] & 0xFFFF0000);
+
+ {
+ BEGIN_LP_RING(8);
+
+ if (pScrn->bitsPerPixel == 32) {
+ OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA |
+ tiled << 11 | XY_MONO_SRC_BLT_WRITE_RGB);
+ } else {
+ OUT_RING(XY_MONO_SRC_BLT_CMD | tiled << 11);
+ }
+ 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 (IS_I965G(pI830))
+ I830EmitFlush(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);
+ unsigned int tiled = CheckTiling(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 |
+ tiled << 11 | XY_SRC_COPY_BLT_WRITE_RGB);
+ } else {
+ OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 11);
+ }
+ 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
+}
+
diff --git a/src/i915_3d.c b/src/i915_3d.c
index b1f30ef2..e70bb24a 100644
--- a/src/i915_3d.c
+++ b/src/i915_3d.c
@@ -78,9 +78,7 @@ void I915EmitInvarientState( ScrnInfoPtr pScrn )
/* Need to initialize this to zero.
*/
- OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
- I1_LOAD_S(3) |
- (1));
+ OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0);
OUT_RING(0);
/* XXX: Use this */
diff --git a/src/i915_3d.h b/src/i915_3d.h
index fc4ca603..10902186 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -33,7 +33,7 @@
#define MASK_Y 0x2
#define MASK_Z 0x4
#define MASK_W 0x8
-#define MASK_XYZ (MASK_X | MASK_Y | MASK_W)
+#define MASK_XYZ (MASK_X | MASK_Y | MASK_Z)
#define MASK_XYZW (MASK_XYZ | MASK_W)
#define MASK_SATURATE 0x10
@@ -350,8 +350,16 @@ _i915_fs_arith(int cmd, int dest_reg,
return op;
}
+/** Move operand0 to dest_reg */
+#define i915_fs_mov(dest_reg, operand0) \
+do { \
+ FS_OUT(i915_fs_arith(MOV, dest_reg, operand0, \
+ i915_fs_operand_none(), \
+ i915_fs_operand_none())); \
+} while (0)
+
/**
- * Move the values in operand0 to the dest reg with the masking/saturation
+ * Move the value in operand0 to the dest reg with the masking/saturation
* specified.
*/
#define i915_fs_mov_masked(dest_reg, dest_mask, operand0) \
@@ -375,6 +383,13 @@ do { \
i915_fs_operand_none())); \
} while (0)
+/** Add operand0 and operand1 and put the result in dest_reg */
+#define i915_fs_mul(dest_reg, operand0, operand1) \
+do { \
+ FS_OUT(i915_fs_arith(MUL, dest_reg, operand0, operand1, \
+ i915_fs_operand_none())); \
+} while (0)
+
/**
* Perform a 3-component dot-product of operand0 and operand1 and put the
* resulting scalar in the channels of dest_reg specified by the dest_mask.
@@ -383,7 +398,7 @@ do { \
do { \
struct i915_fs_op op; \
\
- op = i915_fs_arith(DP3, dest_reg, operand0, i915_fs_operand_none(), \
+ op = i915_fs_arith(DP3, dest_reg, operand0, operand1, \
i915_fs_operand_none()); \
op.ui[0] &= ~A0_DEST_CHANNEL_ALL; \
op.ui[0] |= ((dest_mask) & ~MASK_SATURATE) << A0_DEST_CHANNEL_SHIFT; \
@@ -421,11 +436,13 @@ do { \
#define FS_END() \
do { \
- int _i; \
- BEGIN_LP_RING(_cur_shader_commands * 3 + 1); \
+ int _i, _pad = (_cur_shader_commands & 0x1) ? 0 : 1; \
+ BEGIN_LP_RING(_cur_shader_commands * 3 + 1 + _pad); \
OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM | \
(_cur_shader_commands * 3 - 1)); \
for (_i = 0; _i < _cur_shader_commands * 3; _i++) \
OUT_RING(_shader_buf[_i]); \
+ if (_pad != 0) \
+ OUT_RING(MI_NOOP); \
ADVANCE_LP_RING(); \
} while (0);
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
new file mode 100644
index 00000000..90240b82
--- /dev/null
+++ b/src/i915_exa_render.c
@@ -0,0 +1,501 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ * Wang Zhenyu <zhenyu.z.wang@intel.com>
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+#include "i915_reg.h"
+#include "i915_3d.h"
+
+#ifdef I830DEBUG
+#define DEBUG_I830FALLBACK 1
+#endif
+
+#ifdef DEBUG_I830FALLBACK
+#define I830FALLBACK(s, arg...) \
+do { \
+ DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); \
+ return FALSE; \
+} while(0)
+#else
+#define I830FALLBACK(s, arg...) \
+do { \
+ return FALSE; \
+} while(0)
+#endif
+
+extern float scale_units[2][2];
+extern Bool is_transform[2];
+extern PictTransform *transform[2];
+static CARD32 mapstate[6];
+static CARD32 samplerstate[6];
+
+struct formatinfo {
+ int fmt;
+ CARD32 card_fmt;
+};
+
+struct blendinfo {
+ Bool dst_alpha;
+ Bool src_alpha;
+ CARD32 src_blend;
+ CARD32 dst_blend;
+};
+
+extern Bool
+I915EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture);
+
+extern Bool
+I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
+
+static struct blendinfo I915BlendOp[] = {
+ /* Clear */
+ {0, 0, BLENDFACT_ZERO, BLENDFACT_ZERO},
+ /* Src */
+ {0, 0, BLENDFACT_ONE, BLENDFACT_ZERO},
+ /* Dst */
+ {0, 0, BLENDFACT_ZERO, BLENDFACT_ONE},
+ /* Over */
+ {0, 1, BLENDFACT_ONE, BLENDFACT_INV_SRC_ALPHA},
+ /* OverReverse */
+ {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE},
+ /* In */
+ {1, 0, BLENDFACT_DST_ALPHA, BLENDFACT_ZERO},
+ /* InReverse */
+ {0, 1, BLENDFACT_ZERO, BLENDFACT_SRC_ALPHA},
+ /* Out */
+ {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO},
+ /* OutReverse */
+ {0, 1, BLENDFACT_ZERO, BLENDFACT_INV_SRC_ALPHA},
+ /* Atop */
+ {1, 1, BLENDFACT_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
+ /* AtopReverse */
+ {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA},
+ /* Xor */
+ {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
+ /* Add */
+ {0, 0, BLENDFACT_ONE, BLENDFACT_ONE},
+};
+
+static struct formatinfo I915TexFormats[] = {
+ {PICT_a8r8g8b8, MAPSURF_32BIT | MT_32BIT_ARGB8888 },
+ {PICT_x8r8g8b8, MAPSURF_32BIT | MT_32BIT_XRGB8888 },
+ {PICT_a8b8g8r8, MAPSURF_32BIT | MT_32BIT_ABGR8888 },
+ {PICT_x8b8g8r8, MAPSURF_32BIT | MT_32BIT_XBGR8888 },
+ {PICT_r5g6b5, MAPSURF_16BIT | MT_16BIT_RGB565 },
+ {PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
+ {PICT_x1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
+ {PICT_a8, MAPSURF_8BIT | MT_8BIT_A8 },
+};
+
+static CARD32 I915GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
+{
+ CARD32 sblend, dblend;
+
+ sblend = I915BlendOp[op].src_blend;
+ dblend = I915BlendOp[op].dst_blend;
+
+ /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+ * it as always 1.
+ */
+ if (PICT_FORMAT_A(dst_format) == 0 && I915BlendOp[op].dst_alpha) {
+ if (sblend == BLENDFACT_DST_ALPHA)
+ sblend = BLENDFACT_ONE;
+ else if (sblend == BLENDFACT_INV_DST_ALPHA)
+ sblend = BLENDFACT_ZERO;
+ }
+
+ /* If the source alpha is being used, then we should only be in a case where
+ * the source blend factor is 0, and the source blend value is the mask
+ * channels multiplied by the source picture's alpha.
+ */
+ if (pMask && pMask->componentAlpha && I915BlendOp[op].src_alpha) {
+ if (dblend == BLENDFACT_SRC_ALPHA) {
+ dblend = BLENDFACT_SRC_COLR;
+ } else if (dblend == BLENDFACT_INV_SRC_ALPHA) {
+ dblend = BLENDFACT_INV_SRC_COLR;
+ }
+ }
+
+ return (sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
+ (dblend << S6_CBUF_DST_BLEND_FACT_SHIFT);
+}
+
+static Bool I915GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
+{
+ switch (pDstPicture->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ *dst_format = COLR_BUF_ARGB8888;
+ break;
+ case PICT_r5g6b5:
+ *dst_format = COLR_BUF_RGB565;
+ break;
+ case PICT_a1r5g5b5:
+ case PICT_x1r5g5b5:
+ *dst_format = COLR_BUF_ARGB1555;
+ break;
+ /* COLR_BUF_8BIT is special for YUV surfaces. While we may end up being
+ * able to use it depending on how the hardware implements it, disable it
+ * for now while we don't know what exactly it does (what channel does it
+ * read from?
+ */
+ /*
+ case PICT_a8:
+ *dst_format = COLR_BUF_8BIT;
+ break;
+ */
+ case PICT_a4r4g4b4:
+ case PICT_x4r4g4b4:
+ *dst_format = COLR_BUF_ARGB4444;
+ break;
+ default:
+ I830FALLBACK("Unsupported dest format 0x%x\n",
+ (int)pDstPicture->format);
+ }
+
+ return TRUE;
+}
+
+static Bool I915CheckCompositeTexture(PicturePtr pPict, int unit)
+{
+ int w = pPict->pDrawable->width;
+ int h = pPict->pDrawable->height;
+ int i;
+
+ if ((w > 0x7ff) || (h > 0x7ff))
+ I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
+
+ for (i = 0; i < sizeof(I915TexFormats) / sizeof(I915TexFormats[0]); i++)
+ {
+ if (I915TexFormats[i].fmt == pPict->format)
+ break;
+ }
+ if (i == sizeof(I915TexFormats) / sizeof(I915TexFormats[0]))
+ I830FALLBACK("Unsupported picture format 0x%x\n",
+ (int)pPict->format);
+
+ if (pPict->repeat && pPict->repeatType != RepeatNormal)
+ I830FALLBACK("extended repeat (%d) not supported\n",
+ pPict->repeatType);
+
+ if (pPict->filter != PictFilterNearest &&
+ pPict->filter != PictFilterBilinear)
+ I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
+
+ return TRUE;
+}
+
+Bool
+I915EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture)
+{
+ CARD32 tmp1;
+
+ /* Check for unsupported compositing operations. */
+ if (op >= sizeof(I915BlendOp) / sizeof(I915BlendOp[0]))
+ I830FALLBACK("Unsupported Composite op 0x%x\n", op);
+ if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
+ /* Check if it's component alpha that relies on a source alpha and on
+ * the source value. We can only get one of those into the single
+ * source value that we get to blend with.
+ */
+ if (I915BlendOp[op].src_alpha &&
+ (I915BlendOp[op].src_blend != BLENDFACT_ZERO))
+ I830FALLBACK("Component alpha not supported with source "
+ "alpha and source value blending.\n");
+ }
+
+ if (!I915CheckCompositeTexture(pSrcPicture, 0))
+ I830FALLBACK("Check Src picture texture\n");
+ if (pMaskPicture != NULL && !I915CheckCompositeTexture(pMaskPicture, 1))
+ I830FALLBACK("Check Mask picture texture\n");
+
+ if (!I915GetDestFormat(pDstPicture, &tmp1))
+ I830FALLBACK("Get Color buffer format\n");
+
+ return TRUE;
+}
+
+static Bool
+I915TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 format, offset, pitch, filter;
+ int w, h, i;
+ CARD32 wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
+
+ offset = exaGetPixmapOffset(pPix);
+ pitch = exaGetPixmapPitch(pPix);
+ w = pPict->pDrawable->width;
+ h = pPict->pDrawable->height;
+ scale_units[unit][0] = pPix->drawable.width;
+ scale_units[unit][1] = pPix->drawable.height;
+
+ for (i = 0; i < sizeof(I915TexFormats) / sizeof(I915TexFormats[0]); i++) {
+ if (I915TexFormats[i].fmt == pPict->format)
+ break;
+ }
+ if (i == sizeof(I915TexFormats)/ sizeof(I915TexFormats[0]))
+ I830FALLBACK("unknown texture format\n");
+ format = I915TexFormats[i].card_fmt;
+
+ if (pPict->repeat)
+ wrap_mode = TEXCOORDMODE_WRAP;
+
+ switch (pPict->filter) {
+ case PictFilterNearest:
+ filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) |
+ (FILTER_NEAREST << SS2_MIN_FILTER_SHIFT);
+ break;
+ case PictFilterBilinear:
+ filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
+ (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT);
+ break;
+ default:
+ filter = 0;
+ I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
+ }
+
+ mapstate[unit * 3 + 0] = offset;
+ mapstate[unit * 3 + 1] = format |
+ ((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
+ ((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT);
+ if (!pI830->disableTiling)
+ samplerstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS;
+ mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
+
+ samplerstate[unit * 3 + 0] = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT);
+ samplerstate[unit * 3 + 0] |= filter;
+ samplerstate[unit * 3 + 1] = SS3_NORMALIZED_COORDS;
+ samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCX_ADDR_MODE_SHIFT;
+ samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCY_ADDR_MODE_SHIFT;
+ samplerstate[unit * 3 + 1] |= unit << SS3_TEXTUREMAP_INDEX_SHIFT;
+ samplerstate[unit * 3 + 2] = 0x00000000; /* border color */
+
+ if (pPict->transform != 0) {
+ is_transform[unit] = TRUE;
+ transform[unit] = pPict->transform;
+ } else {
+ is_transform[unit] = FALSE;
+ }
+
+#ifdef I830DEBUG
+ ErrorF("try to sync to show any errors...");
+ I830Sync(pScrn);
+#endif
+
+ return TRUE;
+}
+
+Bool
+I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 dst_format, dst_offset, dst_pitch;
+ CARD32 blendctl;
+
+ ErrorF("i915 prepareComposite\n");
+
+ I915GetDestFormat(pDstPicture, &dst_format);
+ dst_offset = exaGetPixmapOffset(pDst);
+ dst_pitch = exaGetPixmapPitch(pDst);
+ scale_units[2][0] = pDst->drawable.width;
+ scale_units[2][1] = pDst->drawable.height;
+ FS_LOCALS(20);
+
+ if (!I915TextureSetup(pSrcPicture, pSrc, 0))
+ I830FALLBACK("fail to setup src texture\n");
+ if (pMask != NULL) {
+ if (!I915TextureSetup(pMaskPicture, pMask, 1))
+ I830FALLBACK("fail to setup mask texture\n");
+ } else {
+ is_transform[1] = FALSE;
+ scale_units[1][0] = -1;
+ scale_units[1][1] = -1;
+ }
+
+ if (pMask == NULL) {
+ BEGIN_LP_RING(10);
+ OUT_RING(_3DSTATE_MAP_STATE | 3);
+ OUT_RING(0x00000001); /* map 0 */
+ OUT_RING(mapstate[0]);
+ OUT_RING(mapstate[1]);
+ OUT_RING(mapstate[2]);
+
+ OUT_RING(_3DSTATE_SAMPLER_STATE | 3);
+ OUT_RING(0x00000001); /* sampler 0 */
+ OUT_RING(samplerstate[0]);
+ OUT_RING(samplerstate[1]);
+ OUT_RING(samplerstate[2]);
+ ADVANCE_LP_RING();
+ } else {
+ BEGIN_LP_RING(16);
+ OUT_RING(_3DSTATE_MAP_STATE | 6);
+ OUT_RING(0x00000003); /* map 0,1 */
+ OUT_RING(mapstate[0]);
+ OUT_RING(mapstate[1]);
+ OUT_RING(mapstate[2]);
+ OUT_RING(mapstate[3]);
+ OUT_RING(mapstate[4]);
+ OUT_RING(mapstate[5]);
+
+ OUT_RING(_3DSTATE_SAMPLER_STATE | 6);
+ OUT_RING(0x00000003); /* sampler 0,1 */
+ OUT_RING(samplerstate[0]);
+ OUT_RING(samplerstate[1]);
+ OUT_RING(samplerstate[2]);
+ OUT_RING(samplerstate[3]);
+ OUT_RING(samplerstate[4]);
+ OUT_RING(samplerstate[5]);
+ ADVANCE_LP_RING();
+ }
+ {
+ CARD32 ss2;
+
+ BEGIN_LP_RING(26);
+ /* color buffer
+ * XXX: Need to add USE_FENCE if we ever tile the X Server's pixmaps or
+ * visible screen.
+ */
+ OUT_RING(_3DSTATE_BUF_INFO_CMD);
+ OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
+ OUT_RING(BUF_3D_ADDR(dst_offset));
+ OUT_RING(MI_NOOP);
+
+ OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
+ OUT_RING(dst_format);
+
+ /* XXX: defaults */
+ OUT_RING(_3DSTATE_DFLT_Z_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
+ I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
+ ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
+ if (pMask)
+ ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
+ else
+ ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
+ ss2 |= S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT);
+ ss2 |= S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT);
+ ss2 |= S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT);
+ ss2 |= S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT);
+ ss2 |= S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT);
+ ss2 |= S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
+ OUT_RING(ss2);
+ OUT_RING(0x00000000); /* Disable texture coordinate wrap-shortest */
+ OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
+ S4_CULLMODE_NONE| S4_VFMT_XY);
+ blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
+ OUT_RING(0x00000000); /* Disable stencil buffer */
+ OUT_RING(S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
+ (BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
+
+ /* issue a flush */
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(MI_NOOP);
+
+ /* draw rect is unconditional */
+ OUT_RING(_3DSTATE_DRAW_RECT_CMD);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000); /* ymin, xmin*/
+ OUT_RING(DRAW_YMAX(pDst->drawable.height - 1) |
+ DRAW_XMAX(pDst->drawable.width - 1));
+ OUT_RING(0x00000000); /* yorig, xorig (relate to color buffer?)*/
+ OUT_RING(MI_NOOP);
+ ADVANCE_LP_RING();
+ }
+
+ FS_BEGIN();
+
+ /* Declare the registers necessary for our program. I don't think the
+ * S then T ordering is necessary.
+ */
+ i915_fs_dcl(FS_S0);
+ if (pMask)
+ i915_fs_dcl(FS_S1);
+ i915_fs_dcl(FS_T0);
+ if (pMask)
+ i915_fs_dcl(FS_T1);
+
+ /* Load the pSrcPicture texel */
+ i915_fs_texld(FS_R0, FS_S0, FS_T0);
+ /* If the texture lacks an alpha channel, force the alpha to 1. */
+ if (PICT_FORMAT_A(pSrcPicture->format) == 0)
+ i915_fs_mov_masked(FS_R0, MASK_W, i915_fs_operand_one());
+
+ if (!pMask) {
+ /* No mask, so move to output color */
+ i915_fs_mov(FS_OC, i915_fs_operand_reg(FS_R0));
+ } else {
+ /* Load the pMaskPicture texel */
+ i915_fs_texld(FS_R1, FS_S1, FS_T1);
+ /* If the texture lacks an alpha channel, force the alpha to 1. */
+ if (PICT_FORMAT_A(pMaskPicture->format) == 0)
+ i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one());
+
+ /* If component alpha is set in the mask, then we need to provide
+ * the source alpha component (channelwise multiplication) as the
+ * output color. If it isn't set, then we need to provide the
+ * source value component, which is the multipliction of the source
+ * by the mask alpha.
+ */
+ if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8) {
+ i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
+ i915_fs_operand_reg(FS_R1));
+ } else {
+ i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
+ i915_fs_operand(FS_R1, W, W, W, W));
+ }
+ }
+ FS_END();
+
+#ifdef I830DEBUG
+ ErrorF("try to sync to show any errors...");
+ I830Sync(pScrn);
+#endif
+
+ return TRUE;
+}
diff --git a/src/i915_reg.h b/src/i915_reg.h
index 6d4f8fc0..6751de60 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -161,6 +161,9 @@
#define COLR_BUF_RGB555 (1<<8)
#define COLR_BUF_RGB565 (2<<8)
#define COLR_BUF_ARGB8888 (3<<8)
+#define COLR_BUF_ARGB4444 (8<<8)
+#define COLR_BUF_ARGB1555 (9<<8)
+#define COLR_BUF_ARGB2AAA (0xa<<8)
#define DEPTH_FRMT_16_FIXED 0
#define DEPTH_FRMT_16_FLOAT (1<<2)
#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2)
@@ -685,7 +688,9 @@
-/* p207 */
+/* p207.
+ * The DWORD count is 3 times the number of bits set in MS1_MAPMASK_MASK
+ */
#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16))
#define MS1_MAPMASK_SHIFT 0
@@ -752,6 +757,7 @@
#define MS3_TILED_SURFACE (1<<1)
#define MS3_TILE_WALK (1<<0)
+/* The pitch is the pitch measured in DWORDS, minus 1 */
#define MS4_PITCH_SHIFT 21
#define MS4_CUBE_FACE_ENA_NEGX (1<<20)
#define MS4_CUBE_FACE_ENA_POSX (1<<19)
@@ -768,7 +774,9 @@
#define MS4_VOLUME_DEPTH_SHIFT 0
#define MS4_VOLUME_DEPTH_MASK (0xff<<0)
-/* p244 */
+/* p244.
+ * The DWORD count is 3 times the number of bits set in SS1_MAPMASK_MASK.
+ */
#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16))
#define SS1_MAPMASK_SHIFT 0