[01/18] Xv i830_display_video splitup: extract i830_calc_src_regs
diff mbox

Message ID 0328734a90544a6cd72d9eaf64015db9d3462921.1249999028.git.daniel.vetter@ffwll.ch
State Not Applicable
Headers show

Commit Message

Daniel Vetter Aug. 11, 2009, 2:06 p.m. UTC
Also introduce an is_planar_fourcc helper. I'll use that one later.

In i830_display_video this changeset moves the XVMC case (previously
obscured as the default case) around. I've figured this default case
does not make sense, here's why:

XvMC is everywhere else handled as a planar format (e.g. in the register
programming a few lines down). Furthermore the id variable gets mapped
to FOURCC_YV12 if IS_I915(pI830) is true in I830PutImage. There's a
second caller in the offscreen overlay support code.  But I think that
code is bitrotten and not reliable as an information source.

So we have a different behaviour only for id=FOURCC_XVMC and i965 class
hw (i830 class doesn't have xvmc). I've crawled through various
sources/intel documentations. Finally in the textured video implemention
for i965 class hw (src/i965_video.c) I've found a switch statement that
puts XVMC into the same case as I420 and YV12. So also in i965 class hw
xvmc uses a planar format.

In conclusion I claim that this code was bogus and XvMC on i965 class hw
over Xv overlay was most likely broken.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 src/i830_video.c |  113 +++++++++++++++++++++++++++++++-----------------------
 1 files changed, 65 insertions(+), 48 deletions(-)

Patch
diff mbox

diff --git a/src/i830_video.c b/src/i830_video.c
index 9fb0b56..2944563 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1782,6 +1782,46 @@  i830_swidth (I830Ptr pI830, unsigned int offset,
 }
 
 static void
+i830_calc_src_regs(I830Ptr pI830, int planar, short width, short height,
+	uint32_t *swidth_out, uint32_t *swidthsw_out, uint32_t *sheigth_out)
+{
+    unsigned int	mask, shift, offsety, offsetu;
+    unsigned int	swidth, swidthy, swidthuv;
+    I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+
+    if (IS_I9XX(pI830)) {
+	shift = 6;
+	mask = 0x3f;
+    } else {
+	shift = 5;
+	mask = 0x1f;
+    }
+
+    if (pPriv->currentBuf == 0) {
+	offsety = pPriv->YBuf0offset;
+	offsetu = pPriv->UBuf0offset;
+    } else {
+	offsety = pPriv->YBuf1offset;
+	offsetu = pPriv->UBuf1offset;
+    }
+
+    if (planar) {
+	*swidth_out = width | ((width/2 & 0x7ff) << 16);
+	swidthy  = i830_swidth (pI830, offsety, width, mask, shift);
+	swidthuv = i830_swidth (pI830, offsetu, width/2, mask, shift);
+	*swidthsw_out = (swidthy) | (swidthuv << 16);
+	*sheigth_out = height | ((height / 2) << 16);
+    } else {
+	*swidth_out = width;
+	swidth = i830_swidth (pI830, offsety, width << 1, mask, shift);
+	*swidthsw_out = swidth;
+	*sheigth_out = height;
+    }
+
+    return;
+}
+
+static void
 i830_update_dst_box_to_crtc_coords(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
 		BoxPtr dstBox)
 {
@@ -1833,6 +1873,23 @@  i830_update_dst_box_to_crtc_coords(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
     return;
 }
 
+static int
+is_planar_fourcc(int id)
+{
+    switch (id) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
+#ifdef INTEL_XVMC
+    case FOURCC_XVMC:
+#endif
+	return 1;
+    case FOURCC_UYVY:
+    case FOURCC_YUY2:
+    default:
+	return 0;
+    }
+}
+
 static void
 i830_store_coeffs_in_overlay_regs(uint16_t *reg_coeffs, coeffPtr new_coeffs,
 	int max_taps)
@@ -1981,8 +2038,8 @@  i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
     I830Ptr		pI830 = I830PTR(pScrn);
     I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
     I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
-    unsigned int	swidth, swidthy, swidthuv;
-    unsigned int	mask, shift, offsety, offsetu;
+    int			planar;
+    uint32_t		swidth, swidthsw, sheigth;
     int			tmp;
     uint32_t		OCMD;
     Bool		scaleChanged = FALSE;
@@ -2039,54 +2096,14 @@  i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
 	drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1;
     }
 
-    if (IS_I9XX(pI830)) {
-	shift = 6;
-	mask = 0x3f;
-    } else {
-	shift = 5;
-	mask = 0x1f;
-    }
-
-    if (pPriv->currentBuf == 0) {
-	offsety = pPriv->YBuf0offset;
-	offsetu = pPriv->UBuf0offset;
-    } else {
-	offsety = pPriv->YBuf1offset;
-	offsetu = pPriv->UBuf1offset;
-    }
-
-    switch (id) {
-    case FOURCC_YV12:
-    case FOURCC_I420:
-	overlay->SWIDTH = width | ((width/2 & 0x7ff) << 16);
-	swidthy  = i830_swidth (pI830, offsety, width, mask, shift);
-	swidthuv = i830_swidth (pI830, offsetu, width/2, mask, shift);
-	overlay->SWIDTHSW = (swidthy) | (swidthuv << 16);
-	overlay->SHEIGHT = height | ((height / 2) << 16);
-	break;
-    case FOURCC_UYVY:
-    case FOURCC_YUY2:
-    default:
-	overlay->SWIDTH = width;
-	swidth = ((offsety + (width << 1) + mask) >> shift) -
-	(offsety >> shift);
-
-	if (IS_I9XX(pI830))
-	    swidth <<= 1;
+    planar = is_planar_fourcc(id);
 
-	swidth -= 1;
+    i830_calc_src_regs(pI830, planar, width, height,
+	    &swidth, &swidthsw, &sheigth);
 
-	swidth <<= 2;
-	
-	OVERLAY_DEBUG("swidthsw is old %d new %d\n",
-		      swidth,
-		      i830_swidth (pI830, offsety, width << 1,
-				   mask, shift));
-
-	overlay->SWIDTHSW = swidth;
-	overlay->SHEIGHT = height;
-	break;
-    }
+    overlay->SWIDTH = swidth;
+    overlay->SWIDTHSW = swidthsw;
+    overlay->SHEIGHT = sheigth;
 
     overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;