📄 radeon_video.c
字号:
/* $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 "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;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;} 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 12static 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+3static 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"},};#define NUM_IMAGES 4static 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);}voidRADEONResetVideo(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 XF86VideoAdaptorPtrRADEONAllocAdaptor(ScrnInfoPtr pScrn){ XF86VideoAdaptorPtr adapt; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr pPriv; unsigned char *RADEONMMIO = info->MMIO; 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; /* * 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 */ if(info->ModeReg.dot_clock_freq < 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)); if ((info->ChipFamily == CHIP_FAMILY_RS100) || (info->ChipFamily == CHIP_FAMILY_RS200) || (info->ChipFamily == CHIP_FAMILY_RS300)) { /* Force the overlay clock on for integrated chips */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -