r300/vertprog: Refactor fog_as_texcoord to use rc_program

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
This commit is contained in:
Nicolai Hähnle
2009-07-25 00:41:05 +02:00
parent a1e8992ffa
commit ce0c32e3d2
4 changed files with 35 additions and 37 deletions
@@ -634,39 +634,6 @@ static void pos_as_texcoord(struct gl_program *prog, int tex_id)
prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id);
}
/**
* The fogcoord attribute is special in that only the first component
* is relevant, and the remaining components are always fixed (when read
* from by the fragment program) to yield an X001 pattern.
*
* We need to enforce this either in the vertex program or in the fragment
* program, and this code chooses not to enforce it in the vertex program.
* This is slightly cheaper, as long as the fragment program does not use
* weird swizzles.
*
* And it seems that usually, weird swizzles are not used, so...
*
* See also the counterpart rewriting for fragment programs.
*/
static void fog_as_texcoord(struct gl_program *prog, int tex_id)
{
struct prog_instruction *vpi;
vpi = prog->Instructions;
while (vpi->Opcode != OPCODE_END) {
if (vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_FOGC) {
vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id;
vpi->DstReg.WriteMask = WRITEMASK_X;
}
++vpi;
}
prog->OutputsWritten &= ~(1 << VERT_RESULT_FOGC);
prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id);
}
static void addArtificialOutputs(struct r300_vertex_program_compiler * compiler)
{
int i;
@@ -721,11 +688,12 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
pos_as_texcoord(compiler->program, compiler->state.WPosAttr - FRAG_ATTRIB_TEX0);
}
if (compiler->state.FogAttr != FRAG_ATTRIB_MAX) {
fog_as_texcoord(compiler->program, compiler->state.FogAttr - FRAG_ATTRIB_TEX0);
}
rc_mesa_to_rc_program(&compiler->Base, compiler->program);
compiler->program = 0;
if (compiler->state.FogAttr != FRAG_ATTRIB_MAX) {
rc_move_output(&compiler->Base, VERT_RESULT_FOGC, compiler->state.FogAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0, WRITEMASK_X);
}
addArtificialOutputs(compiler);
@@ -122,6 +122,32 @@ void rc_move_input(struct radeon_compiler * c, unsigned input, struct prog_src_r
}
/**
* Rewrite the program such that everything that writes into the given
* output register will instead write to new_output. The new_output
* writemask is honoured.
*/
void rc_move_output(struct radeon_compiler * c, unsigned output, unsigned new_output, unsigned writemask)
{
struct rc_instruction * inst;
c->Program.OutputsWritten &= ~(1 << output);
for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) {
const unsigned numdsts = _mesa_num_inst_dst_regs(inst->I.Opcode);
if (numdsts) {
if (inst->I.DstReg.File == PROGRAM_OUTPUT && inst->I.DstReg.Index == output) {
inst->I.DstReg.Index = new_output;
inst->I.DstReg.WriteMask &= writemask;
c->Program.OutputsWritten |= 1 << new_output;
}
}
}
}
/**
* Introduce standard code fragment to deal with fragment.position.
*/
@@ -65,6 +65,7 @@ void rc_debug(struct radeon_compiler * c, const char * fmt, ...);
void rc_error(struct radeon_compiler * c, const char * fmt, ...);
void rc_move_input(struct radeon_compiler * c, unsigned input, struct prog_src_register new_input);
void rc_move_output(struct radeon_compiler * c, unsigned output, unsigned new_output, unsigned writemask);
void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input);
struct r300_fragment_program_compiler {
@@ -161,6 +161,9 @@ static struct r300_vertex_program *build_program(GLcontext *ctx,
r3xx_compile_vertex_program(&compiler);
vp->error = compiler.Base.Error;
vp->Base->Base.InputsRead = vp->code.InputsRead;
vp->Base->Base.OutputsWritten = vp->code.OutputsWritten;
rc_destroy(&compiler.Base);
return vp;