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

📄 r300_state.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		fprintf(stderr,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");		exit(-1);		}	switch((dest>>8) & 0xf){	case 0:		R300_STATECHANGE(r300, vpi);		for(i=0;i<vsf->length;i++)			r300->hw.vpi.cmd[R300_VPI_INSTR_0+i+4*(dest & 0xff)]=(vsf->body.d[i]);		bump_vpu_count(r300->hw.vpi.cmd, vsf->length+4*(dest & 0xff));		break;	case 2:		R300_STATECHANGE(r300, vpp);		for(i=0;i<vsf->length;i++)			r300->hw.vpp.cmd[R300_VPP_PARAM_0+i+4*(dest & 0xff)]=(vsf->body.d[i]);		bump_vpu_count(r300->hw.vpp.cmd, vsf->length+4*(dest & 0xff));		break;	case 4:		R300_STATECHANGE(r300, vps);		for(i=0;i<vsf->length;i++)			r300->hw.vps.cmd[1+i+4*(dest & 0xff)]=(vsf->body.d[i]);		bump_vpu_count(r300->hw.vps.cmd, vsf->length+4*(dest & 0xff));		break;	default:		fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest);		exit(-1);	}}void r300SetupVertexProgram(r300ContextPtr rmesa);/* just a skeleton for now.. *//* Generate a vertex shader that simply transforms vertex and texture coordinates,   while leaving colors intact. Nothing fancy (like lights)       If implementing lights make a copy first, so it is easy to switch between the two versions */static void r300GenerateSimpleVertexShader(r300ContextPtr r300){	int i;	GLuint o_reg = 0;	/* Allocate parameters */	r300->state.vap_param.transform_offset=0x0;  /* transform matrix */	r300->state.vertex_shader.param_offset=0x0;	r300->state.vertex_shader.param_count=0x4;  /* 4 vector values - 4x4 matrix */		r300->state.vertex_shader.program_start=0x0;	r300->state.vertex_shader.unknown_ptr1=0x4; /* magic value ? */	r300->state.vertex_shader.program_end=0x0;		r300->state.vertex_shader.unknown_ptr2=0x0; /* magic value */	r300->state.vertex_shader.unknown_ptr3=0x4; /* magic value */		/* Initialize matrix and vector parameters.. these should really be restructured */	/* TODO: fix vertex_shader structure */	r300->state.vertex_shader.matrix[0].length=16;	r300->state.vertex_shader.matrix[1].length=0;	r300->state.vertex_shader.matrix[2].length=0;	r300->state.vertex_shader.vector[0].length=0;	r300->state.vertex_shader.vector[1].length=0;	r300->state.vertex_shader.unknown1.length=0;	r300->state.vertex_shader.unknown2.length=0;	#define WRITE_OP(oper,source1,source2,source3)	{\	r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \	r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \	r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src2=(source2); \	r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src3=(source3); \	r300->state.vertex_shader.program_end++; \	}	/* Multiply vertex coordinates with transform matrix */				WRITE_OP(		EASY_VSF_OP(MUL, 0, ALL, TMP),		VSF_PARAM(3),		VSF_ATTR_W(0),		EASY_VSF_SOURCE(0, W, W, W, W, NONE, NONE)		)		WRITE_OP(		EASY_VSF_OP(MUL, 1, ALL, RESULT),		VSF_REG(1),		VSF_ATTR_UNITY(1),		VSF_UNITY(1)		)		WRITE_OP(		EASY_VSF_OP(MAD, 0, ALL, TMP),		VSF_PARAM(2),		VSF_ATTR_Z(0),		VSF_TMP(0)		)		WRITE_OP(		EASY_VSF_OP(MAD, 0, ALL, TMP),		VSF_PARAM(1),		VSF_ATTR_Y(0),		VSF_TMP(0)		)		WRITE_OP(		EASY_VSF_OP(MAD, 0, ALL, RESULT),		VSF_PARAM(0),		VSF_ATTR_X(0),		VSF_TMP(0)		)	o_reg += 2;		if (r300->state.render_inputs & _TNL_BIT_COLOR1) {		WRITE_OP(			EASY_VSF_OP(MUL, o_reg++, ALL, RESULT),			VSF_REG(r300->state.vap_reg.i_color[1]),			VSF_ATTR_UNITY(r300->state.vap_reg.i_color[1]),			VSF_UNITY(r300->state.vap_reg.i_color[1])		)	}		/* Pass through texture coordinates, if any */	for(i=0;i < r300->radeon.glCtx->Const.MaxTextureUnits;i++)		if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i)){			// fprintf(stderr, "i_tex[%d]=%d\n", i, r300->state.vap_reg.i_tex[i]);			WRITE_OP(				EASY_VSF_OP(MUL, o_reg++ /* 2+i */, ALL, RESULT),				VSF_REG(r300->state.vap_reg.i_tex[i]),				VSF_ATTR_UNITY(r300->state.vap_reg.i_tex[i]),				VSF_UNITY(r300->state.vap_reg.i_tex[i])				)			}		r300->state.vertex_shader.program_end--; /* r300 wants program length to be one more - no idea why */	r300->state.vertex_shader.program.length=(r300->state.vertex_shader.program_end+1)*4;		r300->state.vertex_shader.unknown_ptr1=r300->state.vertex_shader.program_end; /* magic value ? */	r300->state.vertex_shader.unknown_ptr2=r300->state.vertex_shader.program_end; /* magic value ? */	r300->state.vertex_shader.unknown_ptr3=r300->state.vertex_shader.program_end; /* magic value ? */	}void r300SetupVertexShader(r300ContextPtr rmesa){	GLcontext* ctx = rmesa->radeon.glCtx;	/* Reset state, in case we don't use something */	((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;	((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;	((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;	/* Not sure why this doesnt work...	   0x400 area might have something to do with pixel shaders as it appears right after pfs programming.	   0x406 is set to { 0.0, 0.0, 1.0, 0.0 } most of the time but should change with smooth points and in other rare cases. */	//setup_vertex_shader_fragment(rmesa, 0x406, &unk4);	if(hw_tcl_on && ((struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx))->translated){		r300SetupVertexProgram(rmesa);		return ;	}/* This needs to be replaced by vertex shader generation code */#if 0	/* textures enabled ? */	if(rmesa->state.texture.tc_count>0){		rmesa->state.vertex_shader=SINGLE_TEXTURE_VERTEX_SHADER;		} else {		rmesa->state.vertex_shader=FLAT_COLOR_VERTEX_SHADER;		}#endif	r300GenerateSimpleVertexShader(rmesa);        rmesa->state.vertex_shader.matrix[0].length=16;        memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);	setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->state.vertex_shader.program));	setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->state.vertex_shader.matrix[0]));#if 0	setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX1, &(rmesa->state.vertex_shader.matrix[0]));	setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX2, &(rmesa->state.vertex_shader.matrix[0]));	setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR0, &(rmesa->state.vertex_shader.vector[0]));	setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR1, &(rmesa->state.vertex_shader.vector[1]));#endif#if 0	setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));	setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));#endif	R300_STATECHANGE(rmesa, pvs);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(rmesa->state.vertex_shader.program_start << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)		| (rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_POS_END_SHIFT)		| (rmesa->state.vertex_shader.program_end << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(rmesa->state.vertex_shader.param_offset << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)		| (rmesa->state.vertex_shader.param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(rmesa->state.vertex_shader.unknown_ptr2 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)	| (rmesa->state.vertex_shader.unknown_ptr3 << 0);	/* This is done for vertex shader fragments, but also needs to be done for vap_pvs,	so I leave it as a reminder */#if 0	reg_start(R300_VAP_PVS_WAITIDLE,0);		e32(0x00000000);#endif}void r300SetupVertexProgram(r300ContextPtr rmesa){	GLcontext* ctx = rmesa->radeon.glCtx;	int inst_count;	int param_count;	struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);				((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;	R300_STATECHANGE(rmesa, vpp);	param_count = r300VertexProgUpdateParams(ctx, prog, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);	bump_vpu_count(rmesa->hw.vpp.cmd, param_count);	param_count /= 4;		/* Reset state, in case we don't use something */	((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;	((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;	setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(prog->program));#if 0	setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));	setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));#endif	inst_count=prog->program.length/4 - 1;	R300_STATECHANGE(rmesa, pvs);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)		| (inst_count/*pos_end*/ << R300_PVS_CNTL_1_POS_END_SHIFT)		| (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)		| (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)	| (inst_count /*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);	/* This is done for vertex shader fragments, but also needs to be done for vap_pvs,	so I leave it as a reminder */#if 0	reg_start(R300_VAP_PVS_WAITIDLE,0);		e32(0x00000000);#endif}extern void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx );extern int future_hw_tcl_on;void r300UpdateShaders(r300ContextPtr rmesa){	GLcontext *ctx;	struct r300_vertex_program *vp;		ctx = rmesa->radeon.glCtx;		/* Disable tnl programs when doing software vertex programs.	   I can only hope this actually disables it at the right time. */	ctx->_MaintainTnlProgram = hw_tcl_on;		if (rmesa->NewGLState && hw_tcl_on) {		rmesa->NewGLState = 0;				_tnl_UpdateFixedFunctionProgram(ctx);			vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);		if (vp->translated == GL_FALSE)			r300_translate_vertex_shader(vp);		if (vp->translated == GL_FALSE) {			fprintf(stderr, "Failing back to sw-tcl\n");			hw_tcl_on = future_hw_tcl_on = 0;			r300ResetHwState(rmesa);			return ;		}	}	}void r300UpdateShaderStates(r300ContextPtr rmesa){	GLcontext *ctx;	ctx = rmesa->radeon.glCtx;	#ifdef CB_DPATH	r300UpdateTextureState(ctx);#endif	r300SetupPixelShader(rmesa);	r300_setup_textures(ctx);		r300SetupVertexShader(rmesa);	r300_setup_rs_unit(ctx);}/* This is probably wrong for some values, I need to test this * some more.  Range checking would be a good idea also.. *  * But it works for most things.  I'll fix it later if someone * else with a better clue doesn't */static unsigned int r300PackFloat24(float f){	float mantissa;	int exponent;	unsigned int float24 = 0;	if (f == 0.0) return 0;	mantissa = frexpf(f, &exponent);	/* Handle -ve */	if (mantissa < 0) {		float24 |= (1<<23);		mantissa = mantissa * -1.0;	}	/* Handle exponent, bias of 63 */	exponent += 62;	float24 |= (exponent << 16);	/* Kill 7 LSB of mantissa */	float24 |= (r300PackFloat32(mantissa) & 0x7FFFFF)  >> 7;	return float24;}void r300SetupPixelShader(r300ContextPtr rmesa){	GLcontext *ctx = rmesa->radeon.glCtx;	struct r300_fragment_program *rp =		(struct r300_fragment_program *)		(char *)ctx->FragmentProgram._Current;	int i,k;	if (!rp)	/* should only happenen once, just after context is created */		return;		r300_translate_fragment_shader(rp);	if (!rp->translated) {		fprintf(stderr, "%s: No valid fragment shader, exiting\n", __func__);		exit(-1);	}	#define OUTPUT_FIELD(st, reg, field)  \		R300_STATECHANGE(rmesa, st); \		for(i=0;i<=rp->alu_end;i++) \			rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rp->alu.inst[i].field;\		rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, rp->alu_end+1);	OUTPUT_FIELD(fpi[0], R300_PFS_INSTR0_0, inst0);	OUTPUT_FIELD(fpi[1], R300_PFS_INSTR1_0, inst1);	OUTPUT_FIELD(fpi[2], R300_PFS_INSTR2_0, inst2);	OUTPUT_FIELD(fpi[3], R300_PFS_INSTR3_0, inst3);#undef OUTPUT_FIELD	R300_STATECHANGE(rmesa, fp);	/* I just want to say, the way these nodes are stored.. weird.. */	for (i=0,k=(4-(rp->cur_node+1));i<4;i++,k++) {		if (i<(rp->cur_node+1)) {			rmesa->hw.fp.cmd[R300_FP_NODE0+k]=				(rp->node[i].alu_offset << R300_PFS_NODE_ALU_OFFSET_SHIFT)				| (rp->node[i].alu_end  << R300_PFS_NODE_ALU_END_SHIFT)				| (rp->node[i].tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT)				| (rp->node[i].tex_end  << R300_PFS_NODE_TEX_END_SHIFT)				| rp->node[i].flags; /*  ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */		} else {			rmesa->hw.fp.cmd[R300_FP_NODE0+(3-i)] = 0;		}	}		/*  PFS_CNTL_0 */	rmesa->hw.fp.cmd[R300_FP_CNTL0]=		rp->cur_node		| (rp->first_node_has_tex<<3);		/* PFS_CNTL_1 */	rmesa->hw.fp.cmd[R300_FP_CNTL1]=rp->max_temp_idx;		/* PFS_CNTL_2 */	rmesa->hw.fp.cmd[R300_FP_CNTL2]=		(rp->alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT)		| (rp->alu_end << R300_PFS_CNTL_ALU_END_SHIFT)		| (rp->tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT)		| (rp->tex_end << R300_PFS_CNTL_TEX_END_SHIFT);	R300_STATECHANGE(rmesa, fpp);	for(i=0;i<rp->const_nr;i++){		rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+0]=r300PackFloat24(rp->constant[i][0]);		rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+1]=r300PackFloat24(rp->constant[i][1]);		rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+2]=r300PackFloat24(rp->constant[i][2]);		rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+3]=r300PackFloat24(rp->constant[i][3]);	}	rmesa->hw.fpp.cmd[R300_FPP_CMD_0]=cmdpacket0(R300_PFS_PARAM_0_X, rp->const_nr*4);}/** * Called by Mesa after an internal state update. */static void r300InvalidateState(GLcontext * ctx, GLuint new_state){	r300ContextPtr r300 = R300_CONTEXT(ctx);		_swrast_InvalidateState(ctx, new_state);	_swsetup_InvalidateState(ctx, new_state);	_ac_InvalidateState(ctx, new_state);	_tnl_InvalidateState(ctx, new_state);	_ae_invalidate_state(ctx, new_state);	if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {		r300UpdateDrawBuffer(ctx);	}#ifndef CB_DPATH	/* Go inefficiency! */	r300ResetHwState(r300);#endif#ifdef HW_VBOS	if(new_state & _NEW_ARRAY)		r300->state.VB.lock_uptodate = GL_FALSE;#endif	r300->NewGLState |= new_state;}/** * Completely recalculates hardware state based on the Mesa state. */void r300ResetHwState(r300ContextPtr r300)

⌨️ 快捷键说明

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