summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r300
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r300')
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c40
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_compiler.c26
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_compiler.h1
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c3
4 files changed, 34 insertions, 36 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
index 53e62ae2f3..38ee9575a3 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -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);
{
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
index adf900a5cb..6e7361d568 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
@@ -123,6 +123,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.
*/
void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input)
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
index 74306994cb..34f4240d53 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
@@ -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 {
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index 7dcf7d0383..27ec23975a 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -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;