diff options
Diffstat (limited to 'vidix/drivers/mach64_vid.c')
-rw-r--r-- | vidix/drivers/mach64_vid.c | 160 |
1 files changed, 114 insertions, 46 deletions
diff --git a/vidix/drivers/mach64_vid.c b/vidix/drivers/mach64_vid.c index c7dd06c295..4cdec6f4da 100644 --- a/vidix/drivers/mach64_vid.c +++ b/vidix/drivers/mach64_vid.c @@ -84,6 +84,10 @@ typedef struct video_registers_s }video_registers_t; static bes_registers_t besr; + +/* Graphic keys */ +static vidix_grkey_t mach64_grkey; + #define DECLARE_VREG(name) { #name, name, 0 } static video_registers_t vregs[] = { @@ -134,6 +138,12 @@ static video_registers_t vregs[] = OUTREG(addr, _tmp); \ } while (0) +static __inline__ int ATIGetMach64LCDReg(int _Index) +{ + OUTREG8(LCD_INDEX, _Index); + return INREG(LCD_DATA); +} + static __inline__ uint32_t INPLL(uint32_t addr) { uint32_t res; @@ -234,6 +244,40 @@ static uint32_t mach64_get_yres( void ) return yres + 1; } +// returns the verical stretch factor in 16.16 +static int mach64_get_vert_stretch(void) +{ + int lcd_index; + int lcd_gen_ctrl; + int vert_stretching; + int ext_vert_stretch; + int ret; + int yres= mach64_get_yres(); + +//FIXME check for mobility & co + + lcd_index= INREG(LCD_INDEX); + + vert_stretching= ATIGetMach64LCDReg(LCD_VERT_STRETCHING); + if(!(vert_stretching&VERT_STRETCH_EN)) ret= 1<<16; + else + { + int panel_size; + + ext_vert_stretch= ATIGetMach64LCDReg(LCD_EXT_VERT_STRETCH); + panel_size= (ext_vert_stretch&VERT_PANEL_SIZE)>>11; + panel_size++; + + ret= ((yres<<16) + (panel_size>>1))/panel_size; + } + +// lcd_gen_ctrl = ATIGetMach64LCDReg(LCD_GEN_CNTL); + + OUTREG(LCD_INDEX, lcd_index); + + return ret; +} + static void mach64_vid_make_default() { mach64_fifo_wait(2); @@ -531,46 +575,10 @@ static void mach64_vid_display_video( void ) // bit 28-31 nothing interresting just crashed my system when i played with them :( mach64_fifo_wait(3); - if(besr.ckey_on) - { - OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk); - OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr); - OUTREG(OVERLAY_KEY_CNTL,0x50); - } - else - { - OUTREG(OVERLAY_GRAPHICS_KEY_MSK, 0ULL); - OUTREG(OVERLAY_GRAPHICS_KEY_CLR, 0ULL); - OUTREG(OVERLAY_KEY_CNTL,0x50); - } -switch(mach64_vid_get_dbpp()) //Ugly Hack (remove me if colorkey is correctly supported in vidix) -{ -case 15: - OUTREG(OVERLAY_GRAPHICS_KEY_MSK, 0x7FFF); - OUTREG(OVERLAY_GRAPHICS_KEY_CLR, 0x7C1F); - OUTREG(OVERLAY_KEY_CNTL,0x50); - break; -case 16: - OUTREG(OVERLAY_GRAPHICS_KEY_MSK, 0xFFFF); - OUTREG(OVERLAY_GRAPHICS_KEY_CLR, 0xF81F); - OUTREG(OVERLAY_KEY_CNTL,0x50); - break; -case 24: - OUTREG(OVERLAY_GRAPHICS_KEY_MSK, 0xFFFFFF); - OUTREG(OVERLAY_GRAPHICS_KEY_CLR, 0xFF00FF); - OUTREG(OVERLAY_KEY_CNTL,0x50); - break; -case 32: - OUTREG(OVERLAY_GRAPHICS_KEY_MSK, 0xFFFFFF); - OUTREG(OVERLAY_GRAPHICS_KEY_CLR, 0xFF00FF); - OUTREG(OVERLAY_KEY_CNTL,0x50); - break; -default: - OUTREG(OVERLAY_GRAPHICS_KEY_MSK, 0); - OUTREG(OVERLAY_GRAPHICS_KEY_CLR, 0); - OUTREG(OVERLAY_KEY_CNTL,0x50); - break; -} + OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk); + OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr); + OUTREG(OVERLAY_KEY_CNTL,0x50); + mach64_wait_for_idle(); vf = INREG(VIDEO_FORMAT); @@ -661,11 +669,13 @@ static int mach64_vid_init_video( vidix_playback_t *config ) dest_h = config->dest.h; besr.fourcc = config->fourcc; ecp = (INPLL(PLL_VCLK_CNTL) & PLL_ECP_DIV) >> 4; - v_inc = (src_h << (12 - +(mach64_is_interlace()?1:0) - -(mach64_is_dbl_scan()?1:0) -// +(is_420?1:0) - )) / dest_h; + v_inc = src_h * mach64_get_vert_stretch(); + + if(mach64_is_interlace()) v_inc<<=1; + if(mach64_is_dbl_scan() ) v_inc>>=1; + v_inc>>=4; // convert 16.16 -> 20.12 + v_inc/= dest_h; + h_inc = (src_w << (12+ecp)) / dest_w; /* keep everything in 16.16 */ config->offsets[0] = 0; @@ -726,6 +736,52 @@ static int mach64_vid_init_video( vidix_playback_t *config ) besr.y_x_end = y_pos | ((config->dest.x + dest_w) << 16); besr.height_width = ((src_w - left)<<16) | (src_h - top); + if(mach64_grkey.ckey.op == CKEY_TRUE) + { + besr.ckey_on=1; + + switch(mach64_vid_get_dbpp()) + { + case 15: + besr.graphics_key_msk=0x7FFF; + besr.graphics_key_clr= + ((mach64_grkey.ckey.blue &0xF8)>>3) + | ((mach64_grkey.ckey.green&0xF8)<<2) + | ((mach64_grkey.ckey.red &0xF8)<<7); + break; + case 16: + besr.graphics_key_msk=0xFFFF; + besr.graphics_key_clr= + ((mach64_grkey.ckey.blue &0xF8)>>3) + | ((mach64_grkey.ckey.green&0xFC)<<3) + | ((mach64_grkey.ckey.red &0xF8)<<8); + break; + case 24: + besr.graphics_key_msk=0xFFFFFF; + besr.graphics_key_clr= + ((mach64_grkey.ckey.blue &0xFF)) + | ((mach64_grkey.ckey.green&0xFF)<<8) + | ((mach64_grkey.ckey.red &0xFF)<<16); + break; + case 32: + besr.graphics_key_msk=0xFFFFFF; + besr.graphics_key_clr= + ((mach64_grkey.ckey.blue &0xFF)) + | ((mach64_grkey.ckey.green&0xFF)<<8) + | ((mach64_grkey.ckey.red &0xFF)<<16); + default: + besr.ckey_on=0; + besr.graphics_key_msk=0; + besr.graphics_key_clr=0; + } + } + else + { + besr.ckey_on=0; + besr.graphics_key_msk=0; + besr.graphics_key_clr=0; + } + return 0; } @@ -756,7 +812,7 @@ int vixQueryFourcc(vidix_fourcc_t *to) VID_DEPTH_12BPP| VID_DEPTH_15BPP| VID_DEPTH_16BPP| VID_DEPTH_24BPP| VID_DEPTH_32BPP; - to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK; + to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; @@ -949,3 +1005,15 @@ int vixPlaybackSetEq( const vidix_video_eq_t * eq) OUTREG(SCALER_COLOUR_CNTL, (br & 0x7f) | (sat << 8) | (sat << 16)); return 0; } + +int vixGetGrKeys(vidix_grkey_t *grkey) +{ + memcpy(grkey, &mach64_grkey, sizeof(vidix_grkey_t)); + return(0); +} + +int vixSetGrKeys(const vidix_grkey_t *grkey) +{ + memcpy(&mach64_grkey, grkey, sizeof(vidix_grkey_t)); + return(0); +} |