diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/radeon.h | 2 | ||||
-rw-r--r-- | src/radeon_driver.c | 29 | ||||
-rw-r--r-- | src/radeon_video.c | 40 | ||||
-rw-r--r-- | src/radeon_video.h | 3 |
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; |