summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/smi_video.c181
1 files changed, 47 insertions, 134 deletions
diff --git a/src/smi_video.c b/src/smi_video.c
index 810b0c2..df11a67 100644
--- a/src/smi_video.c
+++ b/src/smi_video.c
@@ -109,7 +109,6 @@ static int SMI_QueryImageAttributes(ScrnInfoPtr pScrn,
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_CSC_Start(SMIPtr pSmi, CARD32 CSC_Control);
static void SMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset,
short width, short height, int pitch,
int x1, int y1, int x2, int y2,
@@ -138,10 +137,6 @@ static void CopyYV12ToVideoMem(unsigned char *src1, unsigned char *src2,
unsigned char *src3, unsigned char *dst,
int src1Pitch, int src23Pitch, int dstPitch,
int height, int width);
-static void SMI_CopyYV12Data(unsigned char *src1, unsigned char *src2,
- unsigned char *src3, unsigned char *dst,
- int srcPitch1, int srcPitch2, int dstPitch,
- int height, int width);
static int SMI_AllocSurface(ScrnInfoPtr pScrn,
int id, unsigned short width, unsigned short height,
XF86SurfacePtr surface);
@@ -621,7 +616,6 @@ void
SMI_InitVideo(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- SMIPtr psmi = SMIPTR(pScrn);
XF86VideoAdaptorPtr *ptrAdaptors, *newAdaptors = NULL;
XF86VideoAdaptorPtr newAdaptor = NULL;
int numAdaptors;
@@ -1817,29 +1811,6 @@ SMI_DisplayVideo(
}
static void
-SMI_CSC_Start(SMIPtr pSmi, CARD32 CSC_Control)
-{
- CARD32 CSC_Control_Old;
-
- while (1) {
- CSC_Control_Old = READ_DPR(pSmi, 0xFC);
- if (CSC_Control_Old & 0x80000000)
- continue;
- else {
- CSC_Control |= 1 << 31;
- WRITE_DPR(pSmi, 0xFC, CSC_Control);
- break;
- }
- }
- /* CSC stop */
- while (1) {
- CSC_Control_Old = READ_DPR(pSmi, 0xFC);
- if (!(CSC_Control_Old & 0x80000000))
- break;
- }
-}
-
-static void
SMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset,
short width, short height, int pitch,
int x1, int y1, int x2, int y2, BoxPtr dstBox,
@@ -1848,71 +1819,57 @@ SMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset,
{
int32_t ScaleXn, ScaleXd, ScaleYn, ScaleYd;
int32_t SrcTn, SrcTd, SrcLn, SrcLd;
+ int32_t SrcRn, SrcBn;
int32_t SrcDimX, SrcDimY;
- int32_t SrcFormat, DstFormat, HFilter, VFilter, byOrder;
int32_t SrcYBase, SrcUBase, SrcVBase, SrcYPitch, SrcUVPitch;
- int32_t rect_x, rect_y, rect_w, rect_h;
- int32_t DestPitch, DestBpp;
- int32_t SrcBpp = 0, SrcLnAdd = 0;
+ int32_t DestPitch;
SMIPtr pSmi = SMIPTR(pScrn);
BoxPtr pbox = REGION_RECTS(clipboxes);
int i, nbox = REGION_NUM_RECTS(clipboxes);
- int32_t CSC_Control;
- float wscale, hscale;
+ int32_t rect_x, rect_y, rect_w, rect_h, csc;
+ float Hscale, Vscale;
ENTER();
- if (!pScrn->vtSema)
- return;
-
SrcYBase = offset;
SrcYPitch = pitch;
- /* Don't need to round as it is shifted right */
- DestPitch = pScrn->displayWidth * pSmi->Bpp;
- DestBpp = pSmi->Bpp;
+ DestPitch = (pScrn->displayWidth * pSmi->Bpp + 15) & ~15;
- byOrder = 0;
+ Hscale = (vid_w - 1) / (float)(drw_w - 1);
+ ScaleXn = Hscale;
+ ScaleXd = ((vid_w - 1) << 13) / (drw_w - 1) - (ScaleXn << 13);
- wscale = (vid_w - 1) / (float)(drw_w - 1);
- hscale = (vid_h - 1) / (float)(drw_h - 1);
-
- ScaleXn = wscale;
- ScaleXd = ((vid_w - 1) << 13) / (float)(drw_w - 1) - (ScaleXn << 13);
-
- ScaleYn = hscale;
- ScaleYd = ((vid_h - 1) << 13) / (float)(drw_h - 1) - (ScaleYn << 13);
+ Vscale = (vid_h - 1) / (float)(drw_h - 1);
+ ScaleYn = Vscale;
+ ScaleYd = ((vid_h - 1) << 13) / (drw_h - 1) - (ScaleYn << 13);
+ /* CSC constants */
+ WRITE_DPR(pSmi, 0xcc, 0);
/* Use start of framebuffer as base offset */
- WRITE_DPR(pSmi, 0xF8, 0);
+ WRITE_DPR(pSmi, 0xf8, 0);
+
+ csc = (1 << 31) | (1 << 25);
+ if (pSmi->Bpp > 2)
+ csc |= 1 << 26;
+ if (id == FOURCC_YV12 || id == FOURCC_I420)
+ csc |= 2 << 28;
for (i = 0; i < nbox; i++, pbox++) {
rect_x = pbox->x1;
rect_y = pbox->y1;
- rect_w = pbox->x2 - rect_x;
- rect_h = pbox->y2 - rect_y;
+ rect_w = pbox->x2 - pbox->x1;
+ rect_h = pbox->y2 - pbox->y1;
switch (id) {
case FOURCC_YV12:
- SrcFormat = 2;
- byOrder = 0;
- SrcLnAdd = 0;
-
- SrcYPitch = pitch;
SrcUVPitch = SrcYPitch / 2;
-
SrcVBase = SrcYBase + SrcYPitch * height;
SrcUBase = SrcVBase + SrcUVPitch * height / 2;
break;
case FOURCC_I420:
- SrcFormat = 2;
- byOrder = 0;
- SrcLnAdd = 0;
-
- SrcYPitch = pitch;
SrcUVPitch = SrcYPitch / 2;
-
SrcUBase = SrcYBase + SrcYPitch * height;
SrcVBase = SrcUBase + SrcUVPitch * height / 2;
break;
@@ -1922,60 +1879,42 @@ SMI_DisplayVideo0501_CSC(ScrnInfoPtr pScrn, int id, int offset,
case FOURCC_RV32:
SrcUBase = SrcVBase = SrcYBase;
SrcUVPitch = SrcYPitch;
- SrcFormat = 0;
- byOrder = 0;
- SrcBpp = 16 / 8;
- SrcLnAdd = 0;
break;
- }
- switch (DestBpp) {
- case 2:
- DstFormat = 0;
- break;
- case 4:
- DstFormat = 1;
- break;
default:
return;
}
- HFilter = 1;
-
- /* VFilter causes corruption/noisy in the last video pixel line,
- * regardless of 1x1 or scaling up/down the video. */
- VFilter = 0;
-
- SrcLn = rect_x - dstBox->x1;
- SrcLd = SrcLn << 13;
- SrcLn *= wscale;
- SrcLd *= wscale;
-
- SrcTn = rect_y - dstBox->y1;
- SrcTd = SrcTn << 13;
- SrcTn *= hscale;
- SrcTd *= hscale;
-
- SrcDimX = rect_w * wscale;
- SrcDimY = rect_h * hscale;
-
- WRITE_DPR(pSmi, 0xCC, 0x0);
- WRITE_DPR(pSmi, 0xD0, (SrcLn + SrcLnAdd << 16) | SrcLd);
- WRITE_DPR(pSmi, 0xD4, SrcTn << 16 | SrcTd);
- WRITE_DPR(pSmi, 0xE0, SrcDimX << 16 | SrcDimY);
- WRITE_DPR(pSmi, 0xE4, (SrcYPitch >> 4) << 16 | (SrcUVPitch >> 4));
- WRITE_DPR(pSmi, 0xE8, rect_x << 16 | rect_y);
- WRITE_DPR(pSmi, 0xEC, rect_w << 16 | rect_h);
- WRITE_DPR(pSmi, 0xF0, (DestPitch >> 4) << 16 | rect_h);
- WRITE_DPR(pSmi, 0xF4, (ScaleXn << 13 | ScaleXd) << 16 |
+ SrcLn = (rect_x - dstBox->x1) * Hscale;
+ SrcLd = ((rect_x - dstBox->x1) << 13) * Hscale - (SrcLn << 13);
+ SrcRn = (rect_x + rect_w - dstBox->x1) * Hscale;
+
+ SrcTn = (rect_y - dstBox->y1) * Vscale;
+ SrcTd = ((rect_y - dstBox->y1) << 13) * Vscale - (SrcTn << 13);
+ SrcBn = (rect_y + rect_h - dstBox->y1) * Vscale;
+
+ SrcDimX = SrcRn - SrcLn + 2;
+ SrcDimY = SrcBn - SrcTn + 2;
+
+ WRITE_DPR(pSmi, 0xD0, (SrcLn << 16) | SrcLd);
+ WRITE_DPR(pSmi, 0xD4, (SrcTn << 16) | SrcTd);
+ WRITE_DPR(pSmi, 0xE0, (SrcDimX << 16) | SrcDimY);
+ WRITE_DPR(pSmi, 0xE4, ((SrcYPitch >> 4) << 16) | (SrcUVPitch >> 4));
+ WRITE_DPR(pSmi, 0xE8, (rect_x << 16) | rect_y);
+ WRITE_DPR(pSmi, 0xEC, (rect_w << 16) | rect_h);
+ WRITE_DPR(pSmi, 0xF0, ((DestPitch >> 4) << 16) | rect_h);
+ WRITE_DPR(pSmi, 0xF4, (((ScaleXn << 13) | ScaleXd) << 16) |
(ScaleYn << 13 | ScaleYd));
WRITE_DPR(pSmi, 0xC8, SrcYBase);
WRITE_DPR(pSmi, 0xD8, SrcUBase);
WRITE_DPR(pSmi, 0xDC, SrcVBase);
- CSC_Control = (1 << 31 | SrcFormat << 28 | DstFormat << 26 |
- HFilter << 25 | VFilter << 24 | byOrder << 23);
- SMI_CSC_Start(pSmi, CSC_Control);
+ while (READ_DPR(pSmi, 0xfc) & (1 << 31))
+ ;
+ WRITE_DPR(pSmi, 0xfc, csc);
+ /* CSC stop */
+ while (READ_DPR(pSmi, 0xfc) & (1 << 31))
+ ;
}
LEAVE();
@@ -2401,32 +2340,6 @@ CopyYV12ToVideoMem(unsigned char *src1, unsigned char *src2,
LEAVE();
}
-static void
-SMI_CopyYV12Data(unsigned char *src1, unsigned char *src2,
- unsigned char *src3, unsigned char *dst,
- int srcPitch1, int srcPitch2, int dstPitch,
- int height, int width)
-{
- CARD32 *pDst = (CARD32 *)dst;
- int i, j;
-
- ENTER();
-
- for (j = 0; j < height; j++) {
- for (i = 0; i < width; i++)
- pDst[i] = ( src1[i << 1] | (src1[(i << 1) + 1] << 16) |
- (src3[i ] << 8) | (src2[i ] << 24));
- pDst += dstPitch >> 2;
- src1 += srcPitch1;
- if (j & 1) {
- src2 += srcPitch2;
- src3 += srcPitch2;
- }
- }
-
- LEAVE();
-}
-
static int
SMI_AllocSurface(
ScrnInfoPtr pScrn,