diff options
author | Eric Anholt <eric@anholt.net> | 2007-01-31 12:15:38 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2007-01-31 12:15:38 -0800 |
commit | e62751db8b1a631c22ba0f77c932be4ab39ba741 (patch) | |
tree | 1dc92c929dbb6afe91af1952826e6b1240b5831b | |
parent | 4cd552e8f4851e029e43bf778cd8340f6c2c4881 (diff) |
Add an accelerated path for rotation Render operations in XAA.
The now-generic (kind of) EXA code will be cleaned up and moved to generic
files in a later commit.
-rw-r--r-- | src/i830.h | 20 | ||||
-rw-r--r-- | src/i830_accel.c | 30 | ||||
-rw-r--r-- | src/i830_exa.c | 4 | ||||
-rw-r--r-- | src/i830_exa_render.c | 8 | ||||
-rw-r--r-- | src/i830_xaa.c | 168 | ||||
-rw-r--r-- | src/i915_exa_render.c | 8 | ||||
-rw-r--r-- | src/i965_exa_render.c | 12 |
7 files changed, 231 insertions, 19 deletions
@@ -365,6 +365,18 @@ typedef struct _I830Rec { Bool cursorOn; #ifdef I830_USE_XAA XAAInfoRecPtr AccelInfoRec; + + /* additional XAA accelerated Composite support */ + CompositeProcPtr saved_composite; + Bool (*xaa_check_composite)(int op, PicturePtr pSrc, PicturePtr pMask, + PicturePtr pDst); + Bool (*xaa_prepare_composite)(int op, PicturePtr pSrc, PicturePtr pMask, + PicturePtr pDst, PixmapPtr pSrcPixmap, + PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap); + void (*xaa_composite)(PixmapPtr pDst, int xSrc, int ySrc, + int xMask, int yMask, int xDst, int yDst, + int w, int h); + void (*xaa_done_composite)(PixmapPtr pDst); #endif xf86CursorInfoPtr CursorInfoRec; CloseScreenProcPtr CloseScreen; @@ -560,6 +572,8 @@ extern Bool I830DRILock(ScrnInfoPtr pScrn); extern Bool I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on); #endif +unsigned long intel_get_pixmap_offset(PixmapPtr pPix); +unsigned long intel_get_pixmap_pitch(PixmapPtr pPix); extern Bool I830AccelInit(ScreenPtr pScreen); extern void I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, @@ -634,7 +648,6 @@ DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output); /* i830_tv.c */ void i830_tv_init(ScrnInfoPtr pScrn); -#ifdef I830_USE_EXA extern Bool I830EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr); extern Bool I830EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, PixmapPtr, PixmapPtr, PixmapPtr); @@ -647,6 +660,9 @@ extern Bool I965EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, PixmapPtr, PixmapPtr, PixmapPtr); extern void I965EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height); +void IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, + int maskX, int maskY, int dstX, int dstY, int w, int h); +void IntelEXADoneComposite(PixmapPtr pDst); extern Bool I830EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, @@ -663,7 +679,7 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, extern const int I830PatternROP[16]; extern const int I830CopyROP[16]; -#endif + /* Flags for memory allocation function */ #define FROM_ANYWHERE 0x00000000 #define FROM_POOL_ONLY 0x00000001 diff --git a/src/i830_accel.c b/src/i830_accel.c index 5fdd1012..db3168a8 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -60,6 +60,36 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i810_reg.h" #include "i830_debug.h" +unsigned long +intel_get_pixmap_offset(PixmapPtr pPix) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + +#ifdef I830_USE_EXA + if (pI830->useEXA) + return exaGetPixmapOffset(pPix); +#endif + return (unsigned long)pPix->devPrivate.ptr - (unsigned long)pI830->FbBase; +} + +unsigned long +intel_get_pixmap_pitch(PixmapPtr pPix) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + +#ifdef I830_USE_EXA + if (pI830->useEXA) + return exaGetPixmapPitch(pPix); +#endif +#ifdef I830_USE_XAA + return (unsigned long)pPix->devKind; +#endif +} + int I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis) { diff --git a/src/i830_exa.c b/src/i830_exa.c index b0d886b0..02d2dcfe 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -314,7 +314,7 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, * * This function is shared between i830 and i915 generation code. */ -static void +void IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { @@ -396,7 +396,7 @@ IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, } } -static void +void IntelEXADoneComposite(PixmapPtr pDst) { #if ALWAYS_SYNC diff --git a/src/i830_exa_render.c b/src/i830_exa_render.c index 98a444f1..bf521b45 100644 --- a/src/i830_exa_render.c +++ b/src/i830_exa_render.c @@ -256,8 +256,8 @@ I830TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit) int w, h, i; CARD32 wrap_mode = TEXCOORDMODE_CLAMP; - offset = exaGetPixmapOffset(pPix); - pitch = exaGetPixmapPitch(pPix); + offset = intel_get_pixmap_offset(pPix); + pitch = intel_get_pixmap_pitch(pPix); w = pPict->pDrawable->width; h = pPict->pDrawable->height; pI830->scale_units[unit][0] = pPix->drawable.width; @@ -381,8 +381,8 @@ I830EXAPrepareComposite(int op, PicturePtr pSrcPicture, CARD32 dst_format, dst_offset, dst_pitch; I830GetDestFormat(pDstPicture, &dst_format); - dst_offset = exaGetPixmapOffset(pDst); - dst_pitch = exaGetPixmapPitch(pDst); + dst_offset = intel_get_pixmap_offset(pDst); + dst_pitch = intel_get_pixmap_pitch(pDst); pI830->last_3d = LAST_3D_RENDER; diff --git a/src/i830_xaa.c b/src/i830_xaa.c index 13ba7432..be1fb831 100644 --- a/src/i830_xaa.c +++ b/src/i830_xaa.c @@ -52,6 +52,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xaarop.h" #include "i830.h" #include "i810_reg.h" +#include "mipict.h" #ifndef DO_SCANLINE_IMAGE_WRITE #define DO_SCANLINE_IMAGE_WRITE 0 @@ -91,11 +92,26 @@ static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno); #endif static void I830RestoreAccelState(ScrnInfoPtr pScrn); +void +i830_xaa_composite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + Bool I830XAAInit(ScreenPtr pScreen) { XAAInfoRecPtr infoPtr; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); I830Ptr pI830 = I830PTR(pScrn); int i; int width = 0; @@ -220,7 +236,37 @@ I830XAAInit(ScreenPtr pScreen) I830SelectBuffer(pScrn, I830_SELECT_FRONT); - return XAAInit(pScreen, infoPtr); + if (!XAAInit(pScreen, infoPtr)) + return FALSE; + + if (ps != NULL) { + if (IS_I915G(pI830) || IS_I915GM(pI830) || + IS_I945G(pI830) || IS_I945GM(pI830)) + { + pI830->xaa_check_composite = I915EXACheckComposite; + pI830->xaa_prepare_composite = I915EXAPrepareComposite; + pI830->xaa_composite = IntelEXAComposite; + pI830->xaa_done_composite = IntelEXADoneComposite; + } else if (IS_I865G(pI830) || IS_I855(pI830) || + IS_845G(pI830) || IS_I830(pI830)) { + pI830->xaa_check_composite = I830EXACheckComposite; + pI830->xaa_prepare_composite = I830EXAPrepareComposite; + pI830->xaa_composite = IntelEXAComposite; + pI830->xaa_done_composite = IntelEXADoneComposite; + } else if (IS_I965G(pI830)) { + pI830->xaa_check_composite = I965EXACheckComposite; + pI830->xaa_prepare_composite = I965EXAPrepareComposite; + pI830->xaa_composite = I965EXAComposite; + pI830->xaa_done_composite = IntelEXADoneComposite; + } else { + return TRUE; + } + + pI830->saved_composite = ps->Composite; + ps->Composite = i830_xaa_composite; + } + + return TRUE; } #ifdef XF86DRI @@ -694,6 +740,126 @@ I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) #endif /* DO_SCANLINE_IMAGE_WRITE */ /* Support for multiscreen */ +/** + * Special case acceleration for Render acceleration of rotation operations + * by xf86Rotate.c + */ +void +i830_xaa_composite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + PictureScreenPtr ps; + PixmapPtr pSrcPixmap, pDstPixmap; + RegionRec region; + BoxPtr pbox; + int nbox; + int i; + + /* Throw out cases that aren't going to be our rotation first */ + if (pMask != NULL || op != PictOpSrc || pSrc->pDrawable == NULL) + goto fallback; + + if (pSrc->pDrawable->type != DRAWABLE_PIXMAP || + pDst->pDrawable->type != DRAWABLE_PIXMAP) + { + goto fallback; + } + pSrcPixmap = (PixmapPtr)pSrc->pDrawable; + pDstPixmap = (PixmapPtr)pDst->pDrawable; + + /* Check if the dest is one of our shadow pixmaps */ + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + if (crtc->rotatedPixmap == pDstPixmap) + break; + } + if (i == xf86_config->num_crtc) + goto fallback; + + if (pSrcPixmap != pScreen->GetScreenPixmap(pScreen)) + goto fallback; + + /* OK, so we've got a Render operation on one of our shadow pixmaps, with + * the source being the real framebuffer. We know that both of these are + * in framebuffer, with no x/y offsets, i.e. normal pixmaps like our EXA- + * based Render acceleration code expects. + */ + assert(pSrcPixmap->drawable.x == 0); + assert(pSrcPixmap->drawable.y == 0); + assert(pDstPixmap->drawable.x == 0); + assert(pDstPixmap->drawable.y == 0); + + if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst, + xSrc, ySrc, 0, 0, xDst, yDst, + width, height)) + return; + + if (!pI830->xaa_check_composite(op, pSrc, NULL, pDst)) { + REGION_UNINIT(pScreen, ®ion); + goto fallback; + } + + if (!pI830->xaa_prepare_composite(op, pSrc, NULL, pDst, + pSrcPixmap, NULL, pDstPixmap)) + { + REGION_UNINIT(pScreen, ®ion); + goto fallback; + } + + nbox = REGION_NUM_RECTS(®ion); + pbox = REGION_RECTS(®ion); + + xSrc -= xDst; + ySrc -= yDst; + + while (nbox--) + { + pI830->xaa_composite(pDstPixmap, + pbox->x1 + xSrc, + pbox->y1 + ySrc, + 0, 0, + pbox->x1, + pbox->y1, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + pbox++; + } + + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + + pI830->xaa_done_composite(pDstPixmap); + i830MarkSync(pScrn); + + return; + +fallback: + /* Fallback path: Call down to the next level (XAA) */ + ps = GetPictureScreenIfSet(pScreen); + + ps->Composite = pI830->saved_composite; + + ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height); + + pI830->saved_composite = ps->Composite; + ps->Composite = i830_xaa_composite; +} + static void I830RestoreAccelState(ScrnInfoPtr pScrn) { diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c index 8705c6de..2fb41ad1 100644 --- a/src/i915_exa_render.c +++ b/src/i915_exa_render.c @@ -248,8 +248,8 @@ I915TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit) int w, h, i; CARD32 wrap_mode = TEXCOORDMODE_CLAMP_BORDER; - offset = exaGetPixmapOffset(pPix); - pitch = exaGetPixmapPitch(pPix); + offset = intel_get_pixmap_offset(pPix); + pitch = intel_get_pixmap_pitch(pPix); w = pPict->pDrawable->width; h = pPict->pDrawable->height; pI830->scale_units[unit][0] = pPix->drawable.width; @@ -318,8 +318,8 @@ I915EXAPrepareComposite(int op, PicturePtr pSrcPicture, pI830->last_3d = LAST_3D_RENDER; I915GetDestFormat(pDstPicture, &dst_format); - dst_offset = exaGetPixmapOffset(pDst); - dst_pitch = exaGetPixmapPitch(pDst); + dst_offset = intel_get_pixmap_offset(pDst); + dst_pitch = intel_get_pixmap_pitch(pDst); FS_LOCALS(20); if (!I915TextureSetup(pSrcPicture, pSrc, 0)) diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c index 1dbccc68..99bd6284 100644 --- a/src/i965_exa_render.c +++ b/src/i965_exa_render.c @@ -379,13 +379,13 @@ I965EXAPrepareComposite(int op, PicturePtr pSrcPicture, pI830->last_3d = LAST_3D_RENDER; - src_offset = exaGetPixmapOffset(pSrc); - src_pitch = exaGetPixmapPitch(pSrc); - dst_offset = exaGetPixmapOffset(pDst); - dst_pitch = exaGetPixmapPitch(pDst); + src_offset = intel_get_pixmap_offset(pSrc); + src_pitch = intel_get_pixmap_pitch(pSrc); + dst_offset = intel_get_pixmap_offset(pDst); + dst_pitch = intel_get_pixmap_pitch(pDst); if (pMask) { - mask_offset = exaGetPixmapOffset(pMask); - mask_pitch = exaGetPixmapPitch(pMask); + mask_offset = intel_get_pixmap_offset(pMask); + mask_pitch = intel_get_pixmap_pitch(pMask); } pI830->scale_units[0][0] = pSrc->drawable.width; pI830->scale_units[0][1] = pSrc->drawable.height; |