diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2009-08-11 16:06:31 +0200 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-10-05 13:07:42 -0700 |
commit | 50d70e644ea0574752d0fe160ce8d873653c913b (patch) | |
tree | 45f49c76ebd7fb2190f98cab6c50ae203f6418c8 | |
parent | 2841a4cd8c6c64fdf4b2203ab73b57b38a50f651 (diff) |
Xv i830_display_video splitup: extract i830_calc_src_regs
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>
Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r-- | src/i830_video.c | 113 |
1 files changed, 65 insertions, 48 deletions
diff --git a/src/i830_video.c b/src/i830_video.c index 47c026df..1083f593 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; |