summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2006-11-15 14:20:56 +0100
committerLuc Verhaegen <libv@skynet.be>2006-11-15 14:20:56 +0100
commitbd3a6d5cb1a544ccae9eecf7cb0b40fb6bdac287 (patch)
tree5eb3f553c306c01d0f3d1755b89e3f410a5a6e7a
parentceb75cceb1486393fdcd553236473233cda8100c (diff)
xuma: add subpicture support.xuma
* 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.
-rw-r--r--lib/xuma/xuma.c120
-rw-r--r--lib/xuma/xumalib.h11
-rw-r--r--lib/xuma/xumaproto.h60
-rw-r--r--src/via_driver.h7
-rw-r--r--src/via_mpeg.c400
-rw-r--r--src/via_mpeg.h31
-rw-r--r--src/via_mpegregs.h28
-rw-r--r--src/via_video.c58
-rw-r--r--src/via_video.h3
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();
@@ -282,6 +266,64 @@ XumaGetCapabilities(Display *dpy, int port)
}
/*
+ *
+ */
+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.
*/
unsigned char
@@ -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.
@@ -114,6 +113,33 @@ typedef struct {
#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
*/
typedef struct {
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
@@ -66,6 +66,122 @@
/*
*
+ * 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
+/*
+ *
*/
static void
ViaMpegPrintRegs(ScrnInfoPtr pScrn)
@@ -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);
}
@@ -612,6 +798,102 @@ XumaProcQueryCapabilities(ClientPtr client)
*
*/
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);
+}
+
+/*
+ *
+ */
+static int
XumaProcGrabBuffer(ClientPtr client)
{
ExtensionEntry *MPEGExt;
@@ -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_ */