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

📄 radeon_state.c

📁 ati driver
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 |				   (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( 0x0 );			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( 0x0 );			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( 0x0 );			ADVANCE_RING();		}	}	/* Increment the clear counter.  The client-side 3D driver must	 * wait on this value before performing the clear ioctl.  We	 * need this because the card's so damned fast...	 */	dev_priv->sarea_priv->last_clear++;	BEGIN_RING( 4 );	RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear );	RADEON_WAIT_UNTIL_IDLE();	ADVANCE_RING();}static void radeon_cp_dispatch_swap( drm_device_t *dev ){	drm_radeon_private_t *dev_priv = dev->dev_private;	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;	int nbox = sarea_priv->nbox;	drm_clip_rect_t *pbox = sarea_priv->boxes;	int i;	RING_LOCALS;	DRM_DEBUG( "\n" );	/* Do some trivial performance monitoring...	 */	if (dev_priv->do_boxes)		radeon_cp_performance_boxes( dev_priv );	/* Wait for the 3D stream to idle before dispatching the bitblt.	 * This will prevent data corruption between the two streams.	 */	BEGIN_RING( 2 );	RADEON_WAIT_UNTIL_3D_IDLE();	ADVANCE_RING();	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 swap %d,%d-%d,%d\n",			   x, y, w, h );		BEGIN_RING( 7 );		OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) );		OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL |			  RADEON_GMC_DST_PITCH_OFFSET_CNTL |			  RADEON_GMC_BRUSH_NONE |			  (dev_priv->color_fmt << 8) |			  RADEON_GMC_SRC_DATATYPE_COLOR |			  RADEON_ROP3_S |			  RADEON_DP_SRC_SOURCE_MEMORY |			  RADEON_GMC_CLR_CMP_CNTL_DIS |			  RADEON_GMC_WR_MSK_DIS );				/* Make this work even if front & back are flipped:		 */		if (dev_priv->current_page == 0) {			OUT_RING( dev_priv->back_pitch_offset );			OUT_RING( dev_priv->front_pitch_offset );		} 		else {			OUT_RING( dev_priv->front_pitch_offset );			OUT_RING( dev_priv->back_pitch_offset );		}		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( 4 );	RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );	RADEON_WAIT_UNTIL_2D_IDLE();	ADVANCE_RING();}static void radeon_cp_dispatch_flip( drm_device_t *dev ){	drm_radeon_private_t *dev_priv = dev->dev_private;	drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle;	int offset = (dev_priv->current_page == 1)		   ? dev_priv->front_offset : dev_priv->back_offset;	RING_LOCALS;	DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", 		__FUNCTION__, 		dev_priv->current_page,		dev_priv->sarea_priv->pfCurrentPage);	/* Do some trivial performance monitoring...	 */	if (dev_priv->do_boxes) {		dev_priv->stats.boxes |= RADEON_BOX_FLIP;		radeon_cp_performance_boxes( dev_priv );	}	/* Update the frame offsets for both CRTCs	 */	BEGIN_RING( 6 );	RADEON_WAIT_UNTIL_3D_IDLE();	OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch					      + sarea->frame.x 					      * ( dev_priv->color_fmt - 2 ) ) & ~7 )					  + offset );	OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base					   + offset );	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++;	dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =					      1 - dev_priv->current_page;	BEGIN_RING( 2 );	RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );	ADVANCE_RING();}static int bad_prim_vertex_nr( int primitive, int nr ){	switch (primitive & RADEON_PRIM_TYPE_MASK) {	case RADEON_PRIM_TYPE_NONE:	case RADEON_PRIM_TYPE_POINT:		return nr < 1;	case RADEON_PRIM_TYPE_LINE:		return (nr & 1) || nr == 0;	case RADEON_PRIM_TYPE_LINE_STRIP:		return nr < 2;	case RADEON_PRIM_TYPE_TRI_LIST:	case RADEON_PRIM_TYPE_3VRT_POINT_LIST:	case RADEON_PRIM_TYPE_3VRT_LINE_LIST:	case RADEON_PRIM_TYPE_RECT_LIST:		return nr % 3 || nr == 0;	case RADEON_PRIM_TYPE_TRI_FAN:	case RADEON_PRIM_TYPE_TRI_STRIP:		return nr < 3;	default:		return 1;	}	}typedef struct {	unsigned int start;	unsigned int finish;	unsigned int prim;	unsigned int numverts;	unsigned int offset;           unsigned int vc_format;} drm_radeon_tcl_prim_t;static void radeon_cp_dispatch_vertex( drm_device_t *dev,				       drm_buf_t *buf,				       drm_radeon_tcl_prim_t *prim,				       drm_clip_rect_t *boxes,				       int nbox ){	drm_radeon_private_t *dev_priv = dev->dev_private;	drm_clip_rect_t box;	int offset = dev_priv->agp_buffers_offset + buf->offset + prim->start;	int numverts = (int)prim->numverts;	int i = 0;	RING_LOCALS;	DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",		  prim->prim,		  prim->vc_format,		  prim->start,		  prim->finish,		  prim->numverts);	if (bad_prim_vertex_nr( prim->prim, prim->numverts )) {		DRM_ERROR( "bad prim %x numverts %d\n", 			   prim->prim, prim->numverts );		return;	}	do {		/* Emit the next cliprect */		if ( i < nbox ) {			if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))				return;			radeon_emit_clip_rect( dev_priv, &box );		}		/* Emit the vertex buffer rendering commands */		BEGIN_RING( 5 );		OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) );		OUT_RING( offset );		OUT_RING( numverts );		OUT_RING( prim->vc_format );		OUT_RING( prim->prim | RADEON_PRIM_WALK_LIST |			  RADEON_COLOR_ORDER_RGBA |			  RADEON_VTX_FMT_RADEON_MODE |			  (numverts << RADEON_NUM_VERTICES_SHIFT) );		ADVANCE_RING();		i++;	} while ( i < nbox );}static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf ){	drm_radeon_private_t *dev_priv = dev->dev_private;	drm_radeon_buf_priv_t *buf_priv = buf->dev_private;	RING_LOCALS;	buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;	/* Emit the vertex buffer age */	BEGIN_RING( 2 );	RADEON_DISPATCH_AGE( buf_priv->age );	ADVANCE_RING();	buf->pending = 1;	buf->used = 0;}static void radeon_cp_dispatch_indirect( drm_device_t *dev,					 drm_buf_t *buf,					 int start, int end ){	drm_radeon_private_t *dev_priv = dev->dev_private;	RING_LOCALS;	DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",		   buf->idx, start, end );	if ( start != end ) {		int offset = (dev_priv->agp_buffers_offset			      + 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 CP packet.		 */		if ( dwords & 1 ) {			u32 *data = (u32 *)				((char *)dev_priv->buffers->handle				 + buf->offset + start);			data[dwords++] = RADEON_CP_PACKET2;		}		/* Fire off the indirect buffer */		BEGIN_RING( 3 );		OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) );		OUT_RING( offset );		OUT_RING( dwords );		ADVANCE_RING();	}}static void radeon_cp_dispatch_indices( drm_device_t *dev,					drm_buf_t *elt_buf,					drm_radeon_tcl_prim_t *prim, 					drm_clip_rect_t *boxes,					int nbox ){	drm_radeon_private_t *dev_priv = dev->dev_private;	drm_clip_rect_t box;	int offset = dev_priv->agp_buffers_offset + prim->offset;	u32 *data;	int dwords;	int i = 0;	int start = prim->start + RADEON_INDEX_PRIM_OFFSET;	int count = (prim->finish - start) / sizeof(u16);	DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",		  prim->prim,		  prim->vc_format,		  prim->start,		  prim->finish,		  prim->offset,		  prim->numverts);	if (bad_prim_vertex_nr( prim->prim, count )) {		DRM_ERROR( "bad prim %x count %d\n", 			   prim->prim, count );		return;	}	if ( start >= prim->finish ||	     (prim->start & 0x7) ) {		DRM_ERROR( "buffer prim %d\n", prim->prim );		return;	}	dwords = (prim->finish - prim->start + 3) / sizeof(u32);	data = (u32 *)((char *)dev_priv->buffers->handle +		       elt_buf->offset + prim->start);	data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );	data[1] = offset;	data[2] = prim->numverts;	data[3] = prim->vc_format;	data[4] = (prim->prim |		   RADEON_PRIM_WALK_IND |		   RADEON_COLOR_ORDER_RGBA |		   RADEON_VTX_FMT_RADEON_MODE |		   (count << RADEON_NUM_VERTICES_SHIFT) );	do {		if ( i < nbox ) {			if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))				return;						radeon_emit_clip_rect( dev_priv, &box );		}		radeon_cp_dispatch_indirect( dev, elt_buf,					     prim->start,					     prim->finish );		i++;	} while ( i < nbox );}#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32))static int radeon_cp_dispatch_texture( drm_device_t *dev,				       drm_radeon_texture_t *tex,				       drm_radeon_tex_image_t *image ){	drm_radeon_private_t *dev_priv = dev->dev_private;	drm_buf_t *buf;	u32 format;	u32 *buffer;	const u8 *data;	int size, dwords, tex_width, blit_width;	u32 y, height;	int i;	RING_LOCALS;	dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD;	/* Flush the pixel cache.  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( 4 );	RADEON_FLUSH_CACHE();	RADEON_WAIT_UNTIL_IDLE();	ADVANCE_RING();#ifdef __BIG_ENDIAN	/* The Mesa texture functions provide the data in little endian as the	 * chip wants it, but we need to compensate for the fact that the CP	 * ring gets byte-swapped	 */	BEGIN_RING( 2 );	OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT );	ADVANCE_RING();#endif	/* 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.

⌨️ 快捷键说明

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