summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/radeon.h2
-rw-r--r--src/radeon_driver.c29
-rw-r--r--src/radeon_video.c40
-rw-r--r--src/radeon_video.h3
4 files changed, 51 insertions, 23 deletions
diff --git a/src/radeon.h b/src/radeon.h
index 7789a9a7..646b742e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -142,6 +142,7 @@ typedef enum {
OPTION_TUNER_TYPE,
OPTION_RAGE_THEATRE_MICROC_PATH,
OPTION_RAGE_THEATRE_MICROC_TYPE,
+ OPTION_SCALER_WIDTH,
#endif
#ifdef RENDER
OPTION_RENDER_ACCEL,
@@ -739,6 +740,7 @@ typedef struct {
CARD8 input[5];
} MM_TABLE;
CARD16 video_decoder_type;
+ int overlay_scaler_buffer_width;
/* Render */
Bool RenderAccel;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1950f750..251c4397 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -182,8 +182,9 @@ static const OptionInfoRec RADEONOptions[] = {
{ OPTION_RAGE_THEATRE_COMPOSITE_PORT, "RageTheatreCompositePort", OPTV_INTEGER, {0}, FALSE },
{ OPTION_RAGE_THEATRE_SVIDEO_PORT, "RageTheatreSVideoPort", OPTV_INTEGER, {0}, FALSE },
{ OPTION_TUNER_TYPE, "TunerType", OPTV_INTEGER, {0}, FALSE },
- { OPTION_RAGE_THEATRE_MICROC_PATH, "RageTheatreMicrocPath", OPTV_STRING, {0}, FALSE },
- { OPTION_RAGE_THEATRE_MICROC_TYPE, "RageTheatreMicrocType", OPTV_STRING, {0}, FALSE },
+ { OPTION_RAGE_THEATRE_MICROC_PATH, "RageTheatreMicrocPath", OPTV_STRING, {0}, FALSE },
+ { OPTION_RAGE_THEATRE_MICROC_TYPE, "RageTheatreMicrocType", OPTV_STRING, {0}, FALSE },
+ { OPTION_SCALER_WIDTH, "ScalerWidth", OPTV_INTEGER, {0}, FALSE },
#endif
#ifdef RENDER
{ OPTION_RENDER_ACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE },
@@ -3049,6 +3050,30 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
info->tunerType=-1;
}
+ if(xf86GetOptValInteger(info->Options, OPTION_SCALER_WIDTH, &(info->overlay_scaler_buffer_width))) {
+ if ((info->overlay_scaler_buffer_width < 1024) ||
+ (info->overlay_scaler_buffer_width > 2048) ||
+ ((info->overlay_scaler_buffer_width % 64) != 0)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to set illegal scaler width. Using default\n");
+ info->overlay_scaler_buffer_width = 0;
+ }
+ }
+ else info->overlay_scaler_buffer_width = 0;
+ if (!info->overlay_scaler_buffer_width) {
+ /* overlay scaler line length differs for different revisions
+ this needs to be maintained by hand */
+ switch(info->ChipFamily){
+ case CHIP_FAMILY_R200:
+ case CHIP_FAMILY_R300:
+ info->overlay_scaler_buffer_width = 1920;
+ break;
+ default:
+ info->overlay_scaler_buffer_width = 1536;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Assuming overlay scaler buffer width is %d\n",
+ info->overlay_scaler_buffer_width);
+
if(info->tunerType>31){
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to set tuner type to invalid value. Disabling setting\n");
info->tunerType=-1;
diff --git a/src/radeon_video.c b/src/radeon_video.c
index b9b479f0..6a910a17 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1364,17 +1364,6 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL,
(INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18)));
}
-
- /* overlay scaler line length differs for different revisions
- this needs to be maintained by hand */
- switch(info->ChipFamily){
- case CHIP_FAMILY_R200:
- case CHIP_FAMILY_R300:
- pPriv->overlay_scaler_buffer_width=1920;
- break;
- default:
- pPriv->overlay_scaler_buffer_width=1536;
- }
/* Decide on tuner type */
if((info->tunerType<0) && (info->MM_TABLE_valid)) {
@@ -2439,6 +2428,8 @@ RADEONDisplayVideo(
CARD32 scale_cntl;
double dsr;
int tap_set;
+ int predownscale=0;
+ int src_w_d;
is_rgb=0;
switch(id){
@@ -2513,17 +2504,27 @@ RADEONDisplayVideo(
step_by_y = 1;
step_by_uv = step_by_y;
+ src_w_d = src_w;
+#if 0
+ /* XXX this does not appear to work */
/* if the source width was larger than what would fit in overlay scaler increase step_by values */
i=src_w;
- while(i>pPriv->overlay_scaler_buffer_width){
- step_by_y++;
+ while(i>info->overlay_scaler_buffer_width){
+ step_by_y++;
step_by_uv++;
h_inc >>=1;
i=i/2;
- }
-
+ }
+#else
+ /* predownscale instead (yes this hurts quality) - will only work for widths up
+ to 2 times the overlay_scaler_buffer_width, should be enough */
+ if (src_w_d > info->overlay_scaler_buffer_width) {
+ src_w_d /= 2; /* odd widths? */
+ predownscale = 1;
+ }
+#endif
- h_inc_d = src_w;
+ h_inc_d = src_w_d;
h_inc_d = h_inc_d/drw_w;
/* we could do a tad better - but why
bother when this concerns downscaling and the code is so much more
@@ -2540,7 +2541,7 @@ RADEONDisplayVideo(
h_inc_uv = h_inc>>(step_by_uv-step_by_y);
h_inc = h_inc * h_inc_d;
h_inc_uv = h_inc_uv * h_inc_d;
- /* pPriv->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit
+ /* info->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit
in the buffer for 2 tap filtering */
/* the only place it is documented in is in ATI source code */
/* we need twice as much space for 4 tap filtering.. */
@@ -2550,7 +2551,7 @@ RADEONDisplayVideo(
#if 0
if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12))
&& (deinterlacing_method!=METHOD_WEAVE)
- && (drw_w*2 <= pPriv->overlay_scaler_buffer_width)){
+ && (drw_w*2 <= info->overlay_scaler_buffer_width)){
step_by_y=0;
step_by_uv=1;
h_inc_uv = h_inc;
@@ -2592,7 +2593,8 @@ RADEONDisplayVideo(
RADEONWaitForFifo(pScrn, 10);
OUTREG(RADEON_OV0_H_INC, h_inc | ((h_inc_uv >> 1) << 16));
- OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8));
+ OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) |
+ predownscale << 4 | predownscale << 12);
x_off = 8;
y_off = 0;
diff --git a/src/radeon_video.h b/src/radeon_video.h
index 33e78dfa..4b97d51b 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -62,8 +62,7 @@ typedef struct {
#define METHOD_ADAPTIVE 3
int overlay_deinterlacing_method;
- int overlay_scaler_buffer_width;
-
+
int capture_vbi_data;
int dec_brightness;