summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am4
-rw-r--r--src/i830_accel.c3
-rw-r--r--src/i830_exa.c285
-rw-r--r--src/i830_exa_render.c537
-rw-r--r--src/i830_reg.h101
-rw-r--r--src/i915_exa_render.c553
-rw-r--r--src/i915_reg.h3
7 files changed, 1433 insertions, 53 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c9e8780b..9c2a5c21 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -60,7 +60,9 @@ i810_drv_la_SOURCES = \
i915_3d.c \
i915_reg.h \
i830_exa.c \
- i830_xaa.c
+ i830_xaa.c \
+ i830_exa_render.c \
+ i915_exa_render.c
if DRI
i810_drv_la_SOURCES += \
diff --git a/src/i830_accel.c b/src/i830_accel.c
index f2993985..6b338879 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -110,6 +110,9 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
#ifdef I830_USE_XAA
pI830->AccelInfoRec = NULL; /* Stops recursive behavior */
#endif
+#ifdef I830_USE_EXA
+ pI830->EXADriverPtr = NULL;
+#endif
FatalError("lockup\n");
}
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 665c4d72..83601dc3 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -36,9 +36,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xaarop.h"
#include "i830.h"
#include "i810_reg.h"
+#include "i830_reg.h"
#ifdef I830DEBUG
-#define DEBUG_I830FALLBACK 0
+#define DEBUG_I830FALLBACK 1
#endif
#ifdef DEBUG_I830FALLBACK
@@ -48,9 +49,15 @@ do { \
return FALSE; \
} while(0)
#else
-#define I830FALLBACK(s, arg...) { return FALSE; }
+#define I830FALLBACK(s, arg...) \
+do { \
+ return FALSE; \
+} while(0)
#endif
+float scale_units[2][2];
+int draw_coords[3][2];
+
const int I830CopyROP[16] =
{
ROP_0, /* GXclear */
@@ -91,12 +98,33 @@ const int I830PatternROP[16] =
ROP_1
};
-void i830ScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area);
-Bool i830UploadToScreen(PixmapPtr pDst, char *src, int src_pitch);
-Bool i830UploadToScratch(PixmapPtr pSrc, PixmapPtr pDst);
+/* 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
@@ -295,27 +323,69 @@ I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1,
static void
I830EXADoneCopy(PixmapPtr pDstPixmap)
{
- return;
+ return;
}
-#if 0 /* Not done (or even started for that matter) */
+//#define UPLOAD_USE_BLIT 1
+
static Bool
-I830EXAUploadToScreen(PixmapPtr pDst, char *src, int src_pitch)
+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);
- unsigned char *dst = pDst->devPrivate.ptr;
int dst_pitch = exaGetPixmapPitch(pDst);
- int size = src_pitch < dst_pitch ? src_pitch : dst_pitch;
- int h = pDst->drawable.height;
+ int dst_offset = exaGetPixmapOffset(pDst);
+ unsigned char *dst;
I830Sync(pScrn);
+ 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);
+#ifndef UPLOAD_USE_BLIT
+ dst = pI830->FbBase + dst_offset + y*dst_pitch +
+ x* (pDst->drawable.bitsPerPixel/8);
+ w *= pDst->drawable.bitsPerPixel/8;
while(h--) {
- i830MemCopyToVideoRam(pI830, dst, (unsigned char *)src, size);
+ memcpy(dst, src, w);
src += src_pitch;
dst += dst_pitch;
}
+#else
+ /* setup blit engine to copy one pixel data by one */
+ {
+ int x1, x2, y1, y2, i, j;
+ CARD32 d, len, *srcp;
+ x1 = x;
+ y1 = y;
+ x2 = x + w;
+ y2 = y + h;
+
+ len = (w * (pDst->drawable.bitsPerPixel/8)) >> 2;
+
+ pI830->BR[13] = (1 << 24) | (1 << 25);
+ pI830->BR[13] |= I830CopyROP[GXcopy]<<16;
+ pI830->BR[13] |= dst_pitch & 0xffff;
+ for (i = 0; i < h; i++) {
+ srcp = (CARD32*)src;
+ for ( j = len; j > 0; j--) {
+ d = *srcp;
+ BEGIN_LP_RING(6);
+ OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
+ XY_COLOR_BLT_WRITE_RGB);
+ OUT_RING(pI830->BR[13]);
+ OUT_RING((y1 << 16) | x1);
+ OUT_RING((y2 << 16) | x2);
+ OUT_RING(dst_offset);
+ OUT_RING(d);
+ ADVANCE_LP_RING();
+ srcp++;
+ }
+ src += src_pitch;
+ }
+
+ }
+#endif
return TRUE;
}
@@ -326,14 +396,18 @@ I830EXADownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
{
ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- unsigned char *src = pSrc->devPrivate.ptr;
int src_pitch = exaGetPixmapPitch(pSrc);
- int size = src_pitch < dst_pitch ? src_pitch : dst_pitch;
+ int src_offset = exaGetPixmapOffset(pSrc);
+ unsigned char *src = pI830->FbBase + src_offset + y*src_pitch +
+ x*(pSrc->drawable.bitsPerPixel/8);
I830Sync(pScrn);
+ 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);
+ w *= pSrc->drawable.bitsPerPixel/8;
while(h--) {
- i830MemCopyFromVideoRam(pI830, (unsigned char *)dst, src, size);
+ memcpy(dst, src, w);
src += src_pitch;
dst += dst_pitch;
}
@@ -341,40 +415,145 @@ I830EXADownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
return TRUE;
}
-static Bool
-I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
- PicturePtr pDstPicture)
+static void
+IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int w, int h)
{
- return FALSE; /* no Composite yet */
-}
+ /* 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;
+
+ErrorF("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""\tdx0 %d, dy0 %x, dx1 %d dy1 %x\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],
+ draw_coords[0][0], draw_coords[0][1],
+ draw_coords[1][0], draw_coords[1][1]);
+
+ if (scale_units[1][0] == -1 || scale_units[1][1] == -1) {
+ ErrorF("mask is null\n");
+ pMask = 0;
+ }
-static Bool
-I830EXAPrepareComposite(int op, PicturePtr pSrcPicture,
- PicturePtr pMaskPicture, PicturePtr pDstPicture,
- PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
-{
- return FALSE; /* no Composite yet */
-}
+ 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);
+
+ draw_coords[0][0] -= draw_coords[2][0];
+ draw_coords[0][1] -= draw_coords[2][1];
+ if (pMask) {
+ draw_coords[1][0] -= draw_coords[2][0];
+ draw_coords[1][1] -= draw_coords[2][1];
+ }
+
+ {
+ 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(dstX);
+ OUT_RING(dstY);
+ OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
+ OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
+ if (pMask) {
+ OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
+ OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
+ }
+
+ OUT_RING(dstX);
+ OUT_RING((dstY+h));
+ OUT_RING_F(((srcX - draw_coords[0][0]) / scale_units[0][0]));
+ OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
+ if (pMask) {
+ OUT_RING_F(((maskX - draw_coords[1][0]) / scale_units[1][0]));
+ OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
+ }
+
+ OUT_RING((dstX+w));
+ OUT_RING((dstY+h));
+ OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
+ OUT_RING_F(((srcYend - draw_coords[0][1]) / scale_units[0][1]));
+ if (pMask) {
+ OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
+ OUT_RING_F(((maskYend - draw_coords[1][1]) / scale_units[1][1]));
+ }
+
+ OUT_RING((dstX+w));
+ OUT_RING((dstY));
+ OUT_RING_F(((srcXend - draw_coords[0][0]) / scale_units[0][0]));
+ OUT_RING_F(((srcY - draw_coords[0][1]) / scale_units[0][1]));
+ if (pMask) {
+ OUT_RING_F(((maskXend - draw_coords[1][0]) / scale_units[1][0]));
+ OUT_RING_F(((maskY - draw_coords[1][1]) / scale_units[1][1]));
+ }
+ ADVANCE_LP_RING();
+ }
+#ifdef I830DEBUG
+ ErrorF("sync after 3dprimitive");
+ I830Sync(pScrn);
+#endif
-static void
-I830EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
- int dstX, int dstY, int width, int height)
-{
- return; /* no Composite yet */
}
static void
-I830EXADoneComposite(PixmapPtr pDst)
+IntelEXADoneComposite(PixmapPtr pDst)
{
- return; /* no Composite yet */
+ return;
}
-#endif
-
/*
* TODO:
* - Dual head?
- * - Upload/Download
- * - Composite
*/
Bool
I830EXAInit(ScreenPtr pScreen)
@@ -396,6 +575,12 @@ I830EXAInit(ScreenPtr pScreen)
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;
@@ -422,17 +607,23 @@ I830EXAInit(ScreenPtr pScreen)
pI830->EXADriverPtr->PrepareCopy = I830EXAPrepareCopy;
pI830->EXADriverPtr->Copy = I830EXACopy;
pI830->EXADriverPtr->DoneCopy = I830EXADoneCopy;
-#if 0
- /* Upload, download to/from Screen */
- pI830->EXADriverPtr->UploadToScreen = I830EXAUploadToScreen;
- pI830->EXADriverPtr->DownloadFromScreen = I830EXADownloadFromScreen;
/* Composite */
- pI830->EXADriverPtr->CheckComposite = I830EXACheckComposite;
- pI830->EXADriverPtr->PrepareComposite = I830EXAPrepareComposite;
- pI830->EXADriverPtr->Composite = I830EXAComposite;
- pI830->EXADriverPtr->DoneComposite = I830EXADoneComposite;
-#endif
+ 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);
diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c
new file mode 100644
index 00000000..9b4835bc
--- /dev/null
+++ b/src/i830_exa_render.c
@@ -0,0 +1,537 @@
+#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 int draw_coords[3][2];
+extern Bool is_transform[2];
+extern PictTransform *transform[2];
+
+struct blendinfo {
+ Bool dst_alpha;
+ Bool src_alpha;
+ CARD32 blend_cntl;
+};
+
+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);
+
+/* I830's Blend factor definition, LOAD_STATE_IMMEDIATE_1 */
+/* move to header...*/
+#define I830_SRC_BLENDFACTOR_ZERO (1 << 4)
+#define I830_SRC_BLENDFACTOR_ONE (2 << 4)
+#define I830_SRC_BLENDFACTOR_SRC_COLOR (3 << 4)
+#define I830_SRC_BLENDFACTOR_INV_SRC_COLOR (4 << 4)
+#define I830_SRC_BLENDFACTOR_SRC_ALPHA (5 << 4)
+#define I830_SRC_BLENDFACTOR_INV_SRC_ALPHA (6 << 4)
+#define I830_SRC_BLENDFACTOR_DST_ALPHA (7 << 4)
+#define I830_SRC_BLENDFACTOR_INV_DST_ALPHA (8 << 4)
+#define I830_SRC_BLENDFACTOR_DST_COLOR (9 << 4)
+#define I830_SRC_BLENDFACTOR_INV_DST_COLOR (0xa << 4)
+#define I830_SRC_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb << 4)
+#define I830_SRC_BLENDFACTOR_CONST_COLOR (0xc << 4)
+#define I830_SRC_BLENDFACTOR_INV_CONST_COLOR (0xd << 4)
+#define I830_SRC_BLENDFACTOR_CONST_ALPHA (0xe << 4)
+#define I830_SRC_BLENDFACTOR_INV_CONST_ALPHA (0xf << 4)
+#define I830_SRC_BLENDFACTOR_MASK (0xf << 4)
+
+#define I830_DST_BLENDFACTOR_ZERO (1)
+#define I830_DST_BLENDFACTOR_ONE (2)
+#define I830_DST_BLENDFACTOR_SRC_COLOR (3)
+#define I830_DST_BLENDFACTOR_INV_SRC_COLOR (4)
+#define I830_DST_BLENDFACTOR_SRC_ALPHA (5)
+#define I830_DST_BLENDFACTOR_INV_SRC_ALPHA (6)
+#define I830_DST_BLENDFACTOR_DST_ALPHA (7)
+#define I830_DST_BLENDFACTOR_INV_DST_ALPHA (8)
+#define I830_DST_BLENDFACTOR_DST_COLOR (9)
+#define I830_DST_BLENDFACTOR_INV_DST_COLOR (0xa)
+#define I830_DST_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb)
+#define I830_DST_BLENDFACTOR_CONST_COLOR (0xc)
+#define I830_DST_BLENDFACTOR_INV_CONST_COLOR (0xd)
+#define I830_DST_BLENDFACTOR_CONST_ALPHA (0xe)
+#define I830_DST_BLENDFACTOR_INV_CONST_ALPHA (0xf)
+#define I830_DST_BLENDFACTOR_MASK (0xf)
+
+#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)
+#define TB0A_ARG0_SEL_XXX
+
+/* end */
+
+
+static struct blendinfo I830BlendOp[] = {
+ /* Clear */
+ {0, 0, I830_SRC_BLENDFACTOR_ZERO | I830_DST_BLENDFACTOR_ZERO},
+ /* Src */
+ {0, 0, I830_SRC_BLENDFACTOR_ONE | I830_DST_BLENDFACTOR_ZERO},
+ /* Dst */
+ {0, 0, I830_SRC_BLENDFACTOR_ZERO | I830_DST_BLENDFACTOR_ONE},
+ /* Over */
+ {0, 1, I830_SRC_BLENDFACTOR_ONE | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+ /* OverReverse */
+ {1, 0, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_ONE},
+ /* In */
+ {1, 0, I830_SRC_BLENDFACTOR_DST_ALPHA | I830_DST_BLENDFACTOR_ZERO},
+ /* InReverse */
+ {0, 1, I830_SRC_BLENDFACTOR_ZERO | I830_DST_BLENDFACTOR_SRC_ALPHA},
+ /* Out */
+ {1, 0, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_ZERO},
+ /* OutReverse */
+ {0, 1, I830_SRC_BLENDFACTOR_ZERO | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+ /* Atop */
+ {1, 1, I830_SRC_BLENDFACTOR_DST_ALPHA | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+ /* AtopReverse */
+ {1, 1, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_SRC_ALPHA},
+ /* Xor */
+ {1, 1, I830_SRC_BLENDFACTOR_INV_DST_ALPHA | I830_DST_BLENDFACTOR_INV_SRC_ALPHA},
+ /* Add */
+ {0, 0, I830_SRC_BLENDFACTOR_ONE | I830_DST_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].blend_cntl & I830_SRC_BLENDFACTOR_MASK;
+ dblend = I830BlendOp[op].blend_cntl & I830_DST_BLENDFACTOR_MASK;
+
+ /* 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 == I830_SRC_BLENDFACTOR_DST_ALPHA)
+ sblend = I830_SRC_BLENDFACTOR_ONE;
+ else if (sblend == I830_SRC_BLENDFACTOR_INV_DST_ALPHA)
+ sblend = I830_SRC_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 == I830_DST_BLENDFACTOR_SRC_ALPHA) {
+ dblend = I830_DST_BLENDFACTOR_SRC_COLOR;
+ } else if (dblend == I830_DST_BLENDFACTOR_INV_SRC_ALPHA) {
+ dblend = I830_DST_BLENDFACTOR_INV_SRC_COLOR;
+ }
+ }
+
+ return sblend | dblend;
+}
+
+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;
+ draw_coords[unit][0] = pPix->drawable.x;
+ draw_coords[unit][1] = pPix->drawable.y;
+
+ 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 (pI830->cpp == 1)
+ format |= MAP_SURFACE_8BIT;
+ else if (pI830->cpp == 2)
+ 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<<16)|pPix->drawable.width); /* height, width */
+ OUT_RING(offset<<2); /* map address */
+ OUT_RING(pitch<<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 | /*XXX, check this, and fix vertex tex coord*/
+ 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].blend_cntl & I830_SRC_BLENDFACTOR_MASK) !=
+ I830_SRC_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;
+}
+
+
+static void
+I830DefCtxSetup(ScrnInfoPtr pScrn)
+{
+ /* coord binding */
+ CARD32 mcb;
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ BEGIN_LP_RING(2);
+ OUT_RING(_3DSTATE_MAP_COORD_SETBIND_CMD);
+ mcb = TEXBIND_SET3(TEXCOORDSRC_VTXSET_3);
+ mcb |= TEXBIND_SET2(TEXCOORDSRC_VTXSET_2);
+ mcb |= TEXBIND_SET1(TEXCOORDSRC_VTXSET_1);
+ mcb |= TEXBIND_SET0(TEXCOORDSRC_VTXSET_0);
+ OUT_RING(mcb);
+ ADVANCE_LP_RING();
+}
+
+
+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);
+ draw_coords[2][0] = pDst->drawable.x;
+ draw_coords[2][1] = pDst->drawable.y;
+
+ I830DefCtxSetup(pScrn);
+
+ 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);
+
+ /*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);
+
+ /* 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);
+
+ /* 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);
+
+ 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_reg.h b/src/i830_reg.h
index be12e760..ae68a2e9 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
@@ -301,6 +320,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 +349,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 +550,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 +661,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 +706,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/i915_exa_render.c b/src/i915_exa_render.c
new file mode 100644
index 00000000..68c929ea
--- /dev/null
+++ b/src/i915_exa_render.c
@@ -0,0 +1,553 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+#include "i915_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 int draw_coords[3][2];
+extern Bool is_transform[2];
+extern PictTransform *transform[2];
+
+struct formatinfo {
+ int fmt;
+ CARD32 card_fmt;
+};
+
+struct blendinfo {
+ Bool dst_alpha;
+ Bool src_alpha;
+ CARD32 blend_cntl;
+};
+
+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);
+
+/* copy from Eric's texture-video branch, move to header.. */
+#define OUT_DCL(type, nr) do { \
+ CARD32 chans = 0; \
+ if (REG_TYPE_##type == REG_TYPE_T) \
+ chans = D0_CHANNEL_ALL; \
+ else if (REG_TYPE_##type != REG_TYPE_S) \
+ FatalError("wrong reg type %d to declare\n", REG_TYPE_##type); \
+ OUT_RING(D0_DCL | \
+ (REG_TYPE_##type << D0_TYPE_SHIFT) | (nr << D0_NR_SHIFT) | \
+ chans); \
+ OUT_RING(0x00000000); \
+ OUT_RING(0x00000000); \
+} while (0)
+
+#define OUT_TEXLD(dest_type, dest_nr, sampler_nr, addr_type, addr_nr) \
+do { \
+ OUT_RING(T0_TEXLD | \
+ (REG_TYPE_##dest_type << T0_DEST_TYPE_SHIFT) | \
+ (dest_nr << T0_DEST_NR_SHIFT) | \
+ (sampler_nr << T0_SAMPLER_NR_SHIFT)); \
+ OUT_RING((REG_TYPE_##addr_type << T1_ADDRESS_REG_TYPE_SHIFT) | \
+ (addr_nr << T1_ADDRESS_REG_NR_SHIFT)); \
+ OUT_RING(0x00000000); \
+} while (0)
+
+/* XXX: It seems that offset of 915's blendfactor in Load_immediate_1
+ is _different_ with i830, so I should just define plain value
+ and use it with shift bits*/
+
+#define I915_SRC_BLENDFACTOR_ZERO (1 << 8)
+#define I915_SRC_BLENDFACTOR_ONE (2 << 8)
+#define I915_SRC_BLENDFACTOR_SRC_COLOR (3 << 8)
+#define I915_SRC_BLENDFACTOR_INV_SRC_COLOR (4 << 8)
+#define I915_SRC_BLENDFACTOR_SRC_ALPHA (5 << 8)
+#define I915_SRC_BLENDFACTOR_INV_SRC_ALPHA (6 << 8)
+#define I915_SRC_BLENDFACTOR_DST_ALPHA (7 << 8)
+#define I915_SRC_BLENDFACTOR_INV_DST_ALPHA (8 << 8)
+#define I915_SRC_BLENDFACTOR_DST_COLOR (9 << 8)
+#define I915_SRC_BLENDFACTOR_INV_DST_COLOR (0xa << 8)
+#define I915_SRC_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb << 8)
+#define I915_SRC_BLENDFACTOR_CONST_COLOR (0xc << 8)
+#define I915_SRC_BLENDFACTOR_INV_CONST_COLOR (0xd << 8)
+#define I915_SRC_BLENDFACTOR_CONST_ALPHA (0xe << 8)
+#define I915_SRC_BLENDFACTOR_INV_CONST_ALPHA (0xf << 8)
+#define I915_SRC_BLENDFACTOR_MASK (0xf << 8)
+
+#define I915_DST_BLENDFACTOR_ZERO (1 << 4)
+#define I915_DST_BLENDFACTOR_ONE (2 << 4)
+#define I915_DST_BLENDFACTOR_SRC_COLOR (3 << 4)
+#define I915_DST_BLENDFACTOR_INV_SRC_COLOR (4 << 4)
+#define I915_DST_BLENDFACTOR_SRC_ALPHA (5 << 4)
+#define I915_DST_BLENDFACTOR_INV_SRC_ALPHA (6 << 4)
+#define I915_DST_BLENDFACTOR_DST_ALPHA (7 << 4)
+#define I915_DST_BLENDFACTOR_INV_DST_ALPHA (8 << 4)
+#define I915_DST_BLENDFACTOR_DST_COLOR (9 << 4)
+#define I915_DST_BLENDFACTOR_INV_DST_COLOR (0xa << 4)
+#define I915_DST_BLENDFACTOR_SRC_ALPHA_SATURATE (0xb << 4)
+#define I915_DST_BLENDFACTOR_CONST_COLOR (0xc << 4)
+#define I915_DST_BLENDFACTOR_INV_CONST_COLOR (0xd << 4)
+#define I915_DST_BLENDFACTOR_CONST_ALPHA (0xe << 4)
+#define I915_DST_BLENDFACTOR_INV_CONST_ALPHA (0xf << 4)
+#define I915_DST_BLENDFACTOR_MASK (0xf << 4)
+
+static struct blendinfo I915BlendOp[] = {
+ /* Clear */
+ {0, 0, I915_SRC_BLENDFACTOR_ZERO | I915_DST_BLENDFACTOR_ZERO},
+ /* Src */
+ {0, 0, I915_SRC_BLENDFACTOR_ONE | I915_DST_BLENDFACTOR_ZERO},
+ /* Dst */
+ {0, 0, I915_SRC_BLENDFACTOR_ZERO | I915_DST_BLENDFACTOR_ONE},
+ /* Over */
+ {0, 1, I915_SRC_BLENDFACTOR_ONE | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+ /* OverReverse */
+ {1, 0, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_ONE},
+ /* In */
+ {1, 0, I915_SRC_BLENDFACTOR_DST_ALPHA | I915_DST_BLENDFACTOR_ZERO},
+ /* InReverse */
+ {0, 1, I915_SRC_BLENDFACTOR_ZERO | I915_DST_BLENDFACTOR_SRC_ALPHA},
+ /* Out */
+ {1, 0, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_ZERO},
+ /* OutReverse */
+ {0, 1, I915_SRC_BLENDFACTOR_ZERO | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+ /* Atop */
+ {1, 1, I915_SRC_BLENDFACTOR_DST_ALPHA | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+ /* AtopReverse */
+ {1, 1, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_SRC_ALPHA},
+ /* Xor */
+ {1, 1, I915_SRC_BLENDFACTOR_INV_DST_ALPHA | I915_DST_BLENDFACTOR_INV_SRC_ALPHA},
+ /* Add */
+ {0, 0, I915_SRC_BLENDFACTOR_ONE | I915_DST_BLENDFACTOR_ONE},
+};
+
+static struct formatinfo I915TexFormats[] = {
+ {PICT_a8r8g8b8, MT_32BIT_ARGB8888 },
+ {PICT_x8r8g8b8, MT_32BIT_XRGB8888 },
+ {PICT_a8b8g8r8, MT_32BIT_ABGR8888 },
+ {PICT_x8b8g8r8, MT_32BIT_XBGR8888 },
+ {PICT_r5g6b5, MT_16BIT_RGB565 },
+ {PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
+ {PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
+ {PICT_a8, MT_8BIT_I8 },
+};
+
+static CARD32 I915GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
+{
+ CARD32 sblend, dblend;
+
+ sblend = I915BlendOp[op].blend_cntl & I915_SRC_BLENDFACTOR_MASK;
+ dblend = I915BlendOp[op].blend_cntl & I915_DST_BLENDFACTOR_MASK;
+
+ /* 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 == I915_SRC_BLENDFACTOR_DST_ALPHA)
+ sblend = I915_SRC_BLENDFACTOR_ONE;
+ else if (sblend == I915_SRC_BLENDFACTOR_INV_DST_ALPHA)
+ sblend = I915_SRC_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 && I915BlendOp[op].src_alpha) {
+ if (dblend == I915_DST_BLENDFACTOR_SRC_ALPHA) {
+ dblend = I915_DST_BLENDFACTOR_SRC_COLOR;
+ } else if (dblend == I915_DST_BLENDFACTOR_INV_SRC_ALPHA) {
+ dblend = I915_DST_BLENDFACTOR_INV_SRC_COLOR;
+ }
+ }
+
+ return sblend | dblend;
+}
+
+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;
+ 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);
+
+ /* FIXME: fix repeat support */
+ if (pPict->repeat && ((w&(w-1)) != 0) && ((h&(h-1)) != 0))
+ I830FALLBACK("repeat non log2 aligned!\n");
+
+ 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].blend_cntl & I915_SRC_BLENDFACTOR_MASK) !=
+ I915_SRC_BLENDFACTOR_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_EDGE;
+
+ 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;
+ draw_coords[unit][0] = pPix->drawable.x;
+ draw_coords[unit][1] = pPix->drawable.y;
+
+ 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; /* XXX:correct ? */
+
+ 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);
+ }
+
+ {
+ CARD32 ms3;
+ if (pI830->cpp == 1)
+ format |= MAPSURF_8BIT;
+ else if (pI830->cpp == 2)
+ format |= MAPSURF_16BIT;
+ else
+ format |= MAPSURF_32BIT;
+
+ BEGIN_LP_RING(6);
+ OUT_RING(_3DSTATE_MAP_STATE | (3 * (1 << unit)));
+ OUT_RING(1<<unit);
+ OUT_RING(offset&MS2_ADDRESS_MASK);
+ ms3 = (pPix->drawable.height << MS3_HEIGHT_SHIFT) |
+ (pPix->drawable.width << MS3_WIDTH_SHIFT) | format;
+ if (!pI830->disableTiling)
+ ms3 |= MS3_USE_FENCE_REGS;
+ OUT_RING(ms3);
+ OUT_RING(pitch<<MS4_PITCH_SHIFT);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
+ }
+
+ {
+ CARD32 ss2, ss3;
+ BEGIN_LP_RING(6);
+ /* max & min mip level ? or base mip level? */
+
+ OUT_RING(_3DSTATE_SAMPLER_STATE | (3*(1<<unit)));
+ OUT_RING(1<<unit);
+ ss2 = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT);
+ ss2 |= filter;
+ OUT_RING(ss2);
+ /* repeat? */
+ ss3 = TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT;
+ ss3 |= (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT);
+ ss3 |= SS3_NORMALIZED_COORDS;
+ ss3 |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
+ OUT_RING(ss3);
+ OUT_RING(0x00000000); /* default color */
+ OUT_RING(0);
+
+ ADVANCE_LP_RING();
+ }
+
+ 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;
+}
+
+static void
+I915DefCtxSetup(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ BEGIN_LP_RING(2);
+ /* set default texture binding, may be in prepare better */
+ OUT_RING(_3DSTATE_COORD_SET_BINDINGS | CSB_TCB(0,0) | CSB_TCB(1,1) |
+ CSB_TCB(2,2) | CSB_TCB(3,3) | CSB_TCB(4,4) | CSB_TCB(5,5) |
+ CSB_TCB(6,6) | CSB_TCB(7,7));
+ OUT_RING(0);
+ ADVANCE_LP_RING();
+}
+
+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);
+ draw_coords[2][0] = pDst->drawable.x;
+ draw_coords[2][1] = pDst->drawable.y;
+
+ I915DefCtxSetup(pScrn);
+
+ 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;
+ }
+
+ {
+ CARD32 ss2;
+ BEGIN_LP_RING(24);
+ /*color buffer*/
+ OUT_RING(_3DSTATE_BUF_INFO_CMD);
+ OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch)); /* fence, tile? */
+ 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(0);
+
+ OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
+ OUT_RING(0);
+
+ OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
+ OUT_RING(0);
+
+ /* XXX:S3? define vertex format with tex coord sets number*/
+ OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1|I1_LOAD_S(2)|I1_LOAD_S(3)|
+ I1_LOAD_S(4)|1);
+ 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); /*XXX: does ss3 needed? */
+ OUT_RING((1<<S4_POINT_WIDTH_SHIFT)|S4_LINE_WIDTH_ONE|
+ S4_CULLMODE_NONE| S4_VFMT_XY);
+
+ /* issue a flush */
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(0);
+
+ /* draw rect is unconditional */
+ OUT_RING(_3DSTATE_DRAW_RECT_CMD);
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000); /* ymin, xmin*/
+ OUT_RING(DRAW_YMAX(pScrn->virtualY-1) | DRAW_XMAX(pScrn->virtualX-1));
+ OUT_RING(0x00000000); /* yorig, xorig (relate to color buffer?)*/
+ OUT_RING(0);
+ ADVANCE_LP_RING();
+ }
+
+ /* For (src In mask) operation */
+ /* IN operator: Multiply src by mask components or mask alpha.*/
+ /* TEXBLENDOP_MODULE: arg1*arg2 */
+
+ /* LOAD_IMMEDIATE_1 ss6 ??*/
+
+ /****
+ shader program prototype:
+ dcl t0.xy
+ dcl t1.xy
+ dcl_2d s0
+ dcl_2d s1
+ texld t0, s0
+ texld t1, s1
+ mul oC, t0, t1 ()
+ ***/
+ if (!pMask) {
+ BEGIN_LP_RING(1+3+3+3);
+ OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM |(3*3-1));
+ OUT_DCL(S, 0);
+ OUT_DCL(T, 0);
+ OUT_TEXLD(OC, 0, 0, T, 0);
+ ADVANCE_LP_RING();
+ } else {
+ BEGIN_LP_RING(1+3*6+3);
+ OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM |(3*7-1));
+ OUT_DCL(S, 0);
+ OUT_DCL(S, 1);
+ OUT_DCL(T, 0);
+ OUT_DCL(T, 1);
+ OUT_TEXLD(R, 0, 0, T, 0);
+ OUT_TEXLD(R, 1, 1, T, 1);
+ if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8) {
+ /* then just mul */
+ OUT_RING(A0_MUL | (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) |
+ (0 << A0_DEST_NR_SHIFT) | A0_DEST_CHANNEL_ALL |
+ (REG_TYPE_R << A0_SRC0_TYPE_SHIFT) | (0 << A0_SRC0_NR_SHIFT));
+ OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT)|(SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT)|
+ (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT)|(SRC_W << A1_SRC0_CHANNEL_W_SHIFT)|
+ (REG_TYPE_R << A1_SRC1_TYPE_SHIFT) | (1 << A1_SRC1_NR_SHIFT) |
+ (SRC_X << A1_SRC1_CHANNEL_X_SHIFT) | (SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT));
+ OUT_RING((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) | (SRC_W << A2_SRC1_CHANNEL_W_SHIFT));
+ } else {
+ /* we should duplicate R1's w for all channel, Arithemic can choose channel to use! */
+ OUT_RING(A0_MUL | (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) |
+ (0 << A0_DEST_NR_SHIFT) | A0_DEST_CHANNEL_ALL |
+ (REG_TYPE_R << A0_SRC0_TYPE_SHIFT) | (0 << A0_SRC0_NR_SHIFT));
+ OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) |
+ (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | (SRC_W << A1_SRC0_CHANNEL_W_SHIFT) |
+ (REG_TYPE_R << A1_SRC1_TYPE_SHIFT) | (1 << A1_SRC1_NR_SHIFT) |
+ (SRC_W << A1_SRC1_CHANNEL_X_SHIFT) | (SRC_W << A1_SRC1_CHANNEL_Y_SHIFT));
+ OUT_RING((SRC_W << A2_SRC1_CHANNEL_Z_SHIFT) | (SRC_W << A2_SRC1_CHANNEL_W_SHIFT));
+ }
+ ADVANCE_LP_RING();
+ }
+
+ {
+ CARD32 ss6;
+ blendctl = I915GetBlendCntl(op, pMaskPicture, pDstPicture->format);
+
+ BEGIN_LP_RING(2);
+ OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
+ ss6 = S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE;
+ OUT_RING(ss6 | (0 << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
+ ADVANCE_LP_RING();
+ }
+
+#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 886ae815..e2d7b9d9 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)