savage_dga.c revision ab47cfaa
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c,v 1.6 2003/01/18 15:22:29 eich Exp $ */ 2 3/* 4Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 5 6Permission is hereby granted, free of charge, to any person obtaining a copy of 7this software and associated documentation files (the "Software"), to deal in 8the Software without restriction, including without limitation the rights to 9use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 10of the Software, and to permit persons to whom the Software is furnished to do 11so, subject to the following conditions: 12 13The above copyright notice and this permission notice shall be included in all 14copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 18NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23Except as contained in this notice, the name of the XFree86 Project shall not 24be used in advertising or otherwise to promote the sale, use or other dealings 25in this Software without prior written authorization from the XFree86 Project. 26*/ 27 28#ifdef HAVE_CONFIG_H 29#include "config.h" 30#endif 31 32/* 33 * file: savage_dga.c 34 * ported from s3v, which was ported from mga 35 * 36 */ 37 38 39#include "xaalocal.h" 40#include "savage_driver.h" 41#include "dgaproc.h" 42 43 44Bool SavageDGAInit(ScreenPtr pScreen); 45static Bool Savage_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 46 int *, int *, int *); 47static Bool Savage_SetMode(ScrnInfoPtr, DGAModePtr); 48static int Savage_GetViewport(ScrnInfoPtr); 49static void Savage_SetViewport(ScrnInfoPtr, int, int, int); 50static void Savage_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 51static void Savage_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 52 53 54static 55DGAFunctionRec Savage_DGAFuncs = { 56 Savage_OpenFramebuffer, 57 NULL, /* CloseFrameBuffer */ 58 Savage_SetMode, 59 Savage_SetViewport, 60 Savage_GetViewport, 61 SavageAccelSync, 62 Savage_FillRect, 63 Savage_BlitRect, 64 NULL /* BlitTransRect */ 65}; 66 67#define DGATRACE 4 68 69/* 70 * I don't understand the thinking here. As near as I can tell, we are 71 * never asked to change into a depth other than the frame buffer depth. 72 * So why create modes to do so? 73 */ 74 75static DGAModePtr 76SavageSetupDGAMode( 77 ScrnInfoPtr pScrn, 78 DGAModePtr modes, 79 int *num, 80 int bitsPerPixel, 81 int depth, 82 Bool pixmap, 83 int secondPitch, 84 unsigned long red, 85 unsigned long green, 86 unsigned long blue, 87 short visualClass 88) 89{ 90 SavagePtr psav = SAVPTR(pScrn); 91 DGAModePtr mode, newmodes = NULL; 92 DisplayModePtr pMode, firstMode; 93 int otherPitch, Bpp = bitsPerPixel >> 3; 94 Bool oneMore; 95 96 xf86ErrorFVerb(DGATRACE, " SavageSetupDGAMode\n"); 97 98 pMode = firstMode = pScrn->modes; 99 100 /* 101 * DGA 1.0 would only provide modes where the depth and stride 102 * matched the current desktop. Some DGA apps might still expect 103 * this, so we provide them, too. 104 */ 105 106 while(pMode) { 107 108 otherPitch = secondPitch ? secondPitch : pMode->HDisplay; 109 110 if(pMode->HDisplay != otherPitch) { 111 newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec)); 112 oneMore = TRUE; 113 } else { 114 newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec)); 115 oneMore = FALSE; 116 } 117 118 if(!newmodes) { 119 xfree(modes); 120 return NULL; 121 } 122 modes = newmodes; 123 124SECOND_PASS: 125 126 mode = modes + *num; 127 (*num)++; 128 129 mode->mode = pMode; 130 mode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 131 if(!psav->NoAccel) 132 mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 133 if(pMode->Flags & V_DBLSCAN) 134 mode->flags |= DGA_DOUBLESCAN; 135 if(pMode->Flags & V_INTERLACE) 136 mode->flags |= DGA_INTERLACED; 137 mode->byteOrder = pScrn->imageByteOrder; 138 mode->depth = depth; 139 mode->bitsPerPixel = bitsPerPixel; 140 mode->red_mask = red; 141 mode->green_mask = green; 142 mode->blue_mask = blue; 143 mode->visualClass = visualClass; 144 mode->viewportWidth = pMode->HDisplay; 145 mode->viewportHeight = pMode->VDisplay; 146 mode->xViewportStep = 2; 147 mode->yViewportStep = 1; 148 mode->viewportFlags = DGA_FLIP_RETRACE; 149 mode->offset = 0; 150 mode->address = psav->FBBase; 151 152 xf86ErrorFVerb(DGATRACE, 153 "SavageDGAInit vpWid=%d, vpHgt=%d, Bpp=%d, mdbitsPP=%d\n", 154 mode->viewportWidth, 155 mode->viewportHeight, 156 Bpp, 157 mode->bitsPerPixel 158 ); 159 160 if(oneMore) { /* first one is narrow width */ 161 /* Force stride to multiple of 16 pixels. */ 162 mode->bytesPerScanline = ((pMode->HDisplay + 15) & ~15) * Bpp; 163 mode->imageWidth = pMode->HDisplay; 164 mode->imageHeight = pMode->VDisplay; 165 mode->pixmapWidth = mode->imageWidth; 166 mode->pixmapHeight = mode->imageHeight; 167 mode->maxViewportX = mode->imageWidth - mode->viewportWidth; 168 /* this might need to get clamped to some maximum */ 169 mode->maxViewportY = mode->imageHeight - mode->viewportHeight; 170 oneMore = FALSE; 171 172 xf86ErrorFVerb(DGATRACE, 173 "SavageDGAInit 1 imgHgt=%d, stride=%d\n", 174 mode->imageHeight, 175 mode->bytesPerScanline ); 176 177 goto SECOND_PASS; 178 } else { 179 mode->bytesPerScanline = ((pScrn->displayWidth + 15) & ~15) * Bpp; 180 mode->imageWidth = pScrn->displayWidth; 181 mode->imageHeight = psav->videoRambytes / mode->bytesPerScanline; 182 mode->pixmapWidth = mode->imageWidth; 183 mode->pixmapHeight = mode->imageHeight; 184 mode->maxViewportX = mode->imageWidth - mode->viewportWidth; 185 /* this might need to get clamped to some maximum */ 186 mode->maxViewportY = mode->imageHeight - mode->viewportHeight; 187 188 xf86ErrorFVerb(DGATRACE, 189 "SavageDGAInit 2 imgHgt=%d, stride=%d\n", 190 mode->imageHeight, 191 mode->bytesPerScanline ); 192 } 193 194 pMode = pMode->next; 195 if(pMode == firstMode) 196 break; 197 } 198 199 return modes; 200} 201 202 203Bool 204SavageDGAInit(ScreenPtr pScreen) 205{ 206 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 207 SavagePtr psav = SAVPTR(pScrn); 208 DGAModePtr modes = NULL; 209 int num = 0; 210 211 xf86ErrorFVerb(DGATRACE, " SavageDGAInit\n"); 212 213 /* 8 */ 214 modes = SavageSetupDGAMode (pScrn, modes, &num, 8, 8, 215 (pScrn->bitsPerPixel == 8), 216 (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth, 217 0, 0, 0, PseudoColor); 218 219 /* 15 */ 220 modes = SavageSetupDGAMode (pScrn, modes, &num, 16, 15, 221 (pScrn->bitsPerPixel == 16), 222 (pScrn->depth != 15) ? 0 : pScrn->displayWidth, 223 0x7c00, 0x03e0, 0x001f, TrueColor); 224 225 modes = SavageSetupDGAMode (pScrn, modes, &num, 16, 15, 226 (pScrn->bitsPerPixel == 16), 227 (pScrn->depth != 15) ? 0 : pScrn->displayWidth, 228 0x7c00, 0x03e0, 0x001f, DirectColor); 229 230 /* 16 */ 231 modes = SavageSetupDGAMode (pScrn, modes, &num, 16, 16, 232 (pScrn->bitsPerPixel == 16), 233 (pScrn->depth != 16) ? 0 : pScrn->displayWidth, 234 0xf800, 0x07e0, 0x001f, TrueColor); 235 236 modes = SavageSetupDGAMode (pScrn, modes, &num, 16, 16, 237 (pScrn->bitsPerPixel == 16), 238 (pScrn->depth != 16) ? 0 : pScrn->displayWidth, 239 0xf800, 0x07e0, 0x001f, DirectColor); 240 241 /* 24-in-32 */ 242 modes = SavageSetupDGAMode (pScrn, modes, &num, 32, 24, 243 (pScrn->bitsPerPixel == 32), 244 (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, 245 0xff0000, 0x00ff00, 0x0000ff, TrueColor); 246 247 modes = SavageSetupDGAMode (pScrn, modes, &num, 32, 24, 248 (pScrn->bitsPerPixel == 32), 249 (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, 250 0xff0000, 0x00ff00, 0x0000ff, DirectColor); 251 252 psav->numDGAModes = num; 253 psav->DGAModes = modes; 254 255 return DGAInit(pScreen, &Savage_DGAFuncs, modes, num); 256} 257 258 259static Bool 260Savage_SetMode( 261 ScrnInfoPtr pScrn, 262 DGAModePtr pMode 263){ 264 static int OldDisplayWidth[MAXSCREENS]; 265 static int OldBitsPerPixel[MAXSCREENS]; 266 static int OldDepth[MAXSCREENS]; 267 static DisplayModePtr OldMode[MAXSCREENS]; 268 int index = pScrn->pScreen->myNum; 269 SavagePtr psav = SAVPTR(pScrn); 270 271 if(!pMode) { /* restore the original mode */ 272 /* put the ScreenParameters back */ 273 274 pScrn->displayWidth = OldDisplayWidth[index]; 275 pScrn->bitsPerPixel = OldBitsPerPixel[index]; 276 pScrn->depth = OldDepth[index]; 277 pScrn->currentMode = OldMode[index]; 278 279 psav->DGAactive = FALSE; 280 SavageSwitchMode(index, pScrn->currentMode, 0); 281 if( psav->hwcursor && psav->hwc_on ) 282 SavageShowCursor(pScrn); 283 } else { 284 Bool holdBIOS = psav->UseBIOS; 285 286#if 0 287 ErrorF( 288 "pScrn->bitsPerPixel %d, pScrn->depth %d\n", 289 pScrn->bitsPerPixel, pScrn->depth); 290 ErrorF( 291 " want bitsPerPixel %d, want depth %d\n", 292 pMode->bitsPerPixel, pMode->depth); 293#endif 294 295 if( psav->hwcursor && psav->hwc_on) { 296 SavageHideCursor(pScrn); 297 psav->hwc_on = TRUE; /* save for later restauration */ 298 } 299 300 301 if(!psav->DGAactive) { /* save the old parameters */ 302 OldDisplayWidth[index] = pScrn->displayWidth; 303 OldBitsPerPixel[index] = pScrn->bitsPerPixel; 304 OldDepth[index] = pScrn->depth; 305 OldMode[index] = pScrn->currentMode; 306 307 psav->DGAactive = TRUE; 308 } 309 310 pScrn->bitsPerPixel = pMode->bitsPerPixel; 311 pScrn->depth = pMode->depth; 312 pScrn->displayWidth = pMode->bytesPerScanline / 313 (pMode->bitsPerPixel >> 3); 314 315/* psav->UseBIOS = FALSE; */ 316 SavageSwitchMode(index, pMode->mode, 0); 317 psav->UseBIOS = holdBIOS; 318 } 319 320 return TRUE; 321} 322 323 324static int 325Savage_GetViewport( 326 ScrnInfoPtr pScrn 327){ 328 SavagePtr psav = SAVPTR(pScrn); 329 return psav->DGAViewportStatus; 330} 331 332 333static void 334Savage_SetViewport( 335 ScrnInfoPtr pScrn, 336 int x, int y, 337 int flags 338){ 339 SavagePtr psav = SAVPTR(pScrn); 340 341 SavageAdjustFrame(pScrn->pScreen->myNum, x, y, flags); 342 psav->DGAViewportStatus = 0; /* MGAAdjustFrame loops until finished */ 343} 344 345static void 346Savage_FillRect ( 347 ScrnInfoPtr pScrn, 348 int x, int y, int w, int h, 349 unsigned long color 350){ 351 SavagePtr psav = SAVPTR(pScrn); 352 353 if(psav->AccelInfoRec) { 354 (*psav->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 355 (*psav->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 356 SET_SYNC_FLAG(psav->AccelInfoRec); 357 } 358} 359 360static void 361Savage_BlitRect( 362 ScrnInfoPtr pScrn, 363 int srcx, int srcy, 364 int w, int h, 365 int dstx, int dsty 366){ 367 SavagePtr psav = SAVPTR(pScrn); 368 369 if(psav->AccelInfoRec) { 370 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 371 int ydir = (srcy < dsty) ? -1 : 1; 372 373 (*psav->AccelInfoRec->SetupForScreenToScreenCopy)( 374 pScrn, xdir, ydir, GXcopy, ~0, -1); 375 (*psav->AccelInfoRec->SubsequentScreenToScreenCopy)( 376 pScrn, srcx, srcy, dstx, dsty, w, h); 377 SET_SYNC_FLAG(psav->AccelInfoRec); 378 } 379} 380 381 382static Bool 383Savage_OpenFramebuffer( 384 ScrnInfoPtr pScrn, 385 char **name, 386 unsigned char **mem, 387 int *size, 388 int *offset, 389 int *flags 390){ 391 SavagePtr psav = SAVPTR(pScrn); 392 393 *name = NULL; /* no special device */ 394 *mem = (unsigned char*)psav->FrameBufferBase; 395 *size = psav->videoRambytes; 396 *offset = 0; 397 *flags = DGA_NEED_ROOT; 398 399 return TRUE; 400} 401