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

📄 r300_state.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
		/* with TCL we always seem to route 4 components */		if (InputsRead & (FRAG_BIT_TEX0 << i)) {		  if (hw_tcl_on)		    count = 4;		  else		    count = VB->AttribPtr[_TNL_ATTRIB_TEX(i)]->size;		  /* always have on texcoord */		  swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_S_SHIFT;		  if (count >= 2)		    swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_T_SHIFT;		  else		    swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT;		  if (count >= 3)		    swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_R_SHIFT;		  else		    swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT;		  if (count == 4)		    swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_Q_SHIFT;		  else		    swiz |= R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT;		} else		   swiz = (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) |		          (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) |		          (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |		          (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT);		r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = interp_col[i] | swiz;		r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] = 0;		if (InputsRead & (FRAG_BIT_TEX0 << i)) {			//assert(r300->state.texture.tc_count != 0);			r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] |= R500_RS_INST_TEX_CN_WRITE | i	/* source INTERP */			    | (fp_reg << R500_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] |= R500_RS_INST_COL_CN_WRITE | (fp_reg++ << R500_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] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE |  (fp_reg++ << R500_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 (in_texcoords == 0 && col_interp_nr == 0) {		r300->hw.rr.cmd[R300_RR_INST_0] |= 0 | R500_RS_INST_COL_CN_WRITE | (fp_reg++ << R500_RS_INST_COL_ADDR_SHIFT);		col_interp_nr++;	}	r300->hw.rc.cmd[1] = 0 | (in_texcoords << 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(R500_RS_INST_0, high_rr + 1);	r300->hw.rc.cmd[2] = 0xC0 | high_rr;	if (InputsRead)		WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead);}#define bump_vpu_count(ptr, new_count)   do{\	drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\	int _nc=(new_count)/4; \	assert(_nc < 256); \	if(_nc>_p->vpu.count)_p->vpu.count=_nc;\	}while(0)static INLINE void r300SetupVertexProgramFragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf){	int i;	if (vsf->length == 0)		return;	if (vsf->length & 0x3) {		fprintf(stderr, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");		_mesa_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);		_mesa_exit(-1);	}}#define MIN3(a, b, c)	((a) < (b) ? MIN2(a, c) : MIN2(b, c))static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,			GLuint output_count, GLuint temp_count){    int vtx_mem_size;    int pvs_num_slots;    int pvs_num_cntrls;    /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.     * See r500 docs 6.5.2 - done in emit */    /* avoid division by zero */    if (input_count == 0) input_count = 1;    if (output_count == 0) output_count = 1;    if (temp_count == 0) temp_count = 1;    if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)	vtx_mem_size = 128;    else	vtx_mem_size = 72;    pvs_num_slots = MIN3(10, vtx_mem_size/input_count, vtx_mem_size/output_count);    pvs_num_cntrls = MIN2(6, vtx_mem_size/temp_count);    R300_STATECHANGE(rmesa, vap_cntl);    if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] =	    (pvs_num_slots << R300_PVS_NUM_SLOTS_SHIFT) |	    (pvs_num_cntrls << R300_PVS_NUM_CNTLRS_SHIFT) |	    (12 << R300_VF_MAX_VTX_NUM_SHIFT);	if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)	    rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= R500_TCL_STATE_OPTIMIZATION;    } else	/* not sure about non-tcl */	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |				    (5 << R300_PVS_NUM_CNTLRS_SHIFT) |				    (5 << R300_VF_MAX_VTX_NUM_SHIFT));    if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515)	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (2 << R300_PVS_NUM_FPUS_SHIFT);    else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) ||	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560) ||	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570))	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (5 << R300_PVS_NUM_FPUS_SHIFT);    else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410) ||	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420))	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (6 << R300_PVS_NUM_FPUS_SHIFT);    else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) ||	     (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580))	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (8 << R300_PVS_NUM_FPUS_SHIFT);    else	rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (4 << R300_PVS_NUM_FPUS_SHIFT);}static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa){	struct r300_vertex_shader_state *prog = &(rmesa->state.vertex_shader);	GLuint o_reg = 0;	GLuint i_reg = 0;	int i;	int inst_count = 0;	int param_count = 0;	int program_end = 0;	for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++) {		if (rmesa->state.sw_tcl_inputs[i] != -1) {			prog->program.body.i[program_end + 0] = PVS_OP_DST_OPERAND(VE_MULTIPLY, GL_FALSE, GL_FALSE, o_reg++, VSF_FLAG_ALL, PVS_DST_REG_OUT);			prog->program.body.i[program_end + 1] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);			prog->program.body.i[program_end + 2] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);			prog->program.body.i[program_end + 3] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);			program_end += 4;			i_reg++;		}	}	prog->program.length = program_end;	r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START,				       &(prog->program));	inst_count = (prog->program.length / 4) - 1;	r300VapCntl(rmesa, i_reg, o_reg, 0);	R300_STATECHANGE(rmesa, pvs);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =	    (0 << R300_PVS_FIRST_INST_SHIFT) |	    (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |	    (inst_count << R300_PVS_LAST_INST_SHIFT);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =	    (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) |	    (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =	    (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT);}static int bit_count (int x){    x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U);    x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U);    x = (x >> 16) + (x & 0xffff);    x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f);    return (x >> 8) + (x & 0x00ff);}static void r300SetupRealVertexProgram(r300ContextPtr rmesa){	GLcontext *ctx = rmesa->radeon.glCtx;	struct r300_vertex_program *prog = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);	int inst_count = 0;	int param_count = 0;	/* FIXME: r300SetupVertexProgramFragment */	R300_STATECHANGE(rmesa, vpp);	param_count =	    r300VertexProgUpdateParams(ctx,				       (struct r300_vertex_program_cont *)				       ctx->VertexProgram._Current,				       (float *)&rmesa->hw.vpp.				       cmd[R300_VPP_PARAM_0]);	bump_vpu_count(rmesa->hw.vpp.cmd, param_count);	param_count /= 4;	r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START, &(prog->program));	inst_count = (prog->program.length / 4) - 1;	r300VapCntl(rmesa, bit_count(prog->key.InputsRead),		    bit_count(prog->key.OutputsWritten), prog->num_temporaries);	R300_STATECHANGE(rmesa, pvs);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =	  (0 << R300_PVS_FIRST_INST_SHIFT) |	  (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |	  (inst_count << R300_PVS_LAST_INST_SHIFT);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =	  (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) |	  (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT);	rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =	  (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT);}static void r300SetupVertexProgram(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) {		r300SetupRealVertexProgram(rmesa);	} else {		/* FIXME: This needs to be replaced by vertex shader generation code. */		r300SetupDefaultVertexProgram(rmesa);	}}/** * Enable/Disable states. * * \note Mesa already filters redundant calls to this function. */static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state){	if (RADEON_DEBUG & DEBUG_STATE)		fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,			_mesa_lookup_enum_by_nr(cap),			state ? "GL_TRUE" : "GL_FALSE");	switch (cap) {	case GL_TEXTURE_1D:	case GL_TEXTURE_2D:	case GL_TEXTURE_3D:		/* empty */		break;	case GL_FOG:		r300SetFogState(ctx, state);		break;	case GL_ALPHA_TEST:		r300SetAlphaState(ctx);		break;	case GL_COLOR_LOGIC_OP:		r300SetLogicOpState(ctx);		/* fall-through, because logic op overrides blending */	case GL_BLEND:		r300SetBlendState(ctx);		break;	case GL_CLIP_PLANE0:	case GL_CLIP_PLANE1:	case GL_CLIP_PLANE2:	case GL_CLIP_PLANE3:	case GL_CLIP_PLANE4:	case GL_CLIP_PLANE5:		r300SetClipPlaneState(ctx, cap, state);		break;	case GL_DEPTH_TEST:		r300SetDepthState(ctx);		break;	case GL_STENCIL_TEST:		r300SetStencilState(ctx, state);		break;	case GL_CULL_FACE:		r300UpdateCulling(ctx);		break;	case GL_POLYGON_OFFSET_POINT:	case GL_POLYGON_OFFSET_LINE:	case GL_POLYGON_OFFSET_FILL:		r300SetPolygonOffsetState(ctx, state);		break;	default:		radeonEnable(ctx, cap, state);		break;	}}/** * Completely recalculates hardware state based on the Mesa state. */static void r300ResetHwState(r300ContextPtr r300){	GLcontext *ctx = r300->radeon.glCtx;	int has_tcl = 1;	if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))		has_tcl = 0;	if (RADEON_DEBUG & DEBUG_STATE)		fprintf(stderr, "%s\n", __FUNCTION__);	r300UpdateWindow(ctx);	r300ColorMask(ctx,		      ctx->Color.ColorMask[RCOMP],		      ctx->Color.ColorMask[GCOMP],		      ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP]);	r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);	r300DepthMask(ctx, ctx->Depth.Mask);	r300DepthFunc(ctx, ctx->Depth.Func);	/* stencil */	r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);	r300StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]);	r300StencilFuncSeparate(ctx, 0, ctx->Stencil.Function[0],				ctx->Stencil.Ref[0], ctx->Stencil.ValueMask[0]);	r300StencilOpSeparate(ctx, 0, ctx->Stencil.FailFunc[0],			      ctx->Stencil.ZFailFunc[0],			      ctx->Stencil.ZPassFunc[0]);	r300UpdateCulling(ctx);	r300UpdateTextureState(ctx);	r300SetBlendState(ctx);	r300SetLogicOpState(ctx);	r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);	r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);	r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA	    | R300_VPORT_X_OFFSET_ENA	    | R300_VPORT_Y_SCALE_ENA	    | R300_VPORT_Y_OFFSET_ENA	    | R300_VPORT_Z_SCALE_ENA	    | R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT;	r300->hw.vte.cmd[2] = 0x00000008;	r300->hw.vap_vf_max_vtx_indx.cmd[1] = 0x00FFFFFF;	r300->hw.vap_vf_max_vtx_indx.cmd[2] = 0x00000000;#ifdef MESA_LITTLE_ENDIAN	r300->hw.vap_cntl_status.cmd[1] = R300_VC_NO_SWAP;#else	r300->hw.vap_cntl_status.cmd[1] = R300_VC_32BIT_SWAP;#endif	/* disable VAP/TCL on non-TCL capable chips */	if (!has_tcl)		r300->hw.vap_cntl_status.cmd[1] |= R300_VAP_TCL_BYPASS;	r300->hw.vap_psc_sgn_norm_cntl.cmd[1] = 0xAAAAAAAA;	/* XXX: Other families? */	if (has_tcl) {		r300->hw.vap_clip_cntl.cmd[1] = R300_PS_UCP_MODE_DIST_COP;		r300->hw.vap_clip.cmd[1] = r300PackFloat32(1.0); /* X */		r300->hw.vap_clip.cmd[2] = r300PackFloat32(1.0); /* X */		r300->hw.vap_clip.cmd[3] = r300PackFloat32(1.0); /* Y */		r300->hw.vap_clip.cmd[4] = r300PackFloat32(1.0); /* Y */		switch (r300->radeon.radeonScreen->chip_family) {		case CHIP_FAMILY_R300:			r300->hw.vap_pvs_vtx_timeout_reg.cmd[1] = R300_2288_R300;			break;		default:			r300->hw.vap_pvs_vtx_timeout_reg.cmd[1] = R300_2288_RV350;			break;		}	}	r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE	    | R300_GB_LINE_STUFF_ENABLE	    | R300_GB_TRIANGLE_STUFF_ENABLE;	r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;	r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;	r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =	    R300_G

⌨️ 快捷键说明

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