summaryrefslogtreecommitdiff
path: root/src/mesa/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c1
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program.c35
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c31
3 files changed, 61 insertions, 6 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
index 93a516105e..dad27fc98e 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -89,6 +89,7 @@ static unsigned long t_dst_index(struct r300_vertex_program_code *vp,
static unsigned long t_src_class(gl_register_file file)
{
switch (file) {
+ case PROGRAM_BUILTIN:
case PROGRAM_TEMPORARY:
return PVS_SRC_REG_TEMPORARY;
case PROGRAM_INPUT:
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.c b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
index bbbf0dd776..b636f90a96 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
@@ -150,14 +150,37 @@ void rc_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * progr
c->Program.InputsRead = program->InputsRead;
c->Program.OutputsWritten = program->OutputsWritten;
- for(i = 0; i < program->Parameters->NumParameters; ++i) {
- struct rc_constant constant;
+ int isNVProgram = 0;
- constant.Type = RC_CONSTANT_EXTERNAL;
- constant.Size = 4;
- constant.u.External = i;
+ if (program->Target == GL_VERTEX_PROGRAM_ARB) {
+ struct gl_vertex_program * vp = (struct gl_vertex_program *) program;
+ isNVProgram = vp->IsNVProgram;
+ }
+
+ if (isNVProgram) {
+ /* NV_vertex_program has a fixed-sized constant environment.
+ * This could be handled more efficiently for programs that
+ * do not use relative addressing.
+ */
+ for(i = 0; i < 96; ++i) {
+ struct rc_constant constant;
- rc_constants_add(&c->Program.Constants, &constant);
+ constant.Type = RC_CONSTANT_EXTERNAL;
+ constant.Size = 4;
+ constant.u.External = i;
+
+ rc_constants_add(&c->Program.Constants, &constant);
+ }
+ } else {
+ for(i = 0; i < program->Parameters->NumParameters; ++i) {
+ struct rc_constant constant;
+
+ constant.Type = RC_CONSTANT_EXTERNAL;
+ constant.Size = 4;
+ constant.u.External = i;
+
+ rc_constants_add(&c->Program.Constants, &constant);
+ }
}
}
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index dd0f27f9cb..0cb7dde985 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -203,6 +203,34 @@ static void t_inputs_outputs(struct r300_vertex_program_compiler * c)
}
}
+/**
+ * The NV_vertex_program spec mandates that all registers be
+ * initialized to zero. We do this here unconditionally.
+ *
+ * \note We rely on dead-code elimination in the compiler.
+ */
+static void initialize_NV_registers(struct radeon_compiler * compiler)
+{
+ unsigned int reg;
+ struct rc_instruction * inst;
+
+ for(reg = 0; reg < 12; ++reg) {
+ inst = rc_insert_new_instruction(compiler, &compiler->Program.Instructions);
+ inst->I.Opcode = OPCODE_MOV;
+ inst->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst->I.DstReg.Index = reg;
+ inst->I.SrcReg[0].File = PROGRAM_BUILTIN;
+ inst->I.SrcReg[0].Swizzle = SWIZZLE_0000;
+ }
+
+ inst = rc_insert_new_instruction(compiler, &compiler->Program.Instructions);
+ inst->I.Opcode = OPCODE_ARL;
+ inst->I.DstReg.File = PROGRAM_ADDRESS;
+ inst->I.DstReg.Index = 0;
+ inst->I.DstReg.WriteMask = WRITEMASK_X;
+ inst->I.SrcReg[0].File = PROGRAM_BUILTIN;
+ inst->I.SrcReg[0].Swizzle = SWIZZLE_0000;
+}
static struct r300_vertex_program *build_program(GLcontext *ctx,
struct r300_vertex_program_key *wanted_key,
@@ -234,6 +262,9 @@ static struct r300_vertex_program *build_program(GLcontext *ctx,
rc_mesa_to_rc_program(&compiler.Base, &vp->Base->Base);
+ if (mesa_vp->IsNVProgram)
+ initialize_NV_registers(&compiler.Base);
+
rc_move_output(&compiler.Base, VERT_RESULT_PSIZ, VERT_RESULT_PSIZ, WRITEMASK_X);
if (vp->key.WPosAttr != FRAG_ATTRIB_MAX) {