diff options
-rw-r--r-- | src/smi_video.c | 189 |
1 files changed, 173 insertions, 16 deletions
diff --git a/src/smi_video.c b/src/smi_video.c index 4809c31..0076f43 100644 --- a/src/smi_video.c +++ b/src/smi_video.c @@ -157,6 +157,11 @@ static Bool SMI_ClipVideo(ScrnInfoPtr pScrn, BoxPtr dst, static void SMI_DisplayVideo(ScrnInfoPtr pScrn, int id, int offset, short width, short height, int pitch, int x1, int y1, int x2, int y2, BoxPtr dstBox, short vid_w, short vid_h, short drw_w, short drw_h); +static void SMI_DisplayVideo0501(ScrnInfoPtr pScrn, int id, int offset, + short width, short height, int pitch, + int x1, int y1, int x2, int y2, + BoxPtr dstBox, short vid_w, short vid_h, + short drw_w, short drw_h); static void SMI_DisplayVideo0730(ScrnInfoPtr pScrn, int id, int offset, short width, short height, int pitch, int x1, int y1, int x2, int y2, BoxPtr dstBox, short vid_w, short vid_h, short drw_w, short drw_h); @@ -395,6 +400,51 @@ static XF86ImageRec SMI_VideoImages[] = /**************************************************************************/ +static XF86ImageRec SMI501_VideoImages[] = { + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_I420, + { + FOURCC_RV16, /* id */ + XvRGB, /* type */ + LSBFirst, /* byte_order */ + {'R', 'V', '1', '6', + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /* guid */ + 16, /* bits_per_pixel */ + XvPacked, /* format */ + 1, /* num_planes */ + 16, /* depth */ + 0x001F, 0x07E0, 0xF800, /* red_mask, green, blue */ + 0, 0, 0, /* y_sample_bits, u, v */ + 0, 0, 0, /* horz_y_period, u, v */ + 0, 0, 0, /* vert_y_period, u, v */ + {'R', 'V', 'B'}, /* component_order */ + XvTopToBottom /* scaline_order */ + }, + { + FOURCC_RV32, /* id */ + XvRGB, /* type */ + LSBFirst, /* byte_order */ + {'R', 'V', '3', '2', + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /* guid */ + 32, /* bits_per_pixel */ + XvPacked, /* format */ + 1, /* num_planes */ + 24, /* depth */ + 0x0000FF, 0x00FF00, 0xFF0000, /* red_mask, green, blue */ + 0, 0, 0, /* y_sample_bits, u, v */ + 0, 0, 0, /* horz_y_period, u, v */ + 0, 0, 0, /* vert_y_period, u, v */ + {'R', 'V', 'B'}, /* component_order */ + XvTopToBottom /* scaline_order */ + }, +}; + +/**************************************************************************/ /** * SAA7111 video decoder register values @@ -871,11 +921,17 @@ SMI_SetupVideo(ScreenPtr pScreen) ptrAdaptor->nAttributes = nElems(SMI_VideoAttributes); ptrAdaptor->pAttributes = SMI_VideoAttributes; - ptrAdaptor->nImages = nElems(SMI_VideoImages); - ptrAdaptor->pImages = SMI_VideoImages; + if (IS_MSOC(pSmi)) { + ptrAdaptor->nImages = nElems(SMI501_VideoImages); + ptrAdaptor->pImages = SMI501_VideoImages; + } + else { + ptrAdaptor->nImages = nElems(SMI_VideoImages); + ptrAdaptor->pImages = SMI_VideoImages; + } #if SMI_USE_CAPTURE - if (pSmi->Chipset == SMI_COUGAR3DR) + if (pSmi->Chipset == SMI_COUGAR3DR || IS_MSOC(pSmi)) ptrAdaptor->PutVideo = NULL; else ptrAdaptor->PutVideo = SMI_PutVideo; @@ -1625,19 +1681,23 @@ SMI_PutImage( break; } - if (!REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes)) - { - REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes); + if (IS_MSOC(pSmi) || + !REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes)) { + REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes); xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY], clipBoxes); } - if (pSmi->Chipset != SMI_COUGAR3DR) - SMI_DisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, - &dstBox, src_w, src_h, drw_w, drw_h); - else + if (pSmi->Chipset == SMI_COUGAR3DR) SMI_DisplayVideo0730(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + else if (IS_MSOC(pSmi)) + SMI_DisplayVideo0501(pScrn, id, offset, width, height, dstPitch, + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, + drw_h); + else + SMI_DisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, + &dstBox, src_w, src_h, drw_w, drw_h); pPort->videoStatus = CLIENT_VIDEO_ON; LEAVE_PROC("SMI_PutImage"); @@ -1945,6 +2005,84 @@ SMI_DisplayVideo( } static void +SMI_DisplayVideo0501(ScrnInfoPtr pScrn, + int id, + int offset, + short width, + short height, + int pitch, + int x1, + int y1, + int x2, + int y2, + BoxPtr dstBox, + short vid_w, short vid_h, short drw_w, short drw_h) +{ + SMIPtr pSmi = SMIPTR (pScrn); + CARD32 dcr40; + int hstretch, vstretch; + + ENTER_PROC("SMI_DisplayVideo0501"); + + dcr40 = READ_DCR(pSmi, DCR40) & ~0x00003FFF; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + case FOURCC_YUY2: + dcr40 |= 0x3; + break; + + case FOURCC_RV16: + dcr40 |= 0x1; + break; + + case FOURCC_RV32: + dcr40 |= 0x2; + break; + } + + + if (drw_w > vid_w) { /* Horizontal Stretch */ + hstretch = (40960 * vid_w / drw_w + 5) / 10; + dcr40 |= 1 << 8; + } + else { /* Horizontal Shrink */ + + hstretch = ((40960 * drw_w / vid_w + 5) / 10) | 0x8000; + } + + if (drw_h > vid_h) { /* Vertical Stretch */ + vstretch = (40960 * vid_h / drw_h + 5) / 10; + dcr40 |= 1 << 9; + } + else { /* Vertical Shrink */ + + vstretch = ((40960 * drw_h / vid_h + 5) / 10) | 0x8000; + } +#if 0 + SMI_WaitForSync(pScrn); +#endif + + /* Set Color Key Enable bit */ + + WRITE_DCR(pSmi, DCR00, READ_DCR(pSmi, DCR00) | (1 << 9)); + WRITE_DCR(pSmi, DCR50, dstBox->x1 | (dstBox->y1 << 16)); + WRITE_DCR(pSmi, DCR54, dstBox->x2 | (dstBox->y2 << 16)); + WRITE_DCR(pSmi, DCR44, offset); + + WRITE_DCR(pSmi, DCR48, pitch | (pitch << 16)); + WRITE_DCR(pSmi, DCR4C, offset + (pitch * height)); + WRITE_DCR(pSmi, DCR58, (vstretch << 16) | hstretch); + WRITE_DCR(pSmi, DCR5C, 0x00000000); + WRITE_DCR(pSmi, DCR60, 0x00EDEDED); + + WRITE_DCR(pSmi, DCR40, dcr40 | (1 << 2)); + + LEAVE_PROC("SMI_DisplayVideo0501"); +} + +static void SMI_DisplayVideo0730( ScrnInfoPtr pScrn, int id, @@ -2039,6 +2177,9 @@ SMI_BlockHandler( if (pPort->offTime < currentTime.milliseconds) { if (pSmi->Chipset == SMI_COUGAR3DR) { WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); + } + else if (IS_MSOC(pSmi)) { + WRITE_DCR(pSmi, DCR40, READ_DCR(pSmi, DCR40) & ~0x00000004); } else { WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008); } @@ -2427,17 +2568,25 @@ SMI_DisplaySurface( xf86XVFillKeyHelper(surface->pScrn->pScreen, pPort->Attribute[XV_COLORKEY], clipBoxes); - if (pSmi->Chipset != SMI_COUGAR3DR) { - SMI_ResetVideo(surface->pScrn); - SMI_DisplayVideo(surface->pScrn, surface->id, surface->offsets[0], - surface->width, surface->height, surface->pitches[0], x1, y1, x2, - y2, &dstBox, vid_w, vid_h, drw_w, drw_h); - } else { + if (pSmi->Chipset == SMI_COUGAR3DR) { SMI_ResetVideo(surface->pScrn); SMI_DisplayVideo0730(surface->pScrn, surface->id, surface->offsets[0], surface->width, surface->height, surface->pitches[0], x1, y1, x2, y2, &dstBox, vid_w, vid_h, drw_w, drw_h); } + else if (IS_MSOC(pSmi)) { + SMI_ResetVideo (surface->pScrn); + SMI_DisplayVideo0501(surface->pScrn, surface->id, + surface->offsets[0], surface->width, + surface->height, surface->pitches[0], x1, y1, + x2, y2, &dstBox, vid_w, vid_h, drw_w, drw_h); + } + else { + SMI_ResetVideo(surface->pScrn); + SMI_DisplayVideo(surface->pScrn, surface->id, surface->offsets[0], + surface->width, surface->height, surface->pitches[0], x1, y1, x2, + y2, &dstBox, vid_w, vid_h, drw_w, drw_h); + } ptrOffscreen->isOn = TRUE; if (pPort->videoStatus & CLIENT_VIDEO_ON) { @@ -2506,6 +2655,14 @@ SetKeyReg(SMIPtr pSmi, int reg, int value) { if (pSmi->Chipset == SMI_COUGAR3DR) { WRITE_FPR(pSmi, reg, value); + } + else if (IS_MSOC(pSmi)) { + /* We don't change the color mask, and we don't do brightness. IF + * they write to the colorkey register, we'll write the value to the + * 501 colorkey register */ + if (FPR04 == reg) { /* Only act on colorkey value writes */ + WRITE_DCR (pSmi, DCR08, value); /* ColorKey register is DCR08 */ + } } else { WRITE_VPR(pSmi, reg, value); } |