static GLboolean r200IsProgramNative(struct gl_context *ctx, GLenum target, struct gl_program *prog) { struct r200_vertex_program *vp = (void *)prog; switch(target){ case GL_VERTEX_PROGRAM_ARB: if (!vp->translated) { r200_translate_vertex_program(ctx, vp); } /* does not take parameters etc. into account */ return vp->native; default: _mesa_problem(ctx, "Bad target in r200NewProgram"); } return 0; }
static void r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog) { struct r200_vertex_program *vp = (void *)prog; r200ContextPtr rmesa = R200_CONTEXT(ctx); switch(target) { case GL_VERTEX_PROGRAM_ARB: vp->translated = GL_FALSE; vp->fogpidx = 0; /* memset(&vp->translated, 0, sizeof(struct r200_vertex_program) - sizeof(struct gl_vertex_program));*/ r200_translate_vertex_program(ctx, vp); rmesa->curr_vp_hw = NULL; break; case GL_FRAGMENT_SHADER_ATI: rmesa->afs_loaded = NULL; break; } /* need this for tcl fallbacks */ _tnl_program_string(ctx, target, prog); }
void r200SetupVertexProg( struct gl_context *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); struct r200_vertex_program *vp = (struct r200_vertex_program *)ctx->VertexProgram.Current; GLboolean fallback; GLint i; if (!vp->translated || (ctx->Fog.Enabled && ctx->Fog.Mode != vp->fogmode)) { rmesa->curr_vp_hw = NULL; r200_translate_vertex_program(ctx, vp); } /* could optimize setting up vertex progs away for non-tcl hw */ fallback = !(vp->native && r200VertexProgUpdateParams(ctx, vp)); TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, fallback); if (rmesa->radeon.TclFallback) return; R200_STATECHANGE( rmesa, vap ); /* FIXME: fglrx sets R200_VAP_SINGLE_BUF_STATE_ENABLE too. Do we need it? maybe only when using more than 64 inst / 96 param? */ rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE /*| R200_VAP_SINGLE_BUF_STATE_ENABLE*/; R200_STATECHANGE( rmesa, pvs ); rmesa->hw.pvs.cmd[PVS_CNTL_1] = (0 << R200_PVS_CNTL_1_PROGRAM_START_SHIFT) | ((vp->mesa_program.Base.NumNativeInstructions - 1) << R200_PVS_CNTL_1_PROGRAM_END_SHIFT) | (vp->pos_end << R200_PVS_CNTL_1_POS_END_SHIFT); rmesa->hw.pvs.cmd[PVS_CNTL_2] = (0 << R200_PVS_CNTL_2_PARAM_OFFSET_SHIFT) | (vp->mesa_program.Base.NumNativeParameters << R200_PVS_CNTL_2_PARAM_COUNT_SHIFT); /* maybe user clip planes just work with vertex progs... untested */ if (ctx->Transform.ClipPlanesEnabled) { R200_STATECHANGE( rmesa, tcl ); if (vp->mesa_program.IsPositionInvariant) { rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (ctx->Transform.ClipPlanesEnabled << 2); } else { rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(0xfc); } } if (vp != rmesa->curr_vp_hw) { GLuint count = vp->mesa_program.Base.NumNativeInstructions; drm_radeon_cmd_header_t tmp; R200_STATECHANGE( rmesa, vpi[0] ); R200_STATECHANGE( rmesa, vpi[1] ); /* FIXME: what about using a memcopy... */ for (i = 0; (i < 64) && i < count; i++) { rmesa->hw.vpi[0].cmd[VPI_OPDST_0 + 4 * i] = vp->instr[i].op; rmesa->hw.vpi[0].cmd[VPI_SRC0_0 + 4 * i] = vp->instr[i].src0; rmesa->hw.vpi[0].cmd[VPI_SRC1_0 + 4 * i] = vp->instr[i].src1; rmesa->hw.vpi[0].cmd[VPI_SRC2_0 + 4 * i] = vp->instr[i].src2; } /* hack up the cmd_size so not the whole state atom is emitted always. This may require some more thought, we may emit half progs on lost state, but hopefully it won't matter? WARNING: must not use R200_DB_STATECHANGE, this will produce bogus (and rejected) packet emits (due to the mismatched cmd_size and count in cmd/last_cmd) */ rmesa->hw.vpi[0].cmd_size = 1 + 4 * ((count > 64) ? 64 : count); tmp.i = rmesa->hw.vpi[0].cmd[VPI_CMD_0]; tmp.veclinear.count = (count > 64) ? 64 : count; rmesa->hw.vpi[0].cmd[VPI_CMD_0] = tmp.i; if (count > 64) { for (i = 0; i < (count - 64); i++) { rmesa->hw.vpi[1].cmd[VPI_OPDST_0 + 4 * i] = vp->instr[i + 64].op; rmesa->hw.vpi[1].cmd[VPI_SRC0_0 + 4 * i] = vp->instr[i + 64].src0; rmesa->hw.vpi[1].cmd[VPI_SRC1_0 + 4 * i] = vp->instr[i + 64].src1; rmesa->hw.vpi[1].cmd[VPI_SRC2_0 + 4 * i] = vp->instr[i + 64].src2; } rmesa->hw.vpi[1].cmd_size = 1 + 4 * (count - 64); tmp.i = rmesa->hw.vpi[1].cmd[VPI_CMD_0]; tmp.veclinear.count = count - 64; rmesa->hw.vpi[1].cmd[VPI_CMD_0] = tmp.i; } rmesa->curr_vp_hw = vp; } }