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