summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2007-01-31 12:15:38 -0800
committerEric Anholt <eric@anholt.net>2007-01-31 12:15:38 -0800
commite62751db8b1a631c22ba0f77c932be4ab39ba741 (patch)
tree1dc92c929dbb6afe91af1952826e6b1240b5831b
parent4cd552e8f4851e029e43bf778cd8340f6c2c4881 (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.h20
-rw-r--r--src/i830_accel.c30
-rw-r--r--src/i830_exa.c4
-rw-r--r--src/i830_exa_render.c8
-rw-r--r--src/i830_xaa.c168
-rw-r--r--src/i915_exa_render.c8
-rw-r--r--src/i965_exa_render.c12
7 files changed, 231 insertions, 19 deletions
diff --git a/src/i830.h b/src/i830.h
index 66cfba1e..58e4ec34 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -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 (&region, pSrc, NULL, pDst,
+ xSrc, ySrc, 0, 0, xDst, yDst,
+ width, height))
+ return;
+
+ if (!pI830->xaa_check_composite(op, pSrc, NULL, pDst)) {
+ REGION_UNINIT(pScreen, &region);
+ goto fallback;
+ }
+
+ if (!pI830->xaa_prepare_composite(op, pSrc, NULL, pDst,
+ pSrcPixmap, NULL, pDstPixmap))
+ {
+ REGION_UNINIT(pScreen, &region);
+ goto fallback;
+ }
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ 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, &region);
+
+ 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;