132b578d3Smrg/* 232b578d3Smrg * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 332b578d3Smrg * 432b578d3Smrg * Permission to use, copy, modify, distribute, and sell this software and its 532b578d3Smrg * documentation for any purpose is hereby granted without fee, provided that 632b578d3Smrg * the above copyright notice appear in all copies and that both that copyright 732b578d3Smrg * notice and this permission notice appear in supporting documentation, and 832b578d3Smrg * that the name of Marc Aurele La France not be used in advertising or 932b578d3Smrg * publicity pertaining to distribution of the software without specific, 1032b578d3Smrg * written prior permission. Marc Aurele La France makes no representations 1132b578d3Smrg * about the suitability of this software for any purpose. It is provided 1232b578d3Smrg * "as-is" without express or implied warranty. 1332b578d3Smrg * 1432b578d3Smrg * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1532b578d3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 1632b578d3Smrg * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1732b578d3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1832b578d3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1932b578d3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2032b578d3Smrg * PERFORMANCE OF THIS SOFTWARE. 2132b578d3Smrg */ 2232b578d3Smrg 2332b578d3Smrg#ifdef HAVE_CONFIG_H 2432b578d3Smrg#include "config.h" 2532b578d3Smrg#endif 2632b578d3Smrg 2732b578d3Smrg#include <string.h> 2832b578d3Smrg 2932b578d3Smrg#include "ati.h" 3032b578d3Smrg#include "atichip.h" 3132b578d3Smrg#include "atimach64accel.h" 3232b578d3Smrg#include "atimach64io.h" 3332b578d3Smrg#include "atixv.h" 34d31dbc53Smrg#include "atimach64version.h" 3532b578d3Smrg 3632b578d3Smrg#include <X11/extensions/Xv.h> 3732b578d3Smrg#include "fourcc.h" 3832b578d3Smrg#include "xf86xv.h" 3932b578d3Smrg 4032b578d3Smrg#define MAKE_ATOM(string) MakeAtom(string, strlen(string), TRUE) 4132b578d3Smrg#define MaxScale (CARD32)(CARD16)(-1) 4232b578d3Smrg 4332b578d3Smrgstatic unsigned long ATIMach64XVAtomGeneration = (unsigned long)(-1); 4432b578d3Smrg 4532b578d3Smrgstatic XF86VideoEncodingRec ATIMach64VideoEncoding[] = 4632b578d3Smrg{ 4732b578d3Smrg { 0, "XV_IMAGE", 720, 2048, {1, 1} } 4832b578d3Smrg}; 4932b578d3Smrg#define nATIMach64VideoEncoding NumberOf(ATIMach64VideoEncoding) 5032b578d3Smrg 5132b578d3Smrgstatic XF86VideoFormatRec ATIMach64VideoFormat[] = 5232b578d3Smrg{ 5332b578d3Smrg { 8, TrueColor}, 5432b578d3Smrg { 8, DirectColor}, 5532b578d3Smrg { 8, PseudoColor}, 5632b578d3Smrg { 8, GrayScale}, 5732b578d3Smrg { 8, StaticGray}, 5832b578d3Smrg { 8, StaticColor}, 5932b578d3Smrg {15, TrueColor}, 6032b578d3Smrg {16, TrueColor}, 6132b578d3Smrg {24, TrueColor}, 6232b578d3Smrg {15, DirectColor}, 6332b578d3Smrg {16, DirectColor}, 6432b578d3Smrg {24, DirectColor} 6532b578d3Smrg}; 6632b578d3Smrg#define nATIMach64VideoFormat NumberOf(ATIMach64VideoFormat) 6732b578d3Smrg 6832b578d3Smrgstatic XF86AttributeRec ATIMach64Attribute[] = 6932b578d3Smrg{ 7032b578d3Smrg /* These are only supported on the Rage Pro and later ... */ 7132b578d3Smrg { 7232b578d3Smrg XvSettable | XvGettable, 7332b578d3Smrg -1000, 1000, 7432b578d3Smrg "XV_SATURATION" 7532b578d3Smrg }, 7632b578d3Smrg { 7732b578d3Smrg XvSettable | XvGettable, 7832b578d3Smrg -1000, 1000, 7932b578d3Smrg "XV_BRIGHTNESS" 8032b578d3Smrg }, 8132b578d3Smrg { 8232b578d3Smrg XvSettable | XvGettable, 8332b578d3Smrg -1000, 1000, 8432b578d3Smrg "XV_COLOUR" 8532b578d3Smrg }, 8632b578d3Smrg { 8732b578d3Smrg XvSettable | XvGettable, 8832b578d3Smrg -1000, 1000, 8932b578d3Smrg "XV_COLOR" 9032b578d3Smrg }, 9132b578d3Smrg 9232b578d3Smrg /* Local attributes, odds and ends for compatibility, etc... */ 9332b578d3Smrg { 9432b578d3Smrg XvSettable | XvGettable, 9532b578d3Smrg 0, 1, 9632b578d3Smrg "XV_AUTOPAINT_COLOURKEY" 9732b578d3Smrg }, 9832b578d3Smrg { 9932b578d3Smrg XvSettable | XvGettable, 10032b578d3Smrg 0, 1, 10132b578d3Smrg "XV_AUTOPAINT_COLORKEY" 10232b578d3Smrg }, 10332b578d3Smrg { 10432b578d3Smrg XvSettable | XvGettable, 10532b578d3Smrg 0, (1 << 24) - 1, 10632b578d3Smrg "XV_COLOURKEY" 10732b578d3Smrg }, 10832b578d3Smrg { 10932b578d3Smrg XvSettable | XvGettable, 11032b578d3Smrg 0, (1 << 24) - 1, 11132b578d3Smrg "XV_COLORKEY" 11232b578d3Smrg }, 11332b578d3Smrg { 11432b578d3Smrg XvSettable | XvGettable, 11532b578d3Smrg 0, (1 << 24) - 1, 11632b578d3Smrg "XV_COLOURKEY_MASK" 11732b578d3Smrg }, 11832b578d3Smrg { 11932b578d3Smrg XvSettable | XvGettable, 12032b578d3Smrg 0, (1 << 24) - 1, 12132b578d3Smrg "XV_COLORKEY_MASK" 12232b578d3Smrg }, 12332b578d3Smrg { 12432b578d3Smrg XvSettable, 12532b578d3Smrg 0, 0, 12632b578d3Smrg "XV_SET_DEFAULTS" 12732b578d3Smrg }, 12832b578d3Smrg { /* Keep last */ 12932b578d3Smrg XvSettable | XvGettable, 13032b578d3Smrg 0, 1, 13132b578d3Smrg "XV_DOUBLE_BUFFER" 13232b578d3Smrg } 13332b578d3Smrg}; 13432b578d3Smrg#define nATIMach64Attribute NumberOf(ATIMach64Attribute) 13532b578d3Smrg 13632b578d3Smrgstatic XF86ImageRec ATIMach64Image[] = 13732b578d3Smrg{ 13832b578d3Smrg XVIMAGE_YUY2, 13932b578d3Smrg XVIMAGE_UYVY, 14032b578d3Smrg XVIMAGE_YV12, 14132b578d3Smrg XVIMAGE_I420 14232b578d3Smrg}; 14332b578d3Smrg#define nATIMach64Image NumberOf(ATIMach64Image) 14432b578d3Smrg 14532b578d3Smrg/* A local XVideo adaptor attribute record */ 14632b578d3Smrgtypedef struct _ATIMach64Attribute 14732b578d3Smrg{ 14832b578d3Smrg Atom AttributeID; 14932b578d3Smrg INT32 MaxValue; /* ... for the hardware */ 15032b578d3Smrg void (*SetAttribute) (ATIPtr, INT32); 15132b578d3Smrg INT32 (*GetAttribute) (ATIPtr); 15232b578d3Smrg} ATIMach64AttributeRec, *ATIMach64AttributePtr; 15332b578d3Smrg 15432b578d3Smrg/* Functions to get/set XVideo adaptor attributes */ 15532b578d3Smrg 15632b578d3Smrgstatic void 15732b578d3SmrgATIMach64SetSaturationAttribute 15832b578d3Smrg( 15932b578d3Smrg ATIPtr pATI, 16032b578d3Smrg INT32 Value 16132b578d3Smrg) 16232b578d3Smrg{ 16332b578d3Smrg /* Set the register */ 16432b578d3Smrg pATI->NewHW.scaler_colour_cntl &= 16532b578d3Smrg ~(SCALE_SATURATION_U | SCALE_SATURATION_V); 16632b578d3Smrg pATI->NewHW.scaler_colour_cntl |= SetBits(Value, SCALE_SATURATION_U) | 16732b578d3Smrg SetBits(Value, SCALE_SATURATION_V); 16832b578d3Smrg outf(SCALER_COLOUR_CNTL, pATI->NewHW.scaler_colour_cntl); 16932b578d3Smrg} 17032b578d3Smrg 17132b578d3Smrgstatic INT32 17232b578d3SmrgATIMach64GetSaturationAttribute 17332b578d3Smrg( 17432b578d3Smrg ATIPtr pATI 17532b578d3Smrg) 17632b578d3Smrg{ 17732b578d3Smrg return (INT32)GetBits(pATI->NewHW.scaler_colour_cntl, SCALE_SATURATION_U); 17832b578d3Smrg} 17932b578d3Smrg 18032b578d3Smrgstatic void 18132b578d3SmrgATIMach64SetBrightnessAttribute 18232b578d3Smrg( 18332b578d3Smrg ATIPtr pATI, 18432b578d3Smrg INT32 Value 18532b578d3Smrg) 18632b578d3Smrg{ 18732b578d3Smrg /* Set the register */ 18832b578d3Smrg pATI->NewHW.scaler_colour_cntl &= ~SCALE_BRIGHTNESS; 18932b578d3Smrg pATI->NewHW.scaler_colour_cntl |= SetBits(Value, SCALE_BRIGHTNESS); 19032b578d3Smrg outf(SCALER_COLOUR_CNTL, pATI->NewHW.scaler_colour_cntl); 19132b578d3Smrg} 19232b578d3Smrg 19332b578d3Smrgstatic INT32 19432b578d3SmrgATIMach64GetBrightnessAttribute 19532b578d3Smrg( 19632b578d3Smrg ATIPtr pATI 19732b578d3Smrg) 19832b578d3Smrg{ 19932b578d3Smrg return (INT32)GetBits(pATI->NewHW.scaler_colour_cntl, SCALE_BRIGHTNESS); 20032b578d3Smrg} 20132b578d3Smrg 20232b578d3Smrgstatic void 20332b578d3SmrgATIMach64SetDoubleBufferAttribute 20432b578d3Smrg( 20532b578d3Smrg ATIPtr pATI, 20632b578d3Smrg INT32 Value 20732b578d3Smrg) 20832b578d3Smrg{ 20932b578d3Smrg pATI->DoubleBuffer = Value; 21032b578d3Smrg} 21132b578d3Smrg 21232b578d3Smrgstatic INT32 21332b578d3SmrgATIMach64GetDoubleBufferAttribute 21432b578d3Smrg( 21532b578d3Smrg ATIPtr pATI 21632b578d3Smrg) 21732b578d3Smrg{ 21832b578d3Smrg return (int)pATI->DoubleBuffer; 21932b578d3Smrg} 22032b578d3Smrg 22132b578d3Smrgstatic void 22232b578d3SmrgATIMach64SetAutoPaintAttribute 22332b578d3Smrg( 22432b578d3Smrg ATIPtr pATI, 22532b578d3Smrg INT32 Value 22632b578d3Smrg) 22732b578d3Smrg{ 22832b578d3Smrg pATI->AutoPaint = Value; 22932b578d3Smrg} 23032b578d3Smrg 23132b578d3Smrgstatic INT32 23232b578d3SmrgATIMach64GetAutoPaintAttribute 23332b578d3Smrg( 23432b578d3Smrg ATIPtr pATI 23532b578d3Smrg) 23632b578d3Smrg{ 23732b578d3Smrg return (int)pATI->AutoPaint; 23832b578d3Smrg} 23932b578d3Smrg 24032b578d3Smrgstatic void 24132b578d3SmrgATIMach64SetColourKeyAttribute 24232b578d3Smrg( 24332b578d3Smrg ATIPtr pATI, 24432b578d3Smrg INT32 Value 24532b578d3Smrg) 24632b578d3Smrg{ 24732b578d3Smrg pATI->NewHW.overlay_graphics_key_clr = 24832b578d3Smrg (CARD32)(Value & ((1 << pATI->depth) - 1)); 24932b578d3Smrg outf(OVERLAY_GRAPHICS_KEY_CLR, pATI->NewHW.overlay_graphics_key_clr); 25032b578d3Smrg} 25132b578d3Smrg 25232b578d3Smrgstatic INT32 25332b578d3SmrgATIMach64GetColourKeyAttribute 25432b578d3Smrg( 25532b578d3Smrg ATIPtr pATI 25632b578d3Smrg) 25732b578d3Smrg{ 25832b578d3Smrg return (INT32)pATI->NewHW.overlay_graphics_key_clr; 25932b578d3Smrg} 26032b578d3Smrg 26132b578d3Smrgstatic void 26232b578d3SmrgATIMach64SetColourKeyMaskAttribute 26332b578d3Smrg( 26432b578d3Smrg ATIPtr pATI, 26532b578d3Smrg INT32 Value 26632b578d3Smrg) 26732b578d3Smrg{ 26832b578d3Smrg pATI->NewHW.overlay_graphics_key_msk = 26932b578d3Smrg (CARD32)(Value & ((1 << pATI->depth) - 1)); 27032b578d3Smrg outf(OVERLAY_GRAPHICS_KEY_MSK, pATI->NewHW.overlay_graphics_key_msk); 27132b578d3Smrg} 27232b578d3Smrg 27332b578d3Smrgstatic INT32 27432b578d3SmrgATIMach64GetColourKeyMaskAttribute 27532b578d3Smrg( 27632b578d3Smrg ATIPtr pATI 27732b578d3Smrg) 27832b578d3Smrg{ 27932b578d3Smrg return (INT32)pATI->NewHW.overlay_graphics_key_msk; 28032b578d3Smrg} 28132b578d3Smrg 28232b578d3Smrg/* 28332b578d3Smrg * ATIMach64SetDefaultAttributes -- 28432b578d3Smrg * 28532b578d3Smrg * This function calls other functions to set default values for the various 28632b578d3Smrg * attributes of an XVideo port. 28732b578d3Smrg */ 28832b578d3Smrgstatic void 28932b578d3SmrgATIMach64SetDefaultAttributes 29032b578d3Smrg( 29132b578d3Smrg ATIPtr pATI, 29232b578d3Smrg INT32 Value 29332b578d3Smrg) 29432b578d3Smrg{ 29532b578d3Smrg ATIMach64SetAutoPaintAttribute(pATI, TRUE); 29632b578d3Smrg ATIMach64SetDoubleBufferAttribute(pATI, FALSE); 29732b578d3Smrg ATIMach64SetColourKeyMaskAttribute(pATI, (1 << pATI->depth) - 1); 29832b578d3Smrg ATIMach64SetColourKeyAttribute(pATI, (3 << ((2 * pATI->depth) / 3)) | 29932b578d3Smrg (2 << ((1 * pATI->depth) / 3)) | 30032b578d3Smrg (1 << ((0 * pATI->depth) / 3))); 30132b578d3Smrg 30232b578d3Smrg if (pATI->Chip < ATI_CHIP_264GTPRO) 30332b578d3Smrg return; 30432b578d3Smrg 30532b578d3Smrg ATIMach64SetBrightnessAttribute(pATI, 32); 30632b578d3Smrg ATIMach64SetSaturationAttribute(pATI, 16); 30732b578d3Smrg} 30832b578d3Smrg 30932b578d3Smrg/* 3100b0ce0bfSmrg * There is a one-to-one correspondence between elements of the following array 31132b578d3Smrg * and those of ATIMach64Attribute. 31232b578d3Smrg */ 31332b578d3Smrgstatic ATIMach64AttributeRec ATIMach64AttributeInfo[nATIMach64Attribute] = 31432b578d3Smrg{ 31532b578d3Smrg { /* SATURATION */ 31632b578d3Smrg 0, 23, 31732b578d3Smrg ATIMach64SetSaturationAttribute, 31832b578d3Smrg ATIMach64GetSaturationAttribute 31932b578d3Smrg }, 32032b578d3Smrg { /* BRIGHTNESS */ 32132b578d3Smrg 0, 63, 32232b578d3Smrg ATIMach64SetBrightnessAttribute, 32332b578d3Smrg ATIMach64GetBrightnessAttribute 32432b578d3Smrg }, 32532b578d3Smrg { /* COLOUR */ 32632b578d3Smrg 0, 23, 32732b578d3Smrg ATIMach64SetSaturationAttribute, 32832b578d3Smrg ATIMach64GetSaturationAttribute 32932b578d3Smrg }, 33032b578d3Smrg { /* COLOR */ 33132b578d3Smrg 0, 23, 33232b578d3Smrg ATIMach64SetSaturationAttribute, 33332b578d3Smrg ATIMach64GetSaturationAttribute 33432b578d3Smrg }, 33532b578d3Smrg { /* AUTOPAINT_COLOURKEY */ 33632b578d3Smrg 0, 1, 33732b578d3Smrg ATIMach64SetAutoPaintAttribute, 33832b578d3Smrg ATIMach64GetAutoPaintAttribute 33932b578d3Smrg }, 34032b578d3Smrg { /* AUTOPAINT_COLORKEY */ 34132b578d3Smrg 0, 1, 34232b578d3Smrg ATIMach64SetAutoPaintAttribute, 34332b578d3Smrg ATIMach64GetAutoPaintAttribute 34432b578d3Smrg }, 34532b578d3Smrg { /* COLOURKEY */ 34632b578d3Smrg 0, (1 << 24) - 1, 34732b578d3Smrg ATIMach64SetColourKeyAttribute, 34832b578d3Smrg ATIMach64GetColourKeyAttribute 34932b578d3Smrg }, 35032b578d3Smrg { /* COLORKEY */ 35132b578d3Smrg 0, (1 << 24) - 1, 35232b578d3Smrg ATIMach64SetColourKeyAttribute, 35332b578d3Smrg ATIMach64GetColourKeyAttribute 35432b578d3Smrg }, 35532b578d3Smrg { /* COLOURKEY_MASK */ 35632b578d3Smrg 0, (1 << 24) - 1, 35732b578d3Smrg ATIMach64SetColourKeyMaskAttribute, 35832b578d3Smrg ATIMach64GetColourKeyMaskAttribute 35932b578d3Smrg }, 36032b578d3Smrg { /* COLORKEY_MASK */ 36132b578d3Smrg 0, (1 << 24) - 1, 36232b578d3Smrg ATIMach64SetColourKeyMaskAttribute, 36332b578d3Smrg ATIMach64GetColourKeyMaskAttribute 36432b578d3Smrg }, 36532b578d3Smrg { /* SET_DEFAULTS */ 36632b578d3Smrg 0, 0, 36732b578d3Smrg ATIMach64SetDefaultAttributes, 36832b578d3Smrg NULL 36932b578d3Smrg }, 37032b578d3Smrg { /* DOUBLE_BUFFER */ 37132b578d3Smrg 0, 1, 37232b578d3Smrg ATIMach64SetDoubleBufferAttribute, 37332b578d3Smrg ATIMach64GetDoubleBufferAttribute 37432b578d3Smrg } 37532b578d3Smrg}; 37632b578d3Smrg 37732b578d3Smrg/* 37832b578d3Smrg * ATIMach64FindAttribute -- 37932b578d3Smrg * 38032b578d3Smrg * This function is called to locate an Xv attribute's table entry. 38132b578d3Smrg */ 38232b578d3Smrgstatic int 38332b578d3SmrgATIMach64FindPortAttribute 38432b578d3Smrg( 38532b578d3Smrg ATIPtr pATI, 38632b578d3Smrg Atom AttributeID 38732b578d3Smrg) 38832b578d3Smrg{ 38932b578d3Smrg int iAttribute; 39032b578d3Smrg 39132b578d3Smrg if (pATI->Chip < ATI_CHIP_264GTPRO) 39232b578d3Smrg iAttribute = 4; 39332b578d3Smrg else 39432b578d3Smrg iAttribute = 0; 39532b578d3Smrg 39632b578d3Smrg for (; iAttribute < nATIMach64Attribute; iAttribute++) 39732b578d3Smrg if (AttributeID == ATIMach64AttributeInfo[iAttribute].AttributeID) 39832b578d3Smrg return iAttribute; 39932b578d3Smrg 40032b578d3Smrg return -1; 40132b578d3Smrg} 40232b578d3Smrg 40332b578d3Smrg/* 40432b578d3Smrg * ATIMach64SetPortAttribute -- 40532b578d3Smrg * 40632b578d3Smrg * This function sets the value of a particular port's attribute. 40732b578d3Smrg */ 40832b578d3Smrgstatic int 40932b578d3SmrgATIMach64SetPortAttribute 41032b578d3Smrg( 41132b578d3Smrg ScrnInfoPtr pScreenInfo, 41232b578d3Smrg Atom AttributeID, 41332b578d3Smrg INT32 Value, 41432b578d3Smrg pointer pATI 41532b578d3Smrg) 41632b578d3Smrg{ 41732b578d3Smrg INT32 Range; 41832b578d3Smrg int iAttribute; 41932b578d3Smrg 42032b578d3Smrg if (((iAttribute = ATIMach64FindPortAttribute(pATI, AttributeID)) < 0) || 42132b578d3Smrg !ATIMach64AttributeInfo[iAttribute].SetAttribute) 42232b578d3Smrg return BadMatch; 42332b578d3Smrg 42432b578d3Smrg Range = ATIMach64Attribute[iAttribute].max_value - 42532b578d3Smrg ATIMach64Attribute[iAttribute].min_value; 42632b578d3Smrg 42732b578d3Smrg if (Range >= 0) 42832b578d3Smrg { 42932b578d3Smrg /* Limit and scale the value */ 43032b578d3Smrg Value -= ATIMach64Attribute[iAttribute].min_value; 43132b578d3Smrg 43232b578d3Smrg if (Value < 0) 43332b578d3Smrg Value = 0; 43432b578d3Smrg else if (Value > Range) 43532b578d3Smrg Value = Range; 43632b578d3Smrg 43732b578d3Smrg if (Range != ATIMach64AttributeInfo[iAttribute].MaxValue) 43832b578d3Smrg { 43932b578d3Smrg if (ATIMach64AttributeInfo[iAttribute].MaxValue > 0) 44032b578d3Smrg Value *= ATIMach64AttributeInfo[iAttribute].MaxValue; 44132b578d3Smrg if (Range > 0) 44232b578d3Smrg Value /= Range; 44332b578d3Smrg } 44432b578d3Smrg } 44532b578d3Smrg 44632b578d3Smrg (*ATIMach64AttributeInfo[iAttribute].SetAttribute)(pATI, Value); 44732b578d3Smrg 44832b578d3Smrg return Success; 44932b578d3Smrg} 45032b578d3Smrg 45132b578d3Smrg/* 45232b578d3Smrg * ATIMach64SetPortAttribute -- 45332b578d3Smrg * 45432b578d3Smrg * This function retrieves the value of a particular port's attribute. 45532b578d3Smrg */ 45632b578d3Smrgstatic int 45732b578d3SmrgATIMach64GetPortAttribute 45832b578d3Smrg( 45932b578d3Smrg ScrnInfoPtr pScreenInfo, 46032b578d3Smrg Atom AttributeID, 46132b578d3Smrg INT32 *Value, 46232b578d3Smrg pointer pATI 46332b578d3Smrg) 46432b578d3Smrg{ 46532b578d3Smrg INT32 Range; 46632b578d3Smrg int iAttribute; 46732b578d3Smrg 46832b578d3Smrg if (!Value || 46932b578d3Smrg ((iAttribute = ATIMach64FindPortAttribute(pATI, AttributeID)) < 0) || 47032b578d3Smrg !ATIMach64AttributeInfo[iAttribute].GetAttribute) 47132b578d3Smrg return BadMatch; 47232b578d3Smrg 47332b578d3Smrg *Value = (*ATIMach64AttributeInfo[iAttribute].GetAttribute)(pATI); 47432b578d3Smrg 47532b578d3Smrg Range = ATIMach64Attribute[iAttribute].max_value - 47632b578d3Smrg ATIMach64Attribute[iAttribute].min_value; 47732b578d3Smrg 47832b578d3Smrg if (Range >= 0) 47932b578d3Smrg { 48032b578d3Smrg if (Range != ATIMach64AttributeInfo[iAttribute].MaxValue) 48132b578d3Smrg { 48232b578d3Smrg /* (Un-)scale the value */ 48332b578d3Smrg if (Range > 0) 48432b578d3Smrg *Value *= Range; 48532b578d3Smrg if (ATIMach64AttributeInfo[iAttribute].MaxValue > 0) 48632b578d3Smrg *Value /= ATIMach64AttributeInfo[iAttribute].MaxValue; 48732b578d3Smrg } 48832b578d3Smrg 48932b578d3Smrg *Value += ATIMach64Attribute[iAttribute].min_value; 49032b578d3Smrg } 49132b578d3Smrg 49232b578d3Smrg return Success; 49332b578d3Smrg} 49432b578d3Smrg 49532b578d3Smrgstatic pointer 49632b578d3SmrgATIMach64XVMemAlloc 49732b578d3Smrg( 49832b578d3Smrg ScreenPtr pScreen, 49932b578d3Smrg pointer pVideo, 50032b578d3Smrg int size, 50132b578d3Smrg int *offset, 50232b578d3Smrg ATIPtr pATI 50332b578d3Smrg); 50432b578d3Smrg 50532b578d3Smrgstatic void 50632b578d3SmrgATIMach64XVMemFree 50732b578d3Smrg( 50832b578d3Smrg ScreenPtr pScreen, 50932b578d3Smrg pointer pVideo, 51032b578d3Smrg ATIPtr pATI 51132b578d3Smrg); 51232b578d3Smrg 51332b578d3Smrg#ifdef USE_XAA 51432b578d3Smrg/* 51532b578d3Smrg * ATIMach64RemoveLinearCallback -- 51632b578d3Smrg * 51732b578d3Smrg * This is called by the framebuffer manager to release the offscreen XVideo 51832b578d3Smrg * buffer after the video has been temporarily disabled due to its window being 51932b578d3Smrg * iconified or completely occluded. 52032b578d3Smrg */ 52132b578d3Smrgstatic void 52232b578d3SmrgATIMach64RemoveLinearCallback 52332b578d3Smrg( 52432b578d3Smrg FBLinearPtr pLinear 52532b578d3Smrg) 52632b578d3Smrg{ 527e35d4d8eSmrg ATIPtr pATI = ATIPTR(xf86ScreenToScrn(pLinear->pScreen)); 52832b578d3Smrg 52932b578d3Smrg pATI->pXVBuffer = NULL; 53032b578d3Smrg outf(OVERLAY_SCALE_CNTL, SCALE_EN); 53132b578d3Smrg} 53232b578d3Smrg#endif /* USE_XAA */ 53332b578d3Smrg 53432b578d3Smrg/* 53532b578d3Smrg * ATIMach64StopVideo -- 53632b578d3Smrg * 53732b578d3Smrg * This is called to stop displaying a video. Note that, to prevent jittering 53832b578d3Smrg * this doesn't actually turn off the overlay unless 'Cleanup' is TRUE, i.e. 53932b578d3Smrg * when the video is to be actually stopped rather than temporarily disabled. 54032b578d3Smrg */ 54132b578d3Smrgstatic void 54232b578d3SmrgATIMach64StopVideo 54332b578d3Smrg( 54432b578d3Smrg ScrnInfoPtr pScreenInfo, 54532b578d3Smrg pointer Data, 54632b578d3Smrg Bool Cleanup 54732b578d3Smrg) 54832b578d3Smrg{ 54932b578d3Smrg ScreenPtr pScreen = pScreenInfo->pScreen; 55032b578d3Smrg ATIPtr pATI = Data; 55132b578d3Smrg 55232b578d3Smrg if (pATI->ActiveSurface) 55332b578d3Smrg return; 55432b578d3Smrg 55532b578d3Smrg REGION_EMPTY(pScreen, &pATI->VideoClip); 55632b578d3Smrg 55732b578d3Smrg#ifdef USE_XAA 55832b578d3Smrg if (!pATI->useEXA && !Cleanup) 55932b578d3Smrg { 56032b578d3Smrg /* 56132b578d3Smrg * Free offscreen buffer if/when its allocation is needed by XAA's 56232b578d3Smrg * pixmap cache. 56332b578d3Smrg */ 56432b578d3Smrg FBLinearPtr linear = (FBLinearPtr)pATI->pXVBuffer; 56532b578d3Smrg if (linear) 56632b578d3Smrg linear->RemoveLinearCallback = 56732b578d3Smrg ATIMach64RemoveLinearCallback; 56832b578d3Smrg return; 56932b578d3Smrg } 57032b578d3Smrg#endif /* USE_XAA */ 57132b578d3Smrg 57232b578d3Smrg ATIMach64XVMemFree(pScreen, pATI->pXVBuffer, pATI); 57332b578d3Smrg pATI->pXVBuffer = NULL; 57432b578d3Smrg outf(OVERLAY_SCALE_CNTL, SCALE_EN); 57532b578d3Smrg} 57632b578d3Smrg 57732b578d3Smrg/* 57832b578d3Smrg * ATIMach64QueryBestSize -- 57932b578d3Smrg * 58032b578d3Smrg * Quoting XVideo docs: 58132b578d3Smrg * 58232b578d3Smrg * This function provides the client with a way to query what the destination 58332b578d3Smrg * dimensions would end up being if they were to request that an area 58432b578d3Smrg * VideoWidth by VideoHeight from the video stream be scaled to rectangle of 58532b578d3Smrg * DrawableWidth by DrawableHeight on the screen. Since it is not expected 58632b578d3Smrg * that all hardware will be able to get the target dimensions exactly, it is 58732b578d3Smrg * important that the driver provide this function. 58832b578d3Smrg */ 58932b578d3Smrgstatic void 59032b578d3SmrgATIMach64QueryBestSize 59132b578d3Smrg( 59232b578d3Smrg ScrnInfoPtr pScreenInfo, 59332b578d3Smrg Bool Motion, 59432b578d3Smrg short VideoWidth, 59532b578d3Smrg short VideoHeight, 59632b578d3Smrg short DrawableWidth, 59732b578d3Smrg short DrawableHeight, 59832b578d3Smrg unsigned int *Width, 59932b578d3Smrg unsigned int *Height, 60032b578d3Smrg pointer pATI 60132b578d3Smrg) 60232b578d3Smrg{ 60332b578d3Smrg *Width = DrawableWidth; 60432b578d3Smrg *Height = DrawableHeight; 60532b578d3Smrg} 60632b578d3Smrg 60732b578d3Smrg/* 60832b578d3Smrg * ATIMach64QueryImageAttributes -- 60932b578d3Smrg * 61032b578d3Smrg * Quoting XVideo docs: 61132b578d3Smrg * 61232b578d3Smrg * This function is called to let the driver specify how data for a particular 61332b578d3Smrg * image of size Width by Height should be stored. Sometimes only the size and 61432b578d3Smrg * corrected width and height are needed. In that case pitches and offsets are 61532b578d3Smrg * NULL. The size of the memory required for the image is returned by this 61632b578d3Smrg * function. The width and height of the requested image can be altered by the 61732b578d3Smrg * driver to reflect format limitations (such as component sampling periods 61832b578d3Smrg * that are larger than one). If pPitch and pOffset are not NULL, these will 61932b578d3Smrg * be arrays with as many elements in them as there are planes in the image 62032b578d3Smrg * format. The driver should specify the pitch (in bytes) of each scanline in 62132b578d3Smrg * the particular plane as well as the offset to that plane (in bytes) from the 62232b578d3Smrg * beginning of the image. 62332b578d3Smrg */ 62432b578d3Smrgstatic int 62532b578d3SmrgATIMach64QueryImageAttributes 62632b578d3Smrg( 62732b578d3Smrg ScrnInfoPtr pScreenInfo, 62832b578d3Smrg int ImageID, 62932b578d3Smrg unsigned short *Width, 63032b578d3Smrg unsigned short *Height, 63132b578d3Smrg int *pPitch, 63232b578d3Smrg int *pOffset 63332b578d3Smrg) 63432b578d3Smrg{ 63532b578d3Smrg int Size, tmp; 63632b578d3Smrg 63732b578d3Smrg if (!Width || !Height) 63832b578d3Smrg return 0; 63932b578d3Smrg 64032b578d3Smrg if (*Width > 2048) 64132b578d3Smrg *Width = 2048; 64232b578d3Smrg else 64332b578d3Smrg *Width = (*Width + 1) & ~1; 64432b578d3Smrg 64532b578d3Smrg if (*Height > 2048) 64632b578d3Smrg *Height = 2048; 64732b578d3Smrg 64832b578d3Smrg if (pOffset) 64932b578d3Smrg pOffset[0] = 0; 65032b578d3Smrg 65132b578d3Smrg switch (ImageID) 65232b578d3Smrg { 65332b578d3Smrg case FOURCC_YV12: 65432b578d3Smrg case FOURCC_I420: 65532b578d3Smrg *Height = (*Height + 1) & ~1; 65632b578d3Smrg Size = (*Width + 3) & ~3; 65732b578d3Smrg if (pPitch) 65832b578d3Smrg pPitch[0] = Size; 65932b578d3Smrg Size *= *Height; 66032b578d3Smrg if (pOffset) 66132b578d3Smrg pOffset[1] = Size; 66232b578d3Smrg tmp = ((*Width >> 1) + 3) & ~3; 66332b578d3Smrg if (pPitch) 66432b578d3Smrg pPitch[1] = pPitch[2] = tmp; 66532b578d3Smrg tmp *= (*Height >> 1); 66632b578d3Smrg Size += tmp; 66732b578d3Smrg if (pOffset) 66832b578d3Smrg pOffset[2] = Size; 66932b578d3Smrg Size += tmp; 67032b578d3Smrg break; 67132b578d3Smrg 67232b578d3Smrg case FOURCC_UYVY: 67332b578d3Smrg case FOURCC_YUY2: 67432b578d3Smrg Size = *Width << 1; 67532b578d3Smrg if (pPitch) 67632b578d3Smrg pPitch[0] = Size; 67732b578d3Smrg Size *= *Height; 67832b578d3Smrg break; 67932b578d3Smrg 68032b578d3Smrg default: 68132b578d3Smrg Size = 0; 68232b578d3Smrg break; 68332b578d3Smrg } 68432b578d3Smrg 68532b578d3Smrg return Size; 68632b578d3Smrg} 68732b578d3Smrg 68832b578d3Smrg/* 68932b578d3Smrg * ATIMach64ScaleVideo -- 69032b578d3Smrg * 69132b578d3Smrg * This function is called to calculate overlay scaling factors. 69232b578d3Smrg */ 69332b578d3Smrgstatic void 69432b578d3SmrgATIMach64ScaleVideo 69532b578d3Smrg( 69632b578d3Smrg ATIPtr pATI, 69732b578d3Smrg DisplayModePtr pMode, 69832b578d3Smrg int SrcW, 69932b578d3Smrg int SrcH, 70032b578d3Smrg int DstW, 70132b578d3Smrg int DstH, 70232b578d3Smrg CARD32 *pHScale, 70332b578d3Smrg CARD32 *pVScale 70432b578d3Smrg) 70532b578d3Smrg{ 70632b578d3Smrg int Shift; 70732b578d3Smrg 70832b578d3Smrg *pHScale = ATIDivide(SrcW, DstW, 70932b578d3Smrg GetBits(pATI->NewHW.pll_vclk_cntl, PLL_ECP_DIV) + 12, 0); 71032b578d3Smrg 71132b578d3Smrg Shift = 12; 71232b578d3Smrg if (pMode->Flags & V_INTERLACE) 71332b578d3Smrg Shift++; 71432b578d3Smrg 71532b578d3Smrg if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0)) 71632b578d3Smrg { 71732b578d3Smrg if (pMode->VDisplay < pATI->LCDVertical) 71832b578d3Smrg { 71932b578d3Smrg SrcH *= pMode->VDisplay; 72032b578d3Smrg DstH *= pATI->LCDVertical; 72132b578d3Smrg } 72232b578d3Smrg } 72332b578d3Smrg else 72432b578d3Smrg { 72532b578d3Smrg if (pMode->Flags & V_DBLSCAN) 72632b578d3Smrg Shift--; 72732b578d3Smrg if (pMode->VScan > 1) 72832b578d3Smrg DstH *= pMode->VScan; 72932b578d3Smrg } 73032b578d3Smrg 73132b578d3Smrg *pVScale = ATIDivide(SrcH, DstH, Shift, 0); 73232b578d3Smrg} 73332b578d3Smrg 73432b578d3Smrg/* 73532b578d3Smrg * ATIMach64ClipVideo -- 73632b578d3Smrg * 73732b578d3Smrg * Clip the video (both source and destination) and make various other 73832b578d3Smrg * adjustments. 73932b578d3Smrg */ 74032b578d3Smrgstatic Bool 74132b578d3SmrgATIMach64ClipVideo 74232b578d3Smrg( 74332b578d3Smrg ScrnInfoPtr pScreenInfo, 74432b578d3Smrg ATIPtr pATI, 74532b578d3Smrg int ImageID, 74632b578d3Smrg short SrcX, 74732b578d3Smrg short SrcY, 74832b578d3Smrg short SrcW, 74932b578d3Smrg short SrcH, 75032b578d3Smrg short DstX, 75132b578d3Smrg short DstY, 75232b578d3Smrg short *DstW, 75332b578d3Smrg short *DstH, 75432b578d3Smrg short Width, 75532b578d3Smrg short Height, 75632b578d3Smrg RegionPtr pClip, 75732b578d3Smrg BoxPtr pDstBox, 75832b578d3Smrg INT32 *SrcX1, 75932b578d3Smrg INT32 *SrcX2, 76032b578d3Smrg INT32 *SrcY1, 76132b578d3Smrg INT32 *SrcY2, 76232b578d3Smrg int *SrcLeft, 76332b578d3Smrg int *SrcTop 76432b578d3Smrg) 76532b578d3Smrg{ 76632b578d3Smrg CARD32 HScale, VScale; 76732b578d3Smrg 76832b578d3Smrg /* Check hardware limits */ 76932b578d3Smrg if ((Height <= 0) || (Height > 2048) || (Width <= 0) || (Width > 768) || 77032b578d3Smrg ((Width > 384) && (pATI->Chip < ATI_CHIP_264VTB)) || 77132b578d3Smrg ((Width > 720) && (pATI->Chip < ATI_CHIP_264GTPRO || 77232b578d3Smrg pATI->Chip > ATI_CHIP_264LTPRO))) 77332b578d3Smrg return FALSE; 77432b578d3Smrg 77532b578d3Smrg ATIMach64ScaleVideo(pATI, pScreenInfo->currentMode, 77632b578d3Smrg SrcW, SrcH, *DstW, *DstH, &HScale, &VScale); 77732b578d3Smrg if (!HScale || !VScale) 77832b578d3Smrg return FALSE; 77932b578d3Smrg if (HScale > MaxScale) 78032b578d3Smrg *DstW = (*DstW * HScale) / MaxScale; 78132b578d3Smrg if (VScale > MaxScale) 78232b578d3Smrg *DstH = (*DstH * HScale) / MaxScale; 78332b578d3Smrg 78432b578d3Smrg /* Clip both the source and the destination */ 78532b578d3Smrg *SrcX1 = SrcX; 78632b578d3Smrg *SrcX2 = SrcX + SrcW; 78732b578d3Smrg *SrcY1 = SrcY; 78832b578d3Smrg *SrcY2 = SrcY + SrcH; 78932b578d3Smrg 79032b578d3Smrg pDstBox->x1 = DstX; 79132b578d3Smrg pDstBox->x2 = DstX + *DstW; 79232b578d3Smrg pDstBox->y1 = DstY; 79332b578d3Smrg pDstBox->y2 = DstY + *DstH; 79432b578d3Smrg 79532b578d3Smrg if (!xf86XVClipVideoHelper(pDstBox, SrcX1, SrcX2, SrcY1, SrcY2, 79632b578d3Smrg pClip, Width, Height)) 79732b578d3Smrg return FALSE; 79832b578d3Smrg 79932b578d3Smrg /* 80032b578d3Smrg * Reset overlay scaler origin. This prevents jittering during 80132b578d3Smrg * viewport panning or while the video is being moved or gradually 80232b578d3Smrg * obscured/unobscured. 80332b578d3Smrg */ 80432b578d3Smrg pDstBox->x1 = DstX; 80532b578d3Smrg pDstBox->y1 = DstY; 80632b578d3Smrg 80732b578d3Smrg /* Translate to the current viewport */ 80832b578d3Smrg pDstBox->x1 -= pScreenInfo->frameX0; 80932b578d3Smrg pDstBox->x2 -= pScreenInfo->frameX0; 81032b578d3Smrg pDstBox->y1 -= pScreenInfo->frameY0; 81132b578d3Smrg pDstBox->y2 -= pScreenInfo->frameY0; 81232b578d3Smrg 81332b578d3Smrg *SrcLeft = *SrcTop = 0; 81432b578d3Smrg 81532b578d3Smrg /* 81632b578d3Smrg * If the overlay scaler origin ends up outside the current viewport, move 81732b578d3Smrg * it to the viewport's top left corner. This unavoidably causes a slight 81832b578d3Smrg * jittering in the image (even with double-buffering). 81932b578d3Smrg */ 82032b578d3Smrg if (pDstBox->x1 < 0) 82132b578d3Smrg { 82232b578d3Smrg *SrcLeft = ((-pDstBox->x1 * SrcW) / *DstW) & ~1; 82332b578d3Smrg pDstBox->x1 = 0; 82432b578d3Smrg } 82532b578d3Smrg 82632b578d3Smrg if (pDstBox->y1 < 0) 82732b578d3Smrg { 82832b578d3Smrg *SrcTop = (-pDstBox->y1 * SrcH) / *DstH; 82932b578d3Smrg pDstBox->y1 = 0; 83032b578d3Smrg 83132b578d3Smrg switch (ImageID) 83232b578d3Smrg { 83332b578d3Smrg case FOURCC_YV12: 83432b578d3Smrg case FOURCC_I420: 83532b578d3Smrg *SrcTop = (*SrcTop + 1) & ~1; 83632b578d3Smrg break; 83732b578d3Smrg 83832b578d3Smrg default: 83932b578d3Smrg break; 84032b578d3Smrg } 84132b578d3Smrg } 84232b578d3Smrg 84332b578d3Smrg return TRUE; 84432b578d3Smrg} 84532b578d3Smrg 84632b578d3Smrg#ifdef ATIMove32 84732b578d3Smrg 84832b578d3Smrg/* A faster intercept */ 84932b578d3Smrg#undef xf86XVCopyPacked 85032b578d3Smrg#define xf86XVCopyPacked ATIMach64XVCopyPacked 85132b578d3Smrg 85232b578d3Smrgstatic void 85332b578d3SmrgATIMach64XVCopyPacked 85432b578d3Smrg( 85532b578d3Smrg const CARD8 *pSrc, 85632b578d3Smrg CARD8 *pDst, 85732b578d3Smrg int SrcPitch, 85832b578d3Smrg int DstPitch, 85932b578d3Smrg int Height, 86032b578d3Smrg int Width 86132b578d3Smrg) 86232b578d3Smrg{ 86332b578d3Smrg Width >>= 1; 86432b578d3Smrg while (--Height >= 0) 86532b578d3Smrg { 86632b578d3Smrg ATIMove32(pDst, pSrc, Width); 86732b578d3Smrg pSrc += SrcPitch; 86832b578d3Smrg pDst += DstPitch; 86932b578d3Smrg } 87032b578d3Smrg} 87132b578d3Smrg 87232b578d3Smrg#endif 87332b578d3Smrg 87432b578d3Smrg/* 87532b578d3Smrg * ATIMach64DisplayVideo -- 87632b578d3Smrg * 87732b578d3Smrg * This function programmes Mach64 registers needed to display a video. 87832b578d3Smrg */ 87932b578d3Smrgstatic void 88032b578d3SmrgATIMach64DisplayVideo 88132b578d3Smrg( 88232b578d3Smrg ScrnInfoPtr pScreenInfo, 88332b578d3Smrg ATIPtr pATI, 88432b578d3Smrg BoxPtr pDstBox, 88532b578d3Smrg int ImageID, 88632b578d3Smrg int Offset, 88732b578d3Smrg int Pitch, 88832b578d3Smrg short SrcW, 88932b578d3Smrg short SrcH, 89032b578d3Smrg short DstW, 89132b578d3Smrg short DstH, 89232b578d3Smrg short Width, 89332b578d3Smrg short Height 89432b578d3Smrg) 89532b578d3Smrg{ 89632b578d3Smrg DisplayModePtr pMode = pScreenInfo->currentMode; 89732b578d3Smrg CARD32 HScale, VScale; 89832b578d3Smrg 89932b578d3Smrg if (pMode->VScan > 1) 90032b578d3Smrg { 90132b578d3Smrg pDstBox->y1 *= pMode->VScan; 90232b578d3Smrg pDstBox->y2 *= pMode->VScan; 90332b578d3Smrg } 90432b578d3Smrg if (pMode->Flags & V_DBLSCAN) 90532b578d3Smrg { 90632b578d3Smrg pDstBox->y1 <<= 1; 90732b578d3Smrg pDstBox->y2 <<= 1; 90832b578d3Smrg } 90932b578d3Smrg 91032b578d3Smrg /* Recalculate overlay scale factors */ 91132b578d3Smrg ATIMach64ScaleVideo(pATI, pMode, SrcW, SrcH, DstW, DstH, &HScale, &VScale); 91232b578d3Smrg 91332b578d3Smrg pATI->NewHW.video_format &= ~SCALER_IN; 91432b578d3Smrg if (ImageID == FOURCC_UYVY) 91532b578d3Smrg pATI->NewHW.video_format |= SCALER_IN_YVYU422; 91632b578d3Smrg else 91732b578d3Smrg pATI->NewHW.video_format |= SCALER_IN_VYUY422; 91832b578d3Smrg 91932b578d3Smrg ATIMach64WaitForFIFO(pATI, 8); 92032b578d3Smrg outq(OVERLAY_Y_X_START, OVERLAY_Y_X_END, OVERLAY_LOCK_START | 92132b578d3Smrg SetWord(pDstBox->x1, 1) | SetWord(pDstBox->y1, 0), 92232b578d3Smrg SetWord(pDstBox->x2 - 1, 1) | SetWord(pDstBox->y2 - 1, 0)); 92332b578d3Smrg outf(OVERLAY_SCALE_INC, SetWord(HScale, 1) | SetWord(VScale, 0)); 92432b578d3Smrg outf(SCALER_HEIGHT_WIDTH, SetWord(Width, 1) | SetWord(Height, 0)); 92532b578d3Smrg outf(VIDEO_FORMAT, pATI->NewHW.video_format); 92632b578d3Smrg 92732b578d3Smrg if (pATI->Chip < ATI_CHIP_264VTB) 92832b578d3Smrg { 92932b578d3Smrg outf(BUF0_OFFSET, Offset); 93032b578d3Smrg outf(BUF0_PITCH, Pitch); 93132b578d3Smrg } 93232b578d3Smrg else 93332b578d3Smrg { 93432b578d3Smrg outf(SCALER_BUF0_OFFSET, Offset); 93532b578d3Smrg outf(SCALER_BUF_PITCH, Pitch); 93632b578d3Smrg } 93732b578d3Smrg 93832b578d3Smrg outf(OVERLAY_SCALE_CNTL, SCALE_PIX_EXPAND | OVERLAY_EN | SCALE_EN); 93932b578d3Smrg} 94032b578d3Smrg 94132b578d3Smrg/* 94232b578d3Smrg * ATIMach64PutImage -- 94332b578d3Smrg * 94432b578d3Smrg * This function is called to put a video image on the screen. 94532b578d3Smrg */ 94632b578d3Smrgstatic int 94732b578d3SmrgATIMach64PutImage 94832b578d3Smrg( 94932b578d3Smrg ScrnInfoPtr pScreenInfo, 95032b578d3Smrg short SrcX, 95132b578d3Smrg short SrcY, 95232b578d3Smrg short DstX, 95332b578d3Smrg short DstY, 95432b578d3Smrg short SrcW, 95532b578d3Smrg short SrcH, 95632b578d3Smrg short DstW, 95732b578d3Smrg short DstH, 95832b578d3Smrg int ImageID, 95932b578d3Smrg unsigned char *Buffer, 96032b578d3Smrg short Width, 96132b578d3Smrg short Height, 96232b578d3Smrg Bool Synchronise, 96332b578d3Smrg RegionPtr pClip, 96432b578d3Smrg pointer Data, 96532b578d3Smrg DrawablePtr pDraw 96632b578d3Smrg) 96732b578d3Smrg{ 96832b578d3Smrg ATIPtr pATI = Data; 96932b578d3Smrg ScreenPtr pScreen; 97032b578d3Smrg INT32 SrcX1, SrcX2, SrcY1, SrcY2; 97132b578d3Smrg BoxRec DstBox; 97232b578d3Smrg int SrcPitch, SrcPitchUV, DstPitch, DstSize; 97332b578d3Smrg int SrcTop, SrcLeft, DstWidth, DstHeight; 97432b578d3Smrg int Top, Bottom, Left, Right, nLine, nPixel, Offset; 97532b578d3Smrg int OffsetV, OffsetU; 97632b578d3Smrg int XVOffset; 97732b578d3Smrg int tmp; 97832b578d3Smrg CARD8 *pDst; 97932b578d3Smrg 98032b578d3Smrg if (pATI->ActiveSurface) 98132b578d3Smrg return Success; 98232b578d3Smrg 98332b578d3Smrg if (DstH < 16) 98432b578d3Smrg return Success; 98532b578d3Smrg 98632b578d3Smrg if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID, 98732b578d3Smrg SrcX, SrcY, SrcW, SrcH, 98832b578d3Smrg DstX, DstY, &DstW, &DstH, 98932b578d3Smrg Width, Height, pClip, &DstBox, 99032b578d3Smrg &SrcX1, &SrcX2, &SrcY1, &SrcY2, 99132b578d3Smrg &SrcLeft, &SrcTop)) 99232b578d3Smrg return Success; 99332b578d3Smrg 99432b578d3Smrg pScreen = pScreenInfo->pScreen; 99532b578d3Smrg 99632b578d3Smrg DstWidth = Width - SrcLeft; 99732b578d3Smrg DstHeight = Height - SrcTop; 99832b578d3Smrg 99932b578d3Smrg /* 100032b578d3Smrg * Allocate an offscreen buffer for the entire source, even though only a 100132b578d3Smrg * subset of the source will be copied into it. 100232b578d3Smrg */ 100332b578d3Smrg DstPitch = /* bytes */ 100432b578d3Smrg (DstWidth + DstWidth + 15) & ~15; 100532b578d3Smrg DstSize = /* bytes */ 100632b578d3Smrg (DstPitch * DstHeight); 100732b578d3Smrg 100832b578d3Smrg pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, 100932b578d3Smrg (pATI->DoubleBuffer + 1) * DstSize, &XVOffset, pATI); 101032b578d3Smrg 101132b578d3Smrg if (!pATI->pXVBuffer) 101232b578d3Smrg { 101332b578d3Smrg if (!pATI->DoubleBuffer) 101432b578d3Smrg return BadAlloc; 101532b578d3Smrg 101632b578d3Smrg pATI->pXVBuffer = 101732b578d3Smrg ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, DstSize, &XVOffset, pATI); 101832b578d3Smrg 101932b578d3Smrg if (!pATI->pXVBuffer) 102032b578d3Smrg return BadAlloc; 102132b578d3Smrg 102232b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 102332b578d3Smrg "Video image double-buffering downgraded to single-buffering\n due" 102432b578d3Smrg " to insufficient video memory.\n"); 102532b578d3Smrg pATI->DoubleBuffer = pATI->CurrentBuffer = 0; 102632b578d3Smrg } 102732b578d3Smrg else 102832b578d3Smrg { 102932b578d3Smrg /* Possibly switch buffers */ 103032b578d3Smrg pATI->CurrentBuffer = pATI->DoubleBuffer - pATI->CurrentBuffer; 103132b578d3Smrg } 103232b578d3Smrg 103332b578d3Smrg /* Synchronise video memory accesses */ 103432b578d3Smrg ATIMach64Sync(pScreenInfo); 103532b578d3Smrg 103632b578d3Smrg Offset = XVOffset + pATI->CurrentBuffer * DstSize; 103732b578d3Smrg pDst = pATI->pMemoryLE; 103832b578d3Smrg pDst += Offset; 103932b578d3Smrg 104032b578d3Smrg switch (ImageID) 104132b578d3Smrg { 104232b578d3Smrg case FOURCC_YV12: 104332b578d3Smrg case FOURCC_I420: 104432b578d3Smrg Left = (SrcX1 >> 16) & ~1; 104532b578d3Smrg Right = ((SrcX2 + 0x1FFFF) >> 16) & ~1; 104632b578d3Smrg Top = (SrcY1 >> 16) & ~1; 104732b578d3Smrg Bottom = ((SrcY2 + 0x1FFFF) >> 16) & ~1; 104832b578d3Smrg 104932b578d3Smrg if ((Right < Width) && ((SrcX1 & 0x1FFFF) <= (SrcX2 & 0x1FFFF))) 105032b578d3Smrg Right += 2; 105132b578d3Smrg if ((Bottom < Height) && ((SrcY1 & 0x1FFFF) <= (SrcY2 & 0x1FFFF))) 105232b578d3Smrg Bottom += 2; 105332b578d3Smrg 105432b578d3Smrg nPixel = Right - Left; 105532b578d3Smrg nLine = Bottom - Top; 105632b578d3Smrg 105732b578d3Smrg SrcPitch = (Width + 3) & ~3; 105832b578d3Smrg OffsetV = SrcPitch * Height; 105932b578d3Smrg SrcPitchUV = ((Width >> 1) + 3) & ~3; 106032b578d3Smrg OffsetU = ((Height >> 1) * SrcPitchUV) + OffsetV; 106132b578d3Smrg 106232b578d3Smrg tmp = ((Top >> 1) * SrcPitchUV) + (Left >> 1); 106332b578d3Smrg OffsetV += tmp; 106432b578d3Smrg OffsetU += tmp; 106532b578d3Smrg 106632b578d3Smrg if (ImageID == FOURCC_I420) 106732b578d3Smrg { 106832b578d3Smrg tmp = OffsetV; 106932b578d3Smrg OffsetV = OffsetU; 107032b578d3Smrg OffsetU = tmp; 107132b578d3Smrg } 107232b578d3Smrg 107332b578d3Smrg pDst += ((Top - SrcTop) * DstPitch) + ((Left - SrcLeft) << 1); 107432b578d3Smrg 107532b578d3Smrg xf86XVCopyYUV12ToPacked(Buffer + (Top * SrcPitch) + Left, 107632b578d3Smrg Buffer + OffsetV, Buffer + OffsetU, pDst, SrcPitch, SrcPitchUV, 107732b578d3Smrg DstPitch, nLine, nPixel); 107832b578d3Smrg break; 107932b578d3Smrg 108032b578d3Smrg case FOURCC_UYVY: 108132b578d3Smrg case FOURCC_YUY2: 108232b578d3Smrg default: 108332b578d3Smrg Left = (SrcX1 >> 16) & ~1; 108432b578d3Smrg Right = ((SrcX2 + 0x1FFFF) >> 16) & ~1; 108532b578d3Smrg Top = SrcY1 >> 16; 108632b578d3Smrg Bottom = (SrcY2 + 0x0FFFF) >> 16; 108732b578d3Smrg 108832b578d3Smrg if ((Right < Width) && ((SrcX1 & 0x1FFFF) <= (SrcX2 & 0x1FFFF))) 108932b578d3Smrg Right += 2; 109032b578d3Smrg if ((Bottom < Height) && ((SrcY1 & 0x0FFFF) <= (SrcY2 & 0x0FFFF))) 109132b578d3Smrg Bottom++; 109232b578d3Smrg 109332b578d3Smrg nPixel = Right - Left; 109432b578d3Smrg nLine = Bottom - Top; 109532b578d3Smrg 109632b578d3Smrg SrcPitch = Width << 1; 109732b578d3Smrg Buffer += (Top * SrcPitch) + (Left << 1); 109832b578d3Smrg pDst += ((Top - SrcTop) * DstPitch) + ((Left - SrcLeft) << 1); 109932b578d3Smrg 110032b578d3Smrg xf86XVCopyPacked(Buffer, pDst, SrcPitch, DstPitch, nLine, nPixel); 110132b578d3Smrg break; 110232b578d3Smrg } 110332b578d3Smrg 110432b578d3Smrg if (!REGION_EQUAL(pScreen, &pATI->VideoClip, pClip)) 110532b578d3Smrg { 110632b578d3Smrg REGION_COPY(pScreen, &pATI->VideoClip, pClip); 110732b578d3Smrg if (pATI->AutoPaint) 110832b578d3Smrg xf86XVFillKeyHelper(pScreen, pATI->NewHW.overlay_graphics_key_clr, 110932b578d3Smrg pClip); 111032b578d3Smrg } 111132b578d3Smrg 111232b578d3Smrg ATIMach64DisplayVideo(pScreenInfo, pATI, &DstBox, ImageID, 111332b578d3Smrg Offset, DstPitch / 2, SrcW, SrcH, DstW, DstH, DstWidth, DstHeight); 111432b578d3Smrg 111532b578d3Smrg return Success; 111632b578d3Smrg} 111732b578d3Smrg 111832b578d3Smrg/* 111932b578d3Smrg * ATIMach64AllocateSurface -- 112032b578d3Smrg * 112132b578d3Smrg * This function allocates an offscreen buffer (called a "surface") for use by 112232b578d3Smrg * an external driver such as 'v4l'. 112332b578d3Smrg */ 112432b578d3Smrgstatic int 112532b578d3SmrgATIMach64AllocateSurface 112632b578d3Smrg( 112732b578d3Smrg ScrnInfoPtr pScreenInfo, 112832b578d3Smrg int ImageID, 112932b578d3Smrg unsigned short Width, 113032b578d3Smrg unsigned short Height, 113132b578d3Smrg XF86SurfacePtr pSurface 113232b578d3Smrg) 113332b578d3Smrg{ 113432b578d3Smrg ScreenPtr pScreen; 113532b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 113632b578d3Smrg int XVOffset; 113732b578d3Smrg 113832b578d3Smrg if (pATI->ActiveSurface) 113932b578d3Smrg return BadAlloc; 114032b578d3Smrg 114132b578d3Smrg if ((Height <= 0) || (Height > 2048) || (Width <= 0) || (Width > 768) || 114232b578d3Smrg ((Width > 384) && (pATI->Chip < ATI_CHIP_264VTB)) || 114332b578d3Smrg ((Width > 720) && (pATI->Chip < ATI_CHIP_264GTPRO || 114432b578d3Smrg pATI->Chip > ATI_CHIP_264LTPRO))) 114532b578d3Smrg return BadValue; 114632b578d3Smrg 114732b578d3Smrg Width = (Width + 1) & ~1; 114832b578d3Smrg pATI->SurfacePitch = ((Width << 1) + 15) & ~15; 114932b578d3Smrg 115032b578d3Smrg pScreen = pScreenInfo->pScreen; 115132b578d3Smrg 115232b578d3Smrg pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, 115332b578d3Smrg Height * pATI->SurfacePitch, &XVOffset, pATI); 115432b578d3Smrg if (!pATI->pXVBuffer) 115532b578d3Smrg return BadAlloc; 115632b578d3Smrg 115732b578d3Smrg pATI->SurfaceOffset = XVOffset; 115832b578d3Smrg 115932b578d3Smrg pSurface->pScrn = pScreenInfo; 116032b578d3Smrg pSurface->id = ImageID; 116132b578d3Smrg pSurface->width = Width; 116232b578d3Smrg pSurface->height = Height; 116332b578d3Smrg pSurface->pitches = &pATI->SurfacePitch; 116432b578d3Smrg pSurface->offsets = &pATI->SurfaceOffset; 116532b578d3Smrg pSurface->devPrivate.ptr = pATI; 116632b578d3Smrg 116732b578d3Smrg /* Stop the video */ 116832b578d3Smrg outf(OVERLAY_SCALE_CNTL, SCALE_EN); 116932b578d3Smrg REGION_EMPTY(pScreen, &pATI->VideoClip); 117032b578d3Smrg pATI->ActiveSurface = TRUE; 117132b578d3Smrg 117232b578d3Smrg return Success; 117332b578d3Smrg} 117432b578d3Smrg 117532b578d3Smrg/* 117632b578d3Smrg * ATIMach64FreeSurface -- 117732b578d3Smrg * 117832b578d3Smrg * This function called to free a surface's offscreen buffer. 117932b578d3Smrg */ 118032b578d3Smrgstatic int 118132b578d3SmrgATIMach64FreeSurface 118232b578d3Smrg( 118332b578d3Smrg XF86SurfacePtr pSurface 118432b578d3Smrg) 118532b578d3Smrg{ 118632b578d3Smrg ATIPtr pATI = pSurface->devPrivate.ptr; 118732b578d3Smrg 118832b578d3Smrg if (!pATI->ActiveSurface) 118932b578d3Smrg return Success; 119032b578d3Smrg 119132b578d3Smrg outf(OVERLAY_SCALE_CNTL, SCALE_EN); 119232b578d3Smrg ATIMach64XVMemFree(pSurface->pScrn->pScreen, pATI->pXVBuffer, pATI); 119332b578d3Smrg pATI->pXVBuffer = NULL; 119432b578d3Smrg pATI->ActiveSurface = FALSE; 119532b578d3Smrg 119632b578d3Smrg return Success; 119732b578d3Smrg} 119832b578d3Smrg 119932b578d3Smrg/* 120032b578d3Smrg * ATIMach64DisplaySurface -- 120132b578d3Smrg * 120232b578d3Smrg * This function is called to display a video surface. 120332b578d3Smrg */ 120432b578d3Smrgstatic int 120532b578d3SmrgATIMach64DisplaySurface 120632b578d3Smrg( 120732b578d3Smrg XF86SurfacePtr pSurface, 120832b578d3Smrg short SrcX, 120932b578d3Smrg short SrcY, 121032b578d3Smrg short DstX, 121132b578d3Smrg short DstY, 121232b578d3Smrg short SrcW, 121332b578d3Smrg short SrcH, 121432b578d3Smrg short DstW, 121532b578d3Smrg short DstH, 121632b578d3Smrg RegionPtr pClip 121732b578d3Smrg) 121832b578d3Smrg{ 121932b578d3Smrg ATIPtr pATI = pSurface->devPrivate.ptr; 122032b578d3Smrg ScrnInfoPtr pScreenInfo; 122132b578d3Smrg int ImageID; 122232b578d3Smrg short Width, Height; 122332b578d3Smrg BoxRec DstBox; 122432b578d3Smrg INT32 SrcX1, SrcX2, SrcY1, SrcY2; 122532b578d3Smrg int SrcLeft, SrcTop, SrcPitch, Offset; 122632b578d3Smrg 122732b578d3Smrg if (!pATI->ActiveSurface) 122832b578d3Smrg return Success; 122932b578d3Smrg 123032b578d3Smrg pScreenInfo = pSurface->pScrn; 123132b578d3Smrg ImageID = pSurface->id; 123232b578d3Smrg Width = pSurface->width; 123332b578d3Smrg Height = pSurface->height; 123432b578d3Smrg 123532b578d3Smrg if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID, 123632b578d3Smrg SrcX, SrcY, SrcW, SrcH, 123732b578d3Smrg DstX, DstY, &DstW, &DstH, 123832b578d3Smrg Width, Height, pClip, &DstBox, 123932b578d3Smrg &SrcX1, &SrcX2, &SrcY1, &SrcY2, 124032b578d3Smrg &SrcLeft, &SrcTop)) 124132b578d3Smrg return Success; 124232b578d3Smrg 124332b578d3Smrg xf86XVFillKeyHelper(pScreenInfo->pScreen, 124432b578d3Smrg pATI->NewHW.overlay_graphics_key_clr, pClip); 124532b578d3Smrg 124632b578d3Smrg SrcPitch = pSurface->pitches[0]; 124732b578d3Smrg Offset = pSurface->offsets[0] + (SrcTop * SrcPitch) + (SrcLeft << 1); 124832b578d3Smrg ATIMach64DisplayVideo(pScreenInfo, pATI, &DstBox, ImageID, 124932b578d3Smrg Offset, SrcPitch, SrcW, SrcH, DstW, DstH, Width, Height); 125032b578d3Smrg 125132b578d3Smrg return Success; 125232b578d3Smrg} 125332b578d3Smrg 125432b578d3Smrg/* 125532b578d3Smrg * ATIMach64StopSurface -- 125632b578d3Smrg * 125732b578d3Smrg * This function is called to stop the overlaid display of a video surface. 125832b578d3Smrg */ 125932b578d3Smrgstatic int 126032b578d3SmrgATIMach64StopSurface 126132b578d3Smrg( 126232b578d3Smrg XF86SurfacePtr pSurface 126332b578d3Smrg) 126432b578d3Smrg{ 126532b578d3Smrg ATIPtr pATI = pSurface->devPrivate.ptr; 126632b578d3Smrg 126732b578d3Smrg if (pATI->ActiveSurface) 126832b578d3Smrg outf(OVERLAY_SCALE_CNTL, SCALE_EN); 126932b578d3Smrg 127032b578d3Smrg return Success; 127132b578d3Smrg} 127232b578d3Smrg 127332b578d3Smrg/* 127432b578d3Smrg * ATIMach64GetSurfaceAttribute -- 127532b578d3Smrg * 127632b578d3Smrg * Retrieve the value of an XVideo attribute. 127732b578d3Smrg */ 127832b578d3Smrgstatic int 127932b578d3SmrgATIMach64GetSurfaceAttribute 128032b578d3Smrg( 128132b578d3Smrg ScrnInfoPtr pScreenInfo, 128232b578d3Smrg Atom AttributeID, 128332b578d3Smrg INT32 *Value 128432b578d3Smrg) 128532b578d3Smrg{ 128632b578d3Smrg return ATIMach64GetPortAttribute(pScreenInfo, AttributeID, Value, 128732b578d3Smrg ATIPTR(pScreenInfo)); 128832b578d3Smrg} 128932b578d3Smrg 129032b578d3Smrg/* 129132b578d3Smrg * ATIMach64SetSurfaceAttribute 129232b578d3Smrg * 129332b578d3Smrg * Set the value of an XVideo attribute. 129432b578d3Smrg */ 129532b578d3Smrgstatic int 129632b578d3SmrgATIMach64SetSurfaceAttribute 129732b578d3Smrg( 129832b578d3Smrg ScrnInfoPtr pScreenInfo, 129932b578d3Smrg Atom AttributeID, 130032b578d3Smrg INT32 Value 130132b578d3Smrg) 130232b578d3Smrg{ 130332b578d3Smrg return ATIMach64SetPortAttribute(pScreenInfo, AttributeID, Value, 130432b578d3Smrg ATIPTR(pScreenInfo)); 130532b578d3Smrg} 130632b578d3Smrg 130732b578d3Smrg/* XVideo surface registration data */ 130832b578d3Smrgstatic XF86OffscreenImageRec ATIMach64Surface[] = 130932b578d3Smrg{ 131032b578d3Smrg { 131132b578d3Smrg &ATIMach64Image[0], /* YUY2 */ 131232b578d3Smrg VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, 131332b578d3Smrg ATIMach64AllocateSurface, 131432b578d3Smrg ATIMach64FreeSurface, 131532b578d3Smrg ATIMach64DisplaySurface, 131632b578d3Smrg ATIMach64StopSurface, 131732b578d3Smrg ATIMach64GetSurfaceAttribute, 131832b578d3Smrg ATIMach64SetSurfaceAttribute, 131932b578d3Smrg 720, 2048, 132032b578d3Smrg nATIMach64Attribute - 1, /* No double-buffering */ 132132b578d3Smrg ATIMach64Attribute 132232b578d3Smrg }, 132332b578d3Smrg { 132432b578d3Smrg &ATIMach64Image[1], /* UYVY */ 132532b578d3Smrg VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, 132632b578d3Smrg ATIMach64AllocateSurface, 132732b578d3Smrg ATIMach64FreeSurface, 132832b578d3Smrg ATIMach64DisplaySurface, 132932b578d3Smrg ATIMach64StopSurface, 133032b578d3Smrg ATIMach64GetSurfaceAttribute, 133132b578d3Smrg ATIMach64SetSurfaceAttribute, 133232b578d3Smrg 720, 2048, 133332b578d3Smrg nATIMach64Attribute - 1, /* No double-buffering */ 133432b578d3Smrg ATIMach64Attribute 133532b578d3Smrg } 133632b578d3Smrg}; 133732b578d3Smrg#define nATIMach64Surface NumberOf(ATIMach64Surface) 133832b578d3Smrg 133932b578d3Smrg/* 134032b578d3Smrg * ATIMach64XVInitialiseAdaptor -- 134132b578d3Smrg * 134232b578d3Smrg * This function is called to make a Mach64's hardware overlay support 134332b578d3Smrg * available as an XVideo adaptor. 134432b578d3Smrg */ 134532b578d3Smrgstatic int 134632b578d3SmrgATIMach64XVInitialiseAdaptor 134732b578d3Smrg( 134832b578d3Smrg ScrnInfoPtr pScreenInfo, 134932b578d3Smrg XF86VideoAdaptorPtr **pppAdaptor 135032b578d3Smrg) 135132b578d3Smrg{ 1352e35d4d8eSmrg ScreenPtr pScreen = xf86ScrnToScreen(pScreenInfo); 135332b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 135432b578d3Smrg XF86VideoAdaptorPtr *ppAdaptor = NULL; 135532b578d3Smrg XF86VideoAdaptorPtr pAdaptor; 135632b578d3Smrg int Index; 135732b578d3Smrg 135832b578d3Smrg XF86VideoEncodingPtr enc = &(ATIMach64VideoEncoding[0]); 135932b578d3Smrg XF86OffscreenImagePtr surf0 = &(ATIMach64Surface[0]); 136032b578d3Smrg XF86OffscreenImagePtr surf1 = &(ATIMach64Surface[1]); 136132b578d3Smrg 1362d31dbc53Smrg if (xf86NameCmp(pScreenInfo->driverName, MACH64_DRIVER_NAME) != 0) 1363d31dbc53Smrg return 0; 1364d31dbc53Smrg 136532b578d3Smrg if (pppAdaptor) 136632b578d3Smrg *pppAdaptor = NULL; 136732b578d3Smrg 136832b578d3Smrg if (!pATI->Block1Base) 136932b578d3Smrg return 0; 137032b578d3Smrg 137132b578d3Smrg if (!(pAdaptor = xf86XVAllocateVideoAdaptorRec(pScreenInfo))) 137232b578d3Smrg return 0; 137332b578d3Smrg 137432b578d3Smrg ppAdaptor = xnfalloc(sizeof(pAdaptor)); 137532b578d3Smrg ppAdaptor[0] = pAdaptor; 137632b578d3Smrg 137732b578d3Smrg pAdaptor->nPorts = 1; 137832b578d3Smrg pAdaptor->pPortPrivates = pATI->XVPortPrivate; 137932b578d3Smrg pATI->XVPortPrivate[0].ptr = pATI; 138032b578d3Smrg 138132b578d3Smrg pAdaptor->type = XvInputMask | XvImageMask | XvWindowMask; 138232b578d3Smrg pAdaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 138332b578d3Smrg pAdaptor->name = "ATI Mach64 Back-end Overlay Scaler"; 138432b578d3Smrg 138532b578d3Smrg if (pATI->Chip < ATI_CHIP_264VTB) 138632b578d3Smrg { 138732b578d3Smrg enc->width = 384; 138832b578d3Smrg } 138932b578d3Smrg else if (pATI->Chip < ATI_CHIP_264GTPRO || 139032b578d3Smrg pATI->Chip > ATI_CHIP_264LTPRO) 139132b578d3Smrg { 139232b578d3Smrg enc->width = 720; /* default */ 139332b578d3Smrg } 139432b578d3Smrg else 139532b578d3Smrg { 139632b578d3Smrg enc->width = 768; 139732b578d3Smrg } 139832b578d3Smrg pAdaptor->nEncodings = nATIMach64VideoEncoding; 139932b578d3Smrg pAdaptor->pEncodings = ATIMach64VideoEncoding; 140032b578d3Smrg 140132b578d3Smrg pAdaptor->nFormats = nATIMach64VideoFormat; 140232b578d3Smrg pAdaptor->pFormats = ATIMach64VideoFormat; 140332b578d3Smrg 140432b578d3Smrg pAdaptor->nAttributes = nATIMach64Attribute; 140532b578d3Smrg pAdaptor->pAttributes = ATIMach64Attribute; 140632b578d3Smrg 140732b578d3Smrg if (pATI->Chip < ATI_CHIP_264GTPRO) 140832b578d3Smrg { 140932b578d3Smrg /* Older controllers don't have brightness or saturation controls */ 141032b578d3Smrg pAdaptor->nAttributes -= 4; 141132b578d3Smrg pAdaptor->pAttributes += 4; 141232b578d3Smrg } 141332b578d3Smrg 141432b578d3Smrg pAdaptor->nImages = nATIMach64Image; 141532b578d3Smrg pAdaptor->pImages = ATIMach64Image; 141632b578d3Smrg 141732b578d3Smrg pAdaptor->StopVideo = ATIMach64StopVideo; 141832b578d3Smrg pAdaptor->SetPortAttribute = ATIMach64SetPortAttribute; 141932b578d3Smrg pAdaptor->GetPortAttribute = ATIMach64GetPortAttribute; 142032b578d3Smrg pAdaptor->QueryBestSize = ATIMach64QueryBestSize; 142132b578d3Smrg pAdaptor->PutImage = ATIMach64PutImage; 142232b578d3Smrg pAdaptor->QueryImageAttributes = ATIMach64QueryImageAttributes; 142332b578d3Smrg 142432b578d3Smrg REGION_NULL(pScreen, &pATI->VideoClip); 142532b578d3Smrg pATI->ActiveSurface = FALSE; 142632b578d3Smrg 142732b578d3Smrg if (ATIMach64XVAtomGeneration != serverGeneration) 142832b578d3Smrg { 142932b578d3Smrg /* Refresh static data */ 143032b578d3Smrg ATIMach64XVAtomGeneration = serverGeneration; 143132b578d3Smrg 143232b578d3Smrg Index = nATIMach64Attribute - pAdaptor->nAttributes; 143332b578d3Smrg for (; Index < nATIMach64Attribute; Index++) 143432b578d3Smrg ATIMach64AttributeInfo[Index].AttributeID = 143532b578d3Smrg MAKE_ATOM(ATIMach64Attribute[Index].name); 143632b578d3Smrg } 143732b578d3Smrg 143832b578d3Smrg ATIMach64SetDefaultAttributes(pATI, 0); 143932b578d3Smrg 144032b578d3Smrg if (pATI->Chip < ATI_CHIP_264VTB) 144132b578d3Smrg { 144232b578d3Smrg surf0->max_width = 384; 144332b578d3Smrg surf1->max_width = 384; 144432b578d3Smrg } 144532b578d3Smrg else if (pATI->Chip < ATI_CHIP_264GTPRO || 144632b578d3Smrg pATI->Chip > ATI_CHIP_264LTPRO) 144732b578d3Smrg { 144832b578d3Smrg surf0->max_width = 720; /* default */ 144932b578d3Smrg surf1->max_width = 720; 145032b578d3Smrg } 145132b578d3Smrg else 145232b578d3Smrg { 145332b578d3Smrg surf0->max_width = 768; 145432b578d3Smrg surf1->max_width = 768; 145532b578d3Smrg } 145632b578d3Smrg 145732b578d3Smrg if (pATI->Chip < ATI_CHIP_264GTPRO) 145832b578d3Smrg { 145932b578d3Smrg /* No saturation nor brightness */ 146032b578d3Smrg surf0->num_attributes -= 4; 146132b578d3Smrg surf1->num_attributes -= 4; 146232b578d3Smrg surf0->attributes += 4; 146332b578d3Smrg surf1->attributes += 4; 146432b578d3Smrg } 146532b578d3Smrg xf86XVRegisterOffscreenImages(pScreen, ATIMach64Surface, nATIMach64Surface); 146632b578d3Smrg 146732b578d3Smrg if (pppAdaptor) 146832b578d3Smrg *pppAdaptor = ppAdaptor; 146932b578d3Smrg else { 14701b12faf6Smrg free(ppAdaptor[0]); 14711b12faf6Smrg free(ppAdaptor); 147232b578d3Smrg } 147332b578d3Smrg 147432b578d3Smrg return 1; 147532b578d3Smrg} 147632b578d3Smrg 147732b578d3Smrg/* 147832b578d3Smrg * ATIXVPreInit -- 147932b578d3Smrg * 148032b578d3Smrg * This function is called by ATIPreInit() to set up the environment required 148132b578d3Smrg * to support the XVideo extension. 148232b578d3Smrg */ 148332b578d3Smrgvoid 148432b578d3SmrgATIXVPreInit 148532b578d3Smrg( 148632b578d3Smrg ATIPtr pATI 148732b578d3Smrg) 148832b578d3Smrg{ 148932b578d3Smrg (void)xf86XVRegisterGenericAdaptorDriver(ATIMach64XVInitialiseAdaptor); 149032b578d3Smrg} 149132b578d3Smrg 149232b578d3Smrg/* 149332b578d3Smrg * ATIXVFreeAdaptorInfo -- 149432b578d3Smrg * 149532b578d3Smrg * Free XVideo adaptor information. 149632b578d3Smrg */ 149732b578d3Smrgstatic void 149832b578d3SmrgATIXVFreeAdaptorInfo 149932b578d3Smrg( 150032b578d3Smrg XF86VideoAdaptorPtr *ppAdaptor, 150132b578d3Smrg int nAdaptor 150232b578d3Smrg) 150332b578d3Smrg{ 150432b578d3Smrg if (!ppAdaptor) 150532b578d3Smrg return; 150632b578d3Smrg 150732b578d3Smrg while (nAdaptor > 0) 15081b12faf6Smrg free(ppAdaptor[--nAdaptor]); 150932b578d3Smrg 15101b12faf6Smrg free(ppAdaptor); 151132b578d3Smrg} 151232b578d3Smrg 151332b578d3Smrg/* 151432b578d3Smrg * ATIInitializeXVideo -- 151532b578d3Smrg * 151632b578d3Smrg * This function is called to initialise XVideo extension support on a screen. 151732b578d3Smrg */ 151832b578d3SmrgBool 151932b578d3SmrgATIInitializeXVideo 152032b578d3Smrg( 152132b578d3Smrg ScreenPtr pScreen, 152232b578d3Smrg ScrnInfoPtr pScreenInfo, 152332b578d3Smrg ATIPtr pATI 152432b578d3Smrg) 152532b578d3Smrg{ 152632b578d3Smrg XF86VideoAdaptorPtr *ppAdaptor; 152732b578d3Smrg int nAdaptor; 152832b578d3Smrg Bool result; 152932b578d3Smrg 153032b578d3Smrg pScreenInfo->memPhysBase = pATI->LinearBase; 153132b578d3Smrg pScreenInfo->fbOffset = 0; 153232b578d3Smrg 153332b578d3Smrg nAdaptor = xf86XVListGenericAdaptors(pScreenInfo, &ppAdaptor); 153432b578d3Smrg result = xf86XVScreenInit(pScreen, ppAdaptor, nAdaptor); 153532b578d3Smrg 153632b578d3Smrg ATIXVFreeAdaptorInfo(ppAdaptor, nAdaptor); 153732b578d3Smrg 153832b578d3Smrg return result; 153932b578d3Smrg} 154032b578d3Smrg 154132b578d3Smrg/* 154232b578d3Smrg * ATIMach64CloseXVideo -- 154332b578d3Smrg * 154432b578d3Smrg * This function is called during screen termination to clean up after 154532b578d3Smrg * initialisation of Mach64 XVideo support. 154632b578d3Smrg */ 154732b578d3Smrgvoid 154832b578d3SmrgATICloseXVideo 154932b578d3Smrg( 155032b578d3Smrg ScreenPtr pScreen, 155132b578d3Smrg ScrnInfoPtr pScreenInfo, 155232b578d3Smrg ATIPtr pATI 155332b578d3Smrg) 155432b578d3Smrg{ 15551b12faf6Smrg if (!pATI->Block1Base) 15561b12faf6Smrg return; 15571b12faf6Smrg 155832b578d3Smrg ATIMach64StopVideo(pScreenInfo, pATI, TRUE); 155932b578d3Smrg 156032b578d3Smrg REGION_UNINIT(pScreen, &pATI->VideoClip); 156132b578d3Smrg} 156232b578d3Smrg 156332b578d3Smrg/* Functions for offscreen memory management */ 156432b578d3Smrg 156532b578d3Smrg#ifdef USE_XAA 156632b578d3Smrgstatic FBLinearPtr 156732b578d3SmrgATIResizeOffscreenLinear 156832b578d3Smrg( 156932b578d3Smrg ScreenPtr pScreen, 157032b578d3Smrg FBLinearPtr pLinear, 157132b578d3Smrg int Size 157232b578d3Smrg) 157332b578d3Smrg{ 157432b578d3Smrg if (Size <= 0) 157532b578d3Smrg { 157632b578d3Smrg xf86FreeOffscreenLinear(pLinear); 157732b578d3Smrg return NULL; 157832b578d3Smrg } 157932b578d3Smrg 158032b578d3Smrg if (pLinear) 158132b578d3Smrg { 158232b578d3Smrg if ((pLinear->size >= Size) || 158332b578d3Smrg xf86ResizeOffscreenLinear(pLinear, Size)) 158432b578d3Smrg { 158532b578d3Smrg pLinear->MoveLinearCallback = NULL; 158632b578d3Smrg pLinear->RemoveLinearCallback = NULL; 158732b578d3Smrg return pLinear; 158832b578d3Smrg } 158932b578d3Smrg 159032b578d3Smrg xf86FreeOffscreenLinear(pLinear); 159132b578d3Smrg } 159232b578d3Smrg 159332b578d3Smrg pLinear = xf86AllocateOffscreenLinear(pScreen, Size, 16, NULL, NULL, NULL); 159432b578d3Smrg 159532b578d3Smrg if (!pLinear) 159632b578d3Smrg { 159732b578d3Smrg int maxSize; 159832b578d3Smrg 159932b578d3Smrg xf86QueryLargestOffscreenLinear(pScreen, &maxSize, 16, 160032b578d3Smrg PRIORITY_EXTREME); 160132b578d3Smrg 160232b578d3Smrg if (maxSize < Size) 160332b578d3Smrg return NULL; 160432b578d3Smrg 160532b578d3Smrg xf86PurgeUnlockedOffscreenAreas(pScreen); 160632b578d3Smrg pLinear = 160732b578d3Smrg xf86AllocateOffscreenLinear(pScreen, Size, 16, NULL, NULL, NULL); 160832b578d3Smrg } 160932b578d3Smrg 161032b578d3Smrg return pLinear; 161132b578d3Smrg} 161232b578d3Smrg#endif /* USE_XAA */ 161332b578d3Smrg 161432b578d3Smrgstatic pointer 161532b578d3SmrgATIMach64XVMemAlloc 161632b578d3Smrg( 161732b578d3Smrg ScreenPtr pScreen, 161832b578d3Smrg pointer pVideo, 161932b578d3Smrg int size, 162032b578d3Smrg int *offset, 162132b578d3Smrg ATIPtr pATI 162232b578d3Smrg) 162332b578d3Smrg{ 162432b578d3Smrg#ifdef USE_EXA 162532b578d3Smrg if (pATI->useEXA) { 162632b578d3Smrg ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo; 162732b578d3Smrg 162832b578d3Smrg if (area != NULL) { 162932b578d3Smrg if (area->size >= size) { 163032b578d3Smrg *offset = area->offset; 163132b578d3Smrg return area; 163232b578d3Smrg } 163332b578d3Smrg 163432b578d3Smrg exaOffscreenFree(pScreen, area); 163532b578d3Smrg } 163632b578d3Smrg 163732b578d3Smrg area = exaOffscreenAlloc(pScreen, size, 64, TRUE, NULL, NULL); 163832b578d3Smrg if (area != NULL) { 163932b578d3Smrg *offset = area->offset; 164032b578d3Smrg return area; 164132b578d3Smrg } 164232b578d3Smrg } 164332b578d3Smrg#endif /* USE_EXA */ 164432b578d3Smrg 164532b578d3Smrg#ifdef USE_XAA 164632b578d3Smrg if (!pATI->useEXA) { 164732b578d3Smrg FBLinearPtr linear = (FBLinearPtr)pVideo; 164832b578d3Smrg int cpp = pATI->AdjustDepth; 164932b578d3Smrg 165032b578d3Smrg /* XAA allocates in units of pixels at the screen bpp, so adjust size 165132b578d3Smrg * appropriately. 165232b578d3Smrg */ 165332b578d3Smrg size = (size + cpp - 1) / cpp; 165432b578d3Smrg 165532b578d3Smrg linear = ATIResizeOffscreenLinear(pScreen, linear, size); 165632b578d3Smrg if (linear != NULL) { 165732b578d3Smrg *offset = linear->offset * cpp; 165832b578d3Smrg return linear; 165932b578d3Smrg } 166032b578d3Smrg } 166132b578d3Smrg#endif /* USE_XAA */ 166232b578d3Smrg 166332b578d3Smrg *offset = 0; 166432b578d3Smrg return NULL; 166532b578d3Smrg} 166632b578d3Smrg 166732b578d3Smrgstatic void 166832b578d3SmrgATIMach64XVMemFree 166932b578d3Smrg( 167032b578d3Smrg ScreenPtr pScreen, 167132b578d3Smrg pointer pVideo, 167232b578d3Smrg ATIPtr pATI 167332b578d3Smrg) 167432b578d3Smrg{ 167532b578d3Smrg#ifdef USE_EXA 167632b578d3Smrg if (pATI->useEXA) { 167732b578d3Smrg ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo; 167832b578d3Smrg 167932b578d3Smrg if (area != NULL) 168032b578d3Smrg exaOffscreenFree(pScreen, area); 168132b578d3Smrg } 168232b578d3Smrg#endif /* USE_EXA */ 168332b578d3Smrg 168432b578d3Smrg#ifdef USE_XAA 168532b578d3Smrg if (!pATI->useEXA) { 168632b578d3Smrg FBLinearPtr linear = (FBLinearPtr)pVideo; 168732b578d3Smrg 168832b578d3Smrg if (linear != NULL) 168932b578d3Smrg ATIResizeOffscreenLinear(pScreen, linear, 0); 169032b578d3Smrg } 169132b578d3Smrg#endif /* USE_XAA */ 169232b578d3Smrg} 169332b578d3Smrg 1694