radeon_state.c

来自「linux 内核源代码」· C语言 代码 · 共 2,223 行 · 第 1/5 页

C
2,223
字号
			     drm_radeon_context_regs_t * ctx,			     drm_radeon_texture_regs_t * tex,			     unsigned int dirty){	RING_LOCALS;	DRM_DEBUG("dirty=0x%08x\n", dirty);	if (dirty & RADEON_UPLOAD_CONTEXT) {		if (radeon_check_and_fixup_offset(dev_priv, file_priv,						  &ctx->rb3d_depthoffset)) {			DRM_ERROR("Invalid depth buffer offset\n");			return -EINVAL;		}		if (radeon_check_and_fixup_offset(dev_priv, file_priv,						  &ctx->rb3d_coloroffset)) {			DRM_ERROR("Invalid depth buffer offset\n");			return -EINVAL;		}		BEGIN_RING(14);		OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6));		OUT_RING(ctx->pp_misc);		OUT_RING(ctx->pp_fog_color);		OUT_RING(ctx->re_solid_color);		OUT_RING(ctx->rb3d_blendcntl);		OUT_RING(ctx->rb3d_depthoffset);		OUT_RING(ctx->rb3d_depthpitch);		OUT_RING(ctx->rb3d_zstencilcntl);		OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2));		OUT_RING(ctx->pp_cntl);		OUT_RING(ctx->rb3d_cntl);		OUT_RING(ctx->rb3d_coloroffset);		OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0));		OUT_RING(ctx->rb3d_colorpitch);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_VERTFMT) {		BEGIN_RING(2);		OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0));		OUT_RING(ctx->se_coord_fmt);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_LINE) {		BEGIN_RING(5);		OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1));		OUT_RING(ctx->re_line_pattern);		OUT_RING(ctx->re_line_state);		OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0));		OUT_RING(ctx->se_line_width);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_BUMPMAP) {		BEGIN_RING(5);		OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0));		OUT_RING(ctx->pp_lum_matrix);		OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1));		OUT_RING(ctx->pp_rot_matrix_0);		OUT_RING(ctx->pp_rot_matrix_1);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_MASKS) {		BEGIN_RING(4);		OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2));		OUT_RING(ctx->rb3d_stencilrefmask);		OUT_RING(ctx->rb3d_ropcntl);		OUT_RING(ctx->rb3d_planemask);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_VIEWPORT) {		BEGIN_RING(7);		OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5));		OUT_RING(ctx->se_vport_xscale);		OUT_RING(ctx->se_vport_xoffset);		OUT_RING(ctx->se_vport_yscale);		OUT_RING(ctx->se_vport_yoffset);		OUT_RING(ctx->se_vport_zscale);		OUT_RING(ctx->se_vport_zoffset);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_SETUP) {		BEGIN_RING(4);		OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0));		OUT_RING(ctx->se_cntl);		OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0));		OUT_RING(ctx->se_cntl_status);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_MISC) {		BEGIN_RING(2);		OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0));		OUT_RING(ctx->re_misc);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_TEX0) {		if (radeon_check_and_fixup_offset(dev_priv, file_priv,						  &tex[0].pp_txoffset)) {			DRM_ERROR("Invalid texture offset for unit 0\n");			return -EINVAL;		}		BEGIN_RING(9);		OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5));		OUT_RING(tex[0].pp_txfilter);		OUT_RING(tex[0].pp_txformat);		OUT_RING(tex[0].pp_txoffset);		OUT_RING(tex[0].pp_txcblend);		OUT_RING(tex[0].pp_txablend);		OUT_RING(tex[0].pp_tfactor);		OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0));		OUT_RING(tex[0].pp_border_color);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_TEX1) {		if (radeon_check_and_fixup_offset(dev_priv, file_priv,						  &tex[1].pp_txoffset)) {			DRM_ERROR("Invalid texture offset for unit 1\n");			return -EINVAL;		}		BEGIN_RING(9);		OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5));		OUT_RING(tex[1].pp_txfilter);		OUT_RING(tex[1].pp_txformat);		OUT_RING(tex[1].pp_txoffset);		OUT_RING(tex[1].pp_txcblend);		OUT_RING(tex[1].pp_txablend);		OUT_RING(tex[1].pp_tfactor);		OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0));		OUT_RING(tex[1].pp_border_color);		ADVANCE_RING();	}	if (dirty & RADEON_UPLOAD_TEX2) {		if (radeon_check_and_fixup_offset(dev_priv, file_priv,						  &tex[2].pp_txoffset)) {			DRM_ERROR("Invalid texture offset for unit 2\n");			return -EINVAL;		}		BEGIN_RING(9);		OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5));		OUT_RING(tex[2].pp_txfilter);		OUT_RING(tex[2].pp_txformat);		OUT_RING(tex[2].pp_txoffset);		OUT_RING(tex[2].pp_txcblend);		OUT_RING(tex[2].pp_txablend);		OUT_RING(tex[2].pp_tfactor);		OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0));		OUT_RING(tex[2].pp_border_color);		ADVANCE_RING();	}	return 0;}/* Emit 1.2 state */static int radeon_emit_state2(drm_radeon_private_t * dev_priv,			      struct drm_file *file_priv,			      drm_radeon_state_t * state){	RING_LOCALS;	if (state->dirty & RADEON_UPLOAD_ZBIAS) {		BEGIN_RING(3);		OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1));		OUT_RING(state->context2.se_zbias_factor);		OUT_RING(state->context2.se_zbias_constant);		ADVANCE_RING();	}	return radeon_emit_state(dev_priv, file_priv, &state->context,				 state->tex, state->dirty);}/* 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"},	{R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},	{RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"},	{RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},	{RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"},	{RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},	{RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},	{RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},	{R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},	{R200_PP_AFS_0, 32, "R200_PP_AFS_0"},     /* 85 */	{R200_PP_AFS_1, 32, "R200_PP_AFS_1"},	{R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},	{R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},	{R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"},	{R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"},	{R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"},	{R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"},	{R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"},	{R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"},};/* ================================================================ * 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->sarea_priv->pfCurrentPage == 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(struct drm_device * 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;	struct drm_clip_rect *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->sarea_priv->pfCurrentPage == 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();

⌨️ 快捷键说明

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