@@ -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;
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(-)