From 486e92399f09b9d765d03184fe29a32b3bc4ecc5 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 27 Oct 2008 23:12:36 +0100 Subject: Simple EXA Composite implementation. * Implementation of the PictOpSrc render operation with a source coordinate transformation through 2D engine rotate-BITBLTs. * Fix EXA Copy and Solid in 24 bpp packed color mode. --- src/smi.h | 1 + src/smi_exa.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 172 insertions(+), 10 deletions(-) diff --git a/src/smi.h b/src/smi.h index a745f0a..042938b 100644 --- a/src/smi.h +++ b/src/smi.h @@ -187,6 +187,7 @@ typedef struct /* EXA */ ExaDriverPtr EXADriverPtr; Bool useEXA; /* enable exa acceleration */ + PictTransformPtr renderTransform; pciVideoPtr PciInfo; /* PCI info vars */ #ifndef XSERVER_LIBPCIACCESS diff --git a/src/smi_exa.c b/src/smi_exa.c index 9246298..c97f5dc 100644 --- a/src/smi_exa.c +++ b/src/smi_exa.c @@ -56,6 +56,21 @@ SMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int sr Bool SMI_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch); +static Bool +SMI_CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture); +static Bool +SMI_PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst); +static void +SMI_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height); +static void +SMI730_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height); +static void +SMI_DoneComposite(PixmapPtr pDst); + + #define PIXMAP_FORMAT(pixmap) SMI_DEDataFormat(pixmap->drawable.bitsPerPixel) Bool @@ -134,6 +149,16 @@ SMI_EXAInit(ScreenPtr pScreen) pSmi->EXADriverPtr->DownloadFromScreen = SMI_DownloadFromScreen; #endif + /* Composite */ + pSmi->EXADriverPtr->CheckComposite = SMI_CheckComposite; + pSmi->EXADriverPtr->PrepareComposite = SMI_PrepareComposite; + + if (pSmi->Chipset == SMI_COUGAR3DR) + pSmi->EXADriverPtr->Composite = SMI730_Composite; + else + pSmi->EXADriverPtr->Composite = SMI_Composite; + pSmi->EXADriverPtr->DoneComposite = SMI_DoneComposite; + if(!exaDriverInit(pScreen, pSmi->EXADriverPtr)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "exaDriverInit failed.\n"); RETURN(FALSE); @@ -149,7 +174,6 @@ static void SMI_EXASync(ScreenPtr pScreen, int marker) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SMIPtr pSmi = SMIPTR(xf86Screens[pScreen->myNum]); ENTER(); @@ -213,23 +237,23 @@ SMI_PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, } WaitQueue(); - /* Destination and Source Window Widths */ - WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (src_pitch & 0xFFFF)); if (pDstPixmap->drawable.bitsPerPixel == 24) { src_pitch *= 3; dst_pitch *= 3; } + /* Destination and Source Window Widths */ + WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (src_pitch & 0xFFFF)); + /* Destination and Source Row Pitch */ + WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (src_pitch & 0xFFFF)); + /* Bit Mask (planemask) - 16 bit only */ if (pSrcPixmap->drawable.bitsPerPixel == 16) { WRITE_DPR(pSmi, 0x28, planemask | 0xFFFF0000); } else { WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); } - - /* Destination and Source Row Pitch */ - WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (src_pitch & 0xFFFF)); /* Drawing engine data format */ WRITE_DPR(pSmi, 0x1C, PIXMAP_FORMAT(pDstPixmap)); /* Destination and Source Base Address (offset) */ @@ -343,13 +367,16 @@ SMI_PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) | SMI_QUICK_START; WaitQueue(); - /* Destination Window Width */ - WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); if (pPixmap->drawable.bitsPerPixel == 24) { dst_pitch *= 3; } + /* Destination Window Width */ + WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); + /* Destination Row Pitch */ + WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); + /* Bit Mask (planemask) - 16 bit only */ if (pPixmap->drawable.bitsPerPixel == 16) { WRITE_DPR(pSmi, 0x28, planemask | 0xFFFF0000); @@ -357,8 +384,6 @@ SMI_PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); } - /* Destination Row Pitch */ - WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); /* Drawing engine data format */ WRITE_DPR(pSmi, 0x1C, PIXMAP_FORMAT(pPixmap)); /* Source and Destination Base Address (offset) */ @@ -512,3 +537,139 @@ SMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, RETURN(TRUE); } +/* --------------------------------------- EXA Composite ---------------------------------------- */ +/* This is a very incomplete Composite implementation that only + accelerates PictOpSrc with source coordinates transformation by + using 2D Engine rotate-BITBLTs */ + +#define SMI_ISROTATION_90(t) \ + (t->matrix[0][0] == 0 && t->matrix[0][1] == xFixed1 && \ + t->matrix[1][0] == -xFixed1 && t->matrix[1][1] == 0) + +#define SMI_ISROTATION_270(t) \ + (t->matrix[0][0] == 0 && t->matrix[0][1] == -xFixed1 && \ + t->matrix[1][0] == xFixed1 && t->matrix[1][1] == 0) + +static Bool +SMI_CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture) +{ + ENTER(); + + if(op!=PictOpSrc || pMaskPicture || + pSrcPicture->repeatType || !pSrcPicture->transform) + RETURN(FALSE); + + if(!SMI_ISROTATION_90(pSrcPicture->transform) && + !SMI_ISROTATION_270(pSrcPicture->transform)) + RETURN(FALSE); + + if(PICT_FORMAT_BPP(pSrcPicture->format) == 24) + RETURN(FALSE); + + RETURN(TRUE); +} + +static Bool +SMI_PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + SMIPtr pSmi = SMIPTR(pScrn); + int src_pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel >> 3); + int dst_pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel >> 3); + + ENTER(); + + WaitQueue(); + + /* Destination and Source Window Widths */ + WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (src_pitch & 0xFFFF)); + + /* Destination and Source Row Pitch */ + WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (src_pitch & 0xFFFF)); + + /* Drawing engine data format */ + WRITE_DPR(pSmi, 0x1C, PIXMAP_FORMAT(pDst)); + + /* DE Bit Mask */ + WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); + + /* Destination and Source Base Address (offset) */ + WRITE_DPR(pSmi, 0x40, exaGetPixmapOffset(pSrc) >> 3); + WRITE_DPR(pSmi, 0x44, exaGetPixmapOffset(pDst) >> 3); + + /* DE command*/ + if(SMI_ISROTATION_90(pSrcPicture->transform)) + WRITE_DPR(pSmi, 0x0C, 0xCC /*GXCopy*/ | SMI_ROTATE_BLT | + SMI_ROTATE_CW | SMI_QUICK_START); + else + WRITE_DPR(pSmi, 0x0C, 0xCC /*GXCopy*/ | SMI_ROTATE_BLT | + SMI_ROTATE_CCW | SMI_QUICK_START); + + pSmi->renderTransform = pSrcPicture->transform; + + RETURN(TRUE); +} + +static void +SMI_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + SMIPtr pSmi = SMIPTR(pScrn); + PictTransformPtr t = pSmi->renderTransform; + PictVector v; + + ENTER(); + + if(SMI_ISROTATION_90(t)){ + srcX=srcX+width; + dstX=dstX+width-1; + }else{ + srcY=srcY+height; + dstY=dstY+height-1; + } + + v.vector[0] = IntToxFixed(srcX); + v.vector[1] = IntToxFixed(srcY); + v.vector[2] = xFixed1; + PictureTransformPoint(t, &v); + + WaitQueue(); + + WRITE_DPR(pSmi, 0x00, (xFixedToInt(v.vector[0]) << 16) + (xFixedToInt(v.vector[1]) & 0xFFFF)); + WRITE_DPR(pSmi, 0x04, (dstX << 16) + (dstY & 0xFFFF)); + WRITE_DPR(pSmi, 0x08, (height << 16) + (width & 0xFFFF)); + + LEAVE(); +} + +static void +SMI730_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + int maxPixels; + + ENTER(); + + /* SM731 cannot rotate-blt more than a certain number of pixels + (based on a calculation from the Windows driver source */ + maxPixels = 1280 / pDst->drawable.bitsPerPixel; + + while(height>0){ + SMI_Composite(pDst, srcX, srcY, maskX, maskY, dstX, dstY, width, min(height, maxPixels)); + + srcY += maxPixels; + dstY += maxPixels; + height -= maxPixels; + } + + LEAVE(); +} + +static void +SMI_DoneComposite(PixmapPtr pDst) +{ + ENTER(); + LEAVE(); +} -- cgit v1.2.3