xf86-video-ati: Branch 'randr-1.2'

Alex Deucher agd5f at kemper.freedesktop.org
Thu Aug 16 18:55:37 PDT 2007


 src/radeon.h       |    3 
 src/radeon_crtc.c  |   25 -----
 src/radeon_video.c |  233 ++++++++++++++++++++++++++++++++++++-----------------
 src/radeon_video.h |    6 -
 4 files changed, 163 insertions(+), 104 deletions(-)

New commits:
diff-tree a90d675832ddb02c81ace010ccbf02619b70edac (from 5793e8753d11432bf95c7c6dd80c811e16aba058)
Author: Alex Deucher <alex at botch2.com>
Date:   Thu Aug 16 21:55:14 2007 -0400

    RADEON: fix Xv clipping and overlay sourcing
    
    - Basically just copied from the intel driver.  I'm planning to push
    this to the server soon, but add it now to get things working
    and to provide compat for older servers.
    
    - Overlay crtc source control attribute now called XV_CRTC
    The old attribute XV_SWITCHCRT has been removed.  If anyone cares,
    we can add it back as an alias to XV_CRTC
    XV_CRTC: -1 auto, 0 crtc0, 1 crtc1

diff --git a/src/radeon.h b/src/radeon.h
index a8f72fc..4f7f60e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -460,7 +460,6 @@ typedef struct {
     Bool              IsMobility;       /* Mobile chips for laptops */
     Bool              IsIGP;            /* IGP chips */
     Bool              HasSingleDAC;     /* only TVDAC on chip */
-    Bool              OverlayOnCRTC2;
     Bool              ddc_mode;         /* Validate mode by matching exactly
 					 * the modes supported in DDC data
 					 */
@@ -948,8 +947,6 @@ void
 radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
 void
 RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num);
-void
-RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox);
 
 extern void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
 					   DisplayModePtr mode, xf86OutputPtr output);
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 8e71330..434034c 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -1296,28 +1296,3 @@ RADEONCrtcFindClosestMode(xf86CrtcPtr cr
     return pMode;
 }
 
-void
-RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox)
-{
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    int c;
-    int crtc_num = 0;
-
-    for (c = 0; c < xf86_config->num_crtc; c++)
-    {
-        xf86CrtcPtr crtc = xf86_config->crtc[c];
-
-	if (!crtc->enabled)
-	    continue;
-
-	if ((dstBox->x1 >= crtc->x) && (dstBox->y1 >= crtc->y))
-	    crtc_num = c;
-    }
-
-    if (crtc_num == 1)
-        info->OverlayOnCRTC2 = TRUE;
-    else
-        info->OverlayOnCRTC2 = FALSE;
-}
-
diff --git a/src/radeon_video.c b/src/radeon_video.c
index dbf66da..a38931c 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -106,7 +106,7 @@ static Atom xvBrightness, xvColorKey, xv
 static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
 static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
 static Atom xvGamma, xvColorspace;
-static Atom xvSwitchCRT;
+static Atom xvCRTC;
 static Atom xvEncoding, xvFrequency, xvVolume, xvMute,
 	     xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation,
 	     xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod,
