diff options
author | thomash <thomash> | 2006-03-08 13:50:10 +0000 |
---|---|---|
committer | thomash <thomash> | 2006-03-08 13:50:10 +0000 |
commit | 2bac8f3b563b6cd739770d7d7f3a3ea350dad5eb (patch) | |
tree | c107f08c10a7b4d32916072644593d9fdb6acc42 | |
parent | ef0a34f6a7d0a6d1fee2a8ca9142374d12dfd8d8 (diff) |
Sync Xv and man with openchrome revision 166.
Xv RV32 support (Ivor Hewitt). Xv VM800 support (Ivor Hewitt). Not enabled
yet pending more testing. A number of Xv Unichrome Pro Group A
bugfixes. Xv PCI DMAblit support. Fix DMAblit DRM version check. Update
manpage.
-rw-r--r-- | ChangeLog | 34 | ||||
-rw-r--r-- | man/via.man | 67 | ||||
-rw-r--r-- | src/via.h | 2 | ||||
-rw-r--r-- | src/via_accel.c | 10 | ||||
-rw-r--r-- | src/via_driver.c | 12 | ||||
-rw-r--r-- | src/via_driver.h | 2 | ||||
-rw-r--r-- | src/via_id.h | 2 | ||||
-rw-r--r-- | src/via_priv.h | 1 | ||||
-rw-r--r-- | src/via_swov.c | 284 | ||||
-rw-r--r-- | src/via_video.c | 419 | ||||
-rw-r--r-- | src/via_video.h | 1 | ||||
-rw-r--r-- | src/via_xvmc.c | 38 | ||||
-rw-r--r-- | src/via_xvpriv.h | 20 |
13 files changed, 659 insertions, 233 deletions
@@ -1,3 +1,37 @@ +2006-03-08 Thomas Hellstrom <thomas-at-tungstengraphics.com> + + * man/via.man: + * src/via.h: + * src/via_accel.c: (viaExaDownloadFromScreen), + (viaExaUploadToScreen): + * src/via_driver.c: (VIAPreInit): + * src/via_driver.h: + * src/via_id.h: + * src/via_priv.h: + * src/via_swov.c: (viaWaitVideoCommandFire), (VIAVidHWDiffInit), + (viaOverlayGetV1V3Format), (viaOverlayGetSrcStartAddress), + (viaOverlayGetFetch), (viaCalculateVideoColor), (viaSetColorSpace), + (ViaInitVideoStatusFlag), (ViaSetVidCtl), (CreateSurface), + (ViaSwovSurfaceCreate), (ViaSwovSurfaceDestroy), (SetFIFO_V3), + (SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16), (SetColorKey), + (SetChromaKey), (SetHQVFetch), (Upd_Video), (VIAVidUpdateOverlay), + (ViaOverlayHide): + * src/via_video.c: (DecideOverlaySupport), (viaXvError), + (viaInitVideo), (viaReputImage), (viaSetupAdaptors), + (viaStopVideo), (Flip), (nv12cp), (viaDmaBlitImage), (viaPutImage), + (viaQueryImageAttributes), (nv12Blit): + * src/via_video.h: + * src/via_xvmc.c: (ViaInitXVMC), (ViaXvMCCreateContext): + * src/via_xvpriv.h: + Sync Xv and man with openchrome revision 166. + + Xv RV32 support (Ivor Hewitt). + Xv VM800 support (Ivor Hewitt). Not enabled yet pending more testing. + A number of Xv Unichrome Pro Group A bugfixes. + Xv PCI DMAblit support. + Fix DMAblit DRM version check. + Update manpage. + 2006-02-27 Thomas Hellstrom <thomas-at-tungstengraphics.com> * configure.ac: diff --git a/man/via.man b/man/via.man index a0794d4..9d3337d 100644 --- a/man/via.man +++ b/man/via.man @@ -17,19 +17,29 @@ is an __xservername__ driver for VIA chipsets with onboard unichrome graphics. .PP The .B via -driver supports the VIA CLE266, KM400/KN400 chipsets, including 2D -acceleration and the Xv video overlay extensions. Flat panel, TV and VGA -outputs are supported. -.PP -K8M800/K8N800, PM8X0 and CN400 support is still under development. +driver supports the VIA CLE266, KM400/KN400, K8M/N800, PM/N800 and +CN400 chipsets, including 2D acceleration and the Xv video overlay +extensions. Flat panel, TV and VGA outputs are supported, depending on +the hardware configuration. .PP Direct rendering 3D is available using experimental drivers in Mesa, www.mesa3d.org. Also there is an XvMC client library for hardware MPEG1 / MPEG2 decoding -acceleration available on the CLE266 and K8M/N800 chipsets that uses the Direct +acceleration available on the CLE266, CN400, PM/N800 and K8M/N800 chipsets that uses the Direct Rendering Infrastructure, DRI. The XvMC client library implements a nonstandard \*qVLD\*q extension to the XvMC standard. The current Direct Rendering Manager -Linux kernel module is available -at dri.sourceforge.net. +Linux kernel module is available at dri.sourceforge.net. +.PP +The driver supports free modes for Unichome Pro chipsets. (K8M/N800, +PM/N800 and CN400). Currently for Unichrome chipsets, it only supports +a limited number of dotclocks, so if you are using X modelines, you +must make sure that the dotclock is one of those supported. Supported +dotclocks on Unichromes are currently (MHz): 25.2, 25.312, 26.591, +31.5, 31.704, 32.663, 33.750, 35.5, 36.0, 39.822, 40.0, 41.164, +46.981, 49.5, 50.0, 56.3, 57.284, 64.995, 65.0, 65.028, 74.480, +75.0, 78.8, 81.613, 94.5, 108.0, 108.28, 122.0, 122.726, 135.0, +148.5, 155.8, 157.5, 161.793, 162.0, 175.5, 189.0, 202.5, 204.8, +218.3, 229.5. On top of this, bandwidth restrictions apply both for +Unichromes and Unichrome Pros. .PP .SH CONFIGURATION DETAILS Please refer to __xconfigfile__(__filemansuffix__) for general configuration @@ -100,19 +110,39 @@ Disable or enable the use of VQ. VQ is enabled by default. .BI "Option \*qDRIXINERAMA\*q \*q" boolean \*q Set DRI Xinerama mode. Currently unsupported. .TP +.BI "Option \*qDisableIRQ\*q \*q" boolean \*q +Disables Vblank IRQ. A workaround for some mainboards that have +problems with IRQs from the unichrome chip. With IRQ disabled, +DRI clients have no way to sync drawing to Vblank. +.TP .BI "Option \*qEnableAGPDMA\*q \*q" boolean \*q Enable the AGP DMA functionality in DRM. This requires that DRI is enabled -and will force 2D acceleration to use AGP DMA. The XvMC DRI client will also -make use of this to consume much less CPU. +and will force 2D, and 3D acceleration to use AGP DMA. The XvMC DRI client will also +make use of this on the CLE266 to consume much less CPU. .TP .BI "Option \*qNoAGPFor2D\*q \*q" boolean \*q With this option on, 2D acceleration will not use AGP DMA even if it is enabled. .TP -.BI "Option \*qVBEModes\*q \*q" boolean \*q -The driver will set modes using BIOS similar to the way the vesa driver does. This -is the default behaviour for Unichrome Pro in panel mode, which is otherwise not -supported. Use this option only when the driver does not support your particular -hardware. +.BI "Option \*qNoXVDMA\*q \*q" boolean \*q +If DRI is enabled, Xv normally uses PCI DMA to transfer video images +from system to frame-buffer memory. This is somewhat slower than +direct copies due to the limitations of the PCI bus, but +on the other hand it decreases CPU usage significantly. Particularly +on computers with fast processors. Some video players are buggy and +will display rendering artifacts when PCI DMA is used. If you +experience this, or don't want your PCI bus to be stressed +with Xv images, set this option to "true". This option has no effect +if DRI is not enabled. +.TP +.BI "Option \*qAccelMethod\*q \*q" string \*q +The driver supports \*qXAA\*q and \*qEXA\*q acceleration methods. The default method is +XAA, since EXA is still experimental. Contrary to XAA. EXA implements acceleration for +screen uploads and downlads (if DRI is enabled) and the Render / Composite extension. +.TP +.BI "Option \*qEXANoComposite\*q \*q" boolean \*q +If Exa is enabled using the above option, Don't accelerate composite. Since EXA, and in +particular, it's composite acceleration is still experimental, This is a way to disable +exa composite acceleration. .SH "Supported TV Encoders" Unichromes tend to be paired with several different TV Encoders. @@ -129,14 +159,11 @@ Supports the following modes: \*q640x480\*q, \*q800x600\*q, \*q1024x768\*q, \*q848x480\*q, \*q720x480\*q (NTSC only) and \*q720x576\*q (PAL only). Use \*q640x480Over\*q, \*q800x600Over\*q, \*q1024x768Over\*q, \*q848x480Over\*q, \*q720x480Over\*q (NTSC) and \*q720x576Over\*q (PAL) for vertical overscan. -The modes \*q720x480Noscale\*q (NTSC VT1622 only) and \*q720x576Noscale\*q -(PAL VT1622 and VT1622a only) provide cleaner TV output (unscaled with only minimal overscan). +The modes \*q720x480Noscale\*q (NTSC) and \*q720x576Noscale\*q (PAL) +(VT1622 only) provide cleaner TV output (unscaled with only minimal overscan). These modes are made available by the driver and modelines provided in __xconfigfile__ will be ignored. -.SH "BUGS" -The driver is not fully 64 bit clean. In particular, 3D acceleration, XvMC and VBEModes do not -work properly in 64-bit mode. .SH "SEE ALSO" __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) .SH AUTHORS @@ -334,6 +334,7 @@ #define V3_FIFO_PRETHRESHOLD56 0x00000038 #define V3_FIFO_PRETHRESHOLD61 0x0000003D #define V3_FIFO_MASK 0x0000007F +#define V3_FIFO_MASK_3314 0x000000FF #define ALPHA_FIFO_DEPTH8 0x00070000 #define ALPHA_FIFO_THRESHOLD4 0x04000000 #define ALPHA_FIFO_MASK 0xffff0000 @@ -483,6 +484,7 @@ #define HQV_TRIPLE_BUFF 0x04000000 #define HQV_SUBPIC_FLIP 0x00008000 #define HQV_FIFO_STATUS 0x00001000 +#define HQV_FIFO_DEPTH_1 0x00010000 /* HQV_FILTER_CONTROL 0x3E4 */ #define HQV_H_LOWPASS_2TAP 0x00000001 diff --git a/src/via_accel.c b/src/via_accel.c index 0960746..e535cb0 100644 --- a/src/via_accel.c +++ b/src/via_accel.c @@ -1559,8 +1559,10 @@ viaExaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, ((useBounceBuffer) ? bounceAligned + VIA_DMA_DL_SIZE * buf : dst); curBlit->mem_stride = (useBounceBuffer) ? bouncePitch : dst_pitch; curBlit->to_fb = 0; -#if (VIA_DRM_VERSION >= ((2 << 16) | 9)) +#if (VIA_DRM_DRIVER_VERSION >= ((2 << 16) | 9)) curBlit->flags = 0; +#else + curBlit->bounce_buffer = 0; #endif while (-EAGAIN == (err = @@ -1774,8 +1776,10 @@ viaExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, blit.mem_addr = (unsigned char *) src; blit.mem_stride = src_pitch; blit.to_fb = 1; -#if (VIA_DRM_VERSION >= ((2 << 16) | 9)) - blit.flags = 0; +#if (VIA_DRM_DRIVER_VERSION >= ((2 << 16) | 9)) + blit.flags = 0; +#else + blit.bounce_buffer = 0; #endif exaWaitSync(pScrn->pScreen); diff --git a/src/via_driver.c b/src/via_driver.c index 90bee5c..d7b76de 100644 --- a/src/via_driver.c +++ b/src/via_driver.c @@ -147,6 +147,7 @@ typedef enum { OPTION_TVDEFLICKER, OPTION_AGP_DMA, OPTION_2D_DMA, + OPTION_XV_DMA, OPTION_EXA_NOCOMPOSITE } VIAOpts; @@ -183,6 +184,7 @@ static OptionInfoRec VIAOptions[] = {OPTION_DISABLEIRQ, "DisableIRQ", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_AGP_DMA, "EnableAGPDMA", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_2D_DMA, "NoAGPFor2D", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_XV_DMA, "NoXVDMA", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_EXA_NOCOMPOSITE, "ExaNoComposite", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -969,6 +971,15 @@ static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags) pVia->dma2d = TRUE; } + if (xf86ReturnOptValBool(VIAOptions, OPTION_XV_DMA, FALSE)) { + pVia->dmaXV = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: NoXVDMA - PCI DMA is not used for XV " + "image transfer\n"); + } else { + pVia->dmaXV = TRUE; + } + if (xf86ReturnOptValBool(VIAOptions, OPTION_VBEMODES, FALSE)) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: VBEModes - Using BIOS modes\n"); @@ -2173,7 +2184,6 @@ static int VIAInternalScreenInit(int scrnIndex, ScreenPtr pScreen) FBStart = pVia->FBBase; } - ErrorF("fbScreenInit"); return fbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, pScrn->yDpi, displayWidth, pScrn->bitsPerPixel); } diff --git a/src/via_driver.h b/src/via_driver.h index fc5a765..d6213d5 100644 --- a/src/via_driver.h +++ b/src/via_driver.h @@ -315,6 +315,7 @@ typedef struct _VIA { Bool DRIIrqEnable; Bool agpEnable; Bool dma2d; + Bool dmaXV; CARD8 ActiveDevice; /* Option */ unsigned char *CursorImage; @@ -336,6 +337,7 @@ typedef struct _VIA { unsigned long old_dwUseExtendedFIFO; ViaSharedPtr sharedData; + Bool useDmaBlit; #ifdef HAVE_DEBUG Bool DumpVGAROM; diff --git a/src/via_id.h b/src/via_id.h index b3c62f7..6b906a1 100644 --- a/src/via_id.h +++ b/src/via_id.h @@ -42,6 +42,7 @@ enum VIACHIPTAGS { VIA_KM400, VIA_K8M800, VIA_PM800, + VIA_VM800, VIA_LAST }; @@ -60,6 +61,7 @@ enum VIACHIPTAGS { #define PCI_CHIP_VT3259 0x3118 /* PM800/PM880/CN400 */ #define PCI_CHIP_CLE3122 0x3122 /* CLE266 */ #define PCI_CHIP_VT3205 0x7205 /* KM400 */ +#define PCI_CHIP_VT3314 0x3344 /* VM800 */ /* * There is also quite some conflicting information on the diff --git a/src/via_priv.h b/src/via_priv.h index 325e5f9..0e619c5 100644 --- a/src/via_priv.h +++ b/src/via_priv.h @@ -20,6 +20,7 @@ #define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') #define FOURCC_RV15 (('5' << 24) + ('1' << 16) + ('V' << 8) + 'R') #define FOURCC_RV16 (('6' << 24) + ('1' << 16) + ('V' << 8) + 'R') +#define FOURCC_RV32 (('2' << 24) + ('3' << 16) + ('V' << 8) + 'R') /* * Structures for create surface diff --git a/src/via_swov.c b/src/via_swov.c index 9cd6814..abcad1c 100644 --- a/src/via_swov.c +++ b/src/via_swov.c @@ -65,31 +65,23 @@ */ #define VIDREG_BUFFER_SIZE 100 /* Number of entries in the VidRegBuffer. */ #define IN_VIDEO_DISPLAY (*((unsigned long volatile *)(pVia->VidMapBase+V_FLAGS))&VBI_STATUS) -#if 0 -#define IN_HQV_FIRE (*((unsigned long volatile *)(pVia->VidMapBase+HQV_CONTROL))&HQV_IDLE) - -#ifdef UNUSED - -#define IN_VIDEO_FIRE (*((unsigned long volatile *)(pVia->VidMapBase+V_COMPOSE_MODE))&V1_COMMAND_FIRE) -#define IN_HQV_FLIP (*((unsigned long volatile *)(pVia->VidMapBase+HQV_CONTROL))&HQV_FLIP_STATUS) -#define IN_DISPLAY (VIDInD(V_FLAGS) & 0x200) -#define IN_VBLANK (!IN_DISPLAY) - -static void -viaWaitHQVIdle(VIAPtr pVia) -{ - while (!IN_HQV_FIRE); -} -#endif /* UNUSED */ -#endif +#define VIA_FIRETIMEOUT 40000 static void viaWaitVideoCommandFire(VIAPtr pVia) { - /*while (IN_VIDEO_FIRE);*/ +/* + * Assume uncached PCI reading throughputs about 9MB/s. 8Bytes / loop means + * Appox 1Mloops / second. We want to time out after 25 ms which means 25000 loops. + */ + + unsigned count = 25000; CARD32 volatile *pdwState = (CARD32 volatile *) (pVia->VidMapBase+V_COMPOSE_MODE); - /*pdwState = (CARD32 volatile *) (pVia->VidMapBase+V_COMPOSE_MODE);*/ - while ((*pdwState & V1_COMMAND_FIRE)||(*pdwState & V3_COMMAND_FIRE)); + + while (--count && ((*pdwState & V1_COMMAND_FIRE)||(*pdwState & V3_COMMAND_FIRE))); + if (!count) { + ErrorF("viaWaitVideoCommandFire: Timeout.\n"); + } } static void @@ -241,7 +233,6 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn) HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; break; -#ifdef HAVE_K8M800 case VIA_K8M800: HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE; @@ -249,8 +240,6 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn) HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; break; -#endif /* HAVE_K8M800 */ -#ifdef HAVE_PM800 case VIA_PM800: HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE; @@ -258,7 +247,13 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn) HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE; break; -#endif /* HAVE_PM800 */ + case VIA_VM800: + HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE; + HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE; + HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE; + HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE; + HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE; + break; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VIAVidHWDiffInit: Unhandled ChipSet.\n"); } @@ -301,57 +296,67 @@ viaOverlayGetV1V3Format(VIAPtr pVia, int vport, /* 1 or 3, as in V1 or V3 */ unsigned long videoFlag, unsigned long * pVidCtl, unsigned long * pHQVCtl) { - BOOL is_ok = TRUE; - - *pVidCtl |= V1_COLORSPACE_SIGN; - switch (pVia->swov.SrcFourCC) { - case FOURCC_YV12: - case FOURCC_XVMC: - if (videoFlag & VIDEO_HQV_INUSE) { - *pVidCtl |= V1_YUV422 | V1_SWAP_HW_HQV; - *pHQVCtl |= HQV_SRC_SW | HQV_YUV420 | HQV_ENABLE | HQV_SW_FLIP; - } else { - if (vport == 1) - *pVidCtl |= V1_YCbCr420; - else { - DBG_DD(ErrorF("viaOverlayGetV1V3Format: V3 does not support planar YUV.\n")); - is_ok = FALSE; - } - } - break; - - case FOURCC_YUY2: - if (videoFlag & VIDEO_HQV_INUSE) { - *pVidCtl |= V1_YUV422 | V1_SWAP_HW_HQV; - *pHQVCtl |= HQV_SRC_SW | HQV_YUV422 | HQV_ENABLE | HQV_SW_FLIP; - } else - *pVidCtl |= V1_YUV422; - break; - - case FOURCC_RV15: - case FOURCC_RV16: - if (videoFlag & VIDEO_HQV_INUSE) { - *pVidCtl |= - ((pVia->swov.SrcFourCC == FOURCC_RV15) ? V1_RGB15 : V1_RGB16) | - V1_SWAP_HW_HQV; - *pHQVCtl |= HQV_SRC_SW | - ((pVia->swov.SrcFourCC == FOURCC_RV15) ? HQV_RGB15 : HQV_RGB16) | - HQV_ENABLE | HQV_SW_FLIP; - } else { - ErrorF("viaOverlayGetV1V3Format: Can't display RGB video in this configuration.\n"); - is_ok = FALSE; - } - break; - - default: - DBG_DD(ErrorF("viaOverlayGetV1V3Format: Invalid FOURCC format (0x%lx).\n", - pVia->swov.SrcFourCC)); - is_ok = FALSE; - - *pVidCtl |= V1_YUV422; - break; + if (videoFlag & VIDEO_HQV_INUSE) + { + switch (pVia->swov.SrcFourCC) + { + case FOURCC_YV12: + case FOURCC_XVMC: + *pHQVCtl |= HQV_YUV420; + break; + case FOURCC_YUY2: + *pHQVCtl |= HQV_YUV422; + break; + case FOURCC_RV32: + *pVidCtl |= V1_RGB32; + *pHQVCtl |= HQV_RGB32; + break; + case FOURCC_RV15: + *pVidCtl |= V1_RGB15; + *pHQVCtl |= HQV_RGB15; + break; + case FOURCC_RV16: + *pVidCtl |= V1_RGB16; + *pHQVCtl |= HQV_RGB16; + break; + default: + DBG_DD(ErrorF("viaOverlayGetV1V3Format: Invalid FOURCC format (0x%lx).\n", pVia->swov.SrcFourCC)); + return FALSE; + } + *pVidCtl |= V1_SWAP_HW_HQV; + *pHQVCtl |= HQV_SRC_SW|HQV_ENABLE|HQV_SW_FLIP; + } + else + { + switch (pVia->swov.SrcFourCC) + { + case FOURCC_YV12: + case FOURCC_XVMC: + if (vport == 1) + { + *pVidCtl |= V1_YCbCr420; + } + else + { + DBG_DD(ErrorF("viaOverlayGetV1V3Format: V3 does not support planar YUV.\n")); + return FALSE; + } + break; + case FOURCC_YUY2: + *pVidCtl |= V1_YUV422; + break; + case FOURCC_RV32: + case FOURCC_RV15: + case FOURCC_RV16: + ErrorF("viaOverlayGetV1V3Format: Can't display RGB video in this configuration.\n"); + return FALSE; + default: + DBG_DD(ErrorF("viaOverlayGetV1V3Format: Invalid FOURCC format (0x%lx).\n", pVia->swov.SrcFourCC)); + return FALSE; + } } - return is_ok; + *pVidCtl |= V1_COLORSPACE_SIGN; + return TRUE; } static unsigned long @@ -368,15 +373,18 @@ viaOverlayGetSrcStartAddress(VIAPtr pVia, unsigned long videoFlag, unsigned long srcTopOffset = 0; unsigned long srcLeftOffset = 0; + int n=1; if ((pUpdate->SrcLeft != 0) || (pUpdate->SrcTop != 0)) { switch (pVia->swov.SrcFourCC) { + case FOURCC_RV32: + n=2; case FOURCC_YUY2: case FOURCC_UYVY: case FOURCC_RV15: case FOURCC_RV16: if (videoFlag & VIDEO_HQV_INUSE) { - offset = (((pUpdate->SrcTop & ~3) * srcPitch) + ((pUpdate->SrcLeft << 1) & ~31)); + offset = (((pUpdate->SrcTop & ~3) * srcPitch) + ((pUpdate->SrcLeft << n) & ~31)); if (srcHeight > dstHeight) srcTopOffset = ((pUpdate->SrcTop & ~3) * dstHeight / srcHeight) * srcPitch; @@ -384,25 +392,25 @@ viaOverlayGetSrcStartAddress(VIAPtr pVia, unsigned long videoFlag, srcTopOffset = (pUpdate->SrcTop & ~3) * srcPitch; if (srcWidth > dstWidth) - srcLeftOffset = ((pUpdate->SrcLeft << 1) & ~31) * dstWidth / srcWidth; + srcLeftOffset = ((pUpdate->SrcLeft << n) & ~31) * dstWidth / srcWidth; else - srcLeftOffset = (pUpdate->SrcLeft << 1) & ~31; + srcLeftOffset = (pUpdate->SrcLeft << n) & ~31; *pHQVoffset = srcTopOffset + srcLeftOffset; } else - offset = ((pUpdate->SrcTop * srcPitch) + ((pUpdate->SrcLeft << 1) & ~15)); + offset = ((pUpdate->SrcTop * srcPitch) + ((pUpdate->SrcLeft << n) & ~15)); break; case FOURCC_YV12: case FOURCC_XVMC: if (videoFlag & VIDEO_HQV_INUSE) - offset = (((pUpdate->SrcTop & ~3) * (srcPitch << 1)) + ((pUpdate->SrcLeft << 1) & ~31)); - else { - offset = ((((pUpdate->SrcTop & ~3) * srcPitch) + pUpdate->SrcLeft) & ~31); - if (pUpdate->SrcTop > 0) - pVia->swov.overlayRecordV1.dwUVoffset = (((((pUpdate->SrcTop & ~3)>>1) * srcPitch) + pUpdate->SrcLeft) & ~31) >> 1; - else - pVia->swov.overlayRecordV1.dwUVoffset = offset >> 1; + offset = (((pUpdate->SrcTop & ~3) * (srcPitch << 1)) + ((pUpdate->SrcLeft << 1) & ~31)); + else { + offset = ((((pUpdate->SrcTop & ~3) * srcPitch) + pUpdate->SrcLeft) & ~31); + if (pUpdate->SrcTop > 0) + pVia->swov.overlayRecordV1.dwUVoffset = (((((pUpdate->SrcTop & ~3)>>1) * srcPitch) + pUpdate->SrcLeft) & ~31) >> 1; + else + pVia->swov.overlayRecordV1.dwUVoffset = offset >> 1; } break; @@ -613,6 +621,9 @@ viaOverlayGetFetch(VIAPtr pVia, unsigned long videoFlag, case FOURCC_RV16: n = 1; /* 2^n = 2 bytes per pixel (packed YUV) */ break; + case FOURCC_RV32: + n = 2; + break; default: DBG_DD(ErrorF("viaOverlayGetFetch: Invalid FOURCC format (0x%lx).\n", pVia->swov.SrcFourCC)); @@ -708,6 +719,7 @@ viaCalculateVideoColor(VIAPtr pVia, int hue, int saturation, int brightness, case PCI_CHIP_VT3205: case PCI_CHIP_VT3204: case PCI_CHIP_VT3259: + case PCI_CHIP_VT3314: model = 0; break; case PCI_CHIP_CLE3122: @@ -829,6 +841,7 @@ void viaSetColorSpace(VIAPtr pVia, int hue, int saturation, int brightness, int case PCI_CHIP_VT3205: case PCI_CHIP_VT3204: case PCI_CHIP_VT3259: + case PCI_CHIP_VT3314: VIDOutD(V3_ColorSpaceReg_1, col1); VIDOutD(V3_ColorSpaceReg_2, col2); DBG_DD(ErrorF("000002C4 %08lx\n",col1)); @@ -855,6 +868,7 @@ static unsigned long ViaInitVideoStatusFlag(VIAPtr pVia) case PCI_CHIP_VT3205: case PCI_CHIP_VT3204: case PCI_CHIP_VT3259: + case PCI_CHIP_VT3314: return VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_3_INUSE; case PCI_CHIP_CLE3122: return VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_1_INUSE; @@ -885,7 +899,8 @@ static unsigned long ViaSetVidCtl(VIAPtr pVia, unsigned int videoFlag) { case PCI_CHIP_VT3205: case PCI_CHIP_VT3204: - case PCI_CHIP_VT3259: + case PCI_CHIP_VT3259: + case PCI_CHIP_VT3314: return V3_ENABLE | V3_EXPIRE_NUM_3205; case PCI_CHIP_CLE3122: @@ -977,14 +992,27 @@ CreateSurface(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width, pVia->swov.SrcFourCC = FourCC; pVia->swov.gdwVideoFlagSW = ViaInitVideoStatusFlag(pVia); - isplanar = ((FourCC == FOURCC_YV12) || (FourCC == FOURCC_XVMC)); - - pitch = ALIGN_TO(Width, 32) * (isplanar ? 1 : 2); - fbsize = pitch * Height * (isplanar ? 1.5 : 1.0); - - VIAFreeLinear(&pVia->swov.SWfbMem); - + isplanar = FALSE; + switch (FourCC) + { + case FOURCC_YV12: + case FOURCC_XVMC: + isplanar = TRUE; + pitch = ALIGN_TO(Width, 32); + fbsize = pitch * Height * 1.5; + break; + case FOURCC_RV32: + pitch = ALIGN_TO(Width<<2, 32); + fbsize = pitch * Height; + break; + default: + pitch = ALIGN_TO(Width<<1, 32); + fbsize = pitch * Height; + break; + } + if (doalloc) { + VIAFreeLinear(&pVia->swov.SWfbMem); retCode = VIAAllocLinear(&pVia->swov.SWfbMem, pScrn, fbsize * 2); if(retCode != Success) return retCode; @@ -1043,6 +1071,7 @@ ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, CARD32 FourCC, case FOURCC_YUY2: case FOURCC_RV15: case FOURCC_RV16: + case FOURCC_RV32: retCode = CreateSurface(pScrn, FourCC, Width, Height, TRUE); if (retCode != Success) break; @@ -1099,6 +1128,7 @@ ViaSwovSurfaceDestroy(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv) switch (pPriv->FourCC) { case FOURCC_YUY2: case FOURCC_RV16: + case FOURCC_RV32: case FOURCC_RV15: pVia->swov.SrcFourCC = 0; @@ -1114,10 +1144,10 @@ ViaSwovSurfaceDestroy(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv) break; case FOURCC_YV12: + VIAFreeLinear(&pVia->swov.SWfbMem); case FOURCC_XVMC: pVia->swov.SrcFourCC = 0; - VIAFreeLinear(&pVia->swov.SWfbMem); VIAFreeLinear(&pVia->swov.HQVMem); pVia->swov.gdwVideoFlagSW = 0; break; @@ -1139,12 +1169,24 @@ static void SetFIFO_V1(VIAPtr pVia, CARD8 depth, CARD8 prethreshold, CARD8 thres static void SetFIFO_V3(VIAPtr pVia, CARD8 depth, CARD8 prethreshold, CARD8 threshold) { - SaveVideoRegister(pVia, ALPHA_V3_FIFO_CONTROL, - (VIDInD(ALPHA_V3_FIFO_CONTROL) & ALPHA_FIFO_MASK) | - ((depth - 1) & 0xff) | ((threshold & 0xff) << 8)); - SaveVideoRegister(pVia, ALPHA_V3_PREFIFO_CONTROL, - (VIDInD(ALPHA_V3_PREFIFO_CONTROL) & ~V3_FIFO_MASK) | - (prethreshold & 0x7f)); + if (pVia->ChipId == PCI_CHIP_VT3314) + { + SaveVideoRegister(pVia, ALPHA_V3_FIFO_CONTROL, + (VIDInD(ALPHA_V3_FIFO_CONTROL) & ALPHA_FIFO_MASK) | + ((depth - 1) & 0xff) | ((threshold & 0xff) << 8)); + SaveVideoRegister(pVia, ALPHA_V3_PREFIFO_CONTROL, + (VIDInD(ALPHA_V3_PREFIFO_CONTROL) & ~V3_FIFO_MASK_3314) | + (prethreshold & 0xff)); + } + else + { + SaveVideoRegister(pVia, ALPHA_V3_FIFO_CONTROL, + (VIDInD(ALPHA_V3_FIFO_CONTROL) & ALPHA_FIFO_MASK) | + ((depth - 1) & 0xff) | ((threshold & 0xff) << 8)); + SaveVideoRegister(pVia, ALPHA_V3_PREFIFO_CONTROL, + (VIDInD(ALPHA_V3_PREFIFO_CONTROL) & ~V3_FIFO_MASK) | + (prethreshold & 0x7f)); + } } static void SetFIFO_64or32(VIAPtr pVia) @@ -1185,8 +1227,13 @@ static void SetFIFO_V3_64or32or32(VIAPtr pVia) { switch (pVia->ChipId) { - case PCI_CHIP_VT3205: case PCI_CHIP_VT3204: + SetFIFO_V3(pVia, 100, 89, 89); + break; + case PCI_CHIP_VT3314: + SetFIFO_V3(pVia, 64, 61, 61); + break; + case PCI_CHIP_VT3205: case PCI_CHIP_VT3259: SetFIFO_V3(pVia, 32, 29, 29); break; @@ -1207,8 +1254,13 @@ static void SetFIFO_V3_64or32or16(VIAPtr pVia) { switch (pVia->ChipId) { - case PCI_CHIP_VT3205: case PCI_CHIP_VT3204: + SetFIFO_V3(pVia, 100, 89, 89); + break; + case PCI_CHIP_VT3314: + SetFIFO_V3(pVia, 64, 61, 61); + break; + case PCI_CHIP_VT3205: case PCI_CHIP_VT3259: SetFIFO_V3(pVia, 32, 29, 29); break; @@ -1325,8 +1377,8 @@ static CARD32 SetColorKey(VIAPtr pVia, unsigned long videoFlag, CARD32 keyLow, CARD32 keyHigh, CARD32 compose) { keyLow &= 0x00FFFFFF; - if ((pVia->ChipId == PCI_CHIP_VT3259)) - keyLow |= 0x40000000; + if (pVia->ChipId == PCI_CHIP_VT3259) + keyLow |= 0x40000000; /*SaveVideoRegister(pVia, V_COLOR_KEY, keyLow);*/ @@ -1357,8 +1409,8 @@ static CARD32 SetChromaKey(VIAPtr pVia, unsigned long videoFlag, chromaLow |= (VIDInD(V_CHROMAKEY_LOW) & ~CHROMA_KEY_LOW); chromaHigh |= (VIDInD(V_CHROMAKEY_HIGH)& ~CHROMA_KEY_HIGH); - if ((pVia->ChipId == PCI_CHIP_VT3259)) - chromaLow |= 0x40000000; + if (pVia->ChipId == PCI_CHIP_VT3259) + chromaLow |= 0x40000000; SaveVideoRegister(pVia, V_CHROMAKEY_HIGH, chromaHigh); @@ -1405,6 +1457,7 @@ static void SetHQVFetch(VIAPtr pVia, CARD32 srcFetch, unsigned long srcHeight) if (!pVia->HWDiff.dwHQVFetchByteUnit) { /* CLE_C0 */ srcFetch >>= 3; /* fetch unit is 8-byte */ } + SaveVideoRegister(pVia, HQV_SRC_FETCH_LINE + proReg, ((srcFetch - 1) << 16) | (srcHeight - 1)); } @@ -1656,7 +1709,7 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag, fetch = viaOverlayGetFetch(pVia, videoFlag, srcWidth, dstWidth, oriSrcWidth, &hqvSrcFetch); - DBG_DD(ErrorF("===fetch= 0x%lx \n", fetch)); + DBG_DD(ErrorF("===fetch= 0x%lx\n", fetch)); #if 0 /* For DCT450 test-BOB INTERLEAVE */ @@ -1686,8 +1739,12 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag, SaveVideoRegister(pVia, V1_STRIDE, srcPitch << 1); else SaveVideoRegister(pVia, V3_STRIDE, srcPitch << 1); - - SaveVideoRegister(pVia, HQV_SRC_STRIDE + proReg, ((srcPitch >> 1) << 16) | srcPitch); + + if (pVia->HWDiff.dwHQVFetchByteUnit) + SaveVideoRegister(pVia, HQV_SRC_STRIDE + proReg, ((srcPitch >> 1) << 16) | srcPitch | HQV_FIFO_DEPTH_1); + else + SaveVideoRegister(pVia, HQV_SRC_STRIDE + proReg, ((srcPitch >> 1) << 16) | srcPitch); + SaveVideoRegister(pVia, HQV_DST_STRIDE + proReg, (srcPitch << 1)); } else { if (videoFlag & VIDEO_1_INUSE) @@ -1923,9 +1980,9 @@ VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate) panDX = pVia->swov.panning_x; - panDY = pVia->swov.panning_y; + panDY = pVia->swov.panning_y; pVia->swov.oldPanningX = pVia->swov.panning_x; - pVia->swov.oldPanningY = pVia->swov.panning_y; + pVia->swov.oldPanningY = pVia->swov.panning_y; pUpdate->DstLeft -= panDX; pUpdate->DstTop -= panDY; @@ -1942,6 +1999,7 @@ VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate) if ((pVia->swov.SrcFourCC == FOURCC_YUY2) || (pVia->swov.SrcFourCC == FOURCC_RV15) || (pVia->swov.SrcFourCC == FOURCC_RV16) || + (pVia->swov.SrcFourCC == FOURCC_RV32) || (pVia->swov.SrcFourCC == FOURCC_YV12) || (pVia->swov.SrcFourCC == FOURCC_XVMC)) { @@ -2012,6 +2070,7 @@ VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate) if ((pVia->swov.SrcFourCC == FOURCC_YUY2) || (pVia->swov.SrcFourCC == FOURCC_RV15) || (pVia->swov.SrcFourCC == FOURCC_RV16) || + (pVia->swov.SrcFourCC == FOURCC_RV32) || (pVia->swov.SrcFourCC == FOURCC_YV12) || (pVia->swov.SrcFourCC == FOURCC_XVMC)) { pVia->swov.SWDevice.gdwSWDstLeft = pUpdate->DstLeft + panDX; @@ -2066,6 +2125,7 @@ ViaOverlayHide(ScrnInfoPtr pScrn) if ((pVia->swov.SrcFourCC == FOURCC_YUY2) || (pVia->swov.SrcFourCC == FOURCC_RV15) || (pVia->swov.SrcFourCC == FOURCC_RV16) || + (pVia->swov.SrcFourCC == FOURCC_RV32) || (pVia->swov.SrcFourCC == FOURCC_YV12) || (pVia->swov.SrcFourCC == FOURCC_XVMC)) videoFlag = pVia->swov.gdwVideoFlagSW; @@ -2085,7 +2145,7 @@ ViaOverlayHide(ScrnInfoPtr pScrn) | ALPHA_FIFO_DEPTH8 | V3_FIFO_THRESHOLD24 | V3_FIFO_DEPTH32); if (videoFlag & VIDEO_HQV_INUSE) - SaveVideoRegister(pVia, HQV_CONTROL + proReg, VIDInD(HQV_CONTROL) & ~HQV_ENABLE); + SaveVideoRegister(pVia, HQV_CONTROL + proReg, VIDInD(HQV_CONTROL + proReg) & ~HQV_ENABLE); if (videoFlag & VIDEO_1_INUSE) SaveVideoRegister(pVia, V1_CONTROL, VIDInD(V1_CONTROL) & ~V1_ENABLE); diff --git a/src/via_video.c b/src/via_video.c index 6da5ab9..7c4bb2f 100644 --- a/src/via_video.c +++ b/src/via_video.c @@ -99,6 +99,11 @@ static int viaSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); static int viaPutImage(ScrnInfoPtr, short, short, short, short, short, short, short, short,int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static void nv12Blit(unsigned char *nv12Chroma, + const unsigned char *uBuffer, + const unsigned char *vBuffer, + unsigned width, unsigned srcPitch, + unsigned dstPitch, unsigned lines); static Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation, xvAutoPaint; @@ -138,7 +143,7 @@ static XF86AttributeRec AttributesG[NUM_ATTRIBUTES_G] = {XvSettable | XvGettable,0,1,"XV_AUTOPAINT_COLORKEY"} }; -#define NUM_IMAGES_G 5 +#define NUM_IMAGES_G 6 static XF86ImageRec ImagesG[NUM_IMAGES_G] = { @@ -200,7 +205,25 @@ static XF86ImageRec ImagesG[NUM_IMAGES_G] = {'R', 'V', 'B',0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, XvTopToBottom + }, + { /* RGB 888 */ + FOURCC_RV32, + XvRGB, + LSBFirst, + {'R','V','3','2', + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + 32, + XvPacked, + 1, + 24, 0xff0000, 0x00ff00, 0x0000ff, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom } + }; static char * XvAdaptorName[XV_ADAPT_NUM] = @@ -221,6 +244,7 @@ static unsigned numAdaptPort[XV_ADAPT_NUM] = * Decide if the mode support video overlay. This depends on the bandwidth * of the mode and the type of RAM available. */ + static Bool DecideOverlaySupport(ScrnInfoPtr pScrn) { VIAPtr pVia = VIAPTR(pScrn); @@ -231,7 +255,8 @@ static Bool DecideOverlaySupport(ScrnInfoPtr pScrn) if ( pVia->ChipId != PCI_CHIP_VT3205 && pVia->ChipId != PCI_CHIP_VT3204 && - pVia->ChipId != PCI_CHIP_VT3259) { + pVia->ChipId != PCI_CHIP_VT3259 && + pVia->ChipId != PCI_CHIP_VT3314) { CARD32 bandwidth = (mode->HDisplay >> 4) * (mode->VDisplay >> 5) * pScrn->bitsPerPixel * mode->VRefresh; @@ -374,6 +399,29 @@ static Bool DecideOverlaySupport(ScrnInfoPtr pScrn) return FALSE; } +static const char *viaXvErrMsg[xve_numerr] = + {"No Error.", + "Bandwidth is insufficient. Check bios memory settings.", + "PCI DMA blit failed. You probably encountered a bug.", + "Not enough resources to complete the request. Probably out of memory.", + "General Error. I wish I could be more specific.", + "Wrong adaptor used. Try another port number."}; + +static void +viaXvError(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, XvError error) +{ + if (error == xve_none) { + pPriv->xvErr = xve_none; + return; + } + if (error == pPriv->xvErr) { + return; + } + pPriv->xvErr = error; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[Xv] Port %d: %s\n", pPriv->xv_portnum, + viaXvErrMsg[error]); +} + static void viaResetVideo(ScrnInfoPtr pScrn) { @@ -473,12 +521,31 @@ void viaInitVideo(ScreenPtr pScreen) allAdaptors = NULL; newAdaptors = NULL; num_new = 0; + + pVia->useDmaBlit = FALSE; +#ifdef XF86DRI + pVia->useDmaBlit = pVia->directRenderingEnabled && + ((pVia->Chipset == VIA_CLE266) || + (pVia->Chipset == VIA_KM400) || + (pVia->Chipset == VIA_K8M800) || + (pVia->Chipset == VIA_PM800) || + (pVia->Chipset == VIA_VM800)); + if ((pVia->drmVerMajor < 2) || + ((pVia->drmVerMajor == 2) && + (pVia->drmVerMinor < 9))) + pVia->useDmaBlit = FALSE; +#endif + pVia->useDmaBlit = pVia->useDmaBlit && pVia->dmaXV; + + if (pVia->useDmaBlit) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[Xv] Using PCI DMA for Xv image transfer.\n"); if (!viaFastVidCpy) viaFastVidCpy = viaVidCopyInit("video", pScreen); if ( (pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400) || - (pVia->Chipset == VIA_K8M800) || (pVia->Chipset == VIA_PM800)) { + (pVia->Chipset == VIA_K8M800) || (pVia->Chipset == VIA_PM800) /* || + (pVia->Chipset == VIA_VM800) */) { num_new = viaSetupAdaptors(pScreen, &newAdaptors); num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); } else { @@ -569,9 +636,10 @@ viaReputImage(ScrnInfoPtr pScrn, if (drw_x == pPriv->old_drw_x && drw_y == pPriv->old_drw_y && pVia->swov.oldPanningX == pVia->swov.panning_x && - pVia->swov.oldPanningY == pVia->swov.panning_y) - + pVia->swov.oldPanningY == pVia->swov.panning_y) { + viaXvError(pScrn, pPriv, xve_none); return Success; + } lpUpdateOverlay->SrcLeft = pPriv->old_src_x; lpUpdateOverlay->SrcTop = pPriv->old_src_y; @@ -592,14 +660,9 @@ viaReputImage(ScrnInfoPtr pScrn, else lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey; - if(!RegionsEqual(&pPriv->clip, clipBoxes)) { - REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); - if (pPriv->autoPaint) - xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); - } - VIAVidUpdateOverlay(pScrn, lpUpdateOverlay); + viaXvError(pScrn, pPriv, xve_none); return Success; } @@ -670,6 +733,9 @@ viaSetupAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr **adaptors) viaAdaptPtr[i]->ReputImage = viaReputImage; viaAdaptPtr[i]->QueryImageAttributes = viaQueryImageAttributes; for (j=0; j<numPorts; ++j) { + viaPortPriv[j].dmaBounceBuffer = NULL; + viaPortPriv[j].dmaBounceStride = 0; + viaPortPriv[j].dmaBounceLines = 0; viaPortPriv[j].colorKey = 0x0821; viaPortPriv[j].autoPaint = TRUE; viaPortPriv[j].brightness = 5000.; @@ -678,7 +744,8 @@ viaSetupAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr **adaptors) viaPortPriv[j].hue = 0; viaPortPriv[j].FourCC = 0; viaPortPriv[j].xv_portnum = j + usedPorts; - REGION_NULL(pScreen, &viaPortPriv[j].clip); + viaPortPriv[j].xvErr = xve_none; + REGION_NULL(pScreen, &viaPortPriv[j].clip); } usedPorts += j; @@ -706,6 +773,10 @@ viaStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) if (exit) { ViaOverlayHide(pScrn); ViaSwovSurfaceDestroy(pScrn, pPriv); + if (pPriv->dmaBounceBuffer) xfree(pPriv->dmaBounceBuffer); + pPriv->dmaBounceBuffer = 0; + pPriv->dmaBounceStride = 0; + pPriv->dmaBounceLines = 0; pVia->dwFrameNum = 0; pPriv->old_drw_x= 0; pPriv->old_drw_y= 0; @@ -867,10 +938,12 @@ static void Flip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc, unsigned long Di case FOURCC_YUY2: case FOURCC_RV15: case FOURCC_RV16: - while ((VIDInD(HQV_CONTROL) & HQV_SW_FLIP) ); + case FOURCC_RV32: + while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP) ); VIDOutD(HQV_SRC_STARTADDR_Y + proReg, pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]); - VIDOutD(HQV_CONTROL,( VIDInD(HQV_CONTROL)&~HQV_FLIP_ODD) |HQV_SW_FLIP|HQV_FLIP_STATUS); + VIDOutD(HQV_CONTROL + proReg,( VIDInD(HQV_CONTROL + proReg)&~HQV_FLIP_ODD) | + HQV_SW_FLIP|HQV_FLIP_STATUS); break; case FOURCC_YV12: @@ -904,55 +977,163 @@ nv12cp(unsigned char *dst, int w, int h, int yuv422) { - int count; - int x, dstAdd; - const unsigned char* src2; - - /* Blit luma component as a fake YUY2 assembler blit. */ + /* + * Blit luma component as a fake YUY2 assembler blit. + */ + (*viaFastVidCpy)(dst, src, dstPitch, w >> 1, h, TRUE); + nv12Blit( dst + dstPitch*h, src + w*h + (w >> 1)*(h >> 1), src + w*h, + w >> 1, w >> 1, dstPitch, h >> 1); +} - src += w*h; - dst += dstPitch*h; - dstAdd = dstPitch - w; - - /* UV component is 1/2 of Y */ - w >>= 1; - /* copy V(Cr),U(Cb) components to video memory */ - count = h/2; +#ifdef XF86DRI - src2 = src + w*count; - while(count--) { - x=w; - while(x > 3) { - register CARD32 - dst32, - src32 = *((CARD32 *) src), - src32_2 = *((CARD32 *) src2); - dst32 = - (src32_2 & 0xff) | ((src32 & 0xff) << 8) | - ((src32_2 & 0x0000ff00) << 8) | ((src32 & 0x0000ff00) << 16); - *((CARD32 *) dst) = dst32; - dst +=4; - dst32 = - ((src32_2 & 0x00ff0000) >> 16) | ((src32 & 0x00ff0000) >> 8) | - ((src32_2 & 0xff000000) >> 8) | (src32 & 0xff000000); - *((CARD32 *) dst) = dst32; - dst +=4; - x -= 4; - src += 4; - src2 += 4; +static int +viaDmaBlitImage(VIAPtr pVia, + viaPortPrivPtr pPort, + unsigned char *src, + CARD32 dst, + unsigned width, + unsigned height, + unsigned lumaStride, + int id) +{ + Bool bounceBuffer; + drm_via_dmablit_t blit; + drm_via_blitsync_t *chromaSync = &blit.sync; + drm_via_blitsync_t lumaSync; + unsigned char *base; + unsigned char *bounceBase; + unsigned bounceStride; + unsigned bounceLines; + unsigned size; + int err=0; + Bool nv12Conversion; + + bounceBuffer = ((unsigned long)src & 15); + nv12Conversion = ((pVia->ChipId == PCI_CHIP_VT3259) && (id == FOURCC_YV12)); + + switch(id) { + case FOURCC_YUY2: + case FOURCC_RV15: + case FOURCC_RV16: + bounceStride = ALIGN_TO(2*width, 16); + bounceLines = height; + break; + case FOURCC_RV32: + bounceStride = ALIGN_TO(4*width, 16); + bounceLines = height; + break; + + case FOURCC_YV12: + default: + bounceStride = ALIGN_TO(width,16); + bounceLines = height; + break; + } + + if (bounceBuffer || nv12Conversion) { + if (!pPort->dmaBounceBuffer || + pPort->dmaBounceStride != bounceStride || + pPort->dmaBounceLines != bounceLines) { + if (pPort->dmaBounceBuffer) { + xfree(pPort->dmaBounceBuffer); + pPort->dmaBounceBuffer = 0; + } + size = bounceStride * bounceLines + 16; + if (FOURCC_YV12 == id) size += ALIGN_TO(bounceStride >> 1, 16) * bounceLines; + pPort->dmaBounceBuffer = (unsigned char *)malloc(size); + pPort->dmaBounceLines = bounceLines; + pPort->dmaBounceStride = bounceStride; } - while(x--) { - *dst++ = *src2++; - *dst++ = *src++; - } - dst += dstAdd; } -} + bounceBase = (unsigned char *)ALIGN_TO((unsigned long)(pPort->dmaBounceBuffer), 16); + base = (bounceBuffer) ? bounceBase : src; + + if(bounceBuffer) { + (*viaFastVidCpy)(base, src, bounceStride, bounceStride >> 1, height, 1); + } + + blit.num_lines = height; + blit.line_length = bounceStride; + blit.fb_addr = dst; + blit.fb_stride = lumaStride; + blit.mem_addr = base; + blit.mem_stride = bounceStride; + blit.to_fb = 1; +#if (VIA_DRM_DRIVER_VERSION >= ((2 << 16) | 9)) + blit.flags = 0; +#else + blit.bounce_buffer = 0; +#endif + +#ifdef XV_DEBUG + ErrorF("Addr: 0x%lx, Offset 0x%lx\n Fb_stride: %u, Mem_stride: %u\n width: %u num_lines: %u\n", + (unsigned long)blit.mem_addr, (unsigned long)blit.fb_addr, + (unsigned)blit.fb_stride,(unsigned)blit.mem_stride, + (unsigned)blit.line_length,(unsigned)blit.num_lines); +#endif + while(-EAGAIN == (err = drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, + &blit, sizeof(blit)))); + if (err < 0) + return -1; + + lumaSync = blit.sync; + + if (id == FOURCC_YV12) { + unsigned tmp = ALIGN_TO(width >> 1, 16); + + if (nv12Conversion) { + nv12Blit(bounceBase + bounceStride*height, + src + bounceStride*height + tmp*(height >> 1), + src + bounceStride*height, width >> 1, tmp, + bounceStride, height >> 1); + } else if (bounceBuffer) { + (*viaFastVidCpy)(base + bounceStride*height,src + bounceStride*height, + tmp, tmp >> 1,height, 1); + } + + if (nv12Conversion) { + blit.num_lines = height >> 1; + blit.line_length = bounceStride; + blit.mem_addr = bounceBase + bounceStride*height; + blit.fb_stride = lumaStride; + blit.mem_stride = bounceStride; + } else { + blit.num_lines = height; + blit.line_length = tmp; + blit.mem_addr = base + bounceStride*height; + blit.fb_stride = lumaStride >> 1; + blit.mem_stride = tmp; + } + + blit.fb_addr = dst + lumaStride*height; + blit.to_fb = 1; +#if (VIA_DRM_DRIVER_VERSION >= ((2 << 16) | 9)) + blit.flags = 0; +#else + blit.bounce_buffer = 0; +#endif + + while(-EAGAIN == (err = drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, + &blit, sizeof(blit)))); + if (err < 0) + return -1; + + } + + while(-EAGAIN == (err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, + chromaSync, sizeof(*chromaSync)))); + if (err < 0) + return -1; + return Success; +} + +#endif static int viaPutImage( @@ -977,7 +1158,7 @@ viaPutImage( ErrorF(" via_video.c : drw_x=%d drw_y=%d drw_w=%d drw_h=%d\n",drw_x,drw_y,drw_w,drw_h); # endif - switch ( pPriv->xv_portnum ) + switch ( pPriv->xv_adaptor ) { case XV_ADAPT_SWOV: { @@ -991,12 +1172,14 @@ viaPutImage( /* Allocate video memory(CreateSurface), * add codes to judge if need to re-create surface */ - if ( (pPriv->old_src_w != src_w) || (pPriv->old_src_h != src_h) ) + if ( (pPriv->old_src_w != src_w) || (pPriv->old_src_h != src_h) ) { ViaSwovSurfaceDestroy(pScrn, pPriv); - + } + if (Success != ( retCode = ViaSwovSurfaceCreate(pScrn, pPriv, id, width, height) )) { DBG_DD(ErrorF(" : Fail to Create SW Video Surface\n")); + viaXvError(pScrn, pPriv, xve_mem); return retCode; } @@ -1007,24 +1190,40 @@ viaPutImage( if (FOURCC_XVMC != id) { dstPitch = pVia->swov.SWDevice.dwPitch; - switch(id) { - case FOURCC_YV12: - if (pVia->ChipId == PCI_CHIP_VT3259) { - nv12cp(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1], - buf,dstPitch,width,height,0); - } else { + if (pVia->useDmaBlit) { +#ifdef XF86DRI + if (viaDmaBlitImage(pVia, pPriv, buf, + (unsigned char *)pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1] - + (unsigned char *)pVia->FBBase, + width, height, dstPitch, id)) { + viaXvError(pScrn, pPriv, xve_dmablit); + return BadAccess; + } +#endif + } else { + switch(id) { + case FOURCC_YV12: + if (pVia->ChipId == PCI_CHIP_VT3259) { + nv12cp(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1], + buf,dstPitch,width,height,0); + } else { + (*viaFastVidCpy)(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1], + buf,dstPitch,width,height,0); + } + break; + case FOURCC_RV32: (*viaFastVidCpy)(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1], - buf,dstPitch,width,height,0); + buf,dstPitch,width<<1,height,1); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_RV15: + case FOURCC_RV16: + default: + (*viaFastVidCpy)(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1], + buf,dstPitch,width,height,1); + break; } - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_RV15: - case FOURCC_RV16: - default: - (*viaFastVidCpy)(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum&1], - buf,dstPitch,width,height,1); - break; } } @@ -1034,6 +1233,7 @@ viaPutImage( !(pVia->OverlaySupported = DecideOverlaySupport(pScrn))) { DBG_DD(ErrorF(" via_video.c : Xv Overlay rejected due to insufficient " "memory bandwidth.\n")); + viaXvError(pScrn, pPriv, xve_bandwidth); return BadAlloc; } @@ -1085,6 +1285,7 @@ viaPutImage( && (pVia->VideoStatus & VIDEO_SWOV_ON) && RegionsEqual(&pPriv->clip, clipBoxes)) { + viaXvError(pScrn, pPriv, xve_none); return Success; } @@ -1105,8 +1306,8 @@ viaPutImage( REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); if (pPriv->autoPaint) xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); - } - + } + /* * Update video overlay */ @@ -1114,19 +1315,21 @@ viaPutImage( DBG_DD(ErrorF(" via_video.c : call v4l updateoverlay fail. \n")); } else { DBG_DD(ErrorF(" via_video.c : PutImage done OK\n")); + viaXvError(pScrn, pPriv, xve_none); return Success; } break; } default: DBG_DD(ErrorF(" via_video.c : XVPort not supported\n")); + viaXvError(pScrn, pPriv, xve_adaptor); break; } DBG_DD(ErrorF(" via_video.c : PutImage done OK\n")); + viaXvError(pScrn, pPriv, xve_none); return Success; } - static int viaQueryImageAttributes( ScrnInfoPtr pScrn, @@ -1135,6 +1338,7 @@ viaQueryImageAttributes( int *pitches, int *offsets ){ int size, tmp; + VIAPtr pVia = VIAPTR(pScrn); DBG_DD(ErrorF(" via_video.c : viaQueryImageAttributes : FourCC=0x%x, ", id)); @@ -1152,10 +1356,14 @@ viaQueryImageAttributes( case FOURCC_YV12: /*Planar format : YV12 -4:2:0*/ *h = (*h + 1) & ~1; size = *w; + if (pVia->useDmaBlit) + size = (size + 15) & ~15; if(pitches) pitches[0] = size; size *= *h; if(offsets) offsets[1] = size; tmp = (*w >> 1); + if (pVia->useDmaBlit) + tmp = (tmp + 15) & ~15; if(pitches) pitches[1] = pitches[2] = tmp; tmp *= (*h >> 1); size += tmp; @@ -1177,12 +1385,22 @@ viaQueryImageAttributes( if (pitches) pitches[0] = *w; if (offsets) offsets[0] = 0; break; + case FOURCC_RV32: + size = *w << 2; + if (pVia->useDmaBlit) + size = (size + 15) & ~15; + if(pitches) + pitches[0] = size; + size *= *h; + break; case FOURCC_UYVY: /*Packed format : UYVY -4:2:2*/ case FOURCC_YUY2: /*Packed format : YUY2 -4:2:2*/ case FOURCC_RV15: case FOURCC_RV16: default: size = *w << 1; + if (pVia->useDmaBlit) + size = (size + 15) & ~15; if(pitches) pitches[0] = size; size *= *h; @@ -1211,4 +1429,53 @@ VIAVidAdjustFrame(ScrnInfoPtr pScrn, int x, int y) pVia->swov.panning_y = y; } +/* + * Blit the chroma field from one buffer to another while at the same time converting from + * YV12 to NV12. + */ + +static void nv12Blit(unsigned char *nv12Chroma, + const unsigned char *uBuffer, + const unsigned char *vBuffer, + unsigned width, unsigned srcPitch, + unsigned dstPitch, unsigned lines) +{ + int x; + int dstAdd; + int srcAdd; + + dstAdd = dstPitch - (width << 1); + srcAdd = srcPitch - width; + + while(lines--) { + x=width; + while(x > 3) { + register CARD32 + dst32, + src32 = *((CARD32 *) vBuffer), + src32_2 = *((CARD32 *) uBuffer); + dst32 = + (src32_2 & 0xff) | ((src32 & 0xff) << 8) | + ((src32_2 & 0x0000ff00) << 8) | ((src32 & 0x0000ff00) << 16); + *((CARD32 *) nv12Chroma) = dst32; + nv12Chroma +=4; + dst32 = + ((src32_2 & 0x00ff0000) >> 16) | ((src32 & 0x00ff0000) >> 8) | + ((src32_2 & 0xff000000) >> 8) | (src32 & 0xff000000); + *((CARD32 *) nv12Chroma) = dst32; + nv12Chroma +=4; + x -= 4; + vBuffer += 4; + uBuffer += 4; + } + while(x--) { + *nv12Chroma++ = *uBuffer++; + *nv12Chroma++ = *vBuffer++; + } + nv12Chroma += dstAdd; + vBuffer += srcAdd; + uBuffer += srcAdd; + } +} + #endif /* !XvExtension */ diff --git a/src/via_video.h b/src/via_video.h index 5c23fe7..dbd6dd0 100644 --- a/src/via_video.h +++ b/src/via_video.h @@ -29,6 +29,7 @@ * I N C L U D E S */ +/*#define XV_DEBUG 1*/ /* write log msg to /var/log/XFree86.0.log */ #define COLOR_KEY 1 /* set color key value from driver layer*/ #define HW_3123 diff --git a/src/via_xvmc.c b/src/via_xvmc.c index 3941f49..ebe99fe 100644 --- a/src/via_xvmc.c +++ b/src/via_xvmc.c @@ -40,14 +40,17 @@ #ifdef XF86DRI #include "via.h" -#include "xf86drm.h" +#include "via_drm.h" #include "via_dri.h" #include "via_driver.h" #include "via_id.h" #include "xf86xv.h" #include "fourcc.h" + +#if defined(X_NEED_XVPRIV_H) || defined (_XF86_FOURCC_H_) #include "xf86xvpriv.h" +#endif #include "xf86xvmc.h" #include <X11/extensions/Xv.h> @@ -56,6 +59,7 @@ #include "xaalocal.h" #include "dixstruct.h" #include "via_xvmc.h" +#include "dristruct.h" #include "dri.h" #include "via_xvpriv.h" #include "via_video.h" @@ -184,8 +188,8 @@ static unsigned long size_xx44(int w, int h) static int yv12_subpicture_index_list[2] = { - FOURCC_IA44, - FOURCC_AI44 + FOURCC_IA44, + FOURCC_AI44 }; static XF86MCImageIDList yv12_subpicture_list = @@ -330,12 +334,11 @@ ViaInitXVMC(ScreenPtr pScreen) VIAPtr pVia = VIAPTR(pScrn); ViaXvMCPtr vXvMC = &(pVia->xvmc); volatile ViaXvMCSAreaPriv *saPriv; - drmVersionPtr drmVer; pVia->XvMCEnabled = 0; - if (!(pVia->Chipset == VIA_CLE266) && !(pVia->Chipset == VIA_K8M800) && - !(pVia->Chipset == VIA_PM800)) { + if (!(pVia->Chipset == VIA_CLE266) && !(pVia->Chipset == VIA_K8M800) && + !(pVia->Chipset == VIA_PM800) && !(pVia->Chipset == VIA_VM800)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] Not supported on this chipset.\n"); return; @@ -347,32 +350,26 @@ ViaInitXVMC(ScreenPtr pScreen) return; } - if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "[XvMC] Could not get drm version. Disabling XvMC\n"); - return; - } - if (((drmVer->version_major <= 2) && (drmVer->version_minor < 4))) { + if (((pVia->drmVerMajor <= 2) && (pVia->drmVerMinor< 4))) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] Kernel drm is not compatible with XvMC.\n"); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] Kernel drm version: %d.%d.%d " "and need at least version 2.4.0.\n", - drmVer->version_major,drmVer->version_minor, - drmVer->version_patchlevel); + pVia->drmVerMajor, + pVia->drmVerMinor, + pVia->drmVerPL); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] Please update. Disabling XvMC.\n"); - drmFreeVersion(drmVer); return; } - if ((drmVer->version_major >= 3)) { + if ((pVia->drmVerMajor >= 3)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] XvMC X driver may not be compatible " "with kernel drm.\n"); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] Continuing, but strange things may happen.\n"); } - drmFreeVersion(drmVer); vXvMC->mmioBase = pVia->registerHandle; @@ -402,9 +399,9 @@ ViaInitXVMC(ScreenPtr pScreen) if (pVia->ChipId != PCI_CHIP_VT3259) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Registering viaXvMC.\n"); - xf86XvMCRegisterDRInfo(pScreen, "viaXvMC",pDRIInfo->busIdString, + xf86XvMCRegisterDRInfo(pScreen, "viaXvMC",pDRIInfo->busIdString, VIAXVMC_MAJOR, VIAXVMC_MINOR, VIAXVMC_PL); - } + } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Registering viaXvMCPro.\n"); @@ -520,7 +517,8 @@ ViaXvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, contextRec->useAGP = pViaDRI->ringBufActive && ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400) || - (pVia->Chipset == VIA_PM800)); + (pVia->Chipset == VIA_PM800) || + (pVia->Chipset == VIA_VM800)); contextRec->chipId = pVia->ChipId; contextRec->screen = pScrn->pScreen->myNum; contextRec->depth = pScrn->bitsPerPixel; diff --git a/src/via_xvpriv.h b/src/via_xvpriv.h index b692e91..d4808ba 100644 --- a/src/via_xvpriv.h +++ b/src/via_xvpriv.h @@ -27,10 +27,19 @@ #include "xf86xv.h" - enum{ XV_ADAPT_SWOV=0, XV_ADAPT_NUM}; +typedef enum{ + xve_none = 0, + xve_bandwidth, + xve_dmablit, + xve_mem, + xve_general, + xve_adaptor, + xve_numerr +} XvError; + #define VIA_MAX_XV_PORTS 1 typedef struct { @@ -59,6 +68,15 @@ typedef struct { short old_drw_h; void *xvmc_priv; + + /* + * For PCI DMA image transfer to frame-buffer memory. + */ + + unsigned char *dmaBounceBuffer; + unsigned dmaBounceStride; + unsigned dmaBounceLines; + XvError xvErr; } viaPortPrivRec, *viaPortPrivPtr; |