#include "utils.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
-int hw_vertprog_on=1;
+int hw_tcl_on=1;
/* Extension strings exported by the R300 driver.
*/
/* Try and go straight to t&l
*/
- //&_r300_tcl_stage,
+ &_r300_tcl_stage,
/* Catch any t&l fallbacks
*/
int unknown_ptr3; /* pointer within program space */
};
-extern int hw_vertprog_on;
-#define VERTPROG_ACTIVE(ctx) ( ctx->VertexProgram._Enabled && (R300_CONTEXT(ctx)->current_vp != NULL) && \
- (R300_CONTEXT(ctx)->current_vp->translated) && hw_vertprog_on)
-
+extern int hw_tcl_on;
+
+#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Enabled ? ctx->VertexProgram.Current : &ctx->_TnlProgram)
+
+//#define TMU_ENABLED(ctx, unit) (hw_tcl_on ? ctx->Texture.Unit[unit]._ReallyEnabled && (OutputsWritten & (1<<(VERT_RESULT_TEX0+(unit)))) : \
+// (r300->state.render_inputs & (_TNL_BIT_TEX0<<(unit))))
+#define TMU_ENABLED(ctx, unit) (hw_tcl_on ? ctx->Texture.Unit[unit]._ReallyEnabled && OutputsWritten & (1<<(VERT_RESULT_TEX0+(unit))) : \
+ ctx->Texture.Unit[unit]._ReallyEnabled && r300->state.render_inputs & (_TNL_BIT_TEX0<<(unit)))
+
/* r300_vertex_shader_state and r300_vertex_program should probably be merged together someday.
* Keeping them them seperate for now should ensure fixed pipeline keeps functioning properly.
*/
int t2rs;
unsigned long num_temporaries; /* Number of temp vars used by program */
int inputs[VERT_ATTRIB_MAX];
- GLuint outputs;
};
/* 64 appears to be the maximum */
GLuint TexGenInputs;
GLuint TexGenCompSel;
GLmatrix tmpmat;
-
- struct r300_vertex_program *current_vp;
};
#define R300_CONTEXT(ctx) ((r300ContextPtr)(ctx->DriverCtx))
GLuint vic_1 = 0; /* R300_VAP_INPUT_CNTL_1 */
GLuint aa_vap_reg = 0; /* VAP register assignment */
GLuint i;
- GLuint inputs = 0, outputs = 0;
+ GLuint inputs = 0;
+ GLuint InputsRead = CURRENT_VERTEX_SHADER(ctx)->InputsRead;
#define CONFIGURE_AOS(r, f, v, sz, cn) { \
exit(-1); \
} \
\
- if (VERTPROG_ACTIVE(ctx) == GL_FALSE) \
+ if (hw_tcl_on == GL_FALSE) \
rmesa->state.aos[nr-1].aos_reg = aa_vap_reg++; \
rmesa->state.aos[nr-1].aos_format = f; \
if (immd) { \
} \
}
- if (VERTPROG_ACTIVE(ctx)) {
- if (rmesa->current_vp->inputs[VERT_ATTRIB_POS] != -1) {
+ if (hw_tcl_on) {
+ struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
+ if (InputsRead & (1<<VERT_ATTRIB_POS)) {
inputs |= _TNL_BIT_POS;
- rmesa->state.aos[nr++].aos_reg = rmesa->current_vp->inputs[VERT_ATTRIB_POS];
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_POS];
}
- if (rmesa->current_vp->inputs[VERT_ATTRIB_NORMAL] != -1) {
+ if (InputsRead & (1<<VERT_ATTRIB_NORMAL)) {
inputs |= _TNL_BIT_NORMAL;
- rmesa->state.aos[nr++].aos_reg = rmesa->current_vp->inputs[VERT_ATTRIB_NORMAL];
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_NORMAL];
}
- if (rmesa->current_vp->inputs[VERT_ATTRIB_COLOR0] != -1) {
+ if (InputsRead & (1<<VERT_ATTRIB_COLOR0)) {
inputs |= _TNL_BIT_COLOR0;
- rmesa->state.aos[nr++].aos_reg = rmesa->current_vp->inputs[VERT_ATTRIB_COLOR0];
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR0];
}
- if (rmesa->current_vp->inputs[VERT_ATTRIB_COLOR1] != -1) {
+ if (InputsRead & (1<<VERT_ATTRIB_COLOR1)) {
inputs |= _TNL_BIT_COLOR1;
- rmesa->state.aos[nr++].aos_reg = rmesa->current_vp->inputs[VERT_ATTRIB_COLOR1];
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR1];
}
- if (rmesa->current_vp->inputs[VERT_ATTRIB_FOG] != -1) {
+ if (InputsRead & (1<<VERT_ATTRIB_FOG)) {
inputs |= _TNL_BIT_FOG;
- rmesa->state.aos[nr++].aos_reg = rmesa->current_vp->inputs[VERT_ATTRIB_FOG];
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_FOG];
}
if(ctx->Const.MaxTextureUnits > 8) { /* Not sure if this can even happen... */
fprintf(stderr, "%s: Cant handle that many inputs\n", __FUNCTION__);
exit(-1);
}
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
- if (rmesa->current_vp->inputs[VERT_ATTRIB_TEX0+i] != -1) {
+ if (InputsRead & (1<<(VERT_ATTRIB_TEX0+i))) {
inputs |= _TNL_BIT_TEX0<<i;
- rmesa->state.aos[nr++].aos_reg = rmesa->current_vp->inputs[VERT_ATTRIB_TEX0+i];
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_TEX0+i];
}
}
nr = 0;
} else {
inputs = TNL_CONTEXT(ctx)->render_inputs;
- /* Hack to see what would happen if we would enable tex units according to their enabled values.
- Why arent we doing this?
- As for vertex programs tex coords should be passed if program wants them as some programs might deliver
- some other values to the program with them. Futher more some programs might generate output tex coords
- without taking them as inputs. */
- /*for (i=0;i<ctx->Const.MaxTextureUnits;i++)
- if(ctx->Texture.Unit[i].Enabled == 0)
- inputs &= ~ (_TNL_BIT_TEX0<<i);*/
}
rmesa->state.render_inputs = inputs;
#endif
/* Stage 3: VAP output */
- if (VERTPROG_ACTIVE(ctx))
- outputs = rmesa->current_vp->outputs;
- else
- outputs = inputs;
R300_STATECHANGE(r300, vof);
r300->hw.vof.cmd[R300_VOF_CNTL_0]=0;
- if(outputs & _TNL_BIT_POS)
- r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
- if(outputs & _TNL_BIT_COLOR0)
- r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
-
r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
- for(i=0;i < ctx->Const.MaxTextureUnits;i++)
- if(outputs & (_TNL_BIT_TEX0<<i))
- r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
+ if (hw_tcl_on){
+ GLuint OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->OutputsWritten;
+
+ if(OutputsWritten & (1<<VERT_RESULT_HPOS))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ if(OutputsWritten & (1<<VERT_RESULT_COL0))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
+ /*if(OutputsWritten & (1<<VERT_RESULT_COL1))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
+ if(OutputsWritten & (1<<VERT_RESULT_BFC0))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
+ if(OutputsWritten & (1<<VERT_RESULT_BFC1))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;*/
+ //if(OutputsWritten & (1<<VERT_RESULT_FOGC))
+ //if(OutputsWritten & (1<<VERT_RESULT_PSIZ))
+
+ for(i=0;i < ctx->Const.MaxTextureUnits;i++)
+ if(OutputsWritten & (1<<(VERT_RESULT_TEX0+i)))
+ r300->hw.vof.cmd[R300_VOF_CNTL_1] |= (4<<(3*i));
+ } else {
+ if(inputs & _TNL_BIT_POS)
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ if(inputs & _TNL_BIT_COLOR0)
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
+
+ for(i=0;i < ctx->Const.MaxTextureUnits;i++)
+ if(inputs & (_TNL_BIT_TEX0<<i))
+ r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
+ }
rmesa->state.aos_count = nr;
}
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
+ if(hw_tcl_on == GL_FALSE)
+ return GL_TRUE;
+ if(ctx->VertexProgram._Enabled == GL_FALSE){
+ _tnl_UpdateFixedFunctionProgram(ctx);
+ r300ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, &ctx->_TnlProgram);
+ }
return r300_run_vb_render(ctx, stage);
}
//stage->active = GL_FALSE;
return;
}
- if(VERTPROG_ACTIVE(ctx)) {
- //stage->active = GL_TRUE;
- //stage->inputs = ctx->VertexProgram.Current->InputsRead;
- } else {
- //stage->active = GL_FALSE;
- }
}
const struct tnl_pipeline_stage _r300_tcl_stage = {
switch(target){
case GL_VERTEX_PROGRAM_ARB:
- rmesa->current_vp = vp;
+ //rmesa->current_vp = vp;
break;
default:
WARN_ONCE("Target not supported yet!\n");
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_vertex_program *vp=(void *)prog;
- if(rmesa->current_vp == vp)
- rmesa->current_vp = NULL;
+ /*if(rmesa->current_vp == vp)
+ rmesa->current_vp = NULL;*/
_mesa_delete_program(ctx, prog);
}
-static void r300ProgramStringNotify(GLcontext *ctx, GLenum target,
+void r300ProgramStringNotify(GLcontext *ctx, GLenum target,
struct program *prog)
{
struct r300_vertex_program *vp=(void *)prog;
}
/* Routing and texture-related */
-
+#if 0
void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
{
int i, count=0,reg=0;
r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
}
-
+#endif
static r300TexObj default_tex_obj={
filter:R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR,
pitch: 0x8000,
r300ContextPtr r300 = R300_CONTEXT(ctx);
int max_texture_unit=-1; /* -1 translates into no setup costs for fields */
struct gl_texture_unit *texUnit;
+ GLuint OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->OutputsWritten;
R300_STATECHANGE(r300, txe);
R300_STATECHANGE(r300, tex.filter);
}
for(i=0; i < mtu; i++) {
- /*if(ctx->Texture.Unit[i].Enabled == 0)
- continue;*/
- if( ((r300->state.render_inputs & (_TNL_BIT_TEX0<<i))!=0) != ((ctx->Texture.Unit[i].Enabled)!=0) ) {
+ /*if( ((r300->state.render_inputs & (_TNL_BIT_TEX0<<i))!=0) != ((ctx->Texture.Unit[i].Enabled)!=0) ) {
WARN_ONCE("Mismatch between render_inputs and ctx->Texture.Unit[i].Enabled value(%d vs %d).\n",
((r300->state.render_inputs & (_TNL_BIT_TEX0<<i))!=0), ((ctx->Texture.Unit[i].Enabled)!=0));
- }
+ }*/
- if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i)) {
+ if(TMU_ENABLED(ctx, i)) {
t=r300->state.texture.unit[i].texobj;
//fprintf(stderr, "format=%08x\n", r300->state.texture.unit[i].format);
r300->state.texture.tc_count++;
0x00,
0x00
};
- GLuint vap_outputs;
+ GLuint OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->OutputsWritten;
/* This needs to be rewritten - it is a hack at best */
cur_reg = 0;
r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0;
- if (VERTPROG_ACTIVE(ctx))
- vap_outputs = r300->current_vp->outputs;
- else
- vap_outputs = r300->state.render_inputs;
-
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0
| R300_RS_INTERP_USED
| interp_magic[i];
// fprintf(stderr, "RS_INTERP[%d] = 0x%x\n", i, r300->hw.ri.cmd[R300_RI_INTERP_0+i]);
- if (r300->state.render_inputs & (_TNL_BIT_TEX0<<i)) {
+ if (TMU_ENABLED(ctx, i)) {
assert(r300->state.texture.tc_count != 0);
r300->hw.rr.cmd[R300_RR_ROUTE_0 + cur_reg] = 0
| R300_RS_ROUTE_ENABLE
cur_reg++;
}
}
- if (vap_outputs & _TNL_BIT_COLOR0)
+ if (hw_tcl_on ? OutputsWritten & (1<<VERT_RESULT_COL0) : r300->state.render_inputs & _TNL_BIT_COLOR0)
r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0
| R300_RS_ROUTE_0_COLOR
| (cur_reg << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
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(VERTPROG_ACTIVE(ctx)){
+ if(hw_tcl_on && ((struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx))->translated){
r300SetupVertexProgram(rmesa);
return ;
}
int inst_count;
int param_count;
LOCAL_VARS
+ struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
/* Reset state, in case we don't use something */
((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;
- r300VertexProgUpdateParams(ctx, rmesa->current_vp);
+ r300VertexProgUpdateParams(ctx, prog);
- setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->current_vp->program));
+ setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(prog->program));
- setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->current_vp->params));
+ setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(prog->params));
#if 0
setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));
setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));
#endif
- inst_count=rmesa->current_vp->program.length/4 - 1;
- param_count=rmesa->current_vp->params.length/4;
+ inst_count=prog->program.length/4 - 1;
+ param_count=prog->params.length/4;
R300_STATECHANGE(rmesa, pvs);
rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
| (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
- | ((inst_count-rmesa->current_vp->t2rs) /*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
+ | (inst_count /*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
/* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
so I leave it as a reminder */
int i, mtu;
mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
GLenum envMode;
+ GLuint OutputsWritten = CURRENT_VERTEX_SHADER(r300->radeon.glCtx)->OutputsWritten;
int tex_inst=0, alu_inst=0;
for(i=0;i<mtu;i++){
/* No need to proliferate {} */
- if(! (r300->state.render_inputs & (_TNL_BIT_TEX0<<i)))continue;
+ if(!TMU_ENABLED(r300->radeon.glCtx, i))continue;
envMode = r300->radeon.glCtx->Texture.Unit[i].EnvMode;
//fprintf(stderr, "envMode=%s\n", _mesa_lookup_enum_by_nr(envMode));
struct r300_pixel_shader_program *p = &ps->program;
GLcontext *ctx = r300->radeon.glCtx;
int i, tc_reg;
+ GLuint OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->OutputsWritten;
p->tex.length = 0;
p->alu.length = 0;
tc_reg = 0;
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
- if (r300->state.render_inputs & (_TNL_BIT_TEX0<<i)) {
+ if (TMU_ENABLED(ctx, i)) {
ps->have_sample = 0;
ps->src_previous = emit_texenv(r300, tc_reg, i);
tc_reg++;
static unsigned long t_dst_index(struct r300_vertex_program *vp, struct vp_dst_register *dst)
{
+ if(dst->File == PROGRAM_OUTPUT)
+ switch(dst->Index){
+ case VERT_RESULT_HPOS:
+ return 0;
+ case VERT_RESULT_COL0:
+ return 1;
+ case VERT_RESULT_TEX0:
+ return 2;
+ case VERT_RESULT_TEX1:
+ return 3;
+ case VERT_RESULT_TEX2:
+ return 4;
+ case VERT_RESULT_TEX3:
+ return 5;
+ case VERT_RESULT_TEX4:
+ return 6;
+ case VERT_RESULT_TEX5:
+ return 7;
+ case VERT_RESULT_TEX6:
+ return 8;
+ case VERT_RESULT_TEX7:
+ return 9;
+ case VERT_RESULT_COL1:
+ case VERT_RESULT_BFC0:
+ case VERT_RESULT_BFC1:
+ case VERT_RESULT_FOGC:
+ case VERT_RESULT_PSIZ:
+ default: WARN_ONCE("Unknown output\n"); return 1;
+ }
return dst->Index;
}
for(i=0; i < VERT_ATTRIB_MAX; i++)
vp->inputs[i]=-1;
- vp->outputs = 0;
- /* FIXME: hardcoded values in arbprogparse.c:parse_result_binding ()
- We might want to use these constants for VAP output in general as well once they have been added to
- mesa headers.
- */
- if(mesa_vp->OutputsWritten & (1<<0))
- vp->outputs |= _TNL_BIT_POS;
- if(mesa_vp->OutputsWritten & (1<<1))
- vp->outputs |= _TNL_BIT_COLOR0;
- if(mesa_vp->OutputsWritten & (1<<2))
- vp->outputs |= _TNL_BIT_COLOR1;
- for(i=0; i < 8/*ctx->Const.MaxTextureUnits*/; i++)
- if(mesa_vp->OutputsWritten & (1<<(7+i)))
- vp->outputs |= _TNL_BIT_TEX(i);
- if(mesa_vp->OutputsWritten & ~(0x7 | 0x3f80))
- fprintf(stderr, "%s:Odd bits(0x%08x)\n", __FUNCTION__, mesa_vp->OutputsWritten);
-
o_inst=vp->program.body.i;
for(vpi=mesa_vp->Instructions; vpi->Opcode != VP_OPCODE_END; vpi++, o_inst++){