savage_video.c revision 6aec45a7
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 2506aec45a7Smrg#ifdef XF86DRI 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,", 307ab47cfaaSmrg offset, (CARD32)MMIO_IN32( psav->MapBase, offset ), value ); 308ab47cfaaSmrg MMIO_OUT32( psav->MapBase, offset, value ); 309ab47cfaaSmrg ErrorF( " now %08lx\n", (CARD32)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{ 341ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 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 */ 387ab47cfaaSmrg xalloc((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) 402ab47cfaaSmrg xfree(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{ 880ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 881ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 882ab47cfaaSmrg XF86VideoAdaptorPtr adapt; 883ab47cfaaSmrg SavagePortPrivPtr pPriv; 884ab47cfaaSmrg 885ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageSetupImageVideo\n"); 886ab47cfaaSmrg 887ab47cfaaSmrg if(!(adapt = xcalloc(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; 10401473d951Smrg SavagePtr psav = SAVPTR(pScrn); 10411473d951Smrg ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; 1042ab47cfaaSmrg 1043ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageStopVideo\n"); 1044ab47cfaaSmrg 1045ab47cfaaSmrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1046ab47cfaaSmrg 1047ab47cfaaSmrg if(shutdown) { 1048ab47cfaaSmrg /*SavageClipVWindow(pScrn);*/ 1049ab47cfaaSmrg SavageStreamsOff( pScrn ); 10501473d951Smrg 10516aec45a7Smrg#ifdef XF86DRI 10521473d951Smrg if (pPriv->agpBufferMap != NULL) { 10531473d951Smrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 10541473d951Smrg 10551473d951Smrg /* agpXVideo is reused to implement UploadToScreen in EXA */ 10561473d951Smrg if (!psav->useEXA) { 10571473d951Smrg drmUnmap(pPriv->agpBufferMap, pSAVAGEDRIServer->agpXVideo.size); 10581473d951Smrg pSAVAGEDRIServer->agpXVideo.map = NULL; 10591473d951Smrg } 10601473d951Smrg pPriv->agpBufferMap = NULL; 10611473d951Smrg pPriv->agpBufferOffset = 0; 10621473d951Smrg } 10636aec45a7Smrg pPriv->tried_agp = FALSE; 10646aec45a7Smrg#endif 10651473d951Smrg 1066ab47cfaaSmrg if (pPriv->video_memory != NULL) { 1067ab47cfaaSmrg SavageFreeMemory(pScrn, pPriv->video_memory); 1068ab47cfaaSmrg pPriv->video_memory = NULL; 1069ab47cfaaSmrg } 10701473d951Smrg if (pPriv->video_planarmem != NULL) { 10711473d951Smrg SavageFreeMemory(pScrn, pPriv->video_planarmem); 10721473d951Smrg pPriv->video_planarmem = NULL; 10731473d951Smrg } 1074ab47cfaaSmrg pPriv->videoStatus = 0; 1075ab47cfaaSmrg } else { 1076ab47cfaaSmrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 1077ab47cfaaSmrg pPriv->videoStatus |= OFF_TIMER; 1078ab47cfaaSmrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 1079ab47cfaaSmrg } 1080ab47cfaaSmrg } 1081ab47cfaaSmrg} 1082ab47cfaaSmrg 1083ab47cfaaSmrg 1084ab47cfaaSmrgstatic int 1085ab47cfaaSmrgSavageSetPortAttribute( 1086ab47cfaaSmrg ScrnInfoPtr pScrn, 1087ab47cfaaSmrg Atom attribute, 1088ab47cfaaSmrg INT32 value, 1089ab47cfaaSmrg pointer data 1090ab47cfaaSmrg){ 1091ab47cfaaSmrg SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1092ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1093ab47cfaaSmrg 1094ab47cfaaSmrg if(attribute == xvColorKey) { 1095ab47cfaaSmrg pPriv->colorKey = value; 1096ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1097ab47cfaaSmrg SavageSetColorKey( pScrn ); 1098ab47cfaaSmrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1099ab47cfaaSmrg } 1100ab47cfaaSmrg else if( attribute == xvBrightness) { 1101ab47cfaaSmrg if((value < -128) || (value > 127)) 1102ab47cfaaSmrg return BadValue; 1103ab47cfaaSmrg pPriv->brightness = value; 1104ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1105ab47cfaaSmrg SavageSetColor( pScrn ); 1106ab47cfaaSmrg } 1107ab47cfaaSmrg else if( attribute == xvContrast) { 1108ab47cfaaSmrg if((value < 0) || (value > 255)) 1109ab47cfaaSmrg return BadValue; 1110ab47cfaaSmrg pPriv->contrast = value; 1111ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1112ab47cfaaSmrg SavageSetColor( pScrn ); 1113ab47cfaaSmrg } 1114ab47cfaaSmrg else if( attribute == xvSaturation) { 1115ab47cfaaSmrg if((value < 0) || (value > 255)) 1116ab47cfaaSmrg return BadValue; 1117ab47cfaaSmrg pPriv->saturation = value; 1118ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1119ab47cfaaSmrg SavageSetColor( pScrn ); 1120ab47cfaaSmrg } 1121ab47cfaaSmrg else if( attribute == xvHue) { 1122ab47cfaaSmrg if((value < -180) || (value > 180)) 1123ab47cfaaSmrg return BadValue; 1124ab47cfaaSmrg pPriv->hue = value; 1125ab47cfaaSmrg if( psav->videoFlags & VF_STREAMS_ON) 1126ab47cfaaSmrg SavageSetColor( pScrn ); 1127ab47cfaaSmrg } 1128ab47cfaaSmrg else if( attribute == xvInterpolation) { 1129ab47cfaaSmrg if((value < 0) || (value > 1)) 1130ab47cfaaSmrg return BadValue; 1131ab47cfaaSmrg if (value == 1) 1132ab47cfaaSmrg pPriv->interpolation = TRUE; 1133ab47cfaaSmrg else 1134ab47cfaaSmrg pPriv->interpolation = FALSE; 1135ab47cfaaSmrg } 1136ab47cfaaSmrg else 1137ab47cfaaSmrg return BadMatch; 1138ab47cfaaSmrg 1139ab47cfaaSmrg return Success; 1140ab47cfaaSmrg} 1141ab47cfaaSmrg 1142ab47cfaaSmrg 1143ab47cfaaSmrgstatic int 1144ab47cfaaSmrgSavageGetPortAttribute( 1145ab47cfaaSmrg ScrnInfoPtr pScrn, 1146ab47cfaaSmrg Atom attribute, 1147ab47cfaaSmrg INT32 *value, 1148ab47cfaaSmrg pointer data 1149ab47cfaaSmrg){ 1150ab47cfaaSmrg SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1151ab47cfaaSmrg 1152ab47cfaaSmrg if(attribute == xvColorKey) { 1153ab47cfaaSmrg *value = pPriv->colorKey; 1154ab47cfaaSmrg } 1155ab47cfaaSmrg else if( attribute == xvBrightness ) { 1156ab47cfaaSmrg *value = pPriv->brightness; 1157ab47cfaaSmrg } 1158ab47cfaaSmrg else if( attribute == xvContrast ) { 1159ab47cfaaSmrg *value = pPriv->contrast; 1160ab47cfaaSmrg } 1161ab47cfaaSmrg else if( attribute == xvHue ) { 1162ab47cfaaSmrg *value = pPriv->hue; 1163ab47cfaaSmrg } 1164ab47cfaaSmrg else if( attribute == xvSaturation ) { 1165ab47cfaaSmrg *value = pPriv->saturation; 1166ab47cfaaSmrg } 1167ab47cfaaSmrg else if( attribute == xvInterpolation ) { 1168ab47cfaaSmrg *value = pPriv->interpolation; 1169ab47cfaaSmrg } 1170ab47cfaaSmrg else return BadMatch; 1171ab47cfaaSmrg 1172ab47cfaaSmrg return Success; 1173ab47cfaaSmrg} 1174ab47cfaaSmrg 1175ab47cfaaSmrgstatic void 1176ab47cfaaSmrgSavageQueryBestSize( 1177ab47cfaaSmrg ScrnInfoPtr pScrn, 1178ab47cfaaSmrg Bool motion, 1179ab47cfaaSmrg short vid_w, short vid_h, 1180ab47cfaaSmrg short drw_w, short drw_h, 1181ab47cfaaSmrg unsigned int *p_w, unsigned int *p_h, 1182ab47cfaaSmrg pointer data 1183ab47cfaaSmrg){ 1184ab47cfaaSmrg /* What are the real limits for the Savage? */ 1185ab47cfaaSmrg 1186ab47cfaaSmrg *p_w = drw_w; 1187ab47cfaaSmrg *p_h = drw_h; 1188ab47cfaaSmrg 1189ab47cfaaSmrg if(*p_w > 16384) *p_w = 16384; 1190ab47cfaaSmrg} 1191ab47cfaaSmrg 1192ab47cfaaSmrg/* SavageCopyPlanarDataBCI() causes artifacts on the screen when used on savage4. 1193ab47cfaaSmrg * It's probably something with the BCI. Maybe we need a waitforidle() or 1194ab47cfaaSmrg * something... 1195ab47cfaaSmrg */ 1196ab47cfaaSmrgstatic void 1197ab47cfaaSmrgSavageCopyPlanarDataBCI( 1198ab47cfaaSmrg ScrnInfoPtr pScrn, 1199ab47cfaaSmrg unsigned char *srcY, /* Y */ 1200ab47cfaaSmrg unsigned char *srcV, /* V */ 1201ab47cfaaSmrg unsigned char *srcU, /* U */ 1202ab47cfaaSmrg unsigned char *dst, 12031473d951Smrg unsigned char * planarPtr, 12041473d951Smrg unsigned long planarOffset, 1205ab47cfaaSmrg int srcPitch, int srcPitch2, 1206ab47cfaaSmrg int dstPitch, 12071473d951Smrg int h,int w, 12081473d951Smrg Bool isAGP) 1209ab47cfaaSmrg{ 1210ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 12111473d951Smrg 1212ab47cfaaSmrg /* for pixel transfer */ 12131473d951Smrg unsigned long offsetY = planarOffset; 1214ab47cfaaSmrg unsigned long offsetV = offsetY + srcPitch * h; 1215ab47cfaaSmrg unsigned long offsetU = offsetV + srcPitch2 * (h>>1); 1216ab47cfaaSmrg unsigned long dstOffset = (unsigned long)dst - (unsigned long)psav->FBBase; 1217ab47cfaaSmrg int i; 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{ 1329ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 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){ 1345ab47cfaaSmrg ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; 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) 1508ab47cfaaSmrg && psav->FPExpansion) { 1509ab47cfaaSmrg drw_w = (((float)(drw_w * psav->XExp1)/(float)psav->XExp2)+1); 1510ab47cfaaSmrg drw_h = (float)(drw_h * psav->YExp1)/(float)psav->YExp2+1; 1511ab47cfaaSmrg dstBox->x1 = (float)(dstBox->x1 * psav->XExp1)/(float)psav->XExp2; 1512ab47cfaaSmrg dstBox->y1 = (float)(dstBox->y1 * psav->YExp1)/(float)psav->YExp2; 1513ab47cfaaSmrg 1514ab47cfaaSmrg dstBox->x1 += psav->displayXoffset; 1515ab47cfaaSmrg dstBox->y1 += psav->displayYoffset; 1516ab47cfaaSmrg } 1517ab47cfaaSmrg 1518ab47cfaaSmrg /* 1519ab47cfaaSmrg * Process horizontal scaling 1520ab47cfaaSmrg * upscaling and downscaling smaller than 2:1 controled by MM8198 1521ab47cfaaSmrg * MM8190 controls downscaling mode larger than 2:1 15228697ee19Smrg * Together MM8190 and MM8198 can set arbitrary downscale up to 64:1 1523ab47cfaaSmrg */ 1524ab47cfaaSmrg scalratio = 0; 1525ab47cfaaSmrg ssControl = 0; 1526ab47cfaaSmrg 1527ab47cfaaSmrg if (src_w >= (drw_w * 2)) { 1528ab47cfaaSmrg if (src_w < (drw_w * 4)) { 1529ab47cfaaSmrg ssControl |= HDSCALE_4; 15308697ee19Smrg scalratio = HSCALING(src_w,(drw_w*4)); 15318697ee19Smrg } else if (src_w < (drw_w * 8)) { 1532ab47cfaaSmrg ssControl |= HDSCALE_8; 15338697ee19Smrg scalratio = HSCALING(src_w,(drw_w*8)); 15348697ee19Smrg } else if (src_w < (drw_w * 16)) { 1535ab47cfaaSmrg ssControl |= HDSCALE_16; 15368697ee19Smrg scalratio = HSCALING(src_w,(drw_w*16)); 15378697ee19Smrg } else if (src_w < (drw_w * 32)) { 1538ab47cfaaSmrg ssControl |= HDSCALE_32; 15398697ee19Smrg scalratio = HSCALING(src_w,(drw_w*32)); 15408697ee19Smrg } else if (src_w < (drw_w * 64)) { 15418697ee19Smrg ssControl |= HDSCALE_64; 15428697ee19Smrg scalratio = HSCALING(src_w,(drw_w*64)); 15438697ee19Smrg } else { 15448697ee19Smrg /* Request beyond maximum downscale! */ 1545ab47cfaaSmrg ssControl |= HDSCALE_64; 15468697ee19Smrg scalratio = HSCALING(2,1); 15478697ee19Smrg } 1548ab47cfaaSmrg } else 1549ab47cfaaSmrg scalratio = HSCALING(src_w,drw_w); 1550ab47cfaaSmrg 1551ab47cfaaSmrg ssControl |= src_w; 1552ab47cfaaSmrg /*ssControl |= (1 << 24);*/ 1553ab47cfaaSmrg ssControl |= (GetBlendForFourCC(psav->videoFourCC) << 24); 15548697ee19Smrg#if 0 1555ab47cfaaSmrg /* Wait for VBLANK. */ 1556ab47cfaaSmrg VerticalRetraceWait(); 15578697ee19Smrg#endif 1558ab47cfaaSmrg OUTREG(SSTREAM_CONTROL_REG, ssControl); 1559ab47cfaaSmrg if (scalratio) 1560ab47cfaaSmrg OUTREG(SSTREAM_STRETCH_REG,scalratio); 1561ab47cfaaSmrg 1562ab47cfaaSmrg /* Calculate vertical scale factor. */ 1563ab47cfaaSmrg OUTREG(SSTREAM_VINITIAL_REG, 0 ); 1564ab47cfaaSmrg /*OUTREG(SSTREAM_VSCALE_REG, (src_h << 15) / drw_h );*/ 1565ab47cfaaSmrg OUTREG(SSTREAM_VSCALE_REG, VSCALING(src_h,drw_h)); 1566ab47cfaaSmrg 1567ab47cfaaSmrg /* Set surface location and stride. */ 1568ab47cfaaSmrg OUTREG(SSTREAM_FBADDR0_REG, (offset + (x1>>15)) & (0x1ffffff & ~BASE_PAD) ); 1569ab47cfaaSmrg OUTREG(SSTREAM_FBADDR1_REG, 0); 1570ab47cfaaSmrg OUTREG(SSTREAM_STRIDE_REG, pitch & 0xfff ); 1571ab47cfaaSmrg 1572ab47cfaaSmrg OUTREG(SSTREAM_WINDOW_START_REG, OS_XY(dstBox->x1, dstBox->y1) ); 1573ab47cfaaSmrg OUTREG(SSTREAM_WINDOW_SIZE_REG, OS_WH(dstBox->x2-dstBox->x1, 1574ab47cfaaSmrg dstBox->y2-dstBox->y1)); 1575ab47cfaaSmrg 1576ab47cfaaSmrg /* 1577ab47cfaaSmrg * MM81E8:Secondary Stream Source Line Count 1578ab47cfaaSmrg * bit_0~10: # of lines in the source image (before scaling) 1579ab47cfaaSmrg * bit_15 = 1: Enable vertical interpolation 1580ab47cfaaSmrg * 0: Line duplicaion 1581ab47cfaaSmrg */ 1582ab47cfaaSmrg /* 1583ab47cfaaSmrg * Vertical Interpolation is very bandwidth intensive. Some savages can't 1584ab47cfaaSmrg * seem to handle it. Default is line doubling. --AGD 1585ab47cfaaSmrg */ 1586ab47cfaaSmrg if (pPriv->interpolation) { 1587ab47cfaaSmrg if (src_w * 16 <= 0x3300) { 1588ab47cfaaSmrg OUTREG(SSTREAM_LINES_REG, 0x8000 | src_h ); 1589ab47cfaaSmrg OUTREG(FIFO_CONTROL, (INREG(FIFO_CONTROL) + 1)); 1590ab47cfaaSmrg } else { 1591ab47cfaaSmrg OUTREG(SSTREAM_LINES_REG, src_h ); 1592ab47cfaaSmrg } 1593ab47cfaaSmrg } else { 1594ab47cfaaSmrg OUTREG(SSTREAM_LINES_REG, src_h ); 1595ab47cfaaSmrg } 1596ab47cfaaSmrg 1597ab47cfaaSmrg#if 0 1598ab47cfaaSmrg /* Set color key on primary. */ 1599ab47cfaaSmrg 1600ab47cfaaSmrg SavageSetColorKey( pScrn ); 1601ab47cfaaSmrg#endif 1602ab47cfaaSmrg 1603ab47cfaaSmrg /* Set FIFO L2 on second stream. */ 1604ab47cfaaSmrg 1605ab47cfaaSmrg if( pPriv->lastKnownPitch != pitch ) 1606ab47cfaaSmrg { 1607ab47cfaaSmrg unsigned char cr92; 1608ab47cfaaSmrg 1609ab47cfaaSmrg pPriv->lastKnownPitch = pitch; 1610ab47cfaaSmrg 1611ab47cfaaSmrg pitch = (pitch + 7) / 8; 1612ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x92); 1613ab47cfaaSmrg cr92 = VGAIN8(vgaCRReg); 1614ab47cfaaSmrg VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 1615ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x93); 1616ab47cfaaSmrg if (psav->bTiled && (( drw_h > src_h) || (drw_w > src_w))) 1617ab47cfaaSmrg VGAOUT8(vgaCRReg, pitch | 0xf); 1618ab47cfaaSmrg else 1619ab47cfaaSmrg VGAOUT8(vgaCRReg, pitch); 1620ab47cfaaSmrg } 1621ab47cfaaSmrg} 1622ab47cfaaSmrg 1623ab47cfaaSmrgstatic void 1624ab47cfaaSmrgSavageDisplayVideoNew( 1625ab47cfaaSmrg ScrnInfoPtr pScrn, 1626ab47cfaaSmrg int id, 1627ab47cfaaSmrg int offset, 1628ab47cfaaSmrg short width, short height, 1629ab47cfaaSmrg int pitch, 1630ab47cfaaSmrg int x1, int y1, int x2, int y2, 1631ab47cfaaSmrg BoxPtr dstBox, 1632ab47cfaaSmrg short src_w, short src_h, 1633ab47cfaaSmrg short drw_w, short drw_h 1634ab47cfaaSmrg){ 1635ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1636ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1637ab47cfaaSmrg /*DisplayModePtr mode = pScrn->currentMode;*/ 1638ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 1639ab47cfaaSmrg int vgaCRIndex, vgaCRReg, vgaIOBase; 1640ab47cfaaSmrg 1641ab47cfaaSmrg 1642ab47cfaaSmrg vgaIOBase = hwp->IOBase; 1643ab47cfaaSmrg vgaCRIndex = vgaIOBase + 4; 1644ab47cfaaSmrg vgaCRReg = vgaIOBase + 5; 1645ab47cfaaSmrg#if 0 1646ab47cfaaSmrg if ( psav->videoFourCC != id ) { 1647ab47cfaaSmrg SavageSetBlend(pScrn,id); 1648ab47cfaaSmrg SavageResetVideo(pScrn); 1649ab47cfaaSmrg } 1650ab47cfaaSmrg#endif 1651ab47cfaaSmrg if( psav->videoFourCC != id ) 1652ab47cfaaSmrg SavageStreamsOff(pScrn); 1653ab47cfaaSmrg 16548697ee19Smrg if( !(psav->videoFlags & VF_STREAMS_ON) ) 1655ab47cfaaSmrg { 1656ab47cfaaSmrg SavageSetBlend(pScrn,id); 1657ab47cfaaSmrg SavageStreamsOn(pScrn); 1658ab47cfaaSmrg SavageResetVideo(pScrn); 16598697ee19Smrg pPriv->lastKnownPitch = 0; 1660ab47cfaaSmrg } 1661ab47cfaaSmrg 1662ab47cfaaSmrg /* Calculate horizontal and vertical scale factors. */ 1663ab47cfaaSmrg 1664ab47cfaaSmrg if ( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) && 1665ab47cfaaSmrg (psav->DisplayType == MT_LCD) && 1666ab47cfaaSmrg !psav->CrtOnly && 1667ab47cfaaSmrg !psav->TvOn) 1668ab47cfaaSmrg { 1669ab47cfaaSmrg drw_w = (drw_w * psav->XExp1)/psav->XExp2 + 1; 1670ab47cfaaSmrg drw_h = (drw_h * psav->YExp1)/psav->YExp2 + 1; 1671ab47cfaaSmrg dstBox->x1 = (dstBox->x1 * psav->XExp1)/psav->XExp2; 1672ab47cfaaSmrg dstBox->y1 = (dstBox->y1 * psav->YExp1)/psav->YExp2; 1673ab47cfaaSmrg dstBox->x1 += psav->displayXoffset; 1674ab47cfaaSmrg dstBox->y1 += psav->displayYoffset; 1675ab47cfaaSmrg } 1676ab47cfaaSmrg 1677ab47cfaaSmrg if (psav->IsSecondary) { 1678ab47cfaaSmrg OUTREG(SEC_STREAM2_HSCALING, 1679ab47cfaaSmrg ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1680ab47cfaaSmrg /* BUGBUG need to add 00040000 if src stride > 2048 */ 1681ab47cfaaSmrg OUTREG(SEC_STREAM2_VSCALING, 1682ab47cfaaSmrg ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1683ab47cfaaSmrg } else if (psav->IsPrimary) { 1684ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALING, 1685ab47cfaaSmrg ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1686ab47cfaaSmrg /* BUGBUG need to add 00040000 if src stride > 2048 */ 1687ab47cfaaSmrg OUTREG(SEC_STREAM_VSCALING, 1688ab47cfaaSmrg ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1689ab47cfaaSmrg } else { 1690ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALING, 1691ab47cfaaSmrg ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1692ab47cfaaSmrg /* BUGBUG need to add 00040000 if src stride > 2048 */ 1693ab47cfaaSmrg OUTREG(SEC_STREAM_VSCALING, 1694ab47cfaaSmrg ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1695ab47cfaaSmrg#if 0 1696ab47cfaaSmrg OUTREG(SEC_STREAM2_HSCALING, 1697ab47cfaaSmrg ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1698ab47cfaaSmrg /* BUGBUG need to add 00040000 if src stride > 2048 */ 1699ab47cfaaSmrg OUTREG(SEC_STREAM2_VSCALING, 1700ab47cfaaSmrg ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1701ab47cfaaSmrg#endif 1702ab47cfaaSmrg } 1703ab47cfaaSmrg 1704ab47cfaaSmrg /* 1705ab47cfaaSmrg * Set surface location and stride. We use x1>>15 because all surfaces 1706ab47cfaaSmrg * are 2 bytes/pixel. 1707ab47cfaaSmrg */ 1708ab47cfaaSmrg 1709ab47cfaaSmrg if (psav->IsSecondary) { 1710ab47cfaaSmrg OUTREG(SEC_STREAM2_FBUF_ADDR0, (offset + (x1>>15)) 1711ab47cfaaSmrg & (0x7ffffff & ~BASE_PAD)); 1712ab47cfaaSmrg OUTREG(SEC_STREAM2_STRIDE_LPB, pitch & 0xfff ); 1713ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1714ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 1715ab47cfaaSmrg | (dstBox->x2-dstBox->x1) ); 1716ab47cfaaSmrg } else if (psav->IsPrimary) { 1717ab47cfaaSmrg OUTREG(SEC_STREAM_FBUF_ADDR0, (offset + (x1>>15)) 1718ab47cfaaSmrg & (0x7ffffff & ~BASE_PAD)); 1719ab47cfaaSmrg OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff ); 1720ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1721ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 1722ab47cfaaSmrg | (dstBox->x2-dstBox->x1) ); 1723ab47cfaaSmrg } else { 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) 1729ab47cfaaSmrg | (dstBox->x2-dstBox->x1) ); 1730ab47cfaaSmrg#if 0 1731ab47cfaaSmrg OUTREG(SEC_STREAM2_FBUF_ADDR0, (offset + (x1>>15)) 1732ab47cfaaSmrg & (0x7ffffff & ~BASE_PAD)); 1733ab47cfaaSmrg OUTREG(SEC_STREAM2_STRIDE_LPB, pitch & 0xfff ); 1734ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1735ab47cfaaSmrg OUTREG(SEC_STREAM2_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 1736ab47cfaaSmrg | (dstBox->x2-dstBox->x1) ); 1737ab47cfaaSmrg#endif 1738ab47cfaaSmrg } 1739ab47cfaaSmrg 1740ab47cfaaSmrg#if 0 1741ab47cfaaSmrg /* Set color key on primary. */ 1742ab47cfaaSmrg 1743ab47cfaaSmrg SavageSetColorKey( pScrn ); 1744ab47cfaaSmrg#endif 1745ab47cfaaSmrg 1746ab47cfaaSmrg /* Set FIFO L2 on second stream. */ 1747ab47cfaaSmrg /* Is CR92 shadowed for crtc2? -- AGD */ 1748ab47cfaaSmrg if( pPriv->lastKnownPitch != pitch ) 1749ab47cfaaSmrg { 1750ab47cfaaSmrg unsigned char cr92; 1751ab47cfaaSmrg 1752ab47cfaaSmrg pPriv->lastKnownPitch = pitch; 1753ab47cfaaSmrg pitch = (pitch + 7) / 8 - 4; 1754ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x92); 1755ab47cfaaSmrg cr92 = VGAIN8(vgaCRReg); 1756ab47cfaaSmrg VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 1757ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x93); 1758ab47cfaaSmrg VGAOUT8(vgaCRReg, pitch); 1759ab47cfaaSmrg } 1760ab47cfaaSmrg} 1761ab47cfaaSmrg 1762ab47cfaaSmrgstatic void 1763ab47cfaaSmrgSavageDisplayVideo2000( 1764ab47cfaaSmrg ScrnInfoPtr pScrn, 1765ab47cfaaSmrg int id, 1766ab47cfaaSmrg int offset, 1767ab47cfaaSmrg short width, short height, 1768ab47cfaaSmrg int pitch, 1769ab47cfaaSmrg int x1, int y1, int x2, int y2, 1770ab47cfaaSmrg BoxPtr dstBox, 1771ab47cfaaSmrg short src_w, short src_h, 1772ab47cfaaSmrg short drw_w, short drw_h 1773ab47cfaaSmrg){ 1774ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1775ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1776ab47cfaaSmrg /*DisplayModePtr mode = pScrn->currentMode;*/ 1777ab47cfaaSmrg SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 1778ab47cfaaSmrg int vgaCRIndex, vgaCRReg, vgaIOBase; 1779ab47cfaaSmrg CARD32 addr0, addr1, addr2; 1780ab47cfaaSmrg 1781ab47cfaaSmrg vgaIOBase = hwp->IOBase; 1782ab47cfaaSmrg vgaCRIndex = vgaIOBase + 4; 1783ab47cfaaSmrg vgaCRReg = vgaIOBase + 5; 1784ab47cfaaSmrg 1785ab47cfaaSmrg 1786ab47cfaaSmrg if( psav->videoFourCC != id ) 1787ab47cfaaSmrg SavageStreamsOff(pScrn); 1788ab47cfaaSmrg 17898697ee19Smrg if( !(psav->videoFlags & VF_STREAMS_ON) ) 1790ab47cfaaSmrg { 1791ab47cfaaSmrg SavageSetBlend(pScrn,id); 1792ab47cfaaSmrg SavageStreamsOn(pScrn); 1793ab47cfaaSmrg SavageResetVideo(pScrn); 17948697ee19Smrg pPriv->lastKnownPitch = 0; 1795ab47cfaaSmrg } 1796ab47cfaaSmrg 1797ab47cfaaSmrg if (src_w > drw_w) 1798ab47cfaaSmrg OUTREG(SEC_STREAM_SRC_START_2000, 0); 1799ab47cfaaSmrg else 1800ab47cfaaSmrg OUTREG(SEC_STREAM_SRC_START_2000, SRCSTART(x1, y1)); 1801ab47cfaaSmrg 1802ab47cfaaSmrg /*OUTREG(SEC_STREAM_SRC_SIZE_2000, SRCSIZE(src_w, src_h));*/ 1803ab47cfaaSmrg OUTREG(SEC_STREAM_SRC_SIZE_2000, 1804ab47cfaaSmrg SRCSIZE((dstBox->x2-dstBox->x1), (dstBox->y2-dstBox->y1))); 1805ab47cfaaSmrg /* 1806ab47cfaaSmrg buffersize = (src_w * src_h * 2) / 4096; 1807ab47cfaaSmrg OUTREG(SEC_STREAM_BUFFERSIZE_2000, (buffersize & 0xffffff) << 12); 1808ab47cfaaSmrg */ 1809ab47cfaaSmrg 1810ab47cfaaSmrg /*SavageResetVideo(pScrn);*/ 1811ab47cfaaSmrg 1812ab47cfaaSmrg if( src_w > drw_w ) 1813ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALE_NORMALIZE, HSCALING_NORMALIZE(drw_w,src_w)); 1814ab47cfaaSmrg else 1815ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALE_NORMALIZE, (2048 << 16)); 1816ab47cfaaSmrg 1817ab47cfaaSmrg /* Calculate horizontal and vertical scale factors. */ 1818ab47cfaaSmrg if ((src_w > drw_w) || (src_h > drw_h)) 1819ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALING, (HSCALING_2000(src_w,drw_w)) | 0x01000000); 1820ab47cfaaSmrg else 1821ab47cfaaSmrg OUTREG(SEC_STREAM_HSCALING, HSCALING_2000(src_w,drw_w)); 1822ab47cfaaSmrg 1823ab47cfaaSmrg OUTREG(SEC_STREAM_VSCALING, VSCALING_2000(src_h,drw_h)); 1824ab47cfaaSmrg 1825ab47cfaaSmrg /* 1826ab47cfaaSmrg * Set surface location and stride. We use x1>>15 because all surfaces 1827ab47cfaaSmrg * are 2 bytes/pixel. 1828ab47cfaaSmrg */ 1829ab47cfaaSmrg 1830ab47cfaaSmrg addr0 = offset + (x1>>15); /* Y in YCbCr420 */ 1831ab47cfaaSmrg addr1 = addr0 + (width * height); /* Cb in in YCbCr420 */ 1832ab47cfaaSmrg addr2 = addr1 + ((width * height) / 4); /* Cr in in YCbCr420 */ 1833ab47cfaaSmrg OUTREG(SEC_STREAM_FBUF_ADDR0, (addr0) & (0x3fffff & ~BASE_PAD)); 1834ab47cfaaSmrg#if 0 1835ab47cfaaSmrg OUTREG(SEC_STREAM_FBUF_ADDR1, (addr1) & (0x3fffff & ~BASE_PAD)); 1836ab47cfaaSmrg OUTREG(SEC_STREAM_FBUF_ADDR2, (addr2) & (0x3fffff & ~BASE_PAD)); 1837ab47cfaaSmrg#endif 1838ab47cfaaSmrg 1839ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_START, XY_2000(dstBox->x1,dstBox->y1)); 1840ab47cfaaSmrg OUTREG(SEC_STREAM_WINDOW_SZ, 1841ab47cfaaSmrg WH_2000((dstBox->x2-dstBox->x1),(dstBox->y2-dstBox->y1))); 1842ab47cfaaSmrg 1843ab47cfaaSmrg /*pitch = width * 2;*/ 1844ab47cfaaSmrg OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff); 1845ab47cfaaSmrg#if 0 1846ab47cfaaSmrg /* Y stride + CbCr stride in YCbCr420 */ 1847ab47cfaaSmrg OUTREG(SEC_STREAM_STRIDE, (pitch & 0xfff) + ((pitch & 0xfff) << 15)); 1848ab47cfaaSmrg#endif 1849ab47cfaaSmrg 1850ab47cfaaSmrg#if 0 1851ab47cfaaSmrg /* Set color key on primary. */ 1852ab47cfaaSmrg 1853ab47cfaaSmrg SavageSetColorKey2000( pScrn ); 1854ab47cfaaSmrg#endif 1855ab47cfaaSmrg 1856ab47cfaaSmrg#if 0 1857ab47cfaaSmrg /* Set FIFO L2 on second stream. */ 1858ab47cfaaSmrg if( pPriv->lastKnownPitch != pitch ) 1859ab47cfaaSmrg { 1860ab47cfaaSmrg unsigned char cr92; 1861ab47cfaaSmrg 1862ab47cfaaSmrg pPriv->lastKnownPitch = pitch; 1863ab47cfaaSmrg pitch = (pitch + 7) / 8 - 4; 1864ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x92); 1865ab47cfaaSmrg cr92 = VGAIN8(vgaCRReg); 1866ab47cfaaSmrg VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 1867ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x93); 1868ab47cfaaSmrg VGAOUT8(vgaCRReg, pitch); 1869ab47cfaaSmrg } 1870ab47cfaaSmrg#endif 1871ab47cfaaSmrg} 1872ab47cfaaSmrg 18731473d951Smrgstatic void 18741473d951SmrgSavageFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes) 18751473d951Smrg{ 18761473d951Smrg#if HAVE_XV_DRAWABLE_HELPER 18771473d951Smrg xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes); 18781473d951Smrg#else 18791473d951Smrg xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes); 18801473d951Smrg#endif 18811473d951Smrg} 18821473d951Smrg 1883ab47cfaaSmrgstatic int 1884ab47cfaaSmrgSavagePutImage( 1885ab47cfaaSmrg ScrnInfoPtr pScrn, 1886ab47cfaaSmrg short src_x, short src_y, 1887ab47cfaaSmrg short drw_x, short drw_y, 1888ab47cfaaSmrg short src_w, short src_h, 1889ab47cfaaSmrg short drw_w, short drw_h, 1890ab47cfaaSmrg int id, unsigned char* buf, 1891ab47cfaaSmrg short width, short height, 1892ab47cfaaSmrg Bool sync, 1893ab47cfaaSmrg RegionPtr clipBoxes, pointer data, 1894ab47cfaaSmrg DrawablePtr pDraw 1895ab47cfaaSmrg){ 1896ab47cfaaSmrg SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1897ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 1898ab47cfaaSmrg ScreenPtr pScreen = pScrn->pScreen; 1899ab47cfaaSmrg INT32 x1, x2, y1, y2; 1900ab47cfaaSmrg unsigned char *dst_start; 1901ab47cfaaSmrg int pitch, new_size, offset, offsetV=0, offsetU=0; 1902ab47cfaaSmrg int srcPitch, srcPitch2=0, dstPitch; 19031473d951Smrg int planarFrameSize; 1904ab47cfaaSmrg int top, left, npixels, nlines; 1905ab47cfaaSmrg BoxRec dstBox; 1906ab47cfaaSmrg CARD32 tmp; 1907ab47cfaaSmrg/* xf86ErrorFVerb(XVTRACE,"SavagePutImage\n"); */ 1908ab47cfaaSmrg if(drw_w > 16384) drw_w = 16384; 1909ab47cfaaSmrg 1910ab47cfaaSmrg /* Clip */ 1911ab47cfaaSmrg x1 = src_x; 1912ab47cfaaSmrg x2 = src_x + src_w; 1913ab47cfaaSmrg y1 = src_y; 1914ab47cfaaSmrg y2 = src_y + src_h; 1915ab47cfaaSmrg 1916ab47cfaaSmrg dstBox.x1 = drw_x; 1917ab47cfaaSmrg dstBox.x2 = drw_x + drw_w; 1918ab47cfaaSmrg dstBox.y1 = drw_y; 1919ab47cfaaSmrg dstBox.y2 = drw_y + drw_h; 1920ab47cfaaSmrg 1921ab47cfaaSmrg SavageClipVideo(&dstBox, &x1, &x2, &y1, &y2, 1922ab47cfaaSmrg REGION_EXTENTS(pScreen, clipBoxes), width, height); 1923ab47cfaaSmrg 1924ab47cfaaSmrg drw_w = dstBox.x2 - dstBox.x1; 1925ab47cfaaSmrg drw_h = dstBox.y2 - dstBox.y1; 1926ab47cfaaSmrg src_w = ( x2 - x1 ) >> 16; 1927ab47cfaaSmrg src_h = ( y2 - y1 ) >> 16; 1928ab47cfaaSmrg 1929ab47cfaaSmrg if((x1 >= x2) || (y1 >= y2)) 1930ab47cfaaSmrg return Success; 1931ab47cfaaSmrg 1932ab47cfaaSmrg dstBox.x1 -= pScrn->frameX0; 1933ab47cfaaSmrg dstBox.x2 -= pScrn->frameX0; 1934ab47cfaaSmrg dstBox.y1 -= pScrn->frameY0; 1935ab47cfaaSmrg dstBox.y2 -= pScrn->frameY0; 1936ab47cfaaSmrg 1937ab47cfaaSmrg pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; 1938ab47cfaaSmrg 19391473d951Smrg /* All formats directly displayable by Savage are packed and 2 bytes per pixel */ 1940ab47cfaaSmrg dstPitch = ((width << 1) + 15) & ~15; 1941ab47cfaaSmrg new_size = dstPitch * height; 1942ab47cfaaSmrg 1943ab47cfaaSmrg switch(id) { 1944ab47cfaaSmrg case FOURCC_Y211: /* Y211 */ 1945ab47cfaaSmrg srcPitch = width; 1946ab47cfaaSmrg break; 1947ab47cfaaSmrg case FOURCC_YV12: /* YV12 */ 1948ab47cfaaSmrg srcPitch = (width + 3) & ~3; 1949ab47cfaaSmrg offsetV = srcPitch * height; 1950ab47cfaaSmrg srcPitch2 = ((width >> 1) + 3) & ~3; 1951ab47cfaaSmrg offsetU = (srcPitch2 * (height >> 1)) + offsetV; 1952ab47cfaaSmrg break; 1953ab47cfaaSmrg case FOURCC_I420: 1954ab47cfaaSmrg srcPitch = (width + 3) & ~3; 1955ab47cfaaSmrg offsetU = srcPitch * height; 1956ab47cfaaSmrg srcPitch2 = ((width >> 1) + 3) & ~3; 1957ab47cfaaSmrg offsetV = (srcPitch2 * (height >> 1)) + offsetU; 1958ab47cfaaSmrg break; 1959ab47cfaaSmrg case FOURCC_RV15: /* RGB15 */ 1960ab47cfaaSmrg case FOURCC_RV16: /* RGB16 */ 1961ab47cfaaSmrg case FOURCC_YUY2: /* YUY2 */ 1962ab47cfaaSmrg default: 1963ab47cfaaSmrg srcPitch = (width << 1); 1964ab47cfaaSmrg break; 1965ab47cfaaSmrg } 1966ab47cfaaSmrg 19671473d951Smrg /* Calculate required memory for all planar frames */ 19681473d951Smrg planarFrameSize = 0; 19698697ee19Smrg if (srcPitch2 != 0 && S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv) { 19701473d951Smrg new_size = ((new_size + 0xF) & ~0xF); 19711473d951Smrg planarFrameSize = srcPitch * height + srcPitch2 * height; 19721473d951Smrg } 19731473d951Smrg 19741473d951Smrg /* Check whether AGP buffers can be allocated. If not, fall back to ordinary 19751473d951Smrg upload to framebuffer (slower) */ 19766aec45a7Smrg#ifdef XF86DRI 19771473d951Smrg if (!pPriv->tried_agp && !psav->IsPCI && psav->drmFD > 0 && psav->DRIServerInfo != NULL) { 19781473d951Smrg int ret; 19791473d951Smrg SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 19801473d951Smrg 19811473d951Smrg pPriv->tried_agp = TRUE; 19821473d951Smrg if (pSAVAGEDRIServer->agpXVideo.size >= max(new_size, planarFrameSize)) { 19831473d951Smrg if (pSAVAGEDRIServer->agpXVideo.map == NULL && 19841473d951Smrg drmMap( psav->drmFD, 19851473d951Smrg pSAVAGEDRIServer->agpXVideo.handle, 19861473d951Smrg pSAVAGEDRIServer->agpXVideo.size, 19871473d951Smrg &pSAVAGEDRIServer->agpXVideo.map ) < 0 ) { 19881473d951Smrg 19891473d951Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] XVideo: Could not map agpXVideo \n" ); 19901473d951Smrg pPriv->agpBufferOffset = 0; 19911473d951Smrg pPriv->agpBufferMap = NULL; 19921473d951Smrg } else { 19931473d951Smrg pPriv->agpBufferMap = pSAVAGEDRIServer->agpXVideo.map; 19941473d951Smrg pPriv->agpBufferOffset = pSAVAGEDRIServer->agpXVideo.offset; 19951473d951Smrg pPriv->agpBase = drmAgpBase(psav->drmFD); 19961473d951Smrg#if 0 19971473d951Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 19981473d951Smrg "[agp] agpXVideo mapped at 0x%08lx aperture=0x%08x offset=0x%08lx\n", 19991473d951Smrg (unsigned long)pPriv->agpBufferMap, pPriv->agpBase, pPriv->agpBufferOffset); 20001473d951Smrg#endif 20011473d951Smrg } 20021473d951Smrg } else { 20031473d951Smrg /* This situation is expected if AGPforXv is disabled, otherwise report. */ 20041473d951Smrg if (pSAVAGEDRIServer->agpXVideo.size > 0) { 20051473d951Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 20061473d951Smrg "[agp] XVideo: not enough space in buffer (got %ld bytes, required %ld bytes).\n", 20071473d951Smrg pSAVAGEDRIServer->agpXVideo.size, max(new_size, planarFrameSize)); 20081473d951Smrg } 20091473d951Smrg pPriv->agpBufferMap = NULL; 20101473d951Smrg pPriv->agpBufferOffset = 0; 20111473d951Smrg } 20128697ee19Smrg } 20136aec45a7Smrg#endif /* XF86DRI */ 20148697ee19Smrg 20151473d951Smrg 20161473d951Smrg /* Buffer for final packed frame */ 20171473d951Smrg pPriv->video_offset = SavageAllocateMemory( 20181473d951Smrg pScrn, &pPriv->video_memory, 20191473d951Smrg new_size); 2020ab47cfaaSmrg if (pPriv->video_offset == 0) 2021ab47cfaaSmrg return BadAlloc; 2022ab47cfaaSmrg 20231473d951Smrg /* Packed format cases */ 20241473d951Smrg if (planarFrameSize == 0) { 20251473d951Smrg pPriv->video_planarbuf = 0; 20261473d951Smrg 20271473d951Smrg /* Planar format cases */ 20281473d951Smrg } else { 20291473d951Smrg /* Hardware-assisted planar conversion only works on 16-byte aligned addresses */ 20301473d951Smrg pPriv->video_planarbuf = SavageAllocateMemory( 20311473d951Smrg pScrn, &pPriv->video_planarmem, 20321473d951Smrg ((planarFrameSize + 0xF) & ~0xF)); 20331473d951Smrg if (pPriv->video_planarbuf != 0) { 20341473d951Smrg /* TODO: stop any pending conversions when buffers change... */ 20351473d951Smrg pPriv->video_planarbuf = ((pPriv->video_planarbuf + 0xF) & ~0xF); 20361473d951Smrg } else { 20371473d951Smrg /* Fallback using software conversion */ 20381473d951Smrg } 20391473d951Smrg } 20401473d951Smrg 2041ab47cfaaSmrg /* copy data */ 2042ab47cfaaSmrg top = y1 >> 16; 2043ab47cfaaSmrg left = (x1 >> 16) & ~1; 2044ab47cfaaSmrg npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; 2045ab47cfaaSmrg left <<= 1; 2046ab47cfaaSmrg 2047ab47cfaaSmrg offset = (pPriv->video_offset) + (top * dstPitch); 2048ab47cfaaSmrg dst_start = (psav->FBBase + ((offset + left) & ~BASE_PAD)); 2049ab47cfaaSmrg 2050ab47cfaaSmrg switch(id) { 2051ab47cfaaSmrg case FOURCC_YV12: /* YV12 */ 2052ab47cfaaSmrg case FOURCC_I420: 2053ab47cfaaSmrg top &= ~1; 2054ab47cfaaSmrg tmp = ((top >> 1) * srcPitch2) + (left >> 2); 2055ab47cfaaSmrg offsetU += tmp; 2056ab47cfaaSmrg offsetV += tmp; 2057ab47cfaaSmrg nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 20581473d951Smrg if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv && (npixels & 0xF) == 0 && pPriv->video_planarbuf != 0) { 20596aec45a7Smrg#ifdef XF86DRI 20601473d951Smrg if (pPriv->agpBufferMap != NULL) { 20611473d951Smrg /* Using copy to AGP memory */ 20621473d951Smrg SavageCopyPlanarDataBCI( 20631473d951Smrg pScrn, 20641473d951Smrg buf + (top * srcPitch) + (left >> 1), 20651473d951Smrg buf + offsetV, 20661473d951Smrg buf + offsetU, 20671473d951Smrg dst_start, 20681473d951Smrg pPriv->agpBufferMap, 20691473d951Smrg pPriv->agpBase + pPriv->agpBufferOffset, 20701473d951Smrg srcPitch, srcPitch2, dstPitch, nlines, npixels, TRUE); 20716aec45a7Smrg } else 20726aec45a7Smrg#endif /* XF86DRI */ 20736aec45a7Smrg { 20741473d951Smrg /* Using ordinary copy to framebuffer */ 20751473d951Smrg SavageCopyPlanarDataBCI( 20761473d951Smrg pScrn, 20771473d951Smrg buf + (top * srcPitch) + (left >> 1), 20781473d951Smrg buf + offsetV, 20791473d951Smrg buf + offsetU, 20801473d951Smrg dst_start, 20811473d951Smrg (unsigned char *)psav->FBBase + pPriv->video_planarbuf, 20821473d951Smrg pPriv->video_planarbuf, 20831473d951Smrg srcPitch, srcPitch2, dstPitch, nlines, npixels, FALSE); 20841473d951Smrg } 2085ab47cfaaSmrg } else { 2086ab47cfaaSmrg SavageCopyPlanarData( 2087ab47cfaaSmrg buf + (top * srcPitch) + (left >> 1), 2088ab47cfaaSmrg buf + offsetV, 2089ab47cfaaSmrg buf + offsetU, 2090ab47cfaaSmrg dst_start, srcPitch, srcPitch2, dstPitch, nlines, npixels); 2091ab47cfaaSmrg } 2092ab47cfaaSmrg break; 2093ab47cfaaSmrg case FOURCC_Y211: /* Y211 */ 2094ab47cfaaSmrg case FOURCC_RV15: /* RGB15 */ 2095ab47cfaaSmrg case FOURCC_RV16: /* RGB16 */ 2096ab47cfaaSmrg case FOURCC_YUY2: /* YUY2 */ 2097ab47cfaaSmrg default: 2098ab47cfaaSmrg buf += (top * srcPitch) + left; 2099ab47cfaaSmrg nlines = ((y2 + 0xffff) >> 16) - top; 2100ab47cfaaSmrg SavageCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 2101ab47cfaaSmrg break; 2102ab47cfaaSmrg } 2103ab47cfaaSmrg 2104ab47cfaaSmrg /* We need to enable the video before we draw the chroma color. 2105ab47cfaaSmrg Otherwise, we get blue flashes. */ 2106ab47cfaaSmrg 2107ab47cfaaSmrg SavageDisplayVideo(pScrn, id, offset, width, height, dstPitch, 2108ab47cfaaSmrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 2109ab47cfaaSmrg 2110ab47cfaaSmrg /* update cliplist */ 2111ab47cfaaSmrg if(!REGION_EQUAL(pScreen, &pPriv->clip, clipBoxes)) { 2112ab47cfaaSmrg REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 2113ab47cfaaSmrg /* draw these */ 21141473d951Smrg SavageFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes); 2115ab47cfaaSmrg 2116ab47cfaaSmrg } 2117ab47cfaaSmrg 2118ab47cfaaSmrg pPriv->videoStatus = CLIENT_VIDEO_ON; 2119ab47cfaaSmrg 2120ab47cfaaSmrg return Success; 2121ab47cfaaSmrg} 2122ab47cfaaSmrg 2123ab47cfaaSmrgstatic int 2124ab47cfaaSmrgSavageQueryImageAttributes( 2125ab47cfaaSmrg ScrnInfoPtr pScrn, 2126ab47cfaaSmrg int id, 2127ab47cfaaSmrg unsigned short *w, unsigned short *h, 2128ab47cfaaSmrg int *pitches, int *offsets 2129ab47cfaaSmrg){ 2130ab47cfaaSmrg int size, tmp; 2131ab47cfaaSmrg 2132ab47cfaaSmrg if(*w > 1024) *w = 1024; 2133ab47cfaaSmrg if(*h > 1024) *h = 1024; 2134ab47cfaaSmrg 2135ab47cfaaSmrg *w = (*w + 1) & ~1; 2136ab47cfaaSmrg if(offsets) offsets[0] = 0; 2137ab47cfaaSmrg 2138ab47cfaaSmrg switch(id) { 2139ab47cfaaSmrg case FOURCC_IA44: 2140ab47cfaaSmrg if (pitches) pitches[0]=*w; 2141ab47cfaaSmrg size=(*w)*(*h); 2142ab47cfaaSmrg break; 2143ab47cfaaSmrg case FOURCC_Y211: 2144ab47cfaaSmrg size = *w << 2; 2145ab47cfaaSmrg if(pitches) pitches[0] = size; 2146ab47cfaaSmrg size *= *h; 2147ab47cfaaSmrg break; 2148ab47cfaaSmrg case FOURCC_YV12: 2149ab47cfaaSmrg case FOURCC_I420: 2150ab47cfaaSmrg *h = (*h + 1) & ~1; 2151ab47cfaaSmrg size = (*w + 3) & ~3; 2152ab47cfaaSmrg if(pitches) pitches[0] = size; 2153ab47cfaaSmrg size *= *h; 2154ab47cfaaSmrg if(offsets) offsets[1] = size; 2155ab47cfaaSmrg tmp = ((*w >> 1) + 3) & ~3; 2156ab47cfaaSmrg if(pitches) pitches[1] = pitches[2] = tmp; 2157ab47cfaaSmrg tmp *= (*h >> 1); 2158ab47cfaaSmrg size += tmp; 2159ab47cfaaSmrg if(offsets) offsets[2] = size; 2160ab47cfaaSmrg size += tmp; 2161ab47cfaaSmrg break; 2162ab47cfaaSmrg case FOURCC_RV15: /* RGB15 */ 2163ab47cfaaSmrg case FOURCC_RV16: /* RGB16 */ 2164ab47cfaaSmrg case FOURCC_YUY2: 2165ab47cfaaSmrg default: 2166ab47cfaaSmrg size = *w << 1; 2167ab47cfaaSmrg if(pitches) pitches[0] = size; 2168ab47cfaaSmrg size *= *h; 2169ab47cfaaSmrg break; 2170ab47cfaaSmrg } 2171ab47cfaaSmrg 2172ab47cfaaSmrg return size; 2173ab47cfaaSmrg} 2174ab47cfaaSmrg 2175ab47cfaaSmrg/****************** Offscreen stuff ***************/ 2176ab47cfaaSmrg 2177ab47cfaaSmrgtypedef struct { 2178ab47cfaaSmrg void *surface_memory; 2179ab47cfaaSmrg Bool isOn; 2180ab47cfaaSmrg} OffscreenPrivRec, * OffscreenPrivPtr; 2181ab47cfaaSmrg 2182ab47cfaaSmrgstatic int 2183ab47cfaaSmrgSavageAllocateSurface( 2184ab47cfaaSmrg ScrnInfoPtr pScrn, 2185ab47cfaaSmrg int id, 2186ab47cfaaSmrg unsigned short w, 2187ab47cfaaSmrg unsigned short h, 2188ab47cfaaSmrg XF86SurfacePtr surface 2189ab47cfaaSmrg){ 2190ab47cfaaSmrg int offset, size; 2191ab47cfaaSmrg int pitch, fbpitch, numlines; 2192ab47cfaaSmrg void *surface_memory = NULL; 2193ab47cfaaSmrg OffscreenPrivPtr pPriv; 2194ab47cfaaSmrg 2195ab47cfaaSmrg if((w > 1024) || (h > 1024)) 2196ab47cfaaSmrg return BadAlloc; 2197ab47cfaaSmrg 2198ab47cfaaSmrg w = (w + 1) & ~1; 2199ab47cfaaSmrg pitch = ((w << 1) + 15) & ~15; 2200ab47cfaaSmrg fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; 2201ab47cfaaSmrg numlines = ((pitch * h) + fbpitch - 1) / fbpitch; 2202ab47cfaaSmrg size = pitch * h; 2203ab47cfaaSmrg 2204ab47cfaaSmrg offset = SavageAllocateMemory(pScrn, &surface_memory, size); 2205ab47cfaaSmrg if (offset == 0) 2206ab47cfaaSmrg return BadAlloc; 2207ab47cfaaSmrg 2208ab47cfaaSmrg surface->width = w; 2209ab47cfaaSmrg surface->height = h; 2210ab47cfaaSmrg 2211ab47cfaaSmrg if(!(surface->pitches = xalloc(sizeof(int)))) { 2212ab47cfaaSmrg SavageFreeMemory(pScrn, surface_memory); 2213ab47cfaaSmrg return BadAlloc; 2214ab47cfaaSmrg } 2215ab47cfaaSmrg if(!(surface->offsets = xalloc(sizeof(int)))) { 2216ab47cfaaSmrg xfree(surface->pitches); 2217ab47cfaaSmrg SavageFreeMemory(pScrn, surface_memory); 2218ab47cfaaSmrg return BadAlloc; 2219ab47cfaaSmrg } 2220ab47cfaaSmrg if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { 2221ab47cfaaSmrg xfree(surface->pitches); 2222ab47cfaaSmrg xfree(surface->offsets); 2223ab47cfaaSmrg SavageFreeMemory(pScrn, surface_memory); 2224ab47cfaaSmrg return BadAlloc; 2225ab47cfaaSmrg } 2226ab47cfaaSmrg 2227ab47cfaaSmrg pPriv->surface_memory = surface_memory; 2228ab47cfaaSmrg pPriv->isOn = FALSE; 2229ab47cfaaSmrg 2230ab47cfaaSmrg surface->pScrn = pScrn; 2231ab47cfaaSmrg surface->id = id; 2232ab47cfaaSmrg surface->pitches[0] = pitch; 2233ab47cfaaSmrg surface->offsets[0] = offset; /*area->box.y1 * fbpitch;*/ 2234ab47cfaaSmrg surface->devPrivate.ptr = (pointer)pPriv; 2235ab47cfaaSmrg 2236ab47cfaaSmrg return Success; 2237ab47cfaaSmrg} 2238ab47cfaaSmrg 2239ab47cfaaSmrgstatic int 2240ab47cfaaSmrgSavageStopSurface( 2241ab47cfaaSmrg XF86SurfacePtr surface 2242ab47cfaaSmrg){ 2243ab47cfaaSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 2244ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageStopSurface\n"); 2245ab47cfaaSmrg 2246ab47cfaaSmrg if(pPriv->isOn) { 2247ab47cfaaSmrg /*SavagePtr psav = SAVPTR(surface->pScrn);*/ 2248ab47cfaaSmrg /*SavageClipVWindow(surface->pScrn);*/ 2249ab47cfaaSmrg SavageStreamsOff( surface->pScrn ); 2250ab47cfaaSmrg pPriv->isOn = FALSE; 2251ab47cfaaSmrg } 2252ab47cfaaSmrg 2253ab47cfaaSmrg return Success; 2254ab47cfaaSmrg} 2255ab47cfaaSmrg 2256ab47cfaaSmrg 2257ab47cfaaSmrgstatic int 2258ab47cfaaSmrgSavageFreeSurface( 2259ab47cfaaSmrg XF86SurfacePtr surface 2260ab47cfaaSmrg){ 2261ab47cfaaSmrg ScrnInfoPtr pScrn = surface->pScrn; 2262ab47cfaaSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 2263ab47cfaaSmrg 2264ab47cfaaSmrg if(pPriv->isOn) 2265ab47cfaaSmrg SavageStopSurface(surface); 2266ab47cfaaSmrg SavageFreeMemory(pScrn, pPriv->surface_memory); 2267ab47cfaaSmrg xfree(surface->pitches); 2268ab47cfaaSmrg xfree(surface->offsets); 2269ab47cfaaSmrg xfree(surface->devPrivate.ptr); 2270ab47cfaaSmrg 2271ab47cfaaSmrg return Success; 2272ab47cfaaSmrg} 2273ab47cfaaSmrg 2274ab47cfaaSmrgstatic int 2275ab47cfaaSmrgSavageGetSurfaceAttribute( 2276ab47cfaaSmrg ScrnInfoPtr pScrn, 2277ab47cfaaSmrg Atom attribute, 2278ab47cfaaSmrg INT32 *value 2279ab47cfaaSmrg){ 2280ab47cfaaSmrg return SavageGetPortAttribute(pScrn, attribute, value, 2281ab47cfaaSmrg (pointer)(GET_PORT_PRIVATE(pScrn))); 2282ab47cfaaSmrg} 2283ab47cfaaSmrg 2284ab47cfaaSmrgstatic int 2285ab47cfaaSmrgSavageSetSurfaceAttribute( 2286ab47cfaaSmrg ScrnInfoPtr pScrn, 2287ab47cfaaSmrg Atom attribute, 2288ab47cfaaSmrg INT32 value 2289ab47cfaaSmrg){ 2290ab47cfaaSmrg return SavageSetPortAttribute(pScrn, attribute, value, 2291ab47cfaaSmrg (pointer)(GET_PORT_PRIVATE(pScrn))); 2292ab47cfaaSmrg} 2293ab47cfaaSmrg 2294ab47cfaaSmrg 2295ab47cfaaSmrgstatic int 2296ab47cfaaSmrgSavageDisplaySurface( 2297ab47cfaaSmrg XF86SurfacePtr surface, 2298ab47cfaaSmrg short src_x, short src_y, 2299ab47cfaaSmrg short drw_x, short drw_y, 2300ab47cfaaSmrg short src_w, short src_h, 2301ab47cfaaSmrg short drw_w, short drw_h, 2302ab47cfaaSmrg RegionPtr clipBoxes 2303ab47cfaaSmrg){ 2304ab47cfaaSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 2305ab47cfaaSmrg ScrnInfoPtr pScrn = surface->pScrn; 2306ab47cfaaSmrg ScreenPtr pScreen = pScrn->pScreen; 2307ab47cfaaSmrg SavagePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn); 2308ab47cfaaSmrg INT32 x1, y1, x2, y2; 2309ab47cfaaSmrg BoxRec dstBox; 2310ab47cfaaSmrg xf86ErrorFVerb(XVTRACE,"SavageDisplaySurface\n"); 2311ab47cfaaSmrg 2312ab47cfaaSmrg x1 = src_x; 2313ab47cfaaSmrg x2 = src_x + src_w; 2314ab47cfaaSmrg y1 = src_y; 2315ab47cfaaSmrg y2 = src_y + src_h; 2316ab47cfaaSmrg 2317ab47cfaaSmrg dstBox.x1 = drw_x; 2318ab47cfaaSmrg dstBox.x2 = drw_x + drw_w; 2319ab47cfaaSmrg dstBox.y1 = drw_y; 2320ab47cfaaSmrg dstBox.y2 = drw_y + drw_h; 2321ab47cfaaSmrg 2322ab47cfaaSmrg SavageClipVideo(&dstBox, &x1, &x2, &y1, &y2, 2323ab47cfaaSmrg REGION_EXTENTS(pScreen, clipBoxes), 2324ab47cfaaSmrg surface->width, surface->height); 2325ab47cfaaSmrg 2326ab47cfaaSmrg if((x1 >= x2) || (y1 >= y2)) 2327ab47cfaaSmrg return Success; 2328ab47cfaaSmrg 2329ab47cfaaSmrg dstBox.x1 -= pScrn->frameX0; 2330ab47cfaaSmrg dstBox.x2 -= pScrn->frameX0; 2331ab47cfaaSmrg dstBox.y1 -= pScrn->frameY0; 2332ab47cfaaSmrg dstBox.y2 -= pScrn->frameY0; 2333ab47cfaaSmrg 2334ab47cfaaSmrg SavageDisplayVideo(pScrn, surface->id, surface->offsets[0], 2335ab47cfaaSmrg surface->width, surface->height, surface->pitches[0], 2336ab47cfaaSmrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 2337ab47cfaaSmrg 2338ab47cfaaSmrg xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); 2339ab47cfaaSmrg 2340ab47cfaaSmrg pPriv->isOn = TRUE; 2341ab47cfaaSmrg#if 0 2342ab47cfaaSmrg if(portPriv->videoStatus & CLIENT_VIDEO_ON) { 2343ab47cfaaSmrg REGION_EMPTY(pScreen, &portPriv->clip); 2344ab47cfaaSmrg UpdateCurrentTime(); 2345ab47cfaaSmrg portPriv->videoStatus = FREE_TIMER; 2346ab47cfaaSmrg portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 2347ab47cfaaSmrg } 2348ab47cfaaSmrg#endif 2349ab47cfaaSmrg 2350ab47cfaaSmrg return Success; 2351ab47cfaaSmrg} 2352ab47cfaaSmrg 2353ab47cfaaSmrg 2354ab47cfaaSmrgstatic void 2355ab47cfaaSmrgSavageInitOffscreenImages(ScreenPtr pScreen) 2356ab47cfaaSmrg{ 2357ab47cfaaSmrg XF86OffscreenImagePtr offscreenImages; 2358ab47cfaaSmrg SavagePtr psav = SAVPTR(xf86Screens[pScreen->myNum]); 2359ab47cfaaSmrg 2360ab47cfaaSmrg /* need to free this someplace */ 2361ab47cfaaSmrg if (!psav->offscreenImages) { 2362ab47cfaaSmrg if(!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) 2363ab47cfaaSmrg return; 2364ab47cfaaSmrg psav->offscreenImages = offscreenImages; 2365ab47cfaaSmrg } else { 2366ab47cfaaSmrg offscreenImages = psav->offscreenImages; 2367ab47cfaaSmrg } 2368ab47cfaaSmrg 2369ab47cfaaSmrg offscreenImages[0].image = &Images[0]; 2370ab47cfaaSmrg offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | 2371ab47cfaaSmrg VIDEO_CLIP_TO_VIEWPORT; 2372ab47cfaaSmrg offscreenImages[0].alloc_surface = SavageAllocateSurface; 2373ab47cfaaSmrg offscreenImages[0].free_surface = SavageFreeSurface; 2374ab47cfaaSmrg offscreenImages[0].display = SavageDisplaySurface; 2375ab47cfaaSmrg offscreenImages[0].stop = SavageStopSurface; 2376ab47cfaaSmrg offscreenImages[0].setAttribute = SavageSetSurfaceAttribute; 2377ab47cfaaSmrg offscreenImages[0].getAttribute = SavageGetSurfaceAttribute; 2378ab47cfaaSmrg offscreenImages[0].max_width = 1024; 2379ab47cfaaSmrg offscreenImages[0].max_height = 1024; 2380ab47cfaaSmrg offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 2381ab47cfaaSmrg offscreenImages[0].attributes = Attributes; 2382ab47cfaaSmrg 2383ab47cfaaSmrg xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 2384ab47cfaaSmrg} 2385ab47cfaaSmrg 2386