diff options
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/i830_accel.c | 3 | ||||
-rw-r--r-- | src/i830_exa.c | 285 | ||||
-rw-r--r-- | src/i830_exa_render.c | 537 | ||||
-rw-r--r-- | src/i830_reg.h | 101 | ||||
-rw-r--r-- | src/i915_exa_render.c | 553 | ||||
-rw-r--r-- | src/i915_reg.h | 3 |
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) |