radeon_state.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 2,403 行 · 第 1/5 页

C
2,403
字号
/* New (1.3) state mechanism.  3 commands (packet, scalar, vector) in * 1.3 cmdbuffers allow all previous state to be updated as well as * the tcl scalar and vector areas.   */static struct { 	int start; 	int len; 	const char *name;} packet[RADEON_MAX_STATE_PACKETS] = {	{ RADEON_PP_MISC,7,"RADEON_PP_MISC" },	{ RADEON_PP_CNTL,3,"RADEON_PP_CNTL" },	{ RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" },	{ RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" },	{ RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" },	{ RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" },	{ RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" },	{ RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" },	{ RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" },	{ RADEON_SE_CNTL,2,"RADEON_SE_CNTL" },	{ RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" },	{ RADEON_RE_MISC,1,"RADEON_RE_MISC" },	{ RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" },	{ RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" },	{ RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" },	{ RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" },	{ RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" },	{ RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" },	{ RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" },	{ RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },	{ RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },	{ R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" },	{ R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" },	{ R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" },	{ R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" },	{ R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" },	{ R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" },	{ R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" },	{ R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" },	{ R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" },	{ R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" },	{ R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" },	{ R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" },	{ R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" },	{ R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" },	{ R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" },	{ R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" },	{ R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" },	{ R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" },	{ R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" },	{ R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" },	{ R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" },	{ R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" },	{ R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" },	{ R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" },	{ R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" },	{ R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" },	{ R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" },	{ R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" },	{ R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" },	{ R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" },	{ R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, 	{ R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, 	{ R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, 	{ R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, 	{ R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, 	{ R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, 	{ R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, 	{ R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, 	{ R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, 	{ R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },	{ R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */	{ R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */	{ R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" },	{ R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" },	{ R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" },	{ R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" },	{ R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" },	{ R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" },	{ R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" },	{ R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" },	{ R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" },	{ R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" },	{ RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" },	{ RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },	{ RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" },	{ R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" },};/* ================================================================ * Performance monitoring functions */static void radeon_clear_box( drm_radeon_private_t *dev_priv,			      int x, int y, int w, int h,			      int r, int g, int b ){	u32 color;	RING_LOCALS;	x += dev_priv->sarea_priv->boxes[0].x1;	y += dev_priv->sarea_priv->boxes[0].y1;	switch ( dev_priv->color_fmt ) {	case RADEON_COLOR_FORMAT_RGB565:		color = (((r & 0xf8) << 8) |			 ((g & 0xfc) << 3) |			 ((b & 0xf8) >> 3));		break;	case RADEON_COLOR_FORMAT_ARGB8888:	default:		color = (((0xff) << 24) | (r << 16) | (g <<  8) | b);		break;	}	BEGIN_RING( 4 );	RADEON_WAIT_UNTIL_3D_IDLE();			OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );	OUT_RING( 0xffffffff );	ADVANCE_RING();	BEGIN_RING( 6 );	OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );	OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |		  RADEON_GMC_BRUSH_SOLID_COLOR |		  (dev_priv->color_fmt << 8) |		  RADEON_GMC_SRC_DATATYPE_COLOR |		  RADEON_ROP3_P |		  RADEON_GMC_CLR_CMP_CNTL_DIS ); 	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { 		OUT_RING( dev_priv->front_pitch_offset ); 	} else {	 		OUT_RING( dev_priv->back_pitch_offset ); 	} 	OUT_RING( color );	OUT_RING( (x << 16) | y );	OUT_RING( (w << 16) | h );	ADVANCE_RING();}static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ){	/* Collapse various things into a wait flag -- trying to	 * guess if userspase slept -- better just to have them tell us.	 */	if (dev_priv->stats.last_frame_reads > 1 ||	    dev_priv->stats.last_clear_reads > dev_priv->stats.clears) {		dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;	}	if (dev_priv->stats.freelist_loops) {		dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;	}	/* Purple box for page flipping	 */	if ( dev_priv->stats.boxes & RADEON_BOX_FLIP ) 		radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 );	/* Red box if we have to wait for idle at any point	 */	if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE ) 		radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 );	/* Blue box: lost context?	 */	/* Yellow box for texture swaps	 */	if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD ) 		radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 );	/* Green box if hardware never idles (as far as we can tell)	 */	if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) ) 		radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );	/* Draw bars indicating number of buffers allocated 	 * (not a great measure, easily confused)	 */	if (dev_priv->stats.requested_bufs) {		if (dev_priv->stats.requested_bufs > 100)			dev_priv->stats.requested_bufs = 100;		radeon_clear_box( dev_priv, 4, 16,  				  dev_priv->stats.requested_bufs, 4,				  196, 128, 128 );	}	memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) );}/* ================================================================ * CP command dispatch functions */static void radeon_cp_dispatch_clear( drm_device_t *dev,				      drm_radeon_clear_t *clear,				      drm_radeon_clear_rect_t *depth_boxes ){	drm_radeon_private_t *dev_priv = dev->dev_private;	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;	drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear;	int nbox = sarea_priv->nbox;	drm_clip_rect_t *pbox = sarea_priv->boxes;	unsigned int flags = clear->flags;	u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0;	int i;	RING_LOCALS;	DRM_DEBUG( "flags = 0x%x\n", flags );	dev_priv->stats.clears++;	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {		unsigned int tmp = flags;		flags &= ~(RADEON_FRONT | RADEON_BACK);		if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK;		if ( tmp & RADEON_BACK )  flags |= RADEON_FRONT;	}	if ( flags & (RADEON_FRONT | RADEON_BACK) ) {		BEGIN_RING( 4 );		/* Ensure the 3D stream is idle before doing a		 * 2D fill to clear the front or back buffer.		 */		RADEON_WAIT_UNTIL_3D_IDLE();				OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );		OUT_RING( clear->color_mask );		ADVANCE_RING();		/* Make sure we restore the 3D state next time.		 */		dev_priv->sarea_priv->ctx_owner = 0;		for ( i = 0 ; i < nbox ; i++ ) {			int x = pbox[i].x1;			int y = pbox[i].y1;			int w = pbox[i].x2 - x;			int h = pbox[i].y2 - y;			DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",				   x, y, w, h, flags );			if ( flags & RADEON_FRONT ) {				BEGIN_RING( 6 );								OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );				OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |					  RADEON_GMC_BRUSH_SOLID_COLOR |					  (dev_priv->color_fmt << 8) |					  RADEON_GMC_SRC_DATATYPE_COLOR |					  RADEON_ROP3_P |					  RADEON_GMC_CLR_CMP_CNTL_DIS );				OUT_RING( dev_priv->front_pitch_offset );				OUT_RING( clear->clear_color );								OUT_RING( (x << 16) | y );				OUT_RING( (w << 16) | h );								ADVANCE_RING();			}						if ( flags & RADEON_BACK ) {				BEGIN_RING( 6 );								OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );				OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |					  RADEON_GMC_BRUSH_SOLID_COLOR |					  (dev_priv->color_fmt << 8) |					  RADEON_GMC_SRC_DATATYPE_COLOR |					  RADEON_ROP3_P |					  RADEON_GMC_CLR_CMP_CNTL_DIS );								OUT_RING( dev_priv->back_pitch_offset );				OUT_RING( clear->clear_color );				OUT_RING( (x << 16) | y );				OUT_RING( (w << 16) | h );				ADVANCE_RING();			}		}	}	/* We have to clear the depth and/or stencil buffers by	 * rendering a quad into just those buffers.  Thus, we have to	 * make sure the 3D engine is configured correctly.	 */	if ( dev_priv->is_r200 &&	     (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) {		int tempPP_CNTL;		int tempRE_CNTL;		int tempRB3D_CNTL;		int tempRB3D_ZSTENCILCNTL;		int tempRB3D_STENCILREFMASK;		int tempRB3D_PLANEMASK;		int tempSE_CNTL;		int tempSE_VTE_CNTL;		int tempSE_VTX_FMT_0;		int tempSE_VTX_FMT_1;		int tempSE_VAP_CNTL;		int tempRE_AUX_SCISSOR_CNTL;		tempPP_CNTL = 0;		tempRE_CNTL = 0;		tempRB3D_CNTL = depth_clear->rb3d_cntl;		tempRB3D_CNTL &= ~(1<<15); /* unset radeon magic flag */		tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;		tempRB3D_STENCILREFMASK = 0x0;		tempSE_CNTL = depth_clear->se_cntl;		/* Disable TCL */		tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK |  */				   (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));		tempRB3D_PLANEMASK = 0x0;		tempRE_AUX_SCISSOR_CNTL = 0x0;		tempSE_VTE_CNTL =			SE_VTE_CNTL__VTX_XY_FMT_MASK |			SE_VTE_CNTL__VTX_Z_FMT_MASK;		/* Vertex format (X, Y, Z, W)*/		tempSE_VTX_FMT_0 =			SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |			SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;		tempSE_VTX_FMT_1 = 0x0;		/* 		 * Depth buffer specific enables 		 */		if (flags & RADEON_DEPTH) {			/* Enable depth buffer */			tempRB3D_CNTL |= RADEON_Z_ENABLE;		} else {			/* Disable depth buffer */			tempRB3D_CNTL &= ~RADEON_Z_ENABLE;		}		/* 		 * Stencil buffer specific enables		 */		if ( flags & RADEON_STENCIL ) {			tempRB3D_CNTL |=  RADEON_STENCIL_ENABLE;			tempRB3D_STENCILREFMASK = clear->depth_mask; 		} else {			tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE;			tempRB3D_STENCILREFMASK = 0x00000000;		}		BEGIN_RING( 26 );		RADEON_WAIT_UNTIL_2D_IDLE();		OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL );		OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL );		OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL );		OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL,			      tempRB3D_ZSTENCILCNTL );		OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, 			      tempRB3D_STENCILREFMASK );		OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK );		OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL );		OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL );		OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 );		OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 );		OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL );		OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL, 			      tempRE_AUX_SCISSOR_CNTL );		ADVANCE_RING();		/* Make sure we restore the 3D state next time.		 */		dev_priv->sarea_priv->ctx_owner = 0;		for ( i = 0 ; i < nbox ; i++ ) {						/* Funny that this should be required -- 			 *  sets top-left?			 */			radeon_emit_clip_rect( dev_priv,					       &sarea_priv->boxes[i] );			BEGIN_RING( 14 );			OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) );			OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |				   RADEON_PRIM_WALK_RING |				   (3 << RADEON_NUM_VERTICES_SHIFT)) );			OUT_RING( depth_boxes[i].ui[CLEAR_X1] );			OUT_RING( depth_boxes[i].ui[CLEAR_Y1] );			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );			OUT_RING( 0x3f800000 );			OUT_RING( depth_boxes[i].ui[CLEAR_X1] );			OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );			OUT_RING( 0x3f800000 );			OUT_RING( depth_boxes[i].ui[CLEAR_X2] );			OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );			OUT_RING( 0x3f800000 );			ADVANCE_RING();		}	} 	else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) {		rb3d_cntl = depth_clear->rb3d_cntl;		if ( flags & RADEON_DEPTH ) {			rb3d_cntl |=  RADEON_Z_ENABLE;		} else {			rb3d_cntl &= ~RADEON_Z_ENABLE;		}		if ( flags & RADEON_STENCIL ) {			rb3d_cntl |=  RADEON_STENCIL_ENABLE;			rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */		} else {			rb3d_cntl &= ~RADEON_STENCIL_ENABLE;			rb3d_stencilrefmask = 0x00000000;		}		BEGIN_RING( 13 );		RADEON_WAIT_UNTIL_2D_IDLE();		OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) );		OUT_RING( 0x00000000 );		OUT_RING( rb3d_cntl );				OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL,			      depth_clear->rb3d_zstencilcntl );		OUT_RING_REG( RADEON_RB3D_STENCILREFMASK,			      rb3d_stencilrefmask );		OUT_RING_REG( RADEON_RB3D_PLANEMASK,			      0x00000000 );		OUT_RING_REG( RADEON_SE_CNTL,			      depth_clear->se_cntl );		ADVANCE_RING();		/* Make sure we restore the 3D state next time.		 */		dev_priv->sarea_priv->ctx_owner = 0;		for ( i = 0 ; i < nbox ; i++ ) {						/* Funny that this should be required -- 			 *  sets top-left?			 */			radeon_emit_clip_rect( dev_priv,					       &sarea_priv->boxes[i] );			BEGIN_RING( 15 );			OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) );			OUT_RING( RADEON_VTX_Z_PRESENT |				  RADEON_VTX_PKCOLOR_PRESENT);			OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |				   RADEON_PRIM_WALK_RING |				   RADEON_MAOS_ENABLE |				   RADEON_VTX_FMT_RADEON_MODE |

⌨️ 快捷键说明

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