diff options
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/glint')
11 files changed, 1245 insertions, 1352 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile index a23fb7820..487789761 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile,v 1.34.2.1 2001/05/25 11:19:31 alanh Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile,v 1.35 2001/05/25 11:19:58 alanh Exp $ XCOMM XCOMM This is an Imakefile for the GLINT driver. XCOMM diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/README.pm3 b/xc/programs/Xserver/hw/xfree86/drivers/glint/README.pm3 index c4db56f6b..fbbd34628 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/README.pm3 +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/README.pm3 @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/README.pm3,v 1.11 2001/05/08 19:31:22 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/README.pm3,v 1.12 2001/08/18 11:37:30 alanh Exp $ */ STATUS as of Tue, 8 May 2001 19:01:39 +0200 @@ -23,22 +23,24 @@ Working : - Bitmap Writes using direct FIFO writes with or without FIFO Disconnect. - Pixmap Writes using direct FIFO writes with or without FIFO Disconnect. * Appian J2000 second head initialization. - * Dual head : The console fonts will get trashed, but dual head works. * Xv : Hardware video scaler : - Needs checking on a big endian machine. - - Needs acceleration to work. - - Clipping supported trough the alpha channel in depth 15 and 24 - and with an overlay key color in depth 8 and 16. + - Needs acceleration to work - there is a hardware bug in YV12 mode. - Support both dual head and single head, trough gamma or permedia3. + - NOTE: depth 15 and 16 currently broken as I can't figure out the + colorKey equation. From the docs it needs to be padded to 8bits per RGB, + but that doesn't seem to work either. FIXME. - Attributes are : - FILTER : None, Partial (X only) or Full filtering. - - MIRROR : X and/or Y Axis mirroring. - - ALPHA : + - COLORKEY : Speaks for itself + - DOUBLE_BUFFER : Speaks for itself + - AUTOPAINT_COLORKEY : Speaks for itself + - MIRROR : X and/or Y Axis mirroring. (NOT DONE) + - ALPHA : (NOT DONE) - 0 -> FB Only - 1 -> 25% Video, 75% FB - 2 -> 75% Video, 25% FB - 3 -> Video Only - - [TODO] VIDEOKEY : Overlay Key Color for clipping in depth 8 and 16. * DRI : Work is underway. Not Working : @@ -51,14 +53,6 @@ Not Working : - Render extension initialization. - CPUToScreenTexture. - CPUToScreenAlphaTexture. - * [NEED FIX] Xv has still some minor problems : - - depth 8 does not work, but then it may be the app i am using. - - when using 2D accels there is some unstability in the video display. I - guess this is because there is then not enough bandwith to do the - copying of the data in time. After a time of the above, the images - becomes black. It will come back once stopvideo is called. - [FIX] i will disable VideoOverlay each 25 frames, this causes a flicker, - but at least it will bing the image back. * [WORK IS UNDERWAY] DRI/OpenGL (only together with a gamma chip) : - DRI support should be ok, but accelerated openGL is not yet supported. - The accelerated OpenGL library supposes we are using a gamma together @@ -66,24 +60,12 @@ Not Working : Known problems : - * Console gets broken when using dual headed mode. The culprit seems to be - the vga graphics index & port (GraphicsIndexReg : 0x63ce, GraphicsPort : - 0x3cf). I had to use IO acces for both these two, because if not, console - fonts would get trashed even in mono headed mode. - [FIX] Well, if you really need the console and are running linux, just use - vesafb, it will be a bit slower, but the fonts will no more become - corrupt. Maybe i will even try writting a specific fbdev for the pm3, - which will be much faster and have more functionality. - [FIX2] try : consolechars -d, it should reload the console fonts. * [FIXED] R-B inversion. Sometimes, all of a sudden, it seems as the RGB order gets changed. going to console and back solves this. Well, this is partly fixed, but still appears under very heavy load. - * [FIXED] When moving a window around a lot quickly, the video outputs dies. - Well, this is partly fixed, but still appears under very heavy load. - => [NOTE] If this two still happens, try disabling the Hardware cursor, with + => [NOTE] If this still happens, try disabling the Hardware cursor, with the "SWCursor" option to your device XF86Config section. - * Sometimes there are blue transparent garbage in the form of small - horizontal bands, few pixels high, and more pixels width, maybe 64pixels ? - This may be a hardware bug. + => [NOTE2] Or, try starting the Xserver with the -nosilk option. Sven Luther <luther@dpt-info.u-strasbg.fr> +Alan Hourihane <alanh@fairlite.demon.co.uk> diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h index 3db30c12d..3a1a883da 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h,v 1.48.2.1 2001/05/24 20:12:47 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h,v 1.51 2001/08/19 02:47:50 tsi Exp $ */ /* * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk> * @@ -35,6 +35,7 @@ #include "xf86cmap.h" #include "xf86i2c.h" #include "xf86DDC.h" +#include "xf86xv.h" #ifdef XF86DRI #include "xf86drm.h" #include "sarea.h" @@ -162,6 +163,11 @@ typedef struct { CARD32 PM3_AreaStippleMode; CARD32 PM3_VideoControl; int InFifoSpace; +#ifdef XvExtension + void (*VideoTimerCallback)(ScrnInfoPtr, Time); + XF86VideoAdaptorPtr adaptor; + int videoKey; +#endif #ifdef XF86DRI Bool directRenderingEnabled; DRIInfoPtr pDRIInfo; @@ -189,6 +195,8 @@ typedef struct { ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA2V) #define PCI_VENDOR_3DLABS_CHIP_PERMEDIA3 \ ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA3) +#define PCI_VENDOR_3DLABS_CHIP_PERMEDIA4 \ + ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA4) #define PCI_VENDOR_3DLABS_CHIP_300SX \ ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_300SX) #define PCI_VENDOR_3DLABS_CHIP_500TX \ @@ -237,6 +245,7 @@ void Permedia3InitializeEngine(ScrnInfoPtr pScrn); void Permedia3EnableOffscreen(ScreenPtr pScreen); void Permedia3Sync(ScrnInfoPtr pScrn); void DualPermedia3Sync(ScrnInfoPtr pScrn); +void Permedia3InitVideo(ScreenPtr pScreen); void TXRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); void TXSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c index 76f0b0620..df222f6ef 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c @@ -28,7 +28,7 @@ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen, * Siemens Nixdorf Informationssysteme and Appian Graphics. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c,v 1.125.2.4 2001/05/29 11:32:22 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c,v 1.135 2001/08/18 11:37:30 alanh Exp $ */ #include "fb.h" #include "cfb8_32.h" @@ -45,6 +45,7 @@ #include "xf86RAC.h" #include "xf86Resources.h" #include "xf86int10.h" +#include "dixstruct.h" #include "vbe.h" #include "compiler.h" @@ -66,7 +67,6 @@ #include "extensions/dpms.h" #define DEBUG 0 -#define PM3Video 1 #if DEBUG # define TRACE_ENTER(str) ErrorF("glint: " str " %d\n",pScrn->scrnIndex) @@ -130,15 +130,18 @@ DriverRec GLINT = { static SymTabRec GLINTVGAChipsets[] = { { PCI_VENDOR_TI_CHIP_PERMEDIA2, "ti_pm2" }, { PCI_VENDOR_TI_CHIP_PERMEDIA, "ti_pm" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, "pm4" }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, "pm3" }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, "pm2v" }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, "pm2" }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA, "pm" }, + {-1, NULL } }; static PciChipsets GLINTVGAPciChipsets[] = { { PCI_VENDOR_TI_CHIP_PERMEDIA2, PCI_VENDOR_TI_CHIP_PERMEDIA2, RES_SHARED_VGA }, { PCI_VENDOR_TI_CHIP_PERMEDIA, PCI_VENDOR_TI_CHIP_PERMEDIA, NULL }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, RES_SHARED_VGA }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, RES_SHARED_VGA }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, RES_SHARED_VGA }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, RES_SHARED_VGA }, @@ -150,6 +153,7 @@ static SymTabRec GLINTChipsets[] = { { PCI_VENDOR_3DLABS_CHIP_GAMMA, "gamma" }, { PCI_VENDOR_TI_CHIP_PERMEDIA2, "ti_pm2" }, { PCI_VENDOR_TI_CHIP_PERMEDIA, "ti_pm" }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, "pm4" }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, "pm3" }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, "pm2v" }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, "pm2" }, @@ -165,6 +169,7 @@ static PciChipsets GLINTPciChipsets[] = { { PCI_VENDOR_3DLABS_CHIP_GAMMA, PCI_VENDOR_3DLABS_CHIP_GAMMA, NULL }, { PCI_VENDOR_TI_CHIP_PERMEDIA2, PCI_VENDOR_TI_CHIP_PERMEDIA2, RES_SHARED_VGA }, { PCI_VENDOR_TI_CHIP_PERMEDIA, PCI_VENDOR_TI_CHIP_PERMEDIA, NULL }, + { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, RES_SHARED_VGA }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, RES_SHARED_VGA }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, RES_SHARED_VGA }, { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, RES_SHARED_VGA }, @@ -185,7 +190,8 @@ typedef enum { OPTION_OVERLAY, OPTION_SHADOW_FB, OPTION_FBDEV, - OPTION_FLATPANEL + OPTION_FLATPANEL, + OPTION_VIDEO_KEY } GLINTOpts; static const OptionInfoRec GLINTOptions[] = { @@ -198,6 +204,7 @@ static const OptionInfoRec GLINTOptions[] = { { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_FLATPANEL, "UseFlatPanel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VIDEO_KEY, "VideoKey", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -215,42 +222,40 @@ static RamDacSupportedInfoRec TIRamdacs[] = { }; static const char *xf8_32bppSymbols[] = { + "cfb8_32ScreenInit", "xf86Overlay8Plus32Init", NULL }; static const char *xaaSymbols[] = { - "XAADestroyInfoRec", "XAACreateInfoRec", + "XAADestroyInfoRec", + "XAAFillSolidRects", "XAAInit", - "XAAStippleScanlineFuncLSBFirst", - "XAAOverlayFBfuncs", - "XAACachePlanarMonoStipple", - "XAAScreenIndex", "XAAPolyLines", "XAAPolySegment", - "XAAFillSolidRects", + "XAAScreenIndex", NULL }; static const char *fbSymbols[] = { - "cfb8_32ScreenInit", + "fbBres", "fbPictureInit", "fbScreenInit", - "fbBres", NULL }; static const char *ddcSymbols[] = { "xf86PrintEDID", - "xf86DoEDID_DDC1", "xf86DoEDID_DDC2", + "xf86SetDDCproperties", NULL }; static const char *i2cSymbols[] = { "xf86CreateI2CBusRec", "xf86DestroyI2CBusRec", + "xf86DestroyI2CDevRec", "xf86I2CBusInit", "xf86I2CDevInit", "xf86I2CProbeAddress", @@ -271,12 +276,30 @@ static const char *vbeSymbols[] = { NULL }; +static const char *ramdacSymbols[] = { + "IBMramdac526CalculateMNPCForClock", + "IBMramdac640CalculateMNPCForClock", + "IBMramdacProbe", + "RamDacCreateInfoRec", + "RamDacDestroyInfoRec", + "RamDacFreeRec", + "RamDacGetHWIndex", + "RamDacHandleColormaps", + "RamDacInit", + "TIramdacCalculateMNPForClock", + "TIramdacLoadPalette", + "TIramdacProbe", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + "xf86InitCursor", + NULL +}; + + static const char *fbdevHWSymbols[] = { - "fbdevHWInit", "fbdevHWFreeRec", + "fbdevHWInit", "fbdevHWProbe", - "fbdevHWFreeRec", - "fbdevHWGetName", "fbdevHWUseBuildinMode", "fbdevHWGetDepth", @@ -286,18 +309,18 @@ static const char *fbdevHWSymbols[] = { "fbdevHWLoadPalette", /* ScrnInfo hooks */ - "fbdevHWSwitchMode", "fbdevHWAdjustFrame", "fbdevHWEnterVT", "fbdevHWLeaveVT", - "fbdevHWValidMode", - "fbdevHWRestore", + "fbdevHWMapMMIO", + "fbdevHWMapVidmem", "fbdevHWModeInit", + "fbdevHWRestore", "fbdevHWSave", + "fbdevHWSwitchMode", "fbdevHWUnmapMMIO", "fbdevHWUnmapVidmem", - "fbdevHWMapMMIO", - "fbdevHWMapVidmem", + "fbdevHWValidMode", NULL }; @@ -312,27 +335,22 @@ static const char *int10Symbols[] = { static const char *drmSymbols[] = { "drmAddBufs", "drmAddMap", - "drmCtlAddCommand", "drmCtlInstHandler", - "drmGetInterruptFromBusID", - "drmMapBufs", - "drmMarkBufs", - "drmUnmapBufs", "drmFreeVersion", "drmGetVersion", + "drmMapBufs", + "drmUnmapBufs", NULL }; static const char *driSymbols[] = { - "DRIGetDrawableIndex", - "DRIFinishScreenInit", - "DRIDestroyInfoRec", "DRICloseScreen", - "DRIDestroyInfoRec", - "DRIScreenInit", - "DRIDestroyInfoRec", "DRICreateInfoRec", + "DRIDestroyInfoRec", + "DRIFinishScreenInit", + "DRIGetDrawableIndex", "DRIQueryVersion", + "DRIScreenInit", "GlxSetVisualConfigs", NULL }; @@ -369,7 +387,7 @@ glintSetup(pointer module, pointer opts, int *errmaj, int *errmin) LoaderRefSymLists(fbSymbols, ddcSymbols, i2cSymbols, xaaSymbols, xf8_32bppSymbols, shadowSymbols, fbdevHWSymbols, int10Symbols, - vbeSymbols, + vbeSymbols, ramdacSymbols, #ifdef XF86DRI drmSymbols, driSymbols, #endif @@ -575,9 +593,7 @@ static void GLINTProbeDDC(ScrnInfoPtr pScrn, int index) { vbeInfoPtr pVbe; -#ifdef XFree86LOADER if (xf86LoadSubModule(pScrn, "vbe")) -#endif { pVbe = VBEInit(NULL,index); vbeDoEDID(pVbe, NULL); @@ -856,6 +872,7 @@ GetAccelPitchValues(ScrnInfoPtr pScrn) linep = &partprod500TX[0]; break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: linep = &partprodPermedia[0]; break; } @@ -946,6 +963,7 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) ClockRangePtr clockRanges; char *mod = NULL; const char *s; + const char **syms = NULL; TRACE_ENTER("GLINTPreInit"); @@ -1002,6 +1020,7 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) pPci = xf86GetPciInfoForEntity(pEnt->index); if ( (pPci->chipType == PCI_CHIP_MX) || (pPci->chipType == PCI_CHIP_PERMEDIA) || + (pPci->chipType == PCI_CHIP_TI_PERMEDIA) || (pPci->chipType == PCI_CHIP_500TX) || (pPci->chipType == PCI_CHIP_300SX) || (pPci->chipType == PCI_CHIP_PERMEDIA3) ) { @@ -1175,6 +1194,16 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using \"Shadow Framebuffer\" - acceleration disabled\n"); } + if(xf86GetOptValInteger(pGlint->Options, OPTION_VIDEO_KEY, + &(pGlint->videoKey))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", + pGlint->videoKey); + } else { + /* Needs 8bit values for all modes */ + pGlint->videoKey = (1 << 16) | + (1 << 8) | + ((pScrn->mask.blue - 1) << 0); + } /* Check whether to use the FBDev stuff and fill in the rest of pScrn */ if (xf86ReturnOptValBool(pGlint->Options, OPTION_FBDEV, FALSE)) { @@ -1412,7 +1441,8 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) int temp, base3copro, offset; if( (basedelta & 0x20000) ^ (basecopro & 0x20000) ) { - if (pGlint->MultiChip == PCI_CHIP_PERMEDIA) { + if ((pGlint->MultiChip == PCI_CHIP_PERMEDIA) || + (pGlint->MultiChip == PCI_CHIP_TI_PERMEDIA)) { offset = 0x20; /* base4 */ } else { offset = 0x1c; /* base3 */ @@ -1490,6 +1520,7 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) pScrn->videoRam = (((GLINT_READ_REG(PMMemConfig) >> 29) & 0x03) + 1) * 2048; break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: pScrn->videoRam = Permedia3MemorySizeDetect(pScrn); break; @@ -1497,6 +1528,7 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) case PCI_VENDOR_3DLABS_CHIP_GAMMA: switch (pGlint->MultiChip) { case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Attached Rasterizer is GLINT Permedia\n"); pScrn->videoRam = (((GLINT_READ_REG(PMMemConfig)>>29) & @@ -1590,6 +1622,8 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; + xf86LoaderReqSymLists(ramdacSymbols, NULL); + /* Let's check what type of DAC we have and reject if necessary */ switch (pGlint->Chipset) { case PCI_VENDOR_TI_CHIP_PERMEDIA2: @@ -1627,6 +1661,7 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: pGlint->FIFOSize = 120; maxheight = 4096; @@ -1694,6 +1729,7 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) pGlint->FIFOSize = 15; switch (pGlint->MultiChip) { case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: maxheight = 1024; maxwidth = 1536; GLINTProbeIBMramdac(pScrn); @@ -1889,7 +1925,8 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) if ( (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA) || (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA) || ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && - (pGlint->MultiChip == PCI_CHIP_PERMEDIA)) ) { + ((pGlint->MultiChip == PCI_CHIP_PERMEDIA) || + (pGlint->MultiChip == PCI_CHIP_TI_PERMEDIA))) ) { switch (pScrn->bitsPerPixel) { case 8: pGlint->MaxClock = 200000; @@ -1924,6 +1961,7 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) } } if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) pGlint->MaxClock = 300000; @@ -1953,6 +1991,7 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) /* Select valid modes from those available */ if ((pGlint->NoAccel) || (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) { /* @@ -2103,6 +2142,7 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) pGlint->bppalign = 0; break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: pGlint->pprod = partprodPermedia[pScrn->displayWidth >> 5]; pGlint->bppalign = bppand[(pScrn->bitsPerPixel>>3)-1]; break; @@ -2212,22 +2252,25 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) case 16: case 24: mod = "fb"; + syms = fbSymbols; break; case 32: if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { - if (xf86LoadSubModule(pScrn, "xf8_32bpp") == NULL) { - GLINTFreeRec(pScrn); - return FALSE; - } else - xf86LoaderReqSymLists(xf8_32bppSymbols,NULL); - } else + mod = "xf8_32bpp"; + syms = xf8_32bppSymbols; + } else { mod = "fb"; + syms = fbSymbols; + } break; } if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { GLINTFreeRec(pScrn); return FALSE; } + if (mod && syms) { + xf86LoaderReqSymLists(syms, NULL); + } /* Load XAA if needed */ if (!pGlint->NoAccel) { @@ -2252,14 +2295,17 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) GLINTFreeRec(pScrn); return FALSE; } + xf86LoaderReqSymLists(ddcSymbols, NULL); /* Load I2C if needed */ if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) || (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) || (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2)) { if (xf86LoadSubModule(pScrn, "i2c")) { I2CBusPtr pBus; + xf86LoaderReqSymLists(i2cSymbols, NULL); if ((pBus = xf86CreateI2CBusRec())) { pBus->BusName = "DDC"; pBus->scrnIndex = pScrn->scrnIndex; @@ -2407,6 +2453,7 @@ GLINTSave(ScrnInfoPtr pScrn) Permedia2VSave(pScrn, glintReg); break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: Permedia3Save(pScrn, glintReg); break; case PCI_VENDOR_TI_CHIP_PERMEDIA: @@ -2438,6 +2485,7 @@ GLINTSave(ScrnInfoPtr pScrn) (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg); break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: PermediaSave(pScrn, glintReg); (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg); break; @@ -2483,6 +2531,7 @@ GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) ret = Permedia2VInit(pScrn, mode); break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: ret = Permedia3Init(pScrn, mode, glintReg); break; case PCI_VENDOR_TI_CHIP_PERMEDIA: @@ -2508,6 +2557,7 @@ GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) ret = TXInit(pScrn, mode, glintReg); break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: ret = PermediaInit(pScrn, mode); break; case PCI_CHIP_PERMEDIA3: @@ -2540,6 +2590,7 @@ GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) Permedia2VRestore(pScrn, glintReg); break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: Permedia3Restore(pScrn, glintReg); break; case PCI_VENDOR_TI_CHIP_PERMEDIA: @@ -2571,6 +2622,7 @@ GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: PermediaRestore(pScrn, glintReg); (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); break; @@ -2623,10 +2675,7 @@ GLINTRestore(ScrnInfoPtr pScrn) Permedia2VRestore(pScrn, glintReg); break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: -#ifdef PM3Video - TRACE("PM3Video : VideoLeaveVT"); - Permedia3VideoLeaveVT(pScrn); -#endif + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: Permedia3Restore(pScrn, glintReg); break; case PCI_VENDOR_TI_CHIP_PERMEDIA: @@ -2658,14 +2707,11 @@ GLINTRestore(ScrnInfoPtr pScrn) (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: PermediaRestore(pScrn, glintReg); (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg); break; case PCI_CHIP_PERMEDIA3: -#ifdef PM3Video - TRACE("PM3Video : VideoLeaveVT"); - Permedia3VideoLeaveVT(pScrn); -#endif if (pGlint->numMultiDevices == 2) { ACCESSCHIP2(); Permedia3Restore(pScrn, glintReg2); @@ -2691,6 +2737,7 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; GLINTPtr pGlint = GLINTPTR(pScrn); int ret, displayWidth; + int init_picture = 0; unsigned char *FBStart; VisualPtr visual; @@ -2812,8 +2859,7 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, displayWidth, pScrn->bitsPerPixel); - if (ret) - fbPictureInit(pScreen, 0, 0); + init_picture = 1; break; case 32: if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR) @@ -2826,8 +2872,7 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, displayWidth, pScrn->bitsPerPixel); - if (ret) - fbPictureInit(pScreen, 0, 0); + init_picture = 1; } break; default: @@ -2865,6 +2910,9 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } + /* must be after RGB ordering fixed */ + if (init_picture) + fbPictureInit(pScreen, 0, 0); if (!pGlint->NoAccel) { switch (pGlint->Chipset) { @@ -2874,6 +2922,7 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) Permedia2AccelInit(pScreen); break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: Permedia3AccelInit(pScreen); break; case PCI_VENDOR_TI_CHIP_PERMEDIA: @@ -2895,6 +2944,7 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) SXAccelInit(pScreen); break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: PermediaAccelInit(pScreen); break; case PCI_CHIP_PERMEDIA3: @@ -2923,6 +2973,7 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) else if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) || (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) Permedia2vHWCursorInit(pScreen); @@ -2943,6 +2994,7 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || + (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) || ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) { if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, @@ -3006,6 +3058,8 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif + pScrn->fbOffset = 0; + pGlint->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = GLINTCloseScreen; pScreen->SaveScreen = GLINTSaveScreen; @@ -3021,18 +3075,15 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: Permedia2VideoInit(pScreen); break; -#ifdef PM3Video case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: - TRACE("PM3Video : VideoInit"); - Permedia3VideoInit(pScreen); + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + Permedia3InitVideo(pScreen); break; case PCI_VENDOR_3DLABS_CHIP_GAMMA: switch (pGlint->MultiChip) { case PCI_CHIP_PERMEDIA3: - TRACE("PM3Video : VideoInit"); - Permedia3VideoInit(pScreen); + Permedia3InitVideo(pScreen); } -#endif } #if 0 @@ -3067,6 +3118,7 @@ GLINTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) Permedia2InitializeEngine(pScrn); break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: Permedia3InitializeEngine(pScrn); break; case PCI_VENDOR_TI_CHIP_PERMEDIA: @@ -3091,6 +3143,7 @@ GLINTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) SXInitializeEngine(pScrn); break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: PermediaInitializeEngine(pScrn); break; case PCI_CHIP_PERMEDIA3: @@ -3145,6 +3198,7 @@ GLINTAdjustFrame(int scrnIndex, int x, int y, int flags) GLINT_SLOW_WRITE_REG(base, PMScreenBase); break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: base = (y * pScrn->displayWidth + x) >> pGlint->BppShift; GLINT_SLOW_WRITE_REG(base, PMScreenBase); break; @@ -3156,6 +3210,7 @@ GLINTAdjustFrame(int scrnIndex, int x, int y, int flags) GLINT_SLOW_WRITE_REG(base, PMScreenBase); break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: GLINT_SLOW_WRITE_REG(base, PMScreenBase); break; } @@ -3194,18 +3249,6 @@ GLINTEnterVT(int scrnIndex, int flags) case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: Permedia2VideoEnterVT(pScrn); break; -#ifdef PM3Video - case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: - TRACE("PM3Video : VideoEnterVT"); - Permedia3VideoEnterVT(pScrn); - break; - case PCI_VENDOR_3DLABS_CHIP_GAMMA: - switch (pGlint->MultiChip) { - case PCI_CHIP_PERMEDIA3: - TRACE("PM3Video : VideoEnterVT"); - Permedia3VideoEnterVT(pScrn); - } -#endif } if (!pGlint->NoAccel) { @@ -3216,6 +3259,7 @@ GLINTEnterVT(int scrnIndex, int flags) Permedia2InitializeEngine(pScrn); break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: Permedia3InitializeEngine(pScrn); break; case PCI_VENDOR_TI_CHIP_PERMEDIA: @@ -3240,6 +3284,7 @@ GLINTEnterVT(int scrnIndex, int flags) SXInitializeEngine(pScrn); break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: PermediaInitializeEngine(pScrn); break; case PCI_CHIP_PERMEDIA3: @@ -3305,17 +3350,6 @@ GLINTCloseScreen(int scrnIndex, ScreenPtr pScreen) case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: Permedia2VideoUninit(pScrn); break; -#ifdef PM3Video - case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: - TRACE("PM3Video : VideoUninit"); - Permedia3VideoUninit(pScrn); - case PCI_VENDOR_3DLABS_CHIP_GAMMA: - switch (pGlint->MultiChip) { - case PCI_CHIP_PERMEDIA3: - TRACE("PM3Video : VideoUninit"); - Permedia3VideoUninit(pScrn); - } -#endif } if (pScrn->vtSema) { @@ -3389,6 +3423,7 @@ GLINTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) * side appears if not aligned properly */ switch (pGlint->Chipset) { case PCI_VENDOR_TI_CHIP_PERMEDIA2: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: @@ -3448,6 +3483,7 @@ GLINTSaveScreen(ScreenPtr pScreen, int mode) switch (pGlint->Chipset) { case PCI_VENDOR_TI_CHIP_PERMEDIA2: case PCI_VENDOR_TI_CHIP_PERMEDIA: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V: case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2: @@ -3466,6 +3502,7 @@ GLINTSaveScreen(ScreenPtr pScreen, int mode) switch (pGlint->MultiChip) { case PCI_CHIP_PERMEDIA3: case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: temp = GLINT_READ_REG(PMVideoControl); if (unblank) temp |= 1; else temp &= 0xFFFFFFFE; @@ -3500,6 +3537,11 @@ GLINTBlockHandler ( pScreen->BlockHandler = pGlint->BlockHandler; (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); pScreen->BlockHandler = GLINTBlockHandler; + + if(pGlint->VideoTimerCallback) { + UpdateCurrentTime(); + (*pGlint->VideoTimerCallback)(pScrn, currentTime.milliseconds); + } } #ifdef DEBUG @@ -3651,6 +3693,7 @@ Shiftbpp(ScrnInfoPtr pScrn, int value) logbytesperaccess = 2; break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: logbytesperaccess = 4; break; case PCI_VENDOR_3DLABS_CHIP_300SX: @@ -3675,6 +3718,7 @@ Shiftbpp(ScrnInfoPtr pScrn, int value) logbytesperaccess = 3; break; case PCI_CHIP_PERMEDIA: + case PCI_CHIP_TI_PERMEDIA: logbytesperaccess = 2; break; case PCI_CHIP_PERMEDIA3: diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h index 4690035ea..6b5ac64b2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h,v 1.26.2.1 2001/05/24 20:12:47 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h,v 1.28 2001/08/18 11:37:31 alanh Exp $ */ /* * glint register file @@ -29,6 +29,7 @@ #define PCI_CHIP_3DLABS_GAMMA 0x08 #define PCI_CHIP_3DLABS_PERMEDIA2V 0x09 #define PCI_CHIP_3DLABS_PERMEDIA3 0x0A +#define PCI_CHIP_3DLABS_PERMEDIA4 0x0C #define PCI_CHIP_TI_PERMEDIA 0x3d04 /* The boards we know */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c index 67c7c2b18..cf98fc79b 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c @@ -30,7 +30,7 @@ * * Permedia 2 accelerated options. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c,v 1.29.2.1 2001/05/30 11:42:22 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c,v 1.30 2001/05/30 11:41:53 alanh Exp $ */ #include "Xarch.h" #include "xf86.h" diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c index 2a8b55891..05bcaa36c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c @@ -26,7 +26,7 @@ * * Permedia 3 accelerated options. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c,v 1.25 2001/04/18 09:24:47 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c,v 1.28 2001/08/18 11:41:45 alanh Exp $ */ #include "Xarch.h" #include "xf86.h" @@ -129,6 +129,13 @@ Permedia3InitializeEngine(ScrnInfoPtr pScrn) GLINT_SLOW_WRITE_REG(3, BroadcastMask); } + /* Disable LocalBuffer. Fixes stripes problems when + * doing screen-to-screen copies */ + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBDestReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBDestReadEnables); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBSourceReadMode); + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBWriteMode); + /* Host out PreInit */ /* Set filter mode to enable sync tag & data output */ GLINT_SLOW_WRITE_REG(0x400, FilterMode); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_dac.c index 9e330e190..933d1c241 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_dac.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_dac.c @@ -26,7 +26,7 @@ * this work is sponsored by Appian Graphics. * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_dac.c,v 1.24 2001/05/16 07:56:07 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_dac.c,v 1.25 2001/08/18 11:37:31 alanh Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -159,6 +159,121 @@ PM3DAC_CalculateClock return(actualclock); } +static unsigned long +PM4DAC_CalculateClock +( + unsigned long req_clock, /* In kHz units */ + unsigned long ref_clock, /* In kHz units */ + unsigned char *param_m, /* ClkPreScale */ + unsigned char *param_n, /* ClkFeedBackScale */ + unsigned char *param_p /* ClkPostScale */ + ) +{ +#define INITIALFREQERR 10000 + + long fMinVCO = 200000; /* min fVCO is 200MHz (in 10000Hz units) */ + long fMaxVCO = 400000; /* max fVCO is 400MHz (in 10000Hz units) */ + unsigned long int M, N, P; + unsigned long int fVCO; + unsigned long int ActualClock; + int Error; + int LowestError = INITIALFREQERR; + short bFoundFreq = FALSE; + int cInnerLoopIterations = 0; + int LoopCount; + + /* + * Actual Equations: + * fVCO = (ref_clock * M)/(N+1) + * PIXELCLOCK = fVCO/(1<<p) + * 200 <= fVCO <= 400 + * 24 <= N <= 80 + * 1 <= M <= 15 + * 0 <= P <= 3 + * 1Mhz < ref_clock/(N+1) <= 2Mhz - not used + * For refclk == 14.318 we have the tighter equations: + * 32 <= N <= 80 + * 3 <= M <= 12 + * Notes: + * The spec says that the PLLs will only do 260Mhz, but I have assumed 300Mhz 'cos + * 260Mhz is a crap limit. + */ + +#define P4RD_PLL_MIN_P 0 +#define P4RD_PLL_MAX_P 3 +#define P4RD_PLL_MIN_M 1 +#define P4RD_PLL_MAX_M 12 +#define P4RD_PLL_MIN_N 24 +#define P4RD_PLL_MAX_N 80 + + for(P = P4RD_PLL_MIN_P; P <= P4RD_PLL_MAX_P; ++P) { + unsigned long int fVCOLowest, fVCOHighest; + + /* it's pointless going through the main loop if all values of + * N produce an fVCO outside the acceptable range */ + + M = P4RD_PLL_MIN_M; + N = ((M + 1) * (1 << P) * req_clock) / ref_clock; + + fVCOLowest = (ref_clock * N) / (M + 1); + + M = P4RD_PLL_MAX_M; + N = ((M + 1) * (1 << P) * req_clock) / ref_clock; + + fVCOHighest = (ref_clock * N) / (M + 1); + + if(fVCOHighest < fMinVCO || fVCOLowest > fMaxVCO) + continue; + + for(M = P4RD_PLL_MIN_M; M <= P4RD_PLL_MAX_M; ++M, ++cInnerLoopIterations) + { + N = ((M + 1) * (1 << P) * req_clock) / ref_clock; + + if(N > P4RD_PLL_MAX_N || N < P4RD_PLL_MIN_N) + continue; + + /* we can expect rounding errors in calculating M, which will always be rounded down. */ + /* So we'll checkout our calculated value of M along with (M+1) */ + + for(LoopCount = (N == P4RD_PLL_MAX_N) ? 1 : 2; --LoopCount >= 0; ++N) + { + fVCO = (ref_clock * N) / (M + 1); + + if( (fVCO >= fMinVCO) && (fVCO <= fMaxVCO) ) + { + ActualClock = (fVCO / (1 << P)); + + Error = ActualClock - req_clock; + + if(Error < 0) + Error = -Error; + + /* It is desirable that we use the lowest value of M if the*/ + /* frequencies are the same.*/ + if(Error < LowestError || (Error == LowestError && M < *param_m)) + { + bFoundFreq = TRUE; + LowestError = Error; + *param_m = M; + *param_n = N; + *param_p = P; + if(Error == 0) + goto Done; + } + } + } + } + } + +Done: + if(bFoundFreq) + ActualClock = (ref_clock * (*param_n)) / (((*param_m) + 1) * (1 << (*param_p))); + else + ActualClock = 0; + + return(ActualClock); +} + void Permedia3PreInit(ScrnInfoPtr pScrn) { @@ -296,8 +411,15 @@ Permedia3Init(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr pReg) unsigned long clockused; /* Let's program the dot clock */ - clockused = PM3DAC_CalculateClock(mode->Clock, - pGlint->RefClock, &m,&n,&p); + switch (pGlint->Chipset) { + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: + clockused = PM4DAC_CalculateClock(mode->Clock * 1, /* HACK */ + pGlint->RefClock, &m,&n,&p); + break; + case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: + clockused = PM3DAC_CalculateClock(mode->Clock, + pGlint->RefClock, &m,&n,&p); + } STOREDAC(PM3RD_DClk0PreScale, m); STOREDAC(PM3RD_DClk0FeedbackScale, n); STOREDAC(PM3RD_DClk0PostScale, p); @@ -342,7 +464,7 @@ Permedia3Init(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr pReg) case 24: temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE; STOREDAC(PM2VDACRDPixelSize, 0x04); - STOREDAC(PM2VDACRDColorFormat, 0x60); + STOREDAC(PM2VDACRDColorFormat, 0x20); break; case 32: temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE; @@ -509,9 +631,7 @@ void Permedia3LoadPalette( LOCO *colors, VisualPtr pVisual ){ -#if 0 /* NOT YET */ GLINTPtr pGlint = GLINTPTR(pScrn); -#endif int i, index, shift = 0, j, repeat = 1; if (pScrn->depth == 15) { @@ -527,14 +647,11 @@ void Permedia3LoadPalette( Permedia2WriteData(pScrn, colors[index].green); Permedia2WriteData(pScrn, colors[index].blue); } - /* for video i/o */ -#if 0 /* NOT YET */ GLINT_SLOW_WRITE_REG(index, PM3LUTIndex); GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) | ((colors[index].green & 0xFF) << 8) | ((colors[index].blue & 0xFF) << 16), PM3LUTData); -#endif } } @@ -546,9 +663,7 @@ void Permedia3LoadPalette16( LOCO *colors, VisualPtr pVisual ){ -#if 0 /* NOT YET */ GLINTPtr pGlint = GLINTPTR(pScrn); -#endif int i, index, j; for(i = 0; i < numColors; i++) { @@ -559,13 +674,11 @@ void Permedia3LoadPalette16( Permedia2WriteData(pScrn, colors[index].green); Permedia2WriteData(pScrn, colors[index >> 1].blue); } -#if 0 /* NOT YET */ GLINT_SLOW_WRITE_REG(index, PM3LUTIndex); GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) | ((colors[index].green & 0xFF) << 8) | ((colors[index].blue & 0xFF) << 16), PM3LUTData); -#endif if(index <= 31) { for (j = 0; j < 4; j++) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h index d707bee94..7754e1bdc 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h,v 1.7 2001/05/08 19:31:22 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h,v 1.8 2001/08/18 11:37:31 alanh Exp $ */ /* * glint register file @@ -915,6 +915,8 @@ #define PM3TextureIndexMode1 0xb340 #define PM3TextureIndexMode1And 0xb3d0 #define PM3TextureIndexMode1Or 0xb3d8 +#define PM3TextureLODBiasS 0x8450 +#define PM3TextureLODBiasT 0x8458 /* ... */ #define PM3TextureMapSize 0xb428 #define PM3TextureMapWidth0 0x8580 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_video.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_video.c index 589eb8d5c..26f31b5c2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_video.c @@ -1,185 +1,149 @@ /* - * Permedia 3 Xv Driver + * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales. * - * Copyright (C) 2001 Sven Luther <luther@dpt-info.u-strasbg.fr> + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. * - * 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 the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * - * Based on work of Michael H. Schimek <m.schimek@netway.at> + * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk + * Sven Luther <luther@dpt-info.u-strasbg.fr> */ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_video.c,v 1.6 2001/05/08 19:31:22 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_video.c,v 1.7 2001/08/18 11:37:31 alanh Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" +#include "xf86Resources.h" #include "xf86_ansic.h" -#include "xf86Pci.h" +#include "compiler.h" #include "xf86PciInfo.h" -#include "xf86Xinput.h" +#include "xf86Pci.h" #include "xf86fbman.h" -#include "xf86xv.h" -#include "Xv.h" #include "regionstr.h" -#include "xaa.h" -#include "xaalocal.h" +#include "glint.h" #include "glint_regs.h" #include "pm3_regs.h" -#include "glint.h" +#include "Xv.h" +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" -#define DEBUG(x) -#define USE_HARDWARE_COPY 1 -#define SUPPORT_CLIPPING 1 -#define BLACKNESS_WORKAROUND 1 +#define OFF_DELAY 200 /* milliseconds */ +#define FREE_DELAY 60000 -#ifndef XvExtension +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 -void Permedia3VideoInit(ScreenPtr pScreen) {} -void Permedia3VideoUninit(ScrnInfoPtr pScrn) {} -void Permedia3VideoEnterVT(ScrnInfoPtr pScrn) {} -void Permedia3VideoLeaveVT(ScrnInfoPtr pScrn) {} +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) +#ifndef XvExtension +void Permedia3InitVideo(ScreenPtr pScreen) {} +void Permedia3ResetVideo(ScrnInfoPtr pScrn) {} #else -#undef MIN -#undef ABS -#undef CLAMP -#undef ENTRIES +static XF86VideoAdaptorPtr Permedia3SetupImageVideo(ScreenPtr); +static void Permedia3InitOffscreenImages(ScreenPtr); +static void Permedia3StopVideo(ScrnInfoPtr, pointer, Bool); +static int Permedia3SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int Permedia3GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); +static void Permedia3QueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, unsigned int *, pointer); +static int Permedia3PutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static int Permedia3QueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); +static void Permedia3VideoTimerCallback(ScrnInfoPtr pScrn, Time time); -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define ABS(n) (((n) < 0) ? -(n) : (n)) -#define CLAMP(v, min, max) (((v) < (min)) ? (min) : MIN(v, max)) -#define ENTRIES(array) (sizeof(array) / sizeof((array)[0])) - -enum { - OVERLAY_DATA_NONE, - OVERLAY_DATA_COLORKEY, - OVERLAY_DATA_ALPHAKEY, - OVERLAY_DATA_ALPHABLEND -} ; - -#define MAX_BUFFERS 3 - -typedef struct _PortPrivRec { - struct _AdaptorPrivRec * pAdaptor; - - /* Sync function */ - void (*Sync) (ScrnInfoPtr pScrn); - - /* Attributes */ - INT32 ColorKey; - INT32 OverlayAlpha; - INT32 OverlayMode; - INT32 Attribute[3]; - - /* Clipping */ - RegionRec clip; - -#if 0 /* Adding this cause the server to crash if we minimize the video */ - /* Frame counter */ - char Frames; -#endif - - /* Ramdac save values, ... */ - INT32 ramdac_x, ramdac_w; - INT32 ramdac_y, ramdac_h; - Bool ramdac_on; - - /* Buffers */ - int Id, Format; - int FB_Shift, Video_Shift; - short display, copy; - FBAreaPtr Buffer[MAX_BUFFERS]; - CARD32 BufferBase[MAX_BUFFERS]; - - /* Buffer and Drawable size and position */ - INT32 vx, vy, vw, vh; /* 12.10 fp */ - int dx, dy, dw, dh; +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) - /* Timer stuff */ - OsTimerPtr Timer; - Bool TimerInUse; - int Delay, Instant, StopDelay; +static Atom xvColorKey, xvDoubleBuffer, xvAutopaintColorKey, xvFilter; -} PortPrivRec, *PortPrivPtr; +void Permedia3InitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + GLINTPtr pGlint = GLINTPTR(pScrn); + int num_adaptors; + + /* Because of bugs in the PM3 when uploading images via the + * bypass to the framebuffer, we always have to use the accelerator. + */ + if (pGlint->NoAccel) + return; -typedef struct _AdaptorPrivRec { - struct _AdaptorPrivRec * Next; - ScrnInfoPtr pScrn; - PortPrivPtr pPort; -} AdaptorPrivRec, *AdaptorPrivPtr; + newAdaptor = Permedia3SetupImageVideo(pScreen); + Permedia3InitOffscreenImages(pScreen); -static AdaptorPrivPtr AdaptorPrivList = NULL; + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); -/* - * Proprietary Attributes - */ - -#define XV_FILTER "XV_FILTER" -/* We support 3 sorts of filters : - * 0 : None. - * 1 : Partial (only in the X directrion). - * 2 : Full (incompatible with X mirroring). - */ + if(newAdaptor) { + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } -#define XV_MIRROR "XV_MIRROR" -/* We also support mirroring of the image : - * bit 0 : if set, will mirror in the X direction - * (incompatible with full filtering). - * bit 1 : if set, will mirror in the Y direction. - */ + if(num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); -#define XV_ALPHA "XV_ALPHA" -/* We support the following alpha blend factors : - * 0 -> 0% Video, 100% Framebuffer - * 1 -> 25% Video, 75% Framebuffer - * 2 -> 75% Video, 25% Framebuffer - * 3 -> 100% Video, 0% Framebuffer - */ + if(newAdaptors) + xfree(newAdaptors); +} -static XF86AttributeRec -ScalerAttributes[] = +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = { - { XvSettable | XvGettable, 0, 2, XV_FILTER }, - { XvSettable | XvGettable, 0, 3, XV_MIRROR }, - { XvSettable | XvGettable, 0, 3, XV_ALPHA }, + { + 0, + "XV_IMAGE", + 2047, 2047, + {1, 1} + } }; -#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) - -static Atom xvFilter, xvMirror, xvAlpha; - +#define NUM_FORMATS 4 -/* Scaler */ - -static XF86VideoEncodingRec -ScalerEncodings[] = +static XF86VideoFormatRec Formats[NUM_FORMATS] = { - { 0, "XV_IMAGE", 2047, 2047, { 1, 1 }}, + {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} }; -static XF86VideoFormatRec -ScalerVideoFormats[] = +#define NUM_ATTRIBUTES 4 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { - { 8, TrueColor }, /* Dithered */ - { 15, TrueColor }, - { 16, TrueColor }, - { 24, TrueColor }, + {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, + {XvSettable | XvGettable, 0, 2, "XV_FILTER"}, }; /* @@ -191,8 +155,9 @@ ScalerVideoFormats[] = #define NoOrder LSBFirst -static XF86ImageRec -ScalerImages[] = +#define NUM_IMAGES 15 + +static XF86ImageRec Images[NUM_IMAGES] = { /* Planar YVU 4:2:0 (emulated) */ { LE4CC('Y','V','1','2'), XvYUV, NoOrder, GUID4CC('Y','V','1','2'), @@ -269,135 +234,277 @@ ScalerImages[] = 8, XvPacked, 1, 8, 0xC0, 0x38, 0x07, 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGR", XvTopToBottom }, }; -/* - * Buffer management - */ -static void -RemoveBufferCallback(FBAreaPtr Buffer) -{ - PortPrivPtr pPPriv = (PortPrivPtr) Buffer->devPrivate.ptr; - int i = -1; +#define MAX_BUFFERS 2 + +typedef struct { + FBAreaPtr area[MAX_BUFFERS]; + RegionRec clip; + CARD32 colorKey; + CARD32 videoStatus; + Time offTime; + Time freeTime; + int Video_Shift; + int Format; + Bool ramdacOn; + Bool doubleBuffer; + Bool autopaintColorKey; + int Filter; + int sx, sy; + int offset[MAX_BUFFERS]; + int buffer; +} GLINTPortPrivRec, *GLINTPortPrivPtr; + +#define GET_PORT_PRIVATE(pScrn) \ + (GLINTPortPrivPtr)((GLINTPTR(pScrn))->adaptor->pPortPrivates[0].ptr) - /* Find the buffer that is being removed */ - for (i = 0; i < MAX_BUFFERS && pPPriv->Buffer[i] != Buffer; i++); - if (i >= MAX_BUFFERS) return; - - if (i == pPPriv->display) pPPriv->display = -1; - if (i == pPPriv->copy) pPPriv->copy = -1; - pPPriv->Buffer[i] = NULL; +#define RAMDAC_WRITE(data,index) \ +do{ \ + GLINT_WRITE_REG(((index)>>8)&0xff, PM3RD_IndexHigh); \ + GLINT_WRITE_REG((index)&0xff, PM3RD_IndexLow); \ + GLINT_WRITE_REG(data, PM3RD_IndexedData); \ +}while(0) + +void Permedia3ResetVideo(ScrnInfoPtr pScrn) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTPortPrivPtr pPriv = pGlint->adaptor->pPortPrivates[0].ptr; + + GLINT_WAIT(15); + GLINT_WRITE_REG(0xfff0|(0xffff<<16), PM3VideoOverlayFifoControl); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, PM3VideoOverlayMode); + pPriv->ramdacOn = FALSE; + RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, PM3RD_VideoOverlayControl); + RAMDAC_WRITE((pPriv->colorKey&0xff0000)>>16, PM3RD_VideoOverlayKeyR); + RAMDAC_WRITE((pPriv->colorKey&0x00ff00)>>8, PM3RD_VideoOverlayKeyG); + RAMDAC_WRITE(pPriv->colorKey&0x0000ff, PM3RD_VideoOverlayKeyB); + GLINT_WRITE_REG(PM3VideoOverlayUpdate_ENABLE, PM3VideoOverlayUpdate); } -static void -FreeBuffers(PortPrivPtr pPPriv, Bool from_timer) + +static XF86VideoAdaptorPtr +Permedia3SetupImageVideo(ScreenPtr pScreen) { - int i = -1; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GLINTPtr pGlint = GLINTPTR(pScrn); + XF86VideoAdaptorPtr adapt; + GLINTPortPrivPtr pPriv; - if (!from_timer) { - if (pPPriv->TimerInUse) { - pPPriv->TimerInUse = FALSE; - TimerCancel(pPPriv->Timer); - } - } + if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(GLINTPortPrivRec) + + sizeof(DevUnion)))) + return NULL; - pPPriv->display = -1; - pPPriv->copy = -1; - for (i=0; i < MAX_BUFFERS; i++) - if (pPPriv->Buffer[i]) { - xf86FreeOffscreenArea (pPPriv->Buffer[i]); - pPPriv->Buffer[i] = NULL; - } + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "Permedia3 Backend Scaler"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + pPriv = (GLINTPortPrivPtr)(&adapt->pPortPrivates[1]); + adapt->pPortPrivates[0].ptr = (pointer)(pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = Permedia3StopVideo; + adapt->SetPortAttribute = Permedia3SetPortAttribute; + adapt->GetPortAttribute = Permedia3GetPortAttribute; + adapt->QueryBestSize = Permedia3QueryBestSize; + adapt->PutImage = Permedia3PutImage; + adapt->QueryImageAttributes = Permedia3QueryImageAttributes; + + /* FIXME : depth 15 and 16 doesn't work here */ + pPriv->colorKey = pGlint->videoKey; + pPriv->videoStatus = 0; + pPriv->buffer = 0; /* double buffer (or maybe triple later) */ + pPriv->doubleBuffer = TRUE; + pPriv->autopaintColorKey = TRUE; + pPriv->Filter = PM3VideoOverlayMode_FILTER_FULL; + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + pGlint->adaptor = adapt; + + xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); + xvFilter = MAKE_ATOM("XV_FILTER"); + + Permedia3ResetVideo(pScrn); + + return adapt; } -static CARD32 -TimerCallback(OsTimerPtr pTim, CARD32 now, pointer p) + +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) { - PortPrivPtr pPPriv = (PortPrivPtr) p; + int *dataA, *dataB; + int num; - if (pPPriv->StopDelay >= 0) { - if (!(pPPriv->StopDelay--)) { - FreeBuffers(pPPriv, TRUE); - pPPriv->TimerInUse = FALSE; - } - } + num = REGION_NUM_RECTS(A); + if(num != REGION_NUM_RECTS(B)) + return FALSE; - if (pPPriv->TimerInUse) - return pPPriv->Instant; + 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); - return 0; /* Cancel */ + while(num--) { + if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; + } + + return TRUE; } -static int -AllocateBuffers(PortPrivPtr pPPriv, int w_bpp, int h) +static void +Permedia3StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) { - AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; - ScrnInfoPtr pScrn = pAPriv->pScrn; - int i = -1; - - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "We try to allocate a %dx%d buffer.\n", w_bpp, h)); - /* we start a timer to free the buffers if they are nto used within - * 5 seconds (pPPriv->Delay * pPPriv->Instant) */ - pPPriv->StopDelay = pPPriv->Delay; - if (!pPPriv->TimerInUse) { - pPPriv->TimerInUse = TRUE; - TimerSet(pPPriv->Timer, 0, 80, TimerCallback, pAPriv); - } + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; + int i; - for (i=0; i < MAX_BUFFERS - && (i == pPPriv->display || i == pPPriv->copy); i++); - - if (pPPriv->Buffer[i]) { - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Buffer %d exists.\n", i)); - if ((pPPriv->Buffer[i]->box.x2 - pPPriv->Buffer[i]->box.x1) == w_bpp && - (pPPriv->Buffer[i]->box.y2 - pPPriv->Buffer[i]->box.y1) == h) { - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Buffer %d is of the good size, let's use it.\n", i)); - return (pPPriv->copy = i); - } - else if (xf86ResizeOffscreenArea (pPPriv->Buffer[i], w_bpp, h)) { - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "I was able to resize buffer %d, let's use it.\n", i)); - pPPriv->BufferBase[i] = - ((pPPriv->Buffer[i]->box.y1 * pScrn->displayWidth) + - pPPriv->Buffer[i]->box.x1)<<pPPriv->FB_Shift; - return (pPPriv->copy = i); - } - else { - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "I was not able to resize buffer %d.\n", i)); - xf86FreeOffscreenArea (pPPriv->Buffer[i]); - pPPriv->Buffer[i] = NULL; - } + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if(shutdown) { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->ramdacOn = FALSE; + GLINT_WAIT(4); + RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, + PM3RD_VideoOverlayControl); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, + PM3VideoOverlayMode); + } + for (i = 0; i < (pPriv->doubleBuffer ? 2 : 1); i++) { + if(pPriv->area[i]) { + xf86FreeOffscreenArea(pPriv->area[i]); + pPriv->area[i] = NULL; + } + } + pPriv->videoStatus = 0; + } else { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; + } + } +} + +static int +Permedia3SetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value, + pointer data +){ + GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; + GLINTPtr pGlint = GLINTPTR(pScrn); + + if (attribute == xvDoubleBuffer) + { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->doubleBuffer = value; + } + else if (attribute == xvColorKey) + { + pPriv->colorKey = value; + GLINT_WAIT(9); + RAMDAC_WRITE((value & 0xff0000)>>16, PM3RD_VideoOverlayKeyR); + RAMDAC_WRITE((value & 0x00ff00)>>8, PM3RD_VideoOverlayKeyG); + RAMDAC_WRITE((value & 0x0000ff), PM3RD_VideoOverlayKeyB); + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); } - if ((pPPriv->Buffer[i] = xf86AllocateOffscreenArea (pScrn->pScreen, - w_bpp, h, 4 >> pPPriv->FB_Shift, NULL, NULL, (pointer) pPPriv))) { - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Sucessfully allocated buffer %d, let's use it.\n", i)); - pPPriv->BufferBase[i] = - ((pPPriv->Buffer[i]->box.y1 * pScrn->displayWidth) + - pPPriv->Buffer[i]->box.x1)<<pPPriv->FB_Shift; - return (pPPriv->copy = i); + else if (attribute == xvAutopaintColorKey) + { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->autopaintColorKey = value; + } + else if (attribute == xvFilter) + { + if ((value < 0) || (value > 2)) + return BadValue; + switch (value) { + case 0: + pPriv->Filter = PM3VideoOverlayMode_FILTER_OFF; + break; + case 1: + pPriv->Filter = PM3VideoOverlayMode_FILTER_FULL; + break; + case 2: + pPriv->Filter = PM3VideoOverlayMode_FILTER_PARTIAL; + break; + } } - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Unable to allocate a buffer.\n")); - return -1; + else + return BadMatch; + + return Success; } -/* - * Xv interface - */ +static int +Permedia3GetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value, + pointer data +){ + GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; + + if (attribute == xvDoubleBuffer) + *value = (pPriv->doubleBuffer) ? 1 : 0; + else if (attribute == xvColorKey) + *value = pPriv->colorKey; + else if (attribute == xvAutopaintColorKey) + *value = (pPriv->autopaintColorKey) ? 1 : 0; + else if (attribute == xvFilter) + *value = pPriv->Filter >> 14; + else + return BadMatch; + + return Success; +} + +static void +Permedia3QueryBestSize( + ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +){ + if(vid_w > (drw_w << 3)) + drw_w = vid_w >> 3; + if(vid_h > (drw_h << 3)) + drw_h = vid_h >> 3; + + *p_w = drw_w; + *p_h = drw_h; +} -#if USE_HARDWARE_COPY static void -HWCopySetup(PortPrivPtr pPPriv, int x, int y, int w, int h) +HWCopySetup(ScrnInfoPtr pScrn, int x, int y, int w, int h) { - AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; - ScrnInfoPtr pScrn = pAPriv->pScrn; GLINTPtr pGlint = GLINTPTR(pScrn); - DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "x = %d, y = %d, w = %d, h = %d.\n", x, y, w, h)); GLINT_WAIT(4); GLINT_WRITE_REG(0xffffffff, FBHardwareWriteMask); @@ -418,37 +525,41 @@ HWCopySetup(PortPrivPtr pPPriv, int x, int y, int w, int h) PM3Render2D_Width(w) | PM3Render2D_Height(h), PM3Render2D); } + static void -HWCopyYV12(PortPrivPtr pPPriv, CARD8 *Y, int w, int h) +HWCopyYV12(ScrnInfoPtr pScrn, CARD8 *Y, int w, int h) { - AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; - ScrnInfoPtr pScrn = pAPriv->pScrn; GLINTPtr pGlint = GLINTPTR(pScrn); - int Y_size = w * h; - CARD8 *V = Y + Y_size; - CARD8 *U = V + (Y_size >> 2); + int size = w * h; + CARD8 *V = Y + size; + CARD8 *U = V + (size >> 2); CARD32 *dst; - int dwords, i, x; + int pass2 = 0; + int dwords, i, x = 0; + + dwords = size >> 1; - dwords = Y_size >> 1; + w >>= 1; - x = 0; while (dwords >= pGlint->FIFOSize) { dst = (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4); GLINT_WAIT(pGlint->FIFOSize); /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | 0x05, OutputFIFO); - for (i = pGlint->FIFOSize - 1; i; i--, Y += 2, U++, V++, dst++, x++) { - /* mmm, i don't know if this is really needed, as we perform - * endianess inversion as usual, let's check it before removing */ -#if X_BYTE_ORDER == X_BIG_ENDIAN - *dst = V[0] + (Y[1] << 8) + (U[0] << 16) + (Y[0] << 24); -#else - *dst = Y[0] + (U[0] << 8) + (Y[1] << 16) + (V[0] << 24); -#endif - if (x == w>>1) { U -= w>>1; V -= w>>1; } - if (x == w) x = 0; + for (i = pGlint->FIFOSize - 1; i; i--, Y += 2, x++) { + if (x == w) { + x = 0; + if (pass2 == 0) + pass2 = 1; + else + if (pass2 == 1) { + pass2 = 0; + U += w; + V += w; + } + } + *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); } dwords -= pGlint->FIFOSize - 1; } @@ -458,125 +569,112 @@ HWCopyYV12(PortPrivPtr pPPriv, CARD8 *Y, int w, int h) /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ GLINT_WRITE_REG(((dwords - 1) << 16) | (0x15 << 4) | 0x05, OutputFIFO); - for (i = dwords; i; i--, Y += 2, U++, V++, dst++, x++) { - /* mmm, i don't know if this is really needed, as we perform - * endianess inversion as usual, let's check it before removing */ -#if X_BYTE_ORDER == X_BIG_ENDIAN - *dst = V[0] + (Y[1] << 8) + (U[0] << 16) + (Y[0] << 24); -#else - *dst = Y[0] + (U[0] << 8) + (Y[1] << 16) + (V[0] << 24); -#endif - if (x == w>>1) { U -= w>>1; V -= w>>1; } - if (x == w) x = 0; + for (i = dwords; i; i--, Y += 2, x++) { + if (x == w) { + x = 0; + if (pass2 == 0) + pass2 = 1; + else + if (pass2 == 1) { + pass2 = 0; + U += w; + V += w; + } + } + *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); } } } + static void -HWCopyFlat(PortPrivPtr pPPriv, CARD8 *src, int w, int h) +HWCopyFlat(ScrnInfoPtr pScrn, CARD8 *src, int w, int h) { - AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; - ScrnInfoPtr pScrn = pAPriv->pScrn; GLINTPtr pGlint = GLINTPTR(pScrn); - int size = w * h; - int pitch = pScrn->displayWidth<<pPPriv->FB_Shift; - CARD32 *dst; + GLINTPortPrivPtr pPriv = pGlint->adaptor->pPortPrivates[0].ptr; + int pitch = pScrn->displayWidth; CARD8 *tmp_src; - int dwords, i; + int dwords; if (w == pitch) { - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "HWCopyFlat : src = %08x, w = pitch = %d, h = %d.\n", - src, w, h)); - dwords = size >> pPPriv->Video_Shift; - while (dwords >= pGlint->FIFOSize) { - dst = (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4); + dwords = (w * h) >> (2 - pPriv->Video_Shift); + while(dwords >= pGlint->FIFOSize) { GLINT_WAIT(pGlint->FIFOSize); - GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | - 0x05, OutputFIFO); - for (i = pGlint->FIFOSize - 1; i; i--, dst++, src++) *dst = *src; + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)src, pGlint->FIFOSize - 1); dwords -= pGlint->FIFOSize - 1; - } - if (dwords) { - dst = (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4); + src += pGlint->FIFOSize - 1; + } + if(dwords) { GLINT_WAIT(dwords + 1); - GLINT_WRITE_REG(((dwords - 1) << 16) | (0x15 << 4) | - 0x05, OutputFIFO); - for (i = dwords; i; i--, dst++, src++) *dst = *src; - } + GLINT_WRITE_REG(((dwords - 1) << 16)|(0x15 << 4) |0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)src, dwords); + } } else { - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "HWCopyFlat : src = %08x, w = %d, pitch = %d, h = %d.\n", - src, w, pitch, h)); - while (h) { - tmp_src = src; - dwords = w >> pPPriv->Video_Shift; - while (dwords >= pGlint->FIFOSize) { - dst = (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4); + while (h--) { + tmp_src = src; + dwords = w >> (2 - pPriv->Video_Shift); + while(dwords >= pGlint->FIFOSize) { GLINT_WAIT(pGlint->FIFOSize); - GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | - 0x05, OutputFIFO); - for (i = pGlint->FIFOSize - 1; i; i--, dst++, src++) *dst = *src; + GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | + 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)src, pGlint->FIFOSize - 1); dwords -= pGlint->FIFOSize - 1; - } - if (dwords) { - dst = (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4); + src += pGlint->FIFOSize - 1; + } + if(dwords) { GLINT_WAIT(dwords + 1); - GLINT_WRITE_REG(((dwords - 1) << 16) | (0x15 << 4) | - 0x05, OutputFIFO); - for (i = dwords; i; i--, dst++, src++) *dst = *src; - } - src = tmp_src + pitch; - } - } -} -#else -static void -CopyYV12(CARD8 *Y, CARD32 *dst, int width, int height, int pitch) -{ - int Y_size = width * height; - CARD8 *V = Y + Y_size; - CARD8 *U = V + (Y_size >> 2); - int pad = (pitch >> 2) - (width >> 1); - int x; - - width >>= 1; - - for (height >>= 1; height > 0; height--) { - for (x = 0; x < width; Y += 2, x++) -#if X_BYTE_ORDER == X_BIG_ENDIAN - *dst++ = V[x] + (Y[1] << 8) + (U[x] << 16) + (Y[0] << 24); -#else - *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); -#endif - dst += pad; - for (x = 0; x < width; Y += 2, x++) -#if X_BYTE_ORDER == X_BIG_ENDIAN - *dst++ = V[x] + (Y[1] << 8) + (U[x] << 16) + (Y[0] << 24); -#else - *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); -#endif - dst += pad; - U += width; - V += width; + GLINT_WRITE_REG(((dwords-1)<<16)|(0x15<<4) | 0x05, OutputFIFO); + GLINT_MoveDWORDS( + (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), + (CARD32*)src, dwords); + } + src = tmp_src + (w << pPriv->Video_Shift); + } } } -static void -CopyFlat(CARD8 *src, CARD8 *dst, int width, int height, int pitch) +static FBAreaPtr +Permedia3AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area, int width, int height) { - if (width == pitch) { - memcpy(dst, src, width * height); - return; - } + ScreenPtr pScreen; + FBAreaPtr new_area; - while (height > 0) { - memcpy(dst, src, width); - dst += pitch; - src += width; - height--; - } + if (area) { + if ((area->box.x2 - area->box.x1 >= width) && + (area->box.y2 - area->box.y1 >= height)) + return area; + + if (xf86ResizeOffscreenArea(area, width, height)) + return area; + + xf86FreeOffscreenArea(area); + } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_area = xf86AllocateOffscreenArea(pScreen, width, height, pScrn->bitsPerPixel / 8, NULL, NULL, NULL); + + if (!new_area) { + int max_width, max_height; + + xf86QueryLargestOffscreenArea(pScreen, &max_width, &max_height, pScrn->bitsPerPixel / 8, 0, PRIORITY_EXTREME); + + if (max_width < width || max_height < height) + return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_area = xf86AllocateOffscreenArea(pScreen, width, height, pScrn->bitsPerPixel / 8, NULL, NULL, NULL); + } + + return new_area; } -#endif #define FORMAT_RGB8888 PM3VideoOverlayMode_COLORFORMAT_RGB8888 #define FORMAT_RGB4444 PM3VideoOverlayMode_COLORFORMAT_RGB4444 @@ -594,153 +692,73 @@ CopyFlat(CARD8 *src, CARD8 *dst, int width, int height, int pitch) #define FORMAT_VUY422 PM3VideoOverlayMode_COLORFORMAT_VUY422 #define FORMAT_YUV422 PM3VideoOverlayMode_COLORFORMAT_YUV422 -#define RAMDAC_WRITE(data,index) \ -do{ \ - mem_barrier(); \ - GLINT_WAIT(3); \ - mem_barrier(); \ - GLINT_WRITE_REG(((index)>>8)&0xff, PM3RD_IndexHigh); \ - mem_barrier(); \ - GLINT_WRITE_REG((index)&0xff, PM3RD_IndexLow); \ - mem_barrier(); \ - GLINT_WRITE_REG(data, PM3RD_IndexedData); \ - mem_barrier(); \ -}while(0) - -#define RAMDAC_WRITE_OLD(data,index) \ - Permedia2vOutIndReg(pScrn, index, 0x00, data) - /* Notice, have to check that we dont overflow the deltas here ... */ static void compute_scale_factor( - unsigned int* src_w, unsigned int* dst_w, + short* src_w, short* dst_w, unsigned int* shrink_delta, unsigned int* zoom_delta) { + /* NOTE: If we don't return reasonable values here then the video + * unit can potential shut off and won't display an image until re-enabled. + * Seems as though the zoom_delta is o.k, and I've not had the problem. + * The 'shrink_delta' is prone to this the most - FIXME ! */ + if (*src_w >= *dst_w) { + *src_w &= ~0x3; *dst_w &= ~0x3; - *shrink_delta = (((*src_w << 16) / *dst_w) & 0x0ffffff0) + 0x10; + *shrink_delta = (((*src_w << 16) / *dst_w) + 0x0f) & 0x0ffffff0; *zoom_delta = 1<<16; + if ( ((*shrink_delta * *dst_w) >> 16) & 0x03 ) + *shrink_delta += 0x10; } else { - if (*src_w & 0x3) *src_w = (*src_w & ~0x3) + 4; + *src_w &= ~0x3; + *dst_w &= ~0x3; + *zoom_delta = (((*src_w << 16) / *dst_w) + 0x0f) & 0x0001fff0; *shrink_delta = 1<<16; - for (;*dst_w > *src_w; (*dst_w)--) { - *zoom_delta = (*src_w << 16) / *dst_w; - if (((((*zoom_delta&0xf)+1) * *dst_w * *dst_w) >> 16) < *src_w) { - *zoom_delta = ((*zoom_delta & ~0xf) + 0x10) & 0x0001fff0; - return; - } - } - *zoom_delta = 1<<16; + if ( ((*zoom_delta * *dst_w) >> 16) & 0x03 ) + *zoom_delta += 0x10; } } static void -BeginOverlay(PortPrivPtr pPPriv, int display) -{ - AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; - ScrnInfoPtr pScrn = pAPriv->pScrn; +Permedia3DisplayVideo( + ScrnInfoPtr pScrn, + int id, + int offset, + short width, short height, + int x1, int y1, int x2, int y2, + BoxPtr dstBox, + short src_w, short src_h, + short drw_w, short drw_h +){ GLINTPtr pGlint = GLINTPTR(pScrn); - unsigned int src_x = pPPriv->vx, dst_x = pPPriv->dx; - unsigned int src_y = pPPriv->vy, dst_y = pPPriv->dy; - unsigned int src_w = pPPriv->vw, dst_w = pPPriv->dw; - unsigned int src_h = pPPriv->vh, dst_h = pPPriv->dh; - unsigned int shrink_delta, zoom_delta; -#if BLACKNESS_WORKAROUND - static int Frames = 50; -#endif - unsigned int stride = - (pScrn->displayWidth << pPPriv->FB_Shift) >> pPPriv->Video_Shift; + GLINTPortPrivPtr portPriv = pGlint->adaptor->pPortPrivates[0].ptr; + unsigned int shrink, zoom; + unsigned int newx1, newx2; /* Let's overlay only to visible parts of the screen */ - if (pPPriv->dx < pScrn->frameX0) { - dst_w = dst_w - pScrn->frameX0 + dst_x; - dst_x = 0; - src_w = dst_w * pPPriv->vw / pPPriv->dw; - src_x = src_x + pPPriv->vw - src_w; - } else if (pScrn->frameX0 > 0) dst_x = dst_x - pScrn->frameX0; - if (pPPriv->dy < pScrn->frameY0) { - dst_h = dst_h - pScrn->frameY0 + pPPriv->dy; - dst_y = 0; - src_h = dst_h * pPPriv->vh / pPPriv->dh; - src_y = src_y + pPPriv->vh - src_h; - } else if (pScrn->frameY0 > 0) dst_y = dst_y - pScrn->frameY0; - if (dst_x + dst_w > (pScrn->frameX1 - pScrn->frameX0)) { - unsigned int old_w = dst_w; - dst_w = pScrn->frameX1 - pScrn->frameX0 - dst_x; - src_w = dst_w * src_w / old_w; + if (dstBox->x1 == 0) { + x1 = drw_w - dstBox->x2; + drw_w = dstBox->x2; } - if (dst_y + dst_h > (pScrn->frameY1 - pScrn->frameY0)) { - unsigned int old_h = dst_h; - dst_h = pScrn->frameY1 - pScrn->frameY0 - dst_y; - src_h = dst_h * src_h / old_h; + if (dstBox->x2 == pScrn->frameX1) { + x2 = drw_w - (dstBox->x2 - dstBox->x1); + drw_w = (dstBox->x2 - dstBox->x1); } /* Let's adjust the width of source and dest to be compliant with * the Permedia3 overlay unit requirement, and compute the X deltas. */ - compute_scale_factor(&src_w, &dst_w, &shrink_delta, &zoom_delta); - -#if BLACKNESS_WORKAROUND - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "BeginOverlay %d (buffer %d)\n", Frames, display)); -#else - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "BeginOverlay (buffer %d)\n", display)); -#endif - if (src_w != pPPriv->vw) - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "BeginOverlay : Padding video width to 4 pixels %d->%d.\n", - pPPriv->vw, src_w)); - if (dst_w != pPPriv->dw) - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "BeginOverlay : Scaling destination width from %d to %d.\n" - "\tThe scaling factor is to high, and may cause problems.\n", - pPPriv->dw, dst_w)); - - if (display != -1) pPPriv->display = display; - -#if BLACKNESS_WORKAROUND - if (++Frames>25) { - Frames = 0; - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Registers (1) : %08x, %08x, %08x, %08x, %08x.\n", - GLINT_READ_REG(PM3VideoOverlayFifoControl), - GLINT_READ_REG(PM3VideoOverlayMode), - GLINT_READ_REG(PM3VideoOverlayBase0), - GLINT_READ_REG(PM3VideoOverlayBase1), - GLINT_READ_REG(PM3VideoOverlayBase2))); - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Registers (2) : %08x, %08x, %08x, %08x.\n", - GLINT_READ_REG(PM3VideoOverlayStride), - GLINT_READ_REG(PM3VideoOverlayWidth), - GLINT_READ_REG(PM3VideoOverlayHeight), - GLINT_READ_REG(PM3VideoOverlayOrigin))); - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Registers (3) : %08x, %08x, %08x, %08x.\n", - GLINT_READ_REG(PM3VideoOverlayYDelta), - GLINT_READ_REG(PM3VideoOverlayShrinkXDelta), - GLINT_READ_REG(PM3VideoOverlayZoomXDelta), - GLINT_READ_REG(PM3VideoOverlayIndex))); - GLINT_WAIT(8); - GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, - PM3VideoOverlayMode); - } else GLINT_WAIT(7); -#else - GLINT_WAIT(7); -#endif - GLINT_WRITE_REG(3|(12<<16), PM3VideoOverlayFifoControl); - /* Updating the Video Overlay Source Image Parameters */ - GLINT_WRITE_REG( - pPPriv->BufferBase[pPPriv->display]>>pPPriv->Video_Shift, - PM3VideoOverlayBase+(pPPriv->display*8)); - GLINT_WRITE_REG(pPPriv->Format | - PM3VideoOverlayMode_BUFFERSYNC_MANUAL | - PM3VideoOverlayMode_FLIP_VIDEO | - /* Filtering & Mirroring Attributes */ - pPPriv->OverlayMode | - PM3VideoOverlayMode_ENABLE, - PM3VideoOverlayMode); - /* Let's set the source stride. */ - GLINT_WRITE_REG(PM3VideoOverlayStride_STRIDE(stride), + newx1 = src_w; newx2 = drw_w; + compute_scale_factor(&src_w, &drw_w, &shrink, &zoom); + dstBox->x2 -= (newx2 - drw_w); + + /* We do a long wait here - for everything that needs to be written */ + GLINT_WAIT(39); + GLINT_WRITE_REG(offset>>portPriv->Video_Shift, + portPriv->buffer ? PM3VideoOverlayBase1 : PM3VideoOverlayBase0); + /* Let's set the source pitch. */ + GLINT_WRITE_REG(PM3VideoOverlayStride_STRIDE(pScrn->displayWidth<< + (pScrn->bitsPerPixel>>4) >>portPriv->Video_Shift), PM3VideoOverlayStride); /* Let's set the position and size of the visible part of the source. */ GLINT_WRITE_REG(PM3VideoOverlayWidth_WIDTH(src_w), @@ -748,834 +766,551 @@ BeginOverlay(PortPrivPtr pPPriv, int display) GLINT_WRITE_REG(PM3VideoOverlayHeight_HEIGHT(src_h), PM3VideoOverlayHeight); GLINT_WRITE_REG( - PM3VideoOverlayOrigin_XORIGIN(src_x) | - PM3VideoOverlayOrigin_YORIGIN(src_y), + PM3VideoOverlayOrigin_XORIGIN(x1) | + PM3VideoOverlayOrigin_YORIGIN(y1), PM3VideoOverlayOrigin); - - GLINT_WAIT(5); /* Scale the source to the destinationsize */ - if (src_h == dst_h) { + if (src_h == drw_h) { GLINT_WRITE_REG( PM3VideoOverlayYDelta_NONE, PM3VideoOverlayYDelta); } else { GLINT_WRITE_REG( - PM3VideoOverlayYDelta_DELTA(src_h,dst_h), + PM3VideoOverlayYDelta_DELTA(src_h,drw_h), PM3VideoOverlayYDelta); } - GLINT_WRITE_REG(shrink_delta, PM3VideoOverlayShrinkXDelta); - GLINT_WRITE_REG(zoom_delta, PM3VideoOverlayZoomXDelta); - GLINT_WRITE_REG(pPPriv->display, PM3VideoOverlayIndex); - GLINT_WRITE_REG(PM3VideoOverlayUpdate_ENABLE, - PM3VideoOverlayUpdate); - - - /* Now set the ramdac video overlay region and mode */ - if ((pPPriv->ramdac_x != dst_x) || (pPPriv->ramdac_w != dst_w)) { - RAMDAC_WRITE((dst_x&0xff), PM3RD_VideoOverlayXStartLow); - RAMDAC_WRITE((dst_x&0xf00)>>8, PM3RD_VideoOverlayXStartHigh); - RAMDAC_WRITE(((dst_x+dst_w)&0xff), PM3RD_VideoOverlayXEndLow); - RAMDAC_WRITE(((dst_x+dst_w)&0xf00)>>8,PM3RD_VideoOverlayXEndHigh); - pPPriv->ramdac_x = dst_x; - pPPriv->ramdac_w = dst_w; - } - if ((pPPriv->ramdac_y != dst_y) || (pPPriv->ramdac_h != dst_h)) { - RAMDAC_WRITE((dst_y&0xff), PM3RD_VideoOverlayYStartLow); - RAMDAC_WRITE((dst_y&0xf00)>>8, PM3RD_VideoOverlayYStartHigh); - RAMDAC_WRITE(((dst_y+dst_h)&0xff), PM3RD_VideoOverlayYEndLow); - RAMDAC_WRITE(((dst_y+dst_h)&0xf00)>>8,PM3RD_VideoOverlayYEndHigh); - pPPriv->ramdac_y = dst_y; - pPPriv->ramdac_h = dst_h; - } - - if (!pPPriv->ramdac_on) { - if (pPPriv->OverlayAlpha<(3<<6)) { - RAMDAC_WRITE(pPPriv->OverlayAlpha, PM3RD_VideoOverlayBlend); - RAMDAC_WRITE(PM3RD_VideoOverlayControl_ENABLE | - PM3RD_VideoOverlayControl_MODE_BLEND | - PM3RD_VideoOverlayControl_BLENDSRC_REGISTER, - PM3RD_VideoOverlayControl); - } else { -#if SUPPORT_CLIPPING - switch (pScrn->depth) { - case 8: - case 16: - RAMDAC_WRITE((pPPriv->ColorKey&0xff0000)>>16, - PM3RD_VideoOverlayKeyR); - RAMDAC_WRITE((pPPriv->ColorKey&0x00ff00)>>8, - PM3RD_VideoOverlayKeyG); - RAMDAC_WRITE(pPPriv->ColorKey&0x0000ff, - PM3RD_VideoOverlayKeyB); - RAMDAC_WRITE(PM3RD_VideoOverlayControl_ENABLE | - PM3RD_VideoOverlayControl_MODE_MAINKEY | - PM3RD_VideoOverlayControl_KEY_COLOR, - PM3RD_VideoOverlayControl); - break; - case 15: - RAMDAC_WRITE(0x1, PM3RD_VideoOverlayKeyR); - RAMDAC_WRITE(PM3RD_VideoOverlayControl_ENABLE | - PM3RD_VideoOverlayControl_MODE_MAINKEY | - PM3RD_VideoOverlayControl_KEY_ALPHA, - PM3RD_VideoOverlayControl); - break; - case 24: - RAMDAC_WRITE(0xff, PM3RD_VideoOverlayKeyR); - RAMDAC_WRITE(PM3RD_VideoOverlayControl_ENABLE | - PM3RD_VideoOverlayControl_MODE_MAINKEY | - PM3RD_VideoOverlayControl_KEY_ALPHA, - PM3RD_VideoOverlayControl); - break; - } -#else - RAMDAC_WRITE(PM3RD_VideoOverlayControl_ENABLE | - PM3RD_VideoOverlayControl_MODE_ALWAYS, - PM3RD_VideoOverlayControl); -#endif - } - pPPriv->ramdac_on = TRUE; - } - - pPPriv->Buffer[pPPriv->display]->RemoveAreaCallback = - RemoveBufferCallback; - if (display != -1) pPPriv->copy = -1; -} - -#if SUPPORT_CLIPPING - -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 Clip (PortPrivPtr pPPriv, RegionPtr clipBoxes) -{ - AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; - ScrnInfoPtr pScrn = pAPriv->pScrn; - - /* Let's handle the clipping here. */ - if(!RegionsEqual(&pPPriv->clip, clipBoxes)) { - REGION_COPY(pScrn->pScreen, &pPPriv->clip, clipBoxes); - if (pPPriv->OverlayAlpha<(3<<6)) { - XAAFillSolidRects(pScrn, pPPriv->OverlayAlpha<<24, GXcopy, - 0xff000000, REGION_NUM_RECTS(clipBoxes), - REGION_RECTS(clipBoxes)); - } else { - switch (pScrn->depth) { - case 8: /* CI8 */ - XAAFillSolidRects(pScrn, pPPriv->ColorKey, - GXcopy, 0xffffffff, REGION_NUM_RECTS(clipBoxes), - REGION_RECTS(clipBoxes)); - break; - case 15: /* RGB5551 */ - XAAFillSolidRects(pScrn, 0xffffffff, GXcopy, 0x80008000, - REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); - break; - case 16: /* RGB565 */ - XAAFillSolidRects(pScrn, pPPriv->ColorKey, GXcopy, - 0xffffffff, REGION_NUM_RECTS(clipBoxes), - REGION_RECTS(clipBoxes)); - break; - case 24: /* RGB8888 */ - XAAFillSolidRects(pScrn, 0xffffffff, GXcopy, - 0xff000000, REGION_NUM_RECTS(clipBoxes), - REGION_RECTS(clipBoxes)); - break; - } - } + if (src_w == drw_w) { + GLINT_WRITE_REG(1<<16, PM3VideoOverlayShrinkXDelta); + GLINT_WRITE_REG(1<<16, PM3VideoOverlayZoomXDelta); + } else { + GLINT_WRITE_REG(shrink, PM3VideoOverlayShrinkXDelta); + GLINT_WRITE_REG(zoom, PM3VideoOverlayZoomXDelta); } -} -#endif - -static void -StopOverlay(PortPrivPtr pPPriv, int cleanup) -{ - AdaptorPrivPtr pAPriv = pPPriv->pAdaptor; - ScrnInfoPtr pScrn = pAPriv->pScrn; - GLINTPtr pGlint = GLINTPTR(pScrn); + GLINT_WRITE_REG(portPriv->buffer, PM3VideoOverlayIndex); - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "StopOverlay.\n")); - /* Stop the Video Overlay in the RAMDAC */ - if (pPPriv->ramdac_on) { - RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, - PM3RD_VideoOverlayControl); - pPPriv->ramdac_on = FALSE; - } - /* Stop the Video Overlay in the Video Overlay Unit */ - GLINT_WAIT(1); - GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, + /* Now set the ramdac video overlay region and mode */ + RAMDAC_WRITE((dstBox->x1&0xff), PM3RD_VideoOverlayXStartLow); + RAMDAC_WRITE((dstBox->x1&0xf00)>>8, PM3RD_VideoOverlayXStartHigh); + RAMDAC_WRITE((dstBox->x2&0xff), PM3RD_VideoOverlayXEndLow); + RAMDAC_WRITE((dstBox->x2&0xf00)>>8,PM3RD_VideoOverlayXEndHigh); + RAMDAC_WRITE((dstBox->y1&0xff), PM3RD_VideoOverlayYStartLow); + RAMDAC_WRITE((dstBox->y1&0xf00)>>8, PM3RD_VideoOverlayYStartHigh); + RAMDAC_WRITE((dstBox->y2&0xff), PM3RD_VideoOverlayYEndLow); + RAMDAC_WRITE((dstBox->y2&0xf00)>>8,PM3RD_VideoOverlayYEndHigh); + + GLINT_WRITE_REG(portPriv->Video_Shift << 5 | + portPriv->Format | + portPriv->Filter | + PM3VideoOverlayMode_BUFFERSYNC_MANUAL | + PM3VideoOverlayMode_FLIP_VIDEO | + PM3VideoOverlayMode_ENABLE, PM3VideoOverlayMode); -} -/* ReputImage is used if only the destination position or - * the clipboxes change. */ -static int -Permedia3ReputImage(ScrnInfoPtr pScrn, - short drw_x, short drw_y, - RegionPtr clipBoxes, pointer data) -{ - PortPrivPtr pPPriv = (PortPrivPtr) data; - - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "ReputImage %d,%d.\n", drw_x, drw_y)); - -#if !SUPPORT_CLIPPING - /* If the clip region is not a rectangle */ - if (REGION_SIZE(clipBoxes) != 0) { - StopOverlay (pPPriv, FALSE); - return Success; - } -#endif - - /* If the buffer was freed, we cannot overlay it. */ - if (pPPriv->display == -1) { - StopOverlay (pPPriv, FALSE); - return Success; - } - /* Check that the dst area is some part of the visible screen. */ - if ((drw_x + pPPriv->dw) < pScrn->frameX0 || - (drw_y + pPPriv->dh) < pScrn->frameY0 || - drw_x > pScrn->frameX1 || drw_y > pScrn->frameY1) { - return Success; + if (!portPriv->ramdacOn) { + RAMDAC_WRITE(PM3RD_VideoOverlayControl_ENABLE | + PM3RD_VideoOverlayControl_KEY_COLOR | + PM3RD_VideoOverlayControl_MODE_MAINKEY | + PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED, + PM3RD_VideoOverlayControl); + portPriv->ramdacOn = TRUE; } - /* Copy the destinations coordinates */ - pPPriv->dx = drw_x; - pPPriv->dy = drw_y; - -#if SUPPORT_CLIPPING - /* Clipping */ - Clip (pPPriv, clipBoxes); -#endif - - /* Restart the overlay */ - BeginOverlay(pPPriv, -1); - - return Success; + GLINT_WRITE_REG(PM3VideoOverlayUpdate_ENABLE, + PM3VideoOverlayUpdate); } -static int -Permedia3PutImage(ScrnInfoPtr pScrn, - short src_x, short src_y, short drw_x, short drw_y, - short src_w, short src_h, short drw_w, short drw_h, - int id, unsigned char *buf, short width, short height, - Bool sync, RegionPtr clipBoxes, pointer data) -{ - PortPrivPtr pPPriv = (PortPrivPtr) data; -#if !USE_HARDWARE_COPY - GLINTPtr pGlint = GLINTPTR(pScrn); -#endif - int copy = -1; - Bool copy_flat = TRUE; - int w_bpp; - - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "PutImage %d,%d,%d,%d -> %d,%d,%d,%d " - "id=0x%08x buf=%p w=%d h=%d sync=%d\n", - src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, - id, buf, width, height, sync)); - -#if !SUPPORT_CLIPPING - /* If the clip region is not a rectangle */ - if (REGION_SIZE(clipBoxes) != 0) { - StopOverlay (pPPriv, FALSE); - return Success; - } -#endif - - /* Check that the src area to put is included in the buffer. */ - if ((src_x + src_w) > width || - (src_y + src_h) > height || - src_x < 0 || src_y < 0) { - StopOverlay(pPPriv, FALSE); - return BadValue; - } - - /* Check that the dst area is some part of the visible screen. */ - if ((drw_x + drw_w) < pScrn->frameX0 || - (drw_y + drw_h) < pScrn->frameY0 || - drw_x > pScrn->frameX1 || drw_y > pScrn->frameY1) { - StopOverlay(pPPriv, FALSE); - return Success; - } - - /* Copy the source and destinations coordinates and size */ - pPPriv->vx = src_x; - pPPriv->vy = src_y; - pPPriv->vw = src_w; - pPPriv->vh = src_h; - - pPPriv->dx = drw_x; - pPPriv->dy = drw_y; - pPPriv->dw = drw_w; - pPPriv->dh = drw_h; - - /* If the image format changed since a previous call, - * let's check if it is supported. By default, we suppose that - * the previous image format was ScalerImages[0].id */ - if (id != pPPriv->Id) { - int i; - for (i = 0; i < ENTRIES(ScalerImages); i++) - if (id == ScalerImages[i].id) - break; - if (i >= ENTRIES(ScalerImages)) - return XvBadAlloc; - pPPriv->Id = id; - } - - /* Let's find the image format and Video_Shift values */ - switch (id) { +static int +Permedia3PutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool sync, + RegionPtr clipBoxes, pointer data +){ + GLINTPtr pGlint = GLINTPTR(pScrn); + GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; + INT32 x1, x2, y1, y2; + int pitch; + int i; + int w_bpp, bpp; + Bool copy_flat = TRUE; + BoxRec dstBox; + + /* Let's find the image format and Video_Shift values */ + switch (id) { case LE4CC('Y','V','1','2'): - pPPriv->Format = FORMAT_YUV422; - pPPriv->Video_Shift = 1; + pPriv->Format = FORMAT_YUV422; + pPriv->Video_Shift = 1; copy_flat = FALSE; break; case LE4CC('Y','U','Y','2'): - pPPriv->Format = FORMAT_YUV422; - pPPriv->Video_Shift = 1; + pPriv->Format = FORMAT_YUV422; + pPriv->Video_Shift = 1; break; case LE4CC('U','Y','V','Y'): - pPPriv->Format = FORMAT_VUY422; - pPPriv->Video_Shift = 1; + pPriv->Format = FORMAT_VUY422; + pPriv->Video_Shift = 1; break; case LE4CC('Y','U','V','A'): - pPPriv->Format = FORMAT_YUV444; - pPPriv->Video_Shift = 2; + pPriv->Format = FORMAT_YUV444; + pPriv->Video_Shift = 2; break; case LE4CC('V','U','Y','A'): - pPPriv->Format = FORMAT_VUY444; - pPPriv->Video_Shift = 2; + pPriv->Format = FORMAT_VUY444; + pPriv->Video_Shift = 2; break; case 0x41: /* RGBA 8:8:8:8 */ - pPPriv->Format = FORMAT_RGB8888; - pPPriv->Video_Shift = 2; + pPriv->Format = FORMAT_RGB8888; + pPriv->Video_Shift = 2; break; case 0x42: /* RGB 5:6:5 */ - pPPriv->Format = FORMAT_RGB565; - pPPriv->Video_Shift = 1; + pPriv->Format = FORMAT_RGB565; + pPriv->Video_Shift = 1; break; case 0x43: /* RGB 1:5:5:5 */ - pPPriv->Format = FORMAT_RGB5551; - pPPriv->Video_Shift = 1; + pPriv->Format = FORMAT_RGB5551; + pPriv->Video_Shift = 1; break; case 0x44: /* RGB 4:4:4:4 */ - pPPriv->Format = FORMAT_RGB4444; - pPPriv->Video_Shift = 1; + pPriv->Format = FORMAT_RGB4444; + pPriv->Video_Shift = 1; break; case 0x46: /* RGB 2:3:3 */ - pPPriv->Format = FORMAT_RGB332; - pPPriv->Video_Shift = 0; + pPriv->Format = FORMAT_RGB332; + pPriv->Video_Shift = 0; break; case 0x47: /* BGRA 8:8:8:8 */ - pPPriv->Format = FORMAT_BGR8888; - pPPriv->Video_Shift = 2; + pPriv->Format = FORMAT_BGR8888; + pPriv->Video_Shift = 2; break; case 0x48: /* BGR 5:6:5 */ - pPPriv->Format = FORMAT_BGR565; - pPPriv->Video_Shift = 1; + pPriv->Format = FORMAT_BGR565; + pPriv->Video_Shift = 1; break; case 0x49: /* BGR 1:5:5:5 */ - pPPriv->Format = FORMAT_BGR5551; - pPPriv->Video_Shift = 1; + pPriv->Format = FORMAT_BGR5551; + pPriv->Video_Shift = 1; break; case 0x4A: /* BGR 4:4:4:4 */ - pPPriv->Format = FORMAT_BGR4444; - pPPriv->Video_Shift = 1; + pPriv->Format = FORMAT_BGR4444; + pPriv->Video_Shift = 1; break; case 0x4C: /* BGR 2:3:3 */ - pPPriv->Format = FORMAT_BGR332; - pPPriv->Video_Shift = 0; + pPriv->Format = FORMAT_BGR332; + pPriv->Video_Shift = 0; break; - default: + default: return XvBadAlloc; } - /* Now we allocate a buffer, if it is needed */ - w_bpp = (width << pPPriv->Video_Shift) >> pPPriv->FB_Shift; - if ((copy = AllocateBuffers(pPPriv, w_bpp, height)) == -1) - return XvBadAlloc; - - /* Let's copy the image to the framebuffer */ -#if USE_HARDWARE_COPY - /* Erm, ... removing this log message will make the server crash. */ - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Hardware image upload.\n")); - HWCopySetup(pPPriv, pPPriv->Buffer[copy]->box.x1, - pPPriv->Buffer[copy]->box.y1, w_bpp, height); - if (copy_flat) HWCopyFlat(pPPriv, buf, width, height); - else HWCopyYV12(pPPriv, buf, width, height); -#else - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Software image upload (1).\n")); - pPPriv->Sync(pScrn); - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Software image upload (2).\n")); - if (copy_flat) CopyFlat(buf, - (CARD8 *) pGlint->FbBase + pPPriv->BufferBase[copy], - width << pPPriv->FB_Shift, height, - pScrn->displayWidth << pPPriv->FB_Shift); - else CopyYV12(buf, - (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[copy]), - width, height, pScrn->displayWidth << pPPriv->FB_Shift); - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Software image upload (3).\n")); - pPPriv->Sync(pScrn); - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "Software image upload (4).\n")); -#endif + /* Clip */ + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; -#if SUPPORT_CLIPPING - /* Clipping*/ - Clip (pPPriv, clipBoxes); -#endif + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; - /* We start the overlay */ - BeginOverlay(pPPriv, copy); + if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, + width, height)) + return Success; - /* We sync the chip again (if needed). */ - if (sync) pPPriv->Sync(pScrn); + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; - return Success; -} - -static void -Permedia3StopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup) -{ - PortPrivPtr pPPriv = (PortPrivPtr) data; + bpp = pScrn->bitsPerPixel >> 3; + pitch = bpp * pScrn->displayWidth; - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "StopVideo : exit=%d\n", cleanup)); + w_bpp = (width << pPriv->Video_Shift) >> (pScrn->bitsPerPixel >> 4); - REGION_EMPTY(pScrn->pScreen, &pPPriv->clip); - StopOverlay(pPPriv, cleanup); + for (i = 0; i < (pPriv->doubleBuffer ? 2 : 1); i++) { + if (!(pPriv->area[i] = + Permedia3AllocateMemory(pScrn,pPriv->area[i],w_bpp,src_h))) + return BadAlloc; - if (cleanup) { - FreeBuffers(pPPriv, FALSE); + pPriv->offset[i] = (pPriv->area[i]->box.x1 * bpp) + + (pPriv->area[i]->box.y1 * pitch); } -} - -static int -Permedia3SetPortAttribute(ScrnInfoPtr pScrn, - Atom attribute, INT32 value, pointer data) -{ - PortPrivPtr pPPriv = (PortPrivPtr) data; - if (attribute == xvFilter) { - switch (value) { - case 0: /* No Filtering */ - pPPriv->OverlayMode = - (pPPriv->OverlayMode & - ~PM3VideoOverlayMode_FILTER_MASK) | - PM3VideoOverlayMode_FILTER_OFF; - break; - case 1: /* Partial Filtering (X axis only) */ - pPPriv->OverlayMode = - (pPPriv->OverlayMode & - ~PM3VideoOverlayMode_FILTER_MASK) | - PM3VideoOverlayMode_FILTER_PARTIAL; - break; - case 2: /* Full Bilinear Filtering */ - /* We have to disable X mirroring also */ - pPPriv->OverlayMode = - (pPPriv->OverlayMode & - ~(PM3VideoOverlayMode_FILTER_MASK | - PM3VideoOverlayMode_MIRRORX_ON)) | - PM3VideoOverlayMode_FILTER_FULL; - pPPriv->Attribute[1] &= 2; - break; - default: - return BadValue; - } - pPPriv->Attribute[0] = value; - } - else if (attribute == xvMirror) { - switch (value) { - case 0: /* No Mirroring */ - pPPriv->OverlayMode = - (pPPriv->OverlayMode & - ~PM3VideoOverlayMode_MIRROR_MASK) | - PM3VideoOverlayMode_MIRRORX_OFF | - PM3VideoOverlayMode_MIRRORY_OFF; - break; - case 1: /* X Axis Mirroring */ - /* If full filtering was enabled, rever to partial. */ - if (pPPriv->Attribute[0] == 2) { - pPPriv->OverlayMode = - (pPPriv->OverlayMode & - ~(PM3VideoOverlayMode_MIRROR_MASK | - PM3VideoOverlayMode_FILTER_MASK)) | - PM3VideoOverlayMode_MIRRORX_ON | - PM3VideoOverlayMode_MIRRORY_OFF | - PM3VideoOverlayMode_FILTER_PARTIAL; - pPPriv->Attribute[0] = 1; - } else { - pPPriv->OverlayMode = - (pPPriv->OverlayMode & - ~PM3VideoOverlayMode_MIRROR_MASK) | - PM3VideoOverlayMode_MIRRORX_ON | - PM3VideoOverlayMode_MIRRORY_OFF; - } - break; - case 2: /* Y Axis Mirroring */ - pPPriv->OverlayMode = - (pPPriv->OverlayMode & - ~PM3VideoOverlayMode_MIRROR_MASK) | - PM3VideoOverlayMode_MIRRORX_OFF | - PM3VideoOverlayMode_MIRRORY_ON; - break; - case 3: /* X and Y Axis Mirroring */ - /* If full filtering was enabled, rever to partial. */ - if (pPPriv->Attribute[0] == 2) { - pPPriv->OverlayMode = - (pPPriv->OverlayMode & - ~(PM3VideoOverlayMode_MIRROR_MASK | - PM3VideoOverlayMode_FILTER_MASK)) | - PM3VideoOverlayMode_MIRRORX_ON | - PM3VideoOverlayMode_MIRRORY_ON | - PM3VideoOverlayMode_FILTER_PARTIAL; - pPPriv->Attribute[0] = 1; - } else { - pPPriv->OverlayMode = - (pPPriv->OverlayMode & - ~PM3VideoOverlayMode_MIRROR_MASK) | - PM3VideoOverlayMode_MIRRORX_ON | - PM3VideoOverlayMode_MIRRORY_ON; - } - break; - default: - return BadValue; - } - pPPriv->Attribute[1] = value; - } - else if (attribute == xvAlpha) { - if (value >= 0 && value <= 3) { - pPPriv->OverlayAlpha = value << 6; - } else return BadValue; - pPPriv->Attribute[2] = value; + HWCopySetup(pScrn, pPriv->area[pPriv->buffer]->box.x1, + pPriv->area[pPriv->buffer]->box.y1, w_bpp, src_h); + + if (copy_flat) + HWCopyFlat(pScrn, buf, src_w, src_h); + else + HWCopyYV12(pScrn, buf, src_w, src_h); + + /* paint the color key */ + if(pPriv->autopaintColorKey && !RegionsEqual(&pPriv->clip, clipBoxes)) { + /* update cliplist */ + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); +#if 0 + GLINT_WAIT(1); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, + PM3VideoOverlayMode); + pPriv->ramdacOn = FALSE; +#endif + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); } - else return BadMatch; - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "SPA attr=%d val=%d\n", - attribute, value)); - - return Success; -} + Permedia3Sync(pScrn); -static int -Permedia3GetPortAttribute(ScrnInfoPtr pScrn, - Atom attribute, INT32 *value, pointer data) -{ - PortPrivPtr pPPriv = (PortPrivPtr) data; + Permedia3DisplayVideo(pScrn, id, pPriv->offset[pPriv->buffer], width,height, + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); - if (attribute == xvFilter) - *value = pPPriv->Attribute[0]; - else if (attribute == xvMirror) - *value = pPPriv->Attribute[1]; - else if (attribute == xvAlpha) - *value = pPPriv->Attribute[2]; - else return BadMatch; + /* Switch buffer on next run - double buffer */ + if (pPriv->doubleBuffer) { + if (!pPriv->buffer) + pPriv->buffer = 1; + else + pPriv->buffer = 0; + } - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "GPA attr=%d val=%d\n", - attribute, *value)); + pPriv->videoStatus = CLIENT_VIDEO_ON; return Success; } -static void -Permedia3QueryBestSize(ScrnInfoPtr pScrn, Bool motion, - short vid_w, short vid_h, short drw_w, short drw_h, - unsigned int *p_w, unsigned int *p_h, pointer data) -{ - unsigned int zoom_delta, shrink_delta, src_w; +static int +Permedia3QueryImageAttributes( + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +){ + int size, tmp; + + if(*w > 2047) *w = 2047; + if(*h > 2047) *h = 2047; + + *w = (*w + 1) & ~1; + if(offsets) offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: /* YV12 */ + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if(pitches) pitches[0] = size; + size *= *h; + if(offsets) offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if(pitches) pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) offsets[2] = size; + size += tmp; + break; + default: /* RGB15, RGB16, YUY2 */ + size = *w << 1; + if(pitches) pitches[0] = size; + size *= *h; + break; + } - *p_w = drw_w; - compute_scale_factor (&src_w, p_w, &shrink_delta, &zoom_delta); - *p_h = drw_h; + return size; } -static int -Permedia3QueryImageAttributes(ScrnInfoPtr pScrn, - int id, unsigned short *width, unsigned short *height, - int *pitches, int *offsets) -{ - int i, pitch; - - *width = CLAMP(*width, 1, 2047); - *height = CLAMP(*height, 1, 2047); - - if (offsets) - offsets[0] = 0; - - switch (id) { - case LE4CC('Y','V','1','2'): /* Planar YVU 4:2:0 (emulated) */ - *width = CLAMP((*width + 1) & ~1, 2, 2046); - *height = CLAMP((*height + 1) & ~1, 2, 2046); - - pitch = *width; /* luma component */ - - if (offsets) { - offsets[1] = pitch * *height; - offsets[2] = offsets[1] + (offsets[1] >> 2); - } - - if (pitches) { - pitches[0] = pitch; - pitches[1] = pitches[2] = pitch >> 1; - } - - return pitch * *height * 3 / 2; - - case LE4CC('Y','U','Y','2'): /* Packed YUYV 4:2:2 */ - case LE4CC('U','Y','V','Y'): /* Packed UYVY 4:2:2 */ - *width = CLAMP((*width + 1) & ~1, 2, 2046); - - pitch = *width * 2; +/****************** Offscreen stuff ***************/ + +typedef struct { + FBAreaPtr area; + Bool isOn; + int Video_Shift; + int Format; + Bool ramdacOn; +} OffscreenPrivRec, * OffscreenPrivPtr; + +static int +Permedia3AllocateSurface( + ScrnInfoPtr pScrn, + int id, + unsigned short w, + unsigned short h, + XF86SurfacePtr surface +){ + FBAreaPtr area; + int fbpitch, bpp; + OffscreenPrivPtr pPriv; + + if((w > 2047) || (h > 2047)) + return BadAlloc; + + w = (w + 1) & ~1; + bpp = pScrn->bitsPerPixel >> 3; + fbpitch = bpp * pScrn->displayWidth; + + if(!(area = Permedia3AllocateMemory(pScrn, NULL, w, h))) + return BadAlloc; + + surface->width = w; + surface->height = h; + + if(!(surface->offsets = xalloc(sizeof(int)))) { + xf86FreeOffscreenArea(area); + return BadAlloc; + } + if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { + xfree(surface->offsets); + xf86FreeOffscreenArea(area); + return BadAlloc; + } - if (pitches) - pitches[0] = pitch; + pPriv->area = area; + pPriv->isOn = FALSE; - return pitch * *height; + surface->pScrn = pScrn; + surface->id = id; + surface->offsets[0] = (area->box.x1 * bpp) + (area->box.y1 * fbpitch); + surface->devPrivate.ptr = (pointer)pPriv; - default: - for (i = 0; i < ENTRIES(ScalerImages); i++) - if (ScalerImages[i].id == id) - break; + return Success; +} - if (i >= ENTRIES(ScalerImages)) - break; +static int +Permedia3StopSurface( + XF86SurfacePtr surface +){ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; + + if(pPriv->isOn) { + GLINTPtr pGlint = GLINTPTR(surface->pScrn); + pPriv->ramdacOn = FALSE; + GLINT_WAIT(4); + RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, + PM3RD_VideoOverlayControl); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, + PM3VideoOverlayMode); + pPriv->isOn = FALSE; + } - pitch = *width * (ScalerImages[i].bits_per_pixel >> 3); + return Success; +} - if (pitches) - pitches[0] = pitch; +static int +Permedia3FreeSurface( + XF86SurfacePtr surface +){ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; - return pitch * *height; - } + if(pPriv->isOn) + Permedia3StopSurface(surface); + xf86FreeOffscreenArea(pPriv->area); + xfree(surface->pitches); + xfree(surface->offsets); + xfree(surface->devPrivate.ptr); - return 0; + return Success; } -static void -DeleteAdaptorPriv(AdaptorPrivPtr pAPriv) -{ - FreeBuffers(pAPriv->pPort, FALSE); - - TimerFree(pAPriv->pPort->Timer); +static int +Permedia3GetSurfaceAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value +){ + return Permedia3GetPortAttribute(pScrn, attribute, value, + (pointer)(GET_PORT_PRIVATE(pScrn))); +} - xfree(pAPriv); +static int +Permedia3SetSurfaceAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value +){ + return Permedia3SetPortAttribute(pScrn, attribute, value, + (pointer)(GET_PORT_PRIVATE(pScrn))); } -static AdaptorPrivPtr -NewAdaptorPriv(ScrnInfoPtr pScrn) -{ - AdaptorPrivPtr pAPriv = (AdaptorPrivPtr) xcalloc(1, sizeof(AdaptorPrivRec)); - PortPrivPtr pPPriv = (PortPrivPtr) xcalloc(1, sizeof(PortPrivRec)); +static int +Permedia3DisplaySurface( + XF86SurfacePtr surface, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + RegionPtr clipBoxes +){ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; + ScrnInfoPtr pScrn = surface->pScrn; GLINTPtr pGlint = GLINTPTR(pScrn); - int i; + GLINTPortPrivPtr portPriv = pGlint->adaptor->pPortPrivates[0].ptr; + INT32 x1, y1, x2, y2; + BoxRec dstBox; + + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, + surface->width, surface->height)) + { + return Success; + } - if (!pAPriv) return NULL; - pAPriv->pScrn = pScrn; - if (!pPPriv) return NULL; - pAPriv->pPort = pPPriv; + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; - - /* We allocate a timer */ - if (!(pPPriv->Timer = TimerSet(NULL, 0, 0, TimerCallback, pPPriv))) { - DeleteAdaptorPriv(pAPriv); - return NULL; + /* Let's find the image format and Video_Shift values */ + switch (surface->id) { + case LE4CC('Y','V','1','2'): + pPriv->Format = FORMAT_YUV422; + pPriv->Video_Shift = 1; + break; + case LE4CC('Y','U','Y','2'): + pPriv->Format = FORMAT_YUV422; + pPriv->Video_Shift = 1; + break; + case LE4CC('U','Y','V','Y'): + pPriv->Format = FORMAT_VUY422; + pPriv->Video_Shift = 1; + break; + case LE4CC('Y','U','V','A'): + pPriv->Format = FORMAT_YUV444; + pPriv->Video_Shift = 2; + break; + case LE4CC('V','U','Y','A'): + pPriv->Format = FORMAT_VUY444; + pPriv->Video_Shift = 2; + break; + case 0x41: /* RGBA 8:8:8:8 */ + pPriv->Format = FORMAT_RGB8888; + pPriv->Video_Shift = 2; + break; + case 0x42: /* RGB 5:6:5 */ + pPriv->Format = FORMAT_RGB565; + pPriv->Video_Shift = 1; + break; + case 0x43: /* RGB 1:5:5:5 */ + pPriv->Format = FORMAT_RGB5551; + pPriv->Video_Shift = 1; + break; + case 0x44: /* RGB 4:4:4:4 */ + pPriv->Format = FORMAT_RGB4444; + pPriv->Video_Shift = 1; + break; + case 0x46: /* RGB 2:3:3 */ + pPriv->Format = FORMAT_RGB332; + pPriv->Video_Shift = 0; + break; + case 0x47: /* BGRA 8:8:8:8 */ + pPriv->Format = FORMAT_BGR8888; + pPriv->Video_Shift = 2; + break; + case 0x48: /* BGR 5:6:5 */ + pPriv->Format = FORMAT_BGR565; + pPriv->Video_Shift = 1; + break; + case 0x49: /* BGR 1:5:5:5 */ + pPriv->Format = FORMAT_BGR5551; + pPriv->Video_Shift = 1; + break; + case 0x4A: /* BGR 4:4:4:4 */ + pPriv->Format = FORMAT_BGR4444; + pPriv->Video_Shift = 1; + break; + case 0x4C: /* BGR 2:3:3 */ + pPriv->Format = FORMAT_BGR332; + pPriv->Video_Shift = 0; + break; + default: + return XvBadAlloc; } - pPPriv->pAdaptor = pAPriv; - /* Sync */ - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, - "Sync is using : %sPermedia3Sync.\n", - pGlint->MultiAperture?"Dual":"")); - if (pGlint->MultiAperture) pPPriv->Sync = DualPermedia3Sync; - else pPPriv->Sync = Permedia3Sync; - - /* Framebuffer bpp shift */ - pPPriv->FB_Shift = pScrn->bitsPerPixel >> 4; - - /* Attributes */ - pPPriv->Attribute[0] = 2; /* Full filtering enabled */ - pPPriv->Attribute[1] = 0; /* No mirroring */ - pPPriv->Attribute[2] = 3; /* Opaque overlay mode */ - pPPriv->ColorKey = 0; - pPPriv->OverlayAlpha = - PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT; - pPPriv->OverlayMode = - PM3VideoOverlayMode_FILTER_FULL | - PM3VideoOverlayMode_MIRRORX_OFF | - PM3VideoOverlayMode_MIRRORY_OFF; - - /* Clipping */ - REGION_EMPTY(pScrn->pScreen, &pPPriv->clip); - - /* RAMDAC saved values */ - pPPriv->ramdac_x = 0; - pPPriv->ramdac_w = 0; - pPPriv->ramdac_y = 0; - pPPriv->ramdac_h = 0; - pPPriv->ramdac_on = FALSE; - - /* Buffers */ - pPPriv->Id = ScalerImages[0].id; - pPPriv->copy = -1; - pPPriv->display = -1; - for (i = 0; i < MAX_BUFFERS; i++) - pPPriv->Buffer[i] = NULL; - - /* Timer */ - pPPriv->StopDelay = -1; - pPPriv->Delay = 125; - pPPriv->Instant = 1000 / 25; - - return pAPriv; -} + Permedia3DisplayVideo(pScrn, surface->id, surface->offsets[0], + surface->width, surface->height, + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); -/* - * Glint interface - */ + xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); -void -Permedia3VideoEnterVT(ScrnInfoPtr pScrn) -{ - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv enter VT\n")); -} + pPriv->isOn = TRUE; + /* we've prempted the XvImage stream so set its free timer */ + if(portPriv->videoStatus & CLIENT_VIDEO_ON) { + REGION_EMPTY(pScrn->pScreen, &portPriv->clip); + UpdateCurrentTime(); + portPriv->videoStatus = FREE_TIMER; + portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + pGlint->VideoTimerCallback = Permedia3VideoTimerCallback; + } -void -Permedia3VideoLeaveVT(ScrnInfoPtr pScrn) -{ - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv leave VT\n")); + return Success; } -void -Permedia3VideoUninit(ScrnInfoPtr pScrn) +static void +Permedia3InitOffscreenImages(ScreenPtr pScreen) { - AdaptorPrivPtr pAPriv, *ppAPriv; + XF86OffscreenImagePtr offscreenImages; - for (ppAPriv = &AdaptorPrivList; (pAPriv = *ppAPriv); ppAPriv = &(pAPriv->Next)) - if (pAPriv->pScrn == pScrn) { - *ppAPriv = pAPriv->Next; - DeleteAdaptorPriv(pAPriv); - break; - } + /* need to free this someplace */ + if(!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) + return; - DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv cleanup\n")); + offscreenImages[0].image = &Images[0]; + offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | + VIDEO_CLIP_TO_VIEWPORT; + offscreenImages[0].alloc_surface = Permedia3AllocateSurface; + offscreenImages[0].free_surface = Permedia3FreeSurface; + offscreenImages[0].display = Permedia3DisplaySurface; + offscreenImages[0].stop = Permedia3StopSurface; + offscreenImages[0].setAttribute = Permedia3SetSurfaceAttribute; + offscreenImages[0].getAttribute = Permedia3GetSurfaceAttribute; + offscreenImages[0].max_width = 2047; + offscreenImages[0].max_height = 2047; + offscreenImages[0].num_attributes = NUM_ATTRIBUTES; + offscreenImages[0].attributes = Attributes; + + xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); } -void -Permedia3VideoInit(ScreenPtr pScreen) +static void +Permedia3VideoTimerCallback(ScrnInfoPtr pScrn, Time time) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; GLINTPtr pGlint = GLINTPTR(pScrn); - AdaptorPrivPtr pAPriv; - DevUnion Private[1]; - XF86VideoAdaptorRec VAR; - XF86VideoAdaptorPtr VARPtrs; - - switch (pGlint->Chipset) { - case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, - "Using the Permedia3 chipset.\n"); - break; - case PCI_VENDOR_3DLABS_CHIP_GAMMA: - if (pGlint->MultiChip == PCI_CHIP_PERMEDIA3) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, - "Using the Gamma chipset.\n"); - break; - } - default: - xf86DrvMsgVerb(pScrn->scrnIndex, X_ERROR, 1, - "No Xv support for chipset %d.\n", pGlint->Chipset); - return; - } - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, - "Initializing Permedia3 Xv driver rev. 1\n"); - - if (pGlint->NoAccel) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Xv initialization failed : XAA is needed\n"); - return; - } - - if (!(pAPriv = NewAdaptorPriv(pScrn))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv initialization failed\n"); - return; - } + GLINTPortPrivPtr pPriv = pGlint->adaptor->pPortPrivates[0].ptr; + int i; - memset(&VAR, 0, sizeof(VAR)); - - Private[0].ptr = (pointer) pAPriv->pPort; - - VARPtrs = &VAR; - - VAR.type = XvInputMask | XvWindowMask | XvImageMask; - VAR.flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - VAR.name = "Permedia 3 Frontend Scaler"; - VAR.nEncodings = ENTRIES(ScalerEncodings); - VAR.pEncodings = ScalerEncodings; - VAR.nFormats = ENTRIES(ScalerVideoFormats); - VAR.pFormats = ScalerVideoFormats; - VAR.nPorts = 1; - VAR.pPortPrivates = &Private[0]; - VAR.nAttributes = ENTRIES(ScalerAttributes); - VAR.pAttributes = ScalerAttributes; - VAR.nImages = ENTRIES(ScalerImages); - VAR.pImages = ScalerImages; - - VAR.PutVideo = NULL; - VAR.PutStill = NULL; - VAR.GetVideo = NULL; - VAR.GetStill = NULL; - VAR.StopVideo = Permedia3StopVideo; - VAR.SetPortAttribute = Permedia3SetPortAttribute; - VAR.GetPortAttribute = Permedia3GetPortAttribute; - VAR.QueryBestSize = Permedia3QueryBestSize; - VAR.PutImage = Permedia3PutImage; - VAR.ReputImage = Permedia3ReputImage; - VAR.QueryImageAttributes = Permedia3QueryImageAttributes; - - if (xf86XVScreenInit(pScreen, &VARPtrs, 1)) { - xvFilter = MAKE_ATOM(XV_FILTER); - xvMirror = MAKE_ATOM(XV_MIRROR); - xvAlpha = MAKE_ATOM(XV_ALPHA); - -#if USE_HARDWARE_COPY - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Xv frontend scaler enabled (HW)\n"); -#else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Xv frontend scaler enabled (SW)\n"); -#endif - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv initialization failed\n"); - DeleteAdaptorPriv(pAPriv); - } + if(pPriv->videoStatus & TIMER_MASK) { + if(pPriv->videoStatus & OFF_TIMER) { + if(pPriv->offTime < time) { + pPriv->ramdacOn = FALSE; + GLINT_WAIT(4); + RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, + PM3RD_VideoOverlayControl); + GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, + PM3VideoOverlayMode); + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = time + FREE_DELAY; + } + } else { /* FREE_TIMER */ + if(pPriv->freeTime < time) { + for (i = 0; i < (pPriv->doubleBuffer ? 2 : 1); i++) { + if(pPriv->area[i]) { + xf86FreeOffscreenArea(pPriv->area[i]); + pPriv->area[i] = NULL; + } + } + pPriv->videoStatus = 0; + pGlint->VideoTimerCallback = NULL; + } + } + } else /* shouldn't get here */ + pGlint->VideoTimerCallback = NULL; } -#endif /* XvExtension */ +#endif /* !XvExtension */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c index 271754097..9e30ec395 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c @@ -28,7 +28,7 @@ * * GLINT 500TX / MX accelerated options. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c,v 1.26.2.2 2001/05/30 10:08:19 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c,v 1.28 2001/05/30 10:07:56 alanh Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" |