r300/vertprog: Refactor fog_as_texcoord to use rc_program
authorNicolai Hähnle <nhaehnle@gmail.com>
Fri, 24 Jul 2009 22:41:05 +0000 (00:41 +0200)
committerNicolai Hähnle <nhaehnle@gmail.com>
Mon, 27 Jul 2009 20:51:36 +0000 (22:51 +0200)
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
src/mesa/drivers/dri/r300/r300_vertprog.c

index 53e62ae2f325edb55ab1f10de094c5d27f468563..38ee9575a324939db260867c9c4870644dec0357 100644 (file)
@@ -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,12 +688,13 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
                pos_as_texcoord(compiler->program, compiler->state.WPosAttr - FRAG_ATTRIB_TEX0);
        }
 
+       rc_mesa_to_rc_program(&compiler->Base, compiler->program);
+       compiler->program = 0;
+
        if (compiler->state.FogAttr != FRAG_ATTRIB_MAX) {
-               fog_as_texcoord(compiler->program, compiler->state.FogAttr - FRAG_ATTRIB_TEX0);
+               rc_move_output(&compiler->Base, VERT_RESULT_FOGC, compiler->state.FogAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0, WRITEMASK_X);
        }
 
-       rc_mesa_to_rc_program(&compiler->Base, compiler->program);
-
        addArtificialOutputs(compiler);
 
        {
index adf900a5cb3bfb6b23c5de27c45f12da28726685..6e7361d56865ea54c5e0c9989682190fd678064b 100644 (file)
@@ -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.
  */
index 74306994cbd83922f727f029939141eb19b54436..34f4240d534d89ab4aea38c011a6c7d497200c36 100644 (file)
@@ -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 {
index 7dcf7d03837e8b41b0c6a4815ddbdc823c647628..27ec23975a48172116873750b49986be5a552e23 100644 (file)
@@ -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;