diff options
Diffstat (limited to 'src/mesa/main/nvfragparse.c')
-rw-r--r-- | src/mesa/main/nvfragparse.c | 120 |
1 files changed, 112 insertions, 8 deletions
diff --git a/src/mesa/main/nvfragparse.c b/src/mesa/main/nvfragparse.c index 0f75d6c36f6..ff546db6126 100644 --- a/src/mesa/main/nvfragparse.c +++ b/src/mesa/main/nvfragparse.c @@ -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 @@ -42,6 +42,20 @@ #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); |