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