Fix up some assorted issues with initialization of vertex program registers.
Some need to be set per-vertex, other per-primitive. Cleared that up.
Only need to init temp/result registers if executing an NV vertex program.
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index aeeab82..a86b2ce 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1559,6 +1559,7 @@
{
struct program Base; /* base class */
struct vp_instruction *Instructions; /* Compiled instructions */
+ GLboolean IsNVProgram; /* GL_NV_vertex_program ? */
GLboolean IsPositionInvariant; /* GL_NV_vertex_program1_1 */
GLuint InputsRead; /* Bitmask of which input regs are read */
GLuint OutputsWritten; /* Bitmask of which output regs are written to */
diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c
index d32cb7f..4aaa742 100644
--- a/src/mesa/shader/nvprogram.c
+++ b/src/mesa/shader/nvprogram.c
@@ -79,8 +79,8 @@
return;
}
- _mesa_init_vp_registers(ctx);
- _mesa_init_tracked_matrices(ctx);
+ _mesa_init_vp_per_vertex_registers(ctx);
+ _mesa_init_vp_per_primitive_registers(ctx);
COPY_4V(ctx->VertexProgram.Inputs[VERT_ATTRIB_POS], params);
_mesa_exec_vertex_program(ctx, vprog);
}
diff --git a/src/mesa/shader/nvvertexec.c b/src/mesa/shader/nvvertexec.c
index 9663b38..91577d3 100644
--- a/src/mesa/shader/nvvertexec.c
+++ b/src/mesa/shader/nvvertexec.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.0.1
+ * Version: 6.1
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
@@ -39,44 +39,31 @@
#include "math/m_matrix.h"
-static const GLfloat zeroVec[4] = { 0, 0, 0, 0 };
+static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
/**
- * Load/initialize the vertex program registers.
- * This needs to be done per vertex.
+ * Load/initialize the vertex program registers which need to be set
+ * per-vertex.
*/
void
-_mesa_init_vp_registers(GLcontext *ctx)
+_mesa_init_vp_per_vertex_registers(GLcontext *ctx)
{
- GLuint i;
-
/* Input registers get initialized from the current vertex attribs */
MEMCPY(ctx->VertexProgram.Inputs, ctx->Current.Attrib,
VERT_ATTRIB_MAX * 4 * sizeof(GLfloat));
- /* Output and temp regs are initialized to [0,0,0,1] */
- for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
- ASSIGN_4V(ctx->VertexProgram.Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F);
- }
- for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
- ASSIGN_4V(ctx->VertexProgram.Temporaries[i], 0.0F, 0.0F, 0.0F, 1.0F);
- }
-
- /* The program parameters aren't touched */
- /* XXX: This should be moved to glBegin() time, but its safe (and slow!)
- * here - Karl
- */
- if (ctx->VertexProgram.Current->Parameters) {
- /* Grab the state */
- _mesa_load_state_parameters(ctx, ctx->VertexProgram.Current->Parameters);
-
- /* And copy it into the program state */
- for (i=0; i<ctx->VertexProgram.Current->Parameters->NumParameters; i++) {
- MEMCPY(ctx->VertexProgram.Parameters[i],
- &ctx->VertexProgram.Current->Parameters->Parameters[i].Values,
- 4*sizeof(GLfloat));
- }
+ if (ctx->VertexProgram.Current->IsNVProgram) {
+ GLuint i;
+ /* Output/result regs are initialized to [0,0,0,1] */
+ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
+ ASSIGN_4V(ctx->VertexProgram.Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F);
+ }
+ /* Temp regs are initialized to [0,0,0,0] */
+ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
+ ASSIGN_4V(ctx->VertexProgram.Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F);
+ }
+ ASSIGN_4V(ctx->VertexProgram.AddressReg, 0, 0, 0, 0);
}
}
@@ -111,63 +98,84 @@
/**
- * Load all currently tracked matrices into the program registers.
- * This needs to be done per glBegin/glEnd.
+ * Load program parameter registers with tracked matrices (if NV program)
+ * or GL state values (if ARB program).
+ * This needs to be done per glBegin/glEnd, not per-vertex.
*/
void
-_mesa_init_tracked_matrices(GLcontext *ctx)
+_mesa_init_vp_per_primitive_registers(GLcontext *ctx)
{
- GLuint i;
+ if (ctx->VertexProgram.Current->IsNVProgram) {
+ GLuint i;
- for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
- /* point 'mat' at source matrix */
- GLmatrix *mat;
- if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) {
- mat = ctx->ModelviewMatrixStack.Top;
- }
- else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) {
- mat = ctx->ProjectionMatrixStack.Top;
- }
- else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) {
- mat = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top;
- }
- else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) {
- mat = ctx->ColorMatrixStack.Top;
- }
- else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) {
- /* XXX verify the combined matrix is up to date */
- mat = &ctx->_ModelProjectMatrix;
- }
- else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV &&
- ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) {
- GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV;
- ASSERT(n < MAX_PROGRAM_MATRICES);
- mat = ctx->ProgramMatrixStack[n].Top;
- }
- else {
- /* no matrix is tracked, but we leave the register values as-is */
- assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE);
- continue;
- }
+ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
+ /* point 'mat' at source matrix */
+ GLmatrix *mat;
+ if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) {
+ mat = ctx->ModelviewMatrixStack.Top;
+ }
+ else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) {
+ mat = ctx->ProjectionMatrixStack.Top;
+ }
+ else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) {
+ mat = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top;
+ }
+ else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) {
+ mat = ctx->ColorMatrixStack.Top;
+ }
+ else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) {
+ /* XXX verify the combined matrix is up to date */
+ mat = &ctx->_ModelProjectMatrix;
+ }
+ else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV &&
+ ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) {
+ GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV;
+ ASSERT(n < MAX_PROGRAM_MATRICES);
+ mat = ctx->ProgramMatrixStack[n].Top;
+ }
+ else {
+ /* no matrix is tracked, but we leave the register values as-is */
+ assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE);
+ continue;
+ }
- /* load the matrix */
- if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
- load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
+ /* load the matrix */
+ if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
+ load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
+ }
+ else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) {
+ _math_matrix_analyse(mat); /* update the inverse */
+ assert((mat->flags & MAT_DIRTY_INVERSE) == 0);
+ load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
+ }
+ else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
+ load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
+ }
+ else {
+ assert(ctx->VertexProgram.TrackMatrixTransform[i]
+ == GL_INVERSE_TRANSPOSE_NV);
+ _math_matrix_analyse(mat); /* update the inverse */
+ assert((mat->flags & MAT_DIRTY_INVERSE) == 0);
+ load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
+ }
}
- else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) {
- _math_matrix_analyse(mat); /* update the inverse */
- assert((mat->flags & MAT_DIRTY_INVERSE) == 0);
- load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
- }
- else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
- load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
- }
- else {
- assert(ctx->VertexProgram.TrackMatrixTransform[i]
- == GL_INVERSE_TRANSPOSE_NV);
- _math_matrix_analyse(mat); /* update the inverse */
- assert((mat->flags & MAT_DIRTY_INVERSE) == 0);
- load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
+ }
+ else {
+ /* Using and ARB vertex program */
+ if (ctx->VertexProgram.Current->Parameters) {
+ GLuint i;
+
+ /* Grab the state */
+ _mesa_load_state_parameters(ctx,
+ ctx->VertexProgram.Current->Parameters);
+
+ /* And copy it into the program state */
+ for (i = 0; i < ctx->VertexProgram.Current->Parameters->NumParameters;
+ i++) {
+ MEMCPY(ctx->VertexProgram.Parameters[i],
+ &ctx->VertexProgram.Current->Parameters->Parameters[i].Values,
+ 4 * sizeof(GLfloat));
+ }
}
}
}
@@ -237,7 +245,7 @@
ASSERT( (source->File == PROGRAM_ENV_PARAM) ||
(source->File == PROGRAM_STATE_VAR) );
if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
- return zeroVec;
+ return ZeroVec;
else
return state->Parameters[reg];
}
@@ -390,7 +398,7 @@
ctx->VertexProgram.Current->OutputsWritten |= 0x1;
}
- for (inst = program->Instructions; /*inst->Opcode != VP_OPCODE_END*/; inst++) {
+ for (inst = program->Instructions; ; inst++) {
if (ctx->VertexProgram.CallbackEnabled &&
ctx->VertexProgram.Callback) {
diff --git a/src/mesa/shader/nvvertexec.h b/src/mesa/shader/nvvertexec.h
index 0e4b60e..e6e5a3a 100644
--- a/src/mesa/shader/nvvertexec.h
+++ b/src/mesa/shader/nvvertexec.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 5.1
+ * Version: 6.1
*
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -29,10 +29,10 @@
#define NVVERTEXEC_H
extern void
-_mesa_init_vp_registers(GLcontext *ctx);
+_mesa_init_vp_per_vertex_registers(GLcontext *ctx);
extern void
-_mesa_init_tracked_matrices(GLcontext *ctx);
+_mesa_init_vp_per_primitive_registers(GLcontext *ctx);
extern void
_mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program);
diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c
index bacf5a5..88fa32c 100644
--- a/src/mesa/shader/nvvertparse.c
+++ b/src/mesa/shader/nvvertparse.c
@@ -1300,6 +1300,7 @@
program->InputsRead = parseState.inputsRead;
program->OutputsWritten = parseState.outputsWritten;
program->IsPositionInvariant = parseState.isPositionInvariant;
+ program->IsNVProgram = GL_TRUE;
#ifdef DEBUG
_mesa_printf("--- glLoadProgramNV result ---\n");
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index 62141ad..a6c9bc8 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 5.1
+ * Version: 6.1
*
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -91,7 +91,8 @@
/**
* This function executes vertex programs
*/
-static GLboolean run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
+static GLboolean
+run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vp_stage_data *store = VP_STAGE_DATA(stage);
@@ -99,12 +100,14 @@
struct vertex_program *program = ctx->VertexProgram.Current;
GLuint i;
- _mesa_init_tracked_matrices(ctx); /* load registers with matrices */
- _mesa_init_vp_registers(ctx); /* init temp and result regs */
+ /* load program parameter registers (they're read-only) */
+ _mesa_init_vp_per_primitive_registers(ctx);
for (i = 0; i < VB->Count; i++) {
GLuint attr;
+ _mesa_init_vp_per_vertex_registers(ctx);
+
#if 0
printf("Input %d: %f, %f, %f, %f\n", i,
VB->AttribPtr[0]->data[i][0],