From patchwork Mon Oct 26 13:15:26 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 55879 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n9QDFT9t010464 for ; Mon, 26 Oct 2009 13:15:29 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 50B4B9EFEC; Mon, 26 Oct 2009 06:15:29 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail.ffwll.ch (cable-static-49-187.intergga.ch [157.161.49.187]) by gabe.freedesktop.org (Postfix) with ESMTP id 22EC89EFDF for ; Mon, 26 Oct 2009 06:15:25 -0700 (PDT) Received: by mail.ffwll.ch (Postfix, from userid 1000) id D519720C221; Mon, 26 Oct 2009 14:15:24 +0100 (CET) X-Spam-ASN: X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on orange.ffwll.ch X-Spam-Level: X-Spam-Hammy: 0.000-+--struct, 0.000-+--signed-off-by, 0.000-+--signedoffby X-Spam-Status: No, score=-4.6 required=6.0 tests=ALL_TRUSTED,AWL,BAYES_00, USER_SAXASTIC autolearn=ham version=3.2.5 X-Spam-Spammy: 1.000-5--abuse, 1.000-4--Abuse, 0.998-1--Needs Received: from biene (unknown [192.168.23.129]) by mail.ffwll.ch (Postfix) with ESMTP id D4C6C20C21B; Mon, 26 Oct 2009 14:15:06 +0100 (CET) Received: from daniel by biene with local (Exim 4.69) (envelope-from ) id 1N2PQ1-00048x-Tf; Mon, 26 Oct 2009 14:15:29 +0100 From: Daniel Vetter To: intel-gfx@lists.freedesktop.org Date: Mon, 26 Oct 2009 14:15:26 +0100 Message-Id: <1516e4918929b0de22fce55fcab85092e0046760.1256562682.git.daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.6.4.3 In-Reply-To: <5114876d11f3facc1dd2eb23e88bf8a84d67b72b.1256562682.git.daniel.vetter@ffwll.ch> References: <22ebf9a09fb13aacc17f5e00dce5b681f45810c0.1256562682.git.daniel.vetter@ffwll.ch> <5114876d11f3facc1dd2eb23e88bf8a84d67b72b.1256562682.git.daniel.vetter@ffwll.ch> In-Reply-To: References: Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH 3/3] XvMC: Hack up zero-copy bo passthrough to work with kms X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c index 3471524..1d92731 100644 --- a/src/i830_hwmc.c +++ b/src/i830_hwmc.c @@ -55,7 +55,8 @@ Bool intel_xvmc_probe(ScrnInfoPtr scrn) if (!intel->XvMCEnabled) return FALSE; - /* Needs KMS support. */ + /* Needs special KMS support. Look for NEED_PHYSICAL_ADDR in + * i915_hwmc.c to see why. */ if (IS_I915G(intel) || IS_I915GM(intel)) return FALSE; diff --git a/src/i830_video.c b/src/i830_video.c index 888e566..67fe024 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -969,6 +969,11 @@ I830CopyPlanarData(intel_adaptor_private *adaptor_priv, srcPitch, srcPitch2, dstPitch, h, w, top, left); #endif + if (adaptor_priv->xvmc_passthrough_buf) { + drm_intel_bo_map(adaptor_priv->xvmc_passthrough_buf, FALSE); + buf = adaptor_priv->xvmc_passthrough_buf->virtual; + } + /* Copy Y data */ src1 = buf + (top * srcPitch) + left; #if 0 @@ -1021,6 +1026,10 @@ I830CopyPlanarData(intel_adaptor_private *adaptor_priv, dstPitch, srcPitch2, adaptor_priv->rotation); drm_intel_bo_unmap(adaptor_priv->buf); + + if (adaptor_priv->xvmc_passthrough_buf) { + drm_intel_bo_unmap(adaptor_priv->xvmc_passthrough_buf); + } } static void i830_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b) @@ -1166,10 +1175,10 @@ int is_planar_fourcc(int id) } } -static int xvmc_passthrough(int id) +static int xvmc_passthrough(int id, Rotation rotation) { #ifdef INTEL_XVMC - return id == FOURCC_XVMC; + return id == FOURCC_XVMC && rotation == RR_Rotate_0; #else return 0; #endif @@ -1332,7 +1341,7 @@ i830_wait_for_scanline(ScrnInfoPtr scrn, PixmapPtr pixmap, static Bool i830_setup_video_buffer(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, - int alloc_size, int id, unsigned char *buf) + int alloc_size, int id) { intel_screen_private *intel = intel_get_screen_private(scrn); @@ -1342,14 +1351,8 @@ i830_setup_video_buffer(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, adaptor_priv->buf = NULL; } - if (xvmc_passthrough(id)) { + if (xvmc_passthrough(id, adaptor_priv->rotation)) { i830_free_video_buffers(adaptor_priv); - if (IS_I965G(intel)) { - adaptor_priv->buf = - drm_intel_bo_gem_create_from_name(intel->bufmgr, - "xvmc surface", - (uintptr_t)buf); - } } else { if (adaptor_priv->buf == NULL) { adaptor_priv->buf = drm_intel_bo_alloc(intel->bufmgr, @@ -1441,7 +1444,6 @@ i830_copy_video_data(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, INT32 x1, INT32 y1, INT32 x2, INT32 y2, int id, unsigned char *buf) { - intel_screen_private *intel = intel_get_screen_private(scrn); int srcPitch = 0, srcPitch2 = 0; int top, left, npixels, nlines, size; @@ -1455,34 +1457,23 @@ i830_copy_video_data(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, i830_dst_pitch_and_size(scrn, adaptor_priv, width, height, dstPitch, dstPitch2, &size, id); - if (!i830_setup_video_buffer(scrn, adaptor_priv, size, id, buf)) + if (!i830_setup_video_buffer(scrn, adaptor_priv, size, id)) return FALSE; /* fixup pointers */ -#ifdef INTEL_XVMC - if (id == FOURCC_XVMC && IS_I915(intel)) { - adaptor_priv->YBufOffset = (uint32_t) ((uintptr_t) buf); - adaptor_priv->VBufOffset = adaptor_priv->YBufOffset + (*dstPitch2 * height); + adaptor_priv->YBufOffset = 0; + + if (adaptor_priv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { adaptor_priv->UBufOffset = - adaptor_priv->VBufOffset + (*dstPitch * height / 2); + adaptor_priv->YBufOffset + (*dstPitch * 2 * width); + adaptor_priv->VBufOffset = + adaptor_priv->UBufOffset + (*dstPitch * width / 2); } else { -#endif - adaptor_priv->YBufOffset = 0; - - if (adaptor_priv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { - adaptor_priv->UBufOffset = - adaptor_priv->YBufOffset + (*dstPitch * 2 * width); - adaptor_priv->VBufOffset = - adaptor_priv->UBufOffset + (*dstPitch * width / 2); - } else { - adaptor_priv->UBufOffset = - adaptor_priv->YBufOffset + (*dstPitch * 2 * height); - adaptor_priv->VBufOffset = - adaptor_priv->UBufOffset + (*dstPitch * height / 2); - } -#ifdef INTEL_XVMC + adaptor_priv->UBufOffset = + adaptor_priv->YBufOffset + (*dstPitch * 2 * height); + adaptor_priv->VBufOffset = + adaptor_priv->UBufOffset + (*dstPitch * height / 2); } -#endif /* copy data */ top = y1 >> 16; @@ -1490,12 +1481,17 @@ i830_copy_video_data(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; if (is_planar_fourcc(id)) { - if (!xvmc_passthrough(id)) { + if (!xvmc_passthrough(id, adaptor_priv->rotation)) { top &= ~1; nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; I830CopyPlanarData(adaptor_priv, buf, srcPitch, srcPitch2, *dstPitch, height, top, left, nlines, npixels, id); + } else { + /* XVMC zero-copy passthrough. No memory leak here + * because adaptor_priv->buf is freed in this case in + * i830_setup_video_buffer */ + adaptor_priv->buf = adaptor_priv->xvmc_passthrough_buf; } } else { nlines = ((y2 + 0xffff) >> 16) - top; @@ -1557,6 +1553,14 @@ I830PutImage(ScrnInfoPtr scrn, drw_h = src_h / 7; } +#ifdef INTEL_XVMC + if (id == FOURCC_XVMC) + adaptor_priv->xvmc_passthrough_buf = (drm_intel_bo *) buf; + else +#else + adaptor_priv->xvmc_passthrough_buf = NULL; +#endif + /* Clip */ x1 = src_x; x2 = src_x + src_w; diff --git a/src/i830_video.h b/src/i830_video.h index a2beae0..7e0da50 100644 --- a/src/i830_video.h +++ b/src/i830_video.h @@ -52,6 +52,7 @@ typedef struct { Time freeTime; /** YUV data buffers */ drm_intel_bo *buf; + drm_intel_bo *xvmc_passthrough_buf; Bool textured; Rotation rotation; /* should remove intel->rotation later */ diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c index 8be52f2..ed772b6 100644 --- a/src/i915_hwmc.c +++ b/src/i915_hwmc.c @@ -515,7 +515,7 @@ static int i915_xvmc_create_context(ScrnInfoPtr scrn, XvMCContextPtr pContext, contextRec->corrdata.size = ctxpriv->mcCorrdata->size; contextRec->deviceID = DEVICE_ID(intel->PciInfo); - /* XXX: KMS */ + /* XXX: KMS NEED_PHYSICAL_ADDR */ #if 0 if (IS_I915G(intel) || IS_I915GM(intel)) { contextRec->sis.bus_addr = @@ -814,10 +814,13 @@ static int i915_xvmc_put_image(ScrnInfoPtr scrn, return 1; } - /* use char *buf to hold our surface offset...hacky! */ + /* Ugly Hack (tm): Abuse buf to hold the drm_intel_bo + * pointer. As long as the minimum Xv buffer required + * is bigger than struct drm_intel_bo, this cannot be + * exploited by userspace to crash X. */ buf = (unsigned char *)pXvMC->sfprivs[xvmc_cmd->srfNo]-> - surface->offset; + surface->bo; break; default: return 0; diff --git a/src/i965_hwmc.c b/src/i965_hwmc.c index 3fe4f41..f2e6b7e 100644 --- a/src/i965_hwmc.c +++ b/src/i965_hwmc.c @@ -158,11 +158,19 @@ static int put_image(ScrnInfoPtr scrn, short height, Bool sync, RegionPtr clipBoxes, pointer data, DrawablePtr drawable) { + intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_xvmc_command *cmd = (struct intel_xvmc_command *)buf; + drm_intel_bo *bo; if (id == FOURCC_XVMC) { - /* Pass the GEM object name through the pointer arg. */ - buf = (void *)(uintptr_t)cmd->handle; + bo = intel_bo_gem_create_from_name(intel->bufmgr, "surface", + cmd->handle); + + /* Ugly Hack (tm): Abuse buf to hold the drm_intel_bo pointer. + * As long as the minimum Xv buffer required is bigger than + * struct drm_intel_bo, this cannot be exploited by userspace to + * crash X. */ + buf = (unsigned char *) bo; } savedXvPutImage(scrn, src_x, src_y, drw_x, drw_y, src_w, src_h,