summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c95
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_code.h1
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_compiler.h1
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h8
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c42
5 files changed, 69 insertions, 78 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
index 90910c45c6..53e62ae2f3 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -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 },
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
index 9cf4ed57bb..5489931434 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
@@ -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;
};
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
index 37519add05..74306994cb 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
@@ -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;
};
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 5c575441d7..629fd0af27 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -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;
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index fd2b9fcaf2..7dcf7d0383 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -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;