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