summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyu.z.wang@intel.com>2008-06-27 09:39:02 +0800
committerZhenyu Wang <zhenyu.z.wang@intel.com>2008-06-28 19:15:57 +0800
commit989ec9e8a69f909cb64f17e4465982613b4b054d (patch)
treee788ad721cfe1020e581654aec98153bb393ba04
parent550082070a3fdb951e3cf08974dc56276c0a739c (diff)
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.
-rw-r--r--src/common.h1
-rw-r--r--src/i830.h1
-rw-r--r--src/i830_hwmc.c2
-rw-r--r--src/i830_video.c71
-rw-r--r--src/i830_video.h2
-rw-r--r--src/i915_hwmc.c8
-rw-r--r--src/i915_hwmc.h1
-rw-r--r--src/i915_video.c10
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;