Rewrite of fragment program named parameters, constants, etc. Not done.
authorBrian Paul <brian.paul@tungstengraphics.com>
Wed, 19 Mar 2003 05:34:24 +0000 (05:34 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Wed, 19 Mar 2003 05:34:24 +0000 (05:34 +0000)
src/mesa/main/mtypes.h
src/mesa/main/nvfragparse.c
src/mesa/main/nvprogram.c
src/mesa/main/nvprogram.h
src/mesa/swrast/s_nvfragprog.c

index 4a258336999b09626e86bbdf24b20ce767955659..5a946d81ad4e983646ff7b3ed6087311e0fcefd9 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mtypes.h,v 1.106 2003/03/02 19:31:15 brianp Exp $ */
+/* $Id: mtypes.h,v 1.107 2003/03/19 05:34:24 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1208,9 +1208,11 @@ struct fp_machine
 struct vp_instruction;
 struct fp_instruction;
 
-struct symbol_table
+/* Program parameters */
+struct program_parameter
 {
-   struct symbol *Head;
+   const char *Name;
+   GLfloat Values[4];
 };
 
 
@@ -1245,7 +1247,8 @@ struct fragment_program
    GLuint OutputsWritten; /* Bitmask of which output regs are written to */
    GLuint TexturesUsed[MAX_TEXTURE_IMAGE_UNITS];  /* TEXTURE_x_INDEX bitmask */
    GLfloat LocalParams[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4];
-   struct symbol_table SymbolTable;
+   GLuint NumParameters;
+   struct program_parameter *Parameters; /* array [NumParameters] */
 };
 
 
index 0f75d6c36f6dfc9cc15c864e5b0c3113d6cfec4c..ff546db612699629217e7cca5a795d93c74239e9 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: nvfragparse.c,v 1.14 2003/03/15 17:33:26 brianp Exp $ */
+/* $Id: nvfragparse.c,v 1.15 2003/03/19 05:34:25 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "nvprogram.h"
 
 
+/* XXX move */
+static void *
+_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
+{
+   void *newBuffer = _mesa_malloc(newSize);
+   size_t bytes = MIN2(oldSize, newSize);
+   if (newBuffer && bytes > 0) {
+      _mesa_memcpy(newBuffer, oldBuffer, bytes);
+   }
+   _mesa_free(oldBuffer);
+   return newBuffer;
+}
+
+
 #define INPUT_1V     1
 #define INPUT_2V     2
 #define INPUT_3V     3
