r300/vertprog: Refactor addArtificialOutputs to use rc_program
authorNicolai Hähnle <nhaehnle@gmail.com>
Fri, 24 Jul 2009 22:07:46 +0000 (00:07 +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_code.h
src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_vertprog.c

index 90910c45c62b57582b00e11350ee2948977d12e4..53e62ae2f325edb55ab1f10de094c5d27f468563 100644 (file)
@@ -667,93 +667,42 @@ static void fog_as_texcoord(struct gl_program *prog, int tex_id)
 }
 
 
-#define ADD_OUTPUT(fp_attr, vp_result) \
-       do { \
-               if ((FpReads & (1 << (fp_attr))) && !(compiler->program->OutputsWritten & (1 << (vp_result)))) { \
-                       OutputsAdded |= 1 << (vp_result); \
-                       count++; \
-               } \
-       } while (0)
-
 static void addArtificialOutputs(struct r300_vertex_program_compiler * compiler)
 {
-       GLuint OutputsAdded, FpReads;
-       int i, count;
-
-       OutputsAdded = 0;
-       count = 0;
-       FpReads = compiler->state.FpReads;
-
-       ADD_OUTPUT(FRAG_ATTRIB_COL0, VERT_RESULT_COL0);
-       ADD_OUTPUT(FRAG_ATTRIB_COL1, VERT_RESULT_COL1);
-
-       for (i = 0; i < 7; ++i) {
-               ADD_OUTPUT(FRAG_ATTRIB_TEX0 + i, VERT_RESULT_TEX0 + i);
-       }
-
-       /* Some outputs may be artificially added, to match the inputs of the fragment program.
-        * Issue 16 of vertex program spec says that all vertex attributes that are unwritten by
-        * vertex program are undefined, so just use MOV [vertex_result], CONST[0]
-        */
-       if (count > 0) {
-               struct prog_instruction *inst;
-
-               _mesa_insert_instructions(compiler->program, compiler->program->NumInstructions - 1, count);
-               inst = &compiler->program->Instructions[compiler->program->NumInstructions - 1 - count];
+       int i;
 
-               for (i = 0; i < VERT_RESULT_MAX; ++i) {
-                       if (OutputsAdded & (1 << i)) {
-                               inst->Opcode = OPCODE_MOV;
+       for(i = 0; i < 32; ++i) {
+               if ((compiler->RequiredOutputs & (1 << i)) &&
+                   !(compiler->Base.Program.OutputsWritten & (1 << i))) {
+                       struct rc_instruction * inst = rc_insert_new_instruction(&compiler->Base, compiler->Base.Program.Instructions.Prev);
+                       inst->I.Opcode = OPCODE_MOV;
 
-                               inst->DstReg.File = PROGRAM_OUTPUT;
-                               inst->DstReg.Index = i;
-                               inst->DstReg.WriteMask = WRITEMASK_XYZW;
-                               inst->DstReg.CondMask = COND_TR;
+                       inst->I.DstReg.File = PROGRAM_OUTPUT;
+                       inst->I.DstReg.Index = i;
+                       inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
 
-                               inst->SrcReg[0].File = PROGRAM_CONSTANT;
-                               inst->SrcReg[0].Index = 0;
-                               inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
+                       inst->I.SrcReg[0].File = PROGRAM_CONSTANT;
+                       inst->I.SrcReg[0].Index = 0;
+                       inst->I.SrcReg[0].Swizzle = SWIZZLE_XYZW;
 
-                               ++inst;
-                       }
+                       compiler->Base.Program.OutputsWritten |= 1 << i;
                }
-
-               compiler->program->OutputsWritten |= OutputsAdded;
        }
 }
 
-#undef ADD_OUTPUT
-
 static void nqssadceInit(struct nqssadce_state* s)
 {
        struct r300_vertex_program_compiler * compiler = s->UserData;
-       GLuint fp_reads;
-
-       fp_reads = compiler->state.FpReads;
-       {
-               if (fp_reads & FRAG_BIT_COL0) {
-                               s->Outputs[VERT_RESULT_COL0].Sourced = WRITEMASK_XYZW;
-                               s->Outputs[VERT_RESULT_BFC0].Sourced = WRITEMASK_XYZW;
-               }
+       int i;
 
-               if (fp_reads & FRAG_BIT_COL1) {
-                               s->Outputs[VERT_RESULT_COL1].Sourced = WRITEMASK_XYZW;
-                               s->Outputs[VERT_RESULT_BFC1].Sourced = WRITEMASK_XYZW;
+       for(i = 0; i < VERT_RESULT_MAX; ++i) {
+               if (compiler->RequiredOutputs & (1 << i)) {
+                       if (i != VERT_RESULT_PSIZ)
+                               s->Outputs[i].Sourced = WRITEMASK_XYZW;
+                       else
+                               s->Outputs[i].Sourced = WRITEMASK_X; /* ugly hack! */
                }
        }
-
-       {
-               int i;
-               for (i = 0; i < 8; ++i) {
-                       if (fp_reads & FRAG_BIT_TEX(i)) {
-                               s->Outputs[VERT_RESULT_TEX0 + i].Sourced = WRITEMASK_XYZW;
-                       }
-               }
-       }
-
-       s->Outputs[VERT_RESULT_HPOS].Sourced = WRITEMASK_XYZW;
-       if (s->Compiler->Program.OutputsWritten & (1 << VERT_RESULT_PSIZ))
-               s->Outputs[VERT_RESULT_PSIZ].Sourced = WRITEMASK_X;
 }
 
 static GLboolean swizzleIsNative(GLuint opcode, struct prog_src_register reg)
@@ -776,10 +725,10 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
                fog_as_texcoord(compiler->program, compiler->state.FogAttr - FRAG_ATTRIB_TEX0);
        }
 
-       addArtificialOutputs(compiler);
-
        rc_mesa_to_rc_program(&compiler->Base, compiler->program);
 
+       addArtificialOutputs(compiler);
+
        {
                struct radeon_program_transformation transformations[] = {
                        { &r300_transform_vertex_alu, 0 },
index 9cf4ed57bb50ebbf5269f49224d78ffa74394d9a..5489931434fe7051ca8444cd2fb7cc0b6ccbd30b 100644 (file)
@@ -186,7 +186,6 @@ struct rX00_fragment_program_code {
 #define VSF_MAX_FRAGMENT_TEMPS (14)
 
 struct r300_vertex_program_external_state {
-       GLuint FpReads;
        GLuint FogAttr;
        GLuint WPosAttr;
 };
index 37519add05496762aaf2c25ee506e03f3cc432a0..74306994cbd83922f727f029939141eb19b54436 100644 (file)
@@ -82,6 +82,7 @@ struct r300_vertex_program_compiler {
        struct radeon_compiler Base;
        struct r300_vertex_program_code *code;
        struct r300_vertex_program_external_state state;
+       GLbitfield RequiredOutputs;
        struct gl_program *program;
 };
 
index 5c575441d7b381376744828e9948ad25106a5de3..629fd0af27453e946594a9f919f28bc2bc72b350 100644 (file)
@@ -395,11 +395,17 @@ struct r300_hw_state {
 #include "tnl_dd/t_dd_vertex.h"
 #undef TAG
 
+struct r300_vertex_program_key {
+       GLbitfield FpReads;
+       GLuint FogAttr;
+       GLuint WPosAttr;
+};
+
 struct r300_vertex_program {
        struct gl_vertex_program *Base;
        struct r300_vertex_program *next;
 
-       struct r300_vertex_program_external_state key;
+       struct r300_vertex_program_key key;
        struct r300_vertex_program_code code;
 
        GLboolean error;
index fd2b9fcaf26296ab2fda8865e5e419dfbe2828d8..7dcf7d03837e8b41b0c6a4815ddbdc823c647628 100644 (file)
@@ -94,8 +94,42 @@ static int r300VertexProgUpdateParams(GLcontext * ctx, struct r300_vertex_progra
        return 4 * vp->code.constants.Count;
 }
 
+static GLbitfield compute_required_outputs(struct gl_vertex_program * vp, GLbitfield fpreads)
+{
+       GLbitfield outputs = 0;
+       int i;
+
+#define ADD_OUTPUT(fp_attr, vp_result) \
+       do { \
+               if (fpreads & (1 << (fp_attr))) \
+                       outputs |= (1 << (vp_result)); \
+       } while (0)
+
+       ADD_OUTPUT(FRAG_ATTRIB_COL0, VERT_RESULT_COL0);
+       ADD_OUTPUT(FRAG_ATTRIB_COL1, VERT_RESULT_COL1);
+
+       for (i = 0; i <= 7; ++i) {
+               ADD_OUTPUT(FRAG_ATTRIB_TEX0 + i, VERT_RESULT_TEX0 + i);
+       }
+
+#undef ADD_OUTPUT
+
+       if ((fpreads & (1 << FRAG_ATTRIB_COL0)) &&
+           (vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC0)))
+               outputs |= 1 << VERT_RESULT_BFC0;
+       if ((fpreads & (1 << FRAG_ATTRIB_COL1)) &&
+           (vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC1)))
+               outputs |= 1 << VERT_RESULT_BFC1;
+
+       outputs |= 1 << VERT_RESULT_HPOS;
+       if (vp->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ))
+               outputs |= 1 << VERT_RESULT_PSIZ;
+
+       return outputs;
+}
+
 static struct r300_vertex_program *build_program(GLcontext *ctx,
-                                                struct r300_vertex_program_external_state *wanted_key,
+                                                struct r300_vertex_program_key *wanted_key,
                                                 const struct gl_vertex_program *mesa_vp)
 {
        struct r300_vertex_program *vp;
@@ -109,7 +143,9 @@ static struct r300_vertex_program *build_program(GLcontext *ctx,
        compiler.Base.Debug = (RADEON_DEBUG & DEBUG_VERTS) ? GL_TRUE : GL_FALSE;
 
        compiler.code = &vp->code;
-       compiler.state = vp->key;
+       compiler.state.FogAttr = vp->key.FogAttr;
+       compiler.state.WPosAttr = vp->key.WPosAttr;
+       compiler.RequiredOutputs = compute_required_outputs(vp->Base, vp->key.FpReads);
        compiler.program = &vp->Base->Base;
 
        if (compiler.Base.Debug) {
@@ -133,7 +169,7 @@ static struct r300_vertex_program *build_program(GLcontext *ctx,
 struct r300_vertex_program * r300SelectAndTranslateVertexShader(GLcontext *ctx)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
-       struct r300_vertex_program_external_state wanted_key = { 0 };
+       struct r300_vertex_program_key wanted_key = { 0 };
        struct r300_vertex_program_cont *vpc;
        struct r300_vertex_program *vp;