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

📄 r128_state.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 3 页
字号:
		OUT_RING( (x << 16) | y );		OUT_RING( (x << 16) | y );		OUT_RING( (w << 16) | h );		ADVANCE_RING();	}	/* Increment the frame counter.  The client-side 3D driver must	 * throttle the framerate by waiting for this value before	 * performing the swapbuffer ioctl.	 */	dev_priv->sarea_priv->last_frame++;	BEGIN_RING( 2 );	OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );	OUT_RING( dev_priv->sarea_priv->last_frame );	ADVANCE_RING();}static void r128_cce_dispatch_vertex( drm_device_t *dev,				      drm_buf_t *buf ){	drm_r128_private_t *dev_priv = dev->dev_private;	drm_r128_buf_priv_t *buf_priv = buf->dev_private;	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;	int format = sarea_priv->vc_format;	int offset = dev_priv->buffers->offset + buf->offset - dev->agp->base;	int size = buf->used;	int prim = buf_priv->prim;	int i = 0;	RING_LOCALS;	DRM_DEBUG( "%s: buf=%d nbox=%d\n",		   __FUNCTION__, buf->idx, sarea_priv->nbox );	r128_update_ring_snapshot( dev_priv );	if ( 0 )		r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );	if ( buf->used ) {		buf_priv->dispatched = 1;		if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {			r128_emit_state( dev_priv );		}		do {			/* Emit the next set of up to three cliprects */			if ( i < sarea_priv->nbox ) {				r128_emit_clip_rects( dev_priv,						      &sarea_priv->boxes[i],						      sarea_priv->nbox - i );			}			/* Emit the vertex buffer rendering commands */			BEGIN_RING( 5 );			OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 3 ) );			OUT_RING( offset );			OUT_RING( size );			OUT_RING( format );			OUT_RING( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |				  (size << R128_CCE_VC_CNTL_NUM_SHIFT) );			ADVANCE_RING();			i += 3;		} while ( i < sarea_priv->nbox );	}	if ( buf_priv->discard ) {		buf_priv->age = dev_priv->sarea_priv->last_dispatch;		/* Emit the vertex buffer age */		BEGIN_RING( 2 );		OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );		OUT_RING( buf_priv->age );		ADVANCE_RING();		buf->pending = 1;		buf->used = 0;		/* FIXME: Check dispatched field */		buf_priv->dispatched = 0;	}	dev_priv->sarea_priv->last_dispatch++;#if 0	if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {		ret = r128_do_cce_idle( dev_priv );		if ( ret < 0 ) return ret;		dev_priv->submit_age = 0;		r128_freelist_reset( dev );	}#endif	sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;	sarea_priv->nbox = 0;}static void r128_cce_dispatch_indirect( drm_device_t *dev,					drm_buf_t *buf,					int start, int end ){	drm_r128_private_t *dev_priv = dev->dev_private;	drm_r128_buf_priv_t *buf_priv = buf->dev_private;	RING_LOCALS;	DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",		   buf->idx, start, end );	r128_update_ring_snapshot( dev_priv );	if ( start != end ) {		int offset = (dev_priv->buffers->offset - dev->agp->base			      + buf->offset + start);		int dwords = (end - start + 3) / sizeof(u32);		/* Indirect buffer data must be an even number of		 * dwords, so if we've been given an odd number we must		 * pad the data with a Type-2 CCE packet.		 */		if ( dwords & 1 ) {			u32 *data = (u32 *)				((char *)dev_priv->buffers->handle				 + buf->offset + start);			data[dwords++] = R128_CCE_PACKET2;		}		buf_priv->dispatched = 1;		/* Fire off the indirect buffer */		BEGIN_RING( 3 );		OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) );		OUT_RING( offset );		OUT_RING( dwords );		ADVANCE_RING();	}	if ( buf_priv->discard ) {		buf_priv->age = dev_priv->sarea_priv->last_dispatch;		/* Emit the indirect buffer age */		BEGIN_RING( 2 );		OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );		OUT_RING( buf_priv->age );		ADVANCE_RING();		buf->pending = 1;		buf->used = 0;		/* FIXME: Check dispatched field */		buf_priv->dispatched = 0;	}	dev_priv->sarea_priv->last_dispatch++;#if 0	if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {		ret = r128_do_cce_idle( dev_priv );		if ( ret < 0 ) return ret;		dev_priv->submit_age = 0;		r128_freelist_reset( dev );	}#endif}static void r128_cce_dispatch_indices( drm_device_t *dev,				       drm_buf_t *buf,				       int start, int end,				       int count ){	drm_r128_private_t *dev_priv = dev->dev_private;	drm_r128_buf_priv_t *buf_priv = buf->dev_private;	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;	int format = sarea_priv->vc_format;	int offset = dev_priv->buffers->offset - dev->agp->base;	int prim = buf_priv->prim;	u32 *data;	int dwords;	int i = 0;	RING_LOCALS;	DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );	r128_update_ring_snapshot( dev_priv );	if ( 0 )		r128_print_dirty( "dispatch_indices", sarea_priv->dirty );	if ( start != end ) {		buf_priv->dispatched = 1;		if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {			r128_emit_state( dev_priv );		}		dwords = (end - start + 3) / sizeof(u32);		data = (u32 *)((char *)dev_priv->buffers->handle			       + buf->offset + start);		data[0] = CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, dwords-2 );		data[1] = offset;		data[2] = R128_MAX_VB_VERTS;		data[3] = format;		data[4] = (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |			   (count << 16));		if ( count & 0x1 ) {			data[dwords-1] &= 0x0000ffff;		}		do {			/* Emit the next set of up to three cliprects */			if ( i < sarea_priv->nbox ) {				r128_emit_clip_rects( dev_priv,						      &sarea_priv->boxes[i],						      sarea_priv->nbox - i );			}			r128_cce_dispatch_indirect( dev, buf, start, end );			i += 3;		} while ( i < sarea_priv->nbox );	}	if ( buf_priv->discard ) {		buf_priv->age = dev_priv->sarea_priv->last_dispatch;		/* Emit the vertex buffer age */		BEGIN_RING( 2 );		OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );		OUT_RING( buf_priv->age );		ADVANCE_RING();		buf->pending = 1;		/* FIXME: Check dispatched field */		buf_priv->dispatched = 0;	}	dev_priv->sarea_priv->last_dispatch++;#if 0	if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {		ret = r128_do_cce_idle( dev_priv );		if ( ret < 0 ) return ret;		dev_priv->submit_age = 0;		r128_freelist_reset( dev );	}#endif	sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;	sarea_priv->nbox = 0;}static int r128_cce_dispatch_blit( drm_device_t *dev,				   drm_r128_blit_t *blit ){	drm_r128_private_t *dev_priv = dev->dev_private;	drm_device_dma_t *dma = dev->dma;	drm_buf_t *buf;	drm_r128_buf_priv_t *buf_priv;	u32 *data;	int dword_shift, dwords;	RING_LOCALS;	DRM_DEBUG( "%s\n", __FUNCTION__ );	r128_update_ring_snapshot( dev_priv );	/* The compiler won't optimize away a division by a variable,	 * even if the only legal values are powers of two.  Thus, we'll	 * use a shift instead.	 */	switch ( blit->format ) {	case R128_DATATYPE_ARGB1555:	case R128_DATATYPE_RGB565:	case R128_DATATYPE_ARGB4444:		dword_shift = 1;		break;	case R128_DATATYPE_ARGB8888:		dword_shift = 0;		break;	default:		DRM_ERROR( "invalid blit format %d\n", blit->format );		return -EINVAL;	}	/* Flush the pixel cache, and mark the contents as Read Invalid.	 * This ensures no pixel data gets mixed up with the texture	 * data from the host data blit, otherwise part of the texture	 * image may be corrupted.	 */	BEGIN_RING( 2 );	OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );	OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI );	ADVANCE_RING();	/* Dispatch the indirect buffer.	 */	buf = dma->buflist[blit->idx];	buf_priv = buf->dev_private;	if ( buf->pid != current->pid ) {		DRM_ERROR( "process %d using buffer owned by %d\n",			   current->pid, buf->pid );		return -EINVAL;	}	if ( buf->pending ) {		DRM_ERROR( "sending pending buffer %d\n", blit->idx );		return -EINVAL;	}	buf_priv->discard = 1;	dwords = (blit->width * blit->height) >> dword_shift;	data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);	data[0] = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 );	data[1] = ( R128_GMC_DST_PITCH_OFFSET_CNTL		    | R128_GMC_BRUSH_NONE		    | (blit->format << 8)		    | R128_GMC_SRC_DATATYPE_COLOR		    | R128_ROP3_S		    | R128_DP_SRC_SOURCE_HOST_DATA		    | R128_GMC_CLR_CMP_CNTL_DIS		    | R128_GMC_AUX_CLIP_DIS		    | R128_GMC_WR_MSK_DIS );	data[2] = (blit->pitch << 21) | (blit->offset >> 5);	data[3] = 0xffffffff;	data[4] = 0xffffffff;	data[5] = (blit->y << 16) | blit->x;	data[6] = (blit->height << 16) | blit->width;	data[7] = dwords;	buf->used = (dwords + 8) * sizeof(u32);	r128_cce_dispatch_indirect( dev, buf, 0, buf->used );	/* Flush the pixel cache after the blit completes.  This ensures	 * the texture data is written out to memory before rendering	 * continues.	 */	BEGIN_RING( 2 );	OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );	OUT_RING( R128_PC_FLUSH_GUI );	ADVANCE_RING();	return 0;}/* ================================================================ * Tiled depth buffer management * * FIXME: These should all set the destination write mask for when we * have hardware stencil support. */static int r128_cce_dispatch_write_span( drm_device_t *dev,					 drm_r128_depth_t *depth ){	drm_r128_private_t *dev_priv = dev->dev_private;	int count, x, y;	u32 *buffer;	u8 *mask;	u32 depth_bpp;	int i;	RING_LOCALS;	DRM_DEBUG( "%s\n", __FUNCTION__ );	r128_update_ring_snapshot( dev_priv );	switch ( dev_priv->depth_bpp ) {	case 16:		depth_bpp = R128_GMC_DST_16BPP;		break;	case 24:	case 32:		depth_bpp = R128_GMC_DST_32BPP;		break;	default:		return -EINVAL;	}	count = depth->n;	if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {		return -EFAULT;	}	if ( copy_from_user( &y, depth->y, sizeof(y) ) ) {		return -EFAULT;	}	buffer = kmalloc( depth->n * sizeof(u32), 0 );	if ( buffer == NULL )		return -ENOMEM;	if ( copy_from_user( buffer, depth->buffer,			     depth->n * sizeof(u32) ) ) {		kfree( buffer );		return -EFAULT;	}	if ( depth->mask ) {		mask = kmalloc( depth->n * sizeof(u8), 0 );		if ( mask == NULL ) {			kfree( buffer );			return -ENOMEM;		}		if ( copy_from_user( mask, depth->mask,				     depth->n * sizeof(u8) ) ) {			kfree( buffer );			kfree( mask );			return -EFAULT;		}		for ( i = 0 ; i < count ; i++, x++ ) {			if ( mask[i] ) {				BEGIN_RING( 6 );				OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,						       4 ) );				OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL					  | R128_GMC_BRUSH_SOLID_COLOR					  | depth_bpp					  | R128_GMC_SRC_DATATYPE_COLOR					  | R128_ROP3_P					  | R128_GMC_CLR_CMP_CNTL_DIS					  | R128_GMC_WR_MSK_DIS );				OUT_RING( dev_priv->depth_pitch_offset_c );				OUT_RING( buffer[i] );				OUT_RING( (x << 16) | y );				OUT_RING( (1 << 16) | 1 );				ADVANCE_RING();			}		}		kfree( mask );	} else {		for ( i = 0 ; i < count ; i++, x++ ) {			BEGIN_RING( 6 );			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL				  | R128_GMC_BRUSH_SOLID_COLOR				  | depth_bpp				  | R128_GMC_SRC_DATATYPE_COLOR				  | R128_ROP3_P				  | R128_GMC_CLR_CMP_CNTL_DIS				  | R128_GMC_WR_MSK_DIS );			OUT_RING( dev_priv->depth_pitch_offset_c );			OUT_RING( buffer[i] );			OUT_RING( (x << 16) | y );			OUT_RING( (1 << 16) | 1 );			ADVANCE_RING();		}	}	kfree( buffer );	return 0;}static int r128_cce_dispatch_write_pixels( drm_device_t *dev,					   drm_r128_depth_t *depth ){	drm_r128_private_t *dev_priv = dev->dev_private;	int count, *x, *y;	u32 *buffer;	u8 *mask;	u32 depth_bpp;	int i;	RING_LOCALS;	DRM_DEBUG( "%s\n", __FUNCTION__ );	r128_update_ring_snapshot( dev_priv );	switch ( dev_priv->depth_bpp ) {	case 16:		depth_bpp = R128_GMC_DST_16BPP;		break;	case 24:	case 32:		depth_bpp = R128_GMC_DST_32BPP;		break;	default:		return -EINVAL;	}	count = depth->n;	x = kmalloc( count * sizeof(*x), 0 );	if ( x == NULL ) {		return -ENOMEM;	}	y = kmalloc( count * sizeof(*y), 0 );	if ( y == NULL ) {		kfree( x );		return -ENOMEM;	}	if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) {		kfree( x );		kfree( y );		return -EFAULT;	}	if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) {		kfree( x );		kfree( y );		return -EFAULT;	}	buffer = kmalloc( depth->n * sizeof(u32), 0 );	if ( buffer == NULL ) {

⌨️ 快捷键说明

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