From patchwork Tue Aug 11 14:06:36 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 40672 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 n7BE72Dx022295 for ; Tue, 11 Aug 2009 14:07:02 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8E8E69EE0A; Tue, 11 Aug 2009 07:07:01 -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 BE9FB9EE05 for ; Tue, 11 Aug 2009 07:06:57 -0700 (PDT) Received: by mail.ffwll.ch (Postfix, from userid 1000) id D84CE20C223; Wed, 12 Aug 2009 00:00:25 +0200 (CEST) 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-+--signedoffby, 0.000-+--signed-off-by X-Spam-Status: No, score=-4.4 required=6.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham version=3.2.5 X-Spam-Spammy: Received: from biene (unknown [192.168.23.129]) by mail.ffwll.ch (Postfix) with ESMTP id DF54E20C225; Wed, 12 Aug 2009 00:00:07 +0200 (CEST) Received: from daniel by biene with local (Exim 4.69) (envelope-from ) id 1Mas0B-0003eP-0c; Tue, 11 Aug 2009 16:06:59 +0200 From: Daniel Vetter To: intel-gfx@lists.freedesktop.org Date: Tue, 11 Aug 2009 16:06:36 +0200 Message-Id: <2096013512e0099bfbb89439943c1b70cccabc92.1249999028.git.daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <891b387c6b31972a3e339508e57bd660b2991a17.1249999028.git.daniel.vetter@ffwll.ch> References: <0328734a90544a6cd72d9eaf64015db9d3462921.1249999028.git.daniel.vetter@ffwll.ch> <10614c7dd4ecbb1b4d3dd6a15b949cb389053f1f.1249999028.git.daniel.vetter@ffwll.ch> <891b387c6b31972a3e339508e57bd660b2991a17.1249999028.git.daniel.vetter@ffwll.ch> In-Reply-To: References: Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH 06/18] Xv: kill hw double buffering logic 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 The idea for the hw double buffering support is to program two fixed buffers and then only switch buffers in the OCMD register. But the driver as-is always programs the new buffer address (in both register sets when double buffered). Therefore we gain nothing by using this hw capability. Scrap the software support for it. When double buffered, we now allocate just a buffer of size 2*size and switch between the two parts purely in software. To make reviewing this easier, I'll shortly explain the differences of how double-buffering (i.e. tear-free video) is achieved before and after this change: - When double buffer, allocate a buffer twice the size (unchanged). - Depending upon the currently shown buffer-half, copy the new frame into the other buffer-half. In the old code this is done by using the right set of buffer offsets, either *Buf0Offset or *Buf1Offset. The new code simply programs the offset for the right buffer-half into the single set of offsets. The end-result is unchanged. Now the big difference in hw-programming: Old: Programm new buffer offset into both sets of _hw_ buffer offset registers. Depending upon the current _sw_ buffer, select the _hw_ buffer and program this into the OCMD register. This just complicates matters unnecessarly. New: Just always use the hw buffer 0. And then it's again the same story in both old and new code: - Execute an overlay flip (MI_OVERLAY_FLIP) to read in the contents of the hw registers into the shadow hw registers (which are actually being used by the overlay, not the ones we write stuff into). This is synchronized with the respective crtc vblank by the hw. Signed-off-by: Daniel Vetter --- src/i830_video.c | 125 ++++++++++++++++++------------------------------------ src/i830_video.h | 10 +--- src/i915_video.c | 16 +++--- src/i965_video.c | 12 +++--- 4 files changed, 58 insertions(+), 105 deletions(-) diff --git a/src/i830_video.c b/src/i830_video.c index 4ac6689..0b30569 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -1268,10 +1268,7 @@ I830CopyPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, dst_base = pI830->FbBase; } - if (pPriv->currentBuf == 0) - dst = dst_base + pPriv->YBuf0offset; - else - dst = dst_base + pPriv->YBuf1offset; + dst = dst_base + pPriv->YBufOffset; switch (pPriv->rotation) { case RR_Rotate_0: @@ -1430,10 +1427,7 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, dst_base = pI830->FbBase; } - if (pPriv->currentBuf == 0) - dst1 = dst_base + pPriv->YBuf0offset; - else - dst1 = dst_base + pPriv->YBuf1offset; + dst1 = dst_base + pPriv->YBufOffset; i830_memcpy_plane(dst1, src1, h, w, dstPitch2, srcPitch, pPriv->rotation); @@ -1447,17 +1441,10 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, ErrorF("src2 is %p, offset is %ld\n", src2, (unsigned long)src2 - (unsigned long)buf); #endif - if (pPriv->currentBuf == 0) { - if (id == FOURCC_I420) - dst2 = dst_base + pPriv->UBuf0offset; - else - dst2 = dst_base + pPriv->VBuf0offset; - } else { - if (id == FOURCC_I420) - dst2 = dst_base + pPriv->UBuf1offset; - else - dst2 = dst_base + pPriv->VBuf1offset; - } + if (id == FOURCC_I420) + dst2 = dst_base + pPriv->UBufOffset; + else + dst2 = dst_base + pPriv->VBufOffset; i830_memcpy_plane(dst2, src2, h/2, w/2, dstPitch, srcPitch2, pPriv->rotation); @@ -1472,17 +1459,10 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, ErrorF("src3 is %p, offset is %ld\n", src3, (unsigned long)src3 - (unsigned long)buf); #endif - if (pPriv->currentBuf == 0) { - if (id == FOURCC_I420) - dst3 = dst_base + pPriv->VBuf0offset; - else - dst3 = dst_base + pPriv->UBuf0offset; - } else { - if (id == FOURCC_I420) - dst3 = dst_base + pPriv->VBuf1offset; - else - dst3 = dst_base + pPriv->UBuf1offset; - } + if (id == FOURCC_I420) + dst3 = dst_base + pPriv->VBufOffset; + else + dst3 = dst_base + pPriv->UBufOffset; i830_memcpy_plane(dst3, src3, h/2, w/2, dstPitch, srcPitch2, pPriv->rotation); @@ -1729,13 +1709,8 @@ i830_calc_src_regs(I830Ptr pI830, int planar, short width, short height, mask = 0x1f; } - if (pPriv->currentBuf == 0) { - offsety = pPriv->YBuf0offset; - offsetu = pPriv->UBuf0offset; - } else { - offsety = pPriv->YBuf1offset; - offsetu = pPriv->UBuf1offset; - } + offsety = pPriv->YBufOffset; + offsetu = pPriv->UBufOffset; if (planar) { *swidth_out = width | ((width/2 & 0x7ff) << 16); @@ -1822,7 +1797,7 @@ i830_store_coeffs_in_overlay_regs(uint16_t *reg_coeffs, coeffPtr new_coeffs, } static uint32_t -i830_overlay_cmd(int id, int planar, unsigned char currentBuf) +i830_overlay_cmd(int id, int planar) { uint32_t OCMD = OVERLAY_ENABLE; @@ -1841,10 +1816,7 @@ i830_overlay_cmd(int id, int planar, unsigned char currentBuf) } OCMD &= ~(BUFFER_SELECT | FIELD_SELECT); - if (currentBuf == 0) - OCMD |= BUFFER0; - else - OCMD |= BUFFER1; + OCMD |= BUFFER0; OVERLAY_DEBUG("OCMD is 0x%x\n", OCMD); @@ -2077,14 +2049,9 @@ i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2); /* buffer locations */ - overlay->OBUF_0Y = pPriv->YBuf0offset; - overlay->OBUF_0U = pPriv->UBuf0offset; - overlay->OBUF_0V = pPriv->VBuf0offset; - if(pPriv->doubleBuffer) { - overlay->OBUF_1Y = pPriv->YBuf1offset; - overlay->OBUF_1U = pPriv->UBuf1offset; - overlay->OBUF_1V = pPriv->VBuf1offset; - } + overlay->OBUF_0Y = pPriv->YBufOffset; + overlay->OBUF_0U = pPriv->UBufOffset; + overlay->OBUF_0V = pPriv->VBufOffset; OVERLAY_DEBUG("pos: 0x%x, size: 0x%x\n", overlay->DWINPOS, overlay->DWINSZ); @@ -2104,7 +2071,7 @@ i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, } else overlay->OSTRIDE = dstPitch; - overlay->OCMD = i830_overlay_cmd(id, planar, pPriv->currentBuf); + overlay->OCMD = i830_overlay_cmd(id, planar); /* make sure the overlay is on */ i830_overlay_on (pScrn); @@ -2387,42 +2354,38 @@ I830PutImage(ScrnInfoPtr pScrn, /* fixup pointers */ #ifdef INTEL_XVMC if (id == FOURCC_XVMC && IS_I915(pI830)) { - pPriv->YBuf0offset = (uint32_t)((uintptr_t)buf); - pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height); - pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2); + pPriv->YBufOffset = (uint32_t)((uintptr_t)buf); + pPriv->VBufOffset = pPriv->YBufOffset + (dstPitch2 * height); + pPriv->UBufOffset = pPriv->VBufOffset + (dstPitch * height / 2); destId = FOURCC_YV12; } else { #endif if (pPriv->textured) - pPriv->YBuf0offset = 0; + pPriv->YBufOffset = 0; else - pPriv->YBuf0offset = pPriv->buf->offset; + pPriv->YBufOffset = pPriv->buf->offset; + + /* switch buffers if double buffered */ + if (!pPriv->textured && pPriv->doubleBuffer) { + if (pPriv->currentBuf == 0) + pPriv->currentBuf = 1; + else + pPriv->currentBuf = 0; + + pPriv->YBufOffset += size*pPriv->currentBuf; + } 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); - } + pPriv->UBufOffset = pPriv->YBufOffset + (dstPitch * 2 * width); + pPriv->VBufOffset = pPriv->UBufOffset + (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); - } + pPriv->UBufOffset = pPriv->YBufOffset + (dstPitch * 2 * height); + pPriv->VBufOffset = pPriv->UBufOffset + (dstPitch * height / 2); } #ifdef INTEL_XVMC } #endif - /* Pick the idle buffer */ - if (!pPriv->textured && pI830->overlayOn && pPriv->doubleBuffer) - pPriv->currentBuf = !((INREG(DOVSTA) & OC_BUF) >> 20); - /* copy data */ top = y1 >> 16; left = (x1 >> 16) & ~1; @@ -2498,9 +2461,9 @@ I830PutImage(ScrnInfoPtr pScrn, if (IS_I965G(pI830)) { #ifdef INTEL_XVMC if (id == FOURCC_XVMC && pPriv->rotation == RR_Rotate_0) { - pPriv->YBuf0offset = buf - pI830->FbBase; - pPriv->UBuf0offset = pPriv->YBuf0offset + height*width; - pPriv->VBuf0offset = pPriv->UBuf0offset + height*width/4; + pPriv->YBufOffset = buf - pI830->FbBase; + pPriv->UBufOffset = pPriv->YBufOffset + height*width; + pPriv->VBufOffset = pPriv->UBufOffset + height*width/4; } #endif I965DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height, @@ -2761,7 +2724,6 @@ I830DisplaySurface(XF86SurfacePtr surface, OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; ScrnInfoPtr pScrn = surface->pScrn; ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn); INT32 x1, y1, x2, y2; BoxRec dstBox; @@ -2785,12 +2747,7 @@ I830DisplaySurface(XF86SurfacePtr surface, return Success; /* fixup pointers */ - pI830Priv->YBuf0offset = surface->offsets[0]; - pI830Priv->YBuf1offset = pI830Priv->YBuf0offset; - - /* Pick the idle buffer */ - if (!pI830Priv->textured && pI830->overlayOn && pI830Priv->doubleBuffer) - pI830Priv->currentBuf = !((INREG(DOVSTA) & OC_BUF) >> 20); + pI830Priv->YBufOffset = surface->offsets[0]; i830_display_overlay(pScrn, crtc, surface->id, surface->width, surface->height, surface->pitches[0], x1, y1, x2, y2, &dstBox, diff --git a/src/i830_video.h b/src/i830_video.h index fb4ad29..9093d5d 100644 --- a/src/i830_video.h +++ b/src/i830_video.h @@ -28,13 +28,9 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86_OSproc.h" typedef struct { - uint32_t YBuf0offset; - uint32_t UBuf0offset; - uint32_t VBuf0offset; - - uint32_t YBuf1offset; - uint32_t UBuf1offset; - uint32_t VBuf1offset; + uint32_t YBufOffset; + uint32_t UBufOffset; + uint32_t VBufOffset; unsigned char currentBuf; diff --git a/src/i915_video.c b/src/i915_video.c index b978a43..8e8e962 100644 --- a/src/i915_video.c +++ b/src/i915_video.c @@ -158,9 +158,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, OUT_BATCH(_3DSTATE_MAP_STATE | 3); OUT_BATCH(0x00000001); /* texture map #1 */ if (pPriv->buf) - OUT_RELOC(pPriv->buf, I915_GEM_DOMAIN_SAMPLER, 0, pPriv->YBuf0offset); + OUT_RELOC(pPriv->buf, I915_GEM_DOMAIN_SAMPLER, 0, pPriv->YBufOffset); else - OUT_BATCH(pPriv->YBuf0offset); + OUT_BATCH(pPriv->YBufOffset); ms3 = MAPSURF_422 | MS3_USE_FENCE_REGS; switch (id) { @@ -270,9 +270,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, OUT_BATCH(0x00000007); if (pPriv->buf) - OUT_RELOC(pPriv->buf, I915_GEM_DOMAIN_SAMPLER, 0, pPriv->YBuf0offset); + OUT_RELOC(pPriv->buf, I915_GEM_DOMAIN_SAMPLER, 0, pPriv->YBufOffset); else - OUT_BATCH(pPriv->YBuf0offset); + OUT_BATCH(pPriv->YBufOffset); ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS; ms3 |= (height - 1) << MS3_HEIGHT_SHIFT; @@ -287,9 +287,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT); if (pPriv->buf) - OUT_RELOC(pPriv->buf, I915_GEM_DOMAIN_SAMPLER, 0, pPriv->UBuf0offset); + OUT_RELOC(pPriv->buf, I915_GEM_DOMAIN_SAMPLER, 0, pPriv->UBufOffset); else - OUT_BATCH(pPriv->UBuf0offset); + OUT_BATCH(pPriv->UBufOffset); ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS; ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT; @@ -298,9 +298,9 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); if (pPriv->buf) - OUT_RELOC(pPriv->buf, I915_GEM_DOMAIN_SAMPLER, 0, pPriv->VBuf0offset); + OUT_RELOC(pPriv->buf, I915_GEM_DOMAIN_SAMPLER, 0, pPriv->VBufOffset); else - OUT_BATCH(pPriv->VBuf0offset); + OUT_BATCH(pPriv->VBufOffset); ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS; ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT; diff --git a/src/i965_video.c b/src/i965_video.c index 810b761..423d48c 100644 --- a/src/i965_video.c +++ b/src/i965_video.c @@ -997,12 +997,12 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, ErrorF ("INST_PM 0x%08x\n", INREG(INST_PM)); #endif - src_surf_base[0] = pPriv->YBuf0offset; - src_surf_base[1] = pPriv->YBuf0offset; - src_surf_base[2] = pPriv->VBuf0offset; - src_surf_base[3] = pPriv->VBuf0offset; - src_surf_base[4] = pPriv->UBuf0offset; - src_surf_base[5] = pPriv->UBuf0offset; + src_surf_base[0] = pPriv->YBufOffset; + src_surf_base[1] = pPriv->YBufOffset; + src_surf_base[2] = pPriv->VBufOffset; + src_surf_base[3] = pPriv->VBufOffset; + src_surf_base[4] = pPriv->UBufOffset; + src_surf_base[5] = pPriv->UBufOffset; #if 0 ErrorF ("base 0 0x%x base 1 0x%x base 2 0x%x\n", src_surf_base[0], src_surf_base[1], src_surf_base[2]);