summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-11-04 15:57:12 -0200
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-11-04 15:57:12 -0200
commit1d7b9547e1d37601f14410857c22f256e5c74f14 (patch)
tree435e5494c22952c20843eb6282ccf0f67df18fc3
parent93308d067c93126dd0aba9b718d9e0ba28dde9f4 (diff)
Add CSCVideo option to smi 501/502.
This code is an adaptation of SMI sample implementation. CSCVideo is an alternate way to render video, that should reduce memory bandwidth usage, and uses the color space conversion hardware to render video directly to the framebuffer memory. When using randr dual head mode, currently only XAA is supported. As it has a fixed format framebuffer (when using the Virtual xorg.conf option). This patch also ensures that pScrn->displayWidth, pScrn->virtualX and pScrn->virtualY are only changed by the driver when using EXA.
-rw-r--r--src/smi.h12
-rw-r--r--src/smi_accel.c13
-rw-r--r--src/smi_crtc.c12
-rw-r--r--src/smi_driver.c20
-rw-r--r--src/smi_video.c382
-rw-r--r--src/smi_xaa.c3
6 files changed, 367 insertions, 75 deletions
diff --git a/src/smi.h b/src/smi.h
index ccc1eab..0a51c23 100644
--- a/src/smi.h
+++ b/src/smi.h
@@ -126,7 +126,15 @@ typedef struct
OptionInfoPtr Options;
Bool Dualhead;
+
+ /* Don't attempt to program a video mode. Use kernel framebuffer
+ * mode instead. */
Bool UseFBDev;
+
+ /* CSC video uses color space conversion to render video directly to
+ * the framebuffer, without using an overlay. */
+ Bool CSCVideo;
+
Bool PCIBurst; /* Enable PCI burst mode for
reads? */
Bool PCIRetry; /* Enable PCI retries */
@@ -197,10 +205,6 @@ typedef struct
int GEResetCnt; /* Limit the number of errors
printed using a counter */
-
- /* XAA */
- CARD32 Stride; /* Stride of frame buffer */
-
Bool useBIOS; /* Use BIOS for mode sets */
Bool zoomOnLCD; /* Zoom on LCD */
XAAInfoRecPtr XAAInfoRec; /* XAA info Rec */
diff --git a/src/smi_accel.c b/src/smi_accel.c
index a98eb3f..fcfee41 100644
--- a/src/smi_accel.c
+++ b/src/smi_accel.c
@@ -91,15 +91,11 @@ SMI_EngineReset(ScrnInfoPtr pScrn)
{
SMIPtr pSmi = SMIPTR(pScrn);
CARD32 DEDataFormat = 0;
- int i;
+ int i, stride;
int xyAddress[] = { 320, 400, 512, 640, 800, 1024, 1280, 1600, 2048 };
ENTER();
- pSmi->Stride = ((pScrn->virtualX * pSmi->Bpp + 15) & ~15) / pSmi->Bpp;
- if(pScrn->bitsPerPixel==24)
- pSmi->Stride *= 3;
-
DEDataFormat = SMI_DEDataFormat(pScrn->bitsPerPixel);
for (i = 0; i < sizeof(xyAddress) / sizeof(xyAddress[0]); i++) {
if (xyAddress[i] == pScrn->virtualX) {
@@ -109,11 +105,14 @@ SMI_EngineReset(ScrnInfoPtr pScrn)
}
WaitIdle();
- WRITE_DPR(pSmi, 0x10, (pSmi->Stride << 16) | pSmi->Stride);
+ stride = pScrn->displayWidth;
+ if (pSmi->Bpp == 3)
+ stride *= 3;
+ WRITE_DPR(pSmi, 0x10, (stride << 16) | stride);
WRITE_DPR(pSmi, 0x1C, DEDataFormat);
WRITE_DPR(pSmi, 0x24, 0xFFFFFFFF);
WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF);
- WRITE_DPR(pSmi, 0x3C, (pSmi->Stride << 16) | pSmi->Stride);
+ WRITE_DPR(pSmi, 0x3C, (stride << 16) | stride);
WRITE_DPR(pSmi, 0x40, pSmi->FBOffset >> 3);
WRITE_DPR(pSmi, 0x44, pSmi->FBOffset >> 3);
diff --git a/src/smi_crtc.c b/src/smi_crtc.c
index 8ca5ec5..d061ad5 100644
--- a/src/smi_crtc.c
+++ b/src/smi_crtc.c
@@ -243,13 +243,13 @@ SMI_CrtcConfigResize(ScrnInfoPtr pScrn,
pScrn->displayWidth = aligned_pitch / pSmi->Bpp;
pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen),
-1, -1, -1, -1, aligned_pitch, NULL);
- }
- /* Modify the screen dimensions */
- pScrn->virtualX = width;
- pScrn->virtualY = height;
- pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen),
- width, height, -1, -1, 0, NULL);
+ /* Modify the screen dimensions */
+ pScrn->virtualX = width;
+ pScrn->virtualY = height;
+ pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen),
+ width, height, -1, -1, 0, NULL);
+ }
/* Setup each crtc video processor */
for(i=0;i<crtcConf->num_crtc;i++){
diff --git a/src/smi_driver.c b/src/smi_driver.c
index 299772a..9bfc712 100644
--- a/src/smi_driver.c
+++ b/src/smi_driver.c
@@ -166,6 +166,7 @@ typedef enum
OPTION_ACCELMETHOD,
OPTION_PANEL_SIZE,
OPTION_USE_FBDEV,
+ OPTION_CSCVIDEO,
NUMBER_OF_OPTIONS
} SMIOpts;
@@ -191,6 +192,7 @@ static const OptionInfoRec SMIOptions[] =
{ OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE },
{ OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_USE_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CSCVIDEO, "CSCVideo", OPTV_BOOLEAN, {0}, TRUE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -884,6 +886,24 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
pSmi->useEXA ? "EXA" : "XAA");
}
+ if (IS_MSOC(pSmi)) {
+ pSmi->CSCVideo = !pSmi->useEXA || !pSmi->Dualhead;
+ from = X_DEFAULT;
+ if (xf86GetOptValBool(pSmi->Options, OPTION_CSCVIDEO, &pSmi->CSCVideo)) {
+ from = X_CONFIG;
+
+ /* FIXME */
+ if (pSmi->CSCVideo && pSmi->useEXA && pSmi->Dualhead) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "CSCVideo requires XAA or EXA in single head mode.\n");
+ pSmi->CSCVideo = FALSE;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "CSC Video %sabled\n",
+ pSmi->CSCVideo ? "en" : "dis");
+ }
+
SMI_MapMmio(pScrn);
SMI_DetectMem(pScrn);
SMI_MapMem(pScrn);
diff --git a/src/smi_video.c b/src/smi_video.c
index 89b41ca..d340f93 100644
--- a/src/smi_video.c
+++ b/src/smi_video.c
@@ -1,8 +1,8 @@
-/* Header: //Mercury/Projects/archives/XFree86/4.0/smi_video.c.-arc 1.14 30 Nov 2000 16:51:40 Frido $ */
/*
Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
-Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved.
+Copyright (C) 2000,2008 Silicon Motion, Inc. All Rights Reserved.
Copyright (C) 2001 Corvin Zahn. All Rights Reserved.
+Copyright (C) 2008 Mandriva Linux. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
@@ -27,18 +27,25 @@ sale, use or other dealings in this Software without prior written
authorization from the XFree86 Project and silicon Motion.
*/
+
/*
-this is a heavy modified version of the V1.2.2 original siliconmotion driver.
-- SAA7111 support
-- supports attributes: XV_ENCODING, XV_BRIGHTNESS, XV_CONTRAST,
- XV_SATURATION, XV_HUE, XV_COLORKEY, XV_INTERLACED
- XV_CAPTURE_BRIGHTNESS can be used to set brightness in the capture device
-- bug fixes
-- tries not to use acceleration functions
-- interlaced video for double vertical resolution
-
-Author of changes: Corvin Zahn <zahn@zac.de>
-Date: 2.11.2001
+ Corvin Zahn <zahn@zac.de> Date: 2.11.2001
+ - SAA7111 support
+ - supports attributes: XV_ENCODING, XV_BRIGHTNESS, XV_CONTRAST,
+ XV_SATURATION, XV_HUE, XV_COLORKEY, XV_INTERLACED
+ XV_CAPTURE_BRIGHTNESS can be used to set brightness in the capture device
+ - bug fixes
+ - tries not to use acceleration functions
+ - interlaced video for double vertical resolution
+ XV_INTERLACED = 0: only one field of an interlaced video signal is
+ displayed:
+ -> half vertical resolution, but no comb like artifacts
+ from moving vertical edges
+ XV_INTERLACED = 1: both fields of an interlaced video signal are
+ displayed:
+ -> full vertical resolution, but comb like artifacts from
+ moving vertical edges
+ The default value can be set with the driver option Interlaced
*/
@@ -51,22 +58,6 @@ Date: 2.11.2001
#include "xf86Crtc.h"
-/*
-
-new attribute:
-
-XV_INTERLACED = 0: only one field of an interlaced video signal is displayed:
- -> half vertical resolution, but no comb like artifacts from
- moving vertical edges
-XV_INTERLACED = 1: both fields of an interlaced video signal are displayed:
- -> full vertical resolution, but comb like artifacts from
- moving vertical edges
-
-The default value can be set with the driver option Interlaced
-
-*/
-
-
#undef MIN
#undef ABS
#undef CLAMP
@@ -118,6 +109,13 @@ 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,
+ BoxPtr dstBox, short vid_w, short vid_h,
+ short drw_w, short drw_h,
+ RegionPtr clipboxes);
static void SMI_DisplayVideo0501(ScrnInfoPtr pScrn, int id, int offset,
short width, short height, int pitch,
int x1, int y1, int x2, int y2,
@@ -135,8 +133,15 @@ static void SMI_InitOffscreenImages(ScreenPtr pScreen);
static void SMI_VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area);
static CARD32 SMI_AllocateMemory(ScrnInfoPtr pScrn, void **mem_struct, int size);
static void SMI_FreeMemory(ScrnInfoPtr pScrn, void *mem_struct);
-
+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);
@@ -1147,10 +1152,7 @@ SMI_PutVideo(
if (pSmi->ByteSwap)
cpr00 |= 0x00004000;
- fbPitch = pSmi->Stride;
- if (pSmi->Bpp != 3) {
- fbPitch *= pSmi->Bpp;
- }
+ fbPitch = (pScrn->displayWidth * pSmi->Bpp + 15) & ~15;
if (vid_w <= drw_w) {
xscale = (256 * vid_w / drw_w) & 0xFF;
@@ -1483,8 +1485,8 @@ SMI_PutImage(
short src_h,
short drw_w,
short drw_h,
- int id,
- unsigned char *buf,
+ int id,
+ unsigned char *buf,
short width,
short height,
Bool sync,
@@ -1517,15 +1519,23 @@ SMI_PutImage(
dstBox.x2 = drw_x + drw_w;
dstBox.y2 = drw_y + drw_h;
- if(!xf86_crtc_clip_video_helper(pScrn, &crtc, NULL, &dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
- RETURN(Success);
-
- /* Transform dstBox to the CRTC coordinates */
- dstBox.x1 -= crtc->x;
- dstBox.y1 -= crtc->y;
- dstBox.x2 -= crtc->x;
- dstBox.y2 -= crtc->y;
-
+ if (pSmi->CSCVideo) {
+ if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
+ width, height))
+ RETURN(Success);
+ }
+ else {
+ if (!xf86_crtc_clip_video_helper(pScrn, &crtc, NULL, &dstBox,
+ &x1, &x2, &y1, &y2, clipBoxes,
+ width, height))
+ RETURN(Success);
+
+ /* Transform dstBox to the CRTC coordinates */
+ dstBox.x1 -= crtc->x;
+ dstBox.y1 -= crtc->y;
+ dstBox.x2 -= crtc->x;
+ dstBox.y2 -= crtc->y;
+ }
switch (id) {
case FOURCC_YV12:
@@ -1533,14 +1543,20 @@ SMI_PutImage(
offset2 = srcPitch * height;
srcPitch2 = ((width >> 1) + 3) & ~3;
offset3 = offset2 + (srcPitch2 * (height >> 1));
- dstPitch = ((width << 1) + 15) & ~15;
+ if (pSmi->CSCVideo)
+ dstPitch = (((width >> 1) + 15) & ~15) << 1;
+ else
+ dstPitch = ((width << 1) + 15) & ~15;
break;
case FOURCC_I420:
srcPitch = (width + 3) & ~3;
offset3 = srcPitch * height;
srcPitch2 = ((width >> 1) + 3) & ~3;
offset2 = offset3 + (srcPitch2 * (height >> 1));
- dstPitch = ((width << 1) + 15) & ~15;
+ if (pSmi->CSCVideo)
+ dstPitch = (((width >> 1) + 15) & ~15) << 1;
+ else
+ dstPitch = ((width << 1) + 15) & ~15;
break;
case FOURCC_RV24:
bpp = 3;
@@ -1582,10 +1598,25 @@ SMI_PutImage(
tmp = ((top >> 1) * srcPitch2) + (left >> 2);
offset2 += tmp;
offset3 += tmp;
- nLines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
- xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1),
- buf + offset2, buf + offset3, dstStart,
- srcPitch, srcPitch2, dstPitch, nLines, nPixels);
+
+ if (id == FOURCC_I420) {
+ tmp = offset2;
+ offset2 = offset3;
+ offset3 = tmp;
+ }
+
+ if (pSmi->CSCVideo)
+ CopyYV12ToVideoMem(buf,
+ buf + offset2, buf + offset3,
+ dstStart, srcPitch, srcPitch2, dstPitch,
+ height, width);
+ else {
+ nLines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
+ xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1),
+ buf + offset2, buf + offset3, dstStart,
+ srcPitch, srcPitch2, dstPitch, nLines,
+ nPixels);
+ }
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
@@ -1599,17 +1630,24 @@ SMI_PutImage(
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->CSCVideo)
+ xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY],
+ clipBoxes);
}
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 if (IS_MSOC(pSmi)) {
+ if (pSmi->CSCVideo)
+ SMI_DisplayVideo0501_CSC(pScrn, id, offset, width, height, dstPitch,
+ x1, y1, x2, y2, &dstBox,
+ src_w, src_h, drw_w, drw_h, clipBoxes);
+ else
+ SMI_DisplayVideo0501(pScrn, id, offset, width, height, dstPitch,
+ x1, y1, x2, y2, &dstBox, src_w, src_h,
+ drw_w, drw_h);
+ }
else{
if(!pSmi->Dualhead || crtc == crtcConf->crtc[1])
SMI_DisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2,
@@ -1779,6 +1817,176 @@ 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,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipboxes)
+{
+ CARD32 ScaleXn, ScaleXd, ScaleYn, ScaleYd;
+ CARD32 SrcTn, SrcTd, SrcLn, SrcLd;
+ CARD32 SrcRn, SrcRd, SrcBn, SrcBd;
+ CARD32 SrcDimX, SrcDimY, DestDimX, DestDimY;
+ CARD32 SrcFormat, DstFormat, HFilter, VFilter, byOrder;
+ CARD32 SrcYBase, SrcUBase, SrcVBase, SrcYPitch, SrcUVPitch;
+ CARD32 DestPitch, DestHeight, DestWidth, DestBpp;
+ CARD32 SrcBpp = 0, SrcLnAdd = 0;
+ SMIPtr pSmi = SMIPTR(pScrn);
+ BoxPtr pbox = REGION_RECTS(clipboxes);
+ int i, nbox = REGION_NUM_RECTS(clipboxes);
+ xRectangle rect;
+ CARD32 CSC_Control;
+
+ ENTER();
+
+ if (!pScrn->vtSema)
+ return;
+
+ SrcYBase = offset;
+ SrcYPitch = pitch;
+
+ DestPitch = (pScrn->displayWidth * pSmi->Bpp + 15) & ~15;
+ DestBpp = pSmi->Bpp;
+
+ byOrder = 0;
+
+ ScaleXn = (vid_w - 1) / (drw_w - 1);
+ ScaleXd = ((vid_w - 1) << 13) / (drw_w - 1) - (ScaleXn << 13);
+
+ ScaleYn = (vid_h - 1) / (drw_h - 1);
+ ScaleYd = ((vid_h - 1) << 13) / (drw_h - 1) - (ScaleYn << 13);
+
+ for (i = 0; i < nbox; i++, pbox++) {
+ rect.x = pbox->x1;
+ rect.y = pbox->y1;
+ rect.width = pbox->x2 - pbox->x1;
+ rect.height = pbox->y2 - pbox->y1;
+
+ DestHeight = rect.height;
+ DestWidth = rect.width;
+
+ 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;
+
+ case FOURCC_YUY2:
+ case FOURCC_RV16:
+ 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 = 1;
+
+ SrcLn = (rect.x - dstBox->x1) * (vid_w - 1) / (drw_w - 1);
+ SrcLd = ((rect.x - dstBox->x1) << 13) * 1.0 *
+ (vid_w - 1) / (drw_w - 1) - (SrcLn << 13);
+
+ SrcRn = (rect.x + rect.width - dstBox->x1) *
+ (vid_w - 1) / (drw_w-1);
+ SrcRd = ((rect.x + rect.width - dstBox->x1) << 13) * 1.0 *
+ (vid_w - 1) / (drw_w - 1) - (SrcRn << 13);
+
+ SrcTn = (rect.y - dstBox->y1) * (vid_h - 1) / (drw_h - 1);
+ SrcTd = ((rect.y - dstBox->y1) << 13) * 1.0 *
+ (vid_h-1) / (drw_h - 1) - (SrcTn << 13);
+
+ SrcBn = (rect.y + rect.height - dstBox->y1) *
+ (vid_h - 1) / (drw_h - 1);
+ SrcBd = ((rect.y + rect.height - dstBox->y1) << 13) * 1.0 *
+ (vid_h - 1) / (drw_h - 1) - (SrcBn << 13);
+
+ SrcDimX = (SrcRd == 0) ? (SrcRn - SrcLn + 1) : (SrcRn - SrcLn + 2);
+ SrcDimY = (SrcBd == 0) ? (SrcBn - SrcTn + 1) : (SrcBn - SrcTn + 2);
+
+ DestDimX = rect.width;
+ DestDimY = rect.height;
+
+ 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, DestDimX << 16 | DestDimY);
+ WRITE_DPR(pSmi, 0xF0, (DestPitch >> 4) << 16 | DestHeight);
+ 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);
+ WRITE_DPR(pSmi, 0xF8, 0);
+
+ CSC_Control = (1 << 31 | SrcFormat << 28 | DstFormat << 26 |
+ HFilter << 25 | VFilter << 24 | byOrder << 23);
+ SMI_CSC_Start(pSmi, CSC_Control);
+ }
+
+ LEAVE();
+}
+
+static void
SMI_DisplayVideo0501(ScrnInfoPtr pScrn,
int id,
int offset,
@@ -2164,6 +2372,66 @@ SMI_FreeMemory(
LEAVE();
}
+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)
+{
+ int j = height;
+
+ ENTER();
+
+ /* copy 1 data */
+ while (j -- > 0) {
+ memcpy(dst, src1, width);
+ src1 += src1Pitch;
+ dst += dstPitch;
+ }
+ /* copy 2 data */
+ j = height / 2;
+ while (j -- > 0) {
+ memcpy(dst, src2, width / 2);
+ src2 += src23Pitch;
+ dst += dstPitch / 2;
+ }
+ /* copy 3 data */
+ j = height / 2;
+ while (j -- > 0) {
+ memcpy(dst, src3, width / 2);
+ src3 += src23Pitch;
+ dst += dstPitch / 2;
+ }
+
+ 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,
diff --git a/src/smi_xaa.c b/src/smi_xaa.c
index 30f8608..31790bf 100644
--- a/src/smi_xaa.c
+++ b/src/smi_xaa.c
@@ -583,7 +583,8 @@ SMI_SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int rop,
#endif
if (pScrn->bitsPerPixel <= 16) {
/* PDR#950 */
- CARD8* pattern = pSmi->FBBase + (patx + paty * pSmi->Stride) * pSmi->Bpp;
+ CARD8* pattern = pSmi->FBBase +
+ (patx + paty * pScrn->displayWidth) * pSmi->Bpp;
WaitIdle();
WRITE_DPR(pSmi, 0x0C, SMI_BITBLT | SMI_COLOR_PATTERN);