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

📄 r300_state.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
	return f;}static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings){	r300ContextPtr r300 = R300_CONTEXT(ctx);	int i;	struct r300_fragment_program *fp = (struct r300_fragment_program *)	    (char *)ctx->FragmentProgram._Current;	struct r300_fragment_program_code *code = &fp->code;	R300_STATECHANGE(r300, fpt);	for (i = 0; i < code->tex.length; i++) {		int unit;		int opcode;		unsigned long val;		unit = code->tex.inst[i] >> R300_TEX_ID_SHIFT;		unit &= 15;		val = code->tex.inst[i];		val &= ~R300_TEX_ID_MASK;		opcode =			(val & R300_TEX_INST_MASK) >> R300_TEX_INST_SHIFT;		if (opcode == R300_TEX_OP_KIL) {			r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val;		} else {			if (tmu_mappings[unit] >= 0) {				val |=					tmu_mappings[unit] <<					R300_TEX_ID_SHIFT;				r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val;			} else {				// We get here when the corresponding texture image is incomplete				// (e.g. incomplete mipmaps etc.)				r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val;			}		}	}	r300->hw.fpt.cmd[R300_FPT_CMD_0] =		cmdpacket0(R300_US_TEX_INST_0, code->tex.length);}static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings){	int i;	struct r500_fragment_program *fp = (struct r500_fragment_program *)	    (char *)ctx->FragmentProgram._Current;	struct r500_fragment_program_code *code = &fp->code;	/* find all the texture instructions and relocate the texture units */	for (i = 0; i < code->inst_end + 1; i++) {		if ((code->inst[i].inst0 & 0x3) == R500_INST_TYPE_TEX) {			uint32_t val;			int unit, opcode, new_unit;			val = code->inst[i].inst1;			unit = (val >> 16) & 0xf;			val &= ~(0xf << 16);			opcode = val & (0x7 << 22);			if (opcode == R500_TEX_INST_TEXKILL) {				new_unit = 0;			} else {				if (tmu_mappings[unit] >= 0) {					new_unit = tmu_mappings[unit];				} else {					new_unit = 0;				}			}			val |= R500_TEX_ID(new_unit);			code->inst[i].inst1 = val;		}	}}static GLuint translate_lod_bias(GLfloat bias){	GLint b = (int)(bias*32);	if (b >= (1 << 9))		b = (1 << 9)-1;	else if (b < -(1 << 9))		b = -(1 << 9);	return (((GLuint)b) << R300_LOD_BIAS_SHIFT) & R300_LOD_BIAS_MASK;}static void r300SetupTextures(GLcontext * ctx){	int i, mtu;	struct r300_tex_obj *t;	r300ContextPtr r300 = R300_CONTEXT(ctx);	int hw_tmu = 0;	int last_hw_tmu = -1;	/* -1 translates into no setup costs for fields */	int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1, };	struct r300_fragment_program *fp = (struct r300_fragment_program *)	    (char *)ctx->FragmentProgram._Current;	R300_STATECHANGE(r300, txe);	R300_STATECHANGE(r300, tex.filter);	R300_STATECHANGE(r300, tex.filter_1);	R300_STATECHANGE(r300, tex.size);	R300_STATECHANGE(r300, tex.format);	R300_STATECHANGE(r300, tex.pitch);	R300_STATECHANGE(r300, tex.offset);	R300_STATECHANGE(r300, tex.chroma_key);	R300_STATECHANGE(r300, tex.border_color);	r300->hw.txe.cmd[R300_TXE_ENABLE] = 0x0;	mtu = r300->radeon.glCtx->Const.MaxTextureUnits;	if (RADEON_DEBUG & DEBUG_STATE)		fprintf(stderr, "mtu=%d\n", mtu);	if (mtu > R300_MAX_TEXTURE_UNITS) {		fprintf(stderr,			"Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",			mtu, R300_MAX_TEXTURE_UNITS);		_mesa_exit(-1);	}	/* We cannot let disabled tmu offsets pass DRM */	for (i = 0; i < mtu; i++) {		if (ctx->Texture.Unit[i]._ReallyEnabled) {#if 0				/* Enables old behaviour */			hw_tmu = i;#endif			tmu_mappings[i] = hw_tmu;			t = r300->state.texture.unit[i].texobj;			/* XXX questionable fix for bug 9170: */			if (!t)				continue;			if ((t->format & 0xffffff00) == 0xffffff00) {				WARN_ONCE				    ("unknown texture format (entry %x) encountered. Help me !\n",				     t->format & 0xff);			}			if (RADEON_DEBUG & DEBUG_STATE)				fprintf(stderr,					"Activating texture unit %d\n", i);			r300->hw.txe.cmd[R300_TXE_ENABLE] |= (1 << hw_tmu);			r300->hw.tex.filter.cmd[R300_TEX_VALUE_0 +						hw_tmu] =			    gen_fixed_filter(t->filter) | (hw_tmu << 28);			/* Note: There is a LOD bias per texture unit and a LOD bias			 * per texture object. We add them here to get the correct behaviour.			 * (The per-texture object LOD bias was introduced in OpenGL 1.4			 * and is not present in the EXT_texture_object extension).			 */			r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] =				t->filter_1 |				translate_lod_bias(ctx->Texture.Unit[i].LodBias + t->base.tObj->LodBias);			r300->hw.tex.size.cmd[R300_TEX_VALUE_0 + hw_tmu] =			    t->size;			r300->hw.tex.format.cmd[R300_TEX_VALUE_0 +						hw_tmu] = t->format;			r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0 + hw_tmu] =			    t->pitch_reg;			r300->hw.tex.offset.cmd[R300_TEX_VALUE_0 +						hw_tmu] = t->offset;			if (t->offset & R300_TXO_MACRO_TILE) {				WARN_ONCE("macro tiling enabled!\n");			}			if (t->offset & R300_TXO_MICRO_TILE) {				WARN_ONCE("micro tiling enabled!\n");			}			r300->hw.tex.chroma_key.cmd[R300_TEX_VALUE_0 +						    hw_tmu] = 0x0;			r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0 +						      hw_tmu] =			    t->pp_border_color;			last_hw_tmu = hw_tmu;			hw_tmu++;		}	}	r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =	    cmdpacket0(R300_TX_FILTER0_0, last_hw_tmu + 1);	r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] =	    cmdpacket0(R300_TX_FILTER1_0, last_hw_tmu + 1);	r300->hw.tex.size.cmd[R300_TEX_CMD_0] =	    cmdpacket0(R300_TX_SIZE_0, last_hw_tmu + 1);	r300->hw.tex.format.cmd[R300_TEX_CMD_0] =	    cmdpacket0(R300_TX_FORMAT_0, last_hw_tmu + 1);	r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] =	    cmdpacket0(R300_TX_FORMAT2_0, last_hw_tmu + 1);	r300->hw.tex.offset.cmd[R300_TEX_CMD_0] =	    cmdpacket0(R300_TX_OFFSET_0, last_hw_tmu + 1);	r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] =	    cmdpacket0(R300_TX_CHROMA_KEY_0, last_hw_tmu + 1);	r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] =	    cmdpacket0(R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);	if (!fp)		/* should only happenen once, just after context is created */		return;	if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {		if (fp->mesa_program.UsesKill && last_hw_tmu < 0) {			// The KILL operation requires the first texture unit			// to be enabled.			r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1;			r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0;			r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =				cmdpacket0(R300_TX_FILTER0_0, 1);		}		r300SetupFragmentShaderTextures(ctx, tmu_mappings);	} else		r500SetupFragmentShaderTextures(ctx, tmu_mappings);	if (RADEON_DEBUG & DEBUG_STATE)		fprintf(stderr, "TX_ENABLE: %08x  last_hw_tmu=%d\n",			r300->hw.txe.cmd[R300_TXE_ENABLE], last_hw_tmu);}union r300_outputs_written {	GLuint vp_outputs;	/* hw_tcl_on */	 DECLARE_RENDERINPUTS(index_bitset);	/* !hw_tcl_on */};#define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \	((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \	RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))static void r300SetupRSUnit(GLcontext * ctx){	r300ContextPtr r300 = R300_CONTEXT(ctx);	/* I'm still unsure if these are needed */	GLuint interp_col[8];        TNLcontext *tnl = TNL_CONTEXT(ctx);	struct vertex_buffer *VB = &tnl->vb;	union r300_outputs_written OutputsWritten;	GLuint InputsRead;	int fp_reg, high_rr;	int col_interp_nr;	int rs_tex_count = 0, rs_col_count = 0;	int i, count;	memset(interp_col, 0, sizeof(interp_col));	if (hw_tcl_on)		OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;	else		RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->state.render_inputs_bitset);	if (ctx->FragmentProgram._Current)		InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;	else {		fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");		return;		/* This should only ever happen once.. */	}	R300_STATECHANGE(r300, ri);	R300_STATECHANGE(r300, rc);	R300_STATECHANGE(r300, rr);	fp_reg = col_interp_nr = high_rr = 0;	r300->hw.rr.cmd[R300_RR_INST_1] = 0;	if (InputsRead & FRAG_BIT_WPOS) {		for (i = 0; i < ctx->Const.MaxTextureUnits; i++)			if (!(InputsRead & (FRAG_BIT_TEX0 << i)))				break;		if (i == ctx->Const.MaxTextureUnits) {			fprintf(stderr, "\tno free texcoord found...\n");			_mesa_exit(-1);		}		InputsRead |= (FRAG_BIT_TEX0 << i);		InputsRead &= ~FRAG_BIT_WPOS;	}	if (InputsRead & FRAG_BIT_COL0) {		count = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size;		interp_col[0] |= R300_RS_COL_PTR(rs_col_count);		if (count == 3)			interp_col[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1);		rs_col_count += count;	}	else		interp_col[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001);	if (InputsRead & FRAG_BIT_COL1) {		count = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->size;		if (count == 3)			interp_col[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB0);		interp_col[1] |= R300_RS_COL_PTR(1);		rs_col_count += count;	}	for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {		int swiz;		/* with TCL we always seem to route 4 components */		if (hw_tcl_on)		  count = 4;		else		  count = VB->AttribPtr[_TNL_ATTRIB_TEX(i)]->size;		r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = interp_col[i] | rs_tex_count;		switch(count) {		case 4: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;		case 3: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(R300_RS_SEL_K1); break;		default:		case 1:		case 2: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1); break;		};		r300->hw.ri.cmd[R300_RI_INTERP_0 + i] |= swiz;		r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] = 0;		if (InputsRead & (FRAG_BIT_TEX0 << i)) {			rs_tex_count += count;			//assert(r300->state.texture.tc_count != 0);			r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] |= R300_RS_INST_TEX_CN_WRITE | i	/* source INTERP */			    | (fp_reg << R300_RS_INST_TEX_ADDR_SHIFT);			high_rr = fp_reg;			/* Passing invalid data here can lock the GPU. */			if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) {				InputsRead &= ~(FRAG_BIT_TEX0 << i);				fp_reg++;			} else {				WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i);			}		}	}	if (InputsRead & FRAG_BIT_COL0) {		if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) {			r300->hw.rr.cmd[R300_RR_INST_0] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT);			InputsRead &= ~FRAG_BIT_COL0;			col_interp_nr++;		} else {			WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");		}	}	if (InputsRead & FRAG_BIT_COL1) {		if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) {			r300->hw.rr.cmd[R300_RR_INST_1] |= R300_RS_INST_COL_ID(1) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT);			InputsRead &= ~FRAG_BIT_COL1;			if (high_rr < 1)				high_rr = 1;			col_interp_nr++;		} else {			WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");		}	}	/* Need at least one. This might still lock as the values are undefined... */	if (rs_tex_count == 0 && col_interp_nr == 0) {		r300->hw.rr.cmd[R300_RR_INST_0] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT);		col_interp_nr++;	}	r300->hw.rc.cmd[1] = 0 | (rs_tex_count << R300_IT_COUNT_SHIFT)	  | (col_interp_nr << R300_IC_COUNT_SHIFT)	  | R300_HIRES_EN;	assert(high_rr >= 0);	r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, high_rr + 1);	r300->hw.rc.cmd[2] = high_rr;	if (InputsRead)		WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead);}static void r500SetupRSUnit(GLcontext * ctx){	r300ContextPtr r300 = R300_CONTEXT(ctx);	/* I'm still unsure if these are needed */	GLuint interp_col[8];	union r300_outputs_written OutputsWritten;        TNLcontext *tnl = TNL_CONTEXT(ctx);	struct vertex_buffer *VB = &tnl->vb;	GLuint InputsRead;	int fp_reg, high_rr;	int rs_col_count = 0;	int in_texcoords, col_interp_nr;	int i, count;	memset(interp_col, 0, sizeof(interp_col));	if (hw_tcl_on)		OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;	else		RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->state.render_inputs_bitset);	if (ctx->FragmentProgram._Current)		InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;	else {		fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");		return;		/* This should only ever happen once.. */	}	R300_STATECHANGE(r300, ri);	R300_STATECHANGE(r300, rc);	R300_STATECHANGE(r300, rr);	fp_reg = col_interp_nr = high_rr = in_texcoords = 0;	r300->hw.rr.cmd[R300_RR_INST_1] = 0;	if (InputsRead & FRAG_BIT_WPOS) {		for (i = 0; i < ctx->Const.MaxTextureUnits; i++)			if (!(InputsRead & (FRAG_BIT_TEX0 << i)))				break;		if (i == ctx->Const.MaxTextureUnits) {			fprintf(stderr, "\tno free texcoord found...\n");			_mesa_exit(-1);		}		InputsRead |= (FRAG_BIT_TEX0 << i);		InputsRead &= ~FRAG_BIT_WPOS;	}	if (InputsRead & FRAG_BIT_COL0) {		count = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size;		interp_col[0] |= R500_RS_COL_PTR(rs_col_count);		if (count == 3)			interp_col[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1);		rs_col_count += count;	}	else		interp_col[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001);	if (InputsRead & FRAG_BIT_COL1) {		count = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->size;		interp_col[1] |= R500_RS_COL_PTR(1);		if (count == 3)			interp_col[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0);		rs_col_count += count;	}	for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {		GLuint swiz = 0;

⌨️ 快捷键说明

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