summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/radeon.h3
-rw-r--r--src/radeon_crtc.c25
-rw-r--r--src/radeon_video.c233
-rw-r--r--src/radeon_video.h6
4 files changed, 163 insertions, 104 deletions
diff --git a/src/radeon.h b/src/radeon.h
index a8f72fcd..4f7f60e4 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 8e713302..434034c1 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -1296,28 +1296,3 @@ RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
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 dbf66dac..a38931c8 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -106,7 +106,7 @@ static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;
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, xvAlphaMode;
#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_ATTRIBUTES] =
{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_DEC_ATTRIBUTES+1] =
{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 pScrn,
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 pScrn,
*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 b6d5d2d9..072f40e1 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;