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