diff options
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/main/mtypes.h | 8 | ||||
| -rw-r--r-- | src/mesa/main/nvfragparse.c | 251 | ||||
| -rw-r--r-- | src/mesa/main/nvprogram.c | 122 | ||||
| -rw-r--r-- | src/mesa/main/nvprogram.h | 24 | 
4 files changed, 263 insertions, 142 deletions
| diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 4c3fb3bbd4..716bbfcf85 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1,4 +1,4 @@ -/* $Id: mtypes.h,v 1.102 2003/01/26 14:37:15 brianp Exp $ */ +/* $Id: mtypes.h,v 1.103 2003/02/16 23:07:34 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -1177,6 +1177,11 @@ struct fp_machine  struct vp_instruction;  struct fp_instruction; +struct symbol_table +{ +   struct symbol *Head; +}; +  /* Base class for any kind of program object */  struct program @@ -1208,6 +1213,7 @@ struct fragment_program     GLuint InputsRead;     /* Bitmask of which input regs are read */     GLuint OutputsWritten; /* Bitmask of which output regs are written to */     GLfloat LocalParams[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; +   struct symbol_table SymbolTable;  }; diff --git a/src/mesa/main/nvfragparse.c b/src/mesa/main/nvfragparse.c index 05d0ac5452..7b9208d521 100644 --- a/src/mesa/main/nvfragparse.c +++ b/src/mesa/main/nvfragparse.c @@ -1,4 +1,4 @@ -/* $Id: nvfragparse.c,v 1.3 2003/02/08 15:56:34 brianp Exp $ */ +/* $Id: nvfragparse.c,v 1.4 2003/02/16 23:07:35 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -142,14 +142,18 @@ static const struct instruction_pattern Instructions[] = {  /**********************************************************************/ +/* XXX not used yet */  struct parse_state {     const GLubyte *start;    /* start of program */     const GLubyte *end;      /* one char past end of the program */     const GLubyte *s;        /* current position */     GLboolean IsStateProgram;     GLboolean IsVersion1_1; +   struct fragment_program *currentProgram;  }; +/* XXX temporary hack */ +static struct fragment_program *CurrentProgram = NULL;  /* @@ -476,13 +480,13 @@ Parse_Identifier(const char **s, char *ident)  /** - * Parse a floating point constant. + * Parse a floating point constant, or a defined symbol name.   * [+/-]N[.N[eN]]   */  static GLboolean  Parse_ScalarConstant(const char **s, GLfloat *number)  { -   char *end; +   char *end = NULL;     *number = (GLfloat) _mesa_strtod(*s, &end); @@ -496,8 +500,9 @@ Parse_ScalarConstant(const char **s, GLfloat *number)        char ident[100];        if (!Parse_Identifier(s, ident))           PARSE_ERROR1("Expected an identifier"); -      /* XXX Look up the value in the symbol table */ -      *number = -999; +      if (!_mesa_lookup_symbol(&(CurrentProgram->SymbolTable), ident, number)) { +         PARSE_ERROR1("Undefined symbol"); +      }        return GL_TRUE;     }  } @@ -571,7 +576,11 @@ Parse_VectorConstant(const char **s, GLfloat *vec)  } -static GLboolean +/** + * Parse <number>, <varname> or {a, b, c, d}. + * Return number of values in the vector or scalar, or zero if parse error. + */ +static GLuint  Parse_VectorOrScalarConstant(const char **s, GLfloat *vec)  {     char token[100]; @@ -1082,7 +1091,8 @@ Parse_ScalarSrcReg(const char **s, struct fp_src_register *srcReg)  static GLboolean -Parse_InstructionSequence(const char **s, struct fp_instruction program[]) +Parse_InstructionSequence(struct fragment_program *fragProg, +                          const char **s, struct fp_instruction program[])  {     char token[100];     GLint count = 0; @@ -1107,19 +1117,22 @@ Parse_InstructionSequence(const char **s, struct fp_instruction program[])        /* special instructions */        if (StrEq(token, "DEFINE")) {           char id[100]; -         GLfloat value[4]; +         GLfloat value[7];  /* yes, 7 to be safe */           if (!Parse_Identifier(s, id))              PARSE_ERROR;           if (!Parse_String(s, "="))              PARSE_ERROR1("Expected = symbol");           if (!Parse_VectorOrScalarConstant(s, value))              PARSE_ERROR; +         if (!Parse_String(s, ";")) +            PARSE_ERROR1("Expected ;");           printf("Parsed DEFINE %s = %f %f %f %f\n", id, value[0], value[1],                  value[2], value[3]); +         _mesa_add_symbol(&(fragProg->SymbolTable), id, Definition, value);        }        else if (StrEq(token, "DECLARE")) {           char id[100]; -         GLfloat value[4]; +         GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0};  /* yes, to be safe */           if (!Parse_Identifier(s, id))              PARSE_ERROR;           if (!Peek_Token(s, token)) @@ -1128,128 +1141,128 @@ Parse_InstructionSequence(const char **s, struct fp_instruction program[])              Parse_String(s, "=");              if (!Parse_VectorOrScalarConstant(s, value))                 PARSE_ERROR; -            printf("Parsed DECLARE %s = %f %f %f %f\n", id, value[0], value[1], -                   value[2], value[3]); +            printf("Parsed DECLARE %s = %f %f %f %f\n", id, +                   value[0], value[1], value[2], value[3]);           }           else {              printf("Parsed DECLARE %s\n", id);           } +         if (!Parse_String(s, ";")) +            PARSE_ERROR1("Expected ;"); +         _mesa_add_symbol(&(fragProg->SymbolTable), id, Declaration, value);        } +      else { +         /* arithmetic instruction */ -      /* try to find matching instuction */ -      instMatch = MatchInstruction(token); -      if (instMatch.opcode < 0) { -         /* bad instruction name */ -         PARSE_ERROR2("Unexpected token: ", token); -      } +         /* try to find matching instuction */ +         instMatch = MatchInstruction(token); +         if (instMatch.opcode < 0) { +            /* bad instruction name */ +            printf("-------- errror\n"); +            PARSE_ERROR2("Unexpected token: ", token); +         } -      inst->Opcode = instMatch.opcode; -      inst->Precision = instMatch.suffixes & (_R | _H | _X); -      inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE; -      inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; +         inst->Opcode = instMatch.opcode; +         inst->Precision = instMatch.suffixes & (_R | _H | _X); +         inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE; +         inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; -      /* -       * parse the input and output operands -       */ -      if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) { -         if (!Parse_MaskedDstReg(s, &inst->DstReg)) -            PARSE_ERROR; -         if (!Parse_String(s, ",")) -            PARSE_ERROR; -      } -      else if (instMatch.outputs == OUTPUT_NONE) { -         ASSERT(instMatch.opcode == FP_OPCODE_KIL); -         /* This is a little weird, the cond code info is in the dest register */ -         if (!Parse_CondCodeMask(s, &inst->DstReg)) -            PARSE_ERROR; -      } +         /* +          * parse the input and output operands +          */ +         if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) { +            if (!Parse_MaskedDstReg(s, &inst->DstReg)) +               PARSE_ERROR; +            if (!Parse_String(s, ",")) +               PARSE_ERROR; +         } +         else if (instMatch.outputs == OUTPUT_NONE) { +            ASSERT(instMatch.opcode == FP_OPCODE_KIL); +            /* This is a little weird, the cond code info is in the dest register */ +            if (!Parse_CondCodeMask(s, &inst->DstReg)) +               PARSE_ERROR; +         } -      if (instMatch.inputs == INPUT_1V) { -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) -            PARSE_ERROR; -      } -      else if (instMatch.inputs == INPUT_2V) { -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) -            PARSE_ERROR; -         if (!Parse_String(s, ",")) -            PARSE_ERROR; -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) -            PARSE_ERROR; -      } -      else if (instMatch.inputs == INPUT_3V) { -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) -            PARSE_ERROR; -         if (!Parse_String(s, ",")) -            PARSE_ERROR; -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) -            PARSE_ERROR; -         if (!Parse_String(s, ",")) -            PARSE_ERROR; -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) -            PARSE_ERROR; -      } -      else if (instMatch.inputs == INPUT_1S) { -         if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) -            PARSE_ERROR; -      } -      else if (instMatch.inputs == INPUT_2S) { -         if (!Parse_ScalarSrcReg(s, &inst->SrcReg[0])) -            PARSE_ERROR; -         if (!Parse_String(s, ",")) -            PARSE_ERROR; -         if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) -            PARSE_ERROR; -      } -      else if (instMatch.inputs == INPUT_CC) { +         if (instMatch.inputs == INPUT_1V) { +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) +               PARSE_ERROR; +         } +         else if (instMatch.inputs == INPUT_2V) { +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) +               PARSE_ERROR; +            if (!Parse_String(s, ",")) +               PARSE_ERROR; +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) +               PARSE_ERROR; +         } +         else if (instMatch.inputs == INPUT_3V) { +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) +               PARSE_ERROR; +            if (!Parse_String(s, ",")) +               PARSE_ERROR; +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) +               PARSE_ERROR; +            if (!Parse_String(s, ",")) +               PARSE_ERROR; +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) +               PARSE_ERROR; +         } +         else if (instMatch.inputs == INPUT_1S) { +            if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) +               PARSE_ERROR; +         } +         else if (instMatch.inputs == INPUT_2S) { +            if (!Parse_ScalarSrcReg(s, &inst->SrcReg[0])) +               PARSE_ERROR; +            if (!Parse_String(s, ",")) +               PARSE_ERROR; +            if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) +               PARSE_ERROR; +         } +         else if (instMatch.inputs == INPUT_CC) {  #if 00 -         if (!ParseCondCodeSrc(s, &inst->srcReg[0])) -            PARSE_ERROR; +            if (!ParseCondCodeSrc(s, &inst->srcReg[0])) +               PARSE_ERROR;  #endif -      } -      else if (instMatch.inputs == INPUT_1V_T) { -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) -            PARSE_ERROR; -         if (!Parse_String(s, ",")) -            PARSE_ERROR; -         if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) -            PARSE_ERROR; -      } -      else if (instMatch.inputs == INPUT_1V_T) { -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) -            PARSE_ERROR; -         if (!Parse_String(s, ",")) -            PARSE_ERROR; -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) -            PARSE_ERROR; -         if (!Parse_String(s, ",")) -            PARSE_ERROR; -         if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[2])) -            PARSE_ERROR; -         if (!Parse_String(s, ",")) -            PARSE_ERROR; -         if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) -            PARSE_ERROR; -      } +         } +         else if (instMatch.inputs == INPUT_1V_T) { +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) +               PARSE_ERROR; +            if (!Parse_String(s, ",")) +               PARSE_ERROR; +            if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) +               PARSE_ERROR; +         } +         else if (instMatch.inputs == INPUT_1V_T) { +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) +               PARSE_ERROR; +            if (!Parse_String(s, ",")) +               PARSE_ERROR; +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) +               PARSE_ERROR; +            if (!Parse_String(s, ",")) +               PARSE_ERROR; +            if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[2])) +               PARSE_ERROR; +            if (!Parse_String(s, ",")) +               PARSE_ERROR; +            if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) +               PARSE_ERROR; +         } -      /* end of statement semicolon */ -      if (!Parse_String(s, ";")) -         PARSE_ERROR; +         /* end of statement semicolon */ +         if (!Parse_String(s, ";")) +            PARSE_ERROR; -      count++; -      if (count >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) -         PARSE_ERROR1("Program too long"); +         count++; +         if (count >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) +            PARSE_ERROR1("Program too long"); +      }     }     return GL_TRUE;  } -static GLboolean -Parse_Program(const char **s, struct fp_instruction instBuffer[]) -{ -   return Parse_InstructionSequence(s, instBuffer); -} - -  /**   * Parse/compile the 'str' returning the compiled 'program'.   * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos @@ -1297,7 +1310,10 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,        return;     } -   if (Parse_Program(&s, instBuffer)) { +   /* XXX temporary */ +   CurrentProgram = program; + +   if (Parse_InstructionSequence(program, &s, instBuffer)) {        GLuint numInst;        GLuint strLen;        GLuint inputsRead = 0; @@ -1323,10 +1339,10 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,           if ((r = InputRegisterNumber(srcReg0)) >= 0               && !instBuffer[numInst].SrcReg[0].RelAddr)              inputsRead |= (1 << r); -         if ((r = InputRegisterNumber(srcReg1) >= 0 +         if ((r = InputRegisterNumber(srcReg1)) >= 0               && !instBuffer[numInst].SrcReg[1].RelAddr)              inputsRead |= (1 << r); -         if ((r = InputRegisterNumber(srcReg2) >= 0 +         if ((r = InputRegisterNumber(srcReg2)) >= 0               && !instBuffer[numInst].SrcReg[2].RelAddr)              inputsRead |= (1 << r);  #endif @@ -1367,6 +1383,9 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,        }        program->Instructions = newInst; +      /* allocate registers for declared program parameters */ +      _mesa_assign_program_registers(&(program->SymbolTable)); +  #ifdef DEBUG        _mesa_printf("--- glLoadProgramNV result ---\n");        _mesa_print_nv_fragment_program(program); diff --git a/src/mesa/main/nvprogram.c b/src/mesa/main/nvprogram.c index d09e7afbee..b6960c0df8 100644 --- a/src/mesa/main/nvprogram.c +++ b/src/mesa/main/nvprogram.c @@ -1,4 +1,4 @@ -/* $Id: nvprogram.c,v 1.2 2003/02/10 20:31:11 alanh Exp $ */ +/* $Id: nvprogram.c,v 1.3 2003/02/16 23:07:36 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -45,6 +45,86 @@  #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) == 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). @@ -984,20 +1064,13 @@ _mesa_TrackMatrixNV(GLenum target, GLuint address,  } -static GLfloat * -lookup_program_parameter(struct fragment_program *fprog, -                         GLsizei len, const GLubyte *name) -{ -   return NULL; -} - -  void  glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,                              GLfloat x, GLfloat y, GLfloat z, GLfloat w)  {     struct program *prog; -   GLfloat *p; +   struct fragment_program *fragProg; +   GLint reg;     GET_CURRENT_CONTEXT(ctx);     ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -1012,16 +1085,17 @@ glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,        return;     } -   p = lookup_program_parameter((struct fragment_program *) prog, len, name); -   if (!p) { +   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;     } -   p[0] = x; -   p[1] = y; -   p[2] = z; -   p[3] = w; +   fragProg->LocalParams[reg][0] = x; +   fragProg->LocalParams[reg][1] = y; +   fragProg->LocalParams[reg][2] = z; +   fragProg->LocalParams[reg][3] = w;  } @@ -1056,7 +1130,8 @@ glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,                                 GLfloat *params)  {     struct program *prog; -   const GLfloat *p; +   struct fragment_program *fragProg; +   GLint reg;     GET_CURRENT_CONTEXT(ctx);     ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -1071,16 +1146,17 @@ glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,        return;     } -   p = lookup_program_parameter((struct fragment_program *) prog, len, name); -   if (!p) { +   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;     } -   params[0] = p[0]; -   params[1] = p[1]; -   params[2] = p[2]; -   params[3] = p[3]; +   params[0] = fragProg->LocalParams[reg][0]; +   params[1] = fragProg->LocalParams[reg][1]; +   params[2] = fragProg->LocalParams[reg][2]; +   params[3] = fragProg->LocalParams[reg][3];  } diff --git a/src/mesa/main/nvprogram.h b/src/mesa/main/nvprogram.h index 3ede705722..5d31ebba3b 100644 --- a/src/mesa/main/nvprogram.h +++ b/src/mesa/main/nvprogram.h @@ -1,10 +1,10 @@ -/* $Id: nvprogram.h,v 1.1 2003/01/14 04:55:46 brianp Exp $ */ +/* $Id: nvprogram.h,v 1.2 2003/02/16 23:07:36 brianp Exp $ */  /*   * Mesa 3-D graphics library   * Version:  5.1   * - * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved. + * Copyright (C) 1999-2003  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"), @@ -32,6 +32,26 @@  #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); | 