@@ -130,6 +144,13 @@ struct parse_state {
    const GLubyte *start;              /* start of program string */
    const GLubyte *pos;                /* current position */
    struct fragment_program *program;  /* current program */
+
+   GLuint numParameters;
+   struct program_parameter *parameters; /* DECLARE */
+
+   GLuint numConstants;
+   struct program_parameter *constants; /* DEFINE */
+
    GLuint numInst;                    /* number of instructions parsed */
    GLuint inputsRead;                 /* bitmask of input registers used */
    GLuint outputsWritten;             /* 2 = depth register */
@@ -137,6 +158,60 @@ struct parse_state {
 };
 
 
+static void
+add_parameter(struct parse_state *parseState,
+              const char *name, const GLfloat values[4])
+{
+   const GLuint n = parseState->numParameters;
+
+   parseState->parameters = _mesa_realloc(parseState->parameters,
+                                   n * sizeof(struct program_parameter),
+                                   (n + 1) * sizeof(struct program_parameter));
+   parseState->numParameters = n + 1;
+   parseState->parameters[n].Name = _mesa_strdup(name);
+   COPY_4V(parseState->parameters[n].Values, values);
+}
+
+
+static const GLfloat *
+lookup_parameter(struct parse_state *parseState, const char *name)
+{
+   GLuint i;
+   for (i = 0; i < parseState->numParameters; i++) {
+      if (_mesa_strcmp(parseState->parameters[i].Name, name) == 0)
+         return parseState->parameters[i].Values;
+   }
+   return NULL;
+}
+
+
+static void
+add_constant(struct parse_state *parseState,
+             const char *name, const GLfloat values[4])
+{
+   const GLuint n = parseState->numConstants;
+
+   parseState->constants = _mesa_realloc(parseState->constants,
+                                   n * sizeof(struct program_parameter),
+                                   (n + 1) * sizeof(struct program_parameter));
+   parseState->numConstants = n + 1;
+   parseState->constants[n].Name = _mesa_strdup(name);
+   COPY_4V(parseState->constants[n].Values, values);
+}
+
+
+static const GLfloat *
+lookup_constant(struct parse_state *parseState, const char *name)
+{
+   GLuint i;
+   for (i = 0; i < parseState->numConstants; i++) {
+      if (_mesa_strcmp(parseState->constants[i].Name, name) == 0)
+         return parseState->constants[i].Values;
+   }
+   return NULL;
+}
+
+
 /*
  * Called whenever we find an error during parsing.
  */
@@ -493,13 +568,17 @@ Parse_ScalarConstant(struct parse_state *parseState, GLfloat *number)
    else {
       /* should be an identifier */
       GLubyte ident[100];
+      const GLfloat *constant;
       if (!Parse_Identifier(parseState, ident))
          RETURN_ERROR1("Expected an identifier");
-      if (!_mesa_lookup_symbol(&(parseState->program->SymbolTable),
-                               (const char *) ident, number)) {
+      constant = lookup_constant(parseState, (const char *) ident);
+      if (!constant) {
          RETURN_ERROR1("Undefined symbol");
       }
-      return GL_TRUE;
+      else {
+         COPY_4V(number, constant);
+         return GL_TRUE;
+      }
    }
 }
 
@@ -1165,8 +1244,10 @@ Parse_InstructionSequence(struct parse_state *parseState,
             RETURN_ERROR1("Expected ;");
          printf("Parsed DEFINE %s = %f %f %f %f\n", id, value[0], value[1],
                 value[2], value[3]);
-         _mesa_add_symbol(&(parseState->program->SymbolTable),
-                          (const char *) id, Definition, value);
+         if (lookup_parameter(parseState, (const char *) id)) {
+            RETURN_ERROR2(id, "already defined");
+         }
+         add_parameter(parseState, (const char *) id, value);
       }
       else if (Parse_String(parseState, "DECLARE")) {
          GLubyte id[100];
@@ -1185,8 +1266,10 @@ Parse_InstructionSequence(struct parse_state *parseState,
          }
          if (!Parse_String(parseState, ";"))
             RETURN_ERROR1("Expected ;");
-         _mesa_add_symbol(&(parseState->program->SymbolTable),
-                          (const char *) id, Declaration, value);
+         if (lookup_constant(parseState, (const char *) id)) {
+            RETURN_ERROR2(id, "already declared");
+         }
+         add_constant(parseState, (const char *) id, value);
       }
       else if (Parse_String(parseState, "END")) {
          inst->Opcode = FP_OPCODE_END;
@@ -1411,8 +1494,29 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
       for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
          program->TexturesUsed[u] = parseState.texturesUsed[u];
 
+      /* save program parameters */
+      if (program->Parameters) {
+         GLuint i;
+         for (i = 0; i < program->NumParameters; i++)
+            _mesa_free((void *) program->Parameters[i].Name);
+         _mesa_free(program->Parameters);
+      }
+      program->NumParameters = parseState.numParameters;
+      program->Parameters = parseState.parameters;
+
+      /* free program constants */
+      if (parseState.constants) {
+         GLuint i;
+         for (i = 0; i < parseState.numConstants; i++)
+            _mesa_free((void *) parseState.constants[i].Name);
+         _mesa_free(parseState.constants);
+      }
+         
+
       /* allocate registers for declared program parameters */
+#if 00
       _mesa_assign_program_registers(&(program->SymbolTable));
+#endif
 
 #ifdef DEBUG
       _mesa_printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
index 4e371620c5735113d90eea0c2a54df3a17ce691b..75518350b314775f0059e5decb6804470dc816c2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: nvprogram.c,v 1.8 2003/03/14 15:40:59 brianp Exp $ */
+/* $Id: nvprogram.c,v 1.9 2003/03/19 05:34:25 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "nvprogram.h"
 
 
-/**
- * Symbol table entry.
- * Used for named program parameters.
- */
-struct symbol
-{
-   const char *Name;
-   enum symbol_type Type;
-   GLfloat Value[4];
-   GLuint Register;
-   struct symbol *Next;
-};
-
-
-
-void
-_mesa_add_symbol(struct symbol_table *symbolTable,
-                 const char *name, enum symbol_type type, const GLfloat *value)
-{
-   struct symbol *s = MALLOC_STRUCT(symbol);
-   if (s) {
-      s->Name = _mesa_strdup(name);
-      s->Type = type;
-      s->Value[0] = value[0];
-      s->Value[1] = value[1];
-      s->Value[2] = value[2];
-      s->Value[3] = value[3];
-      s->Next = symbolTable->Head;
-      symbolTable->Head = s;
-   }
-}
-
-
-GLboolean
-_mesa_lookup_symbol(const struct symbol_table *symbolTable,
-                    const char *name, GLfloat *value)
-{
-   const struct symbol *s;
-   for (s = symbolTable->Head; s; s = s->Next) {
-      if (_mesa_strcmp(s->Name, name) == 0) {
-         value[0] = s->Value[0];
-         value[1] = s->Value[1];
-         value[2] = s->Value[2];
-         value[3] = s->Value[3];
-         return GL_TRUE;
-      }
-   }
-   printf("lookup %s failed\n", name);
-   return GL_FALSE;
-}
-
-
-static GLint
-_mesa_lookup_program_register(const struct symbol_table *symbolTable,
-                              GLsizei len, const GLubyte *name)
-{
-   const struct symbol *s;
-   for (s = symbolTable->Head; s; s = s->Next) {
-      if (_mesa_strcmp(s->Name, (const char *) name) == 0 &&
-          _mesa_strlen(s->Name) == (size_t) len) {
-         return s->Register;
-      }
-   }
-   return -1;
-}
-
-
-void
-_mesa_assign_program_registers(struct symbol_table *symbolTable)
-{
-   struct symbol *s;
-   GLuint reg = 0;
-   for (s = symbolTable->Head; s; s = s->Next) {
-      if (s->Type == Declaration) {
-         s->Register = reg++;
-      }
-   }
-}
-
-
-
 /**
  * Set the vertex/fragment program error state (position and error string).
  * This is generally called from within the parsers.
@@ -199,20 +118,27 @@ _mesa_delete_program(GLcontext *ctx, GLuint id)
 
    if (prog) {
       if (prog->String)
-         FREE(prog->String);
+         _mesa_free(prog->String);
       if (prog->Target == GL_VERTEX_PROGRAM_NV ||
           prog->Target == GL_VERTEX_STATE_PROGRAM_NV) {
          struct vertex_program *vprog = (struct vertex_program *) prog;
          if (vprog->Instructions)
-            FREE(vprog->Instructions);
+            _mesa_free(vprog->Instructions);
       }
       else if (prog->Target == GL_FRAGMENT_PROGRAM_NV) {
          struct fragment_program *fprog = (struct fragment_program *) prog;
          if (fprog->Instructions)
-            FREE(fprog->Instructions);
+            _mesa_free(fprog->Instructions);
+         if (fprog->Parameters) {
+            GLuint i;
+            for (i = 0; i < fprog->NumParameters; i++) {
+               _mesa_free((void *) fprog->Parameters[i].Name);
+            }
+            _mesa_free(fprog->Parameters);
+         }
       }
       _mesa_HashRemove(ctx->Shared->Programs, id);
-      FREE(prog);
+      _mesa_free(prog);
    }
 }
 
@@ -418,7 +344,7 @@ _mesa_GenProgramsNV(GLsizei n, GLuint *ids)
    for (i = 0; i < (GLuint) n; i++) {
       const int bytes = MAX2(sizeof(struct vertex_program),
                              sizeof(struct fragment_program));
-      struct program *prog = (struct program *) CALLOC(bytes);
+      struct program *prog = (struct program *) _mesa_calloc(bytes);
       if (!prog) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenProgramsNV");
          return;
@@ -962,12 +888,12 @@ _mesa_ProgramParameter4fNV(GLenum target, GLuint index,
          ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w);
       }
       else {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameterrNV(index)");
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameterNV(index)");
          return;
       }
    }
    else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameterrNV");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameterNV");
       return;
    }
 }
@@ -1133,16 +1059,17 @@ glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
    }
 
    fragProg = (struct fragment_program *) prog;
-   reg = _mesa_lookup_program_register(&(fragProg->SymbolTable), len, name);
-   if (reg < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV");
-      return;
+   for (reg = 0; reg < fragProg->NumParameters; reg++) {
+      if (!_mesa_strcmp(fragProg->Parameters[reg].Name, (const char *) name)) {
+         fragProg->Parameters[reg].Values[0] = x;
+         fragProg->Parameters[reg].Values[1] = y;
+         fragProg->Parameters[reg].Values[2] = z;
+         fragProg->Parameters[reg].Values[3] = w;
+         return;
+      }
    }
 
-   fragProg->LocalParams[reg][0] = x;
-   fragProg->LocalParams[reg][1] = y;
-   fragProg->LocalParams[reg][2] = z;
-   fragProg->LocalParams[reg][3] = w;
+   _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV");
 }
 
 
@@ -1194,16 +1121,17 @@ glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
    }
 
    fragProg = (struct fragment_program *) prog;
-   reg = _mesa_lookup_program_register(&(fragProg->SymbolTable), len, name);
-   if (reg < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
-      return;
+   for (reg = 0; reg < fragProg->NumParameters; reg++) {
+      if (!_mesa_strcmp(fragProg->Parameters[reg].Name, (const char *) name)) {
+         params[0] = fragProg->Parameters[reg].Values[0];
+         params[1] = fragProg->Parameters[reg].Values[1];
+         params[2] = fragProg->Parameters[reg].Values[2];
+         params[3] = fragProg->Parameters[reg].Values[3];
+         return;
+      }
    }
 
-   params[0] = fragProg->LocalParams[reg][0];
-   params[1] = fragProg->LocalParams[reg][1];
-   params[2] = fragProg->LocalParams[reg][2];
-   params[3] = fragProg->LocalParams[reg][3];
+   _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
 }
 
 
index b41dc950970df58577dd822762100396b3a5f1a0..cb61444905625b1bd6c13f2303e1246b8cfc08e4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: nvprogram.h,v 1.4 2003/02/25 19:30:29 brianp Exp $ */
+/* $Id: nvprogram.h,v 1.5 2003/03/19 05:34:25 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #define NVPROGRAM_H
 
 
-enum symbol_type
-{
-   Definition,
-   Declaration
-};
-
-
-extern void
-_mesa_add_symbol(struct symbol_table *symbolTable,
-                 const char *name, enum symbol_type type,
-                 const GLfloat *value);
-
-extern GLboolean
-_mesa_lookup_symbol(const struct symbol_table *symbolTable,
-                    const char *name, GLfloat *value);
-
-extern void
-_mesa_assign_program_registers(struct symbol_table *symbolTable);
-
-
 extern void
 _mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string);
 
index cd3f307f9739ccfa76936292781a06f397f7d169..345ddff0a6cd80f81725a61aedca526f012c6b98 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_nvfragprog.c,v 1.9 2003/03/16 22:02:37 brianp Exp $ */
+/* $Id: s_nvfragprog.c,v 1.10 2003/03/19 05:34:25 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1041,39 +1041,45 @@ execute_program( GLcontext *ctx,
 static void
 init_machine( GLcontext *ctx, struct fp_machine *machine,
               const struct fragment_program *program,
-              const struct sw_span *span, GLuint i )
+              const struct sw_span *span, GLuint col )
 {
-   GLuint u;
+   GLuint j, u;
 
    /* Clear temporary registers */
    _mesa_bzero(machine->Registers + FP_TEMP_REG_START,
                MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
 
+   /* Load program local parameters */
+   for (j = 0; j < MAX_NV_FRAGMENT_PROGRAM_PARAMS; j++) {
+      COPY_4V(machine->Registers[FP_PROG_REG_START + j],
+              program->LocalParams[j]);
+   }
+
    /* Load input registers */
    if (program->InputsRead & (1 << FRAG_ATTRIB_WPOS)) {
       GLfloat *wpos = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_WPOS];
-      wpos[0] = span->x + i;
-      wpos[1] = span->y + i;
-      wpos[2] = (GLfloat) span->array->z[i] / ctx->DepthMaxF;
-      wpos[3] = span->w + i * span->dwdx;
+      wpos[0] = span->x + col;
+      wpos[1] = span->y;
+      wpos[2] = (GLfloat) span->array->z[col] / ctx->DepthMaxF;
+      wpos[3] = span->w + col * span->dwdx;
    }
    if (program->InputsRead & (1 << FRAG_ATTRIB_COL0)) {
       GLfloat *col0 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL0];
-      col0[0] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]);
-      col0[1] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]);
-      col0[2] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]);
-      col0[3] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]);
+      col0[0] = CHAN_TO_FLOAT(span->array->rgba[col][RCOMP]);
+      col0[1] = CHAN_TO_FLOAT(span->array->rgba[col][GCOMP]);
+      col0[2] = CHAN_TO_FLOAT(span->array->rgba[col][BCOMP]);
+      col0[3] = CHAN_TO_FLOAT(span->array->rgba[col][ACOMP]);
    }
    if (program->InputsRead & (1 << FRAG_ATTRIB_COL1)) {
       GLfloat *col1 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL1];
