⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overlay.c

📁 ati driver
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	Copyright (c) 2002, Thomas Kurschel		Part of Radeon accelerant			Hardware access routines for overlays*/#include "GlobalData.h"#include "radeon_interface.h"#include "../shared/mmio.h"#include "../regs/overlay_regs.h"#include "../regs/pll_regs.h"#include "../regs/capture_regs.h"#include "../common/utils.h"#include "../shared/pll_access.h"#include <math.h>#include <string.h>#include "CP.h"void Radeon_TempHideOverlay( accelerator_info *ai );// standard (linear) gammastatic struct {    uint16 reg;    bool r200_or_above;    uint32 slope;    uint32 offset;} std_gamma[] = {    { RADEON_OV0_GAMMA_0_F, false, 0x100, 0x0000 },    { RADEON_OV0_GAMMA_10_1F, false, 0x100, 0x0020 },    { RADEON_OV0_GAMMA_20_3F, false, 0x100, 0x0040 },    { RADEON_OV0_GAMMA_40_7F, false, 0x100, 0x0080 },    { RADEON_OV0_GAMMA_80_BF, true, 0x100, 0x0100 },    { RADEON_OV0_GAMMA_C0_FF, true, 0x100, 0x0100 },    { RADEON_OV0_GAMMA_100_13F, true, 0x100, 0x0200 },    { RADEON_OV0_GAMMA_140_17F, true, 0x100, 0x0200 },    { RADEON_OV0_GAMMA_180_1BF, true, 0x100, 0x0300 },    { RADEON_OV0_GAMMA_1C0_1FF, true, 0x100, 0x0300 },    { RADEON_OV0_GAMMA_200_23F, true, 0x100, 0x0400 },    { RADEON_OV0_GAMMA_240_27F, true, 0x100, 0x0400 },    { RADEON_OV0_GAMMA_280_2BF, true, 0x100, 0x0500 },    { RADEON_OV0_GAMMA_2C0_2FF, true, 0x100, 0x0500 },    { RADEON_OV0_GAMMA_300_33F, true, 0x100, 0x0600 },    { RADEON_OV0_GAMMA_340_37F, true, 0x100, 0x0600 },    { RADEON_OV0_GAMMA_380_3BF, false, 0x100, 0x0700 },    { RADEON_OV0_GAMMA_3C0_3FF, false, 0x100, 0x0700 }};// setup overlay unit before first usevoid Radeon_InitOverlay( 	accelerator_info *ai, int crtc_idx ){	vuint8 *regs = ai->regs;	shared_info *si = ai->si;	uint i;	uint32 ecp_div;		SHOW_FLOW0( 0, "" );		// make sure we really write this value as the "toggle" bit	// contained in it (which is zero initially) is edge-sensitive!	// for capturing, we need to select "software" video port	si->overlay_mgr.auto_flip_reg = RADEON_OV0_VID_PORT_SELECT_SOFTWARE;		OUTREG( regs, RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOFT_RESET );	OUTREG( regs, RADEON_OV0_AUTO_FLIP_CNTRL, si->overlay_mgr.auto_flip_reg );	OUTREG( regs, RADEON_OV0_FILTER_CNTL, 			// use fixed filter coefficients		RADEON_OV0_HC_COEF_ON_HORZ_Y |		RADEON_OV0_HC_COEF_ON_HORZ_UV |		RADEON_OV0_HC_COEF_ON_VERT_Y |		RADEON_OV0_HC_COEF_ON_VERT_UV );	OUTREG( regs, RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_EQ |		RADEON_VIDEO_KEY_FN_FALSE |		RADEON_CMP_MIX_OR );	OUTREG( regs, RADEON_OV0_TEST, 0 );//	OUTREG( regs, RADEON_FCP_CNTL, RADEON_FCP_CNTL_GND );	// disable capture clock//	OUTREG( regs, RADEON_CAP0_TRIG_CNTL, 0 );				// disable capturing	OUTREG( regs, RADEON_OV0_REG_LOAD_CNTL, 0 );	// tell deinterlacer to always show recent field	OUTREG( regs, RADEON_OV0_DEINTERLACE_PATTERN, 		0xaaaaa | (9 << RADEON_OV0_DEINT_PAT_LEN_M1_SHIFT) );		// set gamma	for( i = 0; i < sizeof( std_gamma ) / sizeof( std_gamma[0] ); ++i ) {		if( !std_gamma[i].r200_or_above || si->asic >= rt_r200 ) {			OUTREG( regs, std_gamma[i].reg,					(std_gamma[i].slope << 16) | std_gamma[i].offset );		}	}		// overlay unit can only handle up to 175 MHz, if pixel clock is higher,	// only every second pixel is handled	if( si->crtc[crtc_idx].mode.timing.pixel_clock < 175000 )		ecp_div = 0;	else		ecp_div = 1;	Radeon_OUTPLLP( regs, si->asic, RADEON_VCLK_ECP_CNTL, 		ecp_div << RADEON_ECP_DIV_SHIFT, ~RADEON_ECP_DIV_MASK );	si->active_overlay.crtc_idx = si->pending_overlay.crtc_idx;		// invalidate active colour space	si->active_overlay.ob.space = -1;		// invalidate position/scaling	si->active_overlay.ob.width = -1;}// colour space transformation matrixtypedef struct space_transform{    float   RefLuma;	// scaling of luma to use full RGB range    float   RefRCb;		// b/u -> r    float   RefRY;		// g/y -> r    float   RefRCr;		// r/v -> r    float   RefGCb;    float   RefGY;    float   RefGCr;    float   RefBCb;    float   RefBY;    float   RefBCr;} space_transform;// Parameters for ITU-R BT.601 and ITU-R BT.709 colour spacesspace_transform trans_yuv[2] ={    { 1.1678, 0.0, 1, 1.6007, -0.3929, 1, -0.8154, 2.0232, 1, 0.0 }, /* BT.601 */    { 1.1678, 0.0, 1, 1.7980, -0.2139, 1, -0.5345, 2.1186, 1, 0.0 }  /* BT.709 */};// RGB is a pass throughspace_transform trans_rgb =	{ 1, 0, 0, 1, 0, 1, 0, 1, 0, 0 };// set overlay colour space transformation matrixstatic void Radeon_SetTransform( 	accelerator_info *ai,	float	    bright,	float	    cont,	float	    sat, 	float	    hue,	float	    red_intensity, 	float	    green_intensity, 	float	    blue_intensity,	uint	    ref){	vuint8 *regs = ai->regs;	shared_info *si = ai->si;	float	    OvHueSin, OvHueCos;	float	    CAdjOff;	float		CAdjRY, CAdjGY, CAdjBY;	float	    CAdjRCb, CAdjRCr;	float	    CAdjGCb, CAdjGCr;	float	    CAdjBCb, CAdjBCr;	float	    RedAdj,GreenAdj,BlueAdj;	float	    OvROff, OvGOff, OvBOff;	float		OvRY, OvGY, OvBY;	float	    OvRCb, OvRCr;	float	    OvGCb, OvGCr;	float	    OvBCb, OvBCr;	float	    Loff;	float	    Coff;		uint32	    dwOvROff, dwOvGOff, dwOvBOff;	uint32		dwOvRY, dwOvGY, dwOvBY;	uint32	    dwOvRCb, dwOvRCr;	uint32	    dwOvGCb, dwOvGCr;	uint32	    dwOvBCb, dwOvBCr;		space_transform	*trans;		SHOW_FLOW0( 0, "" );	// get proper conversion formula	switch( si->pending_overlay.ob.space ) {	case B_YCbCr422:	case B_YUV12:		Loff = 16 * 4;		// internal representation is 10 Bits		Coff = 128 * 4;				if (ref >= 2) 			ref = 0;				trans = &trans_yuv[ref];		break;			case B_RGB15:	case B_RGB16:	case B_RGB32:	default:		Loff = 0;		Coff = 0;		trans = &trans_rgb;	}		OvHueSin = sin(hue);	OvHueCos = cos(hue);		// get matrix values to convert overlay colour space to RGB	// applying colour adjustment, saturation and luma scaling	// (saturation doesn't work with RGB input, perhaps it did with some	//  maths; this is left to the reader :)	CAdjRY = cont * trans->RefLuma * trans->RefRY;	CAdjGY = cont * trans->RefLuma * trans->RefGY;	CAdjBY = cont * trans->RefLuma * trans->RefBY;		CAdjRCb = sat * -OvHueSin * trans->RefRCr;	CAdjRCr = sat * OvHueCos * trans->RefRCr;	CAdjGCb = sat * (OvHueCos * trans->RefGCb - OvHueSin * trans->RefGCr);	CAdjGCr = sat * (OvHueSin * trans->RefGCb + OvHueCos * trans->RefGCr);	CAdjBCb = sat * OvHueCos * trans->RefBCb;	CAdjBCr = sat * OvHueSin * trans->RefBCb;		// adjust black level	CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0;	RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0;	GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0;	BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0;		OvRY = CAdjRY;	OvGY = CAdjGY;	OvBY = CAdjBY;	OvRCb = CAdjRCb;	OvRCr = CAdjRCr;	OvGCb = CAdjGCb;	OvGCr = CAdjGCr;	OvBCb = CAdjBCb;	OvBCr = CAdjBCr;	// apply offsets	OvROff = RedAdj + CAdjOff -	CAdjRY * Loff - (OvRCb + OvRCr) * Coff;	OvGOff = GreenAdj + CAdjOff - CAdjGY * Loff - (OvGCb + OvGCr) * Coff;	OvBOff = BlueAdj + CAdjOff - CAdjBY * Loff - (OvBCb + OvBCr) * Coff;		dwOvROff = ((int32)(OvROff * 2.0)) & 0x1fff;	dwOvGOff = ((int32)(OvGOff * 2.0)) & 0x1fff;	dwOvBOff = ((int32)(OvBOff * 2.0)) & 0x1fff;	dwOvRY = (((int32)(OvRY * 2048.0))&0x7fff)<<17;	dwOvGY = (((int32)(OvGY * 2048.0))&0x7fff)<<17;	dwOvBY = (((int32)(OvBY * 2048.0))&0x7fff)<<17;	dwOvRCb = (((int32)(OvRCb * 2048.0))&0x7fff)<<1;	dwOvRCr = (((int32)(OvRCr * 2048.0))&0x7fff)<<17;	dwOvGCb = (((int32)(OvGCb * 2048.0))&0x7fff)<<1;	dwOvGCr = (((int32)(OvGCr * 2048.0))&0x7fff)<<17;	dwOvBCb = (((int32)(OvBCb * 2048.0))&0x7fff)<<1;	dwOvBCr = (((int32)(OvBCr * 2048.0))&0x7fff)<<17;	OUTREG( regs, RADEON_OV0_LIN_TRANS_A, dwOvRCb | dwOvRY );	OUTREG( regs, RADEON_OV0_LIN_TRANS_B, dwOvROff | dwOvRCr );	OUTREG( regs, RADEON_OV0_LIN_TRANS_C, dwOvGCb | dwOvGY );	OUTREG( regs, RADEON_OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr );	OUTREG( regs, RADEON_OV0_LIN_TRANS_E, dwOvBCb | dwOvBY );	OUTREG( regs, RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr );		si->active_overlay.ob.space = si->pending_overlay.ob.space;}// convert Be colour key to rgb valuestatic uint32 colourKey2RGB32( 	uint32 space, uint8 red, uint8 green, uint8 blue ) {	uint32 res;		SHOW_FLOW0( 3, "" );		// the way Be defines colour keys may be convinient to some driver developers,	// but it's not well defined - took me some time to find out the format used	// and still I have no idea how alpha is defined; Rudolf told me that alpha is	// never used	switch( space ) {	case B_RGB15:		res = 			((uint32)(red >> 0) << (16+3)) | 			((uint32)(green >> 0) << (8+3)) | 			((blue >> 0) << 3);		break;	case B_RGB16:		res = 			((uint32)(red >> 0) << (16+3)) | 			((uint32)(green >> 0) << (8+2)) | 			((blue >> 0) << 3);		break;	case B_RGB32:	case B_CMAP8:		res = ((uint32)(red) << 16) | ((uint32)(green) << 8) | blue;		break;	default:		res = 0;	}		SHOW_FLOW( 3, "key=%lx", res );	return res;}// set colour key of overlaystatic void Radeon_SetColourKey( 	accelerator_info *ai, const overlay_window *ow ){	virtual_card *vc = ai->vc;	vuint8 *regs = ai->regs;	uint32 rgb32, mask32, min32, max32;		/*SHOW_FLOW( 0, "value=%02x %02x %02x, mask=%02x %02x %02x",		ow->red.value, ow->green.value, ow->blue.value,		ow->red.mask, ow->green.mask, ow->blue.mask );*/		// Radeons don't support value and mask as colour key but colour range	rgb32 = colourKey2RGB32( vc->mode.space, 		ow->red.value, ow->green.value, ow->blue.value );	mask32 = colourKey2RGB32( vc->mode.space,		ow->red.mask, ow->green.mask, ow->blue.mask );	// ~mask32 are all unimportant (usually low order) bits		// oring this to the colour should give us the highest valid colour value	// (add would be more precise but may lead to overflows)	min32 = rgb32;	max32 = rgb32 | ~mask32;		OUTREG( regs, RADEON_OV0_GRAPHICS_KEY_CLR_LOW, min32 );	OUTREG( regs, RADEON_OV0_GRAPHICS_KEY_CLR_HIGH, max32 );	OUTREG( regs, RADEON_OV0_KEY_CNTL, 		RADEON_GRAPHIC_KEY_FN_EQ |		RADEON_VIDEO_KEY_FN_FALSE |		RADEON_CMP_MIX_OR );}typedef struct {	uint max_scale;					// maximum src_width/dest_width, 									// i.e. source increment per screen pixel	uint8 group_size; 				// size of one filter group in pixels	uint8 p1_step_by, p23_step_by;	// > 0: log(source pixel increment)+1, 2-tap filter									// = 0: source pixel increment = 1, 4-tap filter} hscale_factor;#define count_of( a ) (sizeof( a ) / sizeof( a[0] ))// scaling/filter tables depending on overlay colour space:// magnifying pixels is no problem, but minifying can lead to overload,// so we have to skip pixels and/or use 2-tap filtersstatic hscale_factor scale_RGB16[] = {	{ (2 << 12), 		2, 1, 1 },	{ (4 << 12), 		2, 2, 2 },	{ (8 << 12), 		2, 3, 3 },	{ (16 << 12), 		2, 4, 4 },	{ (32 << 12), 		2, 5, 5 }};static hscale_factor scale_RGB32[] = {	{ (2 << 12) / 3,	2, 0, 0 },	{ (4 << 12) / 3,	4, 1, 1 },	{ (8 << 12) / 3,	4, 2, 2 },	{ (4 << 12), 		4, 2, 3 },	{ (16 << 12) / 3,	4, 3, 3 },	{ (8 << 12), 		4, 3, 4 },	{ (32 << 12) / 3,	4, 4, 4 },	{ (16 << 12),		4, 5, 5 }};static hscale_factor scale_YUV[] = {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -