diff options
author | Keith Packard <keithp@keithp.com> | 2001-06-23 03:41:24 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2001-06-23 03:41:24 +0000 |
commit | 01a53daa03a8ee36ce136dde3a9a9b152e9c2e2f (patch) | |
tree | dc982d403f9b6038168705de0f6949147938c100 | |
parent | 31d47ec8bed1b02d04563ba502eaeb028975f653 (diff) |
Clean up mach64 video code to add ReputVideo and make StopVideo not crash
the machine
-rw-r--r-- | hw/kdrive/mach64/mach64.c | 7 | ||||
-rw-r--r-- | hw/kdrive/mach64/mach64.h | 45 | ||||
-rw-r--r-- | hw/kdrive/mach64/mach64draw.c | 3 | ||||
-rw-r--r-- | hw/kdrive/mach64/mach64video.c | 215 |
4 files changed, 187 insertions, 83 deletions
diff --git a/hw/kdrive/mach64/mach64.c b/hw/kdrive/mach64/mach64.c index 3f1c90928..296970ed4 100644 --- a/hw/kdrive/mach64/mach64.c +++ b/hw/kdrive/mach64/mach64.c @@ -19,7 +19,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.c,v 1.3 2001/06/16 05:48:48 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.c,v 1.4 2001/06/19 09:31:47 keithp Exp $ */ #include "mach64.h" #include <sys/io.h> @@ -93,7 +93,6 @@ mach64ScreenInit (KdScreenInfo *screen) mach64s->colorKey = 1; break; } - mach64s->colorKey = 1; memory = mach64s->vesa.fb_size; screen_size = screen->fb[0].byteStride * screen->height; if (mach64s->screen && memory >= screen_size + 2048) @@ -195,7 +194,9 @@ mach64Preserve (KdCardInfo *card) vesaPreserve(card); if (reg) + { mach64c->save.LCD_GEN_CTRL = mach64ReadLCD (reg, 1); + } } void @@ -344,7 +345,9 @@ mach64Restore (KdCardInfo *card) Reg *reg = mach64c->reg; if (reg) + { mach64WriteLCD (reg, 1, mach64c->save.LCD_GEN_CTRL); + } mach64ResetMMIO (mach64c); vesaRestore (card); } diff --git a/hw/kdrive/mach64/mach64.h b/hw/kdrive/mach64/mach64.h index ae79e4e82..d305690bd 100644 --- a/hw/kdrive/mach64/mach64.h +++ b/hw/kdrive/mach64/mach64.h @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.h,v 1.3 2001/06/16 05:48:48 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.h,v 1.4 2001/06/19 09:31:47 keithp Exp $ */ #ifndef _MACH64_H_ #define _MACH64_H_ @@ -332,6 +332,32 @@ typedef struct _Reg { #define HOST_BYTE_ALIGN (1 << 28) #define HOST_BIG_ENDIAN_EN (1 << 29) +/* BUS_CNTL bits */ +#define BUS_DBL_RESYNC (1 << 0) +#define BUS_MSTR_RESET (1 << 1) +#define BUS_FLUSH_BUF (1 << 2) +#define BUS_STOP_REQ_DIS (1 << 3) +#define BUS_APER_REG_DIS (1 << 4) +#define BUS_EXTRA_PIPE_DIS (1 << 5) +#define BUS_MASTER_DIS (1 << 6) +#define ROM_WRT_EN (1 << 7) +#define CHIP_HIDDEN_REV (3 << 8) +#define BUS_PCI_READ_RETRY_EN (1 << 13) +#define BUS_PCI_WRT_RETRY_EN (1 << 15) +#define BUS_RETRY_WS (0xf << 16) +#define BUS_MSTR_RD_MULT (1 << 20) +#define BUS_MSTR_RD_LINE (1 << 21) +#define BUS_SUSPEND (1 << 22) +#define LAT16X (1 << 23) +#define BUS_RD_DISCARD_EN (1 << 24) +#define BUS_RD_ABORT_EN (1 << 25) +#define BUS_MSTR_WS (1 << 26) +#define BUS_EXT_REG_EN (1 << 27) +#define BUS_MSTR_DISCONNECT_EN (1 << 28) +#define BUS_WRT_BURST (1 << 29) +#define BUS_READ_BURST (1 << 30) +#define BUS_RDY_READ_DLY (1 << 31) + #define SCALE_PIX_EXPAND (1 << 0) #define SCALE_Y2R_TEMP (1 << 1) #define SCALE_HORZ_MODE (1 << 2) @@ -359,9 +385,22 @@ typedef struct _Reg { #define SCALER_IN_VYUY422 (0xb << 16) #define SCALER_IN_YVYU422 (0xc << 16) +#define CAP_INPUT_MODE (1 << 0) +#define CAP_BUF_MODE (1 << 2) +#define CAP_START_BUF (1 << 3) +#define CAP_BUF_TYPE_FIELD (0 << 4) +#define CAP_BUF_TYPE_ALTERNATING (1 << 4) +#define CAP_BUF_TYPE_FRAME (2 << 4) + #define OVL_BUF_MODE (1 << 28) #define OVL_BUF_NEXT (1 << 29) +#define CAP_TRIGGER (3 << 0) +#define OVL_CUR_BUF (1 << 5) +#define OVL_BUF_STATUS (1 << 6) +#define CAP_BUF_STATUS (1 << 7) +#define CAPTURE_EN (1 << 31) + typedef struct _MediaReg { VOL32 OVERLAY_Y_X_START; /* 0x100 */ VOL32 OVERLAY_Y_X_END; @@ -498,12 +537,8 @@ typedef struct _mach64Cursor { */ typedef struct _mach64PortPriv { CARD32 YBuf0Offset; - CARD32 UBuf0Offset; - CARD32 VBuf0Offset; CARD32 YBuf1Offset; - CARD32 UBuf1Offset; - CARD32 VBuf1Offset; CARD8 currentBuf; diff --git a/hw/kdrive/mach64/mach64draw.c b/hw/kdrive/mach64/mach64draw.c index 9632eb523..1367c56de 100644 --- a/hw/kdrive/mach64/mach64draw.c +++ b/hw/kdrive/mach64/mach64draw.c @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c,v 1.3 2001/06/16 05:48:49 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c,v 1.4 2001/06/19 09:31:47 keithp Exp $ */ #include "mach64.h" #include "mach64draw.h" @@ -97,7 +97,6 @@ mach64Setup (ScreenPtr pScreen, CARD32 combo, int wait) reg = mach64c->reg; triple = mach64s->bpp24; - avail = 0; mach64WaitAvail(reg, wait + 3); reg->DP_PIX_WIDTH = mach64s->DP_PIX_WIDTH; reg->USR1_DST_OFF_PITCH = mach64s->USR1_DST_OFF_PITCH; diff --git a/hw/kdrive/mach64/mach64video.c b/hw/kdrive/mach64/mach64video.c index 785c63c81..c7588bbb8 100644 --- a/hw/kdrive/mach64/mach64video.c +++ b/hw/kdrive/mach64/mach64video.c @@ -19,7 +19,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64video.c,v 1.3 2001/06/21 01:01:30 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64video.c,v 1.4 2001/06/21 21:44:09 keithp Exp $ */ #include "mach64.h" #include "Xv.h" @@ -31,7 +31,6 @@ static Atom xvBrightness, xvSaturation, xvColorKey; #define IMAGE_MAX_WIDTH 720 #define IMAGE_MAX_HEIGHT 576 -#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT) static void mach64StopVideo(KdScreenInfo *screen, pointer data, Bool exit) @@ -50,12 +49,16 @@ mach64StopVideo(KdScreenInfo *screen, pointer data, Bool exit) if(pPortPriv->videoOn) { mach64WaitIdle (reg); - - media->OVERLAY_Y_X_START = 0x80000000; - media->OVERLAY_Y_X_END = 0; + /* wait for buffer to be displayed */ + while (((media->TRIG_CNTL >> 5) & 1) != pPortPriv->currentBuf) + ; + /* wait for buffer to be finished */ + while (((media->TRIG_CNTL >> 6) & 1) != 0) + ; + mach64WaitAvail (reg, 1); media->OVERLAY_SCALE_CNTL = 0; - media->OVERLAY_Y_X_START = 0; pPortPriv->videoOn = FALSE; + mach64WaitIdle (reg); } } @@ -91,8 +94,11 @@ mach64SetPortAttribute(KdScreenInfo *screen, } else if(attribute == xvColorKey) { - pPortPriv->colorKey = value; - REGION_EMPTY(screen->pScreen, &pPortPriv->clip); + if (pPortPriv->colorKey != value) + { + pPortPriv->colorKey = value; + REGION_EMPTY(screen->pScreen, &pPortPriv->clip); + } } else return BadMatch; @@ -273,17 +279,44 @@ static void mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg) { WindowPtr pRoot = WindowTable[pScreen->myNum]; - unsigned backgroundState; - PixUnion background; - - /* XXX use window background painting routine XXX */ - backgroundState = pRoot->backgroundState; - background = pRoot->background; - pRoot->backgroundState = BackgroundPixel; - pRoot->background.pixel = fg; - (*pScreen->PaintWindowBackground) (pRoot, pRgn, PW_BACKGROUND); - pRoot->backgroundState = backgroundState; - pRoot->background = background; + GCPtr pGC; + CARD32 val[2]; + xRectangle *rects, *r; + BoxPtr pBox = REGION_RECTS (pRgn); + int nBox = REGION_NUM_RECTS (pRgn); + + rects = ALLOCATE_LOCAL (nBox * sizeof (xRectangle)); + if (!rects) + goto bail0; + r = rects; + while (nBox--) + { + r->x = pBox->x1; + r->y = pBox->y1; + r->width = pBox->x2 - pBox->x1; + r->height = pBox->y2 - pBox->y1; + r++; + pBox++; + } + + pGC = GetScratchGC (pRoot->drawable.depth, pScreen); + if (!pGC) + goto bail1; + + val[0] = fg; + val[1] = IncludeInferiors; + ChangeGC (pGC, GCForeground|GCSubwindowMode, val); + + ValidateGC (&pRoot->drawable, pGC); + + (*pGC->ops->PolyFillRect) (&pRoot->drawable, pGC, + REGION_NUM_RECTS (pRgn), rects); + + FreeScratchGC (pGC); +bail1: + DEALLOCATE_LOCAL (rects); +bail0: + ; } /* Mach64ClipVideo - @@ -388,22 +421,29 @@ mach64DisplayVideo(KdScreenInfo *screen, int yscaleIntUV = 0, yscaleFractUV = 0; int HORZ_INC, VERT_INC; CARD32 SCALER_IN; + CARD32 OVERLAY_SCALE_CNTL; int tmp; int left; int bright; int sat; - mach64WaitIdle (reg); + if (id == FOURCC_UYVY) + SCALER_IN = SCALER_IN_YVYU422; + else + SCALER_IN = SCALER_IN_VYUY422; + + mach64WaitAvail (reg, 4); - /* lock registers to prevent non-atomic update */ - media->OVERLAY_Y_X_START = 0x80000000; - /* ending screen coordinate */ - media->OVERLAY_Y_X_END = MACH64_YX (dstBox->x2, dstBox->y2); + media->VIDEO_FORMAT = SCALER_IN | VIDEO_IN_VYUY422; + /* color key */ - media->OVERLAY_GRAPHICS_KEY_CLR = mach64s->colorKey; media->OVERLAY_GRAPHICS_KEY_MSK = (1 << screen->fb[0].depth) - 1; + media->OVERLAY_GRAPHICS_KEY_CLR = pPortPriv->colorKey; /* set key control to obey only graphics color key */ media->OVERLAY_KEY_CNTL = 0x50; + + mach64WaitAvail (reg, 9); + media->CAPTURE_DEBUG = 0; /* no exclusive video region */ media->OVERLAY_EXCLUSIVE_HORZ = 0; media->OVERLAY_EXCLUSIVE_VERT = 0; @@ -413,26 +453,14 @@ mach64DisplayVideo(KdScreenInfo *screen, media->SCALER_H_COEFF2 = 0x0D0A1C0D; media->SCALER_H_COEFF3 = 0x0C0E1A0C; media->SCALER_H_COEFF4 = 0x0C14140C; - - VERT_INC = (src_h << 12) / drw_h; - HORZ_INC = (src_w << 12) / drw_w; - - media->OVERLAY_SCALE_INC = MACH64_YX(HORZ_INC, VERT_INC); + media->SCALER_TEST = 0; + mach64WaitAvail (reg, 2); media->OVERLAY_SCALE_CNTL = (SCALE_PIX_EXPAND | SCALE_GAMMA_BRIGHT | SCALE_BANDWIDTH | SCALE_OVERLAY_EN | SCALE_EN); - media->SCALER_BUF0_OFFSET = pPortPriv->YBuf0Offset; - media->SCALER_BUF1_OFFSET = pPortPriv->YBuf0Offset; - media->SCALER_BUF0_OFFSET_U = pPortPriv->YBuf0Offset; - media->SCALER_BUF1_OFFSET_U = pPortPriv->YBuf1Offset; - media->SCALER_BUF0_OFFSET_V = pPortPriv->YBuf0Offset; - media->SCALER_BUF1_OFFSET_V = pPortPriv->YBuf1Offset; - media->SCALER_BUF_PITCH = dstPitch >> 1; - media->SCALER_HEIGHT_WIDTH = MACH64_YX(src_w - (x1 >> 16), src_h - (y1 >> 16)); - media->SCALER_TEST = 0; bright = (pPortPriv->brightness * 64 / 1000); if (bright < -0x40) @@ -445,24 +473,39 @@ mach64DisplayVideo(KdScreenInfo *screen, sat = 0x1f; if (sat < 0) sat = 0; + media->SCALER_COLOUR_CNTL = ((bright << 0) | /* BRIGHTNESS */ (sat << 8) | /* SATURATION_U */ (sat << 16) | /* SATURATION_V */ (0 << 21) | /* SCALER_VERT_ADJ_UV */ (0 << 28)); /* SCALER_HORZ_ADJ_UV */ + VERT_INC = (src_h << 12) / drw_h; + HORZ_INC = (src_w << 12) / drw_w; - if (id == FOURCC_UYVY) - SCALER_IN = SCALER_IN_YVYU422; - else - SCALER_IN = SCALER_IN_VYUY422; + mach64WaitAvail (reg, 13); - media->VIDEO_FORMAT = SCALER_IN | VIDEO_IN_VYUY422; + /* lock registers to prevent non-atomic update */ + media->OVERLAY_Y_X_START = 0x80000000 | MACH64_YX (dstBox->x1, dstBox->y1); + /* ending screen coordinate */ + media->OVERLAY_Y_X_END = 0x80000000 | MACH64_YX (dstBox->x2, dstBox->y2); + + media->OVERLAY_SCALE_INC = MACH64_YX(HORZ_INC, VERT_INC); - media->CAPTURE_CONFIG = (OVL_BUF_MODE | - (pPortPriv->currentBuf == 0 ? - 0 : OVL_BUF_NEXT)); + media->SCALER_BUF0_OFFSET = pPortPriv->YBuf0Offset; + media->SCALER_BUF1_OFFSET = pPortPriv->YBuf1Offset; + + media->SCALER_BUF0_OFFSET_U = pPortPriv->YBuf0Offset; + media->SCALER_BUF1_OFFSET_U = pPortPriv->YBuf1Offset; + + media->SCALER_BUF0_OFFSET_V = pPortPriv->YBuf0Offset; + media->SCALER_BUF1_OFFSET_V = pPortPriv->YBuf1Offset; + media->SCALER_BUF_PITCH = dstPitch >> 1; + media->SCALER_HEIGHT_WIDTH = MACH64_YX(src_w - (x1 >> 16), src_h - (y1 >> 16)); + + media->CAPTURE_CONFIG = pPortPriv->currentBuf << 28; + /* set XY location and unlock */ media->OVERLAY_Y_X_START = MACH64_YX (dstBox->x1, dstBox->y1); } @@ -487,7 +530,10 @@ mach64PutImage(KdScreenInfo *screen, { KdCardInfo *card = screen->card; Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver; Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data; + Reg *reg = mach64c->reg; + MediaReg *media = mach64c->media_reg; INT32 x1, x2, y1, y2; int srcPitch, srcPitch2, dstPitch; int top, left, npixels, nlines, size; @@ -516,40 +562,38 @@ mach64PutImage(KdScreenInfo *screen, dstPitch = ((width << 1) + 15) & ~15; srcPitch = (width + 3) & ~3; srcPitch2 = ((width >> 1) + 3) & ~3; - size = dstPitch * height; + size = dstPitch * (int) height; break; case FOURCC_UYVY: case FOURCC_YUY2: default: dstPitch = ((width << 1) + 15) & ~15; - size = dstPitch * height; + size = dstPitch * (int) height; srcPitch = (width << 1); break; } pPortPriv->offset = mach64s->off_screen - (CARD8 *) mach64s->vesa.fb; /* fixup pointers */ + pPortPriv->YBuf0Offset = pPortPriv->offset; - pPortPriv->UBuf0Offset = pPortPriv->YBuf0Offset + (dstPitch * 2 * height); - pPortPriv->VBuf0Offset = pPortPriv->UBuf0Offset + (dstPitch * height >> 1); - pPortPriv->YBuf1Offset = pPortPriv->offset + size; - pPortPriv->UBuf1Offset = pPortPriv->YBuf1Offset + (dstPitch * 2 * height); - pPortPriv->VBuf1Offset = pPortPriv->UBuf1Offset + (dstPitch * height >> 1); #if 0 - /* wait for the last rendered buffer to be flipped in */ - while (((INREG(DOV0STA)&0x00100000)>>20) != pPortPriv->currentBuf); -#endif + mach64WaitIdle (reg); - /* buffer swap */ -#if 0 - if (pPortPriv->currentBuf == 0) - pPortPriv->currentBuf = 1; - else + if (pPortPriv->videoOn) + { + /* wait for buffer to be displayed */ + while (((media->TRIG_CNTL >> 5) & 1) != pPortPriv->currentBuf) + ; + } #endif - pPortPriv->currentBuf = 0; - + /* + * Use the other buffer + */ + pPortPriv->currentBuf = 1 - pPortPriv->currentBuf; + /* copy data */ top = y1 >> 16; left = (x1 >> 16) & ~1; @@ -572,14 +616,15 @@ mach64PutImage(KdScreenInfo *screen, break; } + mach64DisplayVideo(screen, id, width, height, dstPitch, + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + /* update cliplist */ if (!RegionsEqual (&pPortPriv->clip, clipBoxes)) { REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes); mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey); } - mach64DisplayVideo(screen, id, width, height, dstPitch, - x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); pPortPriv->videoOn = TRUE; @@ -687,14 +732,35 @@ static void mach64ResetVideo(KdScreenInfo *screen) /* * Default to maximum image size in YV12 */ + +} -#if 0 - media->OVERLAY_Y_X_START = MACH64_YX(0,0); - media->OVERLAY_Y_X_END = MACH64_YX(320,240); - media->OVERLAY_VIDEO_KEY_CLR = mach64s->colorKey; - media->OVERLAY_VIDEO_KEY_MSK = 0xffffffff; - media->OVERLAY_KEY_CNTL = 0; -#endif +static int +mach64ReputImage (KdScreenInfo *screen, + short drw_x, + short drw_y, + RegionPtr clipBoxes, + pointer data) +{ + ScreenPtr pScreen = screen->pScreen; + Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data; + BoxPtr pOldExtents = REGION_EXTENTS (pScreen, &pPortPriv->clip); + BoxPtr pNewExtents = REGION_EXTENTS (pScreen, clipBoxes); + + if (pOldExtents->x1 == pNewExtents->x1 && + pOldExtents->x2 == pNewExtents->x2 && + pOldExtents->y1 == pNewExtents->y1 && + pOldExtents->y2 == pNewExtents->y2) + { + /* update cliplist */ + if (!RegionsEqual (&pPortPriv->clip, clipBoxes)) + { + REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes); + mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey); + } + return Success; + } + return BadMatch; } static KdVideoAdaptorPtr @@ -739,9 +805,10 @@ mach64SetupImageVideo(ScreenPtr pScreen) adapt->GetPortAttribute = mach64GetPortAttribute; adapt->QueryBestSize = mach64QueryBestSize; adapt->PutImage = mach64PutImage; + adapt->ReputImage = mach64ReputImage; adapt->QueryImageAttributes = mach64QueryImageAttributes; - pPortPriv->colorKey = mach64s->colorKey & ((1 << screen->fb[0].depth) - 1); + pPortPriv->colorKey = mach64s->colorKey; pPortPriv->videoOn = FALSE; pPortPriv->brightness = 0; pPortPriv->saturation = 0; |