summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellström <thomas@shipmail.org>2008-10-29 10:58:16 +0000
committerThomas Hellström <thomas@shipmail.org>2008-10-29 10:58:16 +0000
commitf6ece3fb0067584d54e4b91bca76f08a70767adb (patch)
tree7e2a4b3ebec4c9b4794f080d16d205ccc7147ef5
parent56802c957c6bf93c2b47893a32cd9ce19465c96d (diff)
Support HQV command submission fully
-rw-r--r--src/ochr_ioctl.c86
-rw-r--r--src/ochr_ioctl.h8
-rw-r--r--src/via_dmabuffer.h19
-rw-r--r--src/via_driver.h3
-rw-r--r--src/via_swov.c138
-rw-r--r--src/via_video.c108
6 files changed, 244 insertions, 118 deletions
diff --git a/src/ochr_ioctl.c b/src/ochr_ioctl.c
index 697cfe8..ce1324f 100644
--- a/src/ochr_ioctl.c
+++ b/src/ochr_ioctl.c
@@ -185,6 +185,92 @@ struct via_validate_buffer
};
static int
+ochr_apply_yuv_reloc(uint32_t *cmdbuf,
+ uint32_t num_buffers,
+ struct via_validate_buffer *buffers,
+ const struct via_yuv_reloc *reloc)
+{
+ uint32_t *buf = cmdbuf + reloc->base.offset;
+ const struct via_reloc_bufaddr *baddr = &reloc->addr;
+ const struct via_validate_buffer *val_buf;
+ uint32_t val;
+ int i;
+
+ if (reloc->planes > 3)
+ return -EINVAL;
+
+ if (baddr->index > num_buffers)
+ return -EINVAL;
+
+ val_buf = &buffers[baddr->index];
+ if (val_buf->po_correct)
+ return 0;
+
+ val = val_buf->offset + baddr->delta;
+
+ for(i=0; i<reloc->planes; ++i) {
+ *buf++ = val + reloc->plane_offs[i];
+ ++buf;
+ }
+
+ return 0;
+}
+
+int
+ochr_yuv_relocation(struct _ViaCommandBuffer *cBuf,
+ struct _DriBufferObject *buffer,
+ uint32_t delta,
+ int planes, uint32_t plane_0, uint32_t plane_1,
+ uint32_t plane_2,
+ uint64_t flags, uint64_t mask)
+{
+ struct via_yuv_reloc reloc;
+ struct via_validate_buffer fake;
+ int itemLoc;
+ struct _ValidateNode *node;
+ struct via_validate_req *val_req;
+ int ret;
+ uint32_t tmp;
+ uint32_t *cmdbuf = (uint32_t *) cBuf->buf + (cBuf->pos - planes * 2);
+
+ ret = driBOAddListItem(cBuf->validate_list, buffer,
+ flags, mask, &itemLoc, &node);
+ if (ret)
+ return ret;
+
+ val_req = ochrValReq(node);
+
+ if (!(val_req->presumed_flags & VIA_USE_PRESUMED)) {
+ val_req->presumed_gpu_offset = (uint64_t) driBOOffset(buffer) -
+ driBOPoolOffset(buffer);
+ val_req->presumed_flags |= VIA_USE_PRESUMED;
+ }
+
+ fake.po_correct = 0;
+ fake.offset = val_req->presumed_gpu_offset;
+ reloc.base.type = VIA_RELOC_YUV;
+ reloc.base.offset = 1;
+ reloc.addr.index = 0;
+ reloc.addr.delta = delta + driBOPoolOffset(buffer);
+ reloc.planes = planes;
+ reloc.plane_offs[0] = plane_0;
+ reloc.plane_offs[1] = plane_1;
+ reloc.plane_offs[2] = plane_2;
+
+ tmp = cmdbuf - (uint32_t *) cBuf->buf;
+
+ ret = ochr_apply_yuv_reloc(cmdbuf, 1, &fake, &reloc);
+
+ reloc.addr.index = itemLoc;
+ reloc.base.offset = tmp + 1;
+
+ assert(ret == 0);
+
+ return ochr_add_reloc(cBuf->reloc_info, &reloc, sizeof(reloc));
+}
+
+
+static int
ochr_apply_2d_reloc(uint32_t * cmdbuf,
uint32_t num_buffers,
const struct via_validate_buffer *buffers,
diff --git a/src/ochr_ioctl.h b/src/ochr_ioctl.h
index b2505be..666bf63 100644
--- a/src/ochr_ioctl.h
+++ b/src/ochr_ioctl.h
@@ -37,6 +37,14 @@ extern int
ochr_dest_relocation(struct _ViaCommandBuffer *cBuf,
struct _DriBufferObject *dstBuffer,
uint32_t delta, uint64_t flags, uint64_t mask);
+extern int
+ochr_yuv_relocation(struct _ViaCommandBuffer *cBuf,
+ struct _DriBufferObject *buffer,
+ uint32_t delta, int planes,
+ uint32_t plane_0, uint32_t plane_1,
+ uint32_t plane_2,
+ uint64_t flags, uint64_t mask);
+
extern int ochr_execbuf(int fd, struct _ViaCommandBuffer *cBuf);
#endif
diff --git a/src/via_dmabuffer.h b/src/via_dmabuffer.h
index bc2535b..478b259 100644
--- a/src/via_dmabuffer.h
+++ b/src/via_dmabuffer.h
@@ -139,6 +139,25 @@ typedef struct _ViaCommandBuffer
#define OUT_RING_SubA(val1, val2) \
OUT_RING(((val1) << HC_SubA_SHIFT) | ((val2) & HC_Para_MASK))
+#define BEGIN_RING_H6(size) { \
+ BEGIN_RING(((size) + 4 + 3) & ~3); \
+ cb->mode = 6; \
+ cb->header_start = cb->pos; \
+ cb->pos += 4; \
+ }
+#define ADVANCE_RING_H6() { \
+ CARD32 *hs = cb->buf + cb->header_start; \
+ *hs++ = VIA_VIDEO_HEADER6; \
+ *hs++ = (cb->pos - cb->header_start - 4) >> 1; \
+ *hs++ = 0x00F60000; \
+ *hs++ = 0x00000000; \
+ while (cb->pos & 3) \
+ cb->buf[cb->pos++] = 0x00000000; \
+ ADVANCE_RING_VARIABLE; \
+ }
+
+
+
extern int viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffer * buf,
unsigned size);
extern void viaTearDownCBuffer(ViaCommandBuffer * buf);
diff --git a/src/via_driver.h b/src/via_driver.h
index 7399909..4016f4f 100644
--- a/src/via_driver.h
+++ b/src/via_driver.h
@@ -223,7 +223,6 @@ enum _ViaScanoutTypes {
VIA_SCANOUT_DISPLAY,
VIA_SCANOUT_CURSOR,
VIA_SCANOUT_OVERLAY,
- VIA_SCANOUT_HQV,
VIA_SCANOUT_NUM
};
@@ -476,6 +475,8 @@ void viaRestoreVideo(ScrnInfoPtr pScrn);
void viaSetColorSpace(VIAPtr pVia, int hue, int saturation, int brightness, int contrast,
Bool reset);
void VIAVidAdjustFrame(ScrnInfoPtr pScrn, int x, int y);
+void viaVideoFlip(VIAPtr pVia, int fourcc, unsigned long DisplayBufferIndex);
+
/* In via_xwmc.c */
diff --git a/src/via_swov.c b/src/via_swov.c
index 929f547..e35c273 100644
--- a/src/via_swov.c
+++ b/src/via_swov.c
@@ -122,22 +122,6 @@ viaWaitVBI(VIAPtr pVia)
while (IN_VIDEO_DISPLAY) ;
}
-static void
-viaWaitHQVDone(VIAPtr pVia)
-{
- CARD32 volatile *pdwState;
- unsigned long proReg = 0;
-
- if (pVia->ChipId == PCI_CHIP_VT3259
- && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
- proReg = PRO_HQV1_OFFSET;
-
- pdwState = (CARD32 volatile *)(pVia->VidMapBase + (HQV_CONTROL + proReg));
- if (pVia->swov.MPEG_ON) {
- while ((*pdwState & HQV_SW_FLIP)) ;
- }
-}
-
/*
* Send all data in VidRegBuffer to the hardware.
*/
@@ -1047,7 +1031,6 @@ CreateSurface(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width,
&hqvBuf->buf, 0,
DRM_BO_FLAG_MEM_VRAM |
DRM_BO_FLAG_READ |
- DRM_BO_FLAG_NO_EVICT |
hqvFlag, 0);
if (retCode) {
hqvBuf->buf = NULL;
@@ -1580,12 +1563,49 @@ SetVideoWindow(ScrnInfoPtr pScrn, unsigned long videoFlag,
}
}
+static void viaSetHqvSrc(ScrnInfoPtr pScrn, int fourcc,
+ struct _HQVBuffer *hqvBuf)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int proReg = 0;
+
+ if (pVia->ChipId == PCI_CHIP_VT3259
+ && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) {
+ proReg += PRO_HQV1_OFFSET;
+ }
+
+ switch (fourcc) {
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ case FOURCC_RV15:
+ case FOURCC_RV16:
+ case FOURCC_RV32:
+ SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y + proReg,
+ hqvBuf->pinnedOffset + hqvBuf->deltaY);
+ break;
+ case FOURCC_YV12:
+ default:
+ SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y + proReg,
+ hqvBuf->pinnedOffset + hqvBuf->deltaY);
+ if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
+ SaveVideoRegister(pVia, HQV_SRC_STARTADDR_U + proReg,
+ hqvBuf->pinnedOffset + hqvBuf->deltaU);
+ } else {
+ SaveVideoRegister(pVia, HQV_SRC_STARTADDR_U + proReg,
+ hqvBuf->pinnedOffset + hqvBuf->deltaV);
+ SaveVideoRegister(pVia, HQV_SRC_STARTADDR_V + proReg,
+ hqvBuf->pinnedOffset + hqvBuf->deltaU);
+ }
+ break;
+ }
+}
+
/*
* Upd_Video()
*/
static Bool
Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag,
- unsigned long startAddr, LPDDUPDATEOVERLAY pUpdate,
+ LPDDUPDATEOVERLAY pUpdate,
unsigned long srcPitch,
unsigned long oriSrcWidth, unsigned long oriSrcHeight,
unsigned long deinterlaceMode,
@@ -1608,6 +1628,7 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag,
unsigned long hqvSrcFetch = 0, hqvOffset = 0;
unsigned long dwOffset = 0, fetch = 0, tmp = 0;
unsigned long proReg = 0;
+ int ret;
DBG_DD(ErrorF("videoflag=%p\n", videoFlag));
@@ -1674,44 +1695,16 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag,
pVia->swov.overlayRecordV1.dwOffset = dwOffset;
- /*
- * FIXME: Note that the HQV source is initialized to its own destination
- * surfaces here. Should be investigated in case of strange
- * behaviour during video startup.
- */
-
if (pVia->swov.SrcFourCC == FOURCC_YV12
|| pVia->swov.SrcFourCC == FOURCC_XVMC) {
if (videoFlag & VIDEO_HQV_INUSE) {
- int bufNum = 1 - (pVia->dwFrameNum & 1);
- struct _HQVBuffer *hqvBuf = &pVia->swov.SWDevice.hqvBuf[bufNum];
-
SetVideoStart(pVia, videoFlag, hwDiff->dwThreeHQVBuffer ? 3 : 2,
pVia->swov.overlayRecordV1.dwHQVAddr[0] + dwOffset,
pVia->swov.overlayRecordV1.dwHQVAddr[1] + dwOffset,
pVia->swov.overlayRecordV1.dwHQVAddr[2] + dwOffset);
-
- if (pVia->swov.SrcFourCC != FOURCC_XVMC) {
- if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
- SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y + proReg,
- hqvBuf->pinnedOffset + hqvBuf->deltaY);
- SaveVideoRegister(pVia, HQV_SRC_STARTADDR_U + proReg,
- hqvBuf->pinnedOffset + hqvBuf->deltaU);
- } else {
- SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y,
- hqvBuf->pinnedOffset + hqvBuf->deltaY);
- SaveVideoRegister(pVia, HQV_SRC_STARTADDR_U,
- hqvBuf->pinnedOffset + hqvBuf->deltaV);
- SaveVideoRegister(pVia, HQV_SRC_STARTADDR_V,
- hqvBuf->pinnedOffset + hqvBuf->deltaU);
- }
- }
}
} else {
- int bufNum = 1 - (pVia->dwFrameNum & 1);
- struct _HQVBuffer *hqvBuf = &pVia->swov.SWDevice.hqvBuf[bufNum];
-
if (videoFlag & VIDEO_HQV_INUSE) {
hqvSrcWidth = (unsigned long)pUpdate->SrcRight - pUpdate->SrcLeft;
hqvDstWidth = (unsigned long)pUpdate->DstRight - pUpdate->DstLeft;
@@ -1726,10 +1719,6 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag,
if (pVia->VideoEngine == VIDEO_ENGINE_CME)
SaveVideoRegister(pVia, 0x1cc + proReg, dwOffset);
-
- SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y + proReg,
- hqvBuf->pinnedOffset + hqvBuf->deltaY);
-
}
}
@@ -1737,18 +1726,6 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag,
srcWidth, dstWidth, oriSrcWidth, &hqvSrcFetch);
DBG_DD(ErrorF("===fetch= 0x%lx\n", fetch));
-#if 0
- /* For DCT450 test-BOB INTERLEAVE */
- if ((deinterlaceMode & DDOVER_INTERLEAVED)
- && (deinterlaceMode & DDOVER_BOB)) {
- if (videoFlag & VIDEO_HQV_INUSE)
- hqvCtl |= HQV_FIELD_2_FRAME | HQV_FRAME_2_FIELD | HQV_DEINTERLACE;
- } else if (deinterlaceMode & DDOVER_BOB) {
- if (videoFlag & VIDEO_HQV_INUSE)
- /* The HQV source data line count should be two times of the original line count */
- hqvCtl |= HQV_FIELD_2_FRAME | HQV_DEINTERLACE;
- }
-#endif
if (videoFlag & VIDEO_HQV_INUSE) {
if (!(deinterlaceMode & DDOVER_INTERLEAVED)
@@ -1887,12 +1864,25 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag,
/* Set up video control */
if (videoFlag & VIDEO_HQV_INUSE) {
-
if (!pVia->swov.SWVideo_ON) {
+ unsigned bufNum = 1 - (pVia->dwFrameNum & 1);
+ struct _HQVBuffer *hqvBuf = &pVia->swov.SWDevice.hqvBuf[bufNum];
+
DBG_DD(ErrorF(" First HQV\n"));
- FlushVidRegBuffer(pVia);
+ /*
+ * Since HQV initialization seems to require a tight
+ * interaction with the hardware, we pin the HQV source
+ * buffer here, and unpin it when the HQV is idle and
+ * initialization done.
+ */
+ ret = driBOSetStatus(hqvBuf->buf, DRM_BO_FLAG_NO_EVICT, 0);
+ hqvBuf->pinnedOffset = driBOOffset(hqvBuf->buf);
+
+ viaSetHqvSrc(pScrn, pVia->swov.SrcFourCC, hqvBuf);
+ FlushVidRegBuffer(pVia);
+
DBG_DD(ErrorF(" Wait flips"));
if (hwDiff->dwHQVInitPatch) {
@@ -1940,6 +1930,8 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag,
DBG_DD(ErrorF(" Wait flips6"));
}
+ ret = driBOSetStatus(hqvBuf->buf, 0, DRM_BO_FLAG_NO_EVICT);
+
if (videoFlag & VIDEO_1_INUSE) {
VIDOutD(V1_CONTROL, vidCtl);
VIDOutD(V_COMPOSE_MODE, compose | V1_COMMAND_FIRE);
@@ -1961,16 +1953,17 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag,
DBG_DD(ErrorF(" Done flips"));
} else {
DBG_DD(ErrorF(" Normal called\n"));
- SaveVideoRegister(pVia, HQV_CONTROL + proReg,
- hqvCtl | HQV_FLIP_STATUS);
SetVideoControl(pVia, videoFlag, vidCtl);
FireVideoCommand(pVia, videoFlag, compose);
- viaWaitHQVDone(pVia);
FlushVidRegBuffer(pVia);
+
+ viaVideoFlip(pVia, pVia->swov.SrcFourCC,
+ 1 - (pVia->dwFrameNum & 1));
}
}
pVia->swov.SWVideo_ON = TRUE;
+ pVia->swov.hqvCtl = hqvCtl;
DBG_DD(ErrorF(" Done Upd_Video"));
return TRUE;
@@ -1991,7 +1984,6 @@ VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate)
unsigned long flags = pUpdate->dwFlags;
unsigned long videoFlag = 0;
- unsigned long startAddr = 0;
unsigned long deinterlaceMode = 0;
unsigned long haveColorKey = 0, haveChromaKey = 0;
@@ -2042,7 +2034,6 @@ VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate)
ResetVidRegBuffer(pVia);
/* For SW decode HW overlay use */
- startAddr = VIDInD(HQV_SRC_STARTADDR_Y + proReg);
if (flags & DDOVER_KEYDEST) {
haveColorKey = 1;
@@ -2130,14 +2121,14 @@ VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate)
/* Update the overlay */
- if (!Upd_Video(pScrn, videoFlag, startAddr, pUpdate,
+ if (!Upd_Video(pScrn, videoFlag, pUpdate,
pVia->swov.SWDevice.dwPitch, ovlV1->dwV1OriWidth,
ovlV1->dwV1OriHeight, deinterlaceMode, haveColorKey,
haveChromaKey, colorKeyLow, colorKeyHigh, chromaKeyLow,
- chromaKeyHigh))
+ chromaKeyHigh)) {
+ pVia->swov.SWVideo_ON = FALSE;
return FALSE;
-
- pVia->swov.SWVideo_ON = FALSE;
+ }
return TRUE;
@@ -2194,3 +2185,4 @@ ViaOverlayHide(ScrnInfoPtr pScrn)
pVia->swov.SWVideo_ON = FALSE;
pVia->VideoStatus &= ~VIDEO_SWOV_ON;
}
+
diff --git a/src/via_video.c b/src/via_video.c
index 0d2e8fd..723283c 100644
--- a/src/via_video.c
+++ b/src/via_video.c
@@ -1056,19 +1056,23 @@ viaQueryBestSize(ScrnInfoPtr pScrn,
*p_w = 2048;
}
-/*
- * To do SW Flip
- */
-static void
-Flip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc,
- unsigned long DisplayBufferIndex)
+void
+viaVideoFlip(VIAPtr pVia, int fourcc,
+ unsigned long DisplayBufferIndex)
{
- unsigned long proReg = 0;
+ unsigned long proReg = 0x200;
+ uint64_t hqvFlag = VIA_BO_FLAG_HQV0;
struct _HQVBuffer *hqvBuf = &pVia->swov.SWDevice.hqvBuf[DisplayBufferIndex];
+
+ int ret;
+ RING_VARS;
+ BEGIN_RING_H6(8);
if (pVia->ChipId == PCI_CHIP_VT3259
- && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
- proReg = PRO_HQV1_OFFSET;
+ && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) {
+ proReg += PRO_HQV1_OFFSET;
+ hqvFlag = VIA_BO_FLAG_HQV1;
+ }
switch (fourcc) {
case FOURCC_UYVY:
@@ -1076,32 +1080,46 @@ Flip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc,
case FOURCC_RV15:
case FOURCC_RV16:
case FOURCC_RV32:
- while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP));
- VIDOutD(HQV_SRC_STARTADDR_Y + proReg,
- hqvBuf->pinnedOffset + hqvBuf->deltaY);
- VIDOutD(HQV_CONTROL + proReg,
- (VIDInD(HQV_CONTROL +
- proReg) & ~HQV_FLIP_ODD) | HQV_SW_FLIP | HQV_FLIP_STATUS);
+ OUT_RING_QW(HQV_SRC_STARTADDR_Y + proReg, 0);
+ ret = ochr_yuv_relocation(cb, hqvBuf->buf, 0, 1,
+ hqvBuf->deltaY, 0, 0,
+ DRM_BO_FLAG_MEM_VRAM |
+ hqvFlag,
+ DRM_BO_MASK_MEM |
+ hqvFlag);
break;
case FOURCC_YV12:
default:
- while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP));
- VIDOutD(HQV_SRC_STARTADDR_Y + proReg,
- hqvBuf->pinnedOffset + hqvBuf->deltaY);
+ OUT_RING_QW(HQV_SRC_STARTADDR_Y + proReg, 0);
if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
- VIDOutD(HQV_SRC_STARTADDR_U + proReg,
- hqvBuf->pinnedOffset + hqvBuf->deltaU);
+ OUT_RING_QW(HQV_SRC_STARTADDR_U + proReg, 0);
+ ret = ochr_yuv_relocation(cb, hqvBuf->buf, 0, 2,
+ hqvBuf->deltaY, hqvBuf->deltaU, 0,
+ DRM_BO_FLAG_MEM_VRAM |
+ hqvFlag,
+ DRM_BO_MASK_MEM |
+ hqvFlag);
} else {
- VIDOutD(HQV_SRC_STARTADDR_U,
- hqvBuf->pinnedOffset + hqvBuf->deltaV);
- VIDOutD(HQV_SRC_STARTADDR_V,
- hqvBuf->pinnedOffset + hqvBuf->deltaU);
+ OUT_RING_QW(HQV_SRC_STARTADDR_U + proReg, 0);
+ OUT_RING_QW(HQV_SRC_STARTADDR_V + proReg, 0);
+ ret = ochr_yuv_relocation(cb, hqvBuf->buf, 0, 3,
+ hqvBuf->deltaY, hqvBuf->deltaV,
+ hqvBuf->deltaU,
+ DRM_BO_FLAG_MEM_VRAM |
+ hqvFlag,
+ DRM_BO_MASK_MEM |
+ hqvFlag);
}
- VIDOutD(HQV_CONTROL + proReg,
- (VIDInD(HQV_CONTROL +
- proReg) & ~HQV_FLIP_ODD) | HQV_SW_FLIP | HQV_FLIP_STATUS);
+
break;
}
+
+ OUT_RING_QW(HQV_CONTROL + proReg,
+ (pVia->swov.hqvCtl & ~HQV_FLIP_ODD) |
+ HQV_SW_FLIP | HQV_FLIP_STATUS);
+
+ ADVANCE_RING_H6();
+ FLUSH_RING;
}
/*
@@ -1302,11 +1320,6 @@ viaPutImage(ScrnInfoPtr pScrn,
void *virtual;
- if (virtual == NULL) {
- viaXvError(pScrn, pPriv, xve_mem);
- return BadAlloc;
- }
-
DBG_DD(ErrorF(" via_video.c : : S/W Overlay! \n"));
/* Allocate video memory(CreateSurface),
* add codes to judge if need to re-create surface
@@ -1326,6 +1339,12 @@ viaPutImage(ScrnInfoPtr pScrn,
hqvBuf = &pVia->swov.SWDevice.hqvBuf[pVia->dwFrameNum & 1];
virtual = driBOMap(hqvBuf->buf, WS_DRI_MAP_WRITE);
+ if (virtual == NULL) {
+ viaXvError(pScrn, pPriv, xve_mem);
+ return BadAlloc;
+ }
+
+
/* Copy image data from system memory to video memory
* TODO: use DRM's DMA feature to accelerate data copy
*/
@@ -1410,17 +1429,6 @@ viaPutImage(ScrnInfoPtr pScrn,
dwUseExtendedFIFO = 1;
}
- if (FOURCC_XVMC != id) {
-
- /*
- * XvMC flipping is done in the client lib.
- */
-
- DBG_DD(ErrorF(" : Flip\n"));
- Flip(pVia, pPriv, id, pVia->dwFrameNum & 1);
- }
-
- pVia->dwFrameNum++;
/* If the dest rec. & extendFIFO doesn't change, don't do UpdateOverlay
* unless the surface clipping has changed */
@@ -1431,10 +1439,22 @@ viaPutImage(ScrnInfoPtr pScrn,
&& (pVia->old_dwUseExtendedFIFO == dwUseExtendedFIFO)
&& (pVia->VideoStatus & VIDEO_SWOV_ON) &&
RegionsEqual(&pPriv->clip, clipBoxes)) {
+ if (FOURCC_XVMC != id) {
+
+ /*
+ * XvMC flipping is done in the client lib.
+ */
+
+ DBG_DD(ErrorF(" : Flip\n"));
+ viaVideoFlip(pVia, id, pVia->dwFrameNum & 1);
+ pVia->dwFrameNum++;
+ }
+
viaXvError(pScrn, pPriv, xve_none);
return Success;
}
+ pVia->dwFrameNum++;
pPriv->old_src_x = src_x;
pPriv->old_src_y = src_y;
pPriv->old_src_w = src_w;
@@ -1472,7 +1492,7 @@ viaPutImage(ScrnInfoPtr pScrn,
(" via_video.c : call v4l updateoverlay fail. \n"));
} else {
DBG_DD(ErrorF(" via_video.c : PutImage done OK\n"));
- viaXvError(pScrn, pPriv, xve_none);
+ viaXvError(pScrn, pPriv, xve_none);
return Success;
}
break;