atidga.c revision 1b12faf6
1/* 2 * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of Marc Aurele La France not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. Marc Aurele La France makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as-is" without express or implied warranty. 13 * 14 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 16 * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26#ifndef AVOID_DGA 27 28#include <string.h> 29 30#include "ati.h" 31#include "atiadjust.h" 32#include "atichip.h" 33#include "atidac.h" 34#include "atidga.h" 35#include "atimode.h" 36#include "atistruct.h" 37 38#include "dgaproc.h" 39 40/* 41 * ATIDGAOpenFramebuffer -- 42 * 43 * This function returns various framebuffer attributes to a DGA client. 44 */ 45static Bool 46ATIDGAOpenFramebuffer 47( 48 ScrnInfoPtr pScreenInfo, 49 char **DeviceName, 50 unsigned char **ApertureBase, 51 int *ApertureSize, 52 int *ApertureOffset, 53 int *flags 54) 55{ 56 ATIPtr pATI = ATIPTR(pScreenInfo); 57 58 *DeviceName = NULL; /* No special device */ 59 *ApertureBase = (unsigned char *)(pATI->LinearBase); 60 *ApertureSize = pScreenInfo->videoRam * 1024; 61 *ApertureOffset = 0; /* Always */ 62 *flags = 0; /* Root premissions OS-dependent */ 63 64 return TRUE; 65} 66 67static int 68BitsSet 69( 70 unsigned long data 71) 72{ 73 unsigned long mask = 1; 74 int set = 0; 75 76 for (; mask; mask <<= 1) 77 if (data & mask) 78 set++; 79 80 return set; 81} 82 83/* 84 * ATIDGASetMode -- 85 * 86 * This function sets a graphics mode for a DGA client. 87 */ 88static Bool 89ATIDGASetMode 90( 91 ScrnInfoPtr pScreenInfo, 92 DGAModePtr pDGAMode 93) 94{ 95 ATIPtr pATI = ATIPTR(pScreenInfo); 96 DisplayModePtr pMode; 97 int iScreen = pScreenInfo->scrnIndex; 98 int frameX0, frameY0; 99 100 if (pDGAMode) 101 { 102 pMode = pDGAMode->mode; 103 pATI->depth = pDGAMode->depth; 104 pATI->bitsPerPixel = pDGAMode->bitsPerPixel; 105 pATI->displayWidth = 106 pDGAMode->bytesPerScanline * 8 / pATI->bitsPerPixel; 107 pATI->weight.red = BitsSet(pDGAMode->red_mask); 108 pATI->weight.green = BitsSet(pDGAMode->green_mask); 109 pATI->weight.blue = BitsSet(pDGAMode->blue_mask); 110 frameX0 = frameY0 = 0; 111 if (!pATI->currentMode) 112 pATI->currentMode = pScreenInfo->currentMode; 113 } 114 else 115 { 116 if (!(pMode = pATI->currentMode)) 117 return TRUE; 118 119 pATI->depth = pScreenInfo->depth; 120 pATI->bitsPerPixel = pScreenInfo->bitsPerPixel; 121 pATI->displayWidth = pScreenInfo->displayWidth; 122 pATI->weight = pScreenInfo->weight; 123 frameX0 = pScreenInfo->frameX0; 124 frameY0 = pScreenInfo->frameY0; 125 } 126 127 pATI->XModifier = pATI->bitsPerPixel / UnitOf(pATI->bitsPerPixel); 128 ATIAdjustPreInit(pATI); 129 ATIModePreInit(pScreenInfo, pATI, &pATI->NewHW); 130 131 if (!(*pScreenInfo->SwitchMode)(iScreen, pMode, 0)) 132 return FALSE; 133 if (!pDGAMode) 134 pATI->currentMode = NULL; 135 (*pScreenInfo->AdjustFrame)(iScreen, frameX0, frameY0, 0); 136 137 return TRUE; 138} 139 140/* 141 * ATIDGASetViewport -- 142 * 143 * This function sets the display start address for a DGA client. 144 */ 145static void 146ATIDGASetViewport 147( 148 ScrnInfoPtr pScreenInfo, 149 int x, 150 int y, 151 int flags 152) 153{ 154 (*pScreenInfo->AdjustFrame)(pScreenInfo->pScreen->myNum, x, y, flags); 155} 156 157/* 158 * ATIDGAGetViewport -- 159 * 160 * This function returns the current status of prior DGA requests to set the 161 * adapter's display start address. 162 */ 163static int 164ATIDGAGetViewport 165( 166 ScrnInfoPtr pScreenInfo 167) 168{ 169 return 0; /* There are never any pending requests */ 170} 171 172/* 173 * ATIDGAFillRect -- 174 * 175 * This function calls XAA solid fill primitives to fill a rectangle. 176 */ 177static void 178ATIDGAFillRect 179( 180 ScrnInfoPtr pScreenInfo, 181 int x, 182 int y, 183 int w, 184 int h, 185 unsigned long colour 186) 187{ 188 ATIPtr pATI = ATIPTR(pScreenInfo); 189/*FIXME : use EXA if available */ 190#ifdef USE_XAA 191 XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo; 192 193 (*pXAAInfo->SetupForSolidFill)(pScreenInfo, (int)colour, GXcopy, 194 (CARD32)(~0)); 195 (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo, x, y, w, h); 196 197 if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel) 198 SET_SYNC_FLAG(pXAAInfo); 199#endif 200} 201 202/* 203 * ATIDGABlitRect -- 204 * 205 * This function calls XAA screen-to-screen copy primitives to copy a 206 * rectangle. 207 */ 208static void 209ATIDGABlitRect 210( 211 ScrnInfoPtr pScreenInfo, 212 int xSrc, 213 int ySrc, 214 int w, 215 int h, 216 int xDst, 217 int yDst 218) 219{ 220 ATIPtr pATI = ATIPTR(pScreenInfo); 221/*FIXME : use EXA if available */ 222#ifdef USE_XAA 223 XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo; 224 int xdir = ((xSrc < xDst) && (ySrc == yDst)) ? -1 : 1; 225 int ydir = (ySrc < yDst) ? -1 : 1; 226 227 (*pXAAInfo->SetupForScreenToScreenCopy)(pScreenInfo, 228 xdir, ydir, GXcopy, (CARD32)(~0), -1); 229 (*pXAAInfo->SubsequentScreenToScreenCopy)(pScreenInfo, 230 xSrc, ySrc, xDst, yDst, w, h); 231 232 if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel) 233 SET_SYNC_FLAG(pXAAInfo); 234#endif 235} 236 237/* 238 * ATIDGABlitTransRect -- 239 * 240 * This function calls XAA screen-to-screen copy primitives to transparently 241 * copy a rectangle. 242 */ 243static void 244ATIDGABlitTransRect 245( 246 ScrnInfoPtr pScreenInfo, 247 int xSrc, 248 int ySrc, 249 int w, 250 int h, 251 int xDst, 252 int yDst, 253 unsigned long colour 254) 255{ 256 ATIPtr pATI = ATIPTR(pScreenInfo); 257/*FIXME : use EXA if available */ 258#ifdef USE_XAA 259 XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo; 260 int xdir = ((xSrc < xDst) && (ySrc == yDst)) ? -1 : 1; 261 int ydir = (ySrc < yDst) ? -1 : 1; 262 263 pATI->XAAForceTransBlit = TRUE; 264 265 (*pXAAInfo->SetupForScreenToScreenCopy)(pScreenInfo, 266 xdir, ydir, GXcopy, (CARD32)(~0), (int)colour); 267 268 pATI->XAAForceTransBlit = FALSE; 269 270 (*pXAAInfo->SubsequentScreenToScreenCopy)(pScreenInfo, 271 xSrc, ySrc, xDst, yDst, w, h); 272 273 if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel) 274 SET_SYNC_FLAG(pXAAInfo); 275#endif 276} 277 278/* 279 * ATIDGAAddModes -- 280 * 281 * This function translates DisplayModeRec's into DGAModeRec's. 282 */ 283static void 284ATIDGAAddModes 285( 286 ScrnInfoPtr pScreenInfo, 287 ATIPtr pATI, 288 int flags, 289 int depth, 290 int bitsPerPixel, 291 int redMask, 292 int greenMask, 293 int blueMask, 294 int visualClass 295) 296{ 297 DisplayModePtr pMode = pScreenInfo->modes; 298 DGAModePtr pDGAMode; 299 int displayWidth = pScreenInfo->displayWidth; 300 int videoBits = pScreenInfo->videoRam * 1024 * 8; 301 int xViewportStep = 64 / UnitOf(bitsPerPixel); 302 int modePitch, bitsPerScanline, maxViewportY; 303 304 if (bitsPerPixel != pScreenInfo->bitsPerPixel) 305 displayWidth = 0; 306 307 while (1) 308 { 309 /* Weed out multiscanned modes */ 310 if ((pMode->VScan <= 1) || 311 ((pMode->VScan == 2) && !(pMode->Flags & V_DBLSCAN))) 312 { 313 /* 314 * For code simplicity, ensure DGA mode pitch is a multiple of 64 315 * bytes. 316 */ 317 if (!(modePitch = displayWidth)) 318 { 319 modePitch = ((64 * 8) / UnitOf(bitsPerPixel)) - 1; 320 modePitch = (pMode->HDisplay + modePitch) & ~modePitch; 321 } 322 323 /* Ensure the mode fits in video memory */ 324 if ((modePitch * bitsPerPixel * pMode->VDisplay) <= videoBits) 325 { 326 /* Stop generating modes on out-of-memory conditions */ 327 pDGAMode = realloc(pATI->pDGAMode, 328 (pATI->nDGAMode + 1) * SizeOf(DGAModeRec)); 329 if (!pDGAMode) 330 break; 331 332 pATI->pDGAMode = pDGAMode; 333 pDGAMode += pATI->nDGAMode; 334 pATI->nDGAMode++; 335 (void)memset(pDGAMode, 0, SizeOf(DGAModeRec)); 336 337 /* Fill in the mode structure */ 338 pDGAMode->mode = pMode; 339 pDGAMode->flags = flags; 340 if (bitsPerPixel == pScreenInfo->bitsPerPixel) 341 { 342 pDGAMode->flags |= DGA_PIXMAP_AVAILABLE; 343 pDGAMode->address = pATI->pMemory; 344 345#ifdef USE_XAA 346 if (pATI->pXAAInfo) 347 pDGAMode->flags &= ~DGA_CONCURRENT_ACCESS; 348#endif 349 } 350 if ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1)) 351 pDGAMode->flags |= DGA_DOUBLESCAN; 352 if (pMode->Flags & V_INTERLACE) 353 pDGAMode->flags |= DGA_INTERLACED; 354 355 pDGAMode->byteOrder = pScreenInfo->imageByteOrder; 356 pDGAMode->depth = depth; 357 pDGAMode->bitsPerPixel = bitsPerPixel; 358 pDGAMode->red_mask = redMask; 359 pDGAMode->green_mask = greenMask; 360 pDGAMode->blue_mask = blueMask; 361 pDGAMode->visualClass = visualClass; 362 363 pDGAMode->viewportWidth = pMode->HDisplay; 364 pDGAMode->viewportHeight = pMode->VDisplay; 365 pDGAMode->xViewportStep = xViewportStep; 366 pDGAMode->yViewportStep = 1; 367 368 bitsPerScanline = modePitch * bitsPerPixel; 369 pDGAMode->bytesPerScanline = bitsPerScanline / 8; 370 pDGAMode->imageWidth = pDGAMode->pixmapWidth = modePitch; 371 pDGAMode->imageHeight = pDGAMode->pixmapHeight = 372 videoBits / bitsPerScanline; 373 374 pDGAMode->maxViewportX = 375 pDGAMode->imageWidth - pDGAMode->viewportWidth; 376 pDGAMode->maxViewportY = 377 pDGAMode->imageHeight - pDGAMode->viewportHeight; 378 maxViewportY = 379 ((((pATI->AdjustMaxBase * 8) / bitsPerPixel) + 380 xViewportStep) / modePitch) - 1; 381 if (maxViewportY < pDGAMode->maxViewportY) 382 pDGAMode->maxViewportY = maxViewportY; 383 } 384 } 385 386 if ((pMode = pMode->next) == pScreenInfo->modes) 387 { 388 if (!displayWidth) 389 break; 390 391 displayWidth = 0; 392 } 393 } 394} 395 396/* 397 * ATIDGAInit -- 398 * 399 * This function initialises the driver's support for the DGA extension. 400 */ 401Bool 402ATIDGAInit 403( 404 ScreenPtr pScreen, 405 ScrnInfoPtr pScreenInfo, 406 ATIPtr pATI 407) 408{ 409#ifdef USE_XAA 410 XAAInfoRecPtr pXAAInfo; 411#endif 412 int flags; 413 414 if (!pATI->nDGAMode) 415 { 416 /* Set up DGA callbacks */ 417 pATI->ATIDGAFunctions.OpenFramebuffer = ATIDGAOpenFramebuffer; 418 pATI->ATIDGAFunctions.SetMode = ATIDGASetMode; 419 pATI->ATIDGAFunctions.SetViewport = ATIDGASetViewport; 420 pATI->ATIDGAFunctions.GetViewport = ATIDGAGetViewport; 421 422 flags = 0; 423#ifdef USE_XAA 424 if ((pXAAInfo = pATI->pXAAInfo)) 425 { 426 pATI->ATIDGAFunctions.Sync = pXAAInfo->Sync; 427 if (pXAAInfo->SetupForSolidFill && 428 pXAAInfo->SubsequentSolidFillRect) 429 { 430 flags |= DGA_FILL_RECT; 431 pATI->ATIDGAFunctions.FillRect = ATIDGAFillRect; 432 } 433 if (pXAAInfo->SetupForScreenToScreenCopy && 434 pXAAInfo->SubsequentScreenToScreenCopy) 435 { 436 flags |= DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS; 437 pATI->ATIDGAFunctions.BlitRect = ATIDGABlitRect; 438 pATI->ATIDGAFunctions.BlitTransRect = ATIDGABlitTransRect; 439 } 440 } 441#endif 442 if (!flags) 443 flags = DGA_CONCURRENT_ACCESS; 444 445 ATIDGAAddModes(pScreenInfo, pATI, flags, 446 8, 8, 0, 0, 0, PseudoColor); 447 448 if ((pATI->Chip >= ATI_CHIP_264CT)) 449 { 450 ATIDGAAddModes(pScreenInfo, pATI, flags, 451 15, 16, 0x7C00U, 0x03E0U, 0x001FU, TrueColor); 452 453 ATIDGAAddModes(pScreenInfo, pATI, flags, 454 16, 16, 0xF800U, 0x07E0U, 0x001FU, TrueColor); 455 456 ATIDGAAddModes(pScreenInfo, pATI, flags, 457 24, 24, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, TrueColor); 458 459 ATIDGAAddModes(pScreenInfo, pATI, flags, 460 24, 32, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, TrueColor); 461 462 if (pATI->DAC != ATI_DAC_INTERNAL) /* Not first revision */ 463 { 464 ATIDGAAddModes(pScreenInfo, pATI, flags, 465 15, 16, 0x7C00U, 0x03E0U, 0x001FU, DirectColor); 466 467 ATIDGAAddModes(pScreenInfo, pATI, flags, 468 16, 16, 0xF800U, 0x07E0U, 0x001FU, DirectColor); 469 470 ATIDGAAddModes(pScreenInfo, pATI, flags, 471 24, 24, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, DirectColor); 472 473 ATIDGAAddModes(pScreenInfo, pATI, flags, 474 24, 32, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, DirectColor); 475 } 476 } 477 } 478 479 return DGAInit(pScreen, &pATI->ATIDGAFunctions, pATI->pDGAMode, 480 pATI->nDGAMode); 481} 482 483#endif /* AVOID_DGA */ 484