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

📄 radeon_state.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/* radeon_state.c -- State support for Radeon -*- linux-c -*- * * Copyright 2000 VA Linux Systems, Inc., Fremont, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: *    Gareth Hughes <gareth@valinux.com> *    Kevin E. Martin <martin@valinux.com> */#include "drmP.h"#include "drm.h"#include "drm_sarea.h"#include "radeon_drm.h"#include "radeon_drv.h"/* ================================================================ * Helper functions for client state checking and fixup */static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *						    dev_priv,						    drm_file_t * filp_priv,						    u32 *offset){	u32 off = *offset;	struct drm_radeon_driver_file_fields *radeon_priv;	if (off >= dev_priv->fb_location &&	    off < (dev_priv->gart_vm_start + dev_priv->gart_size))		return 0;	radeon_priv = filp_priv->driver_priv;	off += radeon_priv->radeon_fb_delta;	DRM_DEBUG("offset fixed up to 0x%x\n", off);	if (off < dev_priv->fb_location ||	    off >= (dev_priv->gart_vm_start + dev_priv->gart_size))		return DRM_ERR(EINVAL);	*offset = off;	return 0;}static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *						     dev_priv,						     drm_file_t * filp_priv,						     int id, u32 *data){	switch (id) {	case RADEON_EMIT_PP_MISC:		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,						  &data[(RADEON_RB3D_DEPTHOFFSET							 -							 RADEON_PP_MISC) /							4])) {			DRM_ERROR("Invalid depth buffer offset\n");			return DRM_ERR(EINVAL);		}		break;	case RADEON_EMIT_PP_CNTL:		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,						  &data[(RADEON_RB3D_COLOROFFSET							 -							 RADEON_PP_CNTL) /							4])) {			DRM_ERROR("Invalid colour buffer offset\n");			return DRM_ERR(EINVAL);		}		break;	case R200_EMIT_PP_TXOFFSET_0:	case R200_EMIT_PP_TXOFFSET_1:	case R200_EMIT_PP_TXOFFSET_2:	case R200_EMIT_PP_TXOFFSET_3:	case R200_EMIT_PP_TXOFFSET_4:	case R200_EMIT_PP_TXOFFSET_5:		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,						  &data[0])) {			DRM_ERROR("Invalid R200 texture offset\n");			return DRM_ERR(EINVAL);		}		break;	case RADEON_EMIT_PP_TXFILTER_0:	case RADEON_EMIT_PP_TXFILTER_1:	case RADEON_EMIT_PP_TXFILTER_2:		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,						  &data[(RADEON_PP_TXOFFSET_0							 -							 RADEON_PP_TXFILTER_0) /							4])) {			DRM_ERROR("Invalid R100 texture offset\n");			return DRM_ERR(EINVAL);		}		break;	case R200_EMIT_PP_CUBIC_OFFSETS_0:	case R200_EMIT_PP_CUBIC_OFFSETS_1:	case R200_EMIT_PP_CUBIC_OFFSETS_2:	case R200_EMIT_PP_CUBIC_OFFSETS_3:	case R200_EMIT_PP_CUBIC_OFFSETS_4:	case R200_EMIT_PP_CUBIC_OFFSETS_5:{			int i;			for (i = 0; i < 5; i++) {				if (radeon_check_and_fixup_offset				    (dev_priv, filp_priv, &data[i])) {					DRM_ERROR					    ("Invalid R200 cubic texture offset\n");					return DRM_ERR(EINVAL);				}			}			break;		}	case RADEON_EMIT_PP_CUBIC_OFFSETS_T0:	case RADEON_EMIT_PP_CUBIC_OFFSETS_T1:	case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{			int i;			for (i = 0; i < 5; i++) {				if (radeon_check_and_fixup_offset(dev_priv,								  filp_priv,								  &data[i])) {					DRM_ERROR					    ("Invalid R100 cubic texture offset\n");					return DRM_ERR(EINVAL);				}			}		}		break;	case RADEON_EMIT_RB3D_COLORPITCH:	case RADEON_EMIT_RE_LINE_PATTERN:	case RADEON_EMIT_SE_LINE_WIDTH:	case RADEON_EMIT_PP_LUM_MATRIX:	case RADEON_EMIT_PP_ROT_MATRIX_0:	case RADEON_EMIT_RB3D_STENCILREFMASK:	case RADEON_EMIT_SE_VPORT_XSCALE:	case RADEON_EMIT_SE_CNTL:	case RADEON_EMIT_SE_CNTL_STATUS:	case RADEON_EMIT_RE_MISC:	case RADEON_EMIT_PP_BORDER_COLOR_0:	case RADEON_EMIT_PP_BORDER_COLOR_1:	case RADEON_EMIT_PP_BORDER_COLOR_2:	case RADEON_EMIT_SE_ZBIAS_FACTOR:	case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT:	case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED:	case R200_EMIT_PP_TXCBLEND_0:	case R200_EMIT_PP_TXCBLEND_1:	case R200_EMIT_PP_TXCBLEND_2:	case R200_EMIT_PP_TXCBLEND_3:	case R200_EMIT_PP_TXCBLEND_4:	case R200_EMIT_PP_TXCBLEND_5:	case R200_EMIT_PP_TXCBLEND_6:	case R200_EMIT_PP_TXCBLEND_7:	case R200_EMIT_TCL_LIGHT_MODEL_CTL_0:	case R200_EMIT_TFACTOR_0:	case R200_EMIT_VTX_FMT_0:	case R200_EMIT_VAP_CTL:	case R200_EMIT_MATRIX_SELECT_0:	case R200_EMIT_TEX_PROC_CTL_2:	case R200_EMIT_TCL_UCP_VERT_BLEND_CTL:	case R200_EMIT_PP_TXFILTER_0:	case R200_EMIT_PP_TXFILTER_1:	case R200_EMIT_PP_TXFILTER_2:	case R200_EMIT_PP_TXFILTER_3:	case R200_EMIT_PP_TXFILTER_4:	case R200_EMIT_PP_TXFILTER_5:	case R200_EMIT_VTE_CNTL:	case R200_EMIT_OUTPUT_VTX_COMP_SEL:	case R200_EMIT_PP_TAM_DEBUG3:	case R200_EMIT_PP_CNTL_X:	case R200_EMIT_RB3D_DEPTHXY_OFFSET:	case R200_EMIT_RE_AUX_SCISSOR_CNTL:	case R200_EMIT_RE_SCISSOR_TL_0:	case R200_EMIT_RE_SCISSOR_TL_1:	case R200_EMIT_RE_SCISSOR_TL_2:	case R200_EMIT_SE_VAP_CNTL_STATUS:	case R200_EMIT_SE_VTX_STATE_CNTL:	case R200_EMIT_RE_POINTSIZE:	case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0:	case R200_EMIT_PP_CUBIC_FACES_0:	case R200_EMIT_PP_CUBIC_FACES_1:	case R200_EMIT_PP_CUBIC_FACES_2:	case R200_EMIT_PP_CUBIC_FACES_3:	case R200_EMIT_PP_CUBIC_FACES_4:	case R200_EMIT_PP_CUBIC_FACES_5:	case RADEON_EMIT_PP_TEX_SIZE_0:	case RADEON_EMIT_PP_TEX_SIZE_1:	case RADEON_EMIT_PP_TEX_SIZE_2:	case R200_EMIT_RB3D_BLENDCOLOR:	case R200_EMIT_TCL_POINT_SPRITE_CNTL:	case RADEON_EMIT_PP_CUBIC_FACES_0:	case RADEON_EMIT_PP_CUBIC_FACES_1:	case RADEON_EMIT_PP_CUBIC_FACES_2:	case R200_EMIT_PP_TRI_PERF_CNTL:	case R200_EMIT_PP_AFS_0:	case R200_EMIT_PP_AFS_1:	case R200_EMIT_ATF_TFACTOR:	case R200_EMIT_PP_TXCTLALL_0:	case R200_EMIT_PP_TXCTLALL_1:	case R200_EMIT_PP_TXCTLALL_2:	case R200_EMIT_PP_TXCTLALL_3:	case R200_EMIT_PP_TXCTLALL_4:	case R200_EMIT_PP_TXCTLALL_5:		/* These packets don't contain memory offsets */		break;	default:		DRM_ERROR("Unknown state packet ID %d\n", id);		return DRM_ERR(EINVAL);	}	return 0;}static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *						     dev_priv,						     drm_file_t * filp_priv,						     drm_radeon_kcmd_buffer_t *cmdbuf,						     unsigned int *cmdsz){	u32 *cmd = (u32 *) cmdbuf->buf;	*cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);	if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) {		DRM_ERROR("Not a type 3 packet\n");		return DRM_ERR(EINVAL);	}	if (4 * *cmdsz > cmdbuf->bufsz) {		DRM_ERROR("Packet size larger than size of data provided\n");		return DRM_ERR(EINVAL);	}	/* Check client state and fix it up if necessary */	if (cmd[0] & 0x8000) {	/* MSB of opcode: next DWORD GUI_CNTL */		u32 offset;		if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {			offset = cmd[2] << 10;			if (radeon_check_and_fixup_offset			    (dev_priv, filp_priv, &offset)) {				DRM_ERROR("Invalid first packet offset\n");				return DRM_ERR(EINVAL);			}			cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10;		}		if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&		    (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {			offset = cmd[3] << 10;			if (radeon_check_and_fixup_offset			    (dev_priv, filp_priv, &offset)) {				DRM_ERROR("Invalid second packet offset\n");				return DRM_ERR(EINVAL);			}			cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;		}	}	return 0;}/* ================================================================ * CP hardware state programming functions */static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv,					     drm_clip_rect_t * box){	RING_LOCALS;	DRM_DEBUG("   box:  x1=%d y1=%d  x2=%d y2=%d\n",		  box->x1, box->y1, box->x2, box->y2);	BEGIN_RING(4);	OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0));	OUT_RING((box->y1 << 16) | box->x1);	OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));	OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1));	ADVANCE_RING();}/* Emit 1.1 state */static int radeon_emit_state(drm_radeon_private_t * dev_priv,			     drm_file_t * filp_priv,			     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, filp_priv,						  &ctx->rb3d_depthoffset)) {			DRM_ERROR("Invalid depth buffer offset\n");			return DRM_ERR(EINVAL);		}		if (radeon_check_and_fixup_offset(dev_priv, filp_priv,						  &ctx->rb3d_coloroffset)) {			DRM_ERROR("Invalid depth buffer offset\n");			return DRM_ERR(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, filp_priv,						  &tex[0].pp_txoffset)) {			DRM_ERROR("Invalid texture offset for unit 0\n");			return DRM_ERR(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, filp_priv,						  &tex[1].pp_txoffset)) {			DRM_ERROR("Invalid texture offset for unit 1\n");			return DRM_ERR(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();	}

⌨️ 快捷键说明

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