-      col1[0] = CHAN_TO_FLOAT(span->array->spec[i][RCOMP]);
-      col1[1] = CHAN_TO_FLOAT(span->array->spec[i][GCOMP]);
-      col1[2] = CHAN_TO_FLOAT(span->array->spec[i][BCOMP]);
-      col1[3] = CHAN_TO_FLOAT(span->array->spec[i][ACOMP]);
+      col1[0] = CHAN_TO_FLOAT(span->array->spec[col][RCOMP]);
+      col1[1] = CHAN_TO_FLOAT(span->array->spec[col][GCOMP]);
+      col1[2] = CHAN_TO_FLOAT(span->array->spec[col][BCOMP]);
+      col1[3] = CHAN_TO_FLOAT(span->array->spec[col][ACOMP]);
    }
    if (program->InputsRead & (1 << FRAG_ATTRIB_FOGC)) {
       GLfloat *fogc = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_FOGC];
-      fogc[0] = span->array->fog[i];
+      fogc[0] = span->array->fog[col];
       fogc[1] = 0.0F;
       fogc[2] = 0.0F;
       fogc[3] = 0.0F;
@@ -1082,7 +1088,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
       if (program->InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) {
          GLfloat *tex = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_TEX0+u];
          if (ctx->Texture.Unit[u]._ReallyEnabled) {
-            COPY_4V(tex, span->array->texcoords[u][i]);
+            COPY_4V(tex, span->array->texcoords[u][col]);
          }
          else {
             COPY_4V(tex, ctx->Current.Attrib[VERT_ATTRIB_TEX0 + u]);