From bd3a6d5cb1a544ccae9eecf7cb0b40fb6bdac287 Mon Sep 17 00:00:00 2001 From: Luc Verhaegen Date: Wed, 15 Nov 2006 14:20:56 +0100 Subject: xuma: add subpicture support. * Add XumaPutSubPicture and XumaStopSubPicture. * Rework server side versioning to a more Xv like fashion: XumaQueryExtension * Split up initialisation and teardown of Mpeg and Xuma, add SubPicture, and handle all seperately from ViaVideoInit. --- lib/xuma/xuma.c | 120 +++++++++++----- lib/xuma/xumalib.h | 11 +- lib/xuma/xumaproto.h | 60 +++++--- src/via_driver.h | 7 - src/via_mpeg.c | 400 ++++++++++++++++++++++++++++++++++++++------------- src/via_mpeg.h | 31 +++- src/via_mpegregs.h | 28 +++- src/via_video.c | 58 +++++--- src/via_video.h | 3 + 9 files changed, 533 insertions(+), 185 deletions(-) diff --git a/lib/xuma/xuma.c b/lib/xuma/xuma.c index a1438f7..28a3ca3 100644 --- a/lib/xuma/xuma.c +++ b/lib/xuma/xuma.c @@ -91,55 +91,39 @@ XEXT_GENERATE_FIND_DISPLAY(XumaFindDisplay, XumaExtInfo, XUMA_EXT_NAME, /* * */ -Bool -XumaQueryExtension(Display *dpy, int *event_basep, int *error_basep) -{ - XExtDisplayInfo *info = XumaFindDisplay(dpy); - - if (XextHasExtension(info)) { - *event_basep = info->codes->first_event; - *error_basep = info->codes->first_error; - return True; - } else { - return False; - } -} - -/* - * - */ -Bool -XumaQueryVersion(Display *dpy) +int +XumaQueryExtension(Display *dpy, unsigned int *Version, unsigned int *Release, + int *event_basep, int *error_basep) { XExtDisplayInfo *info = XumaFindDisplay(dpy); - xumaVersionReq *req; - xumaVersionReply reply; - Bool ret; + xumaQueryExtensionReq *req; + xumaQueryExtensionReply reply; + int ret; XumaCheckExtension(dpy, info, BadImplementation); LockDisplay(dpy); - XumaGetReq(Version, req); + XumaGetReq(QueryExtension, req); - ret = _XReply(dpy, (xReply *)&reply, 0, xFalse); - if (ret) { - int Major, Minor, Patch; + if (_XReply(dpy, (xReply *)&reply, 0, xFalse)) { + *Version = reply.Version; + *Release = reply.Release; - Major = (reply.Version >> 20) & 0x3FF; - Minor = (reply.Version >> 10) & 0x3FF; - Patch = reply.Version & 0x3FF; - printf("Found %s Version %03d.%03d.%03d.\n", XUMA_EXT_NAME, - Major, Minor, Patch); - - if ((Major != XUMA_VERSION_MAJOR) || - (Minor < XUMA_VERSION_MINOR)) { + if ((*Version != XUMA_VERSION) || (*Release < XUMA_RELEASE)) { fprintf(stderr, "Incompatible %s version found.\n", XUMA_EXT_NAME); - return FALSE; + + ret = BadImplementation; } - } else + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + + ret = Success; + } else { fprintf(stderr, "%s; Xreply failed.\n", __func__); + ret = BadAccess; + } UnlockDisplay(dpy); SyncHandle(); @@ -281,6 +265,64 @@ XumaGetCapabilities(Display *dpy, int port) return Capabilities; } +/* + * + */ +int +XumaPutSubPicture(Display *dpy, int port, int IA44, unsigned short Width, + unsigned short Height, unsigned int Palette[16], + unsigned char *SubPicture) +{ + XExtDisplayInfo *info = XumaFindDisplay(dpy); + xumaPutSubPictureReq *req; + int len; + + XumaCheckExtension(dpy, info, BadImplementation); + + LockDisplay(dpy); + + XumaGetReq(PutSubPicture, req); + + req->Port = port; + req->Width = Width; + req->Height = Height; + req->IA44 = IA44 & 0xFF; + + len = (64 + Width * Height + 3) >> 2; + SetReqLen(req, len, len); + + Data(dpy, (char *) Palette, 64); + Data(dpy, (char *) SubPicture, Width * Height); + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +/* + * + */ +int +XumaStopSubPicture(Display *dpy, int port) +{ + XExtDisplayInfo *info = XumaFindDisplay(dpy); + xumaStopSubPictureReq *req; + + XumaCheckExtension(dpy, info, BadImplementation); + + LockDisplay(dpy); + + XumaGetReq(StopSubPicture, req); + + req->Port = port; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + /* * Returns 0 if no buffer has been grabbed. */ @@ -343,7 +385,7 @@ XumaReleaseBuffer(Display *dpy, int port, unsigned char BufferID) UnlockDisplay(dpy); SyncHandle(); - return Success; /* Where do we see if an error occured? */ + return Success; } /* @@ -369,7 +411,7 @@ XumaPutQMatrix(Display *dpy, int port, int type, unsigned char Matrix[64]) UnlockDisplay(dpy); SyncHandle(); - return Success; /* Where do we see if an error occured? */ + return Success; } /* @@ -441,5 +483,5 @@ XumaPutSlice(Display *dpy, XvPortID port, unsigned char BufferID, unsigned int S UnlockDisplay(dpy); SyncHandle(); - return Success; /* Where do we see if an error occured? */ + return Success; } diff --git a/lib/xuma/xumalib.h b/lib/xuma/xumalib.h index caff2b5..b84ae74 100644 --- a/lib/xuma/xumalib.h +++ b/lib/xuma/xumalib.h @@ -38,14 +38,19 @@ struct XumaCapabilities { unsigned short BufferCount; }; -extern Bool XumaQueryExtension(Display *dpy, int *event_basep, int *error_basep); - -extern Bool XumaQueryVersion(Display *dpy); +extern int XumaQueryExtension(Display *dpy, unsigned int *Version, unsigned int *Release, + int *event_basep, int *error_basep); extern int XumaGrabPort(Display *dpy, XvPortID *port); extern struct XumaCapabilities *XumaGetCapabilities(Display *dpy, int port); +extern int XumaPutSubPicture(Display *dpy, int port, int IA44, unsigned short Width, + unsigned short Height, unsigned int Palette[16], + unsigned char *SubPicture); + +extern int XumaStopSubPicture(Display *dpy, int port); + extern unsigned char XumaGrabBuffer(Display *dpy, XvPortID port, unsigned int Format, unsigned short Width, unsigned short Height); diff --git a/lib/xuma/xumaproto.h b/lib/xuma/xumaproto.h index f314c02..30ed9e5 100644 --- a/lib/xuma/xumaproto.h +++ b/lib/xuma/xumaproto.h @@ -34,29 +34,28 @@ #define XUMA_EXT_NAME "Unichrome MPEG Acceleration Extension" -#define XUMA_VERSION_MAJOR 0 -#define XUMA_VERSION_MINOR 0 -#define XUMA_VERSION_PATCH 0 +#define XUMA_VERSION 0 +#define XUMA_RELEASE 0 -#define xuma_Version 0 +#define xuma_QueryExtension 0 #define xuma_QueryCapabilities 1 -#define xuma_GrabBuffer 2 -#define xuma_ReleaseBuffer 3 -#define xuma_PutQMatrix 4 -#define xuma_InitSlice 5 -#define xuma_PutSlice 6 +#define xuma_PutSubPicture 2 +#define xuma_StopSubPicture 3 +#define xuma_GrabBuffer 4 +#define xuma_ReleaseBuffer 5 +#define xuma_PutQMatrix 6 +#define xuma_InitSlice 7 +#define xuma_PutSlice 8 /* * Version, are we compatible? */ typedef struct { CARD8 reqType; - CARD8 xumaReqType; /* xuma_Version */ + CARD8 xumaReqType; /* xuma_QueryExtension */ CARD16 length B16; - CARD32 Version B32; - CARD32 pad1 B32; -} xumaVersionReq; -#define sz_xumaVersionReq 12 +} xumaQueryExtensionReq; +#define sz_xumaQueryExtensionReq 4 typedef struct { BYTE type; /* X_Reply */ @@ -64,13 +63,13 @@ typedef struct { CARD16 sequenceNumber B16; CARD32 length B32; CARD32 Version B32; - CARD32 pad1 B32; + CARD32 Release B32; CARD32 pad2 B32; CARD32 pad3 B32; CARD32 pad4 B32; CARD32 pad5 B32; -} xumaVersionReply; -#define sz_xumaVersionReply 32 +} xumaQueryExtensionReply; +#define sz_xumaQueryExtensionReply 32 /* * QueryCapabilities, how the client knows what it can and can't use. @@ -113,6 +112,33 @@ typedef struct { } xumaQueryCapabilitiesReply; #define sz_xumaQueryCapabilitiesReply 32 +/* + * PutSubPicture + */ +typedef struct { + CARD8 reqType; + CARD8 xumaReqType; /* xuma_PutSubPicture */ + CARD16 length B16; + CARD32 Port B32; + CARD16 Width B16; + CARD16 Height B16; + CARD8 IA44; + CARD8 pad0; + CARD16 pad1 B16; +} xumaPutSubPictureReq; +#define sz_xumaPutSubPictureReq 16 + +/* + * SubPictureStop + */ +typedef struct { + CARD8 reqType; + CARD8 xumaReqType; /* xuma_StopSubPicture */ + CARD16 length B16; + CARD32 Port B32; +} xumaStopSubPictureReq; +#define sz_xumaStopSubPictureReq 8 + /* * GrabBuffer */ diff --git a/src/via_driver.h b/src/via_driver.h index 6c242df..3201527 100644 --- a/src/via_driver.h +++ b/src/via_driver.h @@ -336,13 +336,6 @@ void ViaVideoInit(ScrnInfoPtr pScrn, ScreenPtr pScreen); void ViaVideoDestroy(ScrnInfoPtr pScrn); #endif -/* via_mpeg.c */ -#ifdef XvExtension -Bool ViaMpegInit(ScrnInfoPtr pScrn, ScreenPtr pScreen); -void ViaMpegStop(ScrnInfoPtr pScrn); -void ViaMpegDestroy(ScrnInfoPtr pScrn); -#endif - /* via_i2c.c */ void ViaI2CInit(ScrnInfoPtr pScrn); diff --git a/src/via_mpeg.c b/src/via_mpeg.c index 298f4b6..11fc01c 100644 --- a/src/via_mpeg.c +++ b/src/via_mpeg.c @@ -40,7 +40,7 @@ * and VT3108. This means that we just get almost raw MPEG data from the * client, which, must also have grabbed a capable Xv port to be accepted. * The volume of data passed around is extremely low, as most of the work - * is all in framebuffer. + * is in the engine and framebuffer. * * Once the slice decoder is solid, MacroBlock decoding will happen. This * implements a lower level of acceleration, but one that should also be @@ -64,6 +64,122 @@ #include "lib/xuma/xumaproto.h" #include "lib/xuma/xuma.h" +/* + * + * SubPicture support. + * + */ +/* + * + */ +static int +ViaSubPicturePut(ScrnInfoPtr pScrn, CARD16 Width, CARD16 Height, CARD8 IA44, + CARD32 *Palette, CARD8 *Buffer) +{ + struct ViaSubPicture *SubPicture = VIAPTR(pScrn)->Swov->SubPicture; + CARD32 Control; + int i; + + if (!SubPicture->Mem || + (Width != SubPicture->Width) || (Height != SubPicture->Height)) { + if (SubPicture->Mem) + ViaMemFree(pScrn, SubPicture->Mem); + + SubPicture->Mem = ViaMemAlloc(pScrn, Width * Height, 16); + if (!SubPicture->Mem) + return BadAlloc; + + SubPicture->Width = Width; + SubPicture->Height = Height; + } + + if (!ViaSwovCopy(pScrn, SubPicture->Mem, Buffer)) + return BadAccess; + + SubPicture->Regs->Address = SubPicture->Mem->Base; + + for (i = 0; i < 16; i++) + SubPicture->Regs->Palette = (Palette[i] & 0xFFFFFF00) | (i << 4) | 0x07; + + Control = SUBPICTURE_HQV_ENABLE; + if (IA44) + Control |= SUBPICTURE_IA44; + + Control |= Width & 0x1FFF; + + SubPicture->Regs->Control = Control; + + return Success; +} + +/* + * + */ +void +ViaSubPictureStop(ScrnInfoPtr pScrn) +{ + struct ViaSwov *Swov = VIAPTR(pScrn)->Swov; + struct ViaSubPicture *SubPicture = Swov->SubPicture; + + if (!SubPicture) + return; + + SubPicture->Regs->Control = 0x00000000; + + if (SubPicture->Mem) + ViaMemFree(pScrn, SubPicture->Mem); + + SubPicture->Mem = NULL; + SubPicture->Width = 0; + SubPicture->Height = 0; +} + +/* + * + */ +void +ViaSubPictureInit(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + struct ViaSwov *Swov = pVia->Swov; + struct ViaSubPicture *SubPicture; + + VIAFUNC(pScrn->scrnIndex); + + SubPicture = xnfcalloc(sizeof(struct ViaSubPicture), 1); + + SubPicture->scrnIndex = pScrn->scrnIndex; + SubPicture->Regs = (struct ViaSubPictureRegs *) (pVia->MapBase + 0x3C0); + + Swov->SubPicture = SubPicture; +} + +/* + * + */ +void +ViaSubPictureDestroy(ScrnInfoPtr pScrn) +{ + struct ViaSwov *Swov = VIAPTR(pScrn)->Swov; + struct ViaSubPicture *SubPicture = Swov->SubPicture; + + VIAFUNC(pScrn->scrnIndex); + + if (!SubPicture) + return; + + ViaSubPictureStop(pScrn); + + xfree(SubPicture); + Swov->SubPicture = NULL; +} + +/* + * + * MPEG engine. + * + */ +#if 0 /* * */ @@ -121,6 +237,7 @@ ViaMpegPrintRegs(ScrnInfoPtr pScrn) ViaDebug(pScrn->scrnIndex, "%s: Done.\n", __func__); } +#endif /* * @@ -501,7 +618,77 @@ ViaMpegPutSlice(ScrnInfoPtr pScrn, CARD8 ID, CARD8 SliceCode, /* * - * Extension starts here. + */ +void +ViaMpegInit(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + struct ViaMpeg *Mpeg; + + VIAFUNC(pScrn->scrnIndex); + + Mpeg = xnfcalloc(sizeof(struct ViaMpeg), 1); + + Mpeg->scrnIndex = pScrn->scrnIndex; + Mpeg->Regs = (struct ViaMpegRegs *) (pVia->MapBase + 0xC00); + pVia->Swov->Mpeg = Mpeg; + + ViaMpegReset(pScrn); +} + +/* + * + */ +void +ViaMpegStop(ScrnInfoPtr pScrn) +{ + struct ViaMpeg *Mpeg = VIAPTR(pScrn)->Swov->Mpeg; + int i; + + ViaMpegEngineIdle(Mpeg); + ViaMpegReset(pScrn); + + for (i = 0; i < VIAMPEG_BUFFERS_MAX; i++) + if (Mpeg->Buffers[i].Mem) { + ViaMemFree(pScrn, Mpeg->Buffers[i].Mem); + Mpeg->Buffers[i].Mem = NULL; + Mpeg->Buffers[i].Width = 0; + Mpeg->Buffers[i].Height = 0; + Mpeg->Buffers[i].MBWidth = 0; + Mpeg->Buffers[i].MBHeight = 0; + } + + Mpeg->Current = 0xFF; + Mpeg->Flipping = 0xFF; +} + +/* + * + */ +void +ViaMpegDestroy(ScrnInfoPtr pScrn) +{ + struct ViaSwov *Swov = VIAPTR(pScrn)->Swov; + struct ViaMpeg *Mpeg = Swov->Mpeg; + + VIAFUNC(pScrn->scrnIndex); + + if (!Mpeg) + return; + + ViaMpegStop(pScrn); + + xfree(Swov->Mpeg); + Swov->Mpeg = NULL; + + ViaSubPictureStop(pScrn); + xfree(Swov->SubPicture); + Swov->SubPicture = NULL; +} + +/* + * + * XUMA Extension. * */ struct XumaPrivates @@ -513,12 +700,12 @@ struct XumaPrivates * */ static int -XumaProcVersion(ClientPtr client) +XumaProcQueryExtension(ClientPtr client) { ExtensionEntry *MPEGExt; - xumaVersionReply rep; + xumaQueryExtensionReply rep; - REQUEST_SIZE_MATCH(xumaVersionReq); + REQUEST_SIZE_MATCH(xumaQueryExtensionReq); MPEGExt = CheckExtension(XUMA_EXT_NAME); if(!MPEGExt || !MPEGExt->extPrivate) @@ -527,12 +714,11 @@ XumaProcVersion(ClientPtr client) rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = - (sizeof(xumaVersionReply) - sizeof(xGenericReply)) >> 2; - rep.Version = (XUMA_VERSION_MAJOR << 20) | - (XUMA_VERSION_MINOR << 10) | XUMA_VERSION_PATCH; + (sizeof(xumaQueryExtensionReply) - sizeof(xGenericReply)) >> 2; + rep.Version = XUMA_VERSION; + rep.Release = XUMA_RELEASE; - WriteToClient(client, sizeof(xumaVersionReply), - (char *)&rep); + WriteToClient(client, sizeof(xumaQueryExtensionReply), (char *)&rep); return (client->noClientException); } @@ -608,6 +794,102 @@ XumaProcQueryCapabilities(ClientPtr client) return (client->noClientException); } +/* + * + */ +static int +XumaProcPutSubPicture(ClientPtr client) +{ + ExtensionEntry *MPEGExt; + struct XumaPrivates *Private; + ScrnInfoPtr pScrn; + XvPortPtr Port; + int ret; + CARD32 *Palette; + CARD8 *SubPicture; + int len; + + REQUEST(xumaPutSubPictureReq); + REQUEST_AT_LEAST_SIZE(xumaPutSubPictureReq); + + MPEGExt = CheckExtension(XUMA_EXT_NAME); + if (!MPEGExt || !MPEGExt->extPrivate) { + xf86Msg(X_WARNING, "%s: Extension not initialised.\n", __func__); + return BadMatch; + } + + Private = MPEGExt->extPrivate; + pScrn = xf86Screens[Private->scrnIndex]; + + /* VIAFUNC(pScrn->scrnIndex); */ + + /* Does our client own this port? */ + Port = LookupIDByType(stuff->Port, XvGetRTPort()); + if (!Port) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "%s: Client doesn't own this Xv Port.\n", __func__); + return BadAccess; + } + + len = 64 + stuff->Width * stuff->Height; + + if (client->req_len != (sz_xumaPutSubPictureReq + len) >> 2) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "%s: Request has wrong length.\n", __func__); + return BadLength; + } + + /* TODO: Check Width and Height for alignment and size */ + + Palette = (CARD32 *) &stuff[1]; + SubPicture = ((CARD8 *) &stuff[1]) + 64; + ret = ViaSubPicturePut(pScrn, stuff->Width, stuff->Height, stuff->IA44, + Palette, SubPicture); + + if (ret != Success) + return ret; + + return (client->noClientException); +} + +/* + * + */ +static int +XumaProcStopSubPicture(ClientPtr client) +{ + ExtensionEntry *MPEGExt; + struct XumaPrivates *Private; + ScrnInfoPtr pScrn; + XvPortPtr Port; + + REQUEST(xumaStopSubPictureReq); + REQUEST_SIZE_MATCH(xumaStopSubPictureReq); + + MPEGExt = CheckExtension(XUMA_EXT_NAME); + if (!MPEGExt || !MPEGExt->extPrivate) { + xf86Msg(X_WARNING, "%s: Extension not initialised.\n", __func__); + return BadMatch; + } + + Private = MPEGExt->extPrivate; + pScrn = xf86Screens[Private->scrnIndex]; + + /* VIAFUNC(pScrn->scrnIndex); */ + + /* Does our client own this port? */ + Port = LookupIDByType(stuff->Port, XvGetRTPort()); + if (!Port) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "%s: Client doesn't own this Xv Port.\n", __func__); + return BadAccess; + } + + ViaSubPictureStop(pScrn); + + return (client->noClientException); +} + /* * */ @@ -645,6 +927,8 @@ XumaProcGrabBuffer(ClientPtr client) return BadAccess; } + /* TODO: Check Width and Height for alignment and size */ + ID = ViaMpegGrabBuffer(pScrn, stuff->Format, stuff->Width, stuff->Height); /* Send back our picture ID */ @@ -853,10 +1137,14 @@ XumaHandler(ClientPtr client) REQUEST(xReq); switch (stuff->data) { - case xuma_Version: - return XumaProcVersion(client); + case xuma_QueryExtension: + return XumaProcQueryExtension(client); case xuma_QueryCapabilities: return XumaProcQueryCapabilities(client); + case xuma_PutSubPicture: + return XumaProcPutSubPicture(client); + case xuma_StopSubPicture: + return XumaProcStopSubPicture(client); case xuma_GrabBuffer: return XumaProcGrabBuffer(client); case xuma_ReleaseBuffer: @@ -900,7 +1188,7 @@ XumaClose(ExtensionEntry *MPEGExt) /* * */ -static Bool +Bool XumaInit(ScrnInfoPtr pScrn) { ExtensionEntry *MPEGExt; @@ -916,93 +1204,9 @@ XumaInit(ScrnInfoPtr pScrn) return FALSE; } - Private = xcalloc(sizeof(struct XumaPrivates), 1); - if (!Private) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "%s: Failed to allocate privates.\n", __func__); - return FALSE; - } - + Private = xnfcalloc(sizeof(struct XumaPrivates), 1); Private->scrnIndex = pScrn->scrnIndex; MPEGExt->extPrivate = Private; return TRUE; } - -/* - * - */ -Bool -ViaMpegInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) -{ - VIAPtr pVia = VIAPTR(pScrn); - struct ViaMpeg *Mpeg; - - VIAFUNC(pScrn->scrnIndex); - - Mpeg = xcalloc(sizeof(struct ViaMpeg), 1); - if (!Mpeg) - return FALSE; - - if (!XumaInit(pScrn)) { - xfree(Mpeg); - return FALSE; - } - - Mpeg->scrnIndex = pScrn->scrnIndex; - Mpeg->Regs = (struct ViaMpegRegs *) (pVia->MapBase + 0xC00); - pVia->Swov->Mpeg = Mpeg; - - ViaMpegPrintRegs(pScrn); - - ViaMpegReset(pScrn); - - ViaMpegPrintRegs(pScrn); - - return TRUE; -} - -/* - * - */ -void -ViaMpegStop(ScrnInfoPtr pScrn) -{ - struct ViaMpeg *Mpeg = VIAPTR(pScrn)->Swov->Mpeg; - int i; - - ViaMpegEngineIdle(Mpeg); - ViaMpegReset(pScrn); - - for (i = 0; i < VIAMPEG_BUFFERS_MAX; i++) - if (Mpeg->Buffers[i].Mem) { - ViaMemFree(pScrn, Mpeg->Buffers[i].Mem); - Mpeg->Buffers[i].Mem = NULL; - Mpeg->Buffers[i].Width = 0; - Mpeg->Buffers[i].Height = 0; - Mpeg->Buffers[i].MBWidth = 0; - Mpeg->Buffers[i].MBHeight = 0; - } - - Mpeg->Current = 0xFF; - Mpeg->Flipping = 0xFF; -} -/* - * - */ -void -ViaMpegDestroy(ScrnInfoPtr pScrn) -{ - struct ViaSwov *Swov = VIAPTR(pScrn)->Swov; - struct ViaMpeg *Mpeg = Swov->Mpeg; - - VIAFUNC(pScrn->scrnIndex); - - if (!Mpeg) - return; - - ViaMpegStop(pScrn); - - xfree(Swov->Mpeg); - Swov->Mpeg = NULL; -} diff --git a/src/via_mpeg.h b/src/via_mpeg.h index 7881028..4ddf592 100644 --- a/src/via_mpeg.h +++ b/src/via_mpeg.h @@ -54,9 +54,38 @@ struct ViaMpeg { struct ViaMpegRegs *Regs; }; +/* + * + */ +struct ViaSubPicture { + int scrnIndex; + + CARD16 Width; + CARD16 Height; + + struct ViaMem *Mem; + + struct ViaSubPictureRegs *Regs; +}; + +/* from via_mpeg.c, to allow via_video.c to sync this engine */ void ViaMpegEngineIdle(struct ViaMpeg *Mpeg); -/* from via_video.c */ +/* from via_video.c, to allow via_mpeg.c to sync this engine */ void ViaHQVIdle(struct ViaSwov *Swov); +/* from via_video.c - to copy over the SubPicture */ +Bool ViaSwovCopy(ScrnInfoPtr pScrn, struct ViaMem *Mem, unsigned char *Buffer); + +/* Function prototypes for via_video.c */ +void ViaSubPictureInit(ScrnInfoPtr pScrn); +void ViaSubPictureStop(ScrnInfoPtr pScrn); +void ViaSubPictureDestroy(ScrnInfoPtr pScrn); + +void ViaMpegInit(ScrnInfoPtr pScrn); +void ViaMpegStop(ScrnInfoPtr pScrn); +void ViaMpegDestroy(ScrnInfoPtr pScrn); + +Bool XumaInit(ScrnInfoPtr pScrn); + #endif /* HAVE_VIA_MPEG_H */ diff --git a/src/via_mpegregs.h b/src/via_mpegregs.h index ef32a9e..6500f26 100644 --- a/src/via_mpegregs.h +++ b/src/via_mpegregs.h @@ -61,8 +61,6 @@ /* Slice stream input: from 0xA0 till 0xB4: 0 <= i <= 4 (???) */ #define MPEG_SLICESTREAM(i) (0xA0 + 0x4*(i)) -/* Only for driver side */ -#ifdef HAVE_VIA_MPEG_H /* * Mpeg Register structure, for direct access. */ @@ -91,6 +89,30 @@ struct ViaMpegRegs { volatile CARD32 SliceControl4; /* 0x9C */ volatile CARD32 SliceStream[5]; /* 0xA0 */ }; -#endif /* HAVE_VIA_MPEG_H */ + +/* + * + * SubPicture Support. + * + * Base Address: 0x3C0 + */ + +/* SUBPICTURE Registers */ +#define SUBPICTURE_CONTROL 0x00 +#define SUBPICTURE_ADDRESS 0x04 +#define SUBPICTURE_PALETTE 0x08 +#define SUBPICTURE_PALETTE_READ 0x0C + +/* SUBPICTURE_CONTROL */ +#define SUBPICTURE_HQV_ENABLE 0x00010000 +#define SUBPICTURE_IA44 0x00020000 +#define SUBPICTURE_STRIDE 0x00001fff + +struct ViaSubPictureRegs { + volatile CARD32 Control; /* 0x00 */ + volatile CARD32 Address; /* 0x04 */ + volatile CARD32 Palette; /* 0x08 */ + volatile CARD32 PaletteRead; /* 0x0C */ +}; #endif /* HAVE_VIA_MPEGREGS_H */ diff --git a/src/via_video.c b/src/via_video.c index bd63885..353eac7 100644 --- a/src/via_video.c +++ b/src/via_video.c @@ -429,9 +429,11 @@ ViaSwovCopyDMA(VIAPtr pVia, struct ViaMem *Mem, CARD8 *buf) /* * */ -static Bool -ViaSwovCopy(VIAPtr pVia, struct ViaMem *Mem, unsigned char *buf) +Bool +ViaSwovCopy(ScrnInfoPtr pScrn, struct ViaMem *Mem, unsigned char *buf) { + VIAPtr pVia = VIAPTR(pScrn); + #ifdef DRM_VIA_DMA_BLIT if (pVia->UseDMACopy) { if (!ViaSwovCopyDMA(pVia, Mem, buf)) { @@ -775,7 +777,7 @@ ViaSwovAlphaPosition(ScrnInfoPtr pScrn) ViaSwovAlphaFillBuffer(pScrn, Port->AlphaLocal, Port->AlphaFB->Size); - ViaSwovCopy(pVia, Port->AlphaFB, Port->AlphaLocal); + ViaSwovCopy(pScrn, Port->AlphaFB, Port->AlphaLocal); Temp = Swov->Video->Video3AlphaFetch & 0xFFFFFC00; Swov->Video->Video3AlphaFetch = Temp | (ALIGN_TO(Port->Win_W, 32) >> 5); @@ -1958,14 +1960,14 @@ ViaHQVFlipInitWait(struct ViaSwov *Swov) * */ static void -ViaHQVFlip(VIAPtr pVia, unsigned char* buf) +ViaHQVFlip(ScrnInfoPtr pScrn, unsigned char* buf) { - struct ViaSwov *Swov = pVia->Swov; + struct ViaSwov *Swov = VIAPTR(pScrn)->Swov; struct ViaXvPort *Port = Swov->Port; int i; for (i = 0; i < 15; i++) - if (!(Swov->HQV->Control & HQV_SW_FLIP)) + if (!(Swov->HQV->Control & (HQV_SW_FLIP | HQV_SUBPIC_FLIP))) break; else usleep(1); @@ -1975,12 +1977,15 @@ ViaHQVFlip(VIAPtr pVia, unsigned char* buf) if ((Swov->HQV->Control & HQV_SW_FLIP)) xf86DrvMsg(Swov->scrnIndex, X_WARNING, "%s: HQV is still flipping.\n", __func__); + if ((Swov->HQV->Control & HQV_SUBPIC_FLIP)) + xf86DrvMsg(Swov->scrnIndex, X_WARNING, + "%s: SubPicture is still flipping.\n", __func__); } if (buf) { /* if NULL, then we need to flip the previous buffer again */ if (Port->FourCC != FOURCC_MPEG) { if (!Port->Front[1]) /* single buffering */ - ViaSwovCopy(pVia, Port->Front[0], buf); + ViaSwovCopy(pScrn, Port->Front[0], buf); else { /* We only need to set the address */ Swov->HQV->SrcAddressY = Port->Front[0]->Base; if (Port->CrOffset) { @@ -2007,7 +2012,10 @@ ViaHQVFlip(VIAPtr pVia, unsigned char* buf) } } - Swov->HQV->Control |= HQV_SW_FLIP | HQV_FLIP_STATUS; + if (Swov->SubPicture->Mem) /* SubPicture active? */ + Swov->HQV->Control |= HQV_SW_FLIP | HQV_FLIP_STATUS | HQV_SUBPIC_FLIP; + else + Swov->HQV->Control |= HQV_SW_FLIP | HQV_FLIP_STATUS; } @@ -2082,6 +2090,7 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, ViaDebug(pScrn->scrnIndex, "%s: (%d + %d, %d + %d) -> (%d + %d, %d + %d)\n", __func__, src_x, src_w, src_y, src_h, drw_x, drw_w, drw_y, drw_h); + /* Check whether MPEG call is correct before trying anything else */ if (id == FOURCC_MPEG) { struct ViaMpeg *Mpeg = Swov->Mpeg; CARD8 ID = buf[0]; @@ -2097,6 +2106,16 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, } } + /* Are we using the SubPicture? */ + if (Swov->SubPicture->Mem) { /* Same as an Active flag */ + if ((Swov->SubPicture->Width != width) || + (Swov->SubPicture->Height != height)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: SubPicture has " + "different size. Disabling.\n", __func__); + ViaSubPictureStop(pScrn); + } + } + if (!Swov->Active) { /* initial pass */ ReAlloc = TRUE; Video3Touched = TRUE; @@ -2116,7 +2135,7 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, } if (Port->Front[1]) /* We're double buffering */ - ViaSwovCopy(pVia, Port->Front[0], buf); + ViaSwovCopy(pScrn, Port->Front[0], buf); ViaHQVInit(Swov); ViaVideo3Init(Swov); @@ -2148,7 +2167,7 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, ViaVideo3Format(Swov); if (Port->Front[1]) /* We're double buffering */ - ViaSwovCopy(pVia, Port->Front[0], buf); + ViaSwovCopy(pScrn, Port->Front[0], buf); } else if ((Port->Width != width) || (Port->Height != height)) { /* resize */ ReAlloc = TRUE; @@ -2165,13 +2184,13 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, } if (Port->Front[1]) /* We're double buffering */ - ViaSwovCopy(pVia, Port->Front[0], buf); + ViaSwovCopy(pScrn, Port->Front[0], buf); } else { /* normal case -- copy now, cut down on idle time */ if (Port->Front[1]) { /* We're double buffering */ struct ViaMem *Mem = Port->Front[0]; Port->Front[0] = Port->Front[1]; Port->Front[1] = Mem; - ViaSwovCopy(pVia, Port->Front[0], buf); + ViaSwovCopy(pScrn, Port->Front[0], buf); } ViaHQVIdle(Swov); } @@ -2220,19 +2239,19 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, /* Double init to avoid flashing old memory content */ if (!Swov->Active && (pVia->Chipset == VT3122) && VT3122_REV_IS_AX(pVia->ChipRev)) { - ViaHQVFlip(pVia, buf); + ViaHQVFlip(pScrn, buf); ViaSwovFireWait(Swov); ViaVideo3Fire(Swov); ViaHQVFlipInitWait(Swov); - ViaHQVFlip(pVia, NULL); + ViaHQVFlip(pScrn, NULL); } else { if (Video3Touched) { ViaSwovFireWait(Swov); ViaVideo3Fire(Swov); } - ViaHQVFlip(pVia, buf); + ViaHQVFlip(pScrn, buf); } Swov->Active = TRUE; @@ -2294,7 +2313,7 @@ ViaSwovReputImage(ScrnInfoPtr pScrn, short drw_x, short drw_y, ViaSwovFireWait(Swov); ViaVideo3Fire(Swov); - ViaHQVFlip(VIAPTR(pScrn), NULL); + ViaHQVFlip(pScrn, NULL); Swov->frameX0 = pScrn->frameX0; Swov->frameY0 = pScrn->frameY0; @@ -2529,6 +2548,7 @@ ViaStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) Port->Drw_H = 0; ViaMpegStop(pScrn); + ViaSubPictureStop(pScrn); } } @@ -2677,7 +2697,10 @@ ViaVideoInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) Swov->Port = ViaXvPortInit(pScreen); - ViaMpegInit(pScrn, pScreen); + /* Init our own little playground. */ + ViaMpegInit(pScrn); + ViaSubPictureInit(pScrn); + XumaInit(pScrn); Swov->Adaptor = ViaXvAdaptorInit(pScrn); @@ -2708,6 +2731,7 @@ ViaVideoDestroy(ScrnInfoPtr pScrn) ViaStopVideo(pScrn, Swov->Port, TRUE); ViaMpegDestroy(pScrn); + ViaSubPictureDestroy(pScrn); /* Now tear down the wallpaper */ xfree(Swov->Adaptors); diff --git a/src/via_video.h b/src/via_video.h index da259bf..a7c89a6 100644 --- a/src/via_video.h +++ b/src/via_video.h @@ -133,6 +133,9 @@ struct ViaSwov { /* MPEG engine handling */ struct ViaMpeg *Mpeg; + + /* SubPicture handling */ + struct ViaSubPicture *SubPicture; }; #endif /* _VIA_VIDEO_H_ */ -- cgit v1.2.3