cir_dga.c revision 1ae1b5e8
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c,v 1.5 2001/02/15 17:39:27 eich Exp $ */ 2/* 3 * Copyright 2000 by Egbert Eich 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 * EGBERT EICH 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: Egbert Eich 25 */ 26 27#ifdef HAVE_CONFIG_H 28#include "config.h" 29#endif 30 31#include "xf86.h" 32#include "xf86_OSproc.h" 33#include "xf86Pci.h" 34#include "xf86PciInfo.h" 35#include "xaa.h" 36#include "xaalocal.h" 37#include "vgaHW.h" 38#include "cir.h" 39#include "dgaproc.h" 40 41static Bool Cir_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 42 int *, int *, int *); 43static Bool Cir_SetMode(ScrnInfoPtr, DGAModePtr); 44static void Cir_Sync(ScrnInfoPtr); 45static int Cir_GetViewport(ScrnInfoPtr); 46static void Cir_SetViewport(ScrnInfoPtr, int, int, int); 47static void Cir_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 48static void Cir_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 49/* 50static void Cir_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 51 unsigned long); 52*/ 53 54static 55DGAFunctionRec CirDGAFuncs = { 56 Cir_OpenFramebuffer, 57 NULL, /* Cir_CloseFramebuffer */ 58 Cir_SetMode, 59 Cir_SetViewport, 60 Cir_GetViewport, 61 Cir_Sync, 62 Cir_FillRect, 63 Cir_BlitRect, 64 NULL /* Cir_BlitTransRect */ 65}; 66 67 68 69 70_X_EXPORT Bool 71CirDGAInit(ScreenPtr pScreen) 72{ 73 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 74 CirPtr pCir = CIRPTR(pScrn); 75 DGAModePtr modes = NULL, newmodes = NULL, currentMode; 76 DisplayModePtr pMode, firstMode; 77 int Bpp = pScrn->bitsPerPixel >> 3; 78 int num = 0; 79 int imlines = (pScrn->videoRam * 1024) / 80 (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 81 82 83 if (!pCir->DGAnumModes) { 84 pMode = firstMode = pScrn->modes; 85 while (pMode) { 86 newmodes = xrealloc(modes, (num + 1) * sizeof (DGAModeRec)); 87 if (!newmodes) { 88 xfree(modes); 89 return FALSE; 90 } 91 modes = newmodes; 92 currentMode = modes + num; 93 num++; 94 (void)memset(currentMode, 1, sizeof(DGAModeRec)); 95 currentMode->mode = pMode; 96 currentMode->flags = DGA_PIXMAP_AVAILABLE 97 | ((!pCir->NoAccel) ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0); 98 if (pMode->Flags & V_DBLSCAN) 99 currentMode->flags |= DGA_DOUBLESCAN; 100 if(pMode->Flags & V_INTERLACE) 101 currentMode->flags |= DGA_INTERLACED; 102 currentMode->byteOrder = pScrn->imageByteOrder; 103 currentMode->depth = pScrn->depth; 104 currentMode->bitsPerPixel = pScrn->bitsPerPixel; 105 currentMode->red_mask = pScrn->mask.red; 106 currentMode->green_mask = pScrn->mask.green; 107 currentMode->blue_mask = pScrn->mask.blue; 108 currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 109 currentMode->viewportWidth = pMode->HDisplay; 110 currentMode->viewportHeight = pMode->VDisplay; 111 currentMode->xViewportStep = 1; /* The granularity of x and y pos. */ 112 currentMode->yViewportStep = 1; 113 currentMode->viewportFlags = 0 /*DGA_FLIP_RETRACE*/; 114 currentMode->offset = 0; 115 currentMode->address = pCir->FbBase; 116 currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; 117 currentMode->pixmapWidth = currentMode->imageWidth 118 = pScrn->displayWidth; 119 currentMode->pixmapHeight = currentMode->imageHeight = imlines; 120 currentMode->maxViewportX = currentMode->imageWidth - 121 currentMode->viewportWidth; 122 /* this might need to get clamped to some maximum */ 123 currentMode->maxViewportY = currentMode->imageHeight - 124 currentMode->viewportHeight; 125 126 pMode = pMode->next; 127 if(pMode == firstMode) 128 break; 129 } 130 pCir->DGAnumModes = num; 131 pCir->DGAModes = modes; 132 } 133 return DGAInit(pScreen, &CirDGAFuncs, pCir->DGAModes, pCir->DGAnumModes); 134} 135 136static Bool 137Cir_OpenFramebuffer( 138 ScrnInfoPtr pScrn, 139 char **name, 140 unsigned char **mem, 141 int *size, 142 int *offset, 143 int *flags 144){ 145 CirPtr pCir = CIRPTR(pScrn); 146 147 *name = NULL; /* no special device */ 148 *mem = (unsigned char*)(long)pCir->FbAddress; 149 *size = pCir->FbMapSize; 150 *offset = 0; /* Always */ 151 *flags = 0; /* Root permissions OS-dependent */ 152 153 return TRUE; 154} 155 156 157static Bool 158Cir_SetMode( 159 ScrnInfoPtr pScrn, 160 DGAModePtr pMode 161){ 162 CirPtr pCir = CIRPTR(pScrn); 163 static int OldDisplayWidth[MAXSCREENS]; 164 int index = pScrn->pScreen->myNum; 165 Bool ret = FALSE; 166 167 if(!pMode) { /* restore the original mode */ 168 /* put the ScreenParameters back */ 169 pScrn->displayWidth = OldDisplayWidth[index]; 170 ret = pCir->DGAModeInit(xf86Screens[index], pScrn->currentMode); 171 pCir->DGAactive = FALSE; 172 } else { 173 if(!pCir->DGAactive) { /* save the old parameters */ 174 OldDisplayWidth[index] = pScrn->displayWidth; 175 176 pCir->DGAactive = TRUE; 177 } 178 pScrn->displayWidth = pMode->bytesPerScanline / 179 (pMode->bitsPerPixel >> 3); 180 181 ret = pCir->DGAModeInit(xf86Screens[index], pMode->mode); 182 } 183 return ret; 184} 185 186static void 187Cir_SetViewport( 188 ScrnInfoPtr pScrn, 189 int x, int y, 190 int flags 191){ 192 CirPtr pCir = CIRPTR(pScrn); 193 vgaHWPtr hwp = VGAHWPTR(pScrn); 194 195 pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags); 196 197 while((hwp->readST01(hwp) & 0x08)); 198 while(!(hwp->readST01(hwp) & 0x08)); 199 200 pCir->DGAViewportStatus = 0; /* AdjustFrame loops until finished */ 201} 202 203static int 204Cir_GetViewport( 205 ScrnInfoPtr pScrn 206){ 207 CirPtr pCir = CIRPTR(pScrn); 208 209 return pCir->DGAViewportStatus; 210} 211 212 213 214static void 215Cir_Sync( 216 ScrnInfoPtr pScrn 217){ 218 CirPtr pCir = CIRPTR(pScrn); 219 220 if(pCir->AccelInfoRec) { 221 (*pCir->AccelInfoRec->Sync)(pScrn); 222 } 223} 224 225static void 226Cir_FillRect ( 227 ScrnInfoPtr pScrn, 228 int x, int y, int w, int h, 229 unsigned long color 230){ 231 CirPtr pCir = CIRPTR(pScrn); 232 233 if(pCir->AccelInfoRec) { 234 (*pCir->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 235 (*pCir->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 236 SET_SYNC_FLAG(pCir->AccelInfoRec); 237 } 238} 239 240static void 241Cir_BlitRect( 242 ScrnInfoPtr pScrn, 243 int srcx, int srcy, 244 int w, int h, 245 int dstx, int dsty 246){ 247 CirPtr pCir = CIRPTR(pScrn); 248 249 if(pCir->AccelInfoRec) { 250 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 251 int ydir = (srcy < dsty) ? -1 : 1; 252 253 (*pCir->AccelInfoRec->SetupForScreenToScreenCopy)( 254 pScrn, xdir, ydir, GXcopy, ~0, -1); 255 (*pCir->AccelInfoRec->SubsequentScreenToScreenCopy)( 256 pScrn, srcx, srcy, dstx, dsty, w, h); 257 SET_SYNC_FLAG(pCir->AccelInfoRec); 258 } 259} 260