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

📄 i830_dma.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
			j++;		} else {			DRM_ERROR("Skipping %d\n", i);		}	}	OUT_RING( STATE3D_CONST_BLEND_COLOR_CMD ); 	OUT_RING( code[I830_CTXREG_BLENDCOLR] ); 	j += 2;	for ( i = I830_CTXREG_VF ; i < I830_CTXREG_MCSB0 ; i++ ) {		tmp = code[i];		if ((tmp & (7<<29)) == CMD_3D &&		    (tmp & (0x1f<<24)) < (0x1d<<24)) {			OUT_RING( tmp ); 			j++;		} else {			DRM_ERROR("Skipping %d\n", i);		}	}	OUT_RING( STATE3D_MAP_COORD_SETBIND_CMD ); 	OUT_RING( code[I830_CTXREG_MCSB1] ); 	j += 2;	if (j & 1) 		OUT_RING( 0 ); 	ADVANCE_LP_RING();}static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code ) {   	drm_i830_private_t *dev_priv = dev->dev_private;	int i, j = 0;	unsigned int tmp;	RING_LOCALS;	if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO ||	    (code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) == 	    (STATE3D_LOAD_STATE_IMMEDIATE_2|4)) {		BEGIN_LP_RING( I830_TEX_SETUP_SIZE );		OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */		OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */		OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */		OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */		OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */		OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */				for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {			tmp = code[i];			OUT_RING( tmp ); 			j++;		} 		if (j & 1) 			OUT_RING( 0 ); 		ADVANCE_LP_RING();	}	else		printk("rejected packet %x\n", code[0]);}static void i830EmitTexBlendVerified( drm_device_t *dev, 				      unsigned int *code,				      unsigned int num){   	drm_i830_private_t *dev_priv = dev->dev_private;	int i, j = 0;	unsigned int tmp;	RING_LOCALS;	if (!num)		return;	BEGIN_LP_RING( num + 1 );	for ( i = 0 ; i < num ; i++ ) {		tmp = code[i];		OUT_RING( tmp );		j++;	}	if (j & 1) 		OUT_RING( 0 ); 	ADVANCE_LP_RING();}static void i830EmitTexPalette( drm_device_t *dev,			        unsigned int *palette,			        int number,			        int is_shared ){   	drm_i830_private_t *dev_priv = dev->dev_private;	int i;	RING_LOCALS;	return;	BEGIN_LP_RING( 258 );	if(is_shared == 1) {		OUT_RING(CMD_OP_MAP_PALETTE_LOAD |			 MAP_PALETTE_NUM(0) |			 MAP_PALETTE_BOTH);	} else {		OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number));	}	for(i = 0; i < 256; i++) {		OUT_RING(palette[i]);	}	OUT_RING(0);	/* KW:  WHERE IS THE ADVANCE_LP_RING?  This is effectively a noop! 	 */}/* Need to do some additional checking when setting the dest buffer. */static void i830EmitDestVerified( drm_device_t *dev, 				  unsigned int *code ) {	   	drm_i830_private_t *dev_priv = dev->dev_private;	unsigned int tmp;	RING_LOCALS;	BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 );	tmp = code[I830_DESTREG_CBUFADDR];	if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {		if (((int)outring) & 8) {			OUT_RING(0);			OUT_RING(0);		}		OUT_RING( CMD_OP_DESTBUFFER_INFO );		OUT_RING( BUF_3D_ID_COLOR_BACK | 			  BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |			  BUF_3D_USE_FENCE);		OUT_RING( tmp );		OUT_RING( 0 );		OUT_RING( CMD_OP_DESTBUFFER_INFO );		OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | 			  BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));		OUT_RING( dev_priv->zi1 );		OUT_RING( 0 );	} else {		DRM_ERROR("bad di1 %x (allow %x or %x)\n",			  tmp, dev_priv->front_di1, dev_priv->back_di1);	}	/* invarient:	 */	OUT_RING( GFX_OP_DESTBUFFER_VARS );	OUT_RING( code[I830_DESTREG_DV1] );	OUT_RING( GFX_OP_DRAWRECT_INFO );	OUT_RING( code[I830_DESTREG_DR1] );	OUT_RING( code[I830_DESTREG_DR2] );	OUT_RING( code[I830_DESTREG_DR3] );	OUT_RING( code[I830_DESTREG_DR4] );	/* Need to verify this */	tmp = code[I830_DESTREG_SENABLE];	if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) {		OUT_RING( tmp );	} else {		DRM_ERROR("bad scissor enable\n");		OUT_RING( 0 );	}	OUT_RING( GFX_OP_SCISSOR_RECT );	OUT_RING( code[I830_DESTREG_SR1] );	OUT_RING( code[I830_DESTREG_SR2] );	OUT_RING( 0 );	ADVANCE_LP_RING();}static void i830EmitStippleVerified( drm_device_t *dev, 				     unsigned int *code ) {   	drm_i830_private_t *dev_priv = dev->dev_private;	RING_LOCALS;	BEGIN_LP_RING( 2 );	OUT_RING( GFX_OP_STIPPLE );	OUT_RING( code[1] );	ADVANCE_LP_RING();	}static void i830EmitState( drm_device_t *dev ){   	drm_i830_private_t *dev_priv = dev->dev_private;      	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;	unsigned int dirty = sarea_priv->dirty;	DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);	if (dirty & I830_UPLOAD_BUFFERS) {		i830EmitDestVerified( dev, sarea_priv->BufferState );		sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS;	}	if (dirty & I830_UPLOAD_CTX) {		i830EmitContextVerified( dev, sarea_priv->ContextState );		sarea_priv->dirty &= ~I830_UPLOAD_CTX;	}	if (dirty & I830_UPLOAD_TEX0) {		i830EmitTexVerified( dev, sarea_priv->TexState[0] );		sarea_priv->dirty &= ~I830_UPLOAD_TEX0;	}	if (dirty & I830_UPLOAD_TEX1) {		i830EmitTexVerified( dev, sarea_priv->TexState[1] );		sarea_priv->dirty &= ~I830_UPLOAD_TEX1;	}	if (dirty & I830_UPLOAD_TEXBLEND0) {		i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[0],				sarea_priv->TexBlendStateWordsUsed[0]);		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0;	}	if (dirty & I830_UPLOAD_TEXBLEND1) {		i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[1],				sarea_priv->TexBlendStateWordsUsed[1]);		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1;	}	if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {		i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1);	} else {		if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {			i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0);			sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0);		}		if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {			i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0);			sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1);		}		/* 1.3:		 */#if 0		if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) {			i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0);			sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);		}		if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) {			i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0);			sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);		}#endif	}	/* 1.3:	 */	if (dirty & I830_UPLOAD_STIPPLE) {		i830EmitStippleVerified( dev, 					 sarea_priv->StippleState);		sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE;	}	if (dirty & I830_UPLOAD_TEX2) {		i830EmitTexVerified( dev, sarea_priv->TexState2 );		sarea_priv->dirty &= ~I830_UPLOAD_TEX2;	}	if (dirty & I830_UPLOAD_TEX3) {		i830EmitTexVerified( dev, sarea_priv->TexState3 );		sarea_priv->dirty &= ~I830_UPLOAD_TEX3;	}	if (dirty & I830_UPLOAD_TEXBLEND2) {		i830EmitTexBlendVerified( 			dev, 			sarea_priv->TexBlendState2,			sarea_priv->TexBlendStateWordsUsed2);		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2;	}	if (dirty & I830_UPLOAD_TEXBLEND3) {		i830EmitTexBlendVerified( 			dev, 			sarea_priv->TexBlendState3,			sarea_priv->TexBlendStateWordsUsed3);		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3;	}}/* ================================================================ * Performance monitoring functions */static void i830_fill_box( drm_device_t *dev,			   int x, int y, int w, int h,			   int r, int g, int b ){   	drm_i830_private_t *dev_priv = dev->dev_private;	u32 color;	unsigned int BR13, CMD;	RING_LOCALS;	BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24);	CMD = XY_COLOR_BLT_CMD;	x += dev_priv->sarea_priv->boxes[0].x1;	y += dev_priv->sarea_priv->boxes[0].y1;	if (dev_priv->cpp == 4) {		BR13 |= (1<<25);		CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);		color = (((0xff) << 24) | (r << 16) | (g <<  8) | b);		} else {		color = (((r & 0xf8) << 8) |			 ((g & 0xfc) << 3) |			 ((b & 0xf8) >> 3));	}	BEGIN_LP_RING( 6 );	    	OUT_RING( CMD );	OUT_RING( BR13 );	OUT_RING( (y << 16) | x );	OUT_RING( ((y+h) << 16) | (x+w) ); 	if ( dev_priv->current_page == 1 ) { 		OUT_RING( dev_priv->front_offset ); 	} else {	 		OUT_RING( dev_priv->back_offset ); 	} 	OUT_RING( color );	ADVANCE_LP_RING();}static void i830_cp_performance_boxes( drm_device_t *dev ){   	drm_i830_private_t *dev_priv = dev->dev_private;	/* Purple box for page flipping	 */	if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP ) 		i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 );	/* Red box if we have to wait for idle at any point	 */	if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT ) 		i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 );	/* Blue box: lost context?	 */	if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT ) 		i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 );	/* Yellow box for texture swaps	 */	if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD ) 		i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 );	/* Green box if hardware never idles (as far as we can tell)	 */	if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) ) 		i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 );	/* Draw bars indicating number of buffers allocated 	 * (not a great measure, easily confused)	 */	if (dev_priv->dma_used) {		int bar = dev_priv->dma_used / 10240;		if (bar > 100) bar = 100;		if (bar < 1) bar = 1;		i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 );		dev_priv->dma_used = 0;	}	dev_priv->sarea_priv->perf_boxes = 0;}static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, 				    unsigned int clear_color,				    unsigned int clear_zval,				    unsigned int clear_depthmask){   	drm_i830_private_t *dev_priv = dev->dev_private;      	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;	int nbox = sarea_priv->nbox;	drm_clip_rect_t *pbox = sarea_priv->boxes;	int pitch = dev_priv->pitch;	int cpp = dev_priv->cpp;	int i;	unsigned int BR13, CMD, D_CMD;	RING_LOCALS;	if ( dev_priv->current_page == 1 ) {		unsigned int tmp = flags;		flags &= ~(I830_FRONT | I830_BACK);		if ( tmp & I830_FRONT ) flags |= I830_BACK;		if ( tmp & I830_BACK )  flags |= I830_FRONT;	}  	i830_kernel_lost_context(dev);	switch(cpp) {	case 2: 		BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);		D_CMD = CMD = XY_COLOR_BLT_CMD;		break;	case 4:		BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);		CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | 		       XY_COLOR_BLT_WRITE_RGB);		D_CMD = XY_COLOR_BLT_CMD;		if(clear_depthmask & 0x00ffffff)			D_CMD |= XY_COLOR_BLT_WRITE_RGB;		if(clear_depthmask & 0xff000000)			D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;		break;	default:		BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);		D_CMD = CMD = XY_COLOR_BLT_CMD;		break;	}      	if (nbox > I830_NR_SAREA_CLIPRECTS)     		nbox = I830_NR_SAREA_CLIPRECTS;	for (i = 0 ; i < nbox ; i++, pbox++) {		if (pbox->x1 > pbox->x2 ||		    pbox->y1 > pbox->y2 ||		    pbox->x2 > dev_priv->w ||		    pbox->y2 > dev_priv->h)			continue;	   	if ( flags & I830_FRONT ) {	    		   	DRM_DEBUG("clear front\n");			BEGIN_LP_RING( 6 );	    			OUT_RING( CMD );			OUT_RING( BR13 );			OUT_RING( (pbox->y1 << 16) | pbox->x1 );			OUT_RING( (pbox->y2 << 16) | pbox->x2 );			OUT_RING( dev_priv->front_offset );			OUT_RING( clear_color );			ADVANCE_LP_RING();		}		if ( flags & I830_BACK ) {			DRM_DEBUG("clear back\n");			BEGIN_LP_RING( 6 );	    			OUT_RING( CMD );			OUT_RING( BR13 );			OUT_RING( (pbox->y1 << 16) | pbox->x1 );			OUT_RING( (pbox->y2 << 16) | pbox->x2 );			OUT_RING( dev_priv->back_offset );			OUT_RING( clear_color );			ADVANCE_LP_RING();		}		if ( flags & I830_DEPTH ) {			DRM_DEBUG("clear depth\n");			BEGIN_LP_RING( 6 );			OUT_RING( D_CMD );			OUT_RING( BR13 );			OUT_RING( (pbox->y1 << 16) | pbox->x1 );			OUT_RING( (pbox->y2 << 16) | pbox->x2 );			OUT_RING( dev_priv->depth_offset );			OUT_RING( clear_zval );			ADVANCE_LP_RING();		}	}}static void i830_dma_dispatch_swap( drm_device_t *dev ){   	drm_i830_private_t *dev_priv = dev->dev_private;      	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;	int nbox = sarea_priv->nbox;	drm_clip_rect_t *pbox = sarea_priv->boxes;	int pitch = dev_priv->pitch;	int cpp = dev_priv->cpp;	int i;	unsigned int CMD, BR13;	RING_LOCALS;	DRM_DEBUG("swapbuffers\n");  	i830_kernel_lost_context(dev);	if (dev_priv->do_boxes)		i830_cp_performance_boxes( dev );	switch(cpp) {	case 2: 		BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);		CMD = XY_SRC_COPY_BLT_CMD;		break;	case 4:		BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25);		CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |		       XY_SRC_COPY_BLT_WRITE_RGB);		break;	default:		BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);		CMD = XY_SRC_COPY_BLT_CMD;		break;	}      	if (nbox > I830_NR_SAREA_CLIPRECTS)     		nbox = I830_NR_SAREA_CLIPRECTS;	for (i = 0 ; i < nbox; i++, pbox++) 	{		if (pbox->x1 > pbox->x2 ||		    pbox->y1 > pbox->y2 ||		    pbox->x2 > dev_priv->w ||		    pbox->y2 > dev_priv->h)			continue; 		DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",

⌨️ 快捷键说明

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