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