190b17f1bSmrg/*
290b17f1bSmrg * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
390b17f1bSmrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
490b17f1bSmrg *
590b17f1bSmrg * Permission is hereby granted, free of charge, to any person obtaining a
690b17f1bSmrg * copy of this software and associated documentation files (the "Software"),
790b17f1bSmrg * to deal in the Software without restriction, including without limitation
890b17f1bSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
990b17f1bSmrg * and/or sell copies of the Software, and to permit persons to whom the
1090b17f1bSmrg * Software is furnished to do so, subject to the following conditions:
1190b17f1bSmrg *
1290b17f1bSmrg * The above copyright notice and this permission notice (including the
1390b17f1bSmrg * next paragraph) shall be included in all copies or substantial portions
1490b17f1bSmrg * of the Software.
1590b17f1bSmrg *
1690b17f1bSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1790b17f1bSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1890b17f1bSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1990b17f1bSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2090b17f1bSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2190b17f1bSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2290b17f1bSmrg * DEALINGS IN THE SOFTWARE.
2390b17f1bSmrg */
2490b17f1bSmrg
2590b17f1bSmrg/*
2690b17f1bSmrg * I N C L U D E S
2790b17f1bSmrg */
2890b17f1bSmrg
2990b17f1bSmrg#ifdef HAVE_CONFIG_H
3090b17f1bSmrg#include "config.h"
3190b17f1bSmrg#endif
3290b17f1bSmrg
3390b17f1bSmrg#include "xf86.h"
3490b17f1bSmrg#include "xf86_OSproc.h"
3590b17f1bSmrg
3690b17f1bSmrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
3790b17f1bSmrg#include "xf86Resources.h"
3890b17f1bSmrg#endif
3990b17f1bSmrg
4090b17f1bSmrg#include "compiler.h"
4190b17f1bSmrg#include "xf86Pci.h"
4290b17f1bSmrg#include "regionstr.h"
4390b17f1bSmrg#include "via_driver.h"
4490b17f1bSmrg
4590b17f1bSmrg#include "xf86xv.h"
4690b17f1bSmrg#include <X11/extensions/Xv.h>
4790b17f1bSmrg#include "dixstruct.h"
4890b17f1bSmrg#include "via_xvpriv.h"
4990b17f1bSmrg#include "fourcc.h"
5090b17f1bSmrg
5190b17f1bSmrg/*
5290b17f1bSmrg * D E F I N E
5390b17f1bSmrg */
5490b17f1bSmrg#define OFF_DELAY       200           /* milliseconds */
5590b17f1bSmrg#define FREE_DELAY      60000
5690b17f1bSmrg#define PARAMSIZE       1024
5790b17f1bSmrg#define SLICESIZE       65536
5890b17f1bSmrg#define OFF_TIMER       0x01
5990b17f1bSmrg#define FREE_TIMER      0x02
6090b17f1bSmrg#define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
6190b17f1bSmrg#define VIA_MAX_XVIMAGE_X 1920
6290b17f1bSmrg#define VIA_MAX_XVIMAGE_Y 1200
6390b17f1bSmrg
6490b17f1bSmrg#define LOW_BAND 0x0CB0
6590b17f1bSmrg#define MID_BAND 0x1f10
6690b17f1bSmrg
6790b17f1bSmrg#define  XV_IMAGE          0
6890b17f1bSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
6990b17f1bSmrg#ifndef XvExtension
7090b17f1bSmrgvoid
7190b17f1bSmrgviaInitVideo(ScreenPtr pScreen)
7290b17f1bSmrg{
7390b17f1bSmrg}
7490b17f1bSmrg
7590b17f1bSmrgvoid
7690b17f1bSmrgviaExitVideo(ScrnInfoPtr pScrn)
7790b17f1bSmrg{
7890b17f1bSmrg}
7990b17f1bSmrgvoid
8090b17f1bSmrgviaSaveVideo(ScrnInfoPtr pScrn)
8190b17f1bSmrg{
8290b17f1bSmrg}
8390b17f1bSmrgvoid
8490b17f1bSmrgviaRestoreVideo(ScrnInfoPtr pScrn)
8590b17f1bSmrg{
8690b17f1bSmrg}
8790b17f1bSmrgvoid
8890b17f1bSmrgVIAVidAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
8990b17f1bSmrg{
9090b17f1bSmrg}
9190b17f1bSmrg#else
9290b17f1bSmrg
9390b17f1bSmrgstatic vidCopyFunc viaFastVidCpy = NULL;
9490b17f1bSmrg
9590b17f1bSmrg/*
9690b17f1bSmrg *  F U N C T I O N   D E C L A R A T I O N
9790b17f1bSmrg */
9890b17f1bSmrgstatic unsigned viaSetupAdaptors(ScreenPtr pScreen,
9990b17f1bSmrg    XF86VideoAdaptorPtr ** adaptors);
10090b17f1bSmrgstatic void viaStopVideo(ScrnInfoPtr, pointer, Bool);
10190b17f1bSmrgstatic void viaQueryBestSize(ScrnInfoPtr, Bool,
10290b17f1bSmrg    short, short, short, short, unsigned int *, unsigned int *, pointer);
10390b17f1bSmrgstatic int viaQueryImageAttributes(ScrnInfoPtr,
10490b17f1bSmrg    int, unsigned short *, unsigned short *, int *, int *);
10590b17f1bSmrgstatic int viaGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer);
10690b17f1bSmrgstatic int viaSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
10790b17f1bSmrgstatic int viaPutImage(ScrnInfoPtr, short, short, short, short, short, short,
10890b17f1bSmrg    short, short, int, unsigned char *, short, short, Bool,
10990b17f1bSmrg    RegionPtr, pointer, DrawablePtr);
11090b17f1bSmrgstatic void UVBlit(unsigned char *dest,
11190b17f1bSmrg    const unsigned char *uBuffer,
11290b17f1bSmrg    const unsigned char *vBuffer,
11390b17f1bSmrg    unsigned width, unsigned srcPitch, unsigned dstPitch, unsigned lines);
11490b17f1bSmrgstatic void nv12Blit(unsigned char *nv12Chroma,
11590b17f1bSmrg    const unsigned char *uBuffer,
11690b17f1bSmrg    const unsigned char *vBuffer,
11790b17f1bSmrg    unsigned width, unsigned srcPitch, unsigned dstPitch, unsigned lines);
11890b17f1bSmrg
11990b17f1bSmrgstatic Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation,
12090b17f1bSmrg    xvAutoPaint;
12190b17f1bSmrg
12290b17f1bSmrg/*
12390b17f1bSmrg *  S T R U C T S
12490b17f1bSmrg */
12590b17f1bSmrg/* client libraries expect an encoding */
12690b17f1bSmrgstatic XF86VideoEncodingRec DummyEncoding[1] = {
12790b17f1bSmrg    {XV_IMAGE, "XV_IMAGE", VIA_MAX_XVIMAGE_X, VIA_MAX_XVIMAGE_Y, {1, 1}},
12890b17f1bSmrg};
12990b17f1bSmrg
13090b17f1bSmrg#define NUM_FORMATS_G 9
13190b17f1bSmrg
13290b17f1bSmrgstatic XF86VideoFormatRec FormatsG[NUM_FORMATS_G] = {
13390b17f1bSmrg    {8, TrueColor},               /* Dithered */
13490b17f1bSmrg    {8, PseudoColor},               /* Using .. */
13590b17f1bSmrg    {8, StaticColor},
13690b17f1bSmrg    {8, GrayScale},
13790b17f1bSmrg    {8, StaticGray},               /* .. TexelLUT */
13890b17f1bSmrg    {16, TrueColor},
13990b17f1bSmrg    {24, TrueColor},
14090b17f1bSmrg    {16, DirectColor},
14190b17f1bSmrg    {24, DirectColor}
14290b17f1bSmrg};
14390b17f1bSmrg
14490b17f1bSmrg#define NUM_ATTRIBUTES_G 6
14590b17f1bSmrg
14690b17f1bSmrgstatic XF86AttributeRec AttributesG[NUM_ATTRIBUTES_G] = {
14790b17f1bSmrg    {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
14890b17f1bSmrg    {XvSettable | XvGettable, 0, 10000, "XV_BRIGHTNESS"},
14990b17f1bSmrg    {XvSettable | XvGettable, 0, 20000, "XV_CONTRAST"},
15090b17f1bSmrg    {XvSettable | XvGettable, 0, 20000, "XV_SATURATION"},
15190b17f1bSmrg    {XvSettable | XvGettable, -180, 180, "XV_HUE"},
15290b17f1bSmrg    {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}
15390b17f1bSmrg};
15490b17f1bSmrg
15590b17f1bSmrg#define NUM_IMAGES_G 7
15690b17f1bSmrg
15790b17f1bSmrgstatic XF86ImageRec ImagesG[NUM_IMAGES_G] = {
15890b17f1bSmrg    XVIMAGE_YUY2,
15990b17f1bSmrg    XVIMAGE_YV12,
16090b17f1bSmrg    XVIMAGE_I420,
16190b17f1bSmrg    {
16290b17f1bSmrg        /*
16390b17f1bSmrg         * Below, a dummy picture type that is used in XvPutImage only to do
16490b17f1bSmrg         * an overlay update. Introduced for the XvMC client lib.
16590b17f1bSmrg         * Defined to have a zero data size.
16690b17f1bSmrg         */
16790b17f1bSmrg
16890b17f1bSmrg        FOURCC_XVMC,
16990b17f1bSmrg        XvYUV,
17090b17f1bSmrg        LSBFirst,
17190b17f1bSmrg        {   'V', 'I', 'A', 0x00,
17290b17f1bSmrg            0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00,
17390b17f1bSmrg            0x38, 0x9B, 0x71},
17490b17f1bSmrg        12,
17590b17f1bSmrg        XvPlanar,
17690b17f1bSmrg        1,
17790b17f1bSmrg        0, 0, 0, 0,
17890b17f1bSmrg        8, 8, 8,
17990b17f1bSmrg        1, 2, 2,
18090b17f1bSmrg        1, 2, 2,
18190b17f1bSmrg        {   'Y', 'V', 'U',
18290b17f1bSmrg            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
18390b17f1bSmrg            0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
18490b17f1bSmrg        XvTopToBottom},
18590b17f1bSmrg    { /* RGB 555 */
18690b17f1bSmrg        FOURCC_RV15,
18790b17f1bSmrg        XvRGB,
18890b17f1bSmrg        LSBFirst,
18990b17f1bSmrg        {   'R', 'V', '1', '5',
19090b17f1bSmrg            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
19190b17f1bSmrg            0x00, 0x00, 0x00},
19290b17f1bSmrg        16,
19390b17f1bSmrg        XvPacked,
19490b17f1bSmrg        1,
19590b17f1bSmrg        15, 0x7C00, 0x03E0, 0x001F,
19690b17f1bSmrg        0, 0, 0,
19790b17f1bSmrg        0, 0, 0,
19890b17f1bSmrg        0, 0, 0,
19990b17f1bSmrg        {   'R', 'V', 'B', 0,
20090b17f1bSmrg            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20190b17f1bSmrg            0, 0, 0, 0, 0, 0, 0, 0, 0},
20290b17f1bSmrg        XvTopToBottom},
20390b17f1bSmrg    { /* RGB 565 */
20490b17f1bSmrg        FOURCC_RV16,
20590b17f1bSmrg        XvRGB,
20690b17f1bSmrg        LSBFirst,
20790b17f1bSmrg        {   'R', 'V', '1', '6',
20890b17f1bSmrg            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20990b17f1bSmrg            0x00, 0x00, 0x00},
21090b17f1bSmrg        16,
21190b17f1bSmrg        XvPacked,
21290b17f1bSmrg        1,
21390b17f1bSmrg        16, 0xF800, 0x07E0, 0x001F,
21490b17f1bSmrg        0, 0, 0,
21590b17f1bSmrg        0, 0, 0,
21690b17f1bSmrg        0, 0, 0,
21790b17f1bSmrg        {   'R', 'V', 'B', 0,
21890b17f1bSmrg            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
21990b17f1bSmrg            0, 0, 0, 0, 0, 0, 0, 0, 0},
22090b17f1bSmrg        XvTopToBottom},
22190b17f1bSmrg    { /* RGB 888 */
22290b17f1bSmrg        FOURCC_RV32,
22390b17f1bSmrg        XvRGB,
22490b17f1bSmrg        LSBFirst,
22590b17f1bSmrg        {   'R', 'V', '3', '2',
22690b17f1bSmrg            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
22790b17f1bSmrg            0x00, 0x00, 0x00},
22890b17f1bSmrg        32,
22990b17f1bSmrg        XvPacked,
23090b17f1bSmrg        1,
23190b17f1bSmrg        24, 0xff0000, 0x00ff00, 0x0000ff,
23290b17f1bSmrg        0, 0, 0,
23390b17f1bSmrg        0, 0, 0,
23490b17f1bSmrg        0, 0, 0,
23590b17f1bSmrg        {   'R', 'V', 'B', 0,
23690b17f1bSmrg            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23790b17f1bSmrg            0, 0, 0, 0, 0, 0, 0, 0, 0},
23890b17f1bSmrg        XvTopToBottom}
23990b17f1bSmrg
24090b17f1bSmrg};
24190b17f1bSmrg
24290b17f1bSmrgstatic char *XvAdaptorName[XV_ADAPT_NUM] = {
24390b17f1bSmrg    "XV_SWOV"
24490b17f1bSmrg};
24590b17f1bSmrg
24690b17f1bSmrgstatic XF86VideoAdaptorPtr viaAdaptPtr[XV_ADAPT_NUM];
24790b17f1bSmrgstatic XF86VideoAdaptorPtr *allAdaptors;
24890b17f1bSmrgstatic unsigned numAdaptPort[XV_ADAPT_NUM] = { 1 };
24990b17f1bSmrg
25090b17f1bSmrg/*
25190b17f1bSmrg *  F U N C T I O N
25290b17f1bSmrg */
25390b17f1bSmrg
25490b17f1bSmrg/*
25590b17f1bSmrg *   Decide if the mode support video overlay. This depends on the bandwidth
25690b17f1bSmrg *   of the mode and the type of RAM available.
25790b17f1bSmrg */
25890b17f1bSmrg
25990b17f1bSmrgstatic Bool
26090b17f1bSmrgDecideOverlaySupport(xf86CrtcPtr crtc)
26190b17f1bSmrg{
26290b17f1bSmrg    DisplayModePtr mode = &crtc->desiredMode;
26390b17f1bSmrg    ScrnInfoPtr pScrn = crtc->scrn;
26490b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
26590b17f1bSmrg
26690b17f1bSmrg#ifdef HAVE_DEBUG
26790b17f1bSmrg    if (pVia->disableXvBWCheck)
26890b17f1bSmrg        return TRUE;
26990b17f1bSmrg#endif
27090b17f1bSmrg
27190b17f1bSmrg    /* Small trick here. We keep the height in 16's of lines and width in 32's
27290b17f1bSmrg     * to avoid numeric overflow */
27390b17f1bSmrg
27490b17f1bSmrg    if (pVia->ChipId != PCI_CHIP_VT3205 &&
27590b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3204 &&
27690b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3259 &&
27790b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3314 &&
27890b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3327 &&
27990b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3336 &&
28090b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3409 &&
28190b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3410 &&
28290b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3364 &&
28390b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3324 &&
28490b17f1bSmrg        pVia->ChipId != PCI_CHIP_VT3353) {
28590b17f1bSmrg        CARD32 bandwidth = (mode->HDisplay >> 4) * (mode->VDisplay >> 5) *
28690b17f1bSmrg                            pScrn->bitsPerPixel * mode->VRefresh;
28790b17f1bSmrg
28890b17f1bSmrg        switch (pVia->MemClk) {
28990b17f1bSmrg        case VIA_MEM_SDR100:           /* No overlay without DDR */
29090b17f1bSmrg        case VIA_MEM_SDR133:
29190b17f1bSmrg            return FALSE;
29290b17f1bSmrg        case VIA_MEM_DDR200:
29390b17f1bSmrg            /* Basic limit for DDR200 is about this */
29490b17f1bSmrg            if (bandwidth > 1800000)
29590b17f1bSmrg                return FALSE;
29690b17f1bSmrg            /* But we have constraints at higher than 800x600 */
29790b17f1bSmrg            if (mode->HDisplay > 800) {
29890b17f1bSmrg                if (pScrn->bitsPerPixel != 8)
29990b17f1bSmrg                    return FALSE;
30090b17f1bSmrg                if (mode->VDisplay > 768)
30190b17f1bSmrg                    return FALSE;
30290b17f1bSmrg                if (mode->VRefresh > 60)
30390b17f1bSmrg                    return FALSE;
30490b17f1bSmrg            }
30590b17f1bSmrg            return TRUE;
30690b17f1bSmrg        case 0:               /*      FIXME: Why does my CLE266 report 0? */
30790b17f1bSmrg        case VIA_MEM_DDR266:
30890b17f1bSmrg            if (bandwidth > 7901250)
30990b17f1bSmrg                return FALSE;
31090b17f1bSmrg            return TRUE;
31190b17f1bSmrg        }
31290b17f1bSmrg        return FALSE;
31390b17f1bSmrg
31490b17f1bSmrg    } else {
31590b17f1bSmrg        unsigned width, height, refresh, dClock;
31690b17f1bSmrg        float mClock, memEfficiency, needBandWidth, totalBandWidth;
31790b17f1bSmrg
31890b17f1bSmrg        switch (pVia->MemClk) {
31990b17f1bSmrg            case VIA_MEM_SDR100:
32090b17f1bSmrg                mClock = 50;           /*HW base on 128 bit */
32190b17f1bSmrg                memEfficiency = (float)SINGLE_3205_100;
32290b17f1bSmrg                break;
32390b17f1bSmrg            case VIA_MEM_SDR133:
32490b17f1bSmrg                mClock = 66.5;
32590b17f1bSmrg                memEfficiency = (float)SINGLE_3205_100;
32690b17f1bSmrg                break;
32790b17f1bSmrg            case VIA_MEM_DDR200:
32890b17f1bSmrg                mClock = 100;
32990b17f1bSmrg                memEfficiency = (float)SINGLE_3205_100;
33090b17f1bSmrg                break;
33190b17f1bSmrg            case VIA_MEM_DDR266:
33290b17f1bSmrg                mClock = 133;
33390b17f1bSmrg                memEfficiency = (float)SINGLE_3205_133;
33490b17f1bSmrg                break;
33590b17f1bSmrg            case VIA_MEM_DDR333:
33690b17f1bSmrg                mClock = 166;
33790b17f1bSmrg                memEfficiency = (float)SINGLE_3205_133;
33890b17f1bSmrg                break;
33990b17f1bSmrg            case VIA_MEM_DDR400:
34090b17f1bSmrg                mClock = 200;
34190b17f1bSmrg                memEfficiency = (float)SINGLE_3205_133;
34290b17f1bSmrg                break;
34390b17f1bSmrg            case VIA_MEM_DDR533:
34490b17f1bSmrg                mClock = 266;
34590b17f1bSmrg                memEfficiency = (float)SINGLE_3205_133;
34690b17f1bSmrg                break;
34790b17f1bSmrg            case VIA_MEM_DDR667:
34890b17f1bSmrg                mClock = 333;
34990b17f1bSmrg                memEfficiency = (float)SINGLE_3205_133;
35090b17f1bSmrg                break;
35190b17f1bSmrg            case VIA_MEM_DDR800:
35290b17f1bSmrg                mClock = 400;
35390b17f1bSmrg                memEfficiency = (float)SINGLE_3205_133;
35490b17f1bSmrg                break;
35590b17f1bSmrg            case VIA_MEM_DDR1066:
35690b17f1bSmrg                mClock = 533;
35790b17f1bSmrg                memEfficiency = (float)SINGLE_3205_133;
35890b17f1bSmrg                break;
35990b17f1bSmrg            default:
360983b4bf2Smrg                ErrorF("Unknown DRAM Type!\n");
36190b17f1bSmrg                mClock = 166;
36290b17f1bSmrg                memEfficiency = (float)SINGLE_3205_133;
36390b17f1bSmrg                break;
36490b17f1bSmrg        }
36590b17f1bSmrg
36690b17f1bSmrg        width = mode->HDisplay;
36790b17f1bSmrg        height = mode->VDisplay;
36890b17f1bSmrg        refresh = mode->VRefresh;
36990b17f1bSmrg
37090b17f1bSmrg        if (refresh==0) {
37190b17f1bSmrg            refresh=60;
37290b17f1bSmrg            ErrorF("Unable to fetch vertical refresh value, needed for bandwidth calculation.\n");
37390b17f1bSmrg        }
37490b17f1bSmrg
37590b17f1bSmrg        /*
37690b17f1bSmrg         * Approximative, VERY conservative formula in some cases.
37790b17f1bSmrg         * This formula and the one below are derived analyzing the
37890b17f1bSmrg         * tables present in VIA's own drivers. They may reject the over-
37990b17f1bSmrg         * lay in some cases where VIA's driver don't.
38090b17f1bSmrg         */
38190b17f1bSmrg        dClock = (width * height * refresh) / 680000;
38290b17f1bSmrg        if (dClock) {
38390b17f1bSmrg            needBandWidth =
38490b17f1bSmrg                (float)(((pScrn->bitsPerPixel >> 3) + VIDEO_BPP) * dClock);
38590b17f1bSmrg            totalBandWidth = (float)(mClock * 16. * memEfficiency);
38690b17f1bSmrg
38790b17f1bSmrg            DBG_DD(ErrorF(" via_xv.c : cBitsPerPel= %d : \n",
38890b17f1bSmrg                pScrn->bitsPerPixel));
38990b17f1bSmrg            DBG_DD(ErrorF(" via_xv.c : Video_Bpp= %d : \n", VIDEO_BPP));
39090b17f1bSmrg            DBG_DD(ErrorF(" via_xv.c : refresh = %d : \n", refresh));
39190b17f1bSmrg            DBG_DD(ErrorF(" via_xv.c : dClock= %d : \n", dClock));
39290b17f1bSmrg            DBG_DD(ErrorF(" via_xv.c : mClk= %f : \n", mClock));
39390b17f1bSmrg            DBG_DD(ErrorF(" via_xv.c : memEfficiency= %f : \n",
39490b17f1bSmrg                memEfficiency));
395963d66acSmrg            if (needBandWidth < totalBandWidth)
396963d66acSmrg                return TRUE;
39790b17f1bSmrg            ErrorF(" via_xv.c : needBandwidth= %f : \n",
39890b17f1bSmrg                needBandWidth);
39990b17f1bSmrg            ErrorF(" via_xv.c : totalBandwidth= %f : \n",
40090b17f1bSmrg                totalBandWidth);
40190b17f1bSmrg        }
40290b17f1bSmrg        return FALSE;
40390b17f1bSmrg    }
40490b17f1bSmrg    return FALSE;
40590b17f1bSmrg}
40690b17f1bSmrg
40790b17f1bSmrgstatic const char *viaXvErrMsg[xve_numerr] = { "No Error.",
40890b17f1bSmrg    "Bandwidth is insufficient. Check bios memory settings.",
40990b17f1bSmrg    "PCI DMA blit failed. You probably encountered a bug.",
41090b17f1bSmrg    "Not enough resources to complete the request. Probably out of memory.",
41190b17f1bSmrg    "General Error. I wish I could be more specific.",
41290b17f1bSmrg    "Wrong adaptor used. Try another port number."
41390b17f1bSmrg};
41490b17f1bSmrg
41590b17f1bSmrgstatic void
41690b17f1bSmrgviaXvError(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, XvError error)
41790b17f1bSmrg{
41890b17f1bSmrg    if (error == xve_none) {
41990b17f1bSmrg        pPriv->xvErr = xve_none;
42090b17f1bSmrg        return;
42190b17f1bSmrg    }
42290b17f1bSmrg    if (error == pPriv->xvErr) {
42390b17f1bSmrg        return;
42490b17f1bSmrg    }
42590b17f1bSmrg    pPriv->xvErr = error;
42690b17f1bSmrg    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[Xv] Port %d: %s\n",
42790b17f1bSmrg            pPriv->xv_portnum, viaXvErrMsg[error]);
42890b17f1bSmrg}
42990b17f1bSmrg
43090b17f1bSmrgstatic void
43190b17f1bSmrgviaResetVideo(ScrnInfoPtr pScrn)
43290b17f1bSmrg{
43390b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
43490b17f1bSmrg    vmmtr viaVidEng = (vmmtr) (pVia->MapBase + 0x200);
43590b17f1bSmrg
43690b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaResetVideo: \n"));
43790b17f1bSmrg
43890b17f1bSmrg    viaVidEng->video1_ctl = 0;
43990b17f1bSmrg    viaVidEng->video3_ctl = 0;
44090b17f1bSmrg    viaVidEng->compose = V1_COMMAND_FIRE;
44190b17f1bSmrg    viaVidEng->compose = V3_COMMAND_FIRE;
44290b17f1bSmrg    viaVidEng->color_key = 0x821;
44390b17f1bSmrg    viaVidEng->snd_color_key = 0x821;
44490b17f1bSmrg}
44590b17f1bSmrg
44690b17f1bSmrgvoid
44790b17f1bSmrgviaSaveVideo(ScrnInfoPtr pScrn)
44890b17f1bSmrg{
44990b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
45090b17f1bSmrg    vmmtr viaVidEng = (vmmtr) (pVia->MapBase + 0x200);
45190b17f1bSmrg
45290b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaSaveVideo : \n"));
45390b17f1bSmrg    /* Save video registers */
45490b17f1bSmrg    memcpy(pVia->VideoRegs, (void*)viaVidEng, sizeof(video_via_regs));
45590b17f1bSmrg
45690b17f1bSmrg    pVia->dwV1 = ((vmmtr) viaVidEng)->video1_ctl;
45790b17f1bSmrg    pVia->dwV3 = ((vmmtr) viaVidEng)->video3_ctl;
45890b17f1bSmrg    viaVidEng->video1_ctl = 0;
45990b17f1bSmrg    viaVidEng->video3_ctl = 0;
46090b17f1bSmrg    viaVidEng->compose = V1_COMMAND_FIRE;
46190b17f1bSmrg    viaVidEng->compose = V3_COMMAND_FIRE;
46290b17f1bSmrg}
46390b17f1bSmrg
46490b17f1bSmrgvoid
46590b17f1bSmrgviaRestoreVideo(ScrnInfoPtr pScrn)
46690b17f1bSmrg{
46790b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
46890b17f1bSmrg    vmmtr viaVidEng = (vmmtr) (pVia->MapBase + 0x200);
46990b17f1bSmrg    video_via_regs  *localVidEng = pVia->VideoRegs;
47090b17f1bSmrg
47190b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaRestoreVideo : \n"));
47290b17f1bSmrg
47390b17f1bSmrg    /* Restore video registers */
47490b17f1bSmrg    /* flush restored video engines' setting to MapBase */
47590b17f1bSmrg    viaVidEng->alphawin_hvstart = localVidEng->alphawin_hvstart;
47690b17f1bSmrg    viaVidEng->alphawin_size   = localVidEng->alphawin_size;
47790b17f1bSmrg    viaVidEng->alphawin_ctl    = localVidEng->alphawin_ctl;
47890b17f1bSmrg    viaVidEng->alphafb_stride  = localVidEng->alphafb_stride;
47990b17f1bSmrg    viaVidEng->color_key       = localVidEng->color_key;
48090b17f1bSmrg    viaVidEng->alphafb_addr    = localVidEng->alphafb_addr;
48190b17f1bSmrg    viaVidEng->chroma_low      = localVidEng->chroma_low;
48290b17f1bSmrg    viaVidEng->chroma_up       = localVidEng->chroma_up;
48390b17f1bSmrg    viaVidEng->interruptflag   = localVidEng->interruptflag;
48490b17f1bSmrg
48590b17f1bSmrg    if (pVia->ChipId != PCI_CHIP_VT3314)
48690b17f1bSmrg    {
48790b17f1bSmrg        /*VT3314 only has V3*/
48890b17f1bSmrg        viaVidEng->video1_ctl      = localVidEng->video1_ctl;
48990b17f1bSmrg        viaVidEng->video1_fetch    = localVidEng->video1_fetch;
49090b17f1bSmrg        viaVidEng->video1y_addr1   = localVidEng->video1y_addr1;
49190b17f1bSmrg        viaVidEng->video1_stride   = localVidEng->video1_stride;
49290b17f1bSmrg        viaVidEng->video1_hvstart  = localVidEng->video1_hvstart;
49390b17f1bSmrg        viaVidEng->video1_size     = localVidEng->video1_size;
49490b17f1bSmrg        viaVidEng->video1y_addr2   = localVidEng->video1y_addr2;
49590b17f1bSmrg        viaVidEng->video1_zoom     = localVidEng->video1_zoom;
49690b17f1bSmrg        viaVidEng->video1_mictl    = localVidEng->video1_mictl;
49790b17f1bSmrg        viaVidEng->video1y_addr0   = localVidEng->video1y_addr0;
49890b17f1bSmrg        viaVidEng->video1_fifo     = localVidEng->video1_fifo;
49990b17f1bSmrg        viaVidEng->video1y_addr3   = localVidEng->video1y_addr3;
50090b17f1bSmrg        viaVidEng->v1_source_w_h   = localVidEng->v1_source_w_h;
50190b17f1bSmrg        viaVidEng->video1_CSC1     = localVidEng->video1_CSC1;
50290b17f1bSmrg        viaVidEng->video1_CSC2     = localVidEng->video1_CSC2;
50390b17f1bSmrg
50490b17f1bSmrg        /* Fix cursor garbage after suspend for VX855 and VX900 (#405) */
50590b17f1bSmrg        /* 0x2E4 T Signature Data Result 1 */
50690b17f1bSmrg        viaVidEng->video1u_addr1         = localVidEng->video1u_addr1;
50790b17f1bSmrg        /* 0x2E8 HI for Primary Display FIFO Control Signal */
50890b17f1bSmrg        viaVidEng->video1u_addr2         = localVidEng->video1u_addr2;
50990b17f1bSmrg        /* 0x2EC HI for Primary Display FIFO Transparent color */
51090b17f1bSmrg        viaVidEng->video1u_addr3         = localVidEng->video1u_addr3;
51190b17f1bSmrg        /* 0x2F0 HI for Primary Display Control Signal */
51290b17f1bSmrg        viaVidEng->video1v_addr0         = localVidEng->video1v_addr0;
51390b17f1bSmrg        /* 0x2F4 HI for Primary Display Frame Buffer Starting Address */
51490b17f1bSmrg        viaVidEng->video1v_addr1         = localVidEng->video1v_addr1;
51590b17f1bSmrg        /* 0x2F8 HI for Primary Display Horizontal and Vertical Start */
51690b17f1bSmrg        viaVidEng->video1v_addr2         = localVidEng->video1v_addr2;
51790b17f1bSmrg        /* 0x2FC HI for Primary Display Center Offset */
51890b17f1bSmrg        viaVidEng->video1v_addr3         = localVidEng->video1v_addr3;
51990b17f1bSmrg    }
52090b17f1bSmrg    viaVidEng->snd_color_key   = localVidEng->snd_color_key;
52190b17f1bSmrg    viaVidEng->v3alpha_prefifo = localVidEng->v3alpha_prefifo;
52290b17f1bSmrg    viaVidEng->v3alpha_fifo    = localVidEng->v3alpha_fifo;
52390b17f1bSmrg    viaVidEng->video3_CSC2     = localVidEng->video3_CSC2;
52490b17f1bSmrg    viaVidEng->video3_CSC2     = localVidEng->video3_CSC2;
52590b17f1bSmrg    viaVidEng->v3_source_width = localVidEng->v3_source_width;
52690b17f1bSmrg    viaVidEng->video3_ctl      = localVidEng->video3_ctl;
52790b17f1bSmrg    viaVidEng->video3_addr0    = localVidEng->video3_addr0;
52890b17f1bSmrg    viaVidEng->video3_addr1    = localVidEng->video3_addr1;
52990b17f1bSmrg    viaVidEng->video3_stride   = localVidEng->video3_stride;
53090b17f1bSmrg    viaVidEng->video3_hvstart  = localVidEng->video3_hvstart;
53190b17f1bSmrg    viaVidEng->video3_size     = localVidEng->video3_size;
53290b17f1bSmrg    viaVidEng->v3alpha_fetch   = localVidEng->v3alpha_fetch;
53390b17f1bSmrg    viaVidEng->video3_zoom     = localVidEng->video3_zoom;
53490b17f1bSmrg    viaVidEng->video3_mictl    = localVidEng->video3_mictl;
53590b17f1bSmrg    viaVidEng->video3_CSC1     = localVidEng->video3_CSC1;
53690b17f1bSmrg    viaVidEng->video3_CSC2     = localVidEng->video3_CSC2;
53790b17f1bSmrg    viaVidEng->compose         = localVidEng->compose;
53890b17f1bSmrg    viaVidEng->video3_ctl      = pVia->dwV3;
53990b17f1bSmrg
54090b17f1bSmrg    if (pVia->ChipId != PCI_CHIP_VT3314) {
54190b17f1bSmrg        viaVidEng->video1_ctl = pVia->dwV1;
54290b17f1bSmrg        viaVidEng->compose = V1_COMMAND_FIRE;
54390b17f1bSmrg    }
54490b17f1bSmrg    viaVidEng->compose = V3_COMMAND_FIRE;
54590b17f1bSmrg}
54690b17f1bSmrg
54790b17f1bSmrgvoid
54890b17f1bSmrgviaExitVideo(ScrnInfoPtr pScrn)
54990b17f1bSmrg{
55090b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
55190b17f1bSmrg    vmmtr viaVidEng = (vmmtr) (pVia->MapBase + 0x200);
55290b17f1bSmrg    XF86VideoAdaptorPtr curAdapt;
55390b17f1bSmrg    int i, j, numPorts;
55490b17f1bSmrg
55590b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaExitVideo : \n"));
55690b17f1bSmrg
55790b17f1bSmrg#ifdef HAVE_DRI
55890b17f1bSmrg    ViaCleanupXVMC(pScrn, viaAdaptPtr, XV_ADAPT_NUM);
55990b17f1bSmrg#endif
56090b17f1bSmrg
56190b17f1bSmrg    viaVidEng->video1_ctl = 0;
56290b17f1bSmrg    viaVidEng->video3_ctl = 0;
56390b17f1bSmrg    viaVidEng->compose = V1_COMMAND_FIRE;
56490b17f1bSmrg    viaVidEng->compose = V3_COMMAND_FIRE;
56590b17f1bSmrg
56690b17f1bSmrg    /*
56790b17f1bSmrg     * Free all adaptor info allocated in viaInitVideo.
56890b17f1bSmrg     */
56990b17f1bSmrg
57090b17f1bSmrg    for (i = 0; i < XV_ADAPT_NUM; ++i) {
57190b17f1bSmrg        curAdapt = viaAdaptPtr[i];
57290b17f1bSmrg        if (curAdapt) {
57390b17f1bSmrg            if (curAdapt->pPortPrivates) {
57490b17f1bSmrg                if (curAdapt->pPortPrivates->ptr) {
57590b17f1bSmrg                    numPorts = numAdaptPort[i];
57690b17f1bSmrg                    for (j = 0; j < numPorts; ++j) {
57790b17f1bSmrg                        viaStopVideo(pScrn,
57890b17f1bSmrg                            (viaPortPrivPtr) curAdapt->pPortPrivates->ptr + j,
57990b17f1bSmrg                            TRUE);
58090b17f1bSmrg                    }
58190b17f1bSmrg                    free(curAdapt->pPortPrivates->ptr);
58290b17f1bSmrg                }
58390b17f1bSmrg                free(curAdapt->pPortPrivates);
58490b17f1bSmrg            }
58590b17f1bSmrg            free(curAdapt);
58690b17f1bSmrg        }
58790b17f1bSmrg    }
58890b17f1bSmrg    if (allAdaptors)
58990b17f1bSmrg        free(allAdaptors);
59090b17f1bSmrg}
59190b17f1bSmrg
59290b17f1bSmrgvoid
59390b17f1bSmrgviaInitVideo(ScreenPtr pScreen)
59490b17f1bSmrg{
59590b17f1bSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
59690b17f1bSmrg    XF86VideoAdaptorPtr *adaptors, *newAdaptors;
59790b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
59890b17f1bSmrg    int num_adaptors, num_new;
59990b17f1bSmrg
60090b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaInitVideo, Screen[%d]\n", pScrn->scrnIndex));
60190b17f1bSmrg
60290b17f1bSmrg    allAdaptors = NULL;
60390b17f1bSmrg    newAdaptors = NULL;
60490b17f1bSmrg    num_new = 0;
60590b17f1bSmrg
60690b17f1bSmrg    pVia->useDmaBlit = FALSE;
60790b17f1bSmrg#ifdef HAVE_DRI
60890b17f1bSmrg    pVia->useDmaBlit = (pVia->directRenderingType == DRI_1) &&
60990b17f1bSmrg    ((pVia->Chipset == VIA_CLE266) ||
61090b17f1bSmrg        (pVia->Chipset == VIA_KM400) ||
61190b17f1bSmrg        (pVia->Chipset == VIA_K8M800) ||
61290b17f1bSmrg        (pVia->Chipset == VIA_PM800) ||
613963d66acSmrg        (pVia->Chipset == VIA_P4M800PRO) ||
61490b17f1bSmrg        (pVia->Chipset == VIA_K8M890) ||
61590b17f1bSmrg        (pVia->Chipset == VIA_P4M900) ||
61690b17f1bSmrg        (pVia->Chipset == VIA_CX700) ||
61790b17f1bSmrg        (pVia->Chipset == VIA_VX800) ||
61890b17f1bSmrg        (pVia->Chipset == VIA_VX855) ||
61990b17f1bSmrg        (pVia->Chipset == VIA_VX900) ||
62090b17f1bSmrg        (pVia->Chipset == VIA_P4M890));
62190b17f1bSmrg    if ((pVia->drmVerMajor < 2) ||
62290b17f1bSmrg        ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor < 9)))
62390b17f1bSmrg        pVia->useDmaBlit = FALSE;
62490b17f1bSmrg#endif
62590b17f1bSmrg    pVia->useDmaBlit = pVia->useDmaBlit && pVia->dmaXV;
62690b17f1bSmrg
62790b17f1bSmrg    if (pVia->useDmaBlit)
62890b17f1bSmrg        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
62990b17f1bSmrg            "[Xv] Using PCI DMA for Xv image transfer.\n");
63090b17f1bSmrg
63190b17f1bSmrg    if (!viaFastVidCpy)
63290b17f1bSmrg        viaFastVidCpy = viaVidCopyInit("video", pScreen);
63390b17f1bSmrg
63490b17f1bSmrg    if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400) ||
63590b17f1bSmrg        (pVia->Chipset == VIA_K8M800) || (pVia->Chipset == VIA_PM800) ||
636963d66acSmrg        (pVia->Chipset == VIA_P4M800PRO) || (pVia->Chipset == VIA_K8M890) ||
63790b17f1bSmrg        (pVia->Chipset == VIA_P4M900) || (pVia->Chipset == VIA_CX700) ||
63890b17f1bSmrg        (pVia->Chipset == VIA_P4M890) || (pVia->Chipset == VIA_VX800) ||
63990b17f1bSmrg        (pVia->Chipset == VIA_VX855 || (pVia->Chipset == VIA_VX900))) {
64090b17f1bSmrg        num_new = viaSetupAdaptors(pScreen, &newAdaptors);
64190b17f1bSmrg        num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
64290b17f1bSmrg    } else {
64390b17f1bSmrg        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
64490b17f1bSmrg                "[Xv] Unsupported Chipset. X video functionality disabled.\n");
64590b17f1bSmrg        num_adaptors = 0;
64690b17f1bSmrg        memset(viaAdaptPtr, 0, sizeof(viaAdaptPtr));
64790b17f1bSmrg    }
64890b17f1bSmrg
64990b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : num_adaptors : %d\n", num_adaptors));
65090b17f1bSmrg    if (newAdaptors) {
65190b17f1bSmrg        allAdaptors = malloc((num_adaptors + num_new) *
65290b17f1bSmrg                sizeof(XF86VideoAdaptorPtr *));
65390b17f1bSmrg        if (allAdaptors) {
65490b17f1bSmrg            if (num_adaptors)
65590b17f1bSmrg                memcpy(allAdaptors, adaptors,
65690b17f1bSmrg                    num_adaptors * sizeof(XF86VideoAdaptorPtr));
65790b17f1bSmrg            memcpy(allAdaptors + num_adaptors, newAdaptors,
65890b17f1bSmrg                    num_new * sizeof(XF86VideoAdaptorPtr));
65990b17f1bSmrg            num_adaptors += num_new;
66090b17f1bSmrg        }
66190b17f1bSmrg    }
66290b17f1bSmrg
66390b17f1bSmrg    if (num_adaptors) {
66490b17f1bSmrg        xf86XVScreenInit(pScreen, allAdaptors, num_adaptors);
66590b17f1bSmrg#ifdef HAVE_DRI
66690b17f1bSmrg        ViaInitXVMC(pScreen);
66790b17f1bSmrg#endif
66890b17f1bSmrg        viaSetColorSpace(pVia, 0, 0, 0, 0, TRUE);
66990b17f1bSmrg        pVia->swov.panning_x = 0;
67090b17f1bSmrg        pVia->swov.panning_y = 0;
67190b17f1bSmrg        pVia->swov.oldPanningX = 0;
67290b17f1bSmrg        pVia->swov.oldPanningY = 0;
67390b17f1bSmrg    }
67490b17f1bSmrg}
67590b17f1bSmrg
67690b17f1bSmrgstatic unsigned
67790b17f1bSmrgviaSetupAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr ** adaptors)
67890b17f1bSmrg{
67990b17f1bSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
68090b17f1bSmrg    int i, j, usedPorts, numPorts;
68190b17f1bSmrg    viaPortPrivRec *viaPortPriv;
68290b17f1bSmrg    DevUnion *pdevUnion;
68390b17f1bSmrg
68490b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaSetupAdaptors (viaSetupImageVideo): \n"));
68590b17f1bSmrg
68690b17f1bSmrg    xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
68790b17f1bSmrg    xvContrast = MAKE_ATOM("XV_CONTRAST");
68890b17f1bSmrg    xvColorKey = MAKE_ATOM("XV_COLORKEY");
68990b17f1bSmrg    xvHue = MAKE_ATOM("XV_HUE");
69090b17f1bSmrg    xvSaturation = MAKE_ATOM("XV_SATURATION");
69190b17f1bSmrg    xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
69290b17f1bSmrg
69390b17f1bSmrg    *adaptors = NULL;
69490b17f1bSmrg    usedPorts = 0;
69590b17f1bSmrg
69690b17f1bSmrg    for (i = 0; i < XV_ADAPT_NUM; i++) {
69790b17f1bSmrg        if (!(viaAdaptPtr[i] = xf86XVAllocateVideoAdaptorRec(pScrn)))
69890b17f1bSmrg            return 0;
69990b17f1bSmrg        numPorts = numAdaptPort[i];
70090b17f1bSmrg
70190b17f1bSmrg        viaPortPriv =
70290b17f1bSmrg            (viaPortPrivPtr) xnfcalloc(numPorts, sizeof(viaPortPrivRec));
70390b17f1bSmrg        pdevUnion = (DevUnion *) xnfcalloc(numPorts, sizeof(DevUnion));
70490b17f1bSmrg
70590b17f1bSmrg        if (i == XV_ADAPT_SWOV) { /* Overlay engine */
70690b17f1bSmrg            viaAdaptPtr[i]->type = XvInputMask | XvWindowMask | XvImageMask |
70790b17f1bSmrg            XvVideoMask | XvStillMask;
70890b17f1bSmrg            viaAdaptPtr[i]->flags =
70990b17f1bSmrg            VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
71090b17f1bSmrg        } else {
71190b17f1bSmrg            viaAdaptPtr[i]->type = XvInputMask | XvWindowMask | XvVideoMask;
71290b17f1bSmrg            viaAdaptPtr[i]->flags =
71390b17f1bSmrg            VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
71490b17f1bSmrg        }
71590b17f1bSmrg        viaAdaptPtr[i]->name = XvAdaptorName[i];
71690b17f1bSmrg        viaAdaptPtr[i]->nEncodings = 1;
71790b17f1bSmrg        viaAdaptPtr[i]->pEncodings = DummyEncoding;
71890b17f1bSmrg        viaAdaptPtr[i]->nFormats = sizeof(FormatsG) / sizeof(FormatsG[0]);
71990b17f1bSmrg        viaAdaptPtr[i]->pFormats = FormatsG;
72090b17f1bSmrg
72190b17f1bSmrg        /* The adapter can handle 1 port simultaneously */
72290b17f1bSmrg        viaAdaptPtr[i]->nPorts = numPorts;
72390b17f1bSmrg        viaAdaptPtr[i]->pPortPrivates = pdevUnion;
72490b17f1bSmrg        viaAdaptPtr[i]->pPortPrivates->ptr = (pointer) viaPortPriv;
72590b17f1bSmrg        viaAdaptPtr[i]->nAttributes = NUM_ATTRIBUTES_G;
72690b17f1bSmrg        viaAdaptPtr[i]->pAttributes = AttributesG;
72790b17f1bSmrg
72890b17f1bSmrg        viaAdaptPtr[i]->nImages = NUM_IMAGES_G;
72990b17f1bSmrg        viaAdaptPtr[i]->pImages = ImagesG;
73090b17f1bSmrg        viaAdaptPtr[i]->PutVideo = NULL;
73190b17f1bSmrg        viaAdaptPtr[i]->StopVideo = viaStopVideo;
73290b17f1bSmrg        viaAdaptPtr[i]->QueryBestSize = viaQueryBestSize;
73390b17f1bSmrg        viaAdaptPtr[i]->GetPortAttribute = viaGetPortAttribute;
73490b17f1bSmrg        viaAdaptPtr[i]->SetPortAttribute = viaSetPortAttribute;
73590b17f1bSmrg        viaAdaptPtr[i]->PutImage = viaPutImage;
73690b17f1bSmrg        viaAdaptPtr[i]->ReputImage = NULL;
73790b17f1bSmrg        viaAdaptPtr[i]->QueryImageAttributes = viaQueryImageAttributes;
73890b17f1bSmrg        for (j = 0; j < numPorts; ++j) {
73990b17f1bSmrg            viaPortPriv[j].dmaBounceBuffer = NULL;
74090b17f1bSmrg            viaPortPriv[j].dmaBounceStride = 0;
74190b17f1bSmrg            viaPortPriv[j].dmaBounceLines = 0;
74290b17f1bSmrg            viaPortPriv[j].colorKey = 0x0821;
74390b17f1bSmrg            viaPortPriv[j].autoPaint = TRUE;
74490b17f1bSmrg            viaPortPriv[j].brightness = 5000.;
74590b17f1bSmrg            viaPortPriv[j].saturation = 10000;
74690b17f1bSmrg            viaPortPriv[j].contrast = 10000;
74790b17f1bSmrg            viaPortPriv[j].hue = 0;
74890b17f1bSmrg            viaPortPriv[j].FourCC = 0;
74990b17f1bSmrg            viaPortPriv[j].xv_portnum = j + usedPorts;
75090b17f1bSmrg            viaPortPriv[j].xvErr = xve_none;
75190b17f1bSmrg
75290b17f1bSmrg#ifdef X_USE_REGION_NULL
75390b17f1bSmrg            REGION_NULL(pScreen, &viaPortPriv[j].clip);
75490b17f1bSmrg#else
75590b17f1bSmrg            REGION_INIT(pScreen, &viaPortPriv[j].clip, NullBox, 1);
75690b17f1bSmrg#endif
75790b17f1bSmrg        }
75890b17f1bSmrg        usedPorts += j;
75990b17f1bSmrg
76090b17f1bSmrg#ifdef HAVE_DRI
76190b17f1bSmrg        viaXvMCInitXv(pScrn, viaAdaptPtr[i]);
76290b17f1bSmrg#endif
76390b17f1bSmrg
76490b17f1bSmrg    } /* End of for */
76590b17f1bSmrg    viaResetVideo(pScrn);
76690b17f1bSmrg    *adaptors = viaAdaptPtr;
76790b17f1bSmrg    return XV_ADAPT_NUM;
76890b17f1bSmrg}
76990b17f1bSmrg
77090b17f1bSmrgstatic void
77190b17f1bSmrgviaStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
77290b17f1bSmrg{
77390b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
77490b17f1bSmrg    viaPortPrivPtr pPriv = (viaPortPrivPtr) data;
77590b17f1bSmrg
77690b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaStopVideo: exit=%d\n", exit));
77790b17f1bSmrg
77890b17f1bSmrg    REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
77990b17f1bSmrg    ViaOverlayHide(pScrn);
78090b17f1bSmrg    if (exit) {
78190b17f1bSmrg        ViaSwovSurfaceDestroy(pScrn, pPriv);
78290b17f1bSmrg        if (pPriv->dmaBounceBuffer)
78390b17f1bSmrg            free(pPriv->dmaBounceBuffer);
78490b17f1bSmrg        pPriv->dmaBounceBuffer = 0;
78590b17f1bSmrg        pPriv->dmaBounceStride = 0;
78690b17f1bSmrg        pPriv->dmaBounceLines = 0;
78790b17f1bSmrg        pVia->dwFrameNum = 0;
78890b17f1bSmrg        pPriv->old_drw_x = 0;
78990b17f1bSmrg        pPriv->old_drw_y = 0;
79090b17f1bSmrg        pPriv->old_drw_w = 0;
79190b17f1bSmrg        pPriv->old_drw_h = 0;
79290b17f1bSmrg    }
79390b17f1bSmrg}
79490b17f1bSmrg
79590b17f1bSmrgstatic int
79690b17f1bSmrgviaSetPortAttribute(ScrnInfoPtr pScrn,
79790b17f1bSmrg        Atom attribute, INT32 value, pointer data)
79890b17f1bSmrg{
79990b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
80090b17f1bSmrg    vmmtr viaVidEng = (vmmtr) (pVia->MapBase + 0x200);
80190b17f1bSmrg    viaPortPrivPtr pPriv = (viaPortPrivPtr) data;
80290b17f1bSmrg    int attr, avalue;
80390b17f1bSmrg
80490b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaSetPortAttribute : \n"));
80590b17f1bSmrg
80690b17f1bSmrg    /* Color Key */
80790b17f1bSmrg    if (attribute == xvColorKey) {
80890b17f1bSmrg        DBG_DD(ErrorF("  V4L Disable  xvColorKey = %08lx\n", value));
80990b17f1bSmrg
81090b17f1bSmrg        pPriv->colorKey = value;
81190b17f1bSmrg        /* All assume color depth is 16 */
81290b17f1bSmrg        value &= 0x00FFFFFF;
81390b17f1bSmrg        viaVidEng->color_key = value;
81490b17f1bSmrg        viaVidEng->snd_color_key = value;
81590b17f1bSmrg        REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
81690b17f1bSmrg        DBG_DD(ErrorF("  V4L Disable done  xvColorKey = %08lx\n", value));
81790b17f1bSmrg
81890b17f1bSmrg    } else if (attribute == xvAutoPaint) {
81990b17f1bSmrg        pPriv->autoPaint = value;
82090b17f1bSmrg        DBG_DD(ErrorF("       xvAutoPaint = %08lx\n", value));
82190b17f1bSmrg        /* Color Control */
82290b17f1bSmrg    } else if (attribute == xvBrightness ||
82390b17f1bSmrg            attribute == xvContrast ||
82490b17f1bSmrg            attribute == xvSaturation || attribute == xvHue) {
82590b17f1bSmrg        if (attribute == xvBrightness) {
82690b17f1bSmrg            DBG_DD(ErrorF("     xvBrightness = %08ld\n", value));
82790b17f1bSmrg            pPriv->brightness = value;
82890b17f1bSmrg        }
82990b17f1bSmrg        if (attribute == xvContrast) {
83090b17f1bSmrg            DBG_DD(ErrorF("     xvContrast = %08ld\n", value));
83190b17f1bSmrg            pPriv->contrast = value;
83290b17f1bSmrg        }
83390b17f1bSmrg        if (attribute == xvSaturation) {
83490b17f1bSmrg            DBG_DD(ErrorF("     xvSaturation = %08ld\n", value));
83590b17f1bSmrg            pPriv->saturation = value;
83690b17f1bSmrg        }
83790b17f1bSmrg        if (attribute == xvHue) {
83890b17f1bSmrg            DBG_DD(ErrorF("     xvHue = %08ld\n", value));
83990b17f1bSmrg            pPriv->hue = value;
84090b17f1bSmrg        }
84190b17f1bSmrg        viaSetColorSpace(pVia, pPriv->hue, pPriv->saturation,
84290b17f1bSmrg                pPriv->brightness, pPriv->contrast, FALSE);
84390b17f1bSmrg    } else {
84490b17f1bSmrg        DBG_DD(ErrorF
84590b17f1bSmrg                (" via_xv.c : viaSetPortAttribute : is not supported the attribute"));
84690b17f1bSmrg        return BadMatch;
84790b17f1bSmrg    }
84890b17f1bSmrg
84990b17f1bSmrg    /* attr,avalue hardware processing goes here */
85090b17f1bSmrg    (void)attr;
85190b17f1bSmrg    (void)avalue;
85290b17f1bSmrg
85390b17f1bSmrg    return Success;
85490b17f1bSmrg}
85590b17f1bSmrg
85690b17f1bSmrgstatic int
85790b17f1bSmrgviaGetPortAttribute(ScrnInfoPtr pScrn,
85890b17f1bSmrg        Atom attribute, INT32 * value, pointer data)
85990b17f1bSmrg{
86090b17f1bSmrg    viaPortPrivPtr pPriv = (viaPortPrivPtr) data;
86190b17f1bSmrg
86290b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaGetPortAttribute : port %d %ld\n",
86390b17f1bSmrg                    pPriv->xv_portnum, attribute));
86490b17f1bSmrg
86590b17f1bSmrg    *value = 0;
86690b17f1bSmrg    if (attribute == xvColorKey) {
86790b17f1bSmrg        *value = (INT32) pPriv->colorKey;
86890b17f1bSmrg        DBG_DD(ErrorF(" via_xv.c :    ColorKey 0x%lx\n", pPriv->colorKey));
86990b17f1bSmrg    } else if (attribute == xvAutoPaint) {
87090b17f1bSmrg        *value = (INT32) pPriv->autoPaint;
87190b17f1bSmrg        DBG_DD(ErrorF("    AutoPaint = %08ld\n", *value));
87290b17f1bSmrg        /* Color Control */
87390b17f1bSmrg    } else if (attribute == xvBrightness ||
87490b17f1bSmrg            attribute == xvContrast ||
87590b17f1bSmrg            attribute == xvSaturation || attribute == xvHue) {
87690b17f1bSmrg        if (attribute == xvBrightness) {
87790b17f1bSmrg            *value = pPriv->brightness;
87890b17f1bSmrg            DBG_DD(ErrorF("    xvBrightness = %08ld\n", *value));
87990b17f1bSmrg        }
88090b17f1bSmrg        if (attribute == xvContrast) {
88190b17f1bSmrg            *value = pPriv->contrast;
88290b17f1bSmrg            DBG_DD(ErrorF("    xvContrast = %08ld\n", *value));
88390b17f1bSmrg        }
88490b17f1bSmrg        if (attribute == xvSaturation) {
88590b17f1bSmrg            *value = pPriv->saturation;
88690b17f1bSmrg            DBG_DD(ErrorF("    xvSaturation = %08ld\n", *value));
88790b17f1bSmrg        }
88890b17f1bSmrg        if (attribute == xvHue) {
88990b17f1bSmrg            *value = pPriv->hue;
89090b17f1bSmrg            DBG_DD(ErrorF("    xvHue = %08ld\n", *value));
89190b17f1bSmrg        }
89290b17f1bSmrg
89390b17f1bSmrg    } else {
89490b17f1bSmrg        DBG_DD(ErrorF(" via_xv.c : viaGetPortAttribute : is not supported the attribute\n"));
89590b17f1bSmrg        /*return BadMatch */;
89690b17f1bSmrg    }
89790b17f1bSmrg    return Success;
89890b17f1bSmrg}
89990b17f1bSmrg
90090b17f1bSmrgstatic void
90190b17f1bSmrgviaQueryBestSize(ScrnInfoPtr pScrn,
90290b17f1bSmrg    Bool motion,
90390b17f1bSmrg    short vid_w, short vid_h,
90490b17f1bSmrg    short drw_w, short drw_h,
90590b17f1bSmrg    unsigned int *p_w, unsigned int *p_h, pointer data)
90690b17f1bSmrg{
90790b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaQueryBestSize :\n"));
90890b17f1bSmrg    *p_w = drw_w;
90990b17f1bSmrg    *p_h = drw_h;
91090b17f1bSmrg
91190b17f1bSmrg    if (*p_w > 2048)
91290b17f1bSmrg        *p_w = 2048;
91390b17f1bSmrg}
91490b17f1bSmrg
91590b17f1bSmrg/*
91690b17f1bSmrg *  To do SW Flip
91790b17f1bSmrg */
91890b17f1bSmrgstatic void
91990b17f1bSmrgFlip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc,
92090b17f1bSmrg        unsigned long DisplayBufferIndex)
92190b17f1bSmrg{
92290b17f1bSmrg    unsigned long proReg = 0;
92390b17f1bSmrg    unsigned count = 50000;
92490b17f1bSmrg
92590b17f1bSmrg    if (pVia->ChipId == PCI_CHIP_VT3259
92690b17f1bSmrg        && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
92790b17f1bSmrg        proReg = PRO_HQV1_OFFSET;
92890b17f1bSmrg
92990b17f1bSmrg    switch (fourcc) {
93090b17f1bSmrg        case FOURCC_UYVY:
93190b17f1bSmrg        case FOURCC_YUY2:
93290b17f1bSmrg        case FOURCC_RV15:
93390b17f1bSmrg        case FOURCC_RV16:
93490b17f1bSmrg        case FOURCC_RV32:
93590b17f1bSmrg            while ((VIAGETREG(HQV_CONTROL + proReg) & HQV_SW_FLIP)
93690b17f1bSmrg                    && --count);
93790b17f1bSmrg            VIASETREG(HQV_SRC_STARTADDR_Y + proReg,
93890b17f1bSmrg                pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]);
93990b17f1bSmrg            VIASETREG(HQV_CONTROL + proReg, (VIAGETREG(HQV_CONTROL + proReg) & ~HQV_FLIP_ODD) | HQV_SW_FLIP | HQV_FLIP_STATUS);
94090b17f1bSmrg            break;
94190b17f1bSmrg        case FOURCC_YV12:
94290b17f1bSmrg        case FOURCC_I420:
94390b17f1bSmrg        default:
94490b17f1bSmrg            while ((VIAGETREG(HQV_CONTROL + proReg) & HQV_SW_FLIP)
94590b17f1bSmrg                    && --count);
94690b17f1bSmrg            VIASETREG(HQV_SRC_STARTADDR_Y + proReg,
94790b17f1bSmrg                pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]);
94890b17f1bSmrg            if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
94990b17f1bSmrg                VIASETREG(HQV_SRC_STARTADDR_U + proReg,
95090b17f1bSmrg                pVia->swov.SWDevice.dwSWCrPhysicalAddr[DisplayBufferIndex]);
95190b17f1bSmrg            } else {
95290b17f1bSmrg                VIASETREG(HQV_SRC_STARTADDR_U,
95390b17f1bSmrg                    pVia->swov.SWDevice.dwSWCbPhysicalAddr[DisplayBufferIndex]);
95490b17f1bSmrg                VIASETREG(HQV_SRC_STARTADDR_V,
95590b17f1bSmrg                    pVia->swov.SWDevice.dwSWCrPhysicalAddr[DisplayBufferIndex]);
95690b17f1bSmrg            }
95790b17f1bSmrg            VIASETREG(HQV_CONTROL + proReg, (VIAGETREG(HQV_CONTROL + proReg) & ~HQV_FLIP_ODD) | HQV_SW_FLIP | HQV_FLIP_STATUS);
95890b17f1bSmrg	    break;
95990b17f1bSmrg    }
96090b17f1bSmrg}
96190b17f1bSmrg
96290b17f1bSmrgstatic void
96390b17f1bSmrgplanar420cp(unsigned char *dst, const unsigned char *src, int dstPitch,
96490b17f1bSmrg            int w, int h, int i420)
96590b17f1bSmrg{
96690b17f1bSmrg    unsigned long srcUOffset, srcVOffset;
96790b17f1bSmrg
96890b17f1bSmrg    /*
96990b17f1bSmrg     * Blit luma component as a fake YUY2 assembler blit.
97090b17f1bSmrg     */
97190b17f1bSmrg    if (i420) {
97290b17f1bSmrg        srcVOffset  = w * h + (w >> 1) * (h >> 1);
97390b17f1bSmrg        srcUOffset = w * h;
97490b17f1bSmrg    } else {
97590b17f1bSmrg        srcUOffset  = w * h + (w >> 1) * (h >> 1);
97690b17f1bSmrg        srcVOffset = w * h;
97790b17f1bSmrg    }
97890b17f1bSmrg
97990b17f1bSmrg    (*viaFastVidCpy) (dst, src, dstPitch, w >> 1, h, 1);
98090b17f1bSmrg    UVBlit(dst + dstPitch * h, src + srcUOffset,
98190b17f1bSmrg            src + srcVOffset, w >> 1, w >> 1, dstPitch, h >> 1);
98290b17f1bSmrg}
98390b17f1bSmrg
98490b17f1bSmrg/*
98590b17f1bSmrg * Slow and dirty. NV12 blit.
98690b17f1bSmrg */
98790b17f1bSmrgstatic void
98890b17f1bSmrgnv12cp(unsigned char *dst, const unsigned char *src, int dstPitch,
98990b17f1bSmrg        int w, int h, int i420)
99090b17f1bSmrg{
99190b17f1bSmrg    unsigned long srcUOffset, srcVOffset;
99290b17f1bSmrg
99390b17f1bSmrg    /*
99490b17f1bSmrg     * Blit luma component as a fake YUY2 assembler blit.
99590b17f1bSmrg     */
99690b17f1bSmrg    if (i420) {
99790b17f1bSmrg        srcVOffset  = w * h + (w >> 1) * (h >> 1);
99890b17f1bSmrg        srcUOffset = w * h;
99990b17f1bSmrg    } else {
100090b17f1bSmrg        srcUOffset  = w * h + (w >> 1) * (h >> 1);
100190b17f1bSmrg        srcVOffset = w * h;
100290b17f1bSmrg    }
100390b17f1bSmrg
100490b17f1bSmrg    (*viaFastVidCpy) (dst, src, dstPitch, w >> 1, h, TRUE);
100590b17f1bSmrg    nv12Blit(dst + dstPitch * h, src + srcUOffset,
100690b17f1bSmrg            src + srcVOffset, w >> 1, w >>1, dstPitch, h >> 1);
100790b17f1bSmrg}
100890b17f1bSmrg
100990b17f1bSmrg#ifdef HAVE_DRI
101090b17f1bSmrg
101190b17f1bSmrgstatic int
101290b17f1bSmrgviaDmaBlitImage(VIAPtr pVia,
101390b17f1bSmrg    viaPortPrivPtr pPort,
101490b17f1bSmrg    unsigned char *src,
101590b17f1bSmrg    CARD32 dst, unsigned width, unsigned height, unsigned lumaStride, int id)
101690b17f1bSmrg{
101790b17f1bSmrg    Bool bounceBuffer;
101890b17f1bSmrg    drm_via_dmablit_t blit;
101990b17f1bSmrg    drm_via_blitsync_t *chromaSync = &blit.sync;
102090b17f1bSmrg    drm_via_blitsync_t lumaSync;
102190b17f1bSmrg    unsigned char *base;
102290b17f1bSmrg    unsigned char *bounceBase;
102390b17f1bSmrg    unsigned bounceStride;
102490b17f1bSmrg    unsigned bounceLines;
102590b17f1bSmrg    unsigned size;
102690b17f1bSmrg    int err = 0;
102790b17f1bSmrg    Bool nv12Conversion;
102890b17f1bSmrg
102990b17f1bSmrg    bounceBuffer = ((unsigned long)src & 15);
103090b17f1bSmrg    nv12Conversion = (pVia->VideoEngine == VIDEO_ENGINE_CME &&
103190b17f1bSmrg                     (id == FOURCC_YV12 || id == FOURCC_I420));
103290b17f1bSmrg
103390b17f1bSmrg    switch (id) {
103490b17f1bSmrg        case FOURCC_YUY2:
103590b17f1bSmrg        case FOURCC_RV15:
103690b17f1bSmrg        case FOURCC_RV16:
103790b17f1bSmrg            bounceStride = ALIGN_TO(2 * width, 16);
103890b17f1bSmrg            bounceLines = height;
103990b17f1bSmrg            break;
104090b17f1bSmrg        case FOURCC_RV32:
104190b17f1bSmrg            bounceStride = ALIGN_TO(4 * width, 16);
104290b17f1bSmrg            bounceLines = height;
104390b17f1bSmrg            break;
104490b17f1bSmrg
104590b17f1bSmrg        case FOURCC_YV12:
104690b17f1bSmrg        case FOURCC_I420:
104790b17f1bSmrg        default:
104890b17f1bSmrg            bounceStride = ALIGN_TO(width, 16);
104990b17f1bSmrg            bounceLines = height;
105090b17f1bSmrg            break;
105190b17f1bSmrg    }
105290b17f1bSmrg
105390b17f1bSmrg    if (bounceBuffer || nv12Conversion) {
105490b17f1bSmrg        if (!pPort->dmaBounceBuffer ||
105590b17f1bSmrg            pPort->dmaBounceStride != bounceStride ||
105690b17f1bSmrg            pPort->dmaBounceLines != bounceLines) {
105790b17f1bSmrg            if (pPort->dmaBounceBuffer) {
105890b17f1bSmrg                free(pPort->dmaBounceBuffer);
105990b17f1bSmrg                pPort->dmaBounceBuffer = 0;
106090b17f1bSmrg            }
106190b17f1bSmrg            size = bounceStride * bounceLines + 16;
106290b17f1bSmrg            if (id == FOURCC_YV12 || id == FOURCC_I420)
106390b17f1bSmrg                size += ALIGN_TO(bounceStride >> 1, 16) * bounceLines;
106490b17f1bSmrg            pPort->dmaBounceBuffer = (unsigned char *)malloc(size);
106590b17f1bSmrg            pPort->dmaBounceLines = bounceLines;
106690b17f1bSmrg            pPort->dmaBounceStride = bounceStride;
106790b17f1bSmrg        }
106890b17f1bSmrg    }
106990b17f1bSmrg
107090b17f1bSmrg    bounceBase =
107190b17f1bSmrg    (unsigned char *)ALIGN_TO((unsigned long)(pPort->dmaBounceBuffer),
107290b17f1bSmrg        16);
107390b17f1bSmrg    base = (bounceBuffer) ? bounceBase : src;
107490b17f1bSmrg
107590b17f1bSmrg    if (bounceBuffer) {
107690b17f1bSmrg        (*viaFastVidCpy) (base, src, bounceStride, bounceStride >> 1, height,
107790b17f1bSmrg        1);
107890b17f1bSmrg    }
107990b17f1bSmrg
108090b17f1bSmrg    blit.num_lines = height;
108190b17f1bSmrg    blit.line_length = bounceStride;
108290b17f1bSmrg    blit.fb_addr = dst;
108390b17f1bSmrg    blit.fb_stride = lumaStride;
108490b17f1bSmrg    blit.mem_addr = base;
108590b17f1bSmrg    blit.mem_stride = bounceStride;
108690b17f1bSmrg    blit.to_fb = 1;
108790b17f1bSmrg#ifdef XV_DEBUG
108890b17f1bSmrg    ErrorF
108990b17f1bSmrg    ("Addr: 0x%lx, Offset 0x%lx\n Fb_stride: %u, Mem_stride: %u\n width: %u num_lines: %u\n",
109090b17f1bSmrg    (unsigned long)blit.mem_addr, (unsigned long)blit.fb_addr,
109190b17f1bSmrg    (unsigned)blit.fb_stride, (unsigned)blit.mem_stride,
109290b17f1bSmrg    (unsigned)blit.line_length, (unsigned)blit.num_lines);
109390b17f1bSmrg#endif
109490b17f1bSmrg    while (-EAGAIN == (err =
109590b17f1bSmrg        drmCommandWriteRead(pVia->drmmode.fd, DRM_VIA_DMA_BLIT, &blit,
109690b17f1bSmrg        sizeof(blit)))) ;
109790b17f1bSmrg    if (err < 0)
109890b17f1bSmrg        return -1;
109990b17f1bSmrg
110090b17f1bSmrg    lumaSync = blit.sync;
110190b17f1bSmrg
110290b17f1bSmrg    if (id == FOURCC_YV12 || id == FOURCC_I420) {
110390b17f1bSmrg        unsigned tmp = ALIGN_TO(width >> 1, 16);
110490b17f1bSmrg
110590b17f1bSmrg        if (nv12Conversion) {
110690b17f1bSmrg            nv12Blit(bounceBase + bounceStride * height,
110790b17f1bSmrg                src + bounceStride * height + tmp * (height >> 1),
110890b17f1bSmrg                src + bounceStride * height, width >> 1, tmp,
110990b17f1bSmrg                bounceStride, height >> 1);
111090b17f1bSmrg        } else if (bounceBuffer) {
111190b17f1bSmrg            (*viaFastVidCpy) (base + bounceStride * height,
111290b17f1bSmrg                    src + bounceStride * height, tmp, tmp >> 1, height, 1);
111390b17f1bSmrg        }
111490b17f1bSmrg
111590b17f1bSmrg        if (nv12Conversion) {
111690b17f1bSmrg            blit.num_lines = height >> 1;
111790b17f1bSmrg            blit.line_length = bounceStride;
111890b17f1bSmrg            blit.mem_addr = bounceBase + bounceStride * height;
111990b17f1bSmrg            blit.fb_stride = lumaStride;
112090b17f1bSmrg            blit.mem_stride = bounceStride;
112190b17f1bSmrg        } else {
112290b17f1bSmrg            blit.num_lines = height;
112390b17f1bSmrg            blit.line_length = tmp;
112490b17f1bSmrg            blit.mem_addr = base + bounceStride * height;
112590b17f1bSmrg            blit.fb_stride = lumaStride >> 1;
112690b17f1bSmrg            blit.mem_stride = tmp;
112790b17f1bSmrg        }
112890b17f1bSmrg
112990b17f1bSmrg        blit.fb_addr = dst + lumaStride * height;
113090b17f1bSmrg        blit.to_fb = 1;
113190b17f1bSmrg
113290b17f1bSmrg        while (-EAGAIN == (err =
113390b17f1bSmrg            drmCommandWriteRead(pVia->drmmode.fd, DRM_VIA_DMA_BLIT, &blit,
113490b17f1bSmrg                sizeof(blit))));
113590b17f1bSmrg        if (err < 0)
113690b17f1bSmrg            return -1;
113790b17f1bSmrg    }
113890b17f1bSmrg
113990b17f1bSmrg    while (-EAGAIN == (err = drmCommandWrite(pVia->drmmode.fd, DRM_VIA_BLIT_SYNC,
114090b17f1bSmrg        chromaSync, sizeof(*chromaSync)))) ;
114190b17f1bSmrg    if (err < 0)
114290b17f1bSmrg        return -1;
114390b17f1bSmrg
114490b17f1bSmrg    return Success;
114590b17f1bSmrg}
114690b17f1bSmrg
114790b17f1bSmrg#endif
114890b17f1bSmrg
114990b17f1bSmrg
115090b17f1bSmrg/*
115190b17f1bSmrg * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h).
115290b17f1bSmrg * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h).
115390b17f1bSmrg * id is a fourcc code for the format of the video.
115490b17f1bSmrg * buf is the pointer to the source data in system memory.
115590b17f1bSmrg * width and height are the w/h of the source data.
115690b17f1bSmrg * If "sync" is TRUE, then we must be finished with *buf at the point of return
115790b17f1bSmrg * (which we always are).
115890b17f1bSmrg * clipBoxes is the clipping region in screen space.
115990b17f1bSmrg * data is a pointer to our port private.
116090b17f1bSmrg * pDraw is a Drawable, which might not be the screen in the case of
116190b17f1bSmrg * compositing.  It's a new argument to the function in the 1.1 server.
116290b17f1bSmrg */
116390b17f1bSmrg
116490b17f1bSmrgstatic int
116590b17f1bSmrgviaPutImage(ScrnInfoPtr pScrn,
116690b17f1bSmrg        short src_x, short src_y,
116790b17f1bSmrg        short drw_x, short drw_y,
116890b17f1bSmrg        short src_w, short src_h,
116990b17f1bSmrg        short drw_w, short drw_h,
117090b17f1bSmrg        int id, unsigned char *buf,
117190b17f1bSmrg        short width, short height, Bool sync, RegionPtr clipBoxes,
117290b17f1bSmrg        pointer data, DrawablePtr pDraw)
117390b17f1bSmrg{
117490b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
117590b17f1bSmrg    viaPortPrivPtr pPriv = (viaPortPrivPtr) data;
117690b17f1bSmrg    xf86CrtcPtr crtc = NULL;
117790b17f1bSmrg    unsigned long retCode;
117890b17f1bSmrg
117990b17f1bSmrg# ifdef XV_DEBUG
118090b17f1bSmrg    ErrorF(" via_xv.c : viaPutImage : called,  Screen[%d]\n", pScrn->scrnIndex);
118190b17f1bSmrg    ErrorF(" via_xv.c : FourCC=0x%x width=%d height=%d sync=%d\n", id,
118290b17f1bSmrg            width, height, sync);
118390b17f1bSmrg    ErrorF
118490b17f1bSmrg    (" via_xv.c : src_x=%d src_y=%d src_w=%d src_h=%d colorkey=0x%lx\n",
118590b17f1bSmrg            src_x, src_y, src_w, src_h, pPriv->colorKey);
118690b17f1bSmrg    ErrorF(" via_xv.c : drw_x=%d drw_y=%d drw_w=%d drw_h=%d\n", drw_x,
118790b17f1bSmrg            drw_y, drw_w, drw_h);
118890b17f1bSmrg# endif
118990b17f1bSmrg
119090b17f1bSmrg    /* Find out which CRTC the surface will belong to */
119190b17f1bSmrg    crtc = window_belongs_to_crtc(pScrn, drw_x, drw_y, drw_w, drw_h);
119290b17f1bSmrg    if (!crtc) {
119390b17f1bSmrg        DBG_DD(ErrorF(" via_xv.c : No usable CRTC\n"));
119490b17f1bSmrg        viaXvError(pScrn, pPriv, xve_adaptor);
119590b17f1bSmrg        return BadAlloc;
119690b17f1bSmrg    }
119790b17f1bSmrg
119890b17f1bSmrg    switch (pPriv->xv_adaptor) {
119990b17f1bSmrg        case XV_ADAPT_SWOV:
120090b17f1bSmrg        {
120190b17f1bSmrg            DDUPDATEOVERLAY UpdateOverlay_Video;
120290b17f1bSmrg            LPDDUPDATEOVERLAY lpUpdateOverlay = &UpdateOverlay_Video;
120390b17f1bSmrg
120490b17f1bSmrg            int dstPitch;
120590b17f1bSmrg            unsigned long dwUseExtendedFIFO = 0;
120690b17f1bSmrg
120790b17f1bSmrg            DBG_DD(ErrorF(" via_xv.c :              : S/W Overlay! \n"));
120890b17f1bSmrg            /*  Allocate video memory(CreateSurface),
120990b17f1bSmrg             *  add codes to judge if need to re-create surface
121090b17f1bSmrg             */
121190b17f1bSmrg            if ((pPriv->old_src_w != src_w) || (pPriv->old_src_h != src_h)) {
121290b17f1bSmrg                ViaSwovSurfaceDestroy(pScrn, pPriv);
121390b17f1bSmrg            }
121490b17f1bSmrg
121590b17f1bSmrg            if (Success != (retCode =
121690b17f1bSmrg                ViaSwovSurfaceCreate(pScrn, pPriv, id, width, height))) {
121790b17f1bSmrg                DBG_DD(ErrorF
121890b17f1bSmrg                        ("             : Fail to Create SW Video Surface\n"));
121990b17f1bSmrg                viaXvError(pScrn, pPriv, xve_mem);
122090b17f1bSmrg                return retCode;
122190b17f1bSmrg            }
122290b17f1bSmrg
122390b17f1bSmrg            /*  Copy image data from system memory to video memory
122490b17f1bSmrg             *  TODO: use DRM's DMA feature to accelerate data copy
122590b17f1bSmrg             */
122690b17f1bSmrg            if (id != FOURCC_XVMC) {
122790b17f1bSmrg                dstPitch = pVia->swov.SWDevice.dwPitch;
122890b17f1bSmrg
122990b17f1bSmrg                if (pVia->useDmaBlit) {
123090b17f1bSmrg#ifdef HAVE_DRI
123190b17f1bSmrg                    if (viaDmaBlitImage(pVia, pPriv, buf,
123290b17f1bSmrg                        (CARD32) pVia->swov.SWDevice.dwSWPhysicalAddr[pVia->dwFrameNum & 1],
123390b17f1bSmrg                        width, height, dstPitch, id)) {
123490b17f1bSmrg                            viaXvError(pScrn, pPriv, xve_dmablit);
123590b17f1bSmrg                        return BadAccess;
123690b17f1bSmrg                    }
123790b17f1bSmrg#endif
123890b17f1bSmrg                } else {
123990b17f1bSmrg                    switch (id) {
124090b17f1bSmrg                        case FOURCC_I420:
124190b17f1bSmrg                            if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
124290b17f1bSmrg                                nv12cp(pVia->swov.SWDevice.
124390b17f1bSmrg                                    lpSWOverlaySurface[pVia->dwFrameNum & 1],
124490b17f1bSmrg                                    buf, dstPitch, width, height, 1);
124590b17f1bSmrg                            } else {
124690b17f1bSmrg                                (*viaFastVidCpy)(pVia->swov.SWDevice.
124790b17f1bSmrg                                    lpSWOverlaySurface[pVia->dwFrameNum & 1],
124890b17f1bSmrg                                    buf, dstPitch, width, height, 0);
124990b17f1bSmrg                            }
125090b17f1bSmrg                            break;
125190b17f1bSmrg                        case FOURCC_YV12:
125290b17f1bSmrg                            if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
125390b17f1bSmrg                                nv12cp(pVia->swov.SWDevice.
125490b17f1bSmrg                                    lpSWOverlaySurface[pVia->dwFrameNum & 1],
125590b17f1bSmrg                                    buf, dstPitch, width, height, 0);
125690b17f1bSmrg                            } else {
125790b17f1bSmrg                                (*viaFastVidCpy)(pVia->swov.SWDevice.
125890b17f1bSmrg                                    lpSWOverlaySurface[pVia->dwFrameNum & 1],
125990b17f1bSmrg                                    buf, dstPitch, width, height, 0);
126090b17f1bSmrg                            }
126190b17f1bSmrg                            break;
126290b17f1bSmrg                        case FOURCC_RV32:
126390b17f1bSmrg                            (*viaFastVidCpy) (pVia->swov.SWDevice.
126490b17f1bSmrg                                lpSWOverlaySurface[pVia->dwFrameNum & 1],
126590b17f1bSmrg                                buf, dstPitch, width << 1, height, 1);
126690b17f1bSmrg                            break;
126790b17f1bSmrg                        case FOURCC_UYVY:
126890b17f1bSmrg                        case FOURCC_YUY2:
126990b17f1bSmrg                        case FOURCC_RV15:
127090b17f1bSmrg                        case FOURCC_RV16:
127190b17f1bSmrg                        default:
127290b17f1bSmrg                            (*viaFastVidCpy) (pVia->swov.SWDevice.
127390b17f1bSmrg                                lpSWOverlaySurface[pVia->dwFrameNum & 1],
127490b17f1bSmrg                                buf, dstPitch, width, height, 1);
127590b17f1bSmrg                            break;
127690b17f1bSmrg                    }
127790b17f1bSmrg                }
127890b17f1bSmrg            }
127990b17f1bSmrg
128090b17f1bSmrg            /* If there is bandwidth issue, block the H/W overlay */
128190b17f1bSmrg            if (!(DecideOverlaySupport(crtc))) {
128290b17f1bSmrg                DBG_DD(ErrorF
128390b17f1bSmrg                        (" via_xv.c : Xv Overlay rejected due to insufficient "
128490b17f1bSmrg                                "memory bandwidth.\n"));
128590b17f1bSmrg                viaXvError(pScrn, pPriv, xve_bandwidth);
128690b17f1bSmrg                return BadAlloc;
128790b17f1bSmrg            }
128890b17f1bSmrg
128990b17f1bSmrg            /*
129090b17f1bSmrg             *  fill video overlay parameter
129190b17f1bSmrg             */
129290b17f1bSmrg            lpUpdateOverlay->SrcLeft = src_x;
129390b17f1bSmrg            lpUpdateOverlay->SrcTop = src_y;
129490b17f1bSmrg            lpUpdateOverlay->SrcRight = src_x + src_w;
129590b17f1bSmrg            lpUpdateOverlay->SrcBottom = src_y + src_h;
129690b17f1bSmrg
129790b17f1bSmrg            lpUpdateOverlay->DstLeft = drw_x;
129890b17f1bSmrg            lpUpdateOverlay->DstTop = drw_y;
129990b17f1bSmrg            lpUpdateOverlay->DstRight = drw_x + drw_w;
130090b17f1bSmrg            lpUpdateOverlay->DstBottom = drw_y + drw_h;
130190b17f1bSmrg
130290b17f1bSmrg            lpUpdateOverlay->dwFlags = DDOVER_KEYDEST;
130390b17f1bSmrg
130490b17f1bSmrg            if (pScrn->bitsPerPixel == 8) {
130590b17f1bSmrg                lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey & 0xff;
130690b17f1bSmrg            } else {
130790b17f1bSmrg                lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey;
130890b17f1bSmrg            }
130990b17f1bSmrg            /* If use extend FIFO mode */
131090b17f1bSmrg            if (pScrn->currentMode->HDisplay > 1024) {
131190b17f1bSmrg                dwUseExtendedFIFO = 1;
131290b17f1bSmrg            }
131390b17f1bSmrg
131490b17f1bSmrg            if (FOURCC_XVMC != id) {
131590b17f1bSmrg
131690b17f1bSmrg                /*
131790b17f1bSmrg                 * XvMC flipping is done in the client lib.
131890b17f1bSmrg                 */
131990b17f1bSmrg
132090b17f1bSmrg                DBG_DD(ErrorF("             : Flip\n"));
132190b17f1bSmrg                Flip(pVia, pPriv, id, pVia->dwFrameNum & 1);
132290b17f1bSmrg            }
132390b17f1bSmrg
132490b17f1bSmrg            pVia->dwFrameNum++;
132590b17f1bSmrg
132690b17f1bSmrg            /* If the dest rec. & extendFIFO doesn't change, don't do UpdateOverlay
132790b17f1bSmrg             * unless the surface clipping has changed */
132890b17f1bSmrg            if ((pPriv->old_drw_x == drw_x) && (pPriv->old_drw_y == drw_y)
132990b17f1bSmrg                    && (pPriv->old_drw_w == drw_w) && (pPriv->old_drw_h == drw_h)
133090b17f1bSmrg                    && (pPriv->old_src_x == src_x) && (pPriv->old_src_y == src_y)
133190b17f1bSmrg                    && (pPriv->old_src_w == src_w) && (pPriv->old_src_h == src_h)
133290b17f1bSmrg                    && (pVia->old_dwUseExtendedFIFO == dwUseExtendedFIFO)
133390b17f1bSmrg                    && (pVia->VideoStatus & VIDEO_SWOV_ON) &&
133490b17f1bSmrg                    REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
133590b17f1bSmrg                DBG_DD(ErrorF(" via_xv.c : don't do UpdateOverlay! \n"));
133690b17f1bSmrg                viaXvError(pScrn, pPriv, xve_none);
133790b17f1bSmrg                return Success;
133890b17f1bSmrg            }
133990b17f1bSmrg
134090b17f1bSmrg            pPriv->old_src_x = src_x;
134190b17f1bSmrg            pPriv->old_src_y = src_y;
134290b17f1bSmrg            pPriv->old_src_w = src_w;
134390b17f1bSmrg            pPriv->old_src_h = src_h;
134490b17f1bSmrg
134590b17f1bSmrg            pPriv->old_drw_x = drw_x;
134690b17f1bSmrg            pPriv->old_drw_y = drw_y;
134790b17f1bSmrg            pPriv->old_drw_w = drw_w;
134890b17f1bSmrg            pPriv->old_drw_h = drw_h;
134990b17f1bSmrg            pVia->old_dwUseExtendedFIFO = dwUseExtendedFIFO;
135090b17f1bSmrg            pVia->VideoStatus |= VIDEO_SWOV_ON;
135190b17f1bSmrg
135290b17f1bSmrg            /*  BitBlt: Draw the colorkey rectangle */
135390b17f1bSmrg            if (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
135490b17f1bSmrg                REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
135590b17f1bSmrg                if (pPriv->autoPaint) {
135690b17f1bSmrg                    if (pDraw->type == DRAWABLE_WINDOW) {
135790b17f1bSmrg                        xf86XVFillKeyHelperDrawable(pDraw, pPriv->colorKey, clipBoxes);
135890b17f1bSmrg                        DamageDamageRegion(pDraw, clipBoxes);
135990b17f1bSmrg                    } else {
136090b17f1bSmrg                        xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
136190b17f1bSmrg                    }
136290b17f1bSmrg                }
136390b17f1bSmrg            } else {
136490b17f1bSmrg                DBG_DD(ErrorF(" via_xv.c : // No need to draw Colorkey!! \n"));
136590b17f1bSmrg            }
136690b17f1bSmrg            /*
136790b17f1bSmrg             *  Update video overlay
136890b17f1bSmrg             */
136990b17f1bSmrg            if (!VIAVidUpdateOverlay(crtc, lpUpdateOverlay)) {
137090b17f1bSmrg                DBG_DD(ErrorF
137190b17f1bSmrg                        (" via_xv.c : call v4l updateoverlay fail. \n"));
137290b17f1bSmrg            } else {
137390b17f1bSmrg                DBG_DD(ErrorF(" via_xv.c : PutImage done OK\n"));
137490b17f1bSmrg                viaXvError(pScrn, pPriv, xve_none);
137590b17f1bSmrg                return Success;
137690b17f1bSmrg            }
137790b17f1bSmrg            break;
137890b17f1bSmrg        }
137990b17f1bSmrg        default:
138090b17f1bSmrg            DBG_DD(ErrorF(" via_xv.c : XVPort not supported\n"));
138190b17f1bSmrg            viaXvError(pScrn, pPriv, xve_adaptor);
138290b17f1bSmrg            break;
138390b17f1bSmrg    }
138490b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : PutImage done OK\n"));
138590b17f1bSmrg    viaXvError(pScrn, pPriv, xve_none);
138690b17f1bSmrg    return Success;
138790b17f1bSmrg}
138890b17f1bSmrg
138990b17f1bSmrgstatic int
139090b17f1bSmrgviaQueryImageAttributes(ScrnInfoPtr pScrn,
139190b17f1bSmrg        int id, unsigned short *w, unsigned short *h, int *pitches,
139290b17f1bSmrg        int *offsets)
139390b17f1bSmrg{
139490b17f1bSmrg    int size, tmp;
139590b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
139690b17f1bSmrg
139790b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : viaQueryImageAttributes : FourCC=0x%x, ",
139890b17f1bSmrg            id));
139990b17f1bSmrg    DBG_DD(ErrorF(" via_xv.c : Screen[%d],  w=%d, h=%d\n", pScrn->scrnIndex, *w, *h));
140090b17f1bSmrg
140190b17f1bSmrg    if ((!w) || (!h))
140290b17f1bSmrg        return 0;
140390b17f1bSmrg
140490b17f1bSmrg    if (*w > VIA_MAX_XVIMAGE_X)
140590b17f1bSmrg        *w = VIA_MAX_XVIMAGE_X;
140690b17f1bSmrg    if (*h > VIA_MAX_XVIMAGE_Y)
140790b17f1bSmrg        *h = VIA_MAX_XVIMAGE_Y;
140890b17f1bSmrg
140990b17f1bSmrg    *w = (*w + 1) & ~1;
141090b17f1bSmrg    if (offsets)
141190b17f1bSmrg        offsets[0] = 0;
141290b17f1bSmrg
141390b17f1bSmrg    switch (id) {
141490b17f1bSmrg        case FOURCC_I420:
141590b17f1bSmrg        case FOURCC_YV12: /*Planar format : YV12 -4:2:0 */
141690b17f1bSmrg            *h = (*h + 1) & ~1;
141790b17f1bSmrg            size = *w;
141890b17f1bSmrg            if (pVia->useDmaBlit)
141990b17f1bSmrg                size = (size + 15) & ~15;
142090b17f1bSmrg            if (pitches)
142190b17f1bSmrg                pitches[0] = size;
142290b17f1bSmrg            size *= *h;
142390b17f1bSmrg            if (offsets)
142490b17f1bSmrg                offsets[1] = size;
142590b17f1bSmrg            tmp = (*w >> 1);
142690b17f1bSmrg            if (pVia->useDmaBlit)
142790b17f1bSmrg                tmp = (tmp + 15) & ~15;
142890b17f1bSmrg            if (pitches)
142990b17f1bSmrg                pitches[1] = pitches[2] = tmp;
143090b17f1bSmrg            tmp *= (*h >> 1);
143190b17f1bSmrg            size += tmp;
143290b17f1bSmrg            if (offsets)
143390b17f1bSmrg                offsets[2] = size;
143490b17f1bSmrg            size += tmp;
143590b17f1bSmrg            break;
143690b17f1bSmrg        case FOURCC_XVMC:
143790b17f1bSmrg            *h = (*h + 1) & ~1;
143890b17f1bSmrg#ifdef HAVE_DRI
143990b17f1bSmrg            size = viaXvMCPutImageSize(pScrn);
144090b17f1bSmrg#else
144190b17f1bSmrg            size = 0;
144290b17f1bSmrg#endif
144390b17f1bSmrg            if (pitches)
144490b17f1bSmrg                pitches[0] = size;
144590b17f1bSmrg            break;
144690b17f1bSmrg        case FOURCC_AI44:
144790b17f1bSmrg        case FOURCC_IA44:
144890b17f1bSmrg            size = *w * *h;
144990b17f1bSmrg            if (pitches)
145090b17f1bSmrg                pitches[0] = *w;
145190b17f1bSmrg            if (offsets)
145290b17f1bSmrg                offsets[0] = 0;
145390b17f1bSmrg            break;
145490b17f1bSmrg        case FOURCC_RV32:
145590b17f1bSmrg            size = *w << 2;
145690b17f1bSmrg            if (pVia->useDmaBlit)
145790b17f1bSmrg                size = (size + 15) & ~15;
145890b17f1bSmrg            if (pitches)
145990b17f1bSmrg                pitches[0] = size;
146090b17f1bSmrg            size *= *h;
146190b17f1bSmrg            break;
146290b17f1bSmrg        case FOURCC_UYVY: /*Packed format : UYVY -4:2:2 */
146390b17f1bSmrg        case FOURCC_YUY2: /*Packed format : YUY2 -4:2:2 */
146490b17f1bSmrg        case FOURCC_RV15:
146590b17f1bSmrg        case FOURCC_RV16:
146690b17f1bSmrg        default:
146790b17f1bSmrg            size = *w << 1;
146890b17f1bSmrg            if (pVia->useDmaBlit)
146990b17f1bSmrg                size = (size + 15) & ~15;
147090b17f1bSmrg            if (pitches)
147190b17f1bSmrg                pitches[0] = size;
147290b17f1bSmrg            size *= *h;
147390b17f1bSmrg        break;
147490b17f1bSmrg    }
147590b17f1bSmrg
147690b17f1bSmrg    if (pitches)
147790b17f1bSmrg        DBG_DD(ErrorF(" pitches[0]=%d, pitches[1]=%d, pitches[2]=%d, ",
147890b17f1bSmrg                    pitches[0], pitches[1], pitches[2]));
147990b17f1bSmrg    if (offsets)
148090b17f1bSmrg        DBG_DD(ErrorF(" offsets[0]=%d, offsets[1]=%d, offsets[2]=%d, ",
148190b17f1bSmrg                    offsets[0], offsets[1], offsets[2]));
148290b17f1bSmrg
148390b17f1bSmrg    DBG_DD(ErrorF(" width=%d, height=%d \n", *w, *h));
148490b17f1bSmrg    return size;
148590b17f1bSmrg}
148690b17f1bSmrg
148790b17f1bSmrg/*
148890b17f1bSmrg *
148990b17f1bSmrg */
149090b17f1bSmrgvoid
149190b17f1bSmrgVIAVidAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
149290b17f1bSmrg{
149390b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
149490b17f1bSmrg
149590b17f1bSmrg    pVia->swov.panning_x = x;
149690b17f1bSmrg    pVia->swov.panning_y = y;
149790b17f1bSmrg}
149890b17f1bSmrg
149990b17f1bSmrg/*
150090b17f1bSmrg * Blit the U and V Fields. Used to Flip the U V for I420.
150190b17f1bSmrg */
150290b17f1bSmrg
150390b17f1bSmrgstatic void
150490b17f1bSmrgUVBlit(unsigned char *dst,
150590b17f1bSmrg        const unsigned char *uBuffer,
150690b17f1bSmrg        const unsigned char *vBuffer,
150790b17f1bSmrg        unsigned width, unsigned srcPitch, unsigned dstPitch, unsigned lines)
150890b17f1bSmrg{
150990b17f1bSmrg    int i, j;
151090b17f1bSmrg
151190b17f1bSmrg    dstPitch >>= 1;
151290b17f1bSmrg
151390b17f1bSmrg    for(j = 0; j < lines; j++)
151490b17f1bSmrg    {
151590b17f1bSmrg        for(i = 0; i < width; i++)
151690b17f1bSmrg        {
151790b17f1bSmrg            dst[i] = (uBuffer[i] << 8) | (vBuffer[i] << 16);
151890b17f1bSmrg        }
151990b17f1bSmrg
152090b17f1bSmrg        dst += dstPitch;
152190b17f1bSmrg        uBuffer += srcPitch;
152290b17f1bSmrg        vBuffer += srcPitch;
152390b17f1bSmrg    }
152490b17f1bSmrg
152590b17f1bSmrg}
152690b17f1bSmrg
152790b17f1bSmrg
152890b17f1bSmrg/*
152990b17f1bSmrg * Blit the chroma field from one buffer to another while at the same time converting from
153090b17f1bSmrg * YV12 to NV12.
153190b17f1bSmrg */
153290b17f1bSmrg
153390b17f1bSmrgstatic void
153490b17f1bSmrgnv12Blit(unsigned char *nv12Chroma,
153590b17f1bSmrg        const unsigned char *uBuffer,
153690b17f1bSmrg        const unsigned char *vBuffer,
153790b17f1bSmrg        unsigned width, unsigned srcPitch, unsigned dstPitch, unsigned lines)
153890b17f1bSmrg{
153990b17f1bSmrg    int x;
154090b17f1bSmrg    int dstAdd;
154190b17f1bSmrg    int srcAdd;
154290b17f1bSmrg
154390b17f1bSmrg    dstAdd = dstPitch - (width << 1);
154490b17f1bSmrg    srcAdd = srcPitch - width;
154590b17f1bSmrg
154690b17f1bSmrg    while (lines--) {
154790b17f1bSmrg        x = width;
154890b17f1bSmrg        while (x > 3) {
154990b17f1bSmrg            register CARD32
155090b17f1bSmrg            dst32,
155190b17f1bSmrg            src32 = *((CARD32 *) vBuffer),
155290b17f1bSmrg            src32_2 = *((CARD32 *) uBuffer);
155390b17f1bSmrg            dst32 =
155490b17f1bSmrg                (src32_2 & 0xff) | ((src32 & 0xff) << 8) |
155590b17f1bSmrg                ((src32_2 & 0x0000ff00) << 8) | ((src32 & 0x0000ff00) << 16);
155690b17f1bSmrg            *((CARD32 *) nv12Chroma) = dst32;
155790b17f1bSmrg            nv12Chroma += 4;
155890b17f1bSmrg            dst32 =
155990b17f1bSmrg                ((src32_2 & 0x00ff0000) >> 16) | ((src32 & 0x00ff0000) >> 8) |
156090b17f1bSmrg                ((src32_2 & 0xff000000) >> 8) | (src32 & 0xff000000);
156190b17f1bSmrg            *((CARD32 *) nv12Chroma) = dst32;
156290b17f1bSmrg            nv12Chroma += 4;
156390b17f1bSmrg            x -= 4;
156490b17f1bSmrg            vBuffer += 4;
156590b17f1bSmrg            uBuffer += 4;
156690b17f1bSmrg        }
156790b17f1bSmrg        while (x--) {
156890b17f1bSmrg            *nv12Chroma++ = *uBuffer++;
156990b17f1bSmrg            *nv12Chroma++ = *vBuffer++;
157090b17f1bSmrg        }
157190b17f1bSmrg        nv12Chroma += dstAdd;
157290b17f1bSmrg        vBuffer += srcAdd;
157390b17f1bSmrg        uBuffer += srcAdd;
157490b17f1bSmrg    }
157590b17f1bSmrg}
157690b17f1bSmrg
157790b17f1bSmrg#endif /* !XvExtension */
1578