📄 r300_state.c
字号:
/* 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 + -