📄 r300_state.c
字号:
r300UpdateWindow(ctx);}void r300UpdateViewportOffset( GLcontext *ctx ){ r300ContextPtr rmesa = R300_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = ((radeonContextPtr)rmesa)->dri.drawable; GLfloat xoffset = (GLfloat)dPriv->x; GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; const GLfloat *v = ctx->Viewport._WindowMap.m; GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y; if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != r300PackFloat32(tx) || rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != r300PackFloat32(ty)) { /* Note: this should also modify whatever data the context reset * code uses... */ R300_STATECHANGE( rmesa, vpt ); rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = r300PackFloat32(tx); rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = r300PackFloat32(ty); } radeonUpdateScissor( ctx );}/** * Tell the card where to render (offset, pitch). * Effected by glDrawBuffer, etc */voidr300UpdateDrawBuffer(GLcontext *ctx){ r300ContextPtr rmesa = R300_CONTEXT(ctx); r300ContextPtr r300 = rmesa; struct gl_framebuffer *fb = ctx->DrawBuffer; driRenderbuffer *drb; if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { /* draw to front */ drb = (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; } else if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) { /* draw to back */ drb = (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; } else { /* drawing to multiple buffers, or none */ return; } assert(drb); assert(drb->flippedPitch); R300_STATECHANGE( rmesa, cb ); r300->hw.cb.cmd[R300_CB_OFFSET] = drb->flippedOffset + //r300->radeon.state.color.drawOffset + r300->radeon.radeonScreen->fbLocation; r300->hw.cb.cmd[R300_CB_PITCH] = drb->flippedPitch;//r300->radeon.state.color.drawPitch; if (r300->radeon.radeonScreen->cpp == 4) r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888; else r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565; if (r300->radeon.sarea->tiling_enabled) r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;#if 0 R200_STATECHANGE( rmesa, ctx ); /* Note: we used the (possibly) page-flipped values */ rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((drb->flippedOffset + rmesa->r200Screen->fbLocation) & R200_COLOROFFSET_MASK); rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch; if (rmesa->sarea->tiling_enabled) { rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; }#endif}/* ============================================================= * Polygon state */static void r300PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units){ r300ContextPtr rmesa = R300_CONTEXT(ctx); GLfloat constant = units; switch (ctx->Visual.depthBits) { case 16: constant *= 4.0; break; case 24: constant *= 2.0; break; } factor *= 12.0;/* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */ R300_STATECHANGE(rmesa, zbs); rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] = r300PackFloat32(factor); rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] = r300PackFloat32(constant); rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] = r300PackFloat32(factor); rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT] = r300PackFloat32(constant);}/* Routing and texture-related *//* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST. * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead. * We need to recalculate wrap modes whenever filter mode is changed because someone might do: * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle * combinations where only one of them is nearest. */static unsigned long gen_fixed_filter(unsigned long f){ unsigned long mag, min, needs_fixing=0; //return f; /* We ignore MIRROR bit so we dont have to do everything twice */ if((f & ((7-1) << R300_TX_WRAP_S_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_S_SHIFT)){ needs_fixing |= 1; } if((f & ((7-1) << R300_TX_WRAP_T_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_T_SHIFT)){ needs_fixing |= 2; } if((f & ((7-1) << R300_TX_WRAP_Q_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_Q_SHIFT)){ needs_fixing |= 4; } if(!needs_fixing) return f; mag=f & R300_TX_MAG_FILTER_MASK; min=f & R300_TX_MIN_FILTER_MASK; /* TODO: Check for anisto filters too */ if((mag != R300_TX_MAG_FILTER_NEAREST) && (min != R300_TX_MIN_FILTER_NEAREST)) return f; /* r300 cant handle these modes hence we force nearest to linear */ if((mag == R300_TX_MAG_FILTER_NEAREST) && (min != R300_TX_MIN_FILTER_NEAREST)){ f &= ~R300_TX_MAG_FILTER_NEAREST; f |= R300_TX_MAG_FILTER_LINEAR; return f; } if((min == R300_TX_MIN_FILTER_NEAREST) && (mag != R300_TX_MAG_FILTER_NEAREST)){ f &= ~R300_TX_MIN_FILTER_NEAREST; f |= R300_TX_MIN_FILTER_LINEAR; return f; } /* Both are nearest */ if(needs_fixing & 1){ f &= ~((7-1) << R300_TX_WRAP_S_SHIFT); f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT; } if(needs_fixing & 2){ f &= ~((7-1) << R300_TX_WRAP_T_SHIFT); f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT; } if(needs_fixing & 4){ f &= ~((7-1) << R300_TX_WRAP_Q_SHIFT); f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_Q_SHIFT; } return f;}void r300_setup_textures(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 *rp = (struct r300_fragment_program *) (char *)ctx->FragmentProgram._Current; R300_STATECHANGE(r300, txe); R300_STATECHANGE(r300, tex.filter); R300_STATECHANGE(r300, tex.unknown1); R300_STATECHANGE(r300, tex.size); R300_STATECHANGE(r300, tex.format); R300_STATECHANGE(r300, tex.pitch); R300_STATECHANGE(r300, tex.offset); R300_STATECHANGE(r300, tex.unknown4); 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); exit(-1); } /* We cannot let disabled tmu offsets pass DRM */ for(i=0; i < mtu; i++) { if(TMU_ENABLED(ctx, i)) { #if 0 /* Enables old behaviour */ hw_tmu = i;#endif tmu_mappings[i] = hw_tmu; t=r300->state.texture.unit[i].texobj; 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); /* Currently disabled! */ r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; //0x20501f80; 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.unknown4.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_FILTER_0, last_hw_tmu + 1); r300->hw.tex.unknown1.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_PITCH_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.unknown4.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 (!rp) /* should only happenen once, just after context is created */ return; R300_STATECHANGE(r300, fpt); for(i = 0; i < rp->tex.length; i++){ int unit; unsigned long val; unit = rp->tex.inst[i] >> R300_FPITX_IMAGE_SHIFT; unit &= 15; val = rp->tex.inst[i]; val &= ~R300_FPITX_IMAGE_MASK; assert(tmu_mappings[unit] >= 0); val |= tmu_mappings[unit] << R300_FPITX_IMAGE_SHIFT; r300->hw.fpt.cmd[R300_FPT_INSTR_0+i] = val; } r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(R300_PFS_TEXI_0, rp->tex.length); 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);}void r300_setup_rs_unit(GLcontext *ctx){ r300ContextPtr r300 = R300_CONTEXT(ctx); /* I'm still unsure if these are needed */ GLuint interp_magic[8] = { 0x00, 0x40, 0x80, 0xC0, 0x00, 0x00, 0x00, 0x00 }; GLuint OutputsWritten; GLuint InputsRead; int fp_reg, high_rr; int in_texcoords, col_interp_nr; int i; if(hw_tcl_on) OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten; else OutputsWritten = r300->state.render_inputs; 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 = in_texcoords = col_interp_nr = high_rr = 0; r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0; r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0; for (i=0;i<ctx->Const.MaxTextureUnits;i++) { r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0 | R300_RS_INTERP_USED | (in_texcoords << R300_RS_INTERP_SRC_SHIFT) | interp_magic[i]; if (InputsRead & (FRAG_BIT_TEX0<<i)) { //assert(r300->state.texture.tc_count != 0); r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] = 0 | R300_RS_ROUTE_ENABLE | i /* source INTERP */ | (fp_reg << R300_RS_ROUTE_DEST_SHIFT); high_rr = fp_reg; if (!(OutputsWritten & (hw_tcl_on ? (1 << (VERT_RESULT_TEX0+i)) : (_TNL_BIT_TEX0<<i)))) { /* Passing invalid data here can lock the GPU. */ WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i); //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base); //exit(-1); } InputsRead &= ~(FRAG_BIT_TEX0<<i); fp_reg++; } /* Need to count all coords enabled at vof */ if (OutputsWritten & (hw_tcl_on ? (1 << (VERT_RESULT_TEX0+i)) : (_TNL_BIT_TEX0<<i))) in_texcoords++; } if (InputsRead & FRAG_BIT_COL0) { if (!(OutputsWritten & (hw_tcl_on ? (1<<VERT_RESULT_COL0) : _TNL_BIT_COLOR0))) { WARN_ONCE("fragprog wants col0, vp doesn't provide it\n"); goto out; /* FIXME */ //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base); //exit(-1); } r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT); InputsRead &= ~FRAG_BIT_COL0; col_interp_nr++; } out: if (InputsRead & FRAG_BIT_COL1) { if (!(OutputsWritten & (hw_tcl_on ? (1<<VERT_RESULT_COL1) : _TNL_BIT_COLOR1))) { WARN_ONCE("fragprog wants col1, vp doesn't provide it\n"); //exit(-1); } r300->hw.rr.cmd[R300_RR_ROUTE_1] |= R300_RS_ROUTE_1_UNKNOWN11 | R300_RS_ROUTE_1_COLOR1 | (fp_reg++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT); InputsRead &= ~FRAG_BIT_COL1; if (high_rr < 1) high_rr = 1; col_interp_nr++; } /* 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_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT); col_interp_nr++; } r300->hw.rc.cmd[1] = 0 | (in_texcoords << R300_RS_CNTL_TC_CNT_SHIFT) | (col_interp_nr << R300_RS_CNTL_CI_CNT_SHIFT) | R300_RS_CNTL_0_UNKNOWN_18; assert(high_rr >= 0); r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_ROUTE_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 vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)#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; \ if(_nc>_p->vpu.count)_p->vpu.count=_nc;\ }while(0)void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf){ int i; if(vsf->length==0)return; if(vsf->length & 0x3){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -