1 /* 2 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi (at) 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 27 #include <string.h> 28 29 #include "ati.h" 30 #include "atichip.h" 31 #include "atimach64accel.h" 32 #include "atimach64io.h" 33 #include "atixv.h" 34 #include "atimach64version.h" 35 36 #include <X11/extensions/Xv.h> 37 #include "fourcc.h" 38 #include "xf86xv.h" 39 40 #define MAKE_ATOM(string) MakeAtom(string, strlen(string), TRUE) 41 #define MaxScale (CARD32)(CARD16)(-1) 42 43 static unsigned long ATIMach64XVAtomGeneration = (unsigned long)(-1); 44 45 static XF86VideoEncodingRec ATIMach64VideoEncoding[] = 46 { 47 { 0, "XV_IMAGE", 720, 2048, {1, 1} } 48 }; 49 #define nATIMach64VideoEncoding NumberOf(ATIMach64VideoEncoding) 50 51 static XF86VideoFormatRec ATIMach64VideoFormat[] = 52 { 53 { 8, TrueColor}, 54 { 8, DirectColor}, 55 { 8, PseudoColor}, 56 { 8, GrayScale}, 57 { 8, StaticGray}, 58 { 8, StaticColor}, 59 {15, TrueColor}, 60 {16, TrueColor}, 61 {24, TrueColor}, 62 {15, DirectColor}, 63 {16, DirectColor}, 64 {24, DirectColor} 65 }; 66 #define nATIMach64VideoFormat NumberOf(ATIMach64VideoFormat) 67 68 static XF86AttributeRec ATIMach64Attribute[] = 69 { 70 /* These are only supported on the Rage Pro and later ... */ 71 { 72 XvSettable | XvGettable, 73 -1000, 1000, 74 "XV_SATURATION" 75 }, 76 { 77 XvSettable | XvGettable, 78 -1000, 1000, 79 "XV_BRIGHTNESS" 80 }, 81 { 82 XvSettable | XvGettable, 83 -1000, 1000, 84 "XV_COLOUR" 85 }, 86 { 87 XvSettable | XvGettable, 88 -1000, 1000, 89 "XV_COLOR" 90 }, 91 92 /* Local attributes, odds and ends for compatibility, etc... */ 93 { 94 XvSettable | XvGettable, 95 0, 1, 96 "XV_AUTOPAINT_COLOURKEY" 97 }, 98 { 99 XvSettable | XvGettable, 100 0, 1, 101 "XV_AUTOPAINT_COLORKEY" 102 }, 103 { 104 XvSettable | XvGettable, 105 0, (1 << 24) - 1, 106 "XV_COLOURKEY" 107 }, 108 { 109 XvSettable | XvGettable, 110 0, (1 << 24) - 1, 111 "XV_COLORKEY" 112 }, 113 { 114 XvSettable | XvGettable, 115 0, (1 << 24) - 1, 116 "XV_COLOURKEY_MASK" 117 }, 118 { 119 XvSettable | XvGettable, 120 0, (1 << 24) - 1, 121 "XV_COLORKEY_MASK" 122 }, 123 { 124 XvSettable, 125 0, 0, 126 "XV_SET_DEFAULTS" 127 }, 128 { /* Keep last */ 129 XvSettable | XvGettable, 130 0, 1, 131 "XV_DOUBLE_BUFFER" 132 } 133 }; 134 #define nATIMach64Attribute NumberOf(ATIMach64Attribute) 135 136 static XF86ImageRec ATIMach64Image[] = 137 { 138 XVIMAGE_YUY2, 139 XVIMAGE_UYVY, 140 XVIMAGE_YV12, 141 XVIMAGE_I420 142 }; 143 #define nATIMach64Image NumberOf(ATIMach64Image) 144 145 /* A local XVideo adaptor attribute record */ 146 typedef struct _ATIMach64Attribute 147 { 148 Atom AttributeID; 149 INT32 MaxValue; /* ... for the hardware */ 150 void (*SetAttribute) (ATIPtr, INT32); 151 INT32 (*GetAttribute) (ATIPtr); 152 } ATIMach64AttributeRec, *ATIMach64AttributePtr; 153 154 /* Functions to get/set XVideo adaptor attributes */ 155 156 static void 157 ATIMach64SetSaturationAttribute 158 ( 159 ATIPtr pATI, 160 INT32 Value 161 ) 162 { 163 /* Set the register */ 164 pATI->NewHW.scaler_colour_cntl &= 165 ~(SCALE_SATURATION_U | SCALE_SATURATION_V); 166 pATI->NewHW.scaler_colour_cntl |= SetBits(Value, SCALE_SATURATION_U) | 167 SetBits(Value, SCALE_SATURATION_V); 168 outf(SCALER_COLOUR_CNTL, pATI->NewHW.scaler_colour_cntl); 169 } 170 171 static INT32 172 ATIMach64GetSaturationAttribute 173 ( 174 ATIPtr pATI 175 ) 176 { 177 return (INT32)GetBits(pATI->NewHW.scaler_colour_cntl, SCALE_SATURATION_U); 178 } 179 180 static void 181 ATIMach64SetBrightnessAttribute 182 ( 183 ATIPtr pATI, 184 INT32 Value 185 ) 186 { 187 /* Set the register */ 188 pATI->NewHW.scaler_colour_cntl &= ~SCALE_BRIGHTNESS; 189 pATI->NewHW.scaler_colour_cntl |= SetBits(Value, SCALE_BRIGHTNESS); 190 outf(SCALER_COLOUR_CNTL, pATI->NewHW.scaler_colour_cntl); 191 } 192 193 static INT32 194 ATIMach64GetBrightnessAttribute 195 ( 196 ATIPtr pATI 197 ) 198 { 199 return (INT32)GetBits(pATI->NewHW.scaler_colour_cntl, SCALE_BRIGHTNESS); 200 } 201 202 static void 203 ATIMach64SetDoubleBufferAttribute 204 ( 205 ATIPtr pATI, 206 INT32 Value 207 ) 208 { 209 pATI->DoubleBuffer = Value; 210 } 211 212 static INT32 213 ATIMach64GetDoubleBufferAttribute 214 ( 215 ATIPtr pATI 216 ) 217 { 218 return (int)pATI->DoubleBuffer; 219 } 220 221 static void 222 ATIMach64SetAutoPaintAttribute 223 ( 224 ATIPtr pATI, 225 INT32 Value 226 ) 227 { 228 pATI->AutoPaint = Value; 229 } 230 231 static INT32 232 ATIMach64GetAutoPaintAttribute 233 ( 234 ATIPtr pATI 235 ) 236 { 237 return (int)pATI->AutoPaint; 238 } 239 240 static void 241 ATIMach64SetColourKeyAttribute 242 ( 243 ATIPtr pATI, 244 INT32 Value 245 ) 246 { 247 pATI->NewHW.overlay_graphics_key_clr = 248 (CARD32)(Value & ((1 << pATI->depth) - 1)); 249 outf(OVERLAY_GRAPHICS_KEY_CLR, pATI->NewHW.overlay_graphics_key_clr); 250 } 251 252 static INT32 253 ATIMach64GetColourKeyAttribute 254 ( 255 ATIPtr pATI 256 ) 257 { 258 return (INT32)pATI->NewHW.overlay_graphics_key_clr; 259 } 260 261 static void 262 ATIMach64SetColourKeyMaskAttribute 263 ( 264 ATIPtr pATI, 265 INT32 Value 266 ) 267 { 268 pATI->NewHW.overlay_graphics_key_msk = 269 (CARD32)(Value & ((1 << pATI->depth) - 1)); 270 outf(OVERLAY_GRAPHICS_KEY_MSK, pATI->NewHW.overlay_graphics_key_msk); 271 } 272 273 static INT32 274 ATIMach64GetColourKeyMaskAttribute 275 ( 276 ATIPtr pATI 277 ) 278 { 279 return (INT32)pATI->NewHW.overlay_graphics_key_msk; 280 } 281 282 /* 283 * ATIMach64SetDefaultAttributes -- 284 * 285 * This function calls other functions to set default values for the various 286 * attributes of an XVideo port. 287 */ 288 static void 289 ATIMach64SetDefaultAttributes 290 ( 291 ATIPtr pATI, 292 INT32 Value 293 ) 294 { 295 ATIMach64SetAutoPaintAttribute(pATI, TRUE); 296 ATIMach64SetDoubleBufferAttribute(pATI, FALSE); 297 ATIMach64SetColourKeyMaskAttribute(pATI, (1 << pATI->depth) - 1); 298 ATIMach64SetColourKeyAttribute(pATI, (3 << ((2 * pATI->depth) / 3)) | 299 (2 << ((1 * pATI->depth) / 3)) | 300 (1 << ((0 * pATI->depth) / 3))); 301 302 if (pATI->Chip < ATI_CHIP_264GTPRO) 303 return; 304 305 ATIMach64SetBrightnessAttribute(pATI, 32); 306 ATIMach64SetSaturationAttribute(pATI, 16); 307 } 308 309 /* 310 * There is a one-to-one correspondence between elements of the following array 311 * and those of ATIMach64Attribute. 312 */ 313 static ATIMach64AttributeRec ATIMach64AttributeInfo[nATIMach64Attribute] = 314 { 315 { /* SATURATION */ 316 0, 23, 317 ATIMach64SetSaturationAttribute, 318 ATIMach64GetSaturationAttribute 319 }, 320 { /* BRIGHTNESS */ 321 0, 63, 322 ATIMach64SetBrightnessAttribute, 323 ATIMach64GetBrightnessAttribute 324 }, 325 { /* COLOUR */ 326 0, 23, 327 ATIMach64SetSaturationAttribute, 328 ATIMach64GetSaturationAttribute 329 }, 330 { /* COLOR */ 331 0, 23, 332 ATIMach64SetSaturationAttribute, 333 ATIMach64GetSaturationAttribute 334 }, 335 { /* AUTOPAINT_COLOURKEY */ 336 0, 1, 337 ATIMach64SetAutoPaintAttribute, 338 ATIMach64GetAutoPaintAttribute 339 }, 340 { /* AUTOPAINT_COLORKEY */ 341 0, 1, 342 ATIMach64SetAutoPaintAttribute, 343 ATIMach64GetAutoPaintAttribute 344 }, 345 { /* COLOURKEY */ 346 0, (1 << 24) - 1, 347 ATIMach64SetColourKeyAttribute, 348 ATIMach64GetColourKeyAttribute 349 }, 350 { /* COLORKEY */ 351 0, (1 << 24) - 1, 352 ATIMach64SetColourKeyAttribute, 353 ATIMach64GetColourKeyAttribute 354 }, 355 { /* COLOURKEY_MASK */ 356 0, (1 << 24) - 1, 357 ATIMach64SetColourKeyMaskAttribute, 358 ATIMach64GetColourKeyMaskAttribute 359 }, 360 { /* COLORKEY_MASK */ 361 0, (1 << 24) - 1, 362 ATIMach64SetColourKeyMaskAttribute, 363 ATIMach64GetColourKeyMaskAttribute 364 }, 365 { /* SET_DEFAULTS */ 366 0, 0, 367 ATIMach64SetDefaultAttributes, 368 NULL 369 }, 370 { /* DOUBLE_BUFFER */ 371 0, 1, 372 ATIMach64SetDoubleBufferAttribute, 373 ATIMach64GetDoubleBufferAttribute 374 } 375 }; 376 377 /* 378 * ATIMach64FindAttribute -- 379 * 380 * This function is called to locate an Xv attribute's table entry. 381 */ 382 static int 383 ATIMach64FindPortAttribute 384 ( 385 ATIPtr pATI, 386 Atom AttributeID 387 ) 388 { 389 int iAttribute; 390 391 if (pATI->Chip < ATI_CHIP_264GTPRO) 392 iAttribute = 4; 393 else 394 iAttribute = 0; 395 396 for (; iAttribute < nATIMach64Attribute; iAttribute++) 397 if (AttributeID == ATIMach64AttributeInfo[iAttribute].AttributeID) 398 return iAttribute; 399 400 return -1; 401 } 402 403 /* 404 * ATIMach64SetPortAttribute -- 405 * 406 * This function sets the value of a particular port's attribute. 407 */ 408 static int 409 ATIMach64SetPortAttribute 410 ( 411 ScrnInfoPtr pScreenInfo, 412 Atom AttributeID, 413 INT32 Value, 414 pointer pATI 415 ) 416 { 417 INT32 Range; 418 int iAttribute; 419 420 if (((iAttribute = ATIMach64FindPortAttribute(pATI, AttributeID)) < 0) || 421 !ATIMach64AttributeInfo[iAttribute].SetAttribute) 422 return BadMatch; 423 424 Range = ATIMach64Attribute[iAttribute].max_value - 425 ATIMach64Attribute[iAttribute].min_value; 426 427 if (Range >= 0) 428 { 429 /* Limit and scale the value */ 430 Value -= ATIMach64Attribute[iAttribute].min_value; 431 432 if (Value < 0) 433 Value = 0; 434 else if (Value > Range) 435 Value = Range; 436 437 if (Range != ATIMach64AttributeInfo[iAttribute].MaxValue) 438 { 439 if (ATIMach64AttributeInfo[iAttribute].MaxValue > 0) 440 Value *= ATIMach64AttributeInfo[iAttribute].MaxValue; 441 if (Range > 0) 442 Value /= Range; 443 } 444 } 445 446 (*ATIMach64AttributeInfo[iAttribute].SetAttribute)(pATI, Value); 447 448 return Success; 449 } 450 451 /* 452 * ATIMach64SetPortAttribute -- 453 * 454 * This function retrieves the value of a particular port's attribute. 455 */ 456 static int 457 ATIMach64GetPortAttribute 458 ( 459 ScrnInfoPtr pScreenInfo, 460 Atom AttributeID, 461 INT32 *Value, 462 pointer pATI 463 ) 464 { 465 INT32 Range; 466 int iAttribute; 467 468 if (!Value || 469 ((iAttribute = ATIMach64FindPortAttribute(pATI, AttributeID)) < 0) || 470 !ATIMach64AttributeInfo[iAttribute].GetAttribute) 471 return BadMatch; 472 473 *Value = (*ATIMach64AttributeInfo[iAttribute].GetAttribute)(pATI); 474 475 Range = ATIMach64Attribute[iAttribute].max_value - 476 ATIMach64Attribute[iAttribute].min_value; 477 478 if (Range >= 0) 479 { 480 if (Range != ATIMach64AttributeInfo[iAttribute].MaxValue) 481 { 482 /* (Un-)scale the value */ 483 if (Range > 0) 484 *Value *= Range; 485 if (ATIMach64AttributeInfo[iAttribute].MaxValue > 0) 486 *Value /= ATIMach64AttributeInfo[iAttribute].MaxValue; 487 } 488 489 *Value += ATIMach64Attribute[iAttribute].min_value; 490 } 491 492 return Success; 493 } 494 495 static pointer 496 ATIMach64XVMemAlloc 497 ( 498 ScreenPtr pScreen, 499 pointer pVideo, 500 int size, 501 int *offset, 502 ATIPtr pATI 503 ); 504 505 static void 506 ATIMach64XVMemFree 507 ( 508 ScreenPtr pScreen, 509 pointer pVideo, 510 ATIPtr pATI 511 ); 512 513 514 /* 515 * ATIMach64StopVideo -- 516 * 517 * This is called to stop displaying a video. Note that, to prevent jittering 518 * this doesn't actually turn off the overlay unless 'Cleanup' is TRUE, i.e. 519 * when the video is to be actually stopped rather than temporarily disabled. 520 */ 521 static void 522 ATIMach64StopVideo 523 ( 524 ScrnInfoPtr pScreenInfo, 525 pointer Data, 526 Bool Cleanup 527 ) 528 { 529 ScreenPtr pScreen = pScreenInfo->pScreen; 530 ATIPtr pATI = Data; 531 532 if (pATI->ActiveSurface) 533 return; 534 535 REGION_EMPTY(pScreen, &pATI->VideoClip); 536 537 538 ATIMach64XVMemFree(pScreen, pATI->pXVBuffer, pATI); 539 pATI->pXVBuffer = NULL; 540 outf(OVERLAY_SCALE_CNTL, SCALE_EN); 541 } 542 543 /* 544 * ATIMach64QueryBestSize -- 545 * 546 * Quoting XVideo docs: 547 * 548 * This function provides the client with a way to query what the destination 549 * dimensions would end up being if they were to request that an area 550 * VideoWidth by VideoHeight from the video stream be scaled to rectangle of 551 * DrawableWidth by DrawableHeight on the screen. Since it is not expected 552 * that all hardware will be able to get the target dimensions exactly, it is 553 * important that the driver provide this function. 554 */ 555 static void 556 ATIMach64QueryBestSize 557 ( 558 ScrnInfoPtr pScreenInfo, 559 Bool Motion, 560 short VideoWidth, 561 short VideoHeight, 562 short DrawableWidth, 563 short DrawableHeight, 564 unsigned int *Width, 565 unsigned int *Height, 566 pointer pATI 567 ) 568 { 569 *Width = DrawableWidth; 570 *Height = DrawableHeight; 571 } 572 573 /* 574 * ATIMach64QueryImageAttributes -- 575 * 576 * Quoting XVideo docs: 577 * 578 * This function is called to let the driver specify how data for a particular 579 * image of size Width by Height should be stored. Sometimes only the size and 580 * corrected width and height are needed. In that case pitches and offsets are 581 * NULL. The size of the memory required for the image is returned by this 582 * function. The width and height of the requested image can be altered by the 583 * driver to reflect format limitations (such as component sampling periods 584 * that are larger than one). If pPitch and pOffset are not NULL, these will 585 * be arrays with as many elements in them as there are planes in the image 586 * format. The driver should specify the pitch (in bytes) of each scanline in 587 * the particular plane as well as the offset to that plane (in bytes) from the 588 * beginning of the image. 589 */ 590 static int 591 ATIMach64QueryImageAttributes 592 ( 593 ScrnInfoPtr pScreenInfo, 594 int ImageID, 595 unsigned short *Width, 596 unsigned short *Height, 597 int *pPitch, 598 int *pOffset 599 ) 600 { 601 int Size, tmp; 602 603 if (!Width || !Height) 604 return 0; 605 606 if (*Width > 2048) 607 *Width = 2048; 608 else 609 *Width = (*Width + 1) & ~1; 610 611 if (*Height > 2048) 612 *Height = 2048; 613 614 if (pOffset) 615 pOffset[0] = 0; 616 617 switch (ImageID) 618 { 619 case FOURCC_YV12: 620 case FOURCC_I420: 621 *Height = (*Height + 1) & ~1; 622 Size = (*Width + 3) & ~3; 623 if (pPitch) 624 pPitch[0] = Size; 625 Size *= *Height; 626 if (pOffset) 627 pOffset[1] = Size; 628 tmp = ((*Width >> 1) + 3) & ~3; 629 if (pPitch) 630 pPitch[1] = pPitch[2] = tmp; 631 tmp *= (*Height >> 1); 632 Size += tmp; 633 if (pOffset) 634 pOffset[2] = Size; 635 Size += tmp; 636 break; 637 638 case FOURCC_UYVY: 639 case FOURCC_YUY2: 640 Size = *Width << 1; 641 if (pPitch) 642 pPitch[0] = Size; 643 Size *= *Height; 644 break; 645 646 default: 647 Size = 0; 648 break; 649 } 650 651 return Size; 652 } 653 654 /* 655 * ATIMach64ScaleVideo -- 656 * 657 * This function is called to calculate overlay scaling factors. 658 */ 659 static void 660 ATIMach64ScaleVideo 661 ( 662 ATIPtr pATI, 663 DisplayModePtr pMode, 664 int SrcW, 665 int SrcH, 666 int DstW, 667 int DstH, 668 CARD32 *pHScale, 669 CARD32 *pVScale 670 ) 671 { 672 int Shift; 673 674 *pHScale = ATIDivide(SrcW, DstW, 675 GetBits(pATI->NewHW.pll_vclk_cntl, PLL_ECP_DIV) + 12, 0); 676 677 Shift = 12; 678 if (pMode->Flags & V_INTERLACE) 679 Shift++; 680 681 if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0)) 682 { 683 if (pMode->VDisplay < pATI->LCDVertical) 684 { 685 SrcH *= pMode->VDisplay; 686 DstH *= pATI->LCDVertical; 687 } 688 } 689 else 690 { 691 if (pMode->Flags & V_DBLSCAN) 692 Shift--; 693 if (pMode->VScan > 1) 694 DstH *= pMode->VScan; 695 } 696 697 *pVScale = ATIDivide(SrcH, DstH, Shift, 0); 698 } 699 700 /* 701 * ATIMach64ClipVideo -- 702 * 703 * Clip the video (both source and destination) and make various other 704 * adjustments. 705 */ 706 static Bool 707 ATIMach64ClipVideo 708 ( 709 ScrnInfoPtr pScreenInfo, 710 ATIPtr pATI, 711 int ImageID, 712 short SrcX, 713 short SrcY, 714 short SrcW, 715 short SrcH, 716 short DstX, 717 short DstY, 718 short *DstW, 719 short *DstH, 720 short Width, 721 short Height, 722 RegionPtr pClip, 723 BoxPtr pDstBox, 724 INT32 *SrcX1, 725 INT32 *SrcX2, 726 INT32 *SrcY1, 727 INT32 *SrcY2, 728 int *SrcLeft, 729 int *SrcTop 730 ) 731 { 732 CARD32 HScale, VScale; 733 734 /* Check hardware limits */ 735 if ((Height <= 0) || (Height > 2048) || (Width <= 0) || (Width > 768) || 736 ((Width > 384) && (pATI->Chip < ATI_CHIP_264VTB)) || 737 ((Width > 720) && (pATI->Chip < ATI_CHIP_264GTPRO || 738 pATI->Chip > ATI_CHIP_264LTPRO))) 739 return FALSE; 740 741 ATIMach64ScaleVideo(pATI, pScreenInfo->currentMode, 742 SrcW, SrcH, *DstW, *DstH, &HScale, &VScale); 743 if (!HScale || !VScale) 744 return FALSE; 745 if (HScale > MaxScale) 746 *DstW = (*DstW * HScale) / MaxScale; 747 if (VScale > MaxScale) 748 *DstH = (*DstH * HScale) / MaxScale; 749 750 /* Clip both the source and the destination */ 751 *SrcX1 = SrcX; 752 *SrcX2 = SrcX + SrcW; 753 *SrcY1 = SrcY; 754 *SrcY2 = SrcY + SrcH; 755 756 pDstBox->x1 = DstX; 757 pDstBox->x2 = DstX + *DstW; 758 pDstBox->y1 = DstY; 759 pDstBox->y2 = DstY + *DstH; 760 761 if (!xf86XVClipVideoHelper(pDstBox, SrcX1, SrcX2, SrcY1, SrcY2, 762 pClip, Width, Height)) 763 return FALSE; 764 765 /* 766 * Reset overlay scaler origin. This prevents jittering during 767 * viewport panning or while the video is being moved or gradually 768 * obscured/unobscured. 769 */ 770 pDstBox->x1 = DstX; 771 pDstBox->y1 = DstY; 772 773 /* Translate to the current viewport */ 774 pDstBox->x1 -= pScreenInfo->frameX0; 775 pDstBox->x2 -= pScreenInfo->frameX0; 776 pDstBox->y1 -= pScreenInfo->frameY0; 777 pDstBox->y2 -= pScreenInfo->frameY0; 778 779 *SrcLeft = *SrcTop = 0; 780 781 /* 782 * If the overlay scaler origin ends up outside the current viewport, move 783 * it to the viewport's top left corner. This unavoidably causes a slight 784 * jittering in the image (even with double-buffering). 785 */ 786 if (pDstBox->x1 < 0) 787 { 788 *SrcLeft = ((-pDstBox->x1 * SrcW) / *DstW) & ~1; 789 pDstBox->x1 = 0; 790 } 791 792 if (pDstBox->y1 < 0) 793 { 794 *SrcTop = (-pDstBox->y1 * SrcH) / *DstH; 795 pDstBox->y1 = 0; 796 797 switch (ImageID) 798 { 799 case FOURCC_YV12: 800 case FOURCC_I420: 801 *SrcTop = (*SrcTop + 1) & ~1; 802 break; 803 804 default: 805 break; 806 } 807 } 808 809 return TRUE; 810 } 811 812 #ifdef ATIMove32 813 814 /* A faster intercept */ 815 #undef xf86XVCopyPacked 816 #define xf86XVCopyPacked ATIMach64XVCopyPacked 817 818 static void 819 ATIMach64XVCopyPacked 820 ( 821 const CARD8 *pSrc, 822 CARD8 *pDst, 823 int SrcPitch, 824 int DstPitch, 825 int Height, 826 int Width 827 ) 828 { 829 Width >>= 1; 830 while (--Height >= 0) 831 { 832 ATIMove32(pDst, pSrc, Width); 833 pSrc += SrcPitch; 834 pDst += DstPitch; 835 } 836 } 837 838 #endif 839 840 /* 841 * ATIMach64DisplayVideo -- 842 * 843 * This function programmes Mach64 registers needed to display a video. 844 */ 845 static void 846 ATIMach64DisplayVideo 847 ( 848 ScrnInfoPtr pScreenInfo, 849 ATIPtr pATI, 850 BoxPtr pDstBox, 851 int ImageID, 852 int Offset, 853 int Pitch, 854 short SrcW, 855 short SrcH, 856 short DstW, 857 short DstH, 858 short Width, 859 short Height 860 ) 861 { 862 DisplayModePtr pMode = pScreenInfo->currentMode; 863 CARD32 HScale, VScale; 864 865 if (pMode->VScan > 1) 866 { 867 pDstBox->y1 *= pMode->VScan; 868 pDstBox->y2 *= pMode->VScan; 869 } 870 if (pMode->Flags & V_DBLSCAN) 871 { 872 pDstBox->y1 <<= 1; 873 pDstBox->y2 <<= 1; 874 } 875 876 /* Recalculate overlay scale factors */ 877 ATIMach64ScaleVideo(pATI, pMode, SrcW, SrcH, DstW, DstH, &HScale, &VScale); 878 879 pATI->NewHW.video_format &= ~SCALER_IN; 880 if (ImageID == FOURCC_UYVY) 881 pATI->NewHW.video_format |= SCALER_IN_YVYU422; 882 else 883 pATI->NewHW.video_format |= SCALER_IN_VYUY422; 884 885 ATIMach64WaitForFIFO(pATI, 8); 886 outq(OVERLAY_Y_X_START, OVERLAY_Y_X_END, OVERLAY_LOCK_START | 887 SetWord(pDstBox->x1, 1) | SetWord(pDstBox->y1, 0), 888 SetWord(pDstBox->x2 - 1, 1) | SetWord(pDstBox->y2 - 1, 0)); 889 outf(OVERLAY_SCALE_INC, SetWord(HScale, 1) | SetWord(VScale, 0)); 890 outf(SCALER_HEIGHT_WIDTH, SetWord(Width, 1) | SetWord(Height, 0)); 891 outf(VIDEO_FORMAT, pATI->NewHW.video_format); 892 893 if (pATI->Chip < ATI_CHIP_264VTB) 894 { 895 outf(BUF0_OFFSET, Offset); 896 outf(BUF0_PITCH, Pitch); 897 } 898 else 899 { 900 outf(SCALER_BUF0_OFFSET, Offset); 901 outf(SCALER_BUF_PITCH, Pitch); 902 } 903 904 outf(OVERLAY_SCALE_CNTL, SCALE_PIX_EXPAND | OVERLAY_EN | SCALE_EN); 905 } 906 907 /* 908 * ATIMach64PutImage -- 909 * 910 * This function is called to put a video image on the screen. 911 */ 912 static int 913 ATIMach64PutImage 914 ( 915 ScrnInfoPtr pScreenInfo, 916 short SrcX, 917 short SrcY, 918 short DstX, 919 short DstY, 920 short SrcW, 921 short SrcH, 922 short DstW, 923 short DstH, 924 int ImageID, 925 unsigned char *Buffer, 926 short Width, 927 short Height, 928 Bool Synchronise, 929 RegionPtr pClip, 930 pointer Data, 931 DrawablePtr pDraw 932 ) 933 { 934 ATIPtr pATI = Data; 935 ScreenPtr pScreen; 936 INT32 SrcX1, SrcX2, SrcY1, SrcY2; 937 BoxRec DstBox; 938 int SrcPitch, SrcPitchUV, DstPitch, DstSize; 939 int SrcTop, SrcLeft, DstWidth, DstHeight; 940 int Top, Bottom, Left, Right, nLine, nPixel, Offset; 941 int OffsetV, OffsetU; 942 int XVOffset; 943 int tmp; 944 CARD8 *pDst; 945 946 if (pATI->ActiveSurface) 947 return Success; 948 949 if (DstH < 16) 950 return Success; 951 952 if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID, 953 SrcX, SrcY, SrcW, SrcH, 954 DstX, DstY, &DstW, &DstH, 955 Width, Height, pClip, &DstBox, 956 &SrcX1, &SrcX2, &SrcY1, &SrcY2, 957 &SrcLeft, &SrcTop)) 958 return Success; 959 960 pScreen = pScreenInfo->pScreen; 961 962 DstWidth = Width - SrcLeft; 963 DstHeight = Height - SrcTop; 964 965 /* 966 * Allocate an offscreen buffer for the entire source, even though only a 967 * subset of the source will be copied into it. 968 */ 969 DstPitch = /* bytes */ 970 (DstWidth + DstWidth + 15) & ~15; 971 DstSize = /* bytes */ 972 (DstPitch * DstHeight); 973 974 pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, 975 (pATI->DoubleBuffer + 1) * DstSize, &XVOffset, pATI); 976 977 if (!pATI->pXVBuffer) 978 { 979 if (!pATI->DoubleBuffer) 980 return BadAlloc; 981 982 pATI->pXVBuffer = 983 ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, DstSize, &XVOffset, pATI); 984 985 if (!pATI->pXVBuffer) 986 return BadAlloc; 987 988 xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 989 "Video image double-buffering downgraded to single-buffering\n due" 990 " to insufficient video memory.\n"); 991 pATI->DoubleBuffer = pATI->CurrentBuffer = 0; 992 } 993 else 994 { 995 /* Possibly switch buffers */ 996 pATI->CurrentBuffer = pATI->DoubleBuffer - pATI->CurrentBuffer; 997 } 998 999 /* Synchronise video memory accesses */ 1000 ATIMach64Sync(pScreenInfo); 1001 1002 Offset = XVOffset + pATI->CurrentBuffer * DstSize; 1003 pDst = pATI->pMemoryLE; 1004 pDst += Offset; 1005 1006 switch (ImageID) 1007 { 1008 case FOURCC_YV12: 1009 case FOURCC_I420: 1010 Left = (SrcX1 >> 16) & ~1; 1011 Right = ((SrcX2 + 0x1FFFF) >> 16) & ~1; 1012 Top = (SrcY1 >> 16) & ~1; 1013 Bottom = ((SrcY2 + 0x1FFFF) >> 16) & ~1; 1014 1015 if ((Right < Width) && ((SrcX1 & 0x1FFFF) <= (SrcX2 & 0x1FFFF))) 1016 Right += 2; 1017 if ((Bottom < Height) && ((SrcY1 & 0x1FFFF) <= (SrcY2 & 0x1FFFF))) 1018 Bottom += 2; 1019 1020 nPixel = Right - Left; 1021 nLine = Bottom - Top; 1022 1023 SrcPitch = (Width + 3) & ~3; 1024 OffsetV = SrcPitch * Height; 1025 SrcPitchUV = ((Width >> 1) + 3) & ~3; 1026 OffsetU = ((Height >> 1) * SrcPitchUV) + OffsetV; 1027 1028 tmp = ((Top >> 1) * SrcPitchUV) + (Left >> 1); 1029 OffsetV += tmp; 1030 OffsetU += tmp; 1031 1032 if (ImageID == FOURCC_I420) 1033 { 1034 tmp = OffsetV; 1035 OffsetV = OffsetU; 1036 OffsetU = tmp; 1037 } 1038 1039 pDst += ((Top - SrcTop) * DstPitch) + ((Left - SrcLeft) << 1); 1040 1041 xf86XVCopyYUV12ToPacked(Buffer + (Top * SrcPitch) + Left, 1042 Buffer + OffsetV, Buffer + OffsetU, pDst, SrcPitch, SrcPitchUV, 1043 DstPitch, nLine, nPixel); 1044 break; 1045 1046 case FOURCC_UYVY: 1047 case FOURCC_YUY2: 1048 default: 1049 Left = (SrcX1 >> 16) & ~1; 1050 Right = ((SrcX2 + 0x1FFFF) >> 16) & ~1; 1051 Top = SrcY1 >> 16; 1052 Bottom = (SrcY2 + 0x0FFFF) >> 16; 1053 1054 if ((Right < Width) && ((SrcX1 & 0x1FFFF) <= (SrcX2 & 0x1FFFF))) 1055 Right += 2; 1056 if ((Bottom < Height) && ((SrcY1 & 0x0FFFF) <= (SrcY2 & 0x0FFFF))) 1057 Bottom++; 1058 1059 nPixel = Right - Left; 1060 nLine = Bottom - Top; 1061 1062 SrcPitch = Width << 1; 1063 Buffer += (Top * SrcPitch) + (Left << 1); 1064 pDst += ((Top - SrcTop) * DstPitch) + ((Left - SrcLeft) << 1); 1065 1066 xf86XVCopyPacked(Buffer, pDst, SrcPitch, DstPitch, nLine, nPixel); 1067 break; 1068 } 1069 1070 if (!REGION_EQUAL(pScreen, &pATI->VideoClip, pClip)) 1071 { 1072 REGION_COPY(pScreen, &pATI->VideoClip, pClip); 1073 if (pATI->AutoPaint) 1074 xf86XVFillKeyHelper(pScreen, pATI->NewHW.overlay_graphics_key_clr, 1075 pClip); 1076 } 1077 1078 ATIMach64DisplayVideo(pScreenInfo, pATI, &DstBox, ImageID, 1079 Offset, DstPitch / 2, SrcW, SrcH, DstW, DstH, DstWidth, DstHeight); 1080 1081 return Success; 1082 } 1083 1084 /* 1085 * ATIMach64AllocateSurface -- 1086 * 1087 * This function allocates an offscreen buffer (called a "surface") for use by 1088 * an external driver such as 'v4l'. 1089 */ 1090 static int 1091 ATIMach64AllocateSurface 1092 ( 1093 ScrnInfoPtr pScreenInfo, 1094 int ImageID, 1095 unsigned short Width, 1096 unsigned short Height, 1097 XF86SurfacePtr pSurface 1098 ) 1099 { 1100 ScreenPtr pScreen; 1101 ATIPtr pATI = ATIPTR(pScreenInfo); 1102 int XVOffset; 1103 1104 if (pATI->ActiveSurface) 1105 return BadAlloc; 1106 1107 if ((Height <= 0) || (Height > 2048) || (Width <= 0) || (Width > 768) || 1108 ((Width > 384) && (pATI->Chip < ATI_CHIP_264VTB)) || 1109 ((Width > 720) && (pATI->Chip < ATI_CHIP_264GTPRO || 1110 pATI->Chip > ATI_CHIP_264LTPRO))) 1111 return BadValue; 1112 1113 Width = (Width + 1) & ~1; 1114 pATI->SurfacePitch = ((Width << 1) + 15) & ~15; 1115 1116 pScreen = pScreenInfo->pScreen; 1117 1118 pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, 1119 Height * pATI->SurfacePitch, &XVOffset, pATI); 1120 if (!pATI->pXVBuffer) 1121 return BadAlloc; 1122 1123 pATI->SurfaceOffset = XVOffset; 1124 1125 pSurface->pScrn = pScreenInfo; 1126 pSurface->id = ImageID; 1127 pSurface->width = Width; 1128 pSurface->height = Height; 1129 pSurface->pitches = &pATI->SurfacePitch; 1130 pSurface->offsets = &pATI->SurfaceOffset; 1131 pSurface->devPrivate.ptr = pATI; 1132 1133 /* Stop the video */ 1134 outf(OVERLAY_SCALE_CNTL, SCALE_EN); 1135 REGION_EMPTY(pScreen, &pATI->VideoClip); 1136 pATI->ActiveSurface = TRUE; 1137 1138 return Success; 1139 } 1140 1141 /* 1142 * ATIMach64FreeSurface -- 1143 * 1144 * This function called to free a surface's offscreen buffer. 1145 */ 1146 static int 1147 ATIMach64FreeSurface 1148 ( 1149 XF86SurfacePtr pSurface 1150 ) 1151 { 1152 ATIPtr pATI = pSurface->devPrivate.ptr; 1153 1154 if (!pATI->ActiveSurface) 1155 return Success; 1156 1157 outf(OVERLAY_SCALE_CNTL, SCALE_EN); 1158 ATIMach64XVMemFree(pSurface->pScrn->pScreen, pATI->pXVBuffer, pATI); 1159 pATI->pXVBuffer = NULL; 1160 pATI->ActiveSurface = FALSE; 1161 1162 return Success; 1163 } 1164 1165 /* 1166 * ATIMach64DisplaySurface -- 1167 * 1168 * This function is called to display a video surface. 1169 */ 1170 static int 1171 ATIMach64DisplaySurface 1172 ( 1173 XF86SurfacePtr pSurface, 1174 short SrcX, 1175 short SrcY, 1176 short DstX, 1177 short DstY, 1178 short SrcW, 1179 short SrcH, 1180 short DstW, 1181 short DstH, 1182 RegionPtr pClip 1183 ) 1184 { 1185 ATIPtr pATI = pSurface->devPrivate.ptr; 1186 ScrnInfoPtr pScreenInfo; 1187 int ImageID; 1188 short Width, Height; 1189 BoxRec DstBox; 1190 INT32 SrcX1, SrcX2, SrcY1, SrcY2; 1191 int SrcLeft, SrcTop, SrcPitch, Offset; 1192 1193 if (!pATI->ActiveSurface) 1194 return Success; 1195 1196 pScreenInfo = pSurface->pScrn; 1197 ImageID = pSurface->id; 1198 Width = pSurface->width; 1199 Height = pSurface->height; 1200 1201 if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID, 1202 SrcX, SrcY, SrcW, SrcH, 1203 DstX, DstY, &DstW, &DstH, 1204 Width, Height, pClip, &DstBox, 1205 &SrcX1, &SrcX2, &SrcY1, &SrcY2, 1206 &SrcLeft, &SrcTop)) 1207 return Success; 1208 1209 xf86XVFillKeyHelper(pScreenInfo->pScreen, 1210 pATI->NewHW.overlay_graphics_key_clr, pClip); 1211 1212 SrcPitch = pSurface->pitches[0]; 1213 Offset = pSurface->offsets[0] + (SrcTop * SrcPitch) + (SrcLeft << 1); 1214 ATIMach64DisplayVideo(pScreenInfo, pATI, &DstBox, ImageID, 1215 Offset, SrcPitch, SrcW, SrcH, DstW, DstH, Width, Height); 1216 1217 return Success; 1218 } 1219 1220 /* 1221 * ATIMach64StopSurface -- 1222 * 1223 * This function is called to stop the overlaid display of a video surface. 1224 */ 1225 static int 1226 ATIMach64StopSurface 1227 ( 1228 XF86SurfacePtr pSurface 1229 ) 1230 { 1231 ATIPtr pATI = pSurface->devPrivate.ptr; 1232 1233 if (pATI->ActiveSurface) 1234 outf(OVERLAY_SCALE_CNTL, SCALE_EN); 1235 1236 return Success; 1237 } 1238 1239 /* 1240 * ATIMach64GetSurfaceAttribute -- 1241 * 1242 * Retrieve the value of an XVideo attribute. 1243 */ 1244 static int 1245 ATIMach64GetSurfaceAttribute 1246 ( 1247 ScrnInfoPtr pScreenInfo, 1248 Atom AttributeID, 1249 INT32 *Value 1250 ) 1251 { 1252 return ATIMach64GetPortAttribute(pScreenInfo, AttributeID, Value, 1253 ATIPTR(pScreenInfo)); 1254 } 1255 1256 /* 1257 * ATIMach64SetSurfaceAttribute 1258 * 1259 * Set the value of an XVideo attribute. 1260 */ 1261 static int 1262 ATIMach64SetSurfaceAttribute 1263 ( 1264 ScrnInfoPtr pScreenInfo, 1265 Atom AttributeID, 1266 INT32 Value 1267 ) 1268 { 1269 return ATIMach64SetPortAttribute(pScreenInfo, AttributeID, Value, 1270 ATIPTR(pScreenInfo)); 1271 } 1272 1273 /* XVideo surface registration data */ 1274 static XF86OffscreenImageRec ATIMach64Surface[] = 1275 { 1276 { 1277 &ATIMach64Image[0], /* YUY2 */ 1278 VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, 1279 ATIMach64AllocateSurface, 1280 ATIMach64FreeSurface, 1281 ATIMach64DisplaySurface, 1282 ATIMach64StopSurface, 1283 ATIMach64GetSurfaceAttribute, 1284 ATIMach64SetSurfaceAttribute, 1285 720, 2048, 1286 nATIMach64Attribute - 1, /* No double-buffering */ 1287 ATIMach64Attribute 1288 }, 1289 { 1290 &ATIMach64Image[1], /* UYVY */ 1291 VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, 1292 ATIMach64AllocateSurface, 1293 ATIMach64FreeSurface, 1294 ATIMach64DisplaySurface, 1295 ATIMach64StopSurface, 1296 ATIMach64GetSurfaceAttribute, 1297 ATIMach64SetSurfaceAttribute, 1298 720, 2048, 1299 nATIMach64Attribute - 1, /* No double-buffering */ 1300 ATIMach64Attribute 1301 } 1302 }; 1303 #define nATIMach64Surface NumberOf(ATIMach64Surface) 1304 1305 /* 1306 * ATIMach64XVInitialiseAdaptor -- 1307 * 1308 * This function is called to make a Mach64's hardware overlay support 1309 * available as an XVideo adaptor. 1310 */ 1311 static int 1312 ATIMach64XVInitialiseAdaptor 1313 ( 1314 ScrnInfoPtr pScreenInfo, 1315 XF86VideoAdaptorPtr **pppAdaptor 1316 ) 1317 { 1318 ScreenPtr pScreen = xf86ScrnToScreen(pScreenInfo); 1319 ATIPtr pATI = ATIPTR(pScreenInfo); 1320 XF86VideoAdaptorPtr *ppAdaptor = NULL; 1321 XF86VideoAdaptorPtr pAdaptor; 1322 1323 XF86VideoEncodingPtr enc = &(ATIMach64VideoEncoding[0]); 1324 XF86OffscreenImagePtr surf0 = &(ATIMach64Surface[0]); 1325 XF86OffscreenImagePtr surf1 = &(ATIMach64Surface[1]); 1326 1327 if (xf86NameCmp(pScreenInfo->driverName, MACH64_DRIVER_NAME) != 0) 1328 return 0; 1329 1330 if (pppAdaptor) 1331 *pppAdaptor = NULL; 1332 1333 if (!pATI->Block1Base) 1334 return 0; 1335 1336 if (!(pAdaptor = xf86XVAllocateVideoAdaptorRec(pScreenInfo))) 1337 return 0; 1338 1339 ppAdaptor = XNFalloc(sizeof(pAdaptor)); 1340 ppAdaptor[0] = pAdaptor; 1341 1342 pAdaptor->nPorts = 1; 1343 pAdaptor->pPortPrivates = pATI->XVPortPrivate; 1344 pATI->XVPortPrivate[0].ptr = pATI; 1345 1346 pAdaptor->type = XvInputMask | XvImageMask | XvWindowMask; 1347 pAdaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1348 pAdaptor->name = "ATI Mach64 Back-end Overlay Scaler"; 1349 1350 if (pATI->Chip < ATI_CHIP_264VTB) 1351 { 1352 enc->width = 384; 1353 } 1354 else if (pATI->Chip < ATI_CHIP_264GTPRO || 1355 pATI->Chip > ATI_CHIP_264LTPRO) 1356 { 1357 enc->width = 720; /* default */ 1358 } 1359 else 1360 { 1361 enc->width = 768; 1362 } 1363 pAdaptor->nEncodings = nATIMach64VideoEncoding; 1364 pAdaptor->pEncodings = ATIMach64VideoEncoding; 1365 1366 pAdaptor->nFormats = nATIMach64VideoFormat; 1367 pAdaptor->pFormats = ATIMach64VideoFormat; 1368 1369 pAdaptor->nAttributes = nATIMach64Attribute; 1370 pAdaptor->pAttributes = ATIMach64Attribute; 1371 1372 if (pATI->Chip < ATI_CHIP_264GTPRO) 1373 { 1374 /* Older controllers don't have brightness or saturation controls */ 1375 pAdaptor->nAttributes -= 4; 1376 pAdaptor->pAttributes += 4; 1377 } 1378 1379 pAdaptor->nImages = nATIMach64Image; 1380 pAdaptor->pImages = ATIMach64Image; 1381 1382 pAdaptor->StopVideo = ATIMach64StopVideo; 1383 pAdaptor->SetPortAttribute = ATIMach64SetPortAttribute; 1384 pAdaptor->GetPortAttribute = ATIMach64GetPortAttribute; 1385 pAdaptor->QueryBestSize = ATIMach64QueryBestSize; 1386 pAdaptor->PutImage = ATIMach64PutImage; 1387 pAdaptor->QueryImageAttributes = ATIMach64QueryImageAttributes; 1388 1389 REGION_NULL(pScreen, &pATI->VideoClip); 1390 pATI->ActiveSurface = FALSE; 1391 1392 if (ATIMach64XVAtomGeneration != serverGeneration) 1393 { 1394 int Index; 1395 1396 /* Refresh static data */ 1397 ATIMach64XVAtomGeneration = serverGeneration; 1398 1399 Index = nATIMach64Attribute - pAdaptor->nAttributes; 1400 for (; Index < nATIMach64Attribute; Index++) 1401 ATIMach64AttributeInfo[Index].AttributeID = 1402 MAKE_ATOM(ATIMach64Attribute[Index].name); 1403 } 1404 1405 ATIMach64SetDefaultAttributes(pATI, 0); 1406 1407 if (pATI->Chip < ATI_CHIP_264VTB) 1408 { 1409 surf0->max_width = 384; 1410 surf1->max_width = 384; 1411 } 1412 else if (pATI->Chip < ATI_CHIP_264GTPRO || 1413 pATI->Chip > ATI_CHIP_264LTPRO) 1414 { 1415 surf0->max_width = 720; /* default */ 1416 surf1->max_width = 720; 1417 } 1418 else 1419 { 1420 surf0->max_width = 768; 1421 surf1->max_width = 768; 1422 } 1423 1424 if (pATI->Chip < ATI_CHIP_264GTPRO) 1425 { 1426 /* No saturation nor brightness */ 1427 surf0->num_attributes -= 4; 1428 surf1->num_attributes -= 4; 1429 surf0->attributes += 4; 1430 surf1->attributes += 4; 1431 } 1432 xf86XVRegisterOffscreenImages(pScreen, ATIMach64Surface, nATIMach64Surface); 1433 1434 if (pppAdaptor) 1435 *pppAdaptor = ppAdaptor; 1436 else { 1437 free(ppAdaptor[0]); 1438 free(ppAdaptor); 1439 } 1440 1441 return 1; 1442 } 1443 1444 /* 1445 * ATIXVPreInit -- 1446 * 1447 * This function is called by ATIPreInit() to set up the environment required 1448 * to support the XVideo extension. 1449 */ 1450 void 1451 ATIXVPreInit 1452 ( 1453 ATIPtr pATI 1454 ) 1455 { 1456 (void)xf86XVRegisterGenericAdaptorDriver(ATIMach64XVInitialiseAdaptor); 1457 } 1458 1459 /* 1460 * ATIXVFreeAdaptorInfo -- 1461 * 1462 * Free XVideo adaptor information. 1463 */ 1464 static void 1465 ATIXVFreeAdaptorInfo 1466 ( 1467 XF86VideoAdaptorPtr *ppAdaptor, 1468 int nAdaptor 1469 ) 1470 { 1471 if (!ppAdaptor) 1472 return; 1473 1474 while (nAdaptor > 0) 1475 free(ppAdaptor[--nAdaptor]); 1476 1477 free(ppAdaptor); 1478 } 1479 1480 /* 1481 * ATIInitializeXVideo -- 1482 * 1483 * This function is called to initialise XVideo extension support on a screen. 1484 */ 1485 Bool 1486 ATIInitializeXVideo 1487 ( 1488 ScreenPtr pScreen, 1489 ScrnInfoPtr pScreenInfo, 1490 ATIPtr pATI 1491 ) 1492 { 1493 XF86VideoAdaptorPtr *ppAdaptor; 1494 int nAdaptor; 1495 Bool result; 1496 1497 pScreenInfo->memPhysBase = pATI->LinearBase; 1498 pScreenInfo->fbOffset = 0; 1499 1500 nAdaptor = xf86XVListGenericAdaptors(pScreenInfo, &ppAdaptor); 1501 result = xf86XVScreenInit(pScreen, ppAdaptor, nAdaptor); 1502 1503 ATIXVFreeAdaptorInfo(ppAdaptor, nAdaptor); 1504 1505 return result; 1506 } 1507 1508 /* 1509 * ATIMach64CloseXVideo -- 1510 * 1511 * This function is called during screen termination to clean up after 1512 * initialisation of Mach64 XVideo support. 1513 */ 1514 void 1515 ATICloseXVideo 1516 ( 1517 ScreenPtr pScreen, 1518 ScrnInfoPtr pScreenInfo, 1519 ATIPtr pATI 1520 ) 1521 { 1522 if (!pATI->Block1Base) 1523 return; 1524 1525 ATIMach64StopVideo(pScreenInfo, pATI, TRUE); 1526 1527 REGION_UNINIT(pScreen, &pATI->VideoClip); 1528 } 1529 1530 /* Functions for offscreen memory management */ 1531 1532 1533 static pointer 1534 ATIMach64XVMemAlloc 1535 ( 1536 ScreenPtr pScreen, 1537 pointer pVideo, 1538 int size, 1539 int *offset, 1540 ATIPtr pATI 1541 ) 1542 { 1543 #ifdef USE_EXA 1544 if (pATI->useEXA) { 1545 ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo; 1546 1547 if (area != NULL) { 1548 if (area->size >= size) { 1549 *offset = area->offset; 1550 return area; 1551 } 1552 1553 exaOffscreenFree(pScreen, area); 1554 } 1555 1556 area = exaOffscreenAlloc(pScreen, size, 64, TRUE, NULL, NULL); 1557 if (area != NULL) { 1558 *offset = area->offset; 1559 return area; 1560 } 1561 } 1562 #endif /* USE_EXA */ 1563 1564 1565 *offset = 0; 1566 return NULL; 1567 } 1568 1569 static void 1570 ATIMach64XVMemFree 1571 ( 1572 ScreenPtr pScreen, 1573 pointer pVideo, 1574 ATIPtr pATI 1575 ) 1576 { 1577 #ifdef USE_EXA 1578 if (pATI->useEXA) { 1579 ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo; 1580 1581 if (area != NULL) 1582 exaOffscreenFree(pScreen, area); 1583 } 1584 #endif /* USE_EXA */ 1585 1586 } 1587 1588