tseng_dga.c revision d983712d
1d983712dSmrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_dga.c,v 1.1 2000/12/06 15:35:24 eich Exp $ */ 2d983712dSmrg/* 3d983712dSmrg * Copyright 2000 by Rainer Keller, <Rainer.Keller@studmail.uni-stuttgart.de>. 4d983712dSmrg * 5d983712dSmrg * Permission to use, copy, modify, distribute, and sell this software and its 6d983712dSmrg * documentation for any purpose is hereby granted without fee, provided that 7d983712dSmrg * the above copyright notice appear in all copies and that both that 8d983712dSmrg * copyright notice and this permission notice appear in supporting 9d983712dSmrg * documentation, and that the name of Alan Hourihane not be used in 10d983712dSmrg * advertising or publicity pertaining to distribution of the software without 11d983712dSmrg * specific, written prior permission. Alan Hourihane makes no representations 12d983712dSmrg * about the suitability of this software for any purpose. It is provided 13d983712dSmrg * "as is" without express or implied warranty. 14d983712dSmrg * 15d983712dSmrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16d983712dSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17d983712dSmrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18d983712dSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19d983712dSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20d983712dSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21d983712dSmrg * PERFORMANCE OF THIS SOFTWARE. 22d983712dSmrg * 23d983712dSmrg * Authors: Adapted from: Alan Hourihane, <alanh@fairlite.demon.co.uk> 24d983712dSmrg * by: Rainer Keller, <Rainer.Keller@studmail.uni-stuttgart.de> 25d983712dSmrg */ 26d983712dSmrg 27d983712dSmrg#ifdef HAVE_CONFIG_H 28d983712dSmrg#include "config.h" 29d983712dSmrg#endif 30d983712dSmrg 31d983712dSmrg#include "tseng.h" 32d983712dSmrg#include "dgaproc.h" 33d983712dSmrg 34d983712dSmrgstatic Bool Tseng_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 35d983712dSmrg int *, int *, int *); 36d983712dSmrgstatic Bool Tseng_SetMode(ScrnInfoPtr, DGAModePtr); 37d983712dSmrgstatic void Tseng_Sync(ScrnInfoPtr); 38d983712dSmrgstatic int Tseng_GetViewport(ScrnInfoPtr); 39d983712dSmrgstatic void Tseng_SetViewport(ScrnInfoPtr, int, int, int); 40d983712dSmrgstatic void Tseng_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 41d983712dSmrgstatic void Tseng_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 42d983712dSmrg/* 43d983712dSmrgstatic void Tseng_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 44d983712dSmrg unsigned long); 45d983712dSmrg*/ 46d983712dSmrg 47d983712dSmrgstatic 48d983712dSmrgDGAFunctionRec TsengDGAFuncs = { 49d983712dSmrg Tseng_OpenFramebuffer, 50d983712dSmrg NULL, /* Tseng_CloseFramebuffer */ 51d983712dSmrg Tseng_SetMode, 52d983712dSmrg Tseng_SetViewport, 53d983712dSmrg Tseng_GetViewport, 54d983712dSmrg Tseng_Sync, 55d983712dSmrg Tseng_FillRect, 56d983712dSmrg Tseng_BlitRect, 57d983712dSmrg NULL /* Tseng_BlitTransRect */ 58d983712dSmrg}; 59d983712dSmrg 60d983712dSmrg 61d983712dSmrg 62d983712dSmrg 63d983712dSmrgBool 64d983712dSmrgTsengDGAInit(ScreenPtr pScreen) 65d983712dSmrg{ 66d983712dSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 67d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 68d983712dSmrg DGAModePtr modes = NULL, newmodes = NULL, currentMode; 69d983712dSmrg DisplayModePtr pMode, firstMode; 70d983712dSmrg int Bpp = pScrn->bitsPerPixel >> 3; 71d983712dSmrg int num = 0; 72d983712dSmrg int imlines = (pScrn->videoRam * 1024) / 73d983712dSmrg (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 74d983712dSmrg 75d983712dSmrg if (!pTseng->DGAnumModes) { 76d983712dSmrg pMode = firstMode = pScrn->modes; 77d983712dSmrg while (pMode) { 78d983712dSmrg newmodes = xrealloc(modes, (num + 1) * sizeof (DGAModeRec)); 79d983712dSmrg if (!newmodes) { 80d983712dSmrg xfree(modes); 81d983712dSmrg return FALSE; 82d983712dSmrg } 83d983712dSmrg modes = newmodes; 84d983712dSmrg currentMode = modes + num; 85d983712dSmrg num++; 86d983712dSmrg (void)memset(currentMode, 1, sizeof(DGAModeRec)); 87d983712dSmrg currentMode->mode = pMode; 88d983712dSmrg currentMode->flags = DGA_PIXMAP_AVAILABLE 89d983712dSmrg | ((pTseng->UseAccel) ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0); 90d983712dSmrg if (pMode->Flags & V_DBLSCAN) 91d983712dSmrg currentMode->flags |= DGA_DOUBLESCAN; 92d983712dSmrg if(pMode->Flags & V_INTERLACE) 93d983712dSmrg currentMode->flags |= DGA_INTERLACED; 94d983712dSmrg currentMode->byteOrder = pScrn->imageByteOrder; 95d983712dSmrg currentMode->depth = pScrn->depth; 96d983712dSmrg currentMode->bitsPerPixel = pScrn->bitsPerPixel; 97d983712dSmrg currentMode->red_mask = pScrn->mask.red; 98d983712dSmrg currentMode->green_mask = pScrn->mask.green; 99d983712dSmrg currentMode->blue_mask = pScrn->mask.blue; 100d983712dSmrg currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 101d983712dSmrg currentMode->viewportWidth = pMode->HDisplay; 102d983712dSmrg currentMode->viewportHeight = pMode->VDisplay; 103d983712dSmrg currentMode->xViewportStep = 1; /* The granularity of x and y pos. */ 104d983712dSmrg currentMode->yViewportStep = 1; 105d983712dSmrg currentMode->viewportFlags = 0 /*DGA_FLIP_RETRACE*/; 106d983712dSmrg currentMode->offset = 0; 107d983712dSmrg currentMode->address = pTseng->FbBase; 108d983712dSmrg currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; 109d983712dSmrg currentMode->pixmapWidth = currentMode->imageWidth = pScrn->displayWidth; 110d983712dSmrg currentMode->pixmapHeight = currentMode->imageHeight = imlines; 111d983712dSmrg currentMode->maxViewportX = currentMode->imageWidth - 112d983712dSmrg currentMode->viewportWidth; 113d983712dSmrg /* this might need to get clamped to some maximum */ 114d983712dSmrg currentMode->maxViewportY = currentMode->imageHeight - 115d983712dSmrg currentMode->viewportHeight; 116d983712dSmrg 117d983712dSmrg pMode = pMode->next; 118d983712dSmrg if(pMode == firstMode) 119d983712dSmrg break; 120d983712dSmrg } 121d983712dSmrg pTseng->DGAnumModes = num; 122d983712dSmrg pTseng->DGAModes = modes; 123d983712dSmrg } 124d983712dSmrg return DGAInit(pScreen, &TsengDGAFuncs, pTseng->DGAModes, pTseng->DGAnumModes); 125d983712dSmrg} 126d983712dSmrg 127d983712dSmrgstatic Bool 128d983712dSmrgTseng_OpenFramebuffer( 129d983712dSmrg ScrnInfoPtr pScrn, 130d983712dSmrg char **name, 131d983712dSmrg unsigned char **mem, 132d983712dSmrg int *size, 133d983712dSmrg int *offset, 134d983712dSmrg int *flags 135d983712dSmrg){ 136d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 137d983712dSmrg 138d983712dSmrg *name = NULL; /* no special device */ 139d983712dSmrg *mem = (unsigned char*)pTseng->FbAddress; 140d983712dSmrg *size = pTseng->FbMapSize; 141d983712dSmrg *offset = 0; /* Always */ 142d983712dSmrg *flags = 0; /* Root permissions OS-dependent */ 143d983712dSmrg 144d983712dSmrg return TRUE; 145d983712dSmrg} 146d983712dSmrg 147d983712dSmrg 148d983712dSmrgstatic Bool 149d983712dSmrgTseng_SetMode( 150d983712dSmrg ScrnInfoPtr pScrn, 151d983712dSmrg DGAModePtr pMode 152d983712dSmrg){ 153d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 154d983712dSmrg static int OldDisplayWidth[MAXSCREENS]; 155d983712dSmrg int index = pScrn->pScreen->myNum; 156d983712dSmrg Bool ret; 157d983712dSmrg 158d983712dSmrg if(!pMode) { /* restore the original mode */ 159d983712dSmrg /* put the ScreenParameters back */ 160d983712dSmrg pScrn->displayWidth = OldDisplayWidth[index]; 161d983712dSmrg ret = TsengModeInit(xf86Screens[index], pScrn->currentMode); 162d983712dSmrg pTseng->DGAactive = FALSE; 163d983712dSmrg } else { 164d983712dSmrg if(!pTseng->DGAactive) { /* save the old parameters */ 165d983712dSmrg OldDisplayWidth[index] = pScrn->displayWidth; 166d983712dSmrg 167d983712dSmrg pTseng->DGAactive = TRUE; 168d983712dSmrg } 169d983712dSmrg pScrn->displayWidth = pMode->bytesPerScanline / 170d983712dSmrg (pMode->bitsPerPixel >> 3); 171d983712dSmrg 172d983712dSmrg ret = TsengModeInit(xf86Screens[index], pMode->mode); 173d983712dSmrg } 174d983712dSmrg return ret; 175d983712dSmrg} 176d983712dSmrg 177d983712dSmrgstatic void 178d983712dSmrgTseng_SetViewport( 179d983712dSmrg ScrnInfoPtr pScrn, 180d983712dSmrg int x, int y, 181d983712dSmrg int flags 182d983712dSmrg){ 183d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 184d983712dSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 185d983712dSmrg 186d983712dSmrg TsengAdjustFrame(pScrn->pScreen->myNum, x, y, flags); 187d983712dSmrg while((hwp->readST01(hwp) & 0x08)); 188d983712dSmrg while(!(hwp->readST01(hwp) & 0x08)); 189d983712dSmrg 190d983712dSmrg pTseng->DGAViewportStatus = 0; /* TsengAdjustFrame loops until finished */ 191d983712dSmrg} 192d983712dSmrg 193d983712dSmrgstatic int 194d983712dSmrgTseng_GetViewport( 195d983712dSmrg ScrnInfoPtr pScrn 196d983712dSmrg){ 197d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 198d983712dSmrg 199d983712dSmrg return pTseng->DGAViewportStatus; 200d983712dSmrg} 201d983712dSmrg 202d983712dSmrg 203d983712dSmrg 204d983712dSmrgstatic void 205d983712dSmrgTseng_Sync( 206d983712dSmrg ScrnInfoPtr pScrn 207d983712dSmrg){ 208d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 209d983712dSmrg 210d983712dSmrg if(pTseng->AccelInfoRec) { 211d983712dSmrg (*pTseng->AccelInfoRec->Sync)(pScrn); 212d983712dSmrg } 213d983712dSmrg} 214d983712dSmrg 215d983712dSmrgstatic void 216d983712dSmrgTseng_FillRect ( 217d983712dSmrg ScrnInfoPtr pScrn, 218d983712dSmrg int x, int y, int w, int h, 219d983712dSmrg unsigned long color 220d983712dSmrg){ 221d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 222d983712dSmrg 223d983712dSmrg if(pTseng->AccelInfoRec) { 224d983712dSmrg (*pTseng->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 225d983712dSmrg (*pTseng->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 226d983712dSmrg SET_SYNC_FLAG(pTseng->AccelInfoRec); 227d983712dSmrg } 228d983712dSmrg} 229d983712dSmrg 230d983712dSmrgstatic void 231d983712dSmrgTseng_BlitRect( 232d983712dSmrg ScrnInfoPtr pScrn, 233d983712dSmrg int srcx, int srcy, 234d983712dSmrg int w, int h, 235d983712dSmrg int dstx, int dsty 236d983712dSmrg){ 237d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 238d983712dSmrg 239d983712dSmrg if(pTseng->AccelInfoRec) { 240d983712dSmrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 241d983712dSmrg int ydir = (srcy < dsty) ? -1 : 1; 242d983712dSmrg 243d983712dSmrg (*pTseng->AccelInfoRec->SetupForScreenToScreenCopy)( 244d983712dSmrg pScrn, xdir, ydir, GXcopy, ~0, -1); 245d983712dSmrg (*pTseng->AccelInfoRec->SubsequentScreenToScreenCopy)( 246d983712dSmrg pScrn, srcx, srcy, dstx, dsty, w, h); 247d983712dSmrg SET_SYNC_FLAG(pTseng->AccelInfoRec); 248d983712dSmrg } 249d983712dSmrg} 250