1ab47cfaaSmrg/* 2ab47cfaaSmrg * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3ab47cfaaSmrg * Copyright (c) 2003-2006, X.Org Foundation 4ab47cfaaSmrg * 5ab47cfaaSmrg * Permission is hereby granted, free of charge, to any person obtaining a 6ab47cfaaSmrg * copy of this software and associated documentation files (the "Software"), 7ab47cfaaSmrg * to deal in the Software without restriction, including without limitation 8ab47cfaaSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9ab47cfaaSmrg * and/or sell copies of the Software, and to permit persons to whom the 10ab47cfaaSmrg * Software is furnished to do so, subject to the following conditions: 11ab47cfaaSmrg * 12ab47cfaaSmrg * The above copyright notice and this permission notice shall be included in 13ab47cfaaSmrg * all copies or substantial portions of the Software. 14ab47cfaaSmrg * 15ab47cfaaSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16ab47cfaaSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17ab47cfaaSmrg * FITESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18ab47cfaaSmrg * COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19ab47cfaaSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20ab47cfaaSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21ab47cfaaSmrg * DEALINGS IN THE SOFTWARE. 22ab47cfaaSmrg * 23ab47cfaaSmrg * Except as contained in this notice, the name of the copyright holder(s) 24ab47cfaaSmrg * and author(s) shall not be used in advertising or otherwise to promote 25ab47cfaaSmrg * the sale, use or other dealings in this Software without prior written 26ab47cfaaSmrg * authorization from the copyright holder(s) and author(s). 27ab47cfaaSmrg */ 28ab47cfaaSmrg 29ab47cfaaSmrg#ifdef HAVE_CONFIG_H 30ab47cfaaSmrg#include "config.h" 31ab47cfaaSmrg#endif 32ab47cfaaSmrg 33ab47cfaaSmrg#include <X11/extensions/Xv.h> 34ab47cfaaSmrg#include "dix.h" 35ab47cfaaSmrg#include "dixstruct.h" 36ab47cfaaSmrg#include "fourcc.h" 37ab47cfaaSmrg 38ab47cfaaSmrg#include "savage_driver.h" 39ab47cfaaSmrg#include "savage_streams.h" 40ab47cfaaSmrg#include "savage_regs.h" 41ab47cfaaSmrg#include "savage_bci.h" 42ab47cfaaSmrg 43ab47cfaaSmrg#define OFF_DELAY 200 /* milliseconds */ 44ab47cfaaSmrg#define FREE_DELAY 60000 45ab47cfaaSmrg 46ab47cfaaSmrg#define OFF_TIMER 0x01 47ab47cfaaSmrg#define FREE_TIMER 0x02 48ab47cfaaSmrg#define CLIENT_VIDEO_ON 0x04 49ab47cfaaSmrg 50ab47cfaaSmrg#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 51ab47cfaaSmrg 52ab47cfaaSmrgvoid savageOUTREG( SavagePtr psav, unsigned long offset, unsigned long value ); 53ab47cfaaSmrg 54ab47cfaaSmrgstatic XF86VideoAdaptorPtr SavageSetupImageVideo(ScreenPtr); 55ab47cfaaSmrgstatic void SavageInitOffscreenImages(ScreenPtr); 56ab47cfaaSmrgstatic void SavageStopVideo(ScrnInfoPtr, pointer, Bool); 57ab47cfaaSmrgstatic int SavageSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 58ab47cfaaSmrgstatic int SavageGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 59ab47cfaaSmrgstatic void SavageQueryBestSize(ScrnInfoPtr, Bool, 60ab47cfaaSmrg short, short, short, short, unsigned int *, unsigned int *, pointer); 61ab47cfaaSmrgstatic int SavagePutImage( ScrnInfoPtr, 62ab47cfaaSmrg short, short, short, short, short, short, short, short, 63ab47cfaaSmrg int, unsigned char*, short, short, Bool, RegionPtr, pointer, 64ab47cfaaSmrg DrawablePtr); 65ab47cfaaSmrgstatic int SavageQueryImageAttributes(ScrnInfoPtr, 66ab47cfaaSmrg int, unsigned short *, unsigned short *, int *, int *); 67ab47cfaaSmrgstatic void SavageFreeMemory(ScrnInfoPtr pScrn, void *mem_struct); 68ab47cfaaSmrg 69ab47cfaaSmrgvoid SavageResetVideo(ScrnInfoPtr pScrn); 70ab47cfaaSmrg 71ab47cfaaSmrgstatic void SavageSetColorKeyOld(ScrnInfoPtr pScrn); 72ab47cfaaSmrgstatic void SavageSetColorKeyNew(ScrnInfoPtr pScrn); 73ab47cfaaSmrgstatic void SavageSetColorKey2000(ScrnInfoPtr pScrn); 74ab47cfaaSmrgstatic void (*SavageSetColorKey)(ScrnInfoPtr pScrn) = NULL; 75ab47cfaaSmrg 76ab47cfaaSmrgstatic void SavageSetColorOld(ScrnInfoPtr pScrn ); 77ab47cfaaSmrgstatic void SavageSetColorNew(ScrnInfoPtr pScrn ); 78ab47cfaaSmrgstatic void SavageSetColor2000(ScrnInfoPtr pScrn ); 79ab47cfaaSmrgstatic void (*SavageSetColor)(ScrnInfoPtr pScrn ) = NULL; 80ab47cfaaSmrg 81ab47cfaaSmrgstatic void (*SavageInitStreams)(ScrnInfoPtr pScrn) = NULL; 82ab47cfaaSmrg 83ab47cfaaSmrgstatic void SavageDisplayVideoOld( 84ab47cfaaSmrg ScrnInfoPtr pScrn, int id, int offset, 85ab47cfaaSmrg short width, short height, int pitch, 86ab47cfaaSmrg int x1, int y1, int x2, int y2, 87ab47cfaaSmrg BoxPtr dstBox, 88ab47cfaaSmrg short src_w, short src_h, 89ab47cfaaSmrg short drw_w, short drw_h 90ab47cfaaSmrg); 91ab47cfaaSmrgstatic void SavageDisplayVideoNew( 92ab47cfaaSmrg ScrnInfoPtr pScrn, int id, int offset, 93ab47cfaaSmrg short width, short height, int pitch, 94ab47cfaaSmrg int x1, int y1, int x2, int y2, 95ab47cfaaSmrg BoxPtr dstBox, 96ab47cfaaSmrg short src_w, short src_h, 97ab47cfaaSmrg short drw_w, short drw_h 98ab47cfaaSmrg); 99ab47cfaaSmrgstatic void SavageDisplayVideo2000( 100ab47cfaaSmrg ScrnInfoPtr pScrn, int id, int offset, 101ab47cfaaSmrg short width, short height, int pitch, 102ab47cfaaSmrg int x1, int y1, int x2, int y2, 103ab47cfaaSmrg BoxPtr dstBox, 104ab47cfaaSmrg short src_w, short src_h, 105ab47cfaaSmrg short drw_w, short drw_h 106ab47cfaaSmrg); 107ab47cfaaSmrgstatic void (*SavageDisplayVideo)( 108ab47cfaaSmrg ScrnInfoPtr pScrn, int id, int offset, 109ab47cfaaSmrg short width, short height, int pitch, 110ab47cfaaSmrg int x1, int y1, int x2, int y2, 111ab47cfaaSmrg BoxPtr dstBox, 112ab47cfaaSmrg short src_w, short src_h, 113ab47cfaaSmrg short drw_w, short drw_h 114ab47cfaaSmrg) = NULL; 115ab47cfaaSmrg 116ab47cfaaSmrg/*static void SavageBlockHandler(int, pointer, pointer, pointer);*/ 117ab47cfaaSmrg 118ab47cfaaSmrg#define XVTRACE 4 119ab47cfaaSmrg 120ab47cfaaSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 121ab47cfaaSmrg 122ab47cfaaSmrgstatic Atom xvColorKey, xvBrightness, xvContrast, xvSaturation, xvHue, xvInterpolation; 123ab47cfaaSmrg 124ab47cfaaSmrg/* client libraries expect an encoding */ 125ab47cfaaSmrgstatic XF86VideoEncodingRec DummyEncoding[1] = 126ab47cfaaSmrg{ 127ab47cfaaSmrg { 128ab47cfaaSmrg 0, 129ab47cfaaSmrg "XV_IMAGE", 130ab47cfaaSmrg 1024, 1024, 131ab47cfaaSmrg {1, 1} 132ab47cfaaSmrg } 133ab47cfaaSmrg}; 134ab47cfaaSmrg 135ab47cfaaSmrg#define NUM_FORMATS 5 136ab47cfaaSmrg 137ab47cfaaSmrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] = 138ab47cfaaSmrg{ 139ab47cfaaSmrg {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 140ab47cfaaSmrg}; 141ab47cfaaSmrg 142ab47cfaaSmrg#define NUM_ATTRIBUTES 6 143ab47cfaaSmrg 144ab47cfaaSmrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] = 145ab47cfaaSmrg{ 146ab47cfaaSmrg {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 147ab47cfaaSmrg {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, 148ab47cfaaSmrg {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}, 149ab47cfaaSmrg {XvSettable | XvGettable, 0, 255, "XV_SATURATION"}, 150ab47cfaaSmrg {XvSettable | XvGettable, -180, 180, "XV_HUE"}, 151ab47cfaaSmrg {XvSettable | XvGettable, 0, 1, "XV_VERTICAL_INTERPOLATION"} 152ab47cfaaSmrg}; 153ab47cfaaSmrg 154ab47cfaaSmrg#define FOURCC_RV16 0x36315652 155ab47cfaaSmrg#define FOURCC_RV15 0x35315652 156ab47cfaaSmrg#define FOURCC_Y211 0x31313259 157ab47cfaaSmrg 158ab47cfaaSmrg/* 159ab47cfaaSmrg * For completeness sake, here is a cracking of the fourcc's I support. 160ab47cfaaSmrg * 161ab47cfaaSmrg * YUY2, packed 4:2:2, byte order: Y0 U0 Y1 V0 Y2 U2 Y3 V2 162ab47cfaaSmrg * Y211, packed 2:1:1, byte order: Y0 U0 Y2 V0 Y4 U2 Y6 V2 163ab47cfaaSmrg * YV12, planar 4:1:1, Y plane HxW, V plane H/2xW/2, U plane H/2xW/2 164ab47cfaaSmrg * I420, planar 4:1:1, Y plane HxW, U plane H/2xW/2, V plane H/2xW/2 165ab47cfaaSmrg * (I420 is also known as IYUV) 166ab47cfaaSmrg */ 167ab47cfaaSmrg 168ab47cfaaSmrg 169ab47cfaaSmrgstatic XF86ImageRec Images[] = 170ab47cfaaSmrg{ 171ab47cfaaSmrg XVIMAGE_YUY2, 172ab47cfaaSmrg XVIMAGE_YV12, 173ab47cfaaSmrg XVIMAGE_I420, 174ab47cfaaSmrg { 175ab47cfaaSmrg FOURCC_RV15, 176ab47cfaaSmrg XvRGB, 177ab47cfaaSmrg LSBFirst, 178ab47cfaaSmrg {'R','V','1','5', 179ab47cfaaSmrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 180ab47cfaaSmrg 16, 181ab47cfaaSmrg XvPacked, 182ab47cfaaSmrg 1, 183ab47cfaaSmrg 15, 0x001F, 0x03E0, 0x7C00, 184ab47cfaaSmrg 0, 0, 0, 185ab47cfaaSmrg 0, 0, 0, 186ab47cfaaSmrg 0, 0, 0, 187ab47cfaaSmrg {'R','V','B',0, 188ab47cfaaSmrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 189ab47cfaaSmrg XvTopToBottom 190ab47cfaaSmrg }, 191ab47cfaaSmrg { 192ab47cfaaSmrg FOURCC_RV16, 193ab47cfaaSmrg XvRGB, 194ab47cfaaSmrg LSBFirst, 195ab47cfaaSmrg {'R','V','1','6', 196ab47cfaaSmrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 197ab47cfaaSmrg 16, 198ab47cfaaSmrg XvPacked, 199ab47cfaaSmrg 1, 200ab47cfaaSmrg 16, 0x001F, 0x07E0, 0xF800, 201ab47cfaaSmrg 0, 0, 0, 202ab47cfaaSmrg 0, 0, 0, 203ab47cfaaSmrg 0, 0, 0, 204ab47cfaaSmrg {'R','V','B',0, 205ab47cfaaSmrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 206ab47cfaaSmrg XvTopToBottom 207ab47cfaaSmrg }, 208ab47cfaaSmrg { 209ab47cfaaSmrg FOURCC_Y211, 210ab47cfaaSmrg XvYUV, 211ab47cfaaSmrg LSBFirst, 212ab47cfaaSmrg {'Y','2','1','1', 213ab47cfaaSmrg 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, 214ab47cfaaSmrg 6, 215ab47cfaaSmrg XvPacked, 216ab47cfaaSmrg 3, 217ab47cfaaSmrg 0, 0, 0, 0 , 218ab47cfaaSmrg 8, 8, 8, 219ab47cfaaSmrg 2, 4, 4, 220ab47cfaaSmrg 1, 1, 1, 221ab47cfaaSmrg {'Y','U','Y','V', 222ab47cfaaSmrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 223ab47cfaaSmrg XvTopToBottom 224ab47cfaaSmrg } 225ab47cfaaSmrg}; 226ab47cfaaSmrg 227ab47cfaaSmrg#define NUM_IMAGES (sizeof(Images)/sizeof(Images[0])) 228ab47cfaaSmrg 229ab47cfaaSmrgtypedef struct { 230ab47cfaaSmrg int brightness; /* -128 .. 127 */ 231ab47cfaaSmrg CARD32 contrast; /* 0 .. 255 */ 232ab47cfaaSmrg CARD32 saturation; /* 0 .. 255 */ 233ab47cfaaSmrg int hue; /* -128 .. 127 */ 234ab47cfaaSmrg Bool interpolation; /* on/off */ 235ab47cfaaSmrg 236ab47cfaaSmrg /*FBAreaPtr area;*/ 237ab47cfaaSmrg RegionRec clip; 238ab47cfaaSmrg CARD32 colorKey; 239ab47cfaaSmrg CARD32 videoStatus; 240ab47cfaaSmrg Time offTime; 241ab47cfaaSmrg Time freeTime; 242ab47cfaaSmrg int lastKnownPitch; 243ab47cfaaSmrg 2441473d951Smrg void *video_memory; /* opaque memory management information structure */ 2451473d951Smrg CARD32 video_offset; /* offset in video memory of packed YUV buffer */ 2461473d951Smrg 2471473d951Smrg void *video_planarmem; /* opaque memory management information structure */ 2481473d951Smrg CARD32 video_planarbuf; /* offset in video memory of planar YV12 buffer */ 2491473d951Smrg 250aa9e3350Smrg#ifdef SAVAGEDRI 2511473d951Smrg Bool tried_agp; /* TRUE if AGP allocation has been tried */ 2521473d951Smrg CARD32 agpBase; /* Physical address of aperture base */ 2531473d951Smrg CARD32 agpBufferOffset; /* Offset of buffer in AGP memory, or 0 if unavailable */ 2541473d951Smrg drmAddress agpBufferMap; /* Mapping of AGP buffer in process memory, or NULL */ 2556aec45a7Smrg#endif 256ab47cfaaSmrg 257ab47cfaaSmrg} SavagePortPrivRec, *SavagePortPrivPtr; 258ab47cfaaSmrg 259ab47cfaaSmrg 260ab47cfaaSmrg#define GET_PORT_PRIVATE(pScrn) \ 261ab47cfaaSmrg (SavagePortPrivPtr)((SAVPTR(pScrn))->adaptor->pPortPrivates[0].ptr) 262ab47cfaaSmrg 263ab47cfaaSmrgstatic 264ab47cfaaSmrgunsigned int GetBlendForFourCC( int id ) 265ab47cfaaSmrg{ 266ab47cfaaSmrg switch( id ) { 267ab47cfaaSmrg case FOURCC_YUY2: 268ab47cfaaSmrg case FOURCC_YV12: /* shouldn't this be 4? */ 269ab47cfaaSmrg case FOURCC_I420: /* shouldn't this be 4? */ 270ab47cfaaSmrg return 1; 271ab47cfaaSmrg case FOURCC_Y211: 272ab47cfaaSmrg return 4; 273ab47cfaaSmrg case FOURCC_RV15: 274ab47cfaaSmrg return 3; 275ab47cfaaSmrg case FOURCC_RV16: 276ab47cfaaSmrg return 5; 277ab47cfaaSmrg default: 278ab47cfaaSmrg return 0; 279ab47cfaaSmrg } 280ab47cfaaSmrg} 281ab47cfaaSmrg 282ab47cfaaSmrgstatic 283ab47cfaaSmrgunsigned int GetBlendForFourCC2000( int id ) 284ab47cfaaSmrg{ 285ab47cfaaSmrg switch( id ) { 286ab47cfaaSmrg case FOURCC_YUY2: 287ab47cfaaSmrg return 1; 288ab47cfaaSmrg case FOURCC_I420: 289ab47cfaaSmrg return 1; /* was 4 */ 290ab47cfaaSmrg case FOURCC_YV12: 291ab47cfaaSmrg return 1; /* was 4 */ 292ab47cfaaSmrg case FOURCC_Y211: 293ab47cfaaSmrg return 4; 294ab47cfaaSmrg case FOURCC_RV15: 295ab47cfaaSmrg return 3; 296ab47cfaaSmrg case FOURCC_RV16: 297ab47cfaaSmrg return 5; 298ab47cfaaSmrg default: 299ab47cfaaSmrg return 0; 300ab47cfaaSmrg } 301ab47cfaaSmrg} 302ab47cfaaSmrg 303ab47cfaaSmrg 304ab47cfaaSmrgvoid savageOUTREG( SavagePtr psav, unsigned long offset, unsigned long value ) 305ab47cfaaSmrg{ 306ab47cfaaSmrg ErrorF( "MMIO %08lx, was %08lx, want %08lx,", 3072b2b4fcbSmrg offset, (unsigned long)MMIO_IN32( psav->MapBase, offset ), value ); 308ab47cfaaSmrg MMIO_OUT32( psav->MapBase, offset, value ); 3092b2b4fcbSmrg ErrorF( " now %08lx\n", (unsigned long)MMIO_IN32( psav->MapBase, offset ) ); 310ab47cfaaSmrg} 311ab47cfaaSmrg 312ab47cfaaSmrg#if 0 313ab47cfaaSmrgstatic void 314ab47cfaaSmrgSavageClipVWindow(ScrnInfoPtr pScrn) 315ab47cfaaSmrg{ 316ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 317ab47cfaaSmrg 318ab47cfaaSmrg if( (psav->Chipset == S3_SAVAGE_MX) || 319ab47cfaaSmrg (psav->Chipset == S3_SUPERSAVAGE) ) { 320ab47cfaaSmrg if (psav->IsSecondary) { 321ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_SZ, 0); 322ab47cfaaSmrg } else if (psav->IsPrimary) { 323ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_SZ, 0); 324ab47cfaaSmrg } else { 325ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_SZ, 0); 326ab47cfaaSmrg#if 0 327ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_SZ, 0); 328ab47cfaaSmrg#endif 329ab47cfaaSmrg } 330ab47cfaaSmrg } else if (psav->Chipset == S3_SAVAGE2000) { 331ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_SZ, 0); 332ab47cfaaSmrg } else { 333ab47cfaaSmrg OUTREG( SSTREAM_WINDOW_SIZE_REG, 1); 334ab47cfaaSmrg OUTREG( SSTREAM_WINDOW_START_REG, 0x03ff03ff); 335ab47cfaaSmrg } 336ab47cfaaSmrg} 337ab47cfaaSmrg#endif 338ab47cfaaSmrg 339ab47cfaaSmrgvoid SavageInitVideo(ScreenPtr pScreen) 340ab47cfaaSmrg{ 341aa9e3350Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 342ab47cfaaSmrg XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 343ab47cfaaSmrg XF86VideoAdaptorPtr newAdaptor = NULL; 344ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 345ab47cfaaSmrg int num_adaptors; 346ab47cfaaSmrg 347ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageInitVideo\n"); 348ab47cfaaSmrg if (S3_SAVAGE_MOBILE_SERIES(psav->Chipset)) 349ab47cfaaSmrg { 350ab47cfaaSmrg newAdaptor = SavageSetupImageVideo(pScreen); 351ab47cfaaSmrg SavageInitOffscreenImages(pScreen); 352ab47cfaaSmrg 353ab47cfaaSmrg SavageInitStreams = SavageInitStreamsNew; 354ab47cfaaSmrg SavageSetColor = SavageSetColorNew; 355ab47cfaaSmrg SavageSetColorKey = SavageSetColorKeyNew; 356ab47cfaaSmrg SavageDisplayVideo = SavageDisplayVideoNew; 357ab47cfaaSmrg } 358ab47cfaaSmrg else if (psav->Chipset == S3_SAVAGE2000) 359ab47cfaaSmrg { 360ab47cfaaSmrg newAdaptor = SavageSetupImageVideo(pScreen); 361ab47cfaaSmrg SavageInitOffscreenImages(pScreen); 362ab47cfaaSmrg 363ab47cfaaSmrg SavageInitStreams = SavageInitStreams2000; 364ab47cfaaSmrg SavageSetColor = SavageSetColor2000; 365ab47cfaaSmrg SavageSetColorKey = SavageSetColorKey2000; 366ab47cfaaSmrg SavageDisplayVideo = SavageDisplayVideo2000; 367ab47cfaaSmrg } 368ab47cfaaSmrg else 369ab47cfaaSmrg { 370ab47cfaaSmrg newAdaptor = SavageSetupImageVideo(pScreen); 371ab47cfaaSmrg SavageInitOffscreenImages(pScreen); 372ab47cfaaSmrg 373ab47cfaaSmrg SavageInitStreams = SavageInitStreamsOld; 374ab47cfaaSmrg SavageSetColor = SavageSetColorOld; 375ab47cfaaSmrg SavageSetColorKey = SavageSetColorKeyOld; 376ab47cfaaSmrg SavageDisplayVideo = SavageDisplayVideoOld; 377ab47cfaaSmrg } 378ab47cfaaSmrg 379ab47cfaaSmrg num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 380ab47cfaaSmrg 381ab47cfaaSmrg if(newAdaptor) { 382ab47cfaaSmrg if(!num_adaptors) { 383ab47cfaaSmrg num_adaptors = 1; 384ab47cfaaSmrg adaptors = &newAdaptor; 385ab47cfaaSmrg } else { 386ab47cfaaSmrg newAdaptors = /* need to free this someplace */ 387aa9e3350Smrg malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); 388ab47cfaaSmrg if(newAdaptors) { 389ab47cfaaSmrg memcpy(newAdaptors, adaptors, num_adaptors * 390ab47cfaaSmrg sizeof(XF86VideoAdaptorPtr)); 391ab47cfaaSmrg newAdaptors[num_adaptors] = newAdaptor; 392ab47cfaaSmrg adaptors = newAdaptors; 393ab47cfaaSmrg num_adaptors++; 394ab47cfaaSmrg } 395ab47cfaaSmrg } 396ab47cfaaSmrg } 397ab47cfaaSmrg 398ab47cfaaSmrg if(num_adaptors) 399ab47cfaaSmrg xf86XVScreenInit(pScreen, adaptors, num_adaptors); 400ab47cfaaSmrg 401ab47cfaaSmrg if(newAdaptors) 402aa9e3350Smrg free(newAdaptors); 403ab47cfaaSmrg 404ab47cfaaSmrg if( newAdaptor ) 405ab47cfaaSmrg { 406ab47cfaaSmrg psav->videoFourCC = 0; 407ab47cfaaSmrg } 408ab47cfaaSmrg} 409ab47cfaaSmrg 410ab47cfaaSmrg 411ab47cfaaSmrgvoid SavageSetColorKeyOld(ScrnInfoPtr pScrn) 412ab47cfaaSmrg{ 413ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 414ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 415ab47cfaaSmrg int red, green, blue; 416ab47cfaaSmrg 417ab47cfaaSmrg /* Here, we reset the colorkey and all the controls. */ 418ab47cfaaSmrg 419ab47cfaaSmrg red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; 420ab47cfaaSmrg green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; 421ab47cfaaSmrg blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 422ab47cfaaSmrg 423ab47cfaaSmrg if( !pPriv->colorKey ) { 424ab47cfaaSmrg OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0 ); 425ab47cfaaSmrg OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 0 ); 426ab47cfaaSmrg OUTREG( BLEND_CONTROL_REG, 0 ); 427ab47cfaaSmrg } 428ab47cfaaSmrg else { 429ab47cfaaSmrg switch (pScrn->depth) { 430ab47cfaaSmrg case 8: 431ab47cfaaSmrg OUTREG( COL_CHROMA_KEY_CONTROL_REG, 432ab47cfaaSmrg 0x37000000 | (pPriv->colorKey & 0xFF) ); 433ab47cfaaSmrg OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 434ab47cfaaSmrg 0x00000000 | (pPriv->colorKey & 0xFF) ); 435ab47cfaaSmrg break; 436ab47cfaaSmrg case 15: 437ab47cfaaSmrg OUTREG( COL_CHROMA_KEY_CONTROL_REG, 438ab47cfaaSmrg 0x05000000 | (red<<19) | (green<<11) | (blue<<3) ); 439ab47cfaaSmrg OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 440ab47cfaaSmrg 0x00000000 | (red<<19) | (green<<11) | (blue<<3) ); 441ab47cfaaSmrg break; 442ab47cfaaSmrg case 16: 443ab47cfaaSmrg OUTREG( COL_CHROMA_KEY_CONTROL_REG, 444ab47cfaaSmrg 0x16000000 | (red<<19) | (green<<10) | (blue<<3) ); 445ab47cfaaSmrg OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 446ab47cfaaSmrg 0x00020002 | (red<<19) | (green<<10) | (blue<<3) ); 447ab47cfaaSmrg break; 448ab47cfaaSmrg case 24: 449ab47cfaaSmrg OUTREG( COL_CHROMA_KEY_CONTROL_REG, 450ab47cfaaSmrg 0x17000000 | (red<<16) | (green<<8) | (blue) ); 451ab47cfaaSmrg OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 452ab47cfaaSmrg 0x00000000 | (red<<16) | (green<<8) | (blue) ); 453ab47cfaaSmrg break; 454ab47cfaaSmrg } 455ab47cfaaSmrg 456ab47cfaaSmrg /* We use destination colorkey */ 457ab47cfaaSmrg OUTREG( BLEND_CONTROL_REG, 0x05000000 ); 458ab47cfaaSmrg } 459ab47cfaaSmrg} 460ab47cfaaSmrg 461ab47cfaaSmrgvoid SavageSetColorKeyNew(ScrnInfoPtr pScrn) 462ab47cfaaSmrg{ 463ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 464ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 465ab47cfaaSmrg int red, green, blue; 466ab47cfaaSmrg 467ab47cfaaSmrg /* Here, we reset the colorkey and all the controls. */ 468ab47cfaaSmrg 469ab47cfaaSmrg red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; 470ab47cfaaSmrg green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; 471ab47cfaaSmrg blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 472ab47cfaaSmrg 473ab47cfaaSmrg if( !pPriv->colorKey ) { 474ab47cfaaSmrg if (psav->IsSecondary) { 475ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 0 ); 476ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 0 ); 477ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 478ab47cfaaSmrg } else if (psav->IsPrimary) { 479ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 0 ); 480ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 0 ); 481ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 482ab47cfaaSmrg } else { 483ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 0 ); 484ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 0 ); 485ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 486ab47cfaaSmrg#if 0 487ab47cfaaSmrg sleep(1); 488ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 0 ); 489ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 0 ); 490ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 491ab47cfaaSmrg#endif 492ab47cfaaSmrg } 493ab47cfaaSmrg } 494ab47cfaaSmrg else { 495ab47cfaaSmrg switch (pScrn->depth) { 496ab47cfaaSmrg case 8: 497ab47cfaaSmrg if (psav->IsSecondary) { 498ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 499ab47cfaaSmrg 0x47000000 | (pPriv->colorKey & 0xFF) ); 500ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 501ab47cfaaSmrg 0x47000000 | (pPriv->colorKey & 0xFF) ); 502ab47cfaaSmrg } else if (psav->IsPrimary) { 503ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 504ab47cfaaSmrg 0x47000000 | (pPriv->colorKey & 0xFF) ); 505ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 506ab47cfaaSmrg 0x47000000 | (pPriv->colorKey & 0xFF) ); 507ab47cfaaSmrg } else { 508ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 509ab47cfaaSmrg 0x47000000 | (pPriv->colorKey & 0xFF) ); 510ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 511ab47cfaaSmrg 0x47000000 | (pPriv->colorKey & 0xFF) ); 512ab47cfaaSmrg#if 0 513ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 514ab47cfaaSmrg 0x47000000 | (pPriv->colorKey & 0xFF) ); 515ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 516ab47cfaaSmrg 0x47000000 | (pPriv->colorKey & 0xFF) ); 517ab47cfaaSmrg#endif 518ab47cfaaSmrg } 519ab47cfaaSmrg break; 520ab47cfaaSmrg case 15: 521ab47cfaaSmrg if (psav->IsSecondary) { 522ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 523ab47cfaaSmrg 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 524ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 525ab47cfaaSmrg 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 526ab47cfaaSmrg } else if (psav->IsPrimary) { 527ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 528ab47cfaaSmrg 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 529ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 530ab47cfaaSmrg 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 531ab47cfaaSmrg } else { 532ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 533ab47cfaaSmrg 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 534ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 535ab47cfaaSmrg 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 536ab47cfaaSmrg#if 0 537ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 538ab47cfaaSmrg 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 539ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 540ab47cfaaSmrg 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 541ab47cfaaSmrg#endif 542ab47cfaaSmrg } 543ab47cfaaSmrg break; 544ab47cfaaSmrg case 16: 545ab47cfaaSmrg if (psav->IsSecondary) { 546ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 547ab47cfaaSmrg 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 548ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 549ab47cfaaSmrg 0x46020002 | (red<<19) | (green<<10) | (blue<<3) ); 550ab47cfaaSmrg } else if (psav->IsPrimary) { 551ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 552ab47cfaaSmrg 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 553ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 554ab47cfaaSmrg 0x46020002 | (red<<19) | (green<<10) | (blue<<3) ); 555ab47cfaaSmrg } else { 556ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 557ab47cfaaSmrg 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 558ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 559ab47cfaaSmrg 0x46020002 | (red<<19) | (green<<10) | (blue<<3) ); 560ab47cfaaSmrg#if 0 561ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 562ab47cfaaSmrg 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 563ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 564ab47cfaaSmrg 0x46020002 | (red<<19) | (green<<10) | (blue<<3) ); 565ab47cfaaSmrg#endif 566ab47cfaaSmrg } 567ab47cfaaSmrg break; 568ab47cfaaSmrg case 24: 569ab47cfaaSmrg if (psav->IsSecondary) { 570ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 571ab47cfaaSmrg 0x47000000 | (red<<16) | (green<<8) | (blue) ); 572ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 573ab47cfaaSmrg 0x47000000 | (red<<16) | (green<<8) | (blue) ); 574ab47cfaaSmrg } else if (psav->IsPrimary) { 575ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 576ab47cfaaSmrg 0x47000000 | (red<<16) | (green<<8) | (blue) ); 577ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 578ab47cfaaSmrg 0x47000000 | (red<<16) | (green<<8) | (blue) ); 579ab47cfaaSmrg } else { 580ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 581ab47cfaaSmrg 0x47000000 | (red<<16) | (green<<8) | (blue) ); 582ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 583ab47cfaaSmrg 0x47000000 | (red<<16) | (green<<8) | (blue) ); 584ab47cfaaSmrg#if 0 585ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_LOW, 586ab47cfaaSmrg 0x47000000 | (red<<16) | (green<<8) | (blue) ); 587ab47cfaaSmrg OUTREG( SEC_STREAM2_CKEY_UPPER, 588ab47cfaaSmrg 0x47000000 | (red<<16) | (green<<8) | (blue) ); 589ab47cfaaSmrg#endif 590ab47cfaaSmrg } 591ab47cfaaSmrg break; 592ab47cfaaSmrg } 593ab47cfaaSmrg 594ab47cfaaSmrg /* We assume destination colorkey */ 595ab47cfaaSmrg if (psav->IsSecondary) { 596ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 597ab47cfaaSmrg } else if (psav->IsPrimary) { 598ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 599ab47cfaaSmrg } else { 600ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 601ab47cfaaSmrg#if 0 602ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 603ab47cfaaSmrg#endif 604ab47cfaaSmrg } 605ab47cfaaSmrg } 606ab47cfaaSmrg} 607ab47cfaaSmrg 608ab47cfaaSmrgvoid SavageSetColorKey2000(ScrnInfoPtr pScrn) 609ab47cfaaSmrg{ 610ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 611ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 612ab47cfaaSmrg int red, green, blue; 613ab47cfaaSmrg 614ab47cfaaSmrg /* Here, we reset the colorkey and all the controls. */ 615ab47cfaaSmrg 616ab47cfaaSmrg red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; 617ab47cfaaSmrg green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; 618ab47cfaaSmrg blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 619ab47cfaaSmrg 620ab47cfaaSmrg if( !pPriv->colorKey ) { 621ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 0); 622ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 0); 623ab47cfaaSmrg OUTREG( BLEND_CONTROL, (8 << 2)); 624ab47cfaaSmrg } 625ab47cfaaSmrg else { 626ab47cfaaSmrg switch (pScrn->depth) { 627ab47cfaaSmrg case 8: 628ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 629ab47cfaaSmrg 0x47000000 | (pPriv->colorKey & 0xFF) ); 630ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 631ab47cfaaSmrg (pPriv->colorKey & 0xFF) ); 632ab47cfaaSmrg break; 633ab47cfaaSmrg case 15: 634ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 635ab47cfaaSmrg 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 636ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 637ab47cfaaSmrg (red<<19) | (green<<11) | (blue<<3) ); 638ab47cfaaSmrg break; 639ab47cfaaSmrg case 16: 640ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 641ab47cfaaSmrg 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 642ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 643ab47cfaaSmrg (red<<19) | (green<<10) | (blue<<3) ); 644ab47cfaaSmrg break; 645ab47cfaaSmrg case 24: 646ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_LOW, 647ab47cfaaSmrg 0x47000000 | (red<<16) | (green<<8) | (blue) ); 648ab47cfaaSmrg OUTREG( SEC_STREAM_CKEY_UPPER, 649ab47cfaaSmrg (red<<16) | (green<<8) | (blue) ); 650ab47cfaaSmrg break; 651ab47cfaaSmrg } 652ab47cfaaSmrg 653ab47cfaaSmrg /* We assume destination colorkey */ 654ab47cfaaSmrg OUTREG( BLEND_CONTROL, INREG(BLEND_CONTROL) | (8 << 2)); 655ab47cfaaSmrg } 656ab47cfaaSmrg} 657ab47cfaaSmrg 658ab47cfaaSmrgvoid SavageSetColorOld( ScrnInfoPtr pScrn ) 659ab47cfaaSmrg{ 660ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 661ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 662ab47cfaaSmrg 663ab47cfaaSmrg xf86ErrorFVerb(XVTRACE, "bright %d, contrast %d, saturation %d, hue %d\n", 664ab47cfaaSmrg pPriv->brightness, (int)pPriv->contrast, (int)pPriv->saturation, pPriv->hue ); 665ab47cfaaSmrg 666ab47cfaaSmrg if( 667ab47cfaaSmrg (psav->videoFourCC == FOURCC_RV15) || 668ab47cfaaSmrg (psav->videoFourCC == FOURCC_RV16) 669ab47cfaaSmrg ) 670ab47cfaaSmrg { 671ab47cfaaSmrg OUTREG( COLOR_ADJUSTMENT_REG, 0 ); 672ab47cfaaSmrg } 673ab47cfaaSmrg else 674ab47cfaaSmrg { 675ab47cfaaSmrg /* Change 0..255 into 0..15 */ 676ab47cfaaSmrg long sat = pPriv->saturation * 16 / 256; 677ab47cfaaSmrg double hue = pPriv->hue * 0.017453292; 678ab47cfaaSmrg unsigned long hs1 = ((long)(sat * cos(hue))) & 0x1f; 679ab47cfaaSmrg unsigned long hs2 = ((long)(sat * sin(hue))) & 0x1f; 680ab47cfaaSmrg 681ab47cfaaSmrg OUTREG( COLOR_ADJUSTMENT_REG, 682ab47cfaaSmrg 0x80008000 | 683ab47cfaaSmrg (pPriv->brightness + 128) | 684ab47cfaaSmrg ((pPriv->contrast & 0xf8) << (12-7)) | 685ab47cfaaSmrg (hs1 << 16) | 686ab47cfaaSmrg (hs2 << 24) 687ab47cfaaSmrg ); 688ab47cfaaSmrg 689ab47cfaaSmrg } 690ab47cfaaSmrg} 691ab47cfaaSmrg 692ab47cfaaSmrgvoid SavageSetColorNew( ScrnInfoPtr pScrn ) 693ab47cfaaSmrg{ 694ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 695ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 696ab47cfaaSmrg 697ab47cfaaSmrg /* Brightness/contrast/saturation/hue computations. */ 698ab47cfaaSmrg 699ab47cfaaSmrg double k, dk1, dk2, dk3, dk4, dk5, dk6, dk7, dkb; 700ab47cfaaSmrg int k1, k2, k3, k4, k5, k6, k7, kb; 701ab47cfaaSmrg double s = pPriv->saturation / 128.0; 702ab47cfaaSmrg double h = pPriv->hue * 0.017453292; 703ab47cfaaSmrg unsigned long assembly1, assembly2, assembly3; 704ab47cfaaSmrg 705ab47cfaaSmrg xf86ErrorFVerb(XVTRACE, "bright %d, contrast %d, saturation %d, hue %d\n", 706ab47cfaaSmrg pPriv->brightness, (int)pPriv->contrast, (int)pPriv->saturation, pPriv->hue ); 707ab47cfaaSmrg 708ab47cfaaSmrg if( psav->videoFourCC == FOURCC_Y211 ) 709ab47cfaaSmrg k = 1.0; /* YUV */ 710ab47cfaaSmrg else 711ab47cfaaSmrg k = 1.14; /* YCrCb */ 712ab47cfaaSmrg 713ab47cfaaSmrg /* 714ab47cfaaSmrg * The S3 documentation must be wrong for k4 and k5. Their default 715ab47cfaaSmrg * values, which they hardcode in their Windows driver, have the 716ab47cfaaSmrg * opposite sign from the results in the register spec. 717ab47cfaaSmrg */ 718ab47cfaaSmrg 719ab47cfaaSmrg dk1 = k * pPriv->contrast; 720ab47cfaaSmrg dk2 = 64.0 * 1.371 * k * s * cos(h); 721ab47cfaaSmrg dk3 = -64.0 * 1.371 * k * s * sin(h); 722ab47cfaaSmrg dk4 = -128.0 * k * s * (0.698 * cos(h) - 0.336 * sin(h)); 723ab47cfaaSmrg dk5 = -128.0 * k * s * (0.698 * sin(h) + 0.336 * cos(h)); 724ab47cfaaSmrg dk6 = 64.0 * 1.732 * k * s * sin(h); /* == k3 / 1.26331, right? */ 725ab47cfaaSmrg dk7 = 64.0 * 1.732 * k * s * cos(h); /* == k2 / -1.26331, right? */ 726ab47cfaaSmrg dkb = 128.0 * pPriv->brightness + 64.0; 727ab47cfaaSmrg if( psav->videoFourCC != FOURCC_Y211 ) 728ab47cfaaSmrg dkb -= dk1 * 14.0; 729ab47cfaaSmrg 730ab47cfaaSmrg k1 = (int)(dk1+0.5) & 0x1ff; 731ab47cfaaSmrg k2 = (int)(dk2+0.5) & 0x1ff; 732ab47cfaaSmrg k3 = (int)(dk3+0.5) & 0x1ff; 733ab47cfaaSmrg assembly1 = (k3<<18) | (k2<<9) | k1; 734ab47cfaaSmrg xf86ErrorFVerb(XVTRACE+1, "CC1 = %08lx ", assembly1 ); 735ab47cfaaSmrg 736ab47cfaaSmrg k4 = (int)(dk4+0.5) & 0x1ff; 737ab47cfaaSmrg k5 = (int)(dk5+0.5) & 0x1ff; 738ab47cfaaSmrg k6 = (int)(dk6+0.5) & 0x1ff; 739ab47cfaaSmrg assembly2 = (k6<<18) | (k5<<9) | k4; 740ab47cfaaSmrg xf86ErrorFVerb(XVTRACE+1, "CC2 = %08lx ", assembly2 ); 741ab47cfaaSmrg 742ab47cfaaSmrg k7 = (int)(dk7+0.5) & 0x1ff; 743ab47cfaaSmrg kb = (int)(dkb+0.5) & 0xffff; 744ab47cfaaSmrg assembly3 = (kb<<9) | k7; 745ab47cfaaSmrg xf86ErrorFVerb(XVTRACE+1, "CC3 = %08lx\n", assembly3 ); 746ab47cfaaSmrg 747ab47cfaaSmrg if (psav->IsSecondary) { 748ab47cfaaSmrg OUTREG( SEC_STREAM2_COLOR_CONVERT1, assembly1 ); 749ab47cfaaSmrg OUTREG( SEC_STREAM2_COLOR_CONVERT2, assembly2 ); 750ab47cfaaSmrg OUTREG( SEC_STREAM2_COLOR_CONVERT3, assembly3 ); 751ab47cfaaSmrg } else if (psav->IsPrimary) { 752ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly1 ); 753ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly2 ); 754ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly3 ); 755ab47cfaaSmrg } else { 756ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly1 ); 757ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly2 ); 758ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly3 ); 759ab47cfaaSmrg#if 0 760ab47cfaaSmrg sleep(1); 761ab47cfaaSmrg OUTREG( SEC_STREAM2_COLOR_CONVERT1, assembly1 ); 762ab47cfaaSmrg OUTREG( SEC_STREAM2_COLOR_CONVERT2, assembly2 ); 763ab47cfaaSmrg OUTREG( SEC_STREAM2_COLOR_CONVERT3, assembly3 ); 764ab47cfaaSmrg#endif 765ab47cfaaSmrg } 766ab47cfaaSmrg} 767ab47cfaaSmrg 768ab47cfaaSmrgvoid SavageSetColor2000( ScrnInfoPtr pScrn ) 769ab47cfaaSmrg{ 770ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 771ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 772ab47cfaaSmrg 773ab47cfaaSmrg /* Brightness/contrast/saturation/hue computations. */ 774ab47cfaaSmrg 775ab47cfaaSmrg double k, yb, dk1, dk2, dk3, dk4, dk5, dk6, dk7, dkb; 776ab47cfaaSmrg int k1, k2, k3, k4, k5, k6, k7, kb; 777ab47cfaaSmrg double s = pPriv->saturation / 10000.0; 778ab47cfaaSmrg double h = pPriv->hue * 0.017453292; 779ab47cfaaSmrg unsigned long assembly1, assembly2, assembly3, assembly4; 780ab47cfaaSmrg unsigned long brightness = pPriv->brightness; 781ab47cfaaSmrg 782ab47cfaaSmrg xf86ErrorFVerb(XVTRACE, "bright %d, contrast %d, saturation %d, hue %d\n", 783ab47cfaaSmrg pPriv->brightness, (int)pPriv->contrast, (int)pPriv->saturation, pPriv->hue ); 784ab47cfaaSmrg 785ab47cfaaSmrg if( psav->videoFourCC == FOURCC_Y211 ) { 786ab47cfaaSmrg k = 1.0;/* YUV */ 787ab47cfaaSmrg yb = 0.0; 788ab47cfaaSmrg } else { 789ab47cfaaSmrg k = 1.1;/* YCrCb */ 790ab47cfaaSmrg yb = 14.0; 791ab47cfaaSmrg } 792ab47cfaaSmrg 793ab47cfaaSmrg dk1 = 128 * k * (pPriv->contrast / 10000.0); 794ab47cfaaSmrg if (dk1 < 0) 795ab47cfaaSmrg dk1 -= 0.5; 796ab47cfaaSmrg else 797ab47cfaaSmrg dk1 += 0.5; 798ab47cfaaSmrg dk2 = 64.0 * 1.371 * k * s * cos(h); 799ab47cfaaSmrg if (dk2 < 0) 800ab47cfaaSmrg dk2 -= 0.5; 801ab47cfaaSmrg else 802ab47cfaaSmrg dk2 += 0.5; 803ab47cfaaSmrg dk3 = -64.0 * 1.371 * k * s * sin(h); 804ab47cfaaSmrg if (dk3 < 0) 805ab47cfaaSmrg dk3 -= 0.5; 806ab47cfaaSmrg else 807ab47cfaaSmrg dk3 += 0.5; 808ab47cfaaSmrg dk4 = -128.0 * k * s * (0.698 * cos(h) + 0.336 * sin(h)); 809ab47cfaaSmrg if (dk4 < 0) 810ab47cfaaSmrg dk4 -= 0.5; 811ab47cfaaSmrg else 812ab47cfaaSmrg dk4 += 0.5; 813ab47cfaaSmrg dk5 = 128.0 * k * s * (0.698 * sin(h) - 0.336 * cos(h)); 814ab47cfaaSmrg if (dk5 < 0) 815ab47cfaaSmrg dk5 -= 0.5; 816ab47cfaaSmrg else 817ab47cfaaSmrg dk5 += 0.5; 818ab47cfaaSmrg dk6 = 64.0 * 1.732 * k * s * sin(h); 819ab47cfaaSmrg if (dk6 < 0) 820ab47cfaaSmrg dk6 -= 0.5; 821ab47cfaaSmrg else 822ab47cfaaSmrg dk6 += 0.5; 823ab47cfaaSmrg dk7 = 64.0 * 1.732 * k * s * cos(h); 824ab47cfaaSmrg if (dk7 < 0) 825ab47cfaaSmrg dk7 -= 0.5; 826ab47cfaaSmrg else 827ab47cfaaSmrg dk7 += 0.5; 828ab47cfaaSmrg 829ab47cfaaSmrg if (pPriv->brightness <= 0) 830ab47cfaaSmrg brightness = pPriv->brightness * 200 / 750 - 200; 831ab47cfaaSmrg else 832ab47cfaaSmrg brightness = (pPriv->brightness - 750) * 200 / (10000 - 750); 833ab47cfaaSmrg dkb = 128 * (brightness - (k * pPriv->contrast * yb / 10000.0) + 0.5); 834ab47cfaaSmrg if (dkb < 0) 835ab47cfaaSmrg dkb -= 0.5; 836ab47cfaaSmrg else 837ab47cfaaSmrg dkb += 0.5; 838ab47cfaaSmrg 839ab47cfaaSmrg k1 = (int)(dk1 /*+0.5*/) & 0x1ff; 840ab47cfaaSmrg k2 = (int)(dk2 /*+0.5*/) & 0x1ff; 841ab47cfaaSmrg assembly1 = (k2<<16) | k1; 842ab47cfaaSmrg 843ab47cfaaSmrg k3 = (int)(dk3 /*+0.5*/) & 0x1ff; 844ab47cfaaSmrg k4 = (int)(dk4 /*+0.5*/) & 0x1ff; 845ab47cfaaSmrg assembly2 = (k4<<16) | k3; 846ab47cfaaSmrg 847ab47cfaaSmrg k5 = (int)(dk5 /*+0.5*/) & 0x1ff; 848ab47cfaaSmrg k6 = (int)(dk6 /*+0.5*/) & 0x1ff; 849ab47cfaaSmrg assembly3 = (k6<<16) | k5; 850ab47cfaaSmrg 851ab47cfaaSmrg k7 = (int)(dk7 /*+0.5*/) & 0x1ff; 852ab47cfaaSmrg kb = (int)(dkb /*+0.5*/) & 0xffff; 853ab47cfaaSmrg assembly4 = (kb<<16) | k7; 854ab47cfaaSmrg 855ab47cfaaSmrg#if 0 856ab47cfaaSmrg assembly1 = 0x640092; 857ab47cfaaSmrg assembly2 = 0x19a0000; 858ab47cfaaSmrg assembly3 = 0x001cf; 859ab47cfaaSmrg assembly4 = 0xf8ca007e; 860ab47cfaaSmrg#endif 861ab47cfaaSmrg 862ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, assembly1 ); 863ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, assembly2 ); 864ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, assembly3 ); 865ab47cfaaSmrg OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, assembly4 ); 866ab47cfaaSmrg 867ab47cfaaSmrg} 868ab47cfaaSmrg 869ab47cfaaSmrgvoid SavageResetVideo(ScrnInfoPtr pScrn) 870ab47cfaaSmrg{ 871ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageResetVideo\n"); 872ab47cfaaSmrg SavageSetColor( pScrn ); 873ab47cfaaSmrg SavageSetColorKey( pScrn ); 874ab47cfaaSmrg} 875ab47cfaaSmrg 876ab47cfaaSmrg 877ab47cfaaSmrgstatic XF86VideoAdaptorPtr 878ab47cfaaSmrgSavageSetupImageVideo(ScreenPtr pScreen) 879ab47cfaaSmrg{ 880aa9e3350Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 881ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 882ab47cfaaSmrg XF86VideoAdaptorPtr adapt; 883ab47cfaaSmrg SavagePortPrivPtr pPriv; 884ab47cfaaSmrg 885ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageSetupImageVideo\n"); 886ab47cfaaSmrg 887aa9e3350Smrg if(!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 888ab47cfaaSmrg sizeof(SavagePortPrivRec) + 889ab47cfaaSmrg sizeof(DevUnion)))) 890ab47cfaaSmrg return NULL; 891ab47cfaaSmrg 892ab47cfaaSmrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 893ab47cfaaSmrg adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 894ab47cfaaSmrg adapt->name = "Savage Streams Engine"; 895ab47cfaaSmrg adapt->nEncodings = 1; 896ab47cfaaSmrg adapt->pEncodings = DummyEncoding; 897ab47cfaaSmrg adapt->nFormats = NUM_FORMATS; 898ab47cfaaSmrg adapt->pFormats = Formats; 899ab47cfaaSmrg adapt->nPorts = 1; 900ab47cfaaSmrg adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 901ab47cfaaSmrg pPriv = (SavagePortPrivPtr)(&adapt->pPortPrivates[1]); 902ab47cfaaSmrg adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 903ab47cfaaSmrg adapt->pAttributes = Attributes; 904ab47cfaaSmrg adapt->nImages = NUM_IMAGES; 905ab47cfaaSmrg adapt->nAttributes = NUM_ATTRIBUTES; 906ab47cfaaSmrg adapt->pImages = Images; 907ab47cfaaSmrg adapt->PutVideo = NULL; 908ab47cfaaSmrg adapt->PutStill = NULL; 909ab47cfaaSmrg adapt->GetVideo = NULL; 910ab47cfaaSmrg adapt->GetStill = NULL; 911ab47cfaaSmrg adapt->StopVideo = SavageStopVideo; 912ab47cfaaSmrg adapt->SetPortAttribute = SavageSetPortAttribute; 913ab47cfaaSmrg adapt->GetPortAttribute = SavageGetPortAttribute; 914ab47cfaaSmrg adapt->QueryBestSize = SavageQueryBestSize; 915ab47cfaaSmrg adapt->PutImage = SavagePutImage; 916ab47cfaaSmrg adapt->QueryImageAttributes = SavageQueryImageAttributes; 917ab47cfaaSmrg 918ab47cfaaSmrg xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 919ab47cfaaSmrg xvContrast = MAKE_ATOM("XV_CONTRAST"); 920ab47cfaaSmrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 921ab47cfaaSmrg xvHue = MAKE_ATOM("XV_HUE"); 922ab47cfaaSmrg xvSaturation = MAKE_ATOM("XV_SATURATION"); 923ab47cfaaSmrg /* interpolation option only available on "old" streams */ 924ab47cfaaSmrg xvInterpolation = MAKE_ATOM("XV_VERTICAL_INTERPOLATION"); 925ab47cfaaSmrg 926ab47cfaaSmrg pPriv->colorKey = 927ab47cfaaSmrg (1 << pScrn->offset.red) | 928ab47cfaaSmrg (1 << pScrn->offset.green) | 929ab47cfaaSmrg (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); 930ab47cfaaSmrg pPriv->videoStatus = 0; 931ab47cfaaSmrg pPriv->brightness = 0; 932ab47cfaaSmrg pPriv->contrast = 128; 933ab47cfaaSmrg pPriv->saturation = 128; 934ab47cfaaSmrg#if 0 935ab47cfaaSmrg /* 936ab47cfaaSmrg * The S3 driver has these values for some of the chips. I have yet 937ab47cfaaSmrg * to find any Savage where these make sense. 938ab47cfaaSmrg */ 939ab47cfaaSmrg pPriv->brightness = 64; 940ab47cfaaSmrg pPriv->contrast = 16; 941ab47cfaaSmrg pPriv->saturation = 128; 942ab47cfaaSmrg#endif 943ab47cfaaSmrg pPriv->hue = 0; 944ab47cfaaSmrg pPriv->lastKnownPitch = 0; 945ab47cfaaSmrg 946ab47cfaaSmrg pPriv->interpolation = FALSE; 947ab47cfaaSmrg 948ab47cfaaSmrg /* gotta uninit this someplace */ 949ab47cfaaSmrg REGION_NULL(pScreen, &pPriv->clip); 950ab47cfaaSmrg 951ab47cfaaSmrg psav->adaptor = adapt; 952ab47cfaaSmrg 953ab47cfaaSmrg #if 0 954ab47cfaaSmrg psav->BlockHandler = pScreen->BlockHandler; 955ab47cfaaSmrg pScreen->BlockHandler = SavageBlockHandler; 956ab47cfaaSmrg #endif 957ab47cfaaSmrg 958ab47cfaaSmrg return adapt; 959ab47cfaaSmrg} 960ab47cfaaSmrg 961ab47cfaaSmrg 962ab47cfaaSmrg/* SavageClipVideo - 963ab47cfaaSmrg 964ab47cfaaSmrg Takes the dst box in standard X BoxRec form (top and left 965ab47cfaaSmrg edges inclusive, bottom and right exclusive). The new dst 966ab47cfaaSmrg box is returned. The source boundaries are given (x1, y1 967ab47cfaaSmrg inclusive, x2, y2 exclusive) and returned are the new source 968ab47cfaaSmrg boundaries in 16.16 fixed point. 969ab47cfaaSmrg*/ 970ab47cfaaSmrg 971ab47cfaaSmrgstatic void 972ab47cfaaSmrgSavageClipVideo( 973ab47cfaaSmrg BoxPtr dst, 974ab47cfaaSmrg INT32 *x1, 975ab47cfaaSmrg INT32 *x2, 976ab47cfaaSmrg INT32 *y1, 977ab47cfaaSmrg INT32 *y2, 978ab47cfaaSmrg BoxPtr extents, /* extents of the clip region */ 979ab47cfaaSmrg INT32 width, 980ab47cfaaSmrg INT32 height 981ab47cfaaSmrg){ 982ab47cfaaSmrg INT32 vscale, hscale, delta; 983ab47cfaaSmrg int diff; 984ab47cfaaSmrg 985ab47cfaaSmrg hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); 986ab47cfaaSmrg vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); 987ab47cfaaSmrg 988ab47cfaaSmrg *x1 <<= 16; *x2 <<= 16; 989ab47cfaaSmrg *y1 <<= 16; *y2 <<= 16; 990ab47cfaaSmrg 991ab47cfaaSmrg diff = extents->x1 - dst->x1; 992ab47cfaaSmrg if(diff > 0) { 993ab47cfaaSmrg dst->x1 = extents->x1; 994ab47cfaaSmrg *x1 += diff * hscale; 995ab47cfaaSmrg } 996ab47cfaaSmrg diff = dst->x2 - extents->x2; 997ab47cfaaSmrg if(diff > 0) { 998ab47cfaaSmrg dst->x2 = extents->x2; 999ab47cfaaSmrg *x2 -= diff * hscale; 1000ab47cfaaSmrg } 1001ab47cfaaSmrg diff = extents->y1 - dst->y1; 1002ab47cfaaSmrg if(diff > 0) { 1003ab47cfaaSmrg dst->y1 = extents->y1; 1004ab47cfaaSmrg *y1 += diff * vscale; 1005ab47cfaaSmrg } 1006ab47cfaaSmrg diff = dst->y2 - extents->y2; 1007ab47cfaaSmrg if(diff > 0) { 1008ab47cfaaSmrg dst->y2 = extents->y2; 1009ab47cfaaSmrg *y2 -= diff * vscale; 1010ab47cfaaSmrg } 1011ab47cfaaSmrg 1012ab47cfaaSmrg if(*x1 < 0) { 1013ab47cfaaSmrg diff = (- *x1 + hscale - 1)/ hscale; 1014ab47cfaaSmrg dst->x1 += diff; 1015ab47cfaaSmrg *x1 += diff * hscale; 1016ab47cfaaSmrg } 1017ab47cfaaSmrg delta = *x2 - (width << 16); 1018ab47cfaaSmrg if(delta > 0) { 1019ab47cfaaSmrg diff = (delta + hscale - 1)/ hscale; 1020ab47cfaaSmrg dst->x2 -= diff; 1021ab47cfaaSmrg *x2 -= diff * hscale; 1022ab47cfaaSmrg } 1023ab47cfaaSmrg if(*y1 < 0) { 1024ab47cfaaSmrg diff = (- *y1 + vscale - 1)/ vscale; 1025ab47cfaaSmrg dst->y1 += diff; 1026ab47cfaaSmrg *y1 += diff * vscale; 1027ab47cfaaSmrg } 1028ab47cfaaSmrg delta = *y2 - (height << 16); 1029ab47cfaaSmrg if(delta > 0) { 1030ab47cfaaSmrg diff = (delta + vscale - 1)/ vscale; 1031ab47cfaaSmrg dst->y2 -= diff; 1032ab47cfaaSmrg *y2 -= diff * vscale; 1033ab47cfaaSmrg } 1034ab47cfaaSmrg} 1035ab47cfaaSmrg 1036ab47cfaaSmrgstatic void 1037ab47cfaaSmrgSavageStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) 1038ab47cfaaSmrg{ 1039ab47cfaaSmrg SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 10402b2b4fcbSmrg#ifdef SAVAGEDRI 10411473d951Smrg SavagePtr psav = SAVPTR(pScrn); 10422b2b4fcbSmrg#endif 1043ab47cfaaSmrg 1044ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageStopVideo\n"); 1045ab47cfaaSmrg 1046ab47cfaaSmrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1047ab47cfaaSmrg 1048ab47cfaaSmrg if(shutdown) { 1049ab47cfaaSmrg /*SavageClipVWindow(pScrn);*/ 1050ab47cfaaSmrg SavageStreamsOff( pScrn ); 10511473d951Smrg 1052aa9e3350Smrg#ifdef SAVAGEDRI 10531473d951Smrg if (pPriv->agpBufferMap != NULL) { 10541473d951Smrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 10551473d951Smrg 10561473d951Smrg /* agpXVideo is reused to implement UploadToScreen in EXA */ 10571473d951Smrg if (!psav->useEXA) { 10581473d951Smrg drmUnmap(pPriv->agpBufferMap, pSAVAGEDRIServer->agpXVideo.size); 10591473d951Smrg pSAVAGEDRIServer->agpXVideo.map = NULL; 10601473d951Smrg } 10611473d951Smrg pPriv->agpBufferMap = NULL; 10621473d951Smrg pPriv->agpBufferOffset = 0; 10631473d951Smrg } 10646aec45a7Smrg pPriv->tried_agp = FALSE; 10656aec45a7Smrg#endif 10661473d951Smrg 1067ab47cfaaSmrg if (pPriv->video_memory != NULL) { 1068ab47cfaaSmrg SavageFreeMemory(pScrn, pPriv->video_memory); 1069ab47cfaaSmrg pPriv->video_memory = NULL; 1070ab47cfaaSmrg } 10711473d951Smrg if (pPriv->video_planarmem != NULL) { 10721473d951Smrg SavageFreeMemory(pScrn, pPriv->video_planarmem); 10731473d951Smrg pPriv->video_planarmem = NULL; 10741473d951Smrg } 1075ab47cfaaSmrg pPriv->videoStatus = 0; 1076ab47cfaaSmrg } else { 1077ab47cfaaSmrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 1078ab47cfaaSmrg pPriv->videoStatus |= OFF_TIMER; 1079ab47cfaaSmrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 1080ab47cfaaSmrg } 1081ab47cfaaSmrg } 1082ab47cfaaSmrg} 1083ab47cfaaSmrg 1084ab47cfaaSmrg 1085ab47cfaaSmrgstatic int 1086ab47cfaaSmrgSavageSetPortAttribute( 1087ab47cfaaSmrg ScrnInfoPtr pScrn, 1088ab47cfaaSmrg Atom attribute, 1089ab47cfaaSmrg INT32 value, 1090ab47cfaaSmrg pointer data 1091ab47cfaaSmrg){ 1092ab47cfaaSmrg SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1093ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1094ab47cfaaSmrg 1095ab47cfaaSmrg if(attribute == xvColorKey) { 1096ab47cfaaSmrg pPriv->colorKey = value; 1097ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1098ab47cfaaSmrg SavageSetColorKey( pScrn ); 1099ab47cfaaSmrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1100ab47cfaaSmrg } 1101ab47cfaaSmrg else if( attribute == xvBrightness) { 1102ab47cfaaSmrg if((value < -128) || (value > 127)) 1103ab47cfaaSmrg return BadValue; 1104ab47cfaaSmrg pPriv->brightness = value; 1105ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1106ab47cfaaSmrg SavageSetColor( pScrn ); 1107ab47cfaaSmrg } 1108ab47cfaaSmrg else if( attribute == xvContrast) { 1109ab47cfaaSmrg if((value < 0) || (value > 255)) 1110ab47cfaaSmrg return BadValue; 1111ab47cfaaSmrg pPriv->contrast = value; 1112ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1113ab47cfaaSmrg SavageSetColor( pScrn ); 1114ab47cfaaSmrg } 1115ab47cfaaSmrg else if( attribute == xvSaturation) { 1116ab47cfaaSmrg if((value < 0) || (value > 255)) 1117ab47cfaaSmrg return BadValue; 1118ab47cfaaSmrg pPriv->saturation = value; 1119ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1120ab47cfaaSmrg SavageSetColor( pScrn ); 1121ab47cfaaSmrg } 1122ab47cfaaSmrg else if( attribute == xvHue) { 1123ab47cfaaSmrg if((value < -180) || (value > 180)) 1124ab47cfaaSmrg return BadValue; 1125ab47cfaaSmrg pPriv->hue = value; 1126ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1127ab47cfaaSmrg SavageSetColor( pScrn ); 1128ab47cfaaSmrg } 1129ab47cfaaSmrg else if( attribute == xvInterpolation) { 1130ab47cfaaSmrg if((value < 0) || (value > 1)) 1131ab47cfaaSmrg return BadValue; 1132ab47cfaaSmrg if (value == 1) 1133ab47cfaaSmrg pPriv->interpolation = TRUE; 1134ab47cfaaSmrg else 1135ab47cfaaSmrg pPriv->interpolation = FALSE; 1136ab47cfaaSmrg } 1137ab47cfaaSmrg else 1138ab47cfaaSmrg return BadMatch; 1139ab47cfaaSmrg 1140ab47cfaaSmrg return Success; 1141ab47cfaaSmrg} 1142ab47cfaaSmrg 1143ab47cfaaSmrg 1144ab47cfaaSmrgstatic int 1145ab47cfaaSmrgSavageGetPortAttribute( 1146ab47cfaaSmrg ScrnInfoPtr pScrn, 1147ab47cfaaSmrg Atom attribute, 1148ab47cfaaSmrg INT32 *value, 1149ab47cfaaSmrg pointer data 1150ab47cfaaSmrg){ 1151ab47cfaaSmrg SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1152ab47cfaaSmrg 1153ab47cfaaSmrg if(attribute == xvColorKey) { 1154ab47cfaaSmrg *value = pPriv->colorKey; 1155ab47cfaaSmrg } 1156ab47cfaaSmrg else if( attribute == xvBrightness ) { 1157ab47cfaaSmrg *value = pPriv->brightness; 1158ab47cfaaSmrg } 1159ab47cfaaSmrg else if( attribute == xvContrast ) { 1160ab47cfaaSmrg *value = pPriv->contrast; 1161ab47cfaaSmrg } 1162ab47cfaaSmrg else if( attribute == xvHue ) { 1163ab47cfaaSmrg *value = pPriv->hue; 1164ab47cfaaSmrg } 1165ab47cfaaSmrg else if( attribute == xvSaturation ) { 1166ab47cfaaSmrg *value = pPriv->saturation; 1167ab47cfaaSmrg } 1168ab47cfaaSmrg else if( attribute == xvInterpolation ) { 1169ab47cfaaSmrg *value = pPriv->interpolation; 1170ab47cfaaSmrg } 1171ab47cfaaSmrg else return BadMatch; 1172ab47cfaaSmrg 1173ab47cfaaSmrg return Success; 1174ab47cfaaSmrg} 1175ab47cfaaSmrg 1176ab47cfaaSmrgstatic void 1177ab47cfaaSmrgSavageQueryBestSize( 1178ab47cfaaSmrg ScrnInfoPtr pScrn, 1179ab47cfaaSmrg Bool motion, 1180ab47cfaaSmrg short vid_w, short vid_h, 1181ab47cfaaSmrg short drw_w, short drw_h, 1182ab47cfaaSmrg unsigned int *p_w, unsigned int *p_h, 1183ab47cfaaSmrg pointer data 1184ab47cfaaSmrg){ 1185ab47cfaaSmrg /* What are the real limits for the Savage? */ 1186ab47cfaaSmrg 1187ab47cfaaSmrg *p_w = drw_w; 1188ab47cfaaSmrg *p_h = drw_h; 1189ab47cfaaSmrg 1190ab47cfaaSmrg if(*p_w > 16384) *p_w = 16384; 1191ab47cfaaSmrg} 1192ab47cfaaSmrg 1193ab47cfaaSmrg/* SavageCopyPlanarDataBCI() causes artifacts on the screen when used on savage4. 1194ab47cfaaSmrg * It's probably something with the BCI. Maybe we need a waitforidle() or 1195ab47cfaaSmrg * something... 1196ab47cfaaSmrg */ 1197ab47cfaaSmrgstatic void 1198ab47cfaaSmrgSavageCopyPlanarDataBCI( 1199ab47cfaaSmrg ScrnInfoPtr pScrn, 1200ab47cfaaSmrg unsigned char *srcY, /* Y */ 1201ab47cfaaSmrg unsigned char *srcV, /* V */ 1202ab47cfaaSmrg unsigned char *srcU, /* U */ 1203ab47cfaaSmrg unsigned char *dst, 12041473d951Smrg unsigned char * planarPtr, 12051473d951Smrg unsigned long planarOffset, 1206ab47cfaaSmrg int srcPitch, int srcPitch2, 1207ab47cfaaSmrg int dstPitch, 12081473d951Smrg int h,int w, 12091473d951Smrg Bool isAGP) 1210ab47cfaaSmrg{ 1211ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 12121473d951Smrg 1213ab47cfaaSmrg /* for pixel transfer */ 12141473d951Smrg unsigned long offsetY = planarOffset; 1215ab47cfaaSmrg unsigned long offsetV = offsetY + srcPitch * h; 1216ab47cfaaSmrg unsigned long offsetU = offsetV + srcPitch2 * (h>>1); 1217ab47cfaaSmrg unsigned long dstOffset = (unsigned long)dst - (unsigned long)psav->FBBase; 12181473d951Smrg unsigned char memType; 1219ab47cfaaSmrg 1220ab47cfaaSmrg BCI_GET_PTR; 1221ab47cfaaSmrg 1222ab47cfaaSmrg /* copy Y planar */ 12231473d951Smrg memcpy(planarPtr, srcY, srcPitch * h); 1224ab47cfaaSmrg 1225ab47cfaaSmrg /* copy V planar */ 12261473d951Smrg planarPtr = planarPtr + srcPitch * h; 12271473d951Smrg memcpy(planarPtr, srcV, srcPitch2 * (h>>1)); 1228ab47cfaaSmrg 1229ab47cfaaSmrg /* copy U planar */ 12301473d951Smrg planarPtr = planarPtr + srcPitch2 * (h>>1); 12311473d951Smrg memcpy(planarPtr, srcU, srcPitch2 * (h>>1)); 12321473d951Smrg 12331473d951Smrg memType = isAGP ? 3 : 0; 1234ab47cfaaSmrg 1235ab47cfaaSmrg /* 1236ab47cfaaSmrg * Transfer pixel data from one memory location to another location 1237ab47cfaaSmrg * and reformat the data during the transfer 1238ab47cfaaSmrg * a. program BCI51 to specify the source information 1239ab47cfaaSmrg * b. program BCI52 to specify the destination information 1240ab47cfaaSmrg * c. program BCI53 to specify the source dimensions 1241ab47cfaaSmrg * d. program BCI54 to specify the destination dimensions 1242ab47cfaaSmrg * e. (if the data is in YCbCr420 format)program BCI55,BCI56,BCI57 to 1243ab47cfaaSmrg * locations of the Y,Cb,and Cr data 1244ab47cfaaSmrg * f. program BCI50(command=011) to specify the formatting options and 1245ab47cfaaSmrg * kick off the transfer 1246ab47cfaaSmrg * this command can be used for color space conversion(YCbCr to RGB) 1247ab47cfaaSmrg * or for oversampling, but not for both simultaneously. it can also be 1248ab47cfaaSmrg * used to do mastered image transfer when the source is tiled 1249ab47cfaaSmrg */ 1250ab47cfaaSmrg 1251ab47cfaaSmrg w = (w+0xf)&0xff0; 1252ab47cfaaSmrg psav->WaitQueue(psav,11); 12531473d951Smrg BCI_SEND(BCI_SET_REGISTER | BCI_SET_REGISTER_COUNT(7) | 0x51); 12541473d951Smrg BCI_SEND(offsetY | memType); 1255ab47cfaaSmrg BCI_SEND(dstOffset); 1256ab47cfaaSmrg BCI_SEND(((h-1)<<16)|((w-1)>>3)); 1257ab47cfaaSmrg BCI_SEND(dstPitch >> 3); 12581473d951Smrg BCI_SEND(offsetU | memType); 12591473d951Smrg BCI_SEND(offsetV | memType); 1260ab47cfaaSmrg BCI_SEND((srcPitch2 << 16)| srcPitch2); 1261ab47cfaaSmrg 12621473d951Smrg BCI_SEND(BCI_SET_REGISTER | BCI_SET_REGISTER_COUNT(1) | 0x50); 1263ab47cfaaSmrg BCI_SEND(0x00200003 | srcPitch); 12641473d951Smrg 1265ab47cfaaSmrg BCI_SEND(0xC0170000); 1266ab47cfaaSmrg} 1267ab47cfaaSmrg 1268ab47cfaaSmrgstatic void 1269ab47cfaaSmrgSavageCopyData( 1270ab47cfaaSmrg unsigned char *src, 1271ab47cfaaSmrg unsigned char *dst, 1272ab47cfaaSmrg int srcPitch, 1273ab47cfaaSmrg int dstPitch, 1274ab47cfaaSmrg int h, 1275ab47cfaaSmrg int w 1276ab47cfaaSmrg){ 1277ab47cfaaSmrg w <<= 1; 12788697ee19Smrg if (w == srcPitch && w == dstPitch) { 12798697ee19Smrg memcpy(dst, src, w * h); 12808697ee19Smrg } else 1281ab47cfaaSmrg while(h--) { 1282ab47cfaaSmrg memcpy(dst, src, w); 1283ab47cfaaSmrg src += srcPitch; 1284ab47cfaaSmrg dst += dstPitch; 1285ab47cfaaSmrg } 1286ab47cfaaSmrg} 1287ab47cfaaSmrg 1288ab47cfaaSmrgstatic void 1289ab47cfaaSmrgSavageCopyPlanarData( 1290ab47cfaaSmrg unsigned char *src1, /* Y */ 1291ab47cfaaSmrg unsigned char *src2, /* V */ 1292ab47cfaaSmrg unsigned char *src3, /* U */ 1293ab47cfaaSmrg unsigned char *dst1, 1294ab47cfaaSmrg int srcPitch, 1295ab47cfaaSmrg int srcPitch2, 1296ab47cfaaSmrg int dstPitch, 1297ab47cfaaSmrg int h, 1298ab47cfaaSmrg int w 1299ab47cfaaSmrg){ 1300ab47cfaaSmrg CARD32 *dst = (CARD32*)dst1; 1301ab47cfaaSmrg int i, j; 1302ab47cfaaSmrg 1303ab47cfaaSmrg dstPitch >>= 2; 1304ab47cfaaSmrg w >>= 1; 1305ab47cfaaSmrg 1306ab47cfaaSmrg for(j = 0; j < h; j++) { 1307ab47cfaaSmrg for(i = 0; i < w; i++) { 1308ab47cfaaSmrg/* Shouldn't this be 'if LITTLEENDIAN'? */ 1309ab47cfaaSmrg#if 1 1310ab47cfaaSmrg dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | 1311ab47cfaaSmrg (src3[i] << 8) | (src2[i] << 24); 1312ab47cfaaSmrg#else 1313ab47cfaaSmrg dst[i] = (src1[i << 1] << 24) | (src1[(i << 1) + 1] << 8) | 1314ab47cfaaSmrg (src3[i] << 0) | (src2[i] << 16); 1315ab47cfaaSmrg#endif 1316ab47cfaaSmrg } 1317ab47cfaaSmrg dst += dstPitch; 1318ab47cfaaSmrg src1 += srcPitch; 1319ab47cfaaSmrg if(j & 1) { 1320ab47cfaaSmrg src2 += srcPitch2; 1321ab47cfaaSmrg src3 += srcPitch2; 1322ab47cfaaSmrg } 1323ab47cfaaSmrg } 1324ab47cfaaSmrg} 1325ab47cfaaSmrg 1326ab47cfaaSmrgstatic void 1327ab47cfaaSmrgSavageVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) 1328ab47cfaaSmrg{ 1329aa9e3350Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1330ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1331ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 1332ab47cfaaSmrg 1333ab47cfaaSmrg if (pPriv->video_memory == area) 1334ab47cfaaSmrg pPriv->video_memory = NULL; 13351473d951Smrg if (pPriv->video_planarmem == area) 13361473d951Smrg pPriv->video_planarmem = NULL; 1337ab47cfaaSmrg} 1338ab47cfaaSmrg 1339ab47cfaaSmrgstatic CARD32 1340ab47cfaaSmrgSavageAllocateMemory( 1341ab47cfaaSmrg ScrnInfoPtr pScrn, 1342ab47cfaaSmrg void **mem_struct, 1343ab47cfaaSmrg int size 1344ab47cfaaSmrg){ 1345aa9e3350Smrg ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 1346ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1347ab47cfaaSmrg int offset = 0; 1348ab47cfaaSmrg 1349ab47cfaaSmrg if (psav->useEXA) { 1350ab47cfaaSmrg ExaOffscreenArea *area = *mem_struct; 1351ab47cfaaSmrg 1352ab47cfaaSmrg if (area != NULL) { 1353ab47cfaaSmrg if (area->size >= size) 1354ab47cfaaSmrg return area->offset; 1355ab47cfaaSmrg 1356ab47cfaaSmrg exaOffscreenFree(pScrn->pScreen, area); 1357ab47cfaaSmrg } 1358ab47cfaaSmrg 1359ab47cfaaSmrg area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, SavageVideoSave, 1360ab47cfaaSmrg NULL); 1361ab47cfaaSmrg *mem_struct = area; 1362ab47cfaaSmrg if (area == NULL) 1363ab47cfaaSmrg return 0; 1364ab47cfaaSmrg offset = area->offset; 1365ab47cfaaSmrg } 1366ab47cfaaSmrg 1367ab47cfaaSmrg if (!psav->useEXA) { 1368ab47cfaaSmrg FBLinearPtr linear = *mem_struct; 1369ab47cfaaSmrg int cpp = pScrn->bitsPerPixel / 8; 1370ab47cfaaSmrg 1371ab47cfaaSmrg /* XAA allocates in units of pixels at the screen bpp, so adjust size 1372ab47cfaaSmrg * appropriately. 1373ab47cfaaSmrg */ 1374ab47cfaaSmrg size = (size + cpp - 1) / cpp; 1375ab47cfaaSmrg 1376ab47cfaaSmrg if (linear) { 1377ab47cfaaSmrg if(linear->size >= size) 1378ab47cfaaSmrg return linear->offset * cpp; 1379ab47cfaaSmrg 1380ab47cfaaSmrg if(xf86ResizeOffscreenLinear(linear, size)) 1381ab47cfaaSmrg return linear->offset * cpp; 1382ab47cfaaSmrg 1383ab47cfaaSmrg xf86FreeOffscreenLinear(linear); 1384ab47cfaaSmrg } 1385ab47cfaaSmrg 1386ab47cfaaSmrg linear = xf86AllocateOffscreenLinear(pScreen, size, 16, 1387ab47cfaaSmrg NULL, NULL, NULL); 1388ab47cfaaSmrg *mem_struct = linear; 1389ab47cfaaSmrg 1390ab47cfaaSmrg if (!linear) { 1391ab47cfaaSmrg int max_size; 1392ab47cfaaSmrg 1393ab47cfaaSmrg xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, 1394ab47cfaaSmrg PRIORITY_EXTREME); 1395ab47cfaaSmrg 1396ab47cfaaSmrg if(max_size < size) 1397ab47cfaaSmrg return 0; 1398ab47cfaaSmrg 1399ab47cfaaSmrg xf86PurgeUnlockedOffscreenAreas(pScreen); 1400ab47cfaaSmrg linear = xf86AllocateOffscreenLinear(pScreen, size, 16, 1401ab47cfaaSmrg NULL, NULL, NULL); 1402ab47cfaaSmrg *mem_struct = linear; 1403ab47cfaaSmrg if (!linear) 1404ab47cfaaSmrg return 0; 1405ab47cfaaSmrg } 1406ab47cfaaSmrg offset = linear->offset * cpp; 1407ab47cfaaSmrg } 1408ab47cfaaSmrg 1409ab47cfaaSmrg return offset; 1410ab47cfaaSmrg} 1411ab47cfaaSmrg 1412ab47cfaaSmrgstatic void 1413ab47cfaaSmrgSavageFreeMemory( 1414ab47cfaaSmrg ScrnInfoPtr pScrn, 1415ab47cfaaSmrg void *mem_struct 1416ab47cfaaSmrg){ 1417ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1418ab47cfaaSmrg 1419ab47cfaaSmrg if (psav->useEXA) { 1420ab47cfaaSmrg ExaOffscreenArea *area = mem_struct; 1421ab47cfaaSmrg 1422ab47cfaaSmrg if (area != NULL) 1423ab47cfaaSmrg exaOffscreenFree(pScrn->pScreen, area); 1424ab47cfaaSmrg } 1425ab47cfaaSmrg if (!psav->useEXA) { 1426ab47cfaaSmrg FBLinearPtr linear = mem_struct; 1427ab47cfaaSmrg 1428ab47cfaaSmrg if (linear != NULL) 1429ab47cfaaSmrg xf86FreeOffscreenLinear(linear); 1430ab47cfaaSmrg } 1431ab47cfaaSmrg} 1432ab47cfaaSmrg 1433ab47cfaaSmrgstatic void 1434ab47cfaaSmrgSavageSetBlend(ScrnInfoPtr pScrn, int id) 1435ab47cfaaSmrg{ 1436ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1437ab47cfaaSmrg 1438ab47cfaaSmrg if ( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) 1439ab47cfaaSmrg { 1440ab47cfaaSmrg psav->blendBase = GetBlendForFourCC( id ); 1441ab47cfaaSmrg xf86ErrorFVerb(XVTRACE+1,"Format %4.4s, blend is %08x\n", (char*)&id, psav->blendBase ); 1442ab47cfaaSmrg if (psav->IsSecondary) { 1443ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 1444ab47cfaaSmrg } else if (psav->IsPrimary) { 1445ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 1446ab47cfaaSmrg } else { 1447ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 1448ab47cfaaSmrg#if 0 1449ab47cfaaSmrg OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 1450ab47cfaaSmrg#endif 1451ab47cfaaSmrg } 1452ab47cfaaSmrg } else if (psav->Chipset == S3_SAVAGE2000) { 1453ab47cfaaSmrg psav->blendBase = GetBlendForFourCC2000( id ); 1454ab47cfaaSmrg xf86ErrorFVerb(XVTRACE+1,"Format %4.4s, blend is %08x\n", (char*)&id, psav->blendBase ); 1455ab47cfaaSmrg if (id != FOURCC_YV12) 1456ab47cfaaSmrg OUTREG( BLEND_CONTROL, 1457ab47cfaaSmrg ((psav->blendBase << 24) | (8 << 2) /*| 0x20000000*/)); 1458ab47cfaaSmrg else 1459ab47cfaaSmrg OUTREG( BLEND_CONTROL, 1460ab47cfaaSmrg ((psav->blendBase << 24) | (8 << 2) /*| 0x10000000*/)); 1461ab47cfaaSmrg } 1462ab47cfaaSmrg 1463ab47cfaaSmrg psav->videoFourCC = id; 1464ab47cfaaSmrg} 1465ab47cfaaSmrg 1466ab47cfaaSmrgstatic void 1467ab47cfaaSmrgSavageDisplayVideoOld( 1468ab47cfaaSmrg ScrnInfoPtr pScrn, 1469ab47cfaaSmrg int id, 1470ab47cfaaSmrg int offset, 1471ab47cfaaSmrg short width, short height, 1472ab47cfaaSmrg int pitch, 1473ab47cfaaSmrg int x1, int y1, int x2, int y2, 1474ab47cfaaSmrg BoxPtr dstBox, 1475ab47cfaaSmrg short src_w, short src_h, 1476ab47cfaaSmrg short drw_w, short drw_h 1477ab47cfaaSmrg){ 1478ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1479ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1480ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 1481ab47cfaaSmrg /*DisplayModePtr mode = pScrn->currentMode;*/ 1482ab47cfaaSmrg int vgaCRIndex, vgaCRReg, vgaIOBase; 1483ab47cfaaSmrg CARD32 ssControl; 1484ab47cfaaSmrg int scalratio; 1485ab47cfaaSmrg 1486ab47cfaaSmrg 1487ab47cfaaSmrg vgaIOBase = hwp->IOBase; 1488ab47cfaaSmrg vgaCRIndex = vgaIOBase + 4; 1489ab47cfaaSmrg vgaCRReg = vgaIOBase + 5; 1490ab47cfaaSmrg#if 0 1491ab47cfaaSmrg if ( psav->videoFourCC != id ) { 1492ab47cfaaSmrg SavageSetBlend(pScrn,id); 1493ab47cfaaSmrg SavageResetVideo(pScrn); 1494ab47cfaaSmrg } 1495ab47cfaaSmrg#endif 1496ab47cfaaSmrg if( psav->videoFourCC != id ) 1497ab47cfaaSmrg SavageStreamsOff(pScrn); 1498ab47cfaaSmrg 14998697ee19Smrg if( !(psav->videoFlags & VF_STREAMS_ON) ) 1500ab47cfaaSmrg { 1501ab47cfaaSmrg SavageSetBlend(pScrn,id); 1502ab47cfaaSmrg SavageStreamsOn(pScrn); 1503ab47cfaaSmrg SavageResetVideo(pScrn); 15048697ee19Smrg pPriv->lastKnownPitch = 0; 1505ab47cfaaSmrg } 1506ab47cfaaSmrg 1507ab47cfaaSmrg if (S3_MOBILE_TWISTER_SERIES(psav->Chipset) 1508aa9e3350Smrg && psav->FPExpansion) { 1509aa9e3350Smrg drw_w = (drw_w * psav->XExp1) / psav->XExp2 + 1; 1510aa9e3350Smrg drw_h = (drw_h * psav->YExp1) / psav->YExp2 + 1; 1511aa9e3350Smrg dstBox->x1 = (dstBox->x1 * psav->XExp1) / psav->XExp2; 1512aa9e3350Smrg dstBox->y1 = (dstBox->y1 * psav->YExp1) / psav->YExp2; 1513aa9e3350Smrg dstBox->x2 = (dstBox->x2 * psav->XExp1) / psav->XExp2; 1514aa9e3350Smrg dstBox->y2 = (dstBox->y2 * psav->YExp1) / psav->YExp2; 1515aa9e3350Smrg dstBox->x1 += psav->displayXoffset; 1516aa9e3350Smrg dstBox->y1 += psav->displayYoffset; 1517aa9e3350Smrg dstBox->x2 += psav->displayXoffset; 1518aa9e3350Smrg dstBox->y2 += psav->displayYoffset; 1519ab47cfaaSmrg } 1520ab47cfaaSmrg 1521ab47cfaaSmrg /* 1522ab47cfaaSmrg * Process horizontal scaling 15232b2b4fcbSmrg * upscaling and downscaling smaller than 2:1 controlled by MM8198 1524ab47cfaaSmrg * MM8190 controls downscaling mode larger than 2:1 15258697ee19Smrg * Together MM8190 and MM8198 can set arbitrary downscale up to 64:1 1526ab47cfaaSmrg */ 1527ab47cfaaSmrg scalratio = 0; 1528ab47cfaaSmrg ssControl = 0; 1529ab47cfaaSmrg 1530ab47cfaaSmrg if (src_w >= (drw_w * 2)) { 1531ab47cfaaSmrg if (src_w < (drw_w * 4)) { 1532ab47cfaaSmrg ssControl |= HDSCALE_4; 15338697ee19Smrg scalratio = HSCALING(src_w,(drw_w*4)); 15348697ee19Smrg } else if (src_w < (drw_w * 8)) { 1535ab47cfaaSmrg ssControl |= HDSCALE_8; 15368697ee19Smrg scalratio = HSCALING(src_w,(drw_w*8)); 15378697ee19Smrg } else if (src_w < (drw_w * 16)) { 1538ab47cfaaSmrg ssControl |= HDSCALE_16; 15398697ee19Smrg scalratio = HSCALING(src_w,(drw_w*16)); 15408697ee19Smrg } else if (src_w < (drw_w * 32)) { 1541ab47cfaaSmrg ssControl |= HDSCALE_32; 15428697ee19Smrg scalratio = HSCALING(src_w,(drw_w*32)); 15438697ee19Smrg } else if (src_w < (drw_w * 64)) { 15448697ee19Smrg ssControl |= HDSCALE_64; 15458697ee19Smrg scalratio = HSCALING(src_w,(drw_w*64)); 15468697ee19Smrg } else { 15478697ee19Smrg /* Request beyond maximum downscale! */ 1548ab47cfaaSmrg ssControl |= HDSCALE_64; 15498697ee19Smrg scalratio = HSCALING(2,1); 15508697ee19Smrg } 1551ab47cfaaSmrg } else 1552ab47cfaaSmrg scalratio = HSCALING(src_w,drw_w); 1553ab47cfaaSmrg 1554ab47cfaaSmrg ssControl |= src_w; 1555ab47cfaaSmrg /*ssControl |= (1 << 24);*/ 1556ab47cfaaSmrg ssControl |= (GetBlendForFourCC(psav->videoFourCC) << 24); 15578697ee19Smrg#if 0 1558ab47cfaaSmrg /* Wait for VBLANK. */ 1559ab47cfaaSmrg VerticalRetraceWait(); 15608697ee19Smrg#endif 1561ab47cfaaSmrg OUTREG(SSTREAM_CONTROL_REG, ssControl); 1562ab47cfaaSmrg if (scalratio) 1563ab47cfaaSmrg OUTREG(SSTREAM_STRETCH_REG,scalratio); 1564ab47cfaaSmrg 1565ab47cfaaSmrg /* Calculate vertical scale factor. */ 1566ab47cfaaSmrg OUTREG(SSTREAM_VINITIAL_REG, 0 ); 1567ab47cfaaSmrg /*OUTREG(SSTREAM_VSCALE_REG, (src_h << 15) / drw_h );*/ 1568ab47cfaaSmrg OUTREG(SSTREAM_VSCALE_REG, VSCALING(src_h,drw_h)); 1569ab47cfaaSmrg 1570ab47cfaaSmrg /* Set surface location and stride. */ 1571ab47cfaaSmrg OUTREG(SSTREAM_FBADDR0_REG, (offset + (x1>>15)) & (0x1ffffff & ~BASE_PAD) ); 1572ab47cfaaSmrg OUTREG(SSTREAM_FBADDR1_REG, 0); 1573ab47cfaaSmrg OUTREG(SSTREAM_STRIDE_REG, pitch & 0xfff ); 1574ab47cfaaSmrg 1575ab47cfaaSmrg OUTREG(SSTREAM_WINDOW_START_REG, OS_XY(dstBox->x1, dstBox->y1) ); 1576ab47cfaaSmrg OUTREG(SSTREAM_WINDOW_SIZE_REG, OS_WH(dstBox->x2-dstBox->x1, 1577ab47cfaaSmrg dstBox->y2-dstBox->y1)); 1578ab47cfaaSmrg 1579ab47cfaaSmrg /* 1580ab47cfaaSmrg * MM81E8:Secondary Stream Source Line Count 1581ab47cfaaSmrg * bit_0~10: # of lines in the source image (before scaling) 1582ab47cfaaSmrg * bit_15 = 1: Enable vertical interpolation 1583ab47cfaaSmrg * 0: Line duplicaion 1584ab47cfaaSmrg */ 1585ab47cfaaSmrg /* 1586ab47cfaaSmrg * Vertical Interpolation is very bandwidth intensive. Some savages can't 1587ab47cfaaSmrg * seem to handle it. Default is line doubling. --AGD 1588ab47cfaaSmrg */ 1589ab47cfaaSmrg if (pPriv->interpolation) { 1590ab47cfaaSmrg if (src_w * 16 <= 0x3300) { 1591ab47cfaaSmrg OUTREG(SSTREAM_LINES_REG, 0x8000 | src_h ); 1592ab47cfaaSmrg OUTREG(FIFO_CONTROL, (INREG(FIFO_CONTROL) + 1)); 1593ab47cfaaSmrg } else { 1594ab47cfaaSmrg OUTREG(SSTREAM_LINES_REG, src_h ); 1595ab47cfaaSmrg } 1596ab47cfaaSmrg } else { 1597ab47cfaaSmrg OUTREG(SSTREAM_LINES_REG, src_h ); 1598ab47cfaaSmrg } 1599ab47cfaaSmrg 1600ab47cfaaSmrg#if 0 1601ab47cfaaSmrg /* Set color key on primary. */ 1602ab47cfaaSmrg 1603ab47cfaaSmrg SavageSetColorKey( pScrn ); 1604ab47cfaaSmrg#endif 1605ab47cfaaSmrg 1606ab47cfaaSmrg /* Set FIFO L2 on second stream. */ 1607ab47cfaaSmrg 1608ab47cfaaSmrg if( pPriv->lastKnownPitch != pitch ) 1609ab47cfaaSmrg { 1610ab47cfaaSmrg unsigned char cr92; 1611ab47cfaaSmrg 1612ab47cfaaSmrg pPriv->lastKnownPitch = pitch; 1613ab47cfaaSmrg 1614ab47cfaaSmrg pitch = (pitch + 7) / 8; 1615ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x92); 1616ab47cfaaSmrg cr92 = VGAIN8(vgaCRReg); 1617ab47cfaaSmrg VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 1618ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x93); 1619ab47cfaaSmrg if (psav->bTiled && (( drw_h > src_h) || (drw_w > src_w))) 1620ab47cfaaSmrg VGAOUT8(vgaCRReg, pitch | 0xf); 1621ab47cfaaSmrg else 1622ab47cfaaSmrg VGAOUT8(vgaCRReg, pitch); 1623ab47cfaaSmrg } 1624ab47cfaaSmrg} 1625ab47cfaaSmrg 1626ab47cfaaSmrgstatic void 1627ab47cfaaSmrgSavageDisplayVideoNew( 1628ab47cfaaSmrg ScrnInfoPtr pScrn, 1629ab47cfaaSmrg int id, 1630ab47cfaaSmrg int offset, 1631ab47cfaaSmrg short width, short height, 1632ab47cfaaSmrg int pitch, 1633ab47cfaaSmrg int x1, int y1, int x2, int y2, 1634ab47cfaaSmrg BoxPtr dstBox, 1635ab47cfaaSmrg short src_w, short src_h, 1636ab47cfaaSmrg short drw_w, short drw_h 1637ab47cfaaSmrg){ 1638ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1639ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1640ab47cfaaSmrg /*DisplayModePtr mode = pScrn->currentMode;*/ 1641ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 1642ab47cfaaSmrg int vgaCRIndex, vgaCRReg, vgaIOBase; 1643ab47cfaaSmrg 1644ab47cfaaSmrg 1645ab47cfaaSmrg vgaIOBase = hwp->IOBase; 1646ab47cfaaSmrg vgaCRIndex = vgaIOBase + 4; 1647ab47cfaaSmrg vgaCRReg = vgaIOBase + 5; 1648ab47cfaaSmrg#if 0 1649ab47cfaaSmrg if ( psav->videoFourCC != id ) { 1650ab47cfaaSmrg SavageSetBlend(pScrn,id); 1651ab47cfaaSmrg SavageResetVideo(pScrn); 1652ab47cfaaSmrg } 1653ab47cfaaSmrg#endif 1654ab47cfaaSmrg if( psav->videoFourCC != id ) 1655ab47cfaaSmrg SavageStreamsOff(pScrn); 1656ab47cfaaSmrg 16578697ee19Smrg if( !(psav->videoFlags & VF_STREAMS_ON) ) 1658ab47cfaaSmrg { 1659ab47cfaaSmrg SavageSetBlend(pScrn,id); 1660ab47cfaaSmrg SavageStreamsOn(pScrn); 1661ab47cfaaSmrg SavageResetVideo(pScrn); 16628697ee19Smrg pPriv->lastKnownPitch = 0; 1663ab47cfaaSmrg } 1664ab47cfaaSmrg 1665ab47cfaaSmrg /* Calculate horizontal and vertical scale factors. */ 1666ab47cfaaSmrg 1667ab47cfaaSmrg if ( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) && 1668ab47cfaaSmrg (psav->DisplayType == MT_LCD) && 1669ab47cfaaSmrg !psav->CrtOnly && 1670ab47cfaaSmrg !psav->TvOn) 1671ab47cfaaSmrg { 1672aa9e3350Smrg drw_w = (drw_w * psav->XExp1) / psav->XExp2 + 1; 1673aa9e3350Smrg drw_h = (drw_h * psav->YExp1) / psav->YExp2 + 1; 1674aa9e3350Smrg dstBox->x1 = (dstBox->x1 * psav->XExp1) / psav->XExp2; 1675aa9e3350Smrg dstBox->y1 = (dstBox->y1 * psav->YExp1) / psav->YExp2; 1676aa9e3350Smrg dstBox->x2 = (dstBox->x2 * psav->XExp1) / psav->XExp2; 1677aa9e3350Smrg dstBox->y2 = (dstBox->y2 * psav->YExp1) / psav->YExp2; 1678ab47cfaaSmrg dstBox->x1 += psav->displayXoffset; 1679ab47cfaaSmrg dstBox->y1 += psav->displayYoffset; 1680aa9e3350Smrg dstBox->x2 += psav->displayXoffset; 1681aa9e3350Smrg dstBox->y2 += psav->displayYoffset; 1682ab47cfaaSmrg } 1683ab47cfaaSmrg 1684ab47cfaaSmrg if (psav->IsSecondary) { 1685ab47cfaaSmrg OUTREG(SEC_STREAM2_HSCALING, 1686ab47cfaaSmrg ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1687ab47cfaaSmrg /* BUGBUG need to add 00040000 if src stride > 2048 */ 1688ab47cfaaSmrg OUTREG(SEC_STREAM2_VSCALING, 1689ab47cfaaSmrg ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1690ab47cfaaSmrg } else if (psav->IsPrimary) { 1691ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALING, 1692ab47cfaaSmrg ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1693ab47cfaaSmrg /* BUGBUG need to add 00040000 if src stride > 2048 */ 1694ab47cfaaSmrg OUTREG(SEC_STREAM_VSCALING, 1695ab47cfaaSmrg ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1696ab47cfaaSmrg } else { 1697ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALING, 1698ab47cfaaSmrg ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1699ab47cfaaSmrg /* BUGBUG need to add 00040000 if src stride > 2048 */ 1700ab47cfaaSmrg OUTREG(SEC_STREAM_VSCALING, 1701ab47cfaaSmrg ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1702ab47cfaaSmrg#if 0 1703ab47cfaaSmrg OUTREG(SEC_STREAM2_HSCALING, 1704ab47cfaaSmrg ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1705ab47cfaaSmrg /* BUGBUG need to add 00040000 if src stride > 2048 */ 1706ab47cfaaSmrg OUTREG(SEC_STREAM2_VSCALING, 1707ab47cfaaSmrg ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1708ab47cfaaSmrg#endif 1709ab47cfaaSmrg } 1710ab47cfaaSmrg 1711ab47cfaaSmrg /* 1712ab47cfaaSmrg * Set surface location and stride. We use x1>>15 because all surfaces 1713ab47cfaaSmrg * are 2 bytes/pixel. 1714ab47cfaaSmrg */ 1715ab47cfaaSmrg 1716ab47cfaaSmrg if (psav->IsSecondary) { 1717ab47cfaaSmrg OUTREG(SEC_STREAM2_FBUF_ADDR0, (offset + (x1>>15)) 1718ab47cfaaSmrg & (0x7ffffff & ~BASE_PAD)); 1719ab47cfaaSmrg OUTREG(SEC_STREAM2_STRIDE_LPB, pitch & 0xfff ); 1720ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1721ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 172238770048Smrg | (dstBox->y2 - dstBox->y1) ); 1723ab47cfaaSmrg } else if (psav->IsPrimary) { 1724ab47cfaaSmrg OUTREG(SEC_STREAM_FBUF_ADDR0, (offset + (x1>>15)) 1725ab47cfaaSmrg & (0x7ffffff & ~BASE_PAD)); 1726ab47cfaaSmrg OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff ); 1727ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1728ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 172938770048Smrg | (dstBox->y2 - dstBox->y1) ); 1730ab47cfaaSmrg } else { 1731ab47cfaaSmrg OUTREG(SEC_STREAM_FBUF_ADDR0, (offset + (x1>>15)) 1732ab47cfaaSmrg & (0x7ffffff & ~BASE_PAD)); 1733ab47cfaaSmrg OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff ); 1734ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1735ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 173638770048Smrg | (dstBox->y2 - dstBox->y1) ); 1737ab47cfaaSmrg#if 0 1738ab47cfaaSmrg OUTREG(SEC_STREAM2_FBUF_ADDR0, (offset + (x1>>15)) 1739ab47cfaaSmrg & (0x7ffffff & ~BASE_PAD)); 1740ab47cfaaSmrg OUTREG(SEC_STREAM2_STRIDE_LPB, pitch & 0xfff ); 1741ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1742ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 174338770048Smrg | (dstBox->y2 - dstBox->y1) ); 1744ab47cfaaSmrg#endif 1745ab47cfaaSmrg } 1746ab47cfaaSmrg 1747ab47cfaaSmrg#if 0 1748ab47cfaaSmrg /* Set color key on primary. */ 1749ab47cfaaSmrg 1750ab47cfaaSmrg SavageSetColorKey( pScrn ); 1751ab47cfaaSmrg#endif 1752ab47cfaaSmrg 1753ab47cfaaSmrg /* Set FIFO L2 on second stream. */ 1754ab47cfaaSmrg /* Is CR92 shadowed for crtc2? -- AGD */ 1755ab47cfaaSmrg if( pPriv->lastKnownPitch != pitch ) 1756ab47cfaaSmrg { 1757ab47cfaaSmrg unsigned char cr92; 1758ab47cfaaSmrg 1759ab47cfaaSmrg pPriv->lastKnownPitch = pitch; 1760ab47cfaaSmrg pitch = (pitch + 7) / 8 - 4; 1761ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x92); 1762ab47cfaaSmrg cr92 = VGAIN8(vgaCRReg); 1763ab47cfaaSmrg VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 1764ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x93); 1765ab47cfaaSmrg VGAOUT8(vgaCRReg, pitch); 1766ab47cfaaSmrg } 1767ab47cfaaSmrg} 1768ab47cfaaSmrg 1769ab47cfaaSmrgstatic void 1770ab47cfaaSmrgSavageDisplayVideo2000( 1771ab47cfaaSmrg ScrnInfoPtr pScrn, 1772ab47cfaaSmrg int id, 1773ab47cfaaSmrg int offset, 1774ab47cfaaSmrg short width, short height, 1775ab47cfaaSmrg int pitch, 1776ab47cfaaSmrg int x1, int y1, int x2, int y2, 1777ab47cfaaSmrg BoxPtr dstBox, 1778ab47cfaaSmrg short src_w, short src_h, 1779ab47cfaaSmrg short drw_w, short drw_h 1780ab47cfaaSmrg){ 1781ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 17822b2b4fcbSmrg#if 0 1783ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 17842b2b4fcbSmrg#endif 1785ab47cfaaSmrg /*DisplayModePtr mode = pScrn->currentMode;*/ 1786ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 17872b2b4fcbSmrg#if 0 1788ab47cfaaSmrg int vgaCRIndex, vgaCRReg, vgaIOBase; 17892b2b4fcbSmrg#endif 17902b2b4fcbSmrg CARD32 addr0; 17912b2b4fcbSmrg#if 0 17922b2b4fcbSmrg CARD32 addr1, addr2; 17932b2b4fcbSmrg#endif 1794ab47cfaaSmrg 17952b2b4fcbSmrg#if 0 1796ab47cfaaSmrg vgaIOBase = hwp->IOBase; 1797ab47cfaaSmrg vgaCRIndex = vgaIOBase + 4; 1798ab47cfaaSmrg vgaCRReg = vgaIOBase + 5; 17992b2b4fcbSmrg#endif 1800ab47cfaaSmrg 1801ab47cfaaSmrg 1802ab47cfaaSmrg if( psav->videoFourCC != id ) 1803ab47cfaaSmrg SavageStreamsOff(pScrn); 1804ab47cfaaSmrg 18058697ee19Smrg if( !(psav->videoFlags & VF_STREAMS_ON) ) 1806ab47cfaaSmrg { 1807ab47cfaaSmrg SavageSetBlend(pScrn,id); 1808ab47cfaaSmrg SavageStreamsOn(pScrn); 1809ab47cfaaSmrg SavageResetVideo(pScrn); 18108697ee19Smrg pPriv->lastKnownPitch = 0; 1811ab47cfaaSmrg } 1812ab47cfaaSmrg 1813ab47cfaaSmrg if (src_w > drw_w) 1814ab47cfaaSmrg OUTREG(SEC_STREAM_SRC_START_2000, 0); 1815ab47cfaaSmrg else 1816ab47cfaaSmrg OUTREG(SEC_STREAM_SRC_START_2000, SRCSTART(x1, y1)); 1817ab47cfaaSmrg 1818ab47cfaaSmrg /*OUTREG(SEC_STREAM_SRC_SIZE_2000, SRCSIZE(src_w, src_h));*/ 1819ab47cfaaSmrg OUTREG(SEC_STREAM_SRC_SIZE_2000, 1820ab47cfaaSmrg SRCSIZE((dstBox->x2-dstBox->x1), (dstBox->y2-dstBox->y1))); 1821ab47cfaaSmrg /* 1822ab47cfaaSmrg buffersize = (src_w * src_h * 2) / 4096; 1823ab47cfaaSmrg OUTREG(SEC_STREAM_BUFFERSIZE_2000, (buffersize & 0xffffff) << 12); 1824ab47cfaaSmrg */ 1825ab47cfaaSmrg 1826ab47cfaaSmrg /*SavageResetVideo(pScrn);*/ 1827ab47cfaaSmrg 1828ab47cfaaSmrg if( src_w > drw_w ) 1829ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALE_NORMALIZE, HSCALING_NORMALIZE(drw_w,src_w)); 1830ab47cfaaSmrg else 1831ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALE_NORMALIZE, (2048 << 16)); 1832ab47cfaaSmrg 1833ab47cfaaSmrg /* Calculate horizontal and vertical scale factors. */ 1834ab47cfaaSmrg if ((src_w > drw_w) || (src_h > drw_h)) 1835ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALING, (HSCALING_2000(src_w,drw_w)) | 0x01000000); 1836ab47cfaaSmrg else 1837ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALING, HSCALING_2000(src_w,drw_w)); 1838ab47cfaaSmrg 1839ab47cfaaSmrg OUTREG(SEC_STREAM_VSCALING, VSCALING_2000(src_h,drw_h)); 1840ab47cfaaSmrg 1841ab47cfaaSmrg /* 1842ab47cfaaSmrg * Set surface location and stride. We use x1>>15 because all surfaces 1843ab47cfaaSmrg * are 2 bytes/pixel. 1844ab47cfaaSmrg */ 1845ab47cfaaSmrg 1846ab47cfaaSmrg addr0 = offset + (x1>>15); /* Y in YCbCr420 */ 18472b2b4fcbSmrg#if 0 1848ab47cfaaSmrg addr1 = addr0 + (width * height); /* Cb in in YCbCr420 */ 1849ab47cfaaSmrg addr2 = addr1 + ((width * height) / 4); /* Cr in in YCbCr420 */ 18502b2b4fcbSmrg#endif 1851ab47cfaaSmrg OUTREG(SEC_STREAM_FBUF_ADDR0, (addr0) & (0x3fffff & ~BASE_PAD)); 1852ab47cfaaSmrg#if 0 1853ab47cfaaSmrg OUTREG(SEC_STREAM_FBUF_ADDR1, (addr1) & (0x3fffff & ~BASE_PAD)); 1854ab47cfaaSmrg OUTREG(SEC_STREAM_FBUF_ADDR2, (addr2) & (0x3fffff & ~BASE_PAD)); 1855ab47cfaaSmrg#endif 1856ab47cfaaSmrg 1857ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_START, XY_2000(dstBox->x1,dstBox->y1)); 1858ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_SZ, 1859ab47cfaaSmrg WH_2000((dstBox->x2-dstBox->x1),(dstBox->y2-dstBox->y1))); 1860ab47cfaaSmrg 1861ab47cfaaSmrg /*pitch = width * 2;*/ 1862ab47cfaaSmrg OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff); 1863ab47cfaaSmrg#if 0 1864ab47cfaaSmrg /* Y stride + CbCr stride in YCbCr420 */ 1865ab47cfaaSmrg OUTREG(SEC_STREAM_STRIDE, (pitch & 0xfff) + ((pitch & 0xfff) << 15)); 1866ab47cfaaSmrg#endif 1867ab47cfaaSmrg 1868ab47cfaaSmrg#if 0 1869ab47cfaaSmrg /* Set color key on primary. */ 1870ab47cfaaSmrg 1871ab47cfaaSmrg SavageSetColorKey2000( pScrn ); 1872ab47cfaaSmrg#endif 1873ab47cfaaSmrg 1874ab47cfaaSmrg#if 0 1875ab47cfaaSmrg /* Set FIFO L2 on second stream. */ 1876ab47cfaaSmrg if( pPriv->lastKnownPitch != pitch ) 1877ab47cfaaSmrg { 1878ab47cfaaSmrg unsigned char cr92; 1879ab47cfaaSmrg 1880ab47cfaaSmrg pPriv->lastKnownPitch = pitch; 1881ab47cfaaSmrg pitch = (pitch + 7) / 8 - 4; 1882ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x92); 1883ab47cfaaSmrg cr92 = VGAIN8(vgaCRReg); 1884ab47cfaaSmrg VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 1885ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x93); 1886ab47cfaaSmrg VGAOUT8(vgaCRReg, pitch); 1887ab47cfaaSmrg } 1888ab47cfaaSmrg#endif 1889ab47cfaaSmrg} 1890ab47cfaaSmrg 18911473d951Smrgstatic void 18921473d951SmrgSavageFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes) 18931473d951Smrg{ 18941473d951Smrg#if HAVE_XV_DRAWABLE_HELPER 18951473d951Smrg xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes); 18961473d951Smrg#else 18971473d951Smrg xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes); 18981473d951Smrg#endif 18991473d951Smrg} 19001473d951Smrg 1901ab47cfaaSmrgstatic int 1902ab47cfaaSmrgSavagePutImage( 1903ab47cfaaSmrg ScrnInfoPtr pScrn, 1904ab47cfaaSmrg short src_x, short src_y, 1905ab47cfaaSmrg short drw_x, short drw_y, 1906ab47cfaaSmrg short src_w, short src_h, 1907ab47cfaaSmrg short drw_w, short drw_h, 1908ab47cfaaSmrg int id, unsigned char* buf, 1909ab47cfaaSmrg short width, short height, 1910ab47cfaaSmrg Bool sync, 1911ab47cfaaSmrg RegionPtr clipBoxes, pointer data, 1912ab47cfaaSmrg DrawablePtr pDraw 1913ab47cfaaSmrg){ 1914ab47cfaaSmrg SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1915ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 19162b2b4fcbSmrg#ifdef SAVAGEDRI 1917ab47cfaaSmrg ScreenPtr pScreen = pScrn->pScreen; 19182b2b4fcbSmrg#endif 1919ab47cfaaSmrg INT32 x1, x2, y1, y2; 1920ab47cfaaSmrg unsigned char *dst_start; 19212b2b4fcbSmrg int new_size, offset, offsetV=0, offsetU=0; 1922ab47cfaaSmrg int srcPitch, srcPitch2=0, dstPitch; 19231473d951Smrg int planarFrameSize; 1924ab47cfaaSmrg int top, left, npixels, nlines; 1925ab47cfaaSmrg BoxRec dstBox; 1926ab47cfaaSmrg CARD32 tmp; 1927ab47cfaaSmrg/* xf86ErrorFVerb(XVTRACE,"SavagePutImage\n"); */ 1928ab47cfaaSmrg if(drw_w > 16384) drw_w = 16384; 1929ab47cfaaSmrg 1930ab47cfaaSmrg /* Clip */ 1931ab47cfaaSmrg x1 = src_x; 1932ab47cfaaSmrg x2 = src_x + src_w; 1933ab47cfaaSmrg y1 = src_y; 1934ab47cfaaSmrg y2 = src_y + src_h; 1935ab47cfaaSmrg 1936ab47cfaaSmrg dstBox.x1 = drw_x; 1937ab47cfaaSmrg dstBox.x2 = drw_x + drw_w; 1938ab47cfaaSmrg dstBox.y1 = drw_y; 1939ab47cfaaSmrg dstBox.y2 = drw_y + drw_h; 1940ab47cfaaSmrg 1941ab47cfaaSmrg SavageClipVideo(&dstBox, &x1, &x2, &y1, &y2, 1942ab47cfaaSmrg REGION_EXTENTS(pScreen, clipBoxes), width, height); 1943ab47cfaaSmrg 1944ab47cfaaSmrg drw_w = dstBox.x2 - dstBox.x1; 1945ab47cfaaSmrg drw_h = dstBox.y2 - dstBox.y1; 1946ab47cfaaSmrg src_w = ( x2 - x1 ) >> 16; 1947ab47cfaaSmrg src_h = ( y2 - y1 ) >> 16; 1948ab47cfaaSmrg 1949ab47cfaaSmrg if((x1 >= x2) || (y1 >= y2)) 1950ab47cfaaSmrg return Success; 1951ab47cfaaSmrg 1952ab47cfaaSmrg dstBox.x1 -= pScrn->frameX0; 1953ab47cfaaSmrg dstBox.x2 -= pScrn->frameX0; 1954ab47cfaaSmrg dstBox.y1 -= pScrn->frameY0; 1955ab47cfaaSmrg dstBox.y2 -= pScrn->frameY0; 1956ab47cfaaSmrg 19571473d951Smrg /* All formats directly displayable by Savage are packed and 2 bytes per pixel */ 1958ab47cfaaSmrg dstPitch = ((width << 1) + 15) & ~15; 1959ab47cfaaSmrg new_size = dstPitch * height; 1960ab47cfaaSmrg 1961ab47cfaaSmrg switch(id) { 1962ab47cfaaSmrg case FOURCC_Y211: /* Y211 */ 1963ab47cfaaSmrg srcPitch = width; 1964ab47cfaaSmrg break; 1965ab47cfaaSmrg case FOURCC_YV12: /* YV12 */ 1966ab47cfaaSmrg srcPitch = (width + 3) & ~3; 1967ab47cfaaSmrg offsetV = srcPitch * height; 1968ab47cfaaSmrg srcPitch2 = ((width >> 1) + 3) & ~3; 1969ab47cfaaSmrg offsetU = (srcPitch2 * (height >> 1)) + offsetV; 1970ab47cfaaSmrg break; 1971ab47cfaaSmrg case FOURCC_I420: 1972ab47cfaaSmrg srcPitch = (width + 3) & ~3; 1973ab47cfaaSmrg offsetU = srcPitch * height; 1974ab47cfaaSmrg srcPitch2 = ((width >> 1) + 3) & ~3; 1975ab47cfaaSmrg offsetV = (srcPitch2 * (height >> 1)) + offsetU; 1976ab47cfaaSmrg break; 1977ab47cfaaSmrg case FOURCC_RV15: /* RGB15 */ 1978ab47cfaaSmrg case FOURCC_RV16: /* RGB16 */ 1979ab47cfaaSmrg case FOURCC_YUY2: /* YUY2 */ 1980ab47cfaaSmrg default: 1981ab47cfaaSmrg srcPitch = (width << 1); 1982ab47cfaaSmrg break; 1983ab47cfaaSmrg } 1984ab47cfaaSmrg 19851473d951Smrg /* Calculate required memory for all planar frames */ 19861473d951Smrg planarFrameSize = 0; 19878697ee19Smrg if (srcPitch2 != 0 && S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv) { 19881473d951Smrg new_size = ((new_size + 0xF) & ~0xF); 19891473d951Smrg planarFrameSize = srcPitch * height + srcPitch2 * height; 19901473d951Smrg } 19911473d951Smrg 19921473d951Smrg /* Check whether AGP buffers can be allocated. If not, fall back to ordinary 19931473d951Smrg upload to framebuffer (slower) */ 1994aa9e3350Smrg#ifdef SAVAGEDRI 19951473d951Smrg if (!pPriv->tried_agp && !psav->IsPCI && psav->drmFD > 0 && psav->DRIServerInfo != NULL) { 19961473d951Smrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 19971473d951Smrg 19981473d951Smrg pPriv->tried_agp = TRUE; 19991473d951Smrg if (pSAVAGEDRIServer->agpXVideo.size >= max(new_size, planarFrameSize)) { 20001473d951Smrg if (pSAVAGEDRIServer->agpXVideo.map == NULL && 20011473d951Smrg drmMap( psav->drmFD, 20021473d951Smrg pSAVAGEDRIServer->agpXVideo.handle, 20031473d951Smrg pSAVAGEDRIServer->agpXVideo.size, 20041473d951Smrg &pSAVAGEDRIServer->agpXVideo.map ) < 0 ) { 20051473d951Smrg 20061473d951Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] XVideo: Could not map agpXVideo \n" ); 20071473d951Smrg pPriv->agpBufferOffset = 0; 20081473d951Smrg pPriv->agpBufferMap = NULL; 20091473d951Smrg } else { 20101473d951Smrg pPriv->agpBufferMap = pSAVAGEDRIServer->agpXVideo.map; 20111473d951Smrg pPriv->agpBufferOffset = pSAVAGEDRIServer->agpXVideo.offset; 20121473d951Smrg pPriv->agpBase = drmAgpBase(psav->drmFD); 20131473d951Smrg#if 0 20141473d951Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 20151473d951Smrg "[agp] agpXVideo mapped at 0x%08lx aperture=0x%08x offset=0x%08lx\n", 20161473d951Smrg (unsigned long)pPriv->agpBufferMap, pPriv->agpBase, pPriv->agpBufferOffset); 20171473d951Smrg#endif 20181473d951Smrg } 20191473d951Smrg } else { 20201473d951Smrg /* This situation is expected if AGPforXv is disabled, otherwise report. */ 20211473d951Smrg if (pSAVAGEDRIServer->agpXVideo.size > 0) { 20221473d951Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 2023aa9e3350Smrg "[agp] XVideo: not enough space in buffer (got %ld bytes, required %d bytes).\n", 2024aa9e3350Smrg (long int)pSAVAGEDRIServer->agpXVideo.size, max(new_size, planarFrameSize)); 20251473d951Smrg } 20261473d951Smrg pPriv->agpBufferMap = NULL; 20271473d951Smrg pPriv->agpBufferOffset = 0; 20281473d951Smrg } 20298697ee19Smrg } 2030aa9e3350Smrg#endif /* SAVAGEDRI */ 20318697ee19Smrg 20321473d951Smrg 20331473d951Smrg /* Buffer for final packed frame */ 20341473d951Smrg pPriv->video_offset = SavageAllocateMemory( 20351473d951Smrg pScrn, &pPriv->video_memory, 20361473d951Smrg new_size); 2037ab47cfaaSmrg if (pPriv->video_offset == 0) 2038ab47cfaaSmrg return BadAlloc; 2039ab47cfaaSmrg 20401473d951Smrg /* Packed format cases */ 20411473d951Smrg if (planarFrameSize == 0) { 20421473d951Smrg pPriv->video_planarbuf = 0; 20431473d951Smrg 20441473d951Smrg /* Planar format cases */ 20451473d951Smrg } else { 20461473d951Smrg /* Hardware-assisted planar conversion only works on 16-byte aligned addresses */ 20471473d951Smrg pPriv->video_planarbuf = SavageAllocateMemory( 20481473d951Smrg pScrn, &pPriv->video_planarmem, 20491473d951Smrg ((planarFrameSize + 0xF) & ~0xF)); 20501473d951Smrg if (pPriv->video_planarbuf != 0) { 20511473d951Smrg /* TODO: stop any pending conversions when buffers change... */ 20521473d951Smrg pPriv->video_planarbuf = ((pPriv->video_planarbuf + 0xF) & ~0xF); 20531473d951Smrg } else { 20541473d951Smrg /* Fallback using software conversion */ 20551473d951Smrg } 20561473d951Smrg } 20571473d951Smrg 2058ab47cfaaSmrg /* copy data */ 2059ab47cfaaSmrg top = y1 >> 16; 2060ab47cfaaSmrg left = (x1 >> 16) & ~1; 2061ab47cfaaSmrg npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; 2062ab47cfaaSmrg left <<= 1; 2063ab47cfaaSmrg 2064ab47cfaaSmrg offset = (pPriv->video_offset) + (top * dstPitch); 2065ab47cfaaSmrg dst_start = (psav->FBBase + ((offset + left) & ~BASE_PAD)); 2066ab47cfaaSmrg 2067ab47cfaaSmrg switch(id) { 2068ab47cfaaSmrg case FOURCC_YV12: /* YV12 */ 2069ab47cfaaSmrg case FOURCC_I420: 2070ab47cfaaSmrg top &= ~1; 2071ab47cfaaSmrg tmp = ((top >> 1) * srcPitch2) + (left >> 2); 2072ab47cfaaSmrg offsetU += tmp; 2073ab47cfaaSmrg offsetV += tmp; 2074ab47cfaaSmrg nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 20751473d951Smrg if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv && (npixels & 0xF) == 0 && pPriv->video_planarbuf != 0) { 2076aa9e3350Smrg#ifdef SAVAGEDRI 20771473d951Smrg if (pPriv->agpBufferMap != NULL) { 20781473d951Smrg /* Using copy to AGP memory */ 20791473d951Smrg SavageCopyPlanarDataBCI( 20801473d951Smrg pScrn, 20811473d951Smrg buf + (top * srcPitch) + (left >> 1), 20821473d951Smrg buf + offsetV, 20831473d951Smrg buf + offsetU, 20841473d951Smrg dst_start, 20851473d951Smrg pPriv->agpBufferMap, 20861473d951Smrg pPriv->agpBase + pPriv->agpBufferOffset, 20871473d951Smrg srcPitch, srcPitch2, dstPitch, nlines, npixels, TRUE); 20886aec45a7Smrg } else 2089aa9e3350Smrg#endif /* SAVAGEDRI */ 20906aec45a7Smrg { 20911473d951Smrg /* Using ordinary copy to framebuffer */ 20921473d951Smrg SavageCopyPlanarDataBCI( 20931473d951Smrg pScrn, 20941473d951Smrg buf + (top * srcPitch) + (left >> 1), 20951473d951Smrg buf + offsetV, 20961473d951Smrg buf + offsetU, 20971473d951Smrg dst_start, 20981473d951Smrg (unsigned char *)psav->FBBase + pPriv->video_planarbuf, 20991473d951Smrg pPriv->video_planarbuf, 21001473d951Smrg srcPitch, srcPitch2, dstPitch, nlines, npixels, FALSE); 21011473d951Smrg } 2102ab47cfaaSmrg } else { 2103ab47cfaaSmrg SavageCopyPlanarData( 2104ab47cfaaSmrg buf + (top * srcPitch) + (left >> 1), 2105ab47cfaaSmrg buf + offsetV, 2106ab47cfaaSmrg buf + offsetU, 2107ab47cfaaSmrg dst_start, srcPitch, srcPitch2, dstPitch, nlines, npixels); 2108ab47cfaaSmrg } 2109ab47cfaaSmrg break; 2110ab47cfaaSmrg case FOURCC_Y211: /* Y211 */ 2111ab47cfaaSmrg case FOURCC_RV15: /* RGB15 */ 2112ab47cfaaSmrg case FOURCC_RV16: /* RGB16 */ 2113ab47cfaaSmrg case FOURCC_YUY2: /* YUY2 */ 2114ab47cfaaSmrg default: 2115ab47cfaaSmrg buf += (top * srcPitch) + left; 2116ab47cfaaSmrg nlines = ((y2 + 0xffff) >> 16) - top; 2117ab47cfaaSmrg SavageCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 2118ab47cfaaSmrg break; 2119ab47cfaaSmrg } 2120ab47cfaaSmrg 2121ab47cfaaSmrg /* We need to enable the video before we draw the chroma color. 2122ab47cfaaSmrg Otherwise, we get blue flashes. */ 2123ab47cfaaSmrg 2124ab47cfaaSmrg SavageDisplayVideo(pScrn, id, offset, width, height, dstPitch, 2125ab47cfaaSmrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 2126ab47cfaaSmrg 2127ab47cfaaSmrg /* update cliplist */ 2128ab47cfaaSmrg if(!REGION_EQUAL(pScreen, &pPriv->clip, clipBoxes)) { 2129ab47cfaaSmrg REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 2130ab47cfaaSmrg /* draw these */ 21311473d951Smrg SavageFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes); 2132ab47cfaaSmrg 2133ab47cfaaSmrg } 2134ab47cfaaSmrg 2135ab47cfaaSmrg pPriv->videoStatus = CLIENT_VIDEO_ON; 2136ab47cfaaSmrg 2137ab47cfaaSmrg return Success; 2138ab47cfaaSmrg} 2139ab47cfaaSmrg 2140ab47cfaaSmrgstatic int 2141ab47cfaaSmrgSavageQueryImageAttributes( 2142ab47cfaaSmrg ScrnInfoPtr pScrn, 2143ab47cfaaSmrg int id, 2144ab47cfaaSmrg unsigned short *w, unsigned short *h, 2145ab47cfaaSmrg int *pitches, int *offsets 2146ab47cfaaSmrg){ 2147ab47cfaaSmrg int size, tmp; 2148ab47cfaaSmrg 2149ab47cfaaSmrg if(*w > 1024) *w = 1024; 2150ab47cfaaSmrg if(*h > 1024) *h = 1024; 2151ab47cfaaSmrg 2152ab47cfaaSmrg *w = (*w + 1) & ~1; 2153ab47cfaaSmrg if(offsets) offsets[0] = 0; 2154ab47cfaaSmrg 2155ab47cfaaSmrg switch(id) { 2156ab47cfaaSmrg case FOURCC_IA44: 2157ab47cfaaSmrg if (pitches) pitches[0]=*w; 2158ab47cfaaSmrg size=(*w)*(*h); 2159ab47cfaaSmrg break; 2160ab47cfaaSmrg case FOURCC_Y211: 2161ab47cfaaSmrg size = *w << 2; 2162ab47cfaaSmrg if(pitches) pitches[0] = size; 2163ab47cfaaSmrg size *= *h; 2164ab47cfaaSmrg break; 2165ab47cfaaSmrg case FOURCC_YV12: 2166ab47cfaaSmrg case FOURCC_I420: 2167ab47cfaaSmrg *h = (*h + 1) & ~1; 2168ab47cfaaSmrg size = (*w + 3) & ~3; 2169ab47cfaaSmrg if(pitches) pitches[0] = size; 2170ab47cfaaSmrg size *= *h; 2171ab47cfaaSmrg if(offsets) offsets[1] = size; 2172ab47cfaaSmrg tmp = ((*w >> 1) + 3) & ~3; 2173ab47cfaaSmrg if(pitches) pitches[1] = pitches[2] = tmp; 2174ab47cfaaSmrg tmp *= (*h >> 1); 2175ab47cfaaSmrg size += tmp; 2176ab47cfaaSmrg if(offsets) offsets[2] = size; 2177ab47cfaaSmrg size += tmp; 2178ab47cfaaSmrg break; 2179ab47cfaaSmrg case FOURCC_RV15: /* RGB15 */ 2180ab47cfaaSmrg case FOURCC_RV16: /* RGB16 */ 2181ab47cfaaSmrg case FOURCC_YUY2: 2182ab47cfaaSmrg default: 2183ab47cfaaSmrg size = *w << 1; 2184ab47cfaaSmrg if(pitches) pitches[0] = size; 2185ab47cfaaSmrg size *= *h; 2186ab47cfaaSmrg break; 2187ab47cfaaSmrg } 2188ab47cfaaSmrg 2189ab47cfaaSmrg return size; 2190ab47cfaaSmrg} 2191ab47cfaaSmrg 2192ab47cfaaSmrg/****************** Offscreen stuff ***************/ 2193ab47cfaaSmrg 2194ab47cfaaSmrgtypedef struct { 2195ab47cfaaSmrg void *surface_memory; 2196ab47cfaaSmrg Bool isOn; 2197ab47cfaaSmrg} OffscreenPrivRec, * OffscreenPrivPtr; 2198ab47cfaaSmrg 2199ab47cfaaSmrgstatic int 2200ab47cfaaSmrgSavageAllocateSurface( 2201ab47cfaaSmrg ScrnInfoPtr pScrn, 2202ab47cfaaSmrg int id, 2203ab47cfaaSmrg unsigned short w, 2204ab47cfaaSmrg unsigned short h, 2205ab47cfaaSmrg XF86SurfacePtr surface 2206ab47cfaaSmrg){ 2207ab47cfaaSmrg int offset, size; 22082b2b4fcbSmrg int pitch; 2209ab47cfaaSmrg void *surface_memory = NULL; 2210ab47cfaaSmrg OffscreenPrivPtr pPriv; 2211ab47cfaaSmrg 2212ab47cfaaSmrg if((w > 1024) || (h > 1024)) 2213ab47cfaaSmrg return BadAlloc; 2214ab47cfaaSmrg 2215ab47cfaaSmrg w = (w + 1) & ~1; 2216ab47cfaaSmrg pitch = ((w << 1) + 15) & ~15; 2217ab47cfaaSmrg size = pitch * h; 2218ab47cfaaSmrg 2219ab47cfaaSmrg offset = SavageAllocateMemory(pScrn, &surface_memory, size); 2220ab47cfaaSmrg if (offset == 0) 2221ab47cfaaSmrg return BadAlloc; 2222ab47cfaaSmrg 2223ab47cfaaSmrg surface->width = w; 2224ab47cfaaSmrg surface->height = h; 2225ab47cfaaSmrg 2226aa9e3350Smrg if(!(surface->pitches = malloc(sizeof(int)))) { 2227ab47cfaaSmrg SavageFreeMemory(pScrn, surface_memory); 2228ab47cfaaSmrg return BadAlloc; 2229ab47cfaaSmrg } 2230aa9e3350Smrg if(!(surface->offsets = malloc(sizeof(int)))) { 2231aa9e3350Smrg free(surface->pitches); 2232ab47cfaaSmrg SavageFreeMemory(pScrn, surface_memory); 2233ab47cfaaSmrg return BadAlloc; 2234ab47cfaaSmrg } 2235aa9e3350Smrg if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { 2236aa9e3350Smrg free(surface->pitches); 2237aa9e3350Smrg free(surface->offsets); 2238ab47cfaaSmrg SavageFreeMemory(pScrn, surface_memory); 2239ab47cfaaSmrg return BadAlloc; 2240ab47cfaaSmrg } 2241ab47cfaaSmrg 2242ab47cfaaSmrg pPriv->surface_memory = surface_memory; 2243ab47cfaaSmrg pPriv->isOn = FALSE; 2244ab47cfaaSmrg 2245ab47cfaaSmrg surface->pScrn = pScrn; 2246ab47cfaaSmrg surface->id = id; 2247ab47cfaaSmrg surface->pitches[0] = pitch; 2248ab47cfaaSmrg surface->offsets[0] = offset; /*area->box.y1 * fbpitch;*/ 2249ab47cfaaSmrg surface->devPrivate.ptr = (pointer)pPriv; 2250ab47cfaaSmrg 2251ab47cfaaSmrg return Success; 2252ab47cfaaSmrg} 2253ab47cfaaSmrg 2254ab47cfaaSmrgstatic int 2255ab47cfaaSmrgSavageStopSurface( 2256ab47cfaaSmrg XF86SurfacePtr surface 2257ab47cfaaSmrg){ 2258ab47cfaaSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 2259ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageStopSurface\n"); 2260ab47cfaaSmrg 2261ab47cfaaSmrg if(pPriv->isOn) { 2262ab47cfaaSmrg /*SavagePtr psav = SAVPTR(surface->pScrn);*/ 2263ab47cfaaSmrg /*SavageClipVWindow(surface->pScrn);*/ 2264ab47cfaaSmrg SavageStreamsOff( surface->pScrn ); 2265ab47cfaaSmrg pPriv->isOn = FALSE; 2266ab47cfaaSmrg } 2267ab47cfaaSmrg 2268ab47cfaaSmrg return Success; 2269ab47cfaaSmrg} 2270ab47cfaaSmrg 2271ab47cfaaSmrg 2272ab47cfaaSmrgstatic int 2273ab47cfaaSmrgSavageFreeSurface( 2274ab47cfaaSmrg XF86SurfacePtr surface 2275ab47cfaaSmrg){ 2276ab47cfaaSmrg ScrnInfoPtr pScrn = surface->pScrn; 2277ab47cfaaSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 2278ab47cfaaSmrg 2279ab47cfaaSmrg if(pPriv->isOn) 2280ab47cfaaSmrg SavageStopSurface(surface); 2281ab47cfaaSmrg SavageFreeMemory(pScrn, pPriv->surface_memory); 2282aa9e3350Smrg free(surface->pitches); 2283aa9e3350Smrg free(surface->offsets); 2284aa9e3350Smrg free(surface->devPrivate.ptr); 2285ab47cfaaSmrg 2286ab47cfaaSmrg return Success; 2287ab47cfaaSmrg} 2288ab47cfaaSmrg 2289ab47cfaaSmrgstatic int 2290ab47cfaaSmrgSavageGetSurfaceAttribute( 2291ab47cfaaSmrg ScrnInfoPtr pScrn, 2292ab47cfaaSmrg Atom attribute, 2293ab47cfaaSmrg INT32 *value 2294ab47cfaaSmrg){ 2295ab47cfaaSmrg return SavageGetPortAttribute(pScrn, attribute, value, 2296ab47cfaaSmrg (pointer)(GET_PORT_PRIVATE(pScrn))); 2297ab47cfaaSmrg} 2298ab47cfaaSmrg 2299ab47cfaaSmrgstatic int 2300ab47cfaaSmrgSavageSetSurfaceAttribute( 2301ab47cfaaSmrg ScrnInfoPtr pScrn, 2302ab47cfaaSmrg Atom attribute, 2303ab47cfaaSmrg INT32 value 2304ab47cfaaSmrg){ 2305ab47cfaaSmrg return SavageSetPortAttribute(pScrn, attribute, value, 2306ab47cfaaSmrg (pointer)(GET_PORT_PRIVATE(pScrn))); 2307ab47cfaaSmrg} 2308ab47cfaaSmrg 2309ab47cfaaSmrg 2310ab47cfaaSmrgstatic int 2311ab47cfaaSmrgSavageDisplaySurface( 2312ab47cfaaSmrg XF86SurfacePtr surface, 2313ab47cfaaSmrg short src_x, short src_y, 2314ab47cfaaSmrg short drw_x, short drw_y, 2315ab47cfaaSmrg short src_w, short src_h, 2316ab47cfaaSmrg short drw_w, short drw_h, 2317ab47cfaaSmrg RegionPtr clipBoxes 2318ab47cfaaSmrg){ 2319ab47cfaaSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 2320ab47cfaaSmrg ScrnInfoPtr pScrn = surface->pScrn; 2321ab47cfaaSmrg ScreenPtr pScreen = pScrn->pScreen; 2322ab47cfaaSmrg SavagePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn); 2323ab47cfaaSmrg INT32 x1, y1, x2, y2; 2324ab47cfaaSmrg BoxRec dstBox; 2325ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageDisplaySurface\n"); 2326ab47cfaaSmrg 2327ab47cfaaSmrg x1 = src_x; 2328ab47cfaaSmrg x2 = src_x + src_w; 2329ab47cfaaSmrg y1 = src_y; 2330ab47cfaaSmrg y2 = src_y + src_h; 2331ab47cfaaSmrg 2332ab47cfaaSmrg dstBox.x1 = drw_x; 2333ab47cfaaSmrg dstBox.x2 = drw_x + drw_w; 2334ab47cfaaSmrg dstBox.y1 = drw_y; 2335ab47cfaaSmrg dstBox.y2 = drw_y + drw_h; 2336ab47cfaaSmrg 2337ab47cfaaSmrg SavageClipVideo(&dstBox, &x1, &x2, &y1, &y2, 2338ab47cfaaSmrg REGION_EXTENTS(pScreen, clipBoxes), 2339ab47cfaaSmrg surface->width, surface->height); 2340ab47cfaaSmrg 2341ab47cfaaSmrg if((x1 >= x2) || (y1 >= y2)) 2342ab47cfaaSmrg return Success; 2343ab47cfaaSmrg 2344ab47cfaaSmrg dstBox.x1 -= pScrn->frameX0; 2345ab47cfaaSmrg dstBox.x2 -= pScrn->frameX0; 2346ab47cfaaSmrg dstBox.y1 -= pScrn->frameY0; 2347ab47cfaaSmrg dstBox.y2 -= pScrn->frameY0; 2348ab47cfaaSmrg 2349ab47cfaaSmrg SavageDisplayVideo(pScrn, surface->id, surface->offsets[0], 2350ab47cfaaSmrg surface->width, surface->height, surface->pitches[0], 2351ab47cfaaSmrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 2352ab47cfaaSmrg 2353aa9e3350Smrg xf86XVFillKeyHelper(pScreen, portPriv->colorKey, clipBoxes); 2354ab47cfaaSmrg 2355ab47cfaaSmrg pPriv->isOn = TRUE; 2356ab47cfaaSmrg#if 0 2357ab47cfaaSmrg if(portPriv->videoStatus & CLIENT_VIDEO_ON) { 2358ab47cfaaSmrg REGION_EMPTY(pScreen, &portPriv->clip); 2359ab47cfaaSmrg UpdateCurrentTime(); 2360ab47cfaaSmrg portPriv->videoStatus = FREE_TIMER; 2361ab47cfaaSmrg portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 2362ab47cfaaSmrg } 2363ab47cfaaSmrg#endif 2364ab47cfaaSmrg 2365ab47cfaaSmrg return Success; 2366ab47cfaaSmrg} 2367ab47cfaaSmrg 2368ab47cfaaSmrg 2369ab47cfaaSmrgstatic void 2370ab47cfaaSmrgSavageInitOffscreenImages(ScreenPtr pScreen) 2371ab47cfaaSmrg{ 2372ab47cfaaSmrg XF86OffscreenImagePtr offscreenImages; 2373aa9e3350Smrg SavagePtr psav = SAVPTR(xf86ScreenToScrn(pScreen)); 2374ab47cfaaSmrg 2375ab47cfaaSmrg /* need to free this someplace */ 2376ab47cfaaSmrg if (!psav->offscreenImages) { 2377aa9e3350Smrg if(!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) 2378ab47cfaaSmrg return; 2379ab47cfaaSmrg psav->offscreenImages = offscreenImages; 2380ab47cfaaSmrg } else { 2381ab47cfaaSmrg offscreenImages = psav->offscreenImages; 2382ab47cfaaSmrg } 2383ab47cfaaSmrg 2384ab47cfaaSmrg offscreenImages[0].image = &Images[0]; 2385ab47cfaaSmrg offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | 2386ab47cfaaSmrg VIDEO_CLIP_TO_VIEWPORT; 2387ab47cfaaSmrg offscreenImages[0].alloc_surface = SavageAllocateSurface; 2388ab47cfaaSmrg offscreenImages[0].free_surface = SavageFreeSurface; 2389ab47cfaaSmrg offscreenImages[0].display = SavageDisplaySurface; 2390ab47cfaaSmrg offscreenImages[0].stop = SavageStopSurface; 2391ab47cfaaSmrg offscreenImages[0].setAttribute = SavageSetSurfaceAttribute; 2392ab47cfaaSmrg offscreenImages[0].getAttribute = SavageGetSurfaceAttribute; 2393ab47cfaaSmrg offscreenImages[0].max_width = 1024; 2394ab47cfaaSmrg offscreenImages[0].max_height = 1024; 2395ab47cfaaSmrg offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 2396ab47cfaaSmrg offscreenImages[0].attributes = Attributes; 2397ab47cfaaSmrg 2398ab47cfaaSmrg xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 2399ab47cfaaSmrg} 2400ab47cfaaSmrg 2401