Index: radeon_video.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c,v
retrieving revision 1.31
diff -U3 -r1.31 radeon_video.c
--- radeon_video.c	10 Nov 2003 18:41:23 -0000	1.31
+++ radeon_video.c	19 Jun 2004 08:22:55 -0000
@@ -37,12 +37,14 @@
 			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)
 
 static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;
 static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
 static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
+static Atom xvOvAlpha, xvGrAlpha, xvAlphaMode;
 
 typedef struct {
    CARD32	 transform_index;
@@ -53,8 +55,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;
@@ -124,7 +129,7 @@
 };
 
 
-#define NUM_ATTRIBUTES 9+3
+#define NUM_ATTRIBUTES 9+6
 
 static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
 {
@@ -140,6 +145,9 @@
    {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
    {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
    {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
+   {XvSettable | XvGettable,     0,  255, "XV_OVERLAY_ALPHA"},
+   {XvSettable | XvGettable,     0,  255, "XV_GRAPHICS_ALPHA"},
+   {XvSettable | XvGettable,     0,    3, "XV_ALPHA_MODE"},
 };
 
 #define NUM_IMAGES 4
@@ -333,6 +341,65 @@
     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 if (alpha_mode == 1) { /* 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));
+    } else if (alpha_mode == 2) {
+      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 1 */
+      OUTREG(RADEON_DISP_MERGE_CNTL,
+        (RADEON_DISP_ALPHA_MODE_PER_PIXEL & 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_PER_PIXEL & RADEON_DISP_ALPHA_MODE_MASK) |
+          ((gr_alpha << 0x00000010) & RADEON_DISP_GRPH_ALPHA_MASK) |
+          ((ov_alpha << 0x00000018) & RADEON_DISP_OV0_ALPHA_MASK));
+    }
+#if 0
+     else {
+    }
+#endif
+     /* per-pixel mode - RADEON_DISP_ALPHA_MODE_PER_PIXEL */
+     /* not yet supported */
+}
+
 static void RADEONSetColorKey(ScrnInfoPtr pScrn, CARD32 colorKey)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -457,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;
@@ -537,6 +607,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");
@@ -582,6 +655,7 @@
     RADEONInfoPtr	info = RADEONPTR(pScrn);
     RADEONPortPrivPtr	pPriv = (RADEONPortPrivPtr)data;
     Bool		setTransform = FALSE;
+    Bool		setAlpha = FALSE;
 
     info->accel->Sync(pScrn);
 
@@ -607,7 +681,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)
     {
@@ -644,6 +722,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, 2);
+       setAlpha = TRUE;
+    }
     else if(attribute == xvDoubleBuffer)
     {
 	pPriv->doubleBuffer = ClipValue (value, 0, 1);
@@ -671,6 +764,11 @@
 			   pPriv->transform_index);
     }
 
+    if (setAlpha)
+    {
+       RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode);
+    }
+
     return Success;
 }
 
@@ -701,6 +799,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)
@@ -856,6 +960,7 @@
     int x_off;
     CARD32 scaler_src;
 
+
     /* 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
 