@@ -119,6 +119,114 @@ static Atom xvOvAlpha, xvGrAlpha, xvAlph
 #define GET_PORT_PRIVATE(pScrn) \
    (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
 
+static void
+radeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
+{
+    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
+    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
+    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
+    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
+
+    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
+	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
+}
+
+static void
+radeon_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
+{
+    if (crtc->enabled) {
+	crtc_box->x1 = crtc->x;
+	crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
+	crtc_box->y1 = crtc->y;
+	crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
+    } else
+	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
+}
+
+static int
+radeon_box_area(BoxPtr box)
+{
+    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
+}
+
+static xf86CrtcPtr
+radeon_covering_crtc(ScrnInfoPtr pScrn,
+		     BoxPtr	box,
+		     xf86CrtcPtr desired,
+		     BoxPtr	crtc_box_ret)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcPtr		crtc, best_crtc;
+    int			coverage, best_coverage;
+    int			c;
+    BoxRec		crtc_box, cover_box;
+
+    best_crtc = NULL;
+    best_coverage = 0;
+    crtc_box_ret->x1 = 0;
+    crtc_box_ret->x2 = 0;
+    crtc_box_ret->y1 = 0;
+    crtc_box_ret->y2 = 0;
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	crtc = xf86_config->crtc[c];
+	radeon_crtc_box(crtc, &crtc_box);
+	radeon_box_intersect(&cover_box, &crtc_box, box);
+	coverage = radeon_box_area(&cover_box);
+	if (coverage && crtc == desired) {
+	    *crtc_box_ret = crtc_box;
+	    return crtc;
+	} else if (coverage > best_coverage) {
+	    *crtc_box_ret = crtc_box;
+	    best_crtc = crtc;
+	    best_coverage = coverage;
+	}
+    }
+    return best_crtc;
+}
+
+static Bool
+radeon_clip_video_helper(ScrnInfoPtr pScrn,
+			 xf86CrtcPtr *crtc_ret,
+			 xf86CrtcPtr desired_crtc,
+			 BoxPtr      dst,
+			 INT32	    *xa,
+			 INT32	    *xb,
+			 INT32	    *ya,
+			 INT32	    *yb,
+			 RegionPtr   reg,
+			 INT32	    width,
+			 INT32	    height)
+{
+    Bool	ret;
+    RegionRec	crtc_region_local;
+    RegionPtr	crtc_region = reg;
+    
+    /*
+     * For overlay video, compute the relevant CRTC and
+     * clip video to that
+     */
+    if (crtc_ret) {
+	BoxRec		crtc_box;
+	xf86CrtcPtr	crtc = radeon_covering_crtc(pScrn, dst,
+						    desired_crtc,
+						    &crtc_box);
+
+	if (crtc) {
+	    REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
+	    crtc_region = &crtc_region_local;
+	    REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
+	}
+	*crtc_ret = crtc;
+    }
+
+    ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb, 
+				crtc_region, width, height);
+
+    if (crtc_region != reg)
+	REGION_UNINIT (pScreen, &crtc_region_local);
+
+    return ret;
+}
 
 #ifdef USE_EXA
 static void
