summaryrefslogtreecommitdiff
path: root/src/nv_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nv_video.c')
-rw-r--r--src/nv_video.c641
1 files changed, 470 insertions, 171 deletions
diff --git a/src/nv_video.c b/src/nv_video.c
index e2010a9..3b2eb5b 100644
--- a/src/nv_video.c
+++ b/src/nv_video.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_video.c,v 1.11 2002/11/26 23:41:59 mvojkovi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_video.c,v 1.21 2003/11/10 18:22:24 tsi Exp $ */
#include "xf86.h"
#include "xf86_OSproc.h"
@@ -18,10 +18,10 @@
#include "fourcc.h"
#include "nv_include.h"
+#include "nv_dma.h"
-
-#define OFF_DELAY 450 /* milliseconds */
-#define FREE_DELAY 10000
+#define OFF_DELAY 500 /* milliseconds */
+#define FREE_DELAY 5000
#define OFF_TIMER 0x01
#define FREE_TIMER 0x02
@@ -29,11 +29,7 @@
#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
-
-
-#ifndef XvExtension
-void NVInitVideo(ScreenPtr pScreen) {}
-#else
+#define NUM_BLIT_PORTS 32
typedef struct _NVPortPrivRec {
short brightness;
@@ -49,13 +45,15 @@ typedef struct _NVPortPrivRec {
Time videoTime;
Bool grabbedByV4L;
Bool iturbt_709;
+ Bool blitter;
FBLinearPtr linear;
int pitch;
int offset;
} NVPortPrivRec, *NVPortPrivPtr;
-static XF86VideoAdaptorPtr NVSetupImageVideo(ScreenPtr);
+static XF86VideoAdaptorPtr NVSetupOverlayVideo(ScreenPtr);
+static XF86VideoAdaptorPtr NVSetupBlitVideo(ScreenPtr);
static void NVStopOverlay (ScrnInfoPtr);
static void NVPutOverlayImage(ScrnInfoPtr pScrnInfo,
@@ -69,10 +67,14 @@ static void NVPutOverlayImage(ScrnInfoPtr pScrnInfo,
short dst_w, short dst_h,
RegionPtr cliplist);
-static int NVSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
-static int NVGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static int NVSetOverlayPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int NVGetOverlayPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static int NVSetBlitPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int NVGetBlitPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
+
static void NVStopOverlayVideo(ScrnInfoPtr, pointer, Bool);
+static void NVStopBlitVideo(ScrnInfoPtr, pointer, Bool);
static int NVPutImage( ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char*, short, short, Bool, RegionPtr, pointer);
static void NVQueryBestSize(ScrnInfoPtr, Bool, short, short, short, short, unsigned int *, unsigned int *, pointer);
@@ -127,14 +129,36 @@ XF86AttributeRec NVAttributes[NUM_ATTRIBUTES] =
{XvSettable | XvGettable, 0, 1, "XV_ITURBT_709"}
};
-#define NUM_IMAGES_ALL 4
+#define NUM_IMAGES_YUV 4
+#define NUM_IMAGES_ALL 5
+
+#define FOURCC_RGB 0x0000003
+#define XVIMAGE_RGB \
+ { \
+ FOURCC_RGB, \
+ XvRGB, \
+ LSBFirst, \
+ { 0x03, 0x00, 0x00, 0x00, \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 32, \
+ XvPacked, \
+ 1, \
+ 24, 0x00ff0000, 0x0000ff00, 0x000000ff, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ {'B','G','R','X',\
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
static XF86ImageRec NVImages[NUM_IMAGES_ALL] =
{
XVIMAGE_YUY2,
XVIMAGE_YV12,
XVIMAGE_UYVY,
- XVIMAGE_I420
+ XVIMAGE_I420,
+ XVIMAGE_RGB
};
static void
@@ -158,7 +182,6 @@ NVResetVideo (ScrnInfoPtr pScrnInfo)
{
NVPtr pNv = NVPTR(pScrnInfo);
NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
- RIVA_HW_INST *pRiva = &(pNv->riva);
int satSine, satCosine;
double angle;
@@ -171,11 +194,11 @@ NVResetVideo (ScrnInfoPtr pScrnInfo)
if (satCosine < -1024)
satCosine = -1024;
- pRiva->PMC[0x00008910/4] = (pPriv->brightness << 16) | pPriv->contrast;
- pRiva->PMC[0x00008914/4] = (pPriv->brightness << 16) | pPriv->contrast;
- pRiva->PMC[0x00008918/4] = (satSine << 16) | (satCosine & 0xffff);
- pRiva->PMC[0x0000891C/4] = (satSine << 16) | (satCosine & 0xffff);
- pRiva->PMC[0x00008b00/4] = pPriv->colorKey;
+ pNv->PMC[0x8910/4] = (pPriv->brightness << 16) | pPriv->contrast;
+ pNv->PMC[0x8914/4] = (pPriv->brightness << 16) | pPriv->contrast;
+ pNv->PMC[0x8918/4] = (satSine << 16) | (satCosine & 0xffff);
+ pNv->PMC[0x891C/4] = (satSine << 16) | (satCosine & 0xffff);
+ pNv->PMC[0x8b00/4] = pPriv->colorKey;
}
@@ -184,9 +207,8 @@ static void
NVStopOverlay (ScrnInfoPtr pScrnInfo)
{
NVPtr pNv = NVPTR(pScrnInfo);
- RIVA_HW_INST *pRiva = &(pNv->riva);
- pRiva->PMC[0x00008704/4] = 1;
+ pNv->PMC[0x00008704/4] = 1;
}
static FBLinearPtr
@@ -242,38 +264,60 @@ static void NVFreeOverlayMemory(ScrnInfoPtr pScrnInfo)
}
+static void NVFreeBlitMemory(ScrnInfoPtr pScrnInfo)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv);
+
+ if(pPriv->linear) {
+ xf86FreeOffscreenLinear(pPriv->linear);
+ pPriv->linear = NULL;
+ }
+}
+
+
void NVInitVideo (ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
XF86VideoAdaptorPtr overlayAdaptor = NULL;
+ XF86VideoAdaptorPtr blitAdaptor = NULL;
NVPtr pNv = NVPTR(pScrn);
int num_adaptors;
- if((pScrn->bitsPerPixel != 8) && (pNv->riva.Architecture >= NV_ARCH_10))
- {
- overlayAdaptor = NVSetupImageVideo(pScreen);
+ if((pScrn->bitsPerPixel != 8) && (pNv->Architecture >= NV_ARCH_10)) {
+ overlayAdaptor = NVSetupOverlayVideo(pScreen);
if(overlayAdaptor)
NVInitOffscreenImages(pScreen);
}
+ if((pScrn->bitsPerPixel != 8) && !pNv->NoAccel)
+ blitAdaptor = NVSetupBlitVideo(pScreen);
+
num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
- if(overlayAdaptor) {
- int size = num_adaptors + 1;
+ if(blitAdaptor || overlayAdaptor) {
+ int size = num_adaptors;
- if((newAdaptors = xalloc(size * sizeof(XF86VideoAdaptorPtr*)))) {
- if(num_adaptors)
- memcpy(newAdaptors, adaptors,
- num_adaptors * sizeof(XF86VideoAdaptorPtr));
+ if(overlayAdaptor) size++;
+ if(blitAdaptor) size++;
- if(overlayAdaptor) {
- newAdaptors[num_adaptors] = overlayAdaptor;
- num_adaptors++;
+ if((newAdaptors = xalloc(size * sizeof(XF86VideoAdaptorPtr*)))) {
+ if(num_adaptors) {
+ memcpy(newAdaptors, adaptors,
+ num_adaptors * sizeof(XF86VideoAdaptorPtr));
+ }
+ if(overlayAdaptor) {
+ newAdaptors[num_adaptors] = overlayAdaptor;
+ num_adaptors++;
}
+ if(blitAdaptor) {
+ newAdaptors[num_adaptors] = blitAdaptor;
+ num_adaptors++;
+ }
adaptors = newAdaptors;
- }
+ }
}
if (num_adaptors)
@@ -284,8 +328,63 @@ void NVInitVideo (ScreenPtr pScreen)
}
+static XF86VideoAdaptorPtr
+NVSetupBlitVideo (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrnInfo);
+ XF86VideoAdaptorPtr adapt;
+ NVPortPrivPtr pPriv;
+ int i;
+
+ if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+ sizeof(NVPortPrivRec) +
+ (sizeof(DevUnion) * NUM_BLIT_PORTS))))
+ {
+ return NULL;
+ }
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = 0;
+ adapt->name = "NV Video Blitter";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = &DummyEncoding;
+ adapt->nFormats = NUM_FORMATS_ALL;
+ adapt->pFormats = NVFormats;
+ adapt->nPorts = NUM_BLIT_PORTS;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+
+ pPriv = (NVPortPrivPtr)(&adapt->pPortPrivates[NUM_BLIT_PORTS]);
+ for(i = 0; i < NUM_BLIT_PORTS; i++)
+ adapt->pPortPrivates[i].ptr = (pointer)(pPriv);
+
+ adapt->pAttributes = NULL;
+ adapt->nAttributes = 0;
+ adapt->pImages = NVImages;
+ adapt->nImages = NUM_IMAGES_ALL;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = NVStopBlitVideo;
+ adapt->SetPortAttribute = NVSetBlitPortAttribute;
+ adapt->GetPortAttribute = NVGetBlitPortAttribute;
+ adapt->QueryBestSize = NVQueryBestSize;
+ adapt->PutImage = NVPutImage;
+ adapt->QueryImageAttributes = NVQueryImageAttributes;
+
+ pPriv->videoStatus = 0;
+ pPriv->grabbedByV4L = FALSE;
+ pPriv->blitter = TRUE;
+ pPriv->doubleBuffer = FALSE;
+
+ pNv->blitAdaptor = adapt;
+
+ return adapt;
+}
+
static XF86VideoAdaptorPtr
-NVSetupImageVideo (ScreenPtr pScreen)
+NVSetupOverlayVideo (ScreenPtr pScreen)
{
ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
NVPtr pNv = NVPTR(pScrnInfo);
@@ -313,14 +412,14 @@ NVSetupImageVideo (ScreenPtr pScreen)
adapt->pAttributes = NVAttributes;
adapt->nAttributes = NUM_ATTRIBUTES;
adapt->pImages = NVImages;
- adapt->nImages = NUM_IMAGES_ALL;
+ adapt->nImages = NUM_IMAGES_YUV;
adapt->PutVideo = NULL;
adapt->PutStill = NULL;
adapt->GetVideo = NULL;
adapt->GetStill = NULL;
adapt->StopVideo = NVStopOverlayVideo;
- adapt->SetPortAttribute = NVSetPortAttribute;
- adapt->GetPortAttribute = NVGetPortAttribute;
+ adapt->SetPortAttribute = NVSetOverlayPortAttribute;
+ adapt->GetPortAttribute = NVGetOverlayPortAttribute;
adapt->QueryBestSize = NVQueryBestSize;
adapt->PutImage = NVPutImage;
adapt->QueryImageAttributes = NVQueryImageAttributes;
@@ -328,11 +427,12 @@ NVSetupImageVideo (ScreenPtr pScreen)
pPriv->videoStatus = 0;
pPriv->currentBuffer = 0;
pPriv->grabbedByV4L = FALSE;
+ pPriv->blitter = FALSE;
NVSetPortDefaults (pScrnInfo, pPriv);
/* gotta uninit this someplace */
- REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
+ REGION_NULL(pScreen, &pPriv->clip);
pNv->overlayAdaptor = adapt;
@@ -351,41 +451,6 @@ NVSetupImageVideo (ScreenPtr pScreen)
return adapt;
}
-/*
- * RegionsEqual
- */
-static Bool RegionsEqual
-(
- RegionPtr A,
- RegionPtr B
-)
-{
- int *dataA, *dataB;
- int num;
-
- num = REGION_NUM_RECTS(A);
- if (num != REGION_NUM_RECTS(B))
- return FALSE;
-
- if ((A->extents.x1 != B->extents.x1) ||
- (A->extents.x2 != B->extents.x2) ||
- (A->extents.y1 != B->extents.y1) ||
- (A->extents.y2 != B->extents.y2))
- return FALSE;
-
- dataA = (int*)REGION_RECTS(A);
- dataB = (int*)REGION_RECTS(B);
-
- while(num--)
- {
- if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
- return FALSE;
- dataA += 2;
- dataB += 2;
- }
- return TRUE;
-}
-
static void
NVPutOverlayImage (
ScrnInfoPtr pScrnInfo,
@@ -408,12 +473,12 @@ NVPutOverlayImage (
{
NVPtr pNv = NVPTR(pScrnInfo);
NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
- RIVA_HW_INST *pRiva = &(pNv->riva);
int buffer = pPriv->currentBuffer;
/* paint the color key */
if(pPriv->autopaintColorKey &&
- (pPriv->grabbedByV4L || !RegionsEqual(&pPriv->clip, clipBoxes)))
+ (pPriv->grabbedByV4L ||
+ !REGION_EQUAL(pScrnInfo->pScreen, &pPriv->clip, clipBoxes)))
{
/* we always paint V4L's color key */
if(!pPriv->grabbedByV4L)
@@ -421,13 +486,19 @@ NVPutOverlayImage (
xf86XVFillKeyHelper(pScrnInfo->pScreen, pPriv->colorKey, clipBoxes);
}
- pRiva->PMC[(0x8900/4) + buffer] = offset;
- pRiva->PMC[(0x8928/4) + buffer] = (height << 16) | width;
- pRiva->PMC[(0x8930/4) + buffer] = ((y1 << 4) & 0xffff0000) | (x1 >> 12);
- pRiva->PMC[(0x8938/4) + buffer] = (src_w << 20) / drw_w;
- pRiva->PMC[(0x8940/4) + buffer] = (src_h << 20) / drw_h;
- pRiva->PMC[(0x8948/4) + buffer] = (dstBox->y1 << 16) | dstBox->x1;
- pRiva->PMC[(0x8950/4) + buffer] = ((dstBox->y2 - dstBox->y1) << 16) |
+ if(pNv->CurrentLayout.mode->Flags & V_DBLSCAN) {
+ dstBox->y1 <<= 1;
+ dstBox->y2 <<= 1;
+ drw_h <<= 1;
+ }
+
+ pNv->PMC[(0x8900/4) + buffer] = offset;
+ pNv->PMC[(0x8928/4) + buffer] = (height << 16) | width;
+ pNv->PMC[(0x8930/4) + buffer] = ((y1 << 4) & 0xffff0000) | (x1 >> 12);
+ pNv->PMC[(0x8938/4) + buffer] = (src_w << 20) / drw_w;
+ pNv->PMC[(0x8940/4) + buffer] = (src_h << 20) / drw_h;
+ pNv->PMC[(0x8948/4) + buffer] = (dstBox->y1 << 16) | dstBox->x1;
+ pNv->PMC[(0x8950/4) + buffer] = ((dstBox->y2 - dstBox->y1) << 16) |
(dstBox->x2 - dstBox->x1);
dstPitch |= 1 << 20; /* use color key */
@@ -437,15 +508,105 @@ NVPutOverlayImage (
if(pPriv->iturbt_709)
dstPitch |= 1 << 24;
- pRiva->PMC[(0x8958/4) + buffer] = dstPitch;
- pRiva->PMC[0x00008704/4] = 0;
- pRiva->PMC[0x8700/4] = 1 << (buffer << 2);
+ pNv->PMC[(0x8958/4) + buffer] = dstPitch;
+ pNv->PMC[0x00008704/4] = 0;
+ pNv->PMC[0x8700/4] = 1 << (buffer << 2);
pPriv->videoStatus = CLIENT_VIDEO_ON;
}
+static void
+NVPutBlitImage (
+ ScrnInfoPtr pScrnInfo,
+ int offset,
+ int id,
+ int dstPitch,
+ BoxPtr dstBox,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ short width,
+ short height,
+ short src_w,
+ short src_h,
+ short drw_w,
+ short drw_h,
+ RegionPtr clipBoxes
+)
+{
+ NVPtr pNv = NVPTR(pScrnInfo);
+ NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv);
+ BoxPtr pbox = REGION_RECTS(clipBoxes);
+ int nbox = REGION_NUM_RECTS(clipBoxes);
+ CARD32 dsdx, dtdy, size, point, srcpoint, format;
+
+ dsdx = (src_w << 20) / drw_w;
+ dtdy = (src_h << 20) / drw_h;
+
+ size = ((dstBox->y2 - dstBox->y1) << 16) | (dstBox->x2 - dstBox->x1);
+ point = (dstBox->y1 << 16) | dstBox->x1;
+
+ dstPitch |= (STRETCH_BLIT_SRC_FORMAT_ORIGIN_CENTER << 16) |
+ (STRETCH_BLIT_SRC_FORMAT_FILTER_BILINEAR << 24);
+
+ srcpoint = ((y1 << 4) & 0xffff0000) | (x1 >> 12);
+
+ switch(id) {
+ case FOURCC_RGB:
+ format = STRETCH_BLIT_FORMAT_X8R8G8B8;
+ break;
+ case FOURCC_UYVY:
+ format = STRETCH_BLIT_FORMAT_UYVY;
+ break;
+ default:
+ format = STRETCH_BLIT_FORMAT_YUYV;
+ break;
+ }
+
+ if(pNv->CurrentLayout.depth == 15) {
+ NVDmaStart(pNv, SURFACE_FORMAT, 1);
+ NVDmaNext (pNv, SURFACE_FORMAT_DEPTH15);
+ }
+
+ NVDmaStart(pNv, STRETCH_BLIT_FORMAT, 1);
+ NVDmaNext (pNv, format);
+
+ while(nbox--) {
+ NVDmaStart(pNv, RECT_SOLID_COLOR, 1);
+ NVDmaNext (pNv, 0);
+
+ NVDmaStart(pNv, STRETCH_BLIT_CLIP_POINT, 6);
+ NVDmaNext (pNv, (pbox->y1 << 16) | pbox->x1);
+ NVDmaNext (pNv, ((pbox->y2 - pbox->y1) << 16) | (pbox->x2 - pbox->x1));
+ NVDmaNext (pNv, point);
+ NVDmaNext (pNv, size);
+ NVDmaNext (pNv, dsdx);
+ NVDmaNext (pNv, dtdy);
+
+ NVDmaStart(pNv, STRETCH_BLIT_SRC_SIZE, 4);
+ NVDmaNext (pNv, (height << 16) | width);
+ NVDmaNext (pNv, dstPitch);
+ NVDmaNext (pNv, offset);
+ NVDmaNext (pNv, srcpoint);
+ pbox++;
+ }
+
+ if(pNv->CurrentLayout.depth == 15) {
+ NVDmaStart(pNv, SURFACE_FORMAT, 1);
+ NVDmaNext (pNv, SURFACE_FORMAT_DEPTH16);
+ }
+
+ NVDmaKickoff(pNv);
+ SET_SYNC_FLAG(pNv->AccelInfoRec);
+
+ pPriv->videoStatus = FREE_TIMER;
+ pPriv->videoTime = currentTime.milliseconds + FREE_DELAY;
+ pNv->VideoTimerCallback = NVVideoTimerCallback;
+}
+
/*
* StopVideo
*/
@@ -463,18 +624,13 @@ static void NVStopOverlayVideo
REGION_EMPTY(pScrnInfo->pScreen, &pPriv->clip);
- if(Exit)
- {
+ if(Exit) {
if(pPriv->videoStatus & CLIENT_VIDEO_ON)
NVStopOverlay(pScrnInfo);
NVFreeOverlayMemory(pScrnInfo);
pPriv->videoStatus = 0;
- pNv->VideoTimerCallback = NULL;
- }
- else
- {
- if(pPriv->videoStatus & CLIENT_VIDEO_ON)
- {
+ } else {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON;
pPriv->videoTime = currentTime.milliseconds + OFF_DELAY;
pNv->VideoTimerCallback = NVVideoTimerCallback;
@@ -482,9 +638,16 @@ static void NVStopOverlayVideo
}
}
+static void NVStopBlitVideo
+(
+ ScrnInfoPtr pScrnInfo,
+ pointer data,
+ Bool Exit
+)
+{
+}
-
-static int NVSetPortAttribute
+static int NVSetOverlayPortAttribute
(
ScrnInfoPtr pScrnInfo,
Atom attribute,
@@ -554,9 +717,7 @@ static int NVSetPortAttribute
}
-
-
-static int NVGetPortAttribute
+static int NVGetOverlayPortAttribute
(
ScrnInfoPtr pScrnInfo,
Atom attribute,
@@ -588,6 +749,28 @@ static int NVGetPortAttribute
return Success;
}
+static int NVSetBlitPortAttribute
+(
+ ScrnInfoPtr pScrnInfo,
+ Atom attribute,
+ INT32 value,
+ pointer data
+)
+{
+ return BadMatch;
+}
+
+static int NVGetBlitPortAttribute
+(
+ ScrnInfoPtr pScrnInfo,
+ Atom attribute,
+ INT32 *value,
+ pointer data
+)
+{
+ return BadMatch;
+}
+
/*
* QueryBestSize
@@ -613,30 +796,7 @@ static void NVQueryBestSize
*p_w = drw_w;
*p_h = drw_h;
}
-/*
- * CopyData
- */
-static void NVCopyData422
-(
- unsigned char *src,
- unsigned char *dst,
- int srcPitch,
- int dstPitch,
- int h,
- int w
-)
-{
- w <<= 1;
- while(h--)
- {
- memcpy(dst, src, w);
- src += srcPitch;
- dst += dstPitch;
- }
-}
-/*
- * CopyMungedData
- */
+
static void NVCopyData420
(
unsigned char *src1,
@@ -694,6 +854,83 @@ static void NVCopyData420
}
}
}
+
+
+static void NVMoveDWORDS(
+ CARD32* dest,
+ CARD32* src,
+ int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *(dest + 1) = *(src + 1);
+ if(dwords == 2) return;
+ *(dest + 2) = *(src + 2);
+}
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+static void NVMoveDWORDSSwapped(
+ CARD32* dest,
+ CARD8* src,
+ int dwords )
+{
+ while(dwords--) {
+ *dest++ = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
+ src += 4;
+ }
+}
+#endif
+
+static void NVCopyData422
+(
+ unsigned char *src,
+ unsigned char *dst,
+ int srcPitch,
+ int dstPitch,
+ int h,
+ int w
+)
+{
+ w >>= 1; /* pixels to DWORDS */
+ while(h--) {
+ NVMoveDWORDS((CARD32*)dst, (CARD32*)src, w);
+ src += srcPitch;
+ dst += dstPitch;
+ }
+}
+
+static void NVCopyDataRGB
+(
+ unsigned char *src,
+ unsigned char *dst,
+ int srcPitch,
+ int dstPitch,
+ int h,
+ int w
+)
+{
+ while(h--) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ NVMoveDWORDSSwapped((CARD32*)dst, (CARD8*)src, w);
+#else
+ NVMoveDWORDS((CARD32*)dst, (CARD32*)src, w);
+#endif
+ src += srcPitch;
+ dst += dstPitch;
+ }
+}
+
+
/*
* PutImage
*/
@@ -721,9 +958,9 @@ static int NVPutImage
NVPtr pNv = NVPTR(pScrnInfo);
INT32 xa, xb, ya, yb;
unsigned char *dst_start;
- int pitch, newSize, offset, s2offset, s3offset;
+ int newSize, offset, s2offset, s3offset;
int srcPitch, srcPitch2, dstPitch;
- int top, left, npixels, nlines, bpp;
+ int top, left, right, bottom, npixels, nlines, bpp;
Bool skip = FALSE;
BoxRec dstBox;
CARD32 tmp;
@@ -744,10 +981,12 @@ static int NVPutImage
/* make the compiler happy */
s2offset = s3offset = srcPitch2 = 0;
- if(src_w > (drw_w << 3))
- drw_w = src_w >> 3;
- if(src_h > (drw_h << 3))
- drw_h = src_h >> 3;
+ if(!pPriv->blitter) {
+ if(src_w > (drw_w << 3))
+ drw_w = src_w >> 3;
+ if(src_h > (drw_h << 3))
+ drw_h = src_h >> 3;
+ }
/* Clip */
xa = src_x;
@@ -764,15 +1003,14 @@ static int NVPutImage
width, height))
return Success;
- dstBox.x1 -= pScrnInfo->frameX0;
- dstBox.x2 -= pScrnInfo->frameX0;
- dstBox.y1 -= pScrnInfo->frameY0;
- dstBox.y2 -= pScrnInfo->frameY0;
+ if(!pPriv->blitter) {
+ dstBox.x1 -= pScrnInfo->frameX0;
+ dstBox.x2 -= pScrnInfo->frameX0;
+ dstBox.y1 -= pScrnInfo->frameY0;
+ dstBox.y2 -= pScrnInfo->frameY0;
+ }
bpp = pScrnInfo->bitsPerPixel >> 3;
- pitch = bpp * pScrnInfo->displayWidth;
-
- dstPitch = ((width << 1) + 63) & ~63;
switch(id) {
case FOURCC_YV12:
@@ -781,12 +1019,19 @@ static int NVPutImage
s2offset = srcPitch * height;
srcPitch2 = ((width >> 1) + 3) & ~3;
s3offset = (srcPitch2 * (height >> 1)) + s2offset;
+ dstPitch = ((width << 1) + 63) & ~63;
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
- default:
- srcPitch = (width << 1);
+ srcPitch = width << 1;
+ dstPitch = ((width << 1) + 63) & ~63;
+ break;
+ case FOURCC_RGB:
+ srcPitch = width << 2;
+ dstPitch = ((width << 2) + 63) & ~63;
break;
+ default:
+ return BadImplementation;
}
newSize = height * dstPitch / bpp;
@@ -803,15 +1048,14 @@ static int NVPutImage
offset = pPriv->linear->offset * bpp;
if(pPriv->doubleBuffer) {
- RIVA_HW_INST *pRiva = &(pNv->riva);
int mask = 1 << (pPriv->currentBuffer << 2);
#if 0
/* burn the CPU until the next buffer is available */
- while(pRiva->PMC[0x00008700/4] & mask);
+ while(pNv->PMC[0x00008700/4] & mask);
#else
/* overwrite the newest buffer if there's not one free */
- if(pRiva->PMC[0x00008700/4] & mask) {
+ if(pNv->PMC[0x00008700/4] & mask) {
if(!pPriv->currentBuffer)
offset += (newSize * bpp) >> 1;
skip = TRUE;
@@ -823,15 +1067,28 @@ static int NVPutImage
dst_start = pNv->FbStart + offset;
- /* copy data */
- top = ya >> 16;
- left = (xa >> 16) & ~1;
- npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left;
+ /* We need to enlarge the copied rectangle by a pixel so the HW
+ filtering doesn't pick up junk laying outside of the source */
+
+ left = (xa - 0x00010000) >> 16;
+ if(left < 0) left = 0;
+ top = (ya - 0x00010000) >> 16;
+ if(top < 0) top = 0;
+ right = (xb + 0x0001ffff) >> 16;
+ if(right > width) right = width;
+ bottom = (yb + 0x0001ffff) >> 16;
+ if(bottom > height) bottom = height;
+
+ if(pPriv->blitter) NVSync(pScrnInfo);
switch(id) {
case FOURCC_YV12:
case FOURCC_I420:
+ left &= ~1;
+ npixels = ((right + 1) & ~1) - left;
top &= ~1;
+ nlines = ((bottom + 1) & ~1) - top;
+
dst_start += (left << 1) + (top * dstPitch);
tmp = ((top >> 1) * srcPitch2) + (left >> 1);
s2offset += tmp;
@@ -841,27 +1098,50 @@ static int NVPutImage
s2offset = s3offset;
s3offset = tmp;
}
- nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top;
- NVCopyData420(buf + (top * srcPitch) + left, buf + s2offset,
- buf + s3offset, dst_start, srcPitch, srcPitch2,
- dstPitch, nlines, npixels);
+ NVCopyData420(buf + (top * srcPitch) + left,
+ buf + s2offset, buf + s3offset,
+ dst_start, srcPitch, srcPitch2,
+ dstPitch, nlines, npixels);
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
- default:
+ left &= ~1;
+ npixels = ((right + 1) & ~1) - left;
+ nlines = bottom - top;
+
left <<= 1;
buf += (top * srcPitch) + left;
- nlines = ((yb + 0xffff) >> 16) - top;
dst_start += left + (top * dstPitch);
+
NVCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
break;
+ case FOURCC_RGB:
+ npixels = right - left;
+ nlines = bottom - top;
+
+ left <<= 2;
+ buf += (top * srcPitch) + left;
+ dst_start += left + (top * dstPitch);
+
+ NVCopyDataRGB(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ break;
+ default:
+ return BadImplementation;
}
if(!skip) {
- NVPutOverlayImage(pScrnInfo, offset, id, dstPitch, &dstBox,
- xa, ya, xb, yb,
- width, height, src_w, src_h, drw_w, drw_h, clipBoxes);
- pPriv->currentBuffer ^= 1;
+ if(pPriv->blitter) {
+ NVPutBlitImage(pScrnInfo, offset, id, dstPitch, &dstBox,
+ xa, ya, xb, yb,
+ width, height, src_w, src_h, drw_w, drw_h,
+ clipBoxes);
+ } else {
+ NVPutOverlayImage(pScrnInfo, offset, id, dstPitch, &dstBox,
+ xa, ya, xb, yb,
+ width, height, src_w, src_h, drw_w, drw_h,
+ clipBoxes);
+ pPriv->currentBuffer ^= 1;
+ }
}
return Success;
@@ -912,12 +1192,20 @@ static int NVQueryImageAttributes
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
- default:
size = *w << 1;
if (pitches)
pitches[0] = size;
size *= *h;
break;
+ case FOURCC_RGB:
+ size = *w << 2;
+ if(pitches)
+ pitches[0] = size;
+ size *= *h;
+ break;
+ default:
+ *w = *h = size = 0;
+ break;
}
return size;
}
@@ -930,8 +1218,8 @@ static void NVVideoTimerCallback
{
NVPtr pNv = NVPTR(pScrnInfo);
NVPortPrivPtr pOverPriv = NULL;
-
- pNv->VideoTimerCallback = NULL;
+ NVPortPrivPtr pBlitPriv = NULL;
+ Bool needCallback = FALSE;
if(!pScrnInfo->vtSema) return;
@@ -941,21 +1229,39 @@ static void NVVideoTimerCallback
pOverPriv = NULL;
}
+ if(pNv->blitAdaptor) {
+ pBlitPriv = GET_BLIT_PRIVATE(pNv);
+ if(!pBlitPriv->videoStatus)
+ pBlitPriv = NULL;
+ }
+
if(pOverPriv) {
if(pOverPriv->videoTime < currentTime) {
if(pOverPriv->videoStatus & OFF_TIMER) {
NVStopOverlay(pScrnInfo);
pOverPriv->videoStatus = FREE_TIMER;
pOverPriv->videoTime = currentTime + FREE_DELAY;
- pNv->VideoTimerCallback = NVVideoTimerCallback;
+ needCallback = TRUE;
} else
if(pOverPriv->videoStatus & FREE_TIMER) {
NVFreeOverlayMemory(pScrnInfo);
pOverPriv->videoStatus = 0;
}
- } else
- pNv->VideoTimerCallback = NVVideoTimerCallback;
+ } else {
+ needCallback = TRUE;
+ }
}
+
+ if(pBlitPriv) {
+ if(pBlitPriv->videoTime < currentTime) {
+ NVFreeBlitMemory(pScrnInfo);
+ pBlitPriv->videoStatus = 0;
+ } else {
+ needCallback = TRUE;
+ }
+ }
+
+ pNv->VideoTimerCallback = needCallback ? NVVideoTimerCallback : NULL;
}
@@ -973,7 +1279,6 @@ NVAllocSurface (
{
NVPtr pNv = NVPTR(pScrnInfo);
NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
- CARD8 *address;
int size, bpp;
bpp = pScrnInfo->bitsPerPixel >> 3;
@@ -992,7 +1297,6 @@ NVAllocSurface (
if(!pPriv->linear) return BadAlloc;
pPriv->offset = pPriv->linear->offset * bpp;
- address = pPriv->offset + pNv->FbStart;
surface->width = w;
surface->height = h;
@@ -1006,7 +1310,6 @@ NVAllocSurface (
NVStopOverlay(pScrnInfo);
pPriv->videoStatus = 0;
REGION_EMPTY(pScrnInfo->pScreen, &pPriv->clip);
- pNv->VideoTimerCallback = NULL;
pPriv->grabbedByV4L = TRUE;
return Success;
@@ -1049,7 +1352,7 @@ NVGetSurfaceAttribute (
NVPtr pNv = NVPTR(pScrnInfo);
NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
- return NVGetPortAttribute(pScrnInfo, attribute, value, (pointer)pPriv);
+ return NVGetOverlayPortAttribute(pScrnInfo, attribute, value, (pointer)pPriv);
}
static int
@@ -1062,7 +1365,7 @@ NVSetSurfaceAttribute(
NVPtr pNv = NVPTR(pScrnInfo);
NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
- return NVSetPortAttribute(pScrnInfo, attribute, value, (pointer)pPriv);
+ return NVSetOverlayPortAttribute(pScrnInfo, attribute, value, (pointer)pPriv);
}
static int
@@ -1154,7 +1457,3 @@ NVInitOffscreenImages (ScreenPtr pScreen)
{
xf86XVRegisterOffscreenImages(pScreen, NVOffscreenImages, 2);
}
-
-#endif
-
-