From ed051008e77536dc3ab55b1343d0248f121416c1 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 27 Jun 2008 09:39:02 +0800 Subject: xvmc: Don't copy on xvmc surface in PutImage As xvmc rendering result has already been in fb, we shouldn't do extra copy on it. Although special care is required for i915 xvmc surface pitch alignment, which must be at least 1KB aligned. So video display function should take it into acount instead of always setting Y pitch to be double of U/V pitch. (cherry picked from commit 989ec9e8a69f909cb64f17e4465982613b4b054d) --- src/common.h | 1 + src/i830.h | 1 - src/i830_hwmc.c | 2 +- src/i830_video.c | 71 +++++++++++++++++++++++++++++++++++--------------------- src/i830_video.h | 2 +- src/i915_hwmc.c | 8 ++----- src/i915_hwmc.h | 1 + src/i915_video.c | 10 ++++++-- 8 files changed, 59 insertions(+), 37 deletions(-) diff --git a/src/common.h b/src/common.h index 1765bb51..b67b20b4 100644 --- a/src/common.h +++ b/src/common.h @@ -362,6 +362,7 @@ extern int I810_DEBUG; DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q35_G ||\ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q33_G) #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810) || IS_G33CLASS(pI810)) +#define IS_I915(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_G33CLASS(pI810)) #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810)) /* mark chipsets for using gfx VM offset for overlay */ diff --git a/src/i830.h b/src/i830.h index 00a5059d..570db13e 100644 --- a/src/i830.h +++ b/src/i830.h @@ -417,7 +417,6 @@ typedef struct _I830Rec { #ifdef INTEL_XVMC /* For XvMC */ Bool XvMCEnabled; - Bool IsXvMCSurface; #endif XF86ModReqInfo shadowReq; /* to test for later libshadow */ diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c index 22fb69e3..787d93da 100644 --- a/src/i830_hwmc.c +++ b/src/i830_hwmc.c @@ -56,7 +56,7 @@ Bool intel_xvmc_probe(ScrnInfoPtr pScrn) return FALSE; if (IS_I9XX(pI830)) { - if (!IS_I965G(pI830)) + if (IS_I915(pI830)) ret = intel_xvmc_set_driver(&i915_xvmc_driver); /* else diff --git a/src/i830_video.c b/src/i830_video.c index 7b81b04d..486f6708 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2210,7 +2210,8 @@ I830PutImage(ScrnInfoPtr pScrn, I830OverlayRegPtr overlay; PixmapPtr pPixmap; INT32 x1, x2, y1, y2; - int srcPitch, srcPitch2 = 0, dstPitch, destId; + int srcPitch = 0, srcPitch2 = 0, dstPitch, destId; + int dstPitch2 = 0; int top, left, npixels, nlines, size; BoxRec dstBox; int pitchAlignMask; @@ -2285,13 +2286,11 @@ I830PutImage(ScrnInfoPtr pScrn, case FOURCC_I420: srcPitch = (width + 0x3) & ~0x3; srcPitch2 = ((width >> 1) + 0x3) & ~0x3; + break; #ifdef INTEL_XVMC - if (pI830->IsXvMCSurface) { - srcPitch = (width + 0x3ff) & ~0x3ff; - srcPitch2 = ((width >> 1) + 0x3ff) & ~0x3ff; - } -#endif + case FOURCC_XVMC: break; +#endif case FOURCC_UYVY: case FOURCC_YUY2: default: @@ -2304,6 +2303,11 @@ I830PutImage(ScrnInfoPtr pScrn, */ if (pPriv->textured) { pitchAlignMask = 3; +#ifdef INTEL_XVMC + /* for i915 xvmc, hw requires at least 1kb aligned surface */ + if ((id == FOURCC_XVMC) && IS_I915(pI830)) + pitchAlignMask = 0x3ff; +#endif } else { if (IS_I965G(pI830)) pitchAlignMask = 255; @@ -2317,9 +2321,6 @@ I830PutImage(ScrnInfoPtr pScrn, switch (destId) { case FOURCC_YV12: case FOURCC_I420: -#ifdef INTEL_XVMC - case FOURCC_XVMC: -#endif if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask; size = dstPitch * width * 3; @@ -2339,7 +2340,14 @@ I830PutImage(ScrnInfoPtr pScrn, size = dstPitch * height; } break; - default: +#ifdef INTEL_XVMC + case FOURCC_XVMC: + dstPitch = ((width / 2) + pitchAlignMask ) & ~pitchAlignMask; + dstPitch2 = (width + pitchAlignMask ) & ~pitchAlignMask; + size = 0; + break; +#endif + default: dstPitch = 0; size = 0; break; @@ -2384,24 +2392,35 @@ I830PutImage(ScrnInfoPtr pScrn, (pPriv->doubleBuffer ? size * 2 : size); /* fixup pointers */ - pPriv->YBuf0offset = pPriv->buf->offset; - if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { - pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width); - pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2); - if(pPriv->doubleBuffer) { - pPriv->YBuf1offset = pPriv->YBuf0offset + size; - pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width); - pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2); - } +#ifdef INTEL_XVMC + if (id == FOURCC_XVMC && IS_I915(pI830)) { + pPriv->YBuf0offset = (uint32_t)buf; + pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height); + pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2); + destId = FOURCC_YV12; } else { - pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); - pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2); - if(pPriv->doubleBuffer) { - pPriv->YBuf1offset = pPriv->YBuf0offset + size; - pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); - pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2); +#endif + pPriv->YBuf0offset = pPriv->buf->offset; + if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width); + pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2); + if(pPriv->doubleBuffer) { + pPriv->YBuf1offset = pPriv->YBuf0offset + size; + pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width); + pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2); + } + } else { + pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); + pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2); + if(pPriv->doubleBuffer) { + pPriv->YBuf1offset = pPriv->YBuf0offset + size; + pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); + pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2); + } } +#ifdef INTEL_XVMC } +#endif /* Pick the idle buffer */ if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer) @@ -2473,7 +2492,7 @@ I830PutImage(ScrnInfoPtr pScrn, src_w, src_h, drw_w, drw_h, pPixmap); } else { I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height, - dstPitch, x1, y1, x2, y2, + dstPitch, dstPitch2, x1, y1, x2, y2, src_w, src_h, drw_w, drw_h, pPixmap); } if (pPriv->textured) { diff --git a/src/i830_video.h b/src/i830_video.h index 52e6b4f8..91f767f9 100644 --- a/src/i830_video.h +++ b/src/i830_video.h @@ -78,7 +78,7 @@ typedef struct { void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, RegionPtr dstRegion, short width, - short height, int video_pitch, + short height, int video_pitch, int video_pitch2, int x1, int y1, int x2, int y2, short src_w, short src_h, short drw_w, short drw_h, diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c index c3451750..659638e1 100644 --- a/src/i915_hwmc.c +++ b/src/i915_hwmc.c @@ -790,7 +790,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, short height, Bool sync, RegionPtr clipBoxes, pointer data, DrawablePtr pDraw) { - I830Ptr pI830 = I830PTR(pScrn); I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf; int ret; @@ -806,10 +805,8 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, return 1; } - buf = pI830->FbBase + - pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset; - id = xvmc_cmd->real_id; - pI830->IsXvMCSurface = 1; + /* use char *buf to hold our surface offset...hacky! */ + buf = (unsigned char *)pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset; break; default: return 0; @@ -819,7 +816,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, ret = pXvMC->savePutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h, drw_w, drw_h, id, buf, width, height, sync, clipBoxes, data, pDraw); - pI830->IsXvMCSurface = 0; return ret; } diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h index 7d90afcc..8f6557da 100644 --- a/src/i915_hwmc.h +++ b/src/i915_hwmc.h @@ -29,6 +29,7 @@ #include "i830_hwmc.h" +/* i915 hw requires surface to be at least 1KB aligned */ #define STRIDE(w) (((w) + 0x3ff) & ~0x3ff) #define SIZE_Y420(w, h) (h * STRIDE(w)) #define SIZE_UV420(w, h) ((h >> 1) * STRIDE(w >> 1)) diff --git a/src/i915_video.c b/src/i915_video.c index aeb37293..d2da94bb 100644 --- a/src/i915_video.c +++ b/src/i915_video.c @@ -42,7 +42,7 @@ void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, RegionPtr dstRegion, - short width, short height, int video_pitch, + short width, short height, int video_pitch, int video_pitch2, int x1, int y1, int x2, int y2, short src_w, short src_h, short drw_w, short drw_h, PixmapPtr pPixmap) @@ -271,7 +271,13 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, ms3 |= (height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); - OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT); + /* check to see if Y has special pitch than normal double u/v pitch, + * e.g i915 XvMC hw requires at least 1K alignment, so Y pitch might + * be same as U/V's.*/ + if (video_pitch2) + OUT_BATCH(((video_pitch2 / 4) - 1) << MS4_PITCH_SHIFT); + else + OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT); OUT_BATCH(pPriv->UBuf0offset); ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS; -- cgit v1.2.3