--- radeon_video.c.pre-gamma 2003-11-08 12:14:14.000000000 -0500 +++ radeon_video.c 2003-11-19 19:10:54.000000000 -0500 @@ -38,6 +38,7 @@ unsigned short *, int *, int *); static void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now); +static void RADEONSetOverlayAlpha(ScrnInfoPtr pScrn, int ov_alpha, int gr_alpha, int alpha_mode); #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) @@ -45,6 +46,7 @@ static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer; static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity; static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults; +static Atom xvOvAlpha, xvGrAlpha, xvAlphaMode; static Atom xvSwitchCRT; typedef struct { @@ -56,8 +58,11 @@ int red_intensity; int green_intensity; int blue_intensity; + int ov_alpha; + int gr_alpha; int ecp_div; + int alpha_mode; /* 0 = key mode, 1 = global mode */ Bool doubleBuffer; unsigned char currentBuffer; RegionRec clip; @@ -129,7 +134,7 @@ }; -#define NUM_ATTRIBUTES 9+4 +#define NUM_ATTRIBUTES 9+7 static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { @@ -146,6 +151,9 @@ {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"}, {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"}, {XvSettable | XvGettable, 0, 1, "XV_SWITCHCRT"}, + {XvSettable | XvGettable, 0, 255, "XV_OVERLAY_ALPHA"}, + {XvSettable | XvGettable, 0, 255, "XV_GRAPHICS_ALPHA"}, + {XvSettable | XvGettable, 0, 1, "XV_ALPHA_MODE"}, }; #define NUM_IMAGES 4 @@ -339,6 +347,58 @@ OUTREG(RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr); } +static void RADEONSetOverlayAlpha(ScrnInfoPtr pScrn, int ov_alpha, int gr_alpha, int alpha_mode) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + if (alpha_mode == 0) { /* key mode */ + OUTREG(RADEON_OV0_KEY_CNTL, + RADEON_GRAPHIC_KEY_FN_EQ | /* what does this do? */ + RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */ + RADEON_CMP_MIX_OR); + /* crtc 1 */ + OUTREG(RADEON_DISP_MERGE_CNTL, + (RADEON_DISP_ALPHA_MODE_KEY & + RADEON_DISP_ALPHA_MODE_MASK) | + ((gr_alpha << 0x00000010) & + RADEON_DISP_GRPH_ALPHA_MASK) | + ((ov_alpha << 0x00000018) & + RADEON_DISP_OV0_ALPHA_MASK)); + /* crtc 2 */ + OUTREG(RADEON_DISP2_MERGE_CNTL, + (RADEON_DISP_ALPHA_MODE_KEY & + RADEON_DISP_ALPHA_MODE_MASK) | + ((gr_alpha << 0x00000010) & + RADEON_DISP_GRPH_ALPHA_MASK) | + ((ov_alpha << 0x00000018) & + RADEON_DISP_OV0_ALPHA_MASK)); + } else { /* global mode */ + OUTREG(RADEON_OV0_KEY_CNTL, + RADEON_GRAPHIC_KEY_FN_FALSE | /* what does this do? */ + RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */ + RADEON_CMP_MIX_AND); + /* crtc 2 */ + OUTREG(RADEON_DISP2_MERGE_CNTL, + (RADEON_DISP_ALPHA_MODE_GLOBAL & + RADEON_DISP_ALPHA_MODE_MASK) | + ((gr_alpha << 0x00000010) & + RADEON_DISP_GRPH_ALPHA_MASK) | + ((ov_alpha << 0x00000018) & + RADEON_DISP_OV0_ALPHA_MASK)); + /* crtc 1 */ + OUTREG(RADEON_DISP_MERGE_CNTL, + (RADEON_DISP_ALPHA_MODE_GLOBAL & + RADEON_DISP_ALPHA_MODE_MASK) | + ((gr_alpha << 0x00000010) & + RADEON_DISP_GRPH_ALPHA_MASK) | + ((ov_alpha << 0x00000018) & + RADEON_DISP_OV0_ALPHA_MASK)); + } + /* per-pixel mode - RADEON_DISP_ALPHA_MODE_PER_PIXEL */ + /* not yet supported */ +} + static void RADEONSetColorKey(ScrnInfoPtr pScrn, CARD32 colorKey) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -464,6 +524,9 @@ pPriv->red_intensity = 0; pPriv->green_intensity = 0; pPriv->blue_intensity = 0; + pPriv->ov_alpha = 255; + pPriv->gr_alpha = 255; + pPriv->alpha_mode = 0; pPriv->hue = 0; pPriv->currentBuffer = 0; pPriv->autopaint_colorkey = TRUE; @@ -561,6 +624,9 @@ xvRedIntensity = MAKE_ATOM("XV_RED_INTENSITY"); xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY"); xvBlueIntensity = MAKE_ATOM("XV_BLUE_INTENSITY"); + xvOvAlpha = MAKE_ATOM("XV_OVERLAY_ALPHA"); + xvGrAlpha = MAKE_ATOM("XV_GRAPHICS_ALPHA"); + xvAlphaMode = MAKE_ATOM("XV_ALPHA_MODE"); xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS"); @@ -607,6 +673,7 @@ RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; Bool setTransform = FALSE; + Bool setAlpha = FALSE; info->accel->Sync(pScrn); @@ -632,7 +699,11 @@ pPriv->green_intensity = 0; pPriv->blue_intensity = 0; pPriv->doubleBuffer = FALSE; + pPriv->ov_alpha = 255; + pPriv->gr_alpha = 255; + pPriv->alpha_mode = 0; setTransform = TRUE; + setAlpha = TRUE; } else if(attribute == xvBrightness) { @@ -669,6 +740,21 @@ pPriv->blue_intensity = ClipValue (value, -1000, 1000); setTransform = TRUE; } + else if(attribute == xvOvAlpha) + { + pPriv->ov_alpha = ClipValue (value, 0, 255); + setAlpha = TRUE; + } + else if(attribute == xvGrAlpha) + { + pPriv->gr_alpha = ClipValue (value, 0, 255); + setAlpha = TRUE; + } + else if(attribute == xvAlphaMode) + { + pPriv->alpha_mode = ClipValue (value, 0, 1); + setAlpha = TRUE; + } else if(attribute == xvDoubleBuffer) { pPriv->doubleBuffer = ClipValue (value, 0, 1); @@ -683,7 +769,6 @@ else if(attribute == xvSwitchCRT) { pPriv->crt2 = ClipValue (value, 0, 1); - pPriv->crt2 = value; if (pPriv->crt2) info->OverlayOnCRTC2 = TRUE; else @@ -704,6 +789,11 @@ RTFIntensity(pPriv->blue_intensity), pPriv->transform_index); } + + if (setAlpha) + { + RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode); + } return Success; } @@ -735,6 +825,12 @@ *value = pPriv->green_intensity; else if(attribute == xvBlueIntensity) *value = pPriv->blue_intensity; + else if(attribute == xvOvAlpha) + *value = pPriv->ov_alpha; + else if(attribute == xvGrAlpha) + *value = pPriv->gr_alpha; + else if(attribute == xvAlphaMode) + *value = pPriv->alpha_mode; else if(attribute == xvDoubleBuffer) *value = pPriv->doubleBuffer ? 1 : 0; else if(attribute == xvColorKey) @@ -895,6 +991,7 @@ 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