@@ -226,7 +334,7 @@ static XF86AttributeRec Attributes[NUM_A
    {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"},
+   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
    {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
    {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
 };
@@ -257,7 +365,7 @@ static XF86AttributeRec Attributes[NUM_D
    {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"},
+   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
    {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
    {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
    
@@ -1082,7 +1190,7 @@ RADEONResetVideo(ScrnInfoPtr pScrn)
 
     xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
     xvSetDefaults       = MAKE_ATOM("XV_SET_DEFAULTS");
-    xvSwitchCRT         = MAKE_ATOM("XV_SWITCHCRT");
+    xvCRTC              = MAKE_ATOM("XV_CRTC");
 
     xvOvAlpha	      = MAKE_ATOM("XV_OVERLAY_ALPHA");
     xvGrAlpha	      = MAKE_ATOM("XV_GRAPHICS_ALPHA");
@@ -1295,11 +1403,8 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
     pPriv->currentBuffer = 0;
     pPriv->autopaint_colorkey = TRUE;
     pPriv->gamma = 1000;
-    if (info->OverlayOnCRTC2)
-	pPriv->crt2 = TRUE;
-    else
-	pPriv->crt2 = FALSE;
-	
+    pPriv->desired_crtc = NULL;
+
     pPriv->ov_alpha = 255;
     pPriv->gr_alpha = 255;
     pPriv->alpha_mode = 0;
@@ -1324,24 +1429,14 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
      * 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
      * for higher clocks, sure makes life nicer
      */
+    dot_clock = info->ModeReg.dot_clock_freq;
 
-    /* Figure out which head we are on */
-    if (info->OverlayOnCRTC2)
-	dot_clock = info->ModeReg.dot_clock_freq_2;
-    else
-	dot_clock = info->ModeReg.dot_clock_freq;
-
-    if(dot_clock < 17500)
+    if (dot_clock < 17500)
         info->ecp_div = 0;
     else
         info->ecp_div = 1;
     ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8);
 
-#if 0
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dotclock is %g Mhz, setting ecp_div to %d\n", info->ModeReg.dot_clock_freq/100.0, info->ecp_div);
-#endif
-
-
     if ((info->ChipFamily == CHIP_FAMILY_RS100) || 
 	(info->ChipFamily == CHIP_FAMILY_RS200) ||
 	(info->ChipFamily == CHIP_FAMILY_RS300)) {
@@ -1353,7 +1448,6 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
     OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, ecp);
 
 
-
     /* Decide on tuner type */
     if((info->tunerType<0) && (info->MM_TABLE_valid)) {
         pPriv->tuner_type = info->MM_TABLE.tuner_type;
@@ -1657,14 +1751,15 @@ RADEONSetPortAttribute(ScrnInfoPtr  pScr
 	RADEONSetColorKey (pScrn, pPriv->colorKey);
 	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
     } 
-    else if(attribute == xvSwitchCRT) 
+    else if(attribute == xvCRTC) 
     {
-	pPriv->crt2 = ClipValue (value, 0, 1);
-	pPriv->crt2 = value;
-	if (pPriv->crt2)
-	    info->OverlayOnCRTC2 = TRUE;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	if ((value < -1) || (value > xf86_config->num_crtc))
+	    return BadValue;
+	if (value < 0)
+	    pPriv->desired_crtc = NULL;
 	else
-	    info->OverlayOnCRTC2 = FALSE; 
+	    pPriv->desired_crtc = xf86_config->crtc[value];
     }
     else if(attribute == xvOvAlpha) 
     {
@@ -1854,8 +1949,16 @@ RADEONGetPortAttribute(ScrnInfoPtr  pScr
 	*value = pPriv->doubleBuffer ? 1 : 0;
     else if(attribute == xvColorKey)
 	*value = pPriv->colorKey;
-    else if(attribute == xvSwitchCRT)
-	*value = pPriv->crt2 ? 1 : 0;
+    else if(attribute == xvCRTC) {
+	int		c;
+	xf86CrtcConfigPtr	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	for (c = 0; c < xf86_config->num_crtc; c++)
+	    if (xf86_config->crtc[c] == pPriv->desired_crtc)
+		break;
+	if (c == xf86_config->num_crtc)
+	    c = -1;
+	*value = c;
+    }
     else if(attribute == xvOvAlpha)
 	*value = pPriv->ov_alpha;
     else if(attribute == xvGrAlpha)
@@ -2388,7 +2491,8 @@ RADEONFreeMemory(
 static void
 RADEONDisplayVideo(
     ScrnInfoPtr pScrn,
-    RADEONPortPrivPtr pPriv, 
+    xf86CrtcPtr crtc,
+    RADEONPortPrivPtr pPriv,
     int id,
     int offset1, int offset2,
     int offset3, int offset4,
@@ -2425,10 +2529,10 @@ RADEONDisplayVideo(
     int predownscale=0;
     int src_w_d;
     int leftuv = 0;
-    xf86CrtcPtr crtc;
     DisplayModePtr mode;
     RADEONOutputPrivatePtr radeon_output;
     xf86OutputPtr output;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
     is_rgb=0; is_planar=0;
     switch(id){
@@ -2451,7 +2555,7 @@ RADEONDisplayVideo(
        workarounds for chip erratas */
 
     /* Figure out which head we are on for dot clock */
-    if (info->OverlayOnCRTC2)
+    if (radeon_crtc->crtc_id == 1)
         dot_clock = info->ModeReg.dot_clock_freq_2;
     else
         dot_clock = info->ModeReg.dot_clock_freq;
@@ -2476,11 +2580,6 @@ RADEONDisplayVideo(
     v_inc_shift = 20;
     y_mult = 1;
 
-    if (info->OverlayOnCRTC2)
-	crtc = xf86_config->crtc[1];
-    else
-	crtc = xf86_config->crtc[0];
-
     mode = &crtc->mode;
 
     if (mode->Flags & V_INTERLACE)
@@ -2494,6 +2593,7 @@ RADEONDisplayVideo(
 	output = xf86_config->output[i];
 	if (output->crtc == crtc) {
 	    radeon_output = output->driver_private;
+	    break;
 	}
     }
 
@@ -2653,7 +2753,7 @@ RADEONDisplayVideo(
      * rendering for the second head.
      */
 
-    if (info->OverlayOnCRTC2) {
+    if (radeon_crtc->crtc_id == 1) {
         x_off = 0;
         OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
                                       ((dstBox->y1*y_mult) << 16)));
@@ -2731,6 +2831,7 @@ RADEONDisplayVideo(
 			| ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0);
 		break;
     }
+
     OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl);
     OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
 }
@@ -2804,16 +2905,10 @@ RADEONPutImage(
    dstBox.y1 = drw_y;
    dstBox.y2 = drw_y + drw_h;
 
-   RADEONChooseOverlayCRTC(pScrn, &dstBox);
-
-   if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb,
-			     clipBoxes, width, height))
-	return Success;
-
-   if (info->OverlayOnCRTC2)
-     crtc = xf86_config->crtc[1];
-   else
-     crtc = xf86_config->crtc[0];
+   if (!radeon_clip_video_helper(pScrn, &crtc, pPriv->desired_crtc,
+				 &dstBox, &xa, &xb, &ya, &yb,
+				 clipBoxes, width, height))
+       return Success;
 
    dstBox.x1 -= crtc->x;
    dstBox.x2 -= crtc->x;
@@ -2942,7 +3037,7 @@ RADEONPutImage(
 
     /* FIXME: someone should look at these offsets, I don't think it makes sense how
               they are handled throughout the source. */
-    RADEONDisplayVideo(pScrn, pPriv, id, offset, offset + d2line, offset + d3line,
+    RADEONDisplayVideo(pScrn, crtc, pPriv, id, offset, offset + d2line, offset + d3line,
 		     offset, offset + d2line, offset + d3line, width, height, dstPitch,
 		     xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB);
 
@@ -3183,17 +3278,11 @@ RADEONDisplaySurface(
     dstBox.y1 = drw_y;
     dstBox.y2 = drw_y + drw_h;
 
-    RADEONChooseOverlayCRTC(pScrn, &dstBox);
-
-    if (!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, 
-			       surface->width, surface->height))
-	return Success;
+    if (!radeon_clip_video_helper(pScrn, &crtc, portPriv->desired_crtc,
+				  &dstBox, &xa, &xb, &ya, &yb, clipBoxes,
+				  surface->width, surface->height))
+        return Success;
 
-    if (info->OverlayOnCRTC2)
-        crtc = xf86_config->crtc[1];
-    else
-        crtc = xf86_config->crtc[0];
-    
     dstBox.x1 -= crtc->x;
     dstBox.x2 -= crtc->x;
     dstBox.y1 -= crtc->y;
@@ -3203,7 +3292,7 @@ RADEONDisplaySurface(
     /* this isn't needed */
     RADEONResetVideo(pScrn);
 #endif
-    RADEONDisplayVideo(pScrn, portPriv, surface->id,
+    RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id,
 		       surface->offsets[0], surface->offsets[0],
 		       surface->offsets[0], surface->offsets[0],
 		       surface->offsets[0], surface->offsets[0],
@@ -3283,6 +3372,7 @@ RADEONPutVideo(
    int mult;
    int vbi_line_width, vbi_start, vbi_end;
    xf86CrtcPtr crtc;
+   RADEONCrtcPrivatePtr radeon_crtc;
 
     RADEON_SYNC(info, pScrn);
    /*
@@ -3320,19 +3410,14 @@ RADEONPutVideo(
 
    vbi_line_width = 798*2;
    if(width<=640)
-	   vbi_line_width = 0x640; /* 1600 actually */
-	   else
-	   vbi_line_width = 2000; /* might need adjustment */
-
-   RADEONChooseOverlayCRTC(pScrn, &dstBox);
-        
-   if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height))
-        return Success;
-
-   if (info->OverlayOnCRTC2)
-     crtc = xf86_config->crtc[1];
+       vbi_line_width = 0x640; /* 1600 actually */
    else
-     crtc = xf86_config->crtc[0];
+       vbi_line_width = 2000; /* might need adjustment */
+
+   if (!radeon_clip_video_helper(pScrn, &crtc, pPriv->desired_crtc,
+				 &dstBox, &xa, &xb, &ya, &yb,
+				 clipBoxes, width, height))
+       return Success;
 
    dstBox.x1 -= crtc->x;
    dstBox.x2 -= crtc->x;
@@ -3487,7 +3572,7 @@ RADEONPutVideo(
 	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
    }
 
-   RADEONDisplayVideo(pScrn, pPriv, id, offset1+top*srcPitch, offset2+top*srcPitch,
+   RADEONDisplayVideo(pScrn, crtc, pPriv, id, offset1+top*srcPitch, offset2+top*srcPitch,
 		offset3+top*srcPitch, offset4+top*srcPitch, offset1+top*srcPitch,
 		offset2+top*srcPitch, width, height, dstPitch*mult/2,
                      xa, xb, ya, &dstBox, src_w, src_h*mult/2, drw_w, drw_h, pPriv->overlay_deinterlacing_method);
diff --git a/src/radeon_video.h b/src/radeon_video.h
index b6d5d2d..072f40e 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -11,6 +11,8 @@
 #include "generic_bus.h"
 #include "theatre.h"
 
+#include "xf86Crtc.h"
+
 /* Xvideo port struct */
 typedef struct {
    CARD32	 transform_index;
@@ -40,7 +42,7 @@ typedef struct {
    CARD8         tuner_type;
    MSP3430Ptr    msp3430;
    TDA9885Ptr    tda9885;
-	UDA1380Ptr	  uda1380;
+    UDA1380Ptr	  uda1380;
 
    /* VIP bus and devices */
    GENERIC_BUS_Ptr  VIP;
@@ -77,7 +79,7 @@ typedef struct {
    Time          offTime;
    Time          freeTime;
    Bool          autopaint_colorkey;
-   Bool		 crt2; /* 0=CRT1, 1=CRT2 */
+   xf86CrtcPtr   desired_crtc;
 
 #ifdef USE_EXA
    int              size;


More information about the xorg-commit mailing list