summaryrefslogtreecommitdiff
path: root/src/radeon_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/radeon_video.c')
-rw-r--r--src/radeon_video.c1551
1 files changed, 0 insertions, 1551 deletions
diff --git a/src/radeon_video.c b/src/radeon_video.c
deleted file mode 100644
index 3f47e499..00000000
--- a/src/radeon_video.c
+++ /dev/null
@@ -1,1551 +0,0 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c,v 1.28 2003/07/02 17:31:30 martin Exp $ */
-
-#include "radeon.h"
-#include "radeon_macros.h"
-#include "radeon_probe.h"
-#include "radeon_reg.h"
-#include "radeon_mergedfb.h"
-
-#include "xf86.h"
-#include "dixstruct.h"
-
-#include "Xv.h"
-#include "fourcc.h"
-
-#define OFF_DELAY 250 /* milliseconds */
-#define FREE_DELAY 15000
-
-#define OFF_TIMER 0x01
-#define FREE_TIMER 0x02
-#define CLIENT_VIDEO_ON 0x04
-
-#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
-
-extern int gRADEONEntityIndex;
-
-static void RADEONInitOffscreenImages(ScreenPtr);
-
-static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr);
-static int RADEONSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
-static int RADEONGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
-static void RADEONStopVideo(ScrnInfoPtr, pointer, Bool);
-static void RADEONQueryBestSize(ScrnInfoPtr, Bool, short, short, short, short,
- unsigned int *, unsigned int *, pointer);
-static int RADEONPutImage(ScrnInfoPtr, short, short, short, short, short,
- short, short, short, int, unsigned char*, short,
- short, Bool, RegionPtr, pointer);
-static int RADEONQueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
- unsigned short *, int *, int *);
-
-static void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now);
-
-
-#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
-
-static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;
-static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
-static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
-static Atom xvSwitchCRT;
-
-typedef struct {
- CARD32 transform_index;
- int brightness;
- int saturation;
- int hue;
- int contrast;
- int red_intensity;
- int green_intensity;
- int blue_intensity;
- int ecp_div;
-
- Bool doubleBuffer;
- unsigned char currentBuffer;
- RegionRec clip;
- CARD32 colorKey;
- CARD32 videoStatus;
- Time offTime;
- Time freeTime;
- Bool autopaint_colorkey;
- Bool crt2; /* 0=CRT1, 1=CRT2 */
-} RADEONPortPrivRec, *RADEONPortPrivPtr;
-
-
-#define GET_PORT_PRIVATE(pScrn) \
- (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
-
-
-void RADEONInitVideo(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
- XF86VideoAdaptorPtr newAdaptor = NULL;
- int num_adaptors;
-
- newAdaptor = RADEONSetupImageVideo(pScreen);
- RADEONInitOffscreenImages(pScreen);
- num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
-
- if(newAdaptor) {
- if(!num_adaptors) {
- num_adaptors = 1;
- adaptors = &newAdaptor;
- } else {
- newAdaptors = /* need to free this someplace */
- xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
- if(newAdaptors) {
- memcpy(newAdaptors, adaptors, num_adaptors *
- sizeof(XF86VideoAdaptorPtr));
- newAdaptors[num_adaptors] = newAdaptor;
- adaptors = newAdaptors;
- num_adaptors++;
- }
- }
- }
-
- if(num_adaptors)
- xf86XVScreenInit(pScreen, adaptors, num_adaptors);
-
- if(newAdaptors)
- xfree(newAdaptors);
-}
-
-/* client libraries expect an encoding */
-static XF86VideoEncodingRec DummyEncoding =
-{
- 0,
- "XV_IMAGE",
- 2048, 2048,
- {1, 1}
-};
-
-#define NUM_FORMATS 12
-
-static XF86VideoFormatRec Formats[NUM_FORMATS] =
-{
- {8, TrueColor}, {8, DirectColor}, {8, PseudoColor},
- {8, GrayScale}, {8, StaticGray}, {8, StaticColor},
- {15, TrueColor}, {16, TrueColor}, {24, TrueColor},
- {15, DirectColor}, {16, DirectColor}, {24, DirectColor}
-};
-
-
-#define NUM_ATTRIBUTES 9+4
-
-static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
-{
- {XvSettable , 0, 1, "XV_SET_DEFAULTS"},
- {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
- {XvSettable | XvGettable, 0, ~0, "XV_COLORKEY"},
- {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
- {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
- {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
- {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
- {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
- {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
- {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
- {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
- {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
- {XvSettable | XvGettable, 0, 1, "XV_SWITCHCRT"},
-};
-
-#define NUM_IMAGES 4
-
-static XF86ImageRec Images[NUM_IMAGES] =
-{
- XVIMAGE_YUY2,
- XVIMAGE_UYVY,
- XVIMAGE_YV12,
- XVIMAGE_I420
-};
-
-/* Reference color space transform data */
-typedef struct tagREF_TRANSFORM
-{
- float RefLuma;
- float RefRCb;
- float RefRCr;
- float RefGCb;
- float RefGCr;
- float RefBCb;
- float RefBCr;
-} REF_TRANSFORM;
-
-/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
-REF_TRANSFORM trans[2] =
-{
- {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
- {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */
-};
-
-
-/* Gamma curve definition */
-typedef struct
-{
- unsigned int gammaReg;
- unsigned int gammaSlope;
- unsigned int gammaOffset;
-} GAMMA_SETTINGS;
-
-/* Recommended gamma curve parameters */
-GAMMA_SETTINGS def_gamma[18] =
-{
- {RADEON_OV0_GAMMA_000_00F, 0x100, 0x0000},
- {RADEON_OV0_GAMMA_010_01F, 0x100, 0x0020},
- {RADEON_OV0_GAMMA_020_03F, 0x100, 0x0040},
- {RADEON_OV0_GAMMA_040_07F, 0x100, 0x0080},
- {RADEON_OV0_GAMMA_080_0BF, 0x100, 0x0100},
- {RADEON_OV0_GAMMA_0C0_0FF, 0x100, 0x0100},
- {RADEON_OV0_GAMMA_100_13F, 0x100, 0x0200},
- {RADEON_OV0_GAMMA_140_17F, 0x100, 0x0200},
- {RADEON_OV0_GAMMA_180_1BF, 0x100, 0x0300},
- {RADEON_OV0_GAMMA_1C0_1FF, 0x100, 0x0300},
- {RADEON_OV0_GAMMA_200_23F, 0x100, 0x0400},
- {RADEON_OV0_GAMMA_240_27F, 0x100, 0x0400},
- {RADEON_OV0_GAMMA_280_2BF, 0x100, 0x0500},
- {RADEON_OV0_GAMMA_2C0_2FF, 0x100, 0x0500},
- {RADEON_OV0_GAMMA_300_33F, 0x100, 0x0600},
- {RADEON_OV0_GAMMA_340_37F, 0x100, 0x0600},
- {RADEON_OV0_GAMMA_380_3BF, 0x100, 0x0700},
- {RADEON_OV0_GAMMA_3C0_3FF, 0x100, 0x0700}
-};
-
-/****************************************************************************
- * SetTransform *
- * Function: Calculates and sets color space transform from supplied *
- * reference transform, gamma, brightness, contrast, hue and *
- * saturation. *
- * Inputs: bright - brightness *
- * cont - contrast *
- * sat - saturation *
- * hue - hue *
- * red_intensity - intensity of red component *
- * green_intensity - intensity of green component *
- * blue_intensity - intensity of blue component *
- * ref - index to the table of refernce transforms *
- * Outputs: NONE *
- ****************************************************************************/
-
-static void RADEONSetTransform (ScrnInfoPtr pScrn,
- float bright,
- float cont,
- float sat,
- float hue,
- float red_intensity,
- float green_intensity,
- float blue_intensity,
- CARD32 ref)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- float OvHueSin, OvHueCos;
- float CAdjLuma, CAdjOff;
- float CAdjRCb, CAdjRCr;
- float CAdjGCb, CAdjGCr;
- float CAdjBCb, CAdjBCr;
- float RedAdj,GreenAdj,BlueAdj;
- float OvLuma, OvROff, OvGOff, OvBOff;
- float OvRCb, OvRCr;
- float OvGCb, OvGCr;
- float OvBCb, OvBCr;
- float Loff = 64.0;
- float Coff = 512.0f;
-
- CARD32 dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff;
- CARD32 dwOvRCb, dwOvRCr;
- CARD32 dwOvGCb, dwOvGCr;
- CARD32 dwOvBCb, dwOvBCr;
-
- if (ref >= 2)
- return;
-
- OvHueSin = sin(hue);
- OvHueCos = cos(hue);
-
- CAdjLuma = cont * trans[ref].RefLuma;
- CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0;
- RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0;
- GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0;
- BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0;
-
- CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr;
- CAdjRCr = sat * OvHueCos * trans[ref].RefRCr;
- CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr);
- CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr);
- CAdjBCb = sat * OvHueCos * trans[ref].RefBCb;
- CAdjBCr = sat * OvHueSin * trans[ref].RefBCb;
-
-#if 0 /* default constants */
- CAdjLuma = 1.16455078125;
-
- CAdjRCb = 0.0;
- CAdjRCr = 1.59619140625;
- CAdjGCb = -0.39111328125;
- CAdjGCr = -0.8125;
- CAdjBCb = 2.01708984375;
- CAdjBCr = 0;
-#endif
- OvLuma = CAdjLuma;
- OvRCb = CAdjRCb;
- OvRCr = CAdjRCr;
- OvGCb = CAdjGCb;
- OvGCr = CAdjGCr;
- OvBCb = CAdjBCb;
- OvBCr = CAdjBCr;
- OvROff = RedAdj + CAdjOff -
- OvLuma * Loff - (OvRCb + OvRCr) * Coff;
- OvGOff = GreenAdj + CAdjOff -
- OvLuma * Loff - (OvGCb + OvGCr) * Coff;
- OvBOff = BlueAdj + CAdjOff -
- OvLuma * Loff - (OvBCb + OvBCr) * Coff;
-#if 0 /* default constants */
- OvROff = -888.5;
- OvGOff = 545;
- OvBOff = -1104;
-#endif
-
- dwOvROff = ((INT32)(OvROff * 2.0)) & 0x1fff;
- dwOvGOff = ((INT32)(OvGOff * 2.0)) & 0x1fff;
- dwOvBOff = ((INT32)(OvBOff * 2.0)) & 0x1fff;
- /*
- * Whatever docs say about R200 having 3.8 format instead of 3.11
- * as in Radeon is a lie
- * Or more precisely the location of bit fields is a lie
- */
- if(1 || info->ChipFamily < CHIP_FAMILY_R200)
- {
- dwOvLuma =(((INT32)(OvLuma * 2048.0))&0x7fff)<<17;
- dwOvRCb = (((INT32)(OvRCb * 2048.0))&0x7fff)<<1;
- dwOvRCr = (((INT32)(OvRCr * 2048.0))&0x7fff)<<17;
- dwOvGCb = (((INT32)(OvGCb * 2048.0))&0x7fff)<<1;
- dwOvGCr = (((INT32)(OvGCr * 2048.0))&0x7fff)<<17;
- dwOvBCb = (((INT32)(OvBCb * 2048.0))&0x7fff)<<1;
- dwOvBCr = (((INT32)(OvBCr * 2048.0))&0x7fff)<<17;
- }
- else
- {
- dwOvLuma = (((INT32)(OvLuma * 256.0))&0x7ff)<<20;
- dwOvRCb = (((INT32)(OvRCb * 256.0))&0x7ff)<<4;
- dwOvRCr = (((INT32)(OvRCr * 256.0))&0x7ff)<<20;
- dwOvGCb = (((INT32)(OvGCb * 256.0))&0x7ff)<<4;
- dwOvGCr = (((INT32)(OvGCr * 256.0))&0x7ff)<<20;
- dwOvBCb = (((INT32)(OvBCb * 256.0))&0x7ff)<<4;
- dwOvBCr = (((INT32)(OvBCr * 256.0))&0x7ff)<<20;
- }
- OUTREG(RADEON_OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma);
- OUTREG(RADEON_OV0_LIN_TRANS_B, dwOvROff | dwOvRCr);
- OUTREG(RADEON_OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma);
- OUTREG(RADEON_OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr);
- OUTREG(RADEON_OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma);
- OUTREG(RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr);
-}
-
-static void RADEONSetColorKey(ScrnInfoPtr pScrn, CARD32 colorKey)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 min, max;
- CARD8 r, g, b;
-
- if (info->CurrentLayout.depth > 8)
- {
- CARD32 rbits, gbits, bbits;
-
- rbits = (colorKey & pScrn->mask.red) >> pScrn->offset.red;
- gbits = (colorKey & pScrn->mask.green) >> pScrn->offset.green;
- bbits = (colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
-
- r = rbits << (8 - pScrn->weight.red);
- g = gbits << (8 - pScrn->weight.green);
- b = bbits << (8 - pScrn->weight.blue);
- }
- else
- {
- CARD32 bits;
-
- bits = colorKey & ((1 << info->CurrentLayout.depth) - 1);
- r = bits;
- g = bits;
- b = bits;
- }
- min = (r << 16) | (g << 8) | (b);
- max = (0xff << 24) | (r << 16) | (g << 8) | (b);
-
- RADEONWaitForFifo(pScrn, 2);
- OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_HIGH, max);
- OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_LOW, min);
-}
-
-void
-RADEONResetVideo(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
-
- if (info->accelOn) info->accel->Sync(pScrn);
-
- RADEONWaitForIdleMMIO(pScrn);
- OUTREG(RADEON_OV0_SCALE_CNTL, 0x80000000);
- OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0); /* maybe */
- OUTREG(RADEON_OV0_EXCLUSIVE_HORZ, 0);
- OUTREG(RADEON_OV0_FILTER_CNTL, 0x0000000f);
- OUTREG(RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_EQ |
- RADEON_VIDEO_KEY_FN_FALSE |
- RADEON_CMP_MIX_OR);
- OUTREG(RADEON_OV0_TEST, 0);
- OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
- OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
- RADEONSetColorKey(pScrn, pPriv->colorKey);
-
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350) ||
- (info->ChipFamily == CHIP_FAMILY_R200) ||
- (info->ChipFamily == CHIP_FAMILY_RADEON)) {
- int i;
-
- OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a20000);
- OUTREG(RADEON_OV0_LIN_TRANS_B, 0x198a190e);
- OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a2f9da);
- OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf2fe0442);
- OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a22046);
- OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
-
- /*
- * Set default Gamma ramp:
- *
- * Of 18 segments for gamma curve, all segments in R200 (and
- * newer) are programmable, while only lower 4 and upper 2
- * segments are programmable in the older Radeons.
- */
- for (i = 0; i < 18; i++) {
- OUTREG(def_gamma[i].gammaReg,
- (def_gamma[i].gammaSlope<<16) | def_gamma[i].gammaOffset);
- }
- } else {
- OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a00000);
- OUTREG(RADEON_OV0_LIN_TRANS_B, 0x1990190e);
- OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a0f9c0);
- OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf3000442);
- OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a02040);
- OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f);
- }
-}
-
-
-static XF86VideoAdaptorPtr
-RADEONAllocAdaptor(ScrnInfoPtr pScrn)
-{
- XF86VideoAdaptorPtr adapt;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONPortPrivPtr pPriv;
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 dot_clock;
-
- if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))
- return NULL;
-
- if(!(pPriv = xcalloc(1, sizeof(RADEONPortPrivRec) + sizeof(DevUnion))))
- {
- xfree(adapt);
- return NULL;
- }
-
- adapt->pPortPrivates = (DevUnion*)(&pPriv[1]);
- adapt->pPortPrivates[0].ptr = (pointer)pPriv;
-
- pPriv->colorKey = info->videoKey;
- pPriv->doubleBuffer = TRUE;
- pPriv->videoStatus = 0;
- pPriv->brightness = 0;
- pPriv->transform_index = 0;
- pPriv->saturation = 0;
- pPriv->contrast = 0;
- pPriv->red_intensity = 0;
- pPriv->green_intensity = 0;
- pPriv->blue_intensity = 0;
- pPriv->hue = 0;
- pPriv->currentBuffer = 0;
- pPriv->autopaint_colorkey = TRUE;
- if (info->OverlayOnCRTC2)
- pPriv->crt2 = TRUE;
- else
- pPriv->crt2 = FALSE;
-
- /*
- * Unlike older Mach64 chips, RADEON has only two ECP settings:
- * 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
- * for higher clocks, sure makes life nicer
- */
-
- /* Figure out which head we are on */
- if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary)
- dot_clock = info->ModeReg.dot_clock_freq_2;
- else
- dot_clock = info->ModeReg.dot_clock_freq;
-
- if(dot_clock < 17500)
- pPriv->ecp_div = 0;
- else
- pPriv->ecp_div = 1;
-
-
-#if 0
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dotclock is %g Mhz, setting ecp_div to %d\n", info->ModeReg.dot_clock_freq/100.0, pPriv->ecp_div);
-#endif
-
- OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) &
- 0xfffffCff) | (pPriv->ecp_div << 8));
-
- /* I suspect we may need a usleep after writing to the PLL. if you play a video too soon
- after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey
- on the right edge video output. */
-
-
- if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
- (info->ChipFamily == CHIP_FAMILY_RS200) ||
- (info->ChipFamily == CHIP_FAMILY_RS300)) {
- /* Force the overlay clock on for integrated chips
- */
- OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18)));
- }
-
- info->adaptor = adapt;
-
- return adapt;
-}
-
-static XF86VideoAdaptorPtr
-RADEONSetupImageVideo(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RADEONPortPrivPtr pPriv;
- XF86VideoAdaptorPtr adapt;
-
- if(!(adapt = RADEONAllocAdaptor(pScrn)))
- return NULL;
-
- adapt->type = XvWindowMask | XvInputMask | XvImageMask;
- adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
- adapt->name = "ATI Radeon Video Overlay";
- adapt->nEncodings = 1;
- adapt->pEncodings = &DummyEncoding;
- adapt->nFormats = NUM_FORMATS;
- adapt->pFormats = Formats;
- adapt->nPorts = 1;
- adapt->nAttributes = NUM_ATTRIBUTES;
- adapt->pAttributes = Attributes;
- adapt->nImages = NUM_IMAGES;
- adapt->pImages = Images;
- adapt->PutVideo = NULL;
- adapt->PutStill = NULL;
- adapt->GetVideo = NULL;
- adapt->GetStill = NULL;
- adapt->StopVideo = RADEONStopVideo;
- adapt->SetPortAttribute = RADEONSetPortAttribute;
- adapt->GetPortAttribute = RADEONGetPortAttribute;
- adapt->QueryBestSize = RADEONQueryBestSize;
- adapt->PutImage = RADEONPutImage;
- adapt->QueryImageAttributes = RADEONQueryImageAttributes;
-
- pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr);
- REGION_INIT(pScreen, &(pPriv->clip), NullBox, 0);
-
- xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
- xvSaturation = MAKE_ATOM("XV_SATURATION");
- xvColor = MAKE_ATOM("XV_COLOR");
- xvContrast = MAKE_ATOM("XV_CONTRAST");
- xvColorKey = MAKE_ATOM("XV_COLORKEY");
- xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
- xvHue = MAKE_ATOM("XV_HUE");
- xvRedIntensity = MAKE_ATOM("XV_RED_INTENSITY");
- xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY");
- xvBlueIntensity = MAKE_ATOM("XV_BLUE_INTENSITY");
-
- xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
- xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS");
- xvSwitchCRT = MAKE_ATOM("XV_SWITCHCRT");
-
- RADEONResetVideo(pScrn);
-
- return adapt;
-}
-
-static void
-RADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
-
- REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
-
- if(cleanup) {
- if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
- RADEONWaitForFifo(pScrn, 2);
- OUTREG(RADEON_OV0_SCALE_CNTL, 0);
- }
- if(info->videoLinear) {
- xf86FreeOffscreenLinear(info->videoLinear);
- info->videoLinear = NULL;
- }
- pPriv->videoStatus = 0;
- } else {
- if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
- pPriv->videoStatus |= OFF_TIMER;
- pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
- }
- }
-}
-
-static int
-RADEONSetPortAttribute(ScrnInfoPtr pScrn,
- Atom attribute,
- INT32 value,
- pointer data)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
- Bool setTransform = FALSE;
-
- info->accel->Sync(pScrn);
-
-#define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0)
-#define RTFBrightness(a) (((a)*1.0)/2000.0)
-#define RTFIntensity(a) (((a)*1.0)/2000.0)
-#define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0)
-#define RTFHue(a) (((a)*3.1416)/1000.0)
-#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
-
- if(attribute == xvAutopaintColorkey)
- {
- pPriv->autopaint_colorkey = ClipValue (value, 0, 1);
- }
- else if(attribute == xvSetDefaults)
- {
- pPriv->autopaint_colorkey = TRUE;
- pPriv->brightness = 0;
- pPriv->saturation = 0;
- pPriv->contrast = 0;
- pPriv->hue = 0;
- pPriv->red_intensity = 0;
- pPriv->green_intensity = 0;
- pPriv->blue_intensity = 0;
- pPriv->doubleBuffer = FALSE;
- setTransform = TRUE;
- }
- else if(attribute == xvBrightness)
- {
- pPriv->brightness = ClipValue (value, -1000, 1000);
- setTransform = TRUE;
- }
- else if((attribute == xvSaturation) || (attribute == xvColor))
- {
- pPriv->saturation = ClipValue (value, -1000, 1000);
- setTransform = TRUE;
- }
- else if(attribute == xvContrast)
- {
- pPriv->contrast = ClipValue (value, -1000, 1000);
- setTransform = TRUE;
- }
- else if(attribute == xvHue)
- {
- pPriv->hue = ClipValue (value, -1000, 1000);
- setTransform = TRUE;
- }
- else if(attribute == xvRedIntensity)
- {
- pPriv->red_intensity = ClipValue (value, -1000, 1000);
- setTransform = TRUE;
- }
- else if(attribute == xvGreenIntensity)
- {
- pPriv->green_intensity = ClipValue (value, -1000, 1000);
- setTransform = TRUE;
- }
- else if(attribute == xvBlueIntensity)
- {
- pPriv->blue_intensity = ClipValue (value, -1000, 1000);
- setTransform = TRUE;
- }
- else if(attribute == xvDoubleBuffer)
- {
- pPriv->doubleBuffer = ClipValue (value, 0, 1);
- pPriv->doubleBuffer = value;
- }
- else if(attribute == xvColorKey)
- {
- pPriv->colorKey = value;
- RADEONSetColorKey (pScrn, pPriv->colorKey);
- REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
- }
- else if(attribute == xvSwitchCRT)
- {
- pPriv->crt2 = ClipValue (value, 0, 1);
- pPriv->crt2 = value;
- if (pPriv->crt2)
- info->OverlayOnCRTC2 = TRUE;
- else
- info->OverlayOnCRTC2 = FALSE;
- }
- else
- return BadMatch;
-
- if (setTransform)
- {
- RADEONSetTransform(pScrn,
- RTFBrightness(pPriv->brightness),
- RTFContrast(pPriv->contrast),
- RTFSaturation(pPriv->saturation),
- RTFHue(pPriv->hue),
- RTFIntensity(pPriv->red_intensity),
- RTFIntensity(pPriv->green_intensity),
- RTFIntensity(pPriv->blue_intensity),
- pPriv->transform_index);
- }
-
- return Success;
-}
-
-static int
-RADEONGetPortAttribute(ScrnInfoPtr pScrn,
- Atom attribute,
- INT32 *value,
- pointer data)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
-
- if (info->accelOn) info->accel->Sync(pScrn);
-
- if(attribute == xvAutopaintColorkey)
- *value = pPriv->autopaint_colorkey;
- else if(attribute == xvBrightness)
- *value = pPriv->brightness;
- else if((attribute == xvSaturation) || (attribute == xvColor))
- *value = pPriv->saturation;
- else if(attribute == xvContrast)
- *value = pPriv->contrast;
- else if(attribute == xvHue)
- *value = pPriv->hue;
- else if(attribute == xvRedIntensity)
- *value = pPriv->red_intensity;
- else if(attribute == xvGreenIntensity)
- *value = pPriv->green_intensity;
- else if(attribute == xvBlueIntensity)
- *value = pPriv->blue_intensity;
- else if(attribute == xvDoubleBuffer)
- *value = pPriv->doubleBuffer ? 1 : 0;
- else if(attribute == xvColorKey)
- *value = pPriv->colorKey;
- else if(attribute == xvSwitchCRT)
- *value = pPriv->crt2 ? 1 : 0;
- else
- return BadMatch;
-
- return Success;
-}
-
-static void
-RADEONQueryBestSize(
- ScrnInfoPtr pScrn,
- Bool motion,
- short vid_w, short vid_h,
- short drw_w, short drw_h,
- unsigned int *p_w, unsigned int *p_h,
- pointer data
-){
- if(vid_w > (drw_w << 4))
- drw_w = vid_w >> 4;
- if(vid_h > (drw_h << 4))
- drw_h = vid_h >> 4;
-
- *p_w = drw_w;
- *p_h = drw_h;
-}
-
-static void
-RADEONCopyData(
- unsigned char *src,
- unsigned char *dst,
- int srcPitch,
- int dstPitch,
- int h,
- int w
-){
- w <<= 1;
- while(h--) {
- memcpy(dst, src, w);
- src += srcPitch;
- dst += dstPitch;
- }
-}
-
-static void
-RADEONCopyMungedData(
- unsigned char *src1,
- unsigned char *src2,
- unsigned char *src3,
- unsigned char *dst1,
- int srcPitch,
- int srcPitch2,
- int dstPitch,
- int h,
- int w
-){
- CARD32 *dst;
- CARD8 *s1, *s2, *s3;
- int i, j;
-
- w >>= 1;
-
- for(j = 0; j < h; j++) {
- dst = (pointer)dst1;
- s1 = src1; s2 = src2; s3 = src3;
- i = w;
- while(i > 4) {
- dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
- dst[1] = s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24);
- dst[2] = s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24);
- dst[3] = s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24);
- dst += 4; s2 += 4; s3 += 4; s1 += 8;
- i -= 4;
- }
- while(i--) {
- dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
- dst++; s2++; s3++;
- s1 += 2;
- }
-
- dst1 += dstPitch;
- src1 += srcPitch;
- if(j & 1) {
- src2 += srcPitch2;
- src3 += srcPitch2;
- }
- }
-}
-
-
-static FBLinearPtr
-RADEONAllocateMemory(
- ScrnInfoPtr pScrn,
- FBLinearPtr linear,
- int size
-){
- ScreenPtr pScreen;
- FBLinearPtr new_linear;
-
- if(linear) {
- if(linear->size >= size)
- return linear;
-
- if(xf86ResizeOffscreenLinear(linear, size))
- return linear;
-
- xf86FreeOffscreenLinear(linear);
- }
-
- pScreen = screenInfo.screens[pScrn->scrnIndex];
-
- new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
- NULL, NULL, NULL);
-
- if(!new_linear) {
- int max_size;
-
- xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16,
- PRIORITY_EXTREME);
-
- if(max_size < size)
- return NULL;
-
- xf86PurgeUnlockedOffscreenAreas(pScreen);
- new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
- NULL, NULL, NULL);
- }
-
- return new_linear;
-}
-
-static void
-RADEONDisplayVideo(
- ScrnInfoPtr pScrn,
- int id,
- int offset1, int offset2,
- short width, short height,
- int pitch,
- int left, int right, int top,
- BoxPtr dstBox,
- short src_w, short src_h,
- short drw_w, short drw_h
-){
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- int v_inc, h_inc, step_by, tmp;
- int p1_h_accum_init, p23_h_accum_init;
- int p1_v_accum_init;
- int ecp_div;
- int v_inc_shift;
- int y_mult;
- int x_off;
- int y_off;
- CARD32 scaler_src;
- CARD32 dot_clock;
- DisplayModePtr overlay_mode;
-
- /* Unlike older Mach64 chips, RADEON has only two ECP settings: 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
- for higher clocks, sure makes life nicer
-
- Here we need to find ecp_div again, as the user may have switched resolutions */
-
-
- /* Figure out which head we are on for dot clock */
- if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary)
- dot_clock = info->ModeReg.dot_clock_freq_2;
- else
- dot_clock = info->ModeReg.dot_clock_freq;
-
- if (dot_clock < 17500)
- ecp_div = 0;
- else
- ecp_div = 1;
-
- OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8));
-
- /* I suspect we may need a usleep after writing to the PLL. if you play a video too soon
- after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey
- on the right edge video output. */
-
- v_inc_shift = 20;
- y_mult = 1;
-
- if (info->MergedFB) {
- if (info->OverlayOnCRTC2)
- overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2;
- else
- overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT1;
- if (overlay_mode->Flags & V_INTERLACE)
- v_inc_shift++;
- if (overlay_mode->Flags & V_DBLSCAN) {
- v_inc_shift--;
- y_mult = 2;
- }
- if (overlay_mode->Flags & RADEON_USE_RMX) {
- v_inc = ((src_h * overlay_mode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
- } else {
- v_inc = (src_h << v_inc_shift) / drw_h;
- }
- } else {
- if (pScrn->currentMode->Flags & V_INTERLACE)
- v_inc_shift++;
- if (pScrn->currentMode->Flags & V_DBLSCAN) {
- v_inc_shift--;
- y_mult = 2;
- }
- if (pScrn->currentMode->Flags & RADEON_USE_RMX) {
- v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
- } else {
- v_inc = (src_h << v_inc_shift) / drw_h;
- }
- }
- h_inc = ((src_w << (12 + ecp_div)) / drw_w);
- step_by = 1;
-
- while(h_inc >= (2 << 12)) {
- step_by++;
- h_inc >>= 1;
- }
-
- /* keep everything in 16.16 */
-
- offset1 += ((left >> 16) & ~7) << 1;
- offset2 += ((left >> 16) & ~7) << 1;
-
- if (info->IsSecondary) {
- offset1 += info->FbMapSize;
- offset2 += info->FbMapSize;
- }
-
- tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
- p1_h_accum_init = ((tmp << 4) & 0x000f8000) |
- ((tmp << 12) & 0xf0000000);
-
- tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2);
- p23_h_accum_init = ((tmp << 4) & 0x000f8000) |
- ((tmp << 12) & 0x70000000);
-
- tmp = (top & 0x0000ffff) + 0x00018000;
- p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001;
-
- left = (left >> 16) & 7;
-
- RADEONWaitForFifo(pScrn, 2);
- OUTREG(RADEON_OV0_REG_LOAD_CNTL, 1);
- if (info->accelOn) info->accel->Sync(pScrn);
- while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & (1 << 3)));
-
- RADEONWaitForFifo(pScrn, 14);
- OUTREG(RADEON_OV0_H_INC, h_inc | ((h_inc >> 1) << 16));
- OUTREG(RADEON_OV0_STEP_BY, step_by | (step_by << 8));
-
- x_off = 8;
- y_off = 0;
-
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350) ||
- (info->ChipFamily == CHIP_FAMILY_R200))
- x_off = 0;
-
- /* needed to make the overlay work on crtc1 in leftof and above modes */
- if (info->MergedFB) {
- RADEONScrn2Rel srel =
- ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
- overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2;
- if (srel == radeonLeftOf) {
- x_off -= overlay_mode->CrtcHDisplay;
- /* y_off -= pScrn->frameY0; */
- }
- if (srel == radeonAbove) {
- y_off -= overlay_mode->CrtcVDisplay;
- /* x_off -= pScrn->frameX0; */
- }
- }
-
- /* Put the hardware overlay on CRTC2:
- *
- * Since one hardware overlay can not be displayed on two heads
- * at the same time, we might need to consider using software
- * rendering for the second head.
- */
-
- if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary) {
- x_off = 0;
- OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
- ((dstBox->y1*y_mult) << 16)));
- OUTREG(RADEON_OV1_Y_X_END, ((dstBox->x2 + x_off) |
- ((dstBox->y2*y_mult) << 16)));
- scaler_src = (1 << 14);
- } else {
- OUTREG(RADEON_OV0_Y_X_START, ((dstBox->x1 + x_off) |
- (((dstBox->y1*y_mult) + y_off) << 16)));
- OUTREG(RADEON_OV0_Y_X_END, ((dstBox->x2 + x_off) |
- (((dstBox->y2*y_mult) + y_off) << 16)));
- scaler_src = 0;
- }
-
- OUTREG(RADEON_OV0_V_INC, v_inc);
- OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16));
- OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch);
- OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, pitch);
- OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16));
- left >>= 1; src_w >>= 1;
- OUTREG(RADEON_OV0_P2_X_START_END, (src_w + left - 1) | (left << 16));
- OUTREG(RADEON_OV0_P3_X_START_END, (src_w + left - 1) | (left << 16));
- OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1 & 0xfffffff0);
- OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2 & 0xfffffff0);
- OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset1 & 0xfffffff0);
-
- RADEONWaitForFifo(pScrn, 9);
- OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset2 & 0xfffffff0);
- OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS, offset1 & 0xfffffff0);
- OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS, offset2 & 0xfffffff0);
- OUTREG(RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);
- OUTREG(RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);
- OUTREG(RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);
-
-#if 0
- if(id == FOURCC_UYVY)
- OUTREG(RADEON_OV0_SCALE_CNTL, 0x41008C03);
- else
- OUTREG(RADEON_OV0_SCALE_CNTL, 0x41008B03);
-#endif
-
- if (id == FOURCC_UYVY)
- OUTREG(RADEON_OV0_SCALE_CNTL, (RADEON_SCALER_SOURCE_YVYU422
- | RADEON_SCALER_ADAPTIVE_DEINT
- | RADEON_SCALER_SMART_SWITCH
- | RADEON_SCALER_DOUBLE_BUFFER
- | RADEON_SCALER_ENABLE
- | scaler_src));
- else
- OUTREG(RADEON_OV0_SCALE_CNTL, (RADEON_SCALER_SOURCE_VYUY422
- | RADEON_SCALER_ADAPTIVE_DEINT
- | RADEON_SCALER_SMART_SWITCH
- | RADEON_SCALER_DOUBLE_BUFFER
- | RADEON_SCALER_ENABLE
- | scaler_src));
-
- OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
-}
-
-
-static int
-RADEONPutImage(
- ScrnInfoPtr pScrn,
- short src_x, short src_y,
- short drw_x, short drw_y,
- short src_w, short src_h,
- short drw_w, short drw_h,
- int id, unsigned char* buf,
- short width, short height,
- Bool Sync,
- RegionPtr clipBoxes, pointer data
-){
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
- INT32 xa, xb, ya, yb;
- unsigned char *dst_start;
- int pitch, new_size, offset, s2offset, s3offset;
- int srcPitch, srcPitch2, dstPitch;
- int top, left, npixels, nlines, bpp;
- BoxRec dstBox;
- CARD32 tmp;
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 surface_cntl = INREG(RADEON_SURFACE_CNTL);
-
- OUTREG(RADEON_SURFACE_CNTL, (surface_cntl |
- RADEON_NONSURF_AP0_SWP_32BPP) & ~RADEON_NONSURF_AP0_SWP_16BPP);
-#endif
-
- /*
- * s2offset, s3offset - byte offsets into U and V plane of the
- * source where copying starts. Y plane is
- * done by editing "buf".
- *
- * offset - byte offset to the first line of the destination.
- *
- * dst_start - byte address to the first displayed pel.
- *
- */
-
- /* make the compiler happy */
- s2offset = s3offset = srcPitch2 = 0;
-
- if(src_w > (drw_w << 4))
- drw_w = src_w >> 4;
- if(src_h > (drw_h << 4))
- drw_h = src_h >> 4;
-
- /* Clip */
- xa = src_x;
- xb = src_x + src_w;
- ya = src_y;
- yb = src_y + src_h;
-
- dstBox.x1 = drw_x;
- dstBox.x2 = drw_x + drw_w;
- dstBox.y1 = drw_y;
- dstBox.y2 = drw_y + drw_h;
-
- if (info->MergedFB)
- RADEONChooseOverlayCRTC(pScrn, &dstBox);
-
- if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb,
- clipBoxes, width, height))
- return Success;
-
- if (info->MergedFB && info->OverlayOnCRTC2) {
- dstBox.x1 -= info->CRT2pScrn->frameX0;
- dstBox.x2 -= info->CRT2pScrn->frameX0;
- dstBox.y1 -= info->CRT2pScrn->frameY0;
- dstBox.y2 -= info->CRT2pScrn->frameY0;
- } else {
- dstBox.x1 -= pScrn->frameX0;
- dstBox.x2 -= pScrn->frameX0;
- dstBox.y1 -= pScrn->frameY0;
- dstBox.y2 -= pScrn->frameY0;
- }
-
- bpp = pScrn->bitsPerPixel >> 3;
- pitch = bpp * pScrn->displayWidth;
-
- switch(id) {
- case FOURCC_YV12:
- case FOURCC_I420:
- dstPitch = ((width << 1) + 15) & ~15;
- new_size = ((dstPitch * height) + bpp - 1) / bpp;
- srcPitch = (width + 3) & ~3;
- s2offset = srcPitch * height;
- srcPitch2 = ((width >> 1) + 3) & ~3;
- s3offset = (srcPitch2 * (height >> 1)) + s2offset;
- break;
- case FOURCC_UYVY:
- case FOURCC_YUY2:
- default:
- dstPitch = ((width << 1) + 15) & ~15;
- new_size = ((dstPitch * height) + bpp - 1) / bpp;
- srcPitch = (width << 1);
- break;
- }
-
- if(!(info->videoLinear = RADEONAllocateMemory(pScrn, info->videoLinear,
- pPriv->doubleBuffer ? (new_size << 1) : new_size)))
- {
- return BadAlloc;
- }
-
- pPriv->currentBuffer ^= 1;
-
- /* copy data */
- top = ya >> 16;
- left = (xa >> 16) & ~1;
- npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left;
-
- offset = (info->videoLinear->offset * bpp) + (top * dstPitch);
- if(pPriv->doubleBuffer)
- offset += pPriv->currentBuffer * new_size * bpp;
-
- dst_start = info->FB + offset;
-
- switch(id) {
- case FOURCC_YV12:
- case FOURCC_I420:
- top &= ~1;
- dst_start += left << 1;
- tmp = ((top >> 1) * srcPitch2) + (left >> 1);
- s2offset += tmp;
- s3offset += tmp;
- if(id == FOURCC_I420) {
- tmp = s2offset;
- s2offset = s3offset;
- s3offset = tmp;
- }
- nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top;
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- OUTREG(RADEON_SURFACE_CNTL, (surface_cntl | RADEON_NONSURF_AP0_SWP_32BPP)
- & ~RADEON_NONSURF_AP0_SWP_16BPP);
-#endif
- RADEONCopyMungedData(buf + (top * srcPitch) + left, buf + s2offset,
- buf + s3offset, dst_start, srcPitch, srcPitch2,
- dstPitch, nlines, npixels);
- break;
- case FOURCC_UYVY:
- case FOURCC_YUY2:
- default:
- left <<= 1;
- buf += (top * srcPitch) + left;
- nlines = ((yb + 0xffff) >> 16) - top;
- dst_start += left;
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- OUTREG(RADEON_SURFACE_CNTL, surface_cntl & ~(RADEON_NONSURF_AP0_SWP_32BPP
- | RADEON_NONSURF_AP0_SWP_16BPP));
-#endif
- RADEONCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
- break;
- }
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- /* restore byte swapping */
- OUTREG(RADEON_SURFACE_CNTL, surface_cntl);
-#endif
-
- /* update cliplist */
- if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))
- {
- REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
- /* draw these */
- if(pPriv->autopaint_colorkey)
- xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
- }
-
- RADEONDisplayVideo(pScrn, id, offset, offset, width, height, dstPitch,
- xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h);
-
- pPriv->videoStatus = CLIENT_VIDEO_ON;
-
- info->VideoTimerCallback = RADEONVideoTimerCallback;
-
- return Success;
-}
-
-
-static int
-RADEONQueryImageAttributes(
- ScrnInfoPtr pScrn,
- int id,
- unsigned short *w, unsigned short *h,
- int *pitches, int *offsets
-){
- int size, tmp;
-
- if(*w > 2048) *w = 2048;
- if(*h > 2048) *h = 2048;
-
- *w = (*w + 1) & ~1;
- if(offsets) offsets[0] = 0;
-
- switch(id) {
- case FOURCC_YV12:
- case FOURCC_I420:
- *h = (*h + 1) & ~1;
- size = (*w + 3) & ~3;
- if(pitches) pitches[0] = size;
- size *= *h;
- if(offsets) offsets[1] = size;
- tmp = ((*w >> 1) + 3) & ~3;
- if(pitches) pitches[1] = pitches[2] = tmp;
- tmp *= (*h >> 1);
- size += tmp;
- if(offsets) offsets[2] = size;
- size += tmp;
- break;
- case FOURCC_UYVY:
- case FOURCC_YUY2:
- default:
- size = *w << 1;
- if(pitches) pitches[0] = size;
- size *= *h;
- break;
- }
-
- return size;
-}
-
-static void
-RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
-
- if(pPriv->videoStatus & TIMER_MASK) {
- if(pPriv->videoStatus & OFF_TIMER) {
- if(pPriv->offTime < now) {
- unsigned char *RADEONMMIO = info->MMIO;
- OUTREG(RADEON_OV0_SCALE_CNTL, 0);
- pPriv->videoStatus = FREE_TIMER;
- pPriv->freeTime = now + FREE_DELAY;
- }
- } else { /* FREE_TIMER */
- if(pPriv->freeTime < now) {
- if(info->videoLinear) {
- xf86FreeOffscreenLinear(info->videoLinear);
- info->videoLinear = NULL;
- }
- pPriv->videoStatus = 0;
- info->VideoTimerCallback = NULL;
- }
- }
- } else /* shouldn't get here */
- info->VideoTimerCallback = NULL;
-}
-
-/****************** Offscreen stuff ***************/
-typedef struct {
- FBLinearPtr linear;
- Bool isOn;
-} OffscreenPrivRec, * OffscreenPrivPtr;
-
-static int
-RADEONAllocateSurface(
- ScrnInfoPtr pScrn,
- int id,
- unsigned short w,
- unsigned short h,
- XF86SurfacePtr surface
-){
- FBLinearPtr linear;
- int pitch, fbpitch, size, bpp;
- OffscreenPrivPtr pPriv;
- if((w > 1024) || (h > 1024))
- return BadAlloc;
-
- w = (w + 1) & ~1;
- pitch = ((w << 1) + 15) & ~15;
- bpp = pScrn->bitsPerPixel >> 3;
- fbpitch = bpp * pScrn->displayWidth;
- size = ((pitch * h) + bpp - 1) / bpp;
-
- if(!(linear = RADEONAllocateMemory(pScrn, NULL, size)))
- return BadAlloc;
-
- surface->width = w;
- surface->height = h;
-
- if(!(surface->pitches = xalloc(sizeof(int)))) {
- xf86FreeOffscreenLinear(linear);
- return BadAlloc;
- }
- if(!(surface->offsets = xalloc(sizeof(int)))) {
- xfree(surface->pitches);
- xf86FreeOffscreenLinear(linear);
- return BadAlloc;
- }
- if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) {
- xfree(surface->pitches);
- xfree(surface->offsets);
- xf86FreeOffscreenLinear(linear);
- return BadAlloc;
- }
-
- pPriv->linear = linear;
- pPriv->isOn = FALSE;
-
- surface->pScrn = pScrn;
- surface->id = id;
- surface->pitches[0] = pitch;
- surface->offsets[0] = linear->offset * bpp;
- surface->devPrivate.ptr = (pointer)pPriv;
-
- return Success;
-}
-
-static int
-RADEONStopSurface(
- XF86SurfacePtr surface
-){
- OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
- RADEONInfoPtr info = RADEONPTR(surface->pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- if(pPriv->isOn) {
- OUTREG(RADEON_OV0_SCALE_CNTL, 0);
- pPriv->isOn = FALSE;
- }
- return Success;
-}
-
-
-static int
-RADEONFreeSurface(
- XF86SurfacePtr surface
-){
- OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
-
- if(pPriv->isOn)
- RADEONStopSurface(surface);
- xf86FreeOffscreenLinear(pPriv->linear);
- xfree(surface->pitches);
- xfree(surface->offsets);
- xfree(surface->devPrivate.ptr);
-
- return Success;
-}
-
-static int
-RADEONGetSurfaceAttribute(
- ScrnInfoPtr pScrn,
- Atom attribute,
- INT32 *value
-){
- return RADEONGetPortAttribute(pScrn, attribute, value,
- (pointer)(GET_PORT_PRIVATE(pScrn)));
-}
-
-static int
-RADEONSetSurfaceAttribute(
- ScrnInfoPtr pScrn,
- Atom attribute,
- INT32 value
-){
- return RADEONSetPortAttribute(pScrn, attribute, value,
- (pointer)(GET_PORT_PRIVATE(pScrn)));
-}
-
-
-static int
-RADEONDisplaySurface(
- XF86SurfacePtr surface,
- short src_x, short src_y,
- short drw_x, short drw_y,
- short src_w, short src_h,
- short drw_w, short drw_h,
- RegionPtr clipBoxes
-){
- OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
- ScrnInfoPtr pScrn = surface->pScrn;
-
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr;
-
- INT32 xa, ya, xb, yb;
- BoxRec dstBox;
-
- if (src_w > (drw_w << 4))
- drw_w = src_w >> 4;
- if (src_h > (drw_h << 4))
- drw_h = src_h >> 4;
-
- xa = src_x;
- xb = src_x + src_w;
- ya = src_y;
- yb = src_y + src_h;
-
- dstBox.x1 = drw_x;
- dstBox.x2 = drw_x + drw_w;
- dstBox.y1 = drw_y;
- dstBox.y2 = drw_y + drw_h;
-
- if (info->MergedFB)
- RADEONChooseOverlayCRTC(pScrn, &dstBox);
-
- if (!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes,
- surface->width, surface->height))
- return Success;
-
- if (info->MergedFB && info->OverlayOnCRTC2) {
- dstBox.x1 -= info->CRT2pScrn->frameX0;
- dstBox.x2 -= info->CRT2pScrn->frameX0;
- dstBox.y1 -= info->CRT2pScrn->frameY0;
- dstBox.y2 -= info->CRT2pScrn->frameY0;
- } else {
- dstBox.x1 -= pScrn->frameX0;
- dstBox.x2 -= pScrn->frameX0;
- dstBox.y1 -= pScrn->frameY0;
- dstBox.y2 -= pScrn->frameY0;
- }
-
- RADEONResetVideo(pScrn);
-
- RADEONDisplayVideo(pScrn, surface->id,
- surface->offsets[0], surface->offsets[0],
- surface->width, surface->height, surface->pitches[0],
- xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h);
-
- if (portPriv->autopaint_colorkey)
- xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
-
- pPriv->isOn = TRUE;
- /* we've prempted the XvImage stream so set its free timer */
- if (portPriv->videoStatus & CLIENT_VIDEO_ON) {
- REGION_EMPTY(pScrn->pScreen, &portPriv->clip);
- UpdateCurrentTime();
- portPriv->videoStatus = FREE_TIMER;
- portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
- info->VideoTimerCallback = RADEONVideoTimerCallback;
- }
-
- return Success;
-}
-
-
-static void
-RADEONInitOffscreenImages(ScreenPtr pScreen)
-{
-/* ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RADEONInfoPtr info = RADEONPTR(pScrn); */
- XF86OffscreenImagePtr offscreenImages;
- /* need to free this someplace */
-
- if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec))))
- return;
-
- offscreenImages[0].image = &Images[0];
- offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES |
- VIDEO_CLIP_TO_VIEWPORT;
- offscreenImages[0].alloc_surface = RADEONAllocateSurface;
- offscreenImages[0].free_surface = RADEONFreeSurface;
- offscreenImages[0].display = RADEONDisplaySurface;
- offscreenImages[0].stop = RADEONStopSurface;
- offscreenImages[0].setAttribute = RADEONSetSurfaceAttribute;
- offscreenImages[0].getAttribute = RADEONGetSurfaceAttribute;
- offscreenImages[0].max_width = 1024;
- offscreenImages[0].max_height = 1024;
- offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
- offscreenImages[0].attributes = Attributes;
-
- xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
-}