Lots of clean-up in arb program parser.
authorBrian Paul <brian.paul@tungstengraphics.com>
Sun, 30 Oct 2005 21:23:23 +0000 (21:23 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sun, 30 Oct 2005 21:23:23 +0000 (21:23 +0000)
Use new _mesa_init_fp/vp_instruction() function to initialize instructions.

src/mesa/shader/arbprogparse.c
src/mesa/shader/nvfragparse.c
src/mesa/shader/nvfragprog.h
src/mesa/shader/nvvertparse.c
src/mesa/shader/nvvertprog.h

index 66cc49393592c89631e2c89a67331eb1b06d34c7..eb3dd5d935b74810072446068a97254b3170f8f7 100644 (file)
@@ -482,9 +482,9 @@ typedef enum
 } var_type;
 
 
-/*
- * Setting an explicit field for each of the binding properties is a bit wasteful
- * of space, but it should be much more clear when reading later on..
+/**
+ * Setting an explicit field for each of the binding properties is a bit
+ * wasteful of space, but it should be much more clear when reading later on..
  */
 struct var_cache
 {
@@ -498,9 +498,7 @@ struct var_cache
    GLuint attrib_is_generic;    /* If the attrib was specified through a generic
                                  * vertex attrib                                   */
    GLuint temp_binding;         /* The index of the temp register we are to use    */
-   GLuint output_binding;       /* For type vt_output, see nvfragprog.h for values */
-   GLuint output_binding_idx;   /* This is the index into the result register file
-                                 * corresponding to the bound result state         */
+   GLuint output_binding;       /* Output/result register number */
    struct var_cache *alias_binding;     /* For type vt_alias, points to the var_cache entry
                                          * that this is aliased to                         */
    GLuint param_binding_type;   /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,
@@ -526,7 +524,6 @@ var_cache_create (struct var_cache **va)
       (**va).attrib_is_generic = 0;
       (**va).temp_binding = ~0;
       (**va).output_binding = ~0;
-      (**va).output_binding_idx = ~0;
       (**va).param_binding_type = ~0;
       (**va).param_binding_begin = ~0;
       (**va).param_binding_length = ~0;
@@ -1580,108 +1577,98 @@ parse_attrib_binding (GLcontext * ctx, GLubyte ** inst,
    return err;
 }
 
+
 /**
  * This translates between a binary token for an output variable type
  * and the mesa token for the same thing.
  *
- *
- * XXX: What is the 'name' for vertex program state? -> do we need it?
- *         I don't think we do;
- *
- * See nvfragprog.h for definitions
- *
- * \param inst        - The parsed tokens
- * \param binding     - The name of the state we are binding too
- * \param binding_idx - The index into the result register file that this is bound too
- *
- * See nvfragparse.c for the register file layout for fragment programs
- * See nvvertparse.c for the register file layout for vertex programs
+ * \param inst       The parsed tokens
+ * \param outputReg  Returned index/number of the output register,
+ *                   one of the VERT_RESULT_* or FRAG_OUTPUT_* values.
  */
 static GLuint
-parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding,
-                      GLuint * binding_idx, struct arb_program *Program)
+parse_result_binding(GLcontext *ctx, GLubyte **inst,
+                     GLuint *outputReg, struct arb_program *Program)
 {
-   GLuint b, out_color;
+   const GLubyte token = *(*inst)++;
 
-   switch (*(*inst)++) {
+   switch (token) {
       case FRAGMENT_RESULT_COLOR:
-         /* for frag programs, this is FRAGMENT_RESULT_COLOR */
          if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
+            GLuint out_color;
+
             /* This gets result of the color buffer we're supposed to 
-             * draw into
+             * draw into.  This pertains to GL_ARB_draw_buffers.
              */
             parse_output_color_num(ctx, inst, Program, &out_color);
-
-            *binding = FRAG_OUTPUT_COLR;
-
-                               /* XXX: We're ignoring the color buffer for now. */
-            *binding_idx = 0;
+            ASSERT(out_color < MAX_DRAW_BUFFERS);
+            *outputReg = FRAG_OUTPUT_COLR;
          }
-         /* for vtx programs, this is VERTEX_RESULT_POSITION */
          else {
-            *binding_idx = 0;
+            /* for vtx programs, this is VERTEX_RESULT_POSITION */
+            *outputReg = VERT_RESULT_HPOS;
          }
          break;
 
       case FRAGMENT_RESULT_DEPTH:
-         /* for frag programs, this is FRAGMENT_RESULT_DEPTH */
          if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-            *binding = FRAG_OUTPUT_DEPR;
-            *binding_idx = 2;
+            /* for frag programs, this is FRAGMENT_RESULT_DEPTH */
+            *outputReg = FRAG_OUTPUT_DEPR;
          }
-         /* for vtx programs, this is VERTEX_RESULT_COLOR */
          else {
+            /* for vtx programs, this is VERTEX_RESULT_COLOR */
             GLint color_type;
             GLuint face_type = parse_face_type(inst);
-           GLint color_type_ret = parse_color_type(ctx, inst, Program, &color_type);
+           GLint err = parse_color_type(ctx, inst, Program, &color_type);
+            if (err)
+               return 1;
 
-            /* back face */
             if (face_type) {
-               if (color_type_ret) return 1;
-
-               /* secondary color */
+               /* back face */
                if (color_type) {
-                  *binding_idx = 4;
+                  *outputReg = VERT_RESULT_BFC1; /* secondary color */
                }
-               /*  primary color */
                else {
-                  *binding_idx = 3;
+                  *outputReg = VERT_RESULT_BFC0; /* primary color */
                }
             }
-            /* front face */
             else {
-               /* secondary color */
+               /* front face */
                if (color_type) {
-                  *binding_idx = 2;
+                  *outputReg = VERT_RESULT_COL1; /* secondary color */
                }
                /* primary color */
                else {
-                  *binding_idx = 1;
+                  *outputReg = VERT_RESULT_COL0; /* primary color */
                }
             }
          }
          break;
 
       case VERTEX_RESULT_FOGCOORD:
-         *binding_idx = 5;
+         *outputReg = VERT_RESULT_FOGC;
          break;
 
       case VERTEX_RESULT_POINTSIZE:
-         *binding_idx = 6;
+         *outputReg = VERT_RESULT_PSIZ;
          break;
 
       case VERTEX_RESULT_TEXCOORD:
-         if (parse_texcoord_num (ctx, inst, Program, &b))
-            return 1;
-         *binding_idx = 7 + b;
+         {
+            GLuint unit;
+            if (parse_texcoord_num (ctx, inst, Program, &unit))
+               return 1;
+            *outputReg = VERT_RESULT_TEX0 + unit;
+         }
          break;
    }
 
-   Program->OutputsWritten |= (1 << *binding_idx);
+   Program->OutputsWritten |= (1 << *outputReg);
 
    return 0;
 }
 
+
 /**
  * This handles the declaration of ATTRIB variables
  *
@@ -1715,22 +1702,19 @@ parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 
    attrib_var->type = vt_attrib;
 
-   /* I think this is ok now - karl */
-   /* XXX: */
-   /*if (Program->type == GL_FRAGMENT_PROGRAM_ARB) */
-   {
-      if (parse_attrib_binding
-          (ctx, inst, Program, &attrib_var->attrib_binding,
-           &attrib_var->attrib_binding_idx, &attrib_var->attrib_is_generic))
-         return 1;
-      if (generic_attrib_check(*vc_head)) {
-         _mesa_set_program_error (ctx, Program->Position,
-   "Cannot use both a generic vertex attribute and a specific attribute of the same type");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-   "Cannot use both a generic vertex attribute and a specific attribute of the same type");
-         return 1;
-      }
+   if (parse_attrib_binding(ctx, inst, Program, &attrib_var->attrib_binding,
+                            &attrib_var->attrib_binding_idx,
+                            &attrib_var->attrib_is_generic))
+      return 1;
 
+   if (generic_attrib_check(*vc_head)) {
+      _mesa_set_program_error(ctx, Program->Position,
+                              "Cannot use both a generic vertex attribute "
+                              "and a specific attribute of the same type");
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "Cannot use both a generic vertex attribute and a specific "
+                  "attribute of the same type");
+      return 1;
    }
 
    Program->Base.NumAttributes++;
@@ -1748,15 +1732,12 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
                       struct arb_program *Program, GLboolean use)
 {
    GLint idx;
-   GLuint err;
+   GLuint err = 0;
    GLint state_tokens[6];
    GLfloat const_values[4];
 
-   err = 0;
-
    switch (*(*inst)++) {
       case PARAM_STATE_ELEMENT:
-
          if (parse_state_single_item (ctx, inst, Program, state_tokens))
             return 1;
 
@@ -1792,7 +1773,6 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
          break;
 
       case PARAM_PROGRAM_ELEMENT:
-
          if (parse_program_single_item (ctx, inst, Program, state_tokens))
             return 1;
          idx = _mesa_add_state_reference (Program->Parameters, state_tokens);
@@ -1841,10 +1821,9 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
                Program->Base.NumParameters++;
             }
          }
-                       else
-                       {
-                               (*inst)++;
-                       }
+         else {
+            (*inst)++;
+         }
          break;
 
       case PARAM_CONSTANT:
@@ -1859,10 +1838,10 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
          break;
 
       default:
-         _mesa_set_program_error (ctx, Program->Position,
-                                  "Unexpected token in parse_param_elements()");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Unexpected token in parse_param_elements()");
+         _mesa_set_program_error(ctx, Program->Position,
+                                 "Unexpected token in parse_param_elements()");
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "Unexpected token in parse_param_elements()");
          return 1;
    }
 
@@ -1882,6 +1861,7 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
    return err;
 }
 
+
 /**
  * This picks out PARAM program parameter bindings.
  *
@@ -1895,7 +1875,6 @@ parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 {
    GLuint found, err;
    GLint specified_length;
-   char *error_msg;
    struct var_cache *param_var;
 
    err = 0;
@@ -1903,7 +1882,8 @@ parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
    Program->Position = parse_position (inst);
 
    if (found) {
-      error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
+      char *error_msg = (char *)
+         _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
       _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
                      param_var->name);
 
@@ -1948,10 +1928,10 @@ parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
    /* Test array length here! */
    if (specified_length) {
       if (specified_length != (int)param_var->param_binding_length) {
-         _mesa_set_program_error (ctx, Program->Position,
-                                  "Declared parameter array length does not match parameter list");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Declared parameter array length does not match parameter list");
+         const char *msg
+            = "Declared parameter array length does not match parameter list";
+         _mesa_set_program_error(ctx, Program->Position, msg);
+         _mesa_error(ctx, GL_INVALID_OPERATION, msg);
       }
    }
 
@@ -2005,13 +1985,12 @@ parse_temp (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 {
    GLuint found;
    struct var_cache *temp_var;
-   char *error_msg;
 
    while (**inst != 0) {
       temp_var = parse_string (inst, vc_head, Program, &found);
       Program->Position = parse_position (inst);
       if (found) {
-         error_msg = (char *)
+         char *error_msg = (char *)
             _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
          _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
                         temp_var->name);
@@ -2057,12 +2036,12 @@ parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 {
    GLuint found;
    struct var_cache *output_var;
+   GLuint err;
 
    output_var = parse_string (inst, vc_head, Program, &found);
    Program->Position = parse_position (inst);
    if (found) {
-      char *error_msg;
-      error_msg = (char *)
+      char *error_msg = (char *)
          _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);
       _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
                      output_var->name);
@@ -2075,8 +2054,9 @@ parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
    }
 
    output_var->type = vt_output;
-   return parse_result_binding (ctx, inst, &output_var->output_binding,
-                                &output_var->output_binding_idx, Program);
+
+   err = parse_result_binding(ctx, inst, &output_var->output_binding, Program);
+   return err;
 }
 
 /**
@@ -2090,14 +2070,12 @@ parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 {
    GLuint found;
    struct var_cache *temp_var;
-   char *error_msg;
-
 
    temp_var = parse_string (inst, vc_head, Program, &found);
    Program->Position = parse_position (inst);
 
    if (found) {
-      error_msg = (char *)
+      char *error_msg = (char *)
          _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
       _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
                      temp_var->name);
@@ -2115,7 +2093,7 @@ parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 
    if (!found)
    {
-      error_msg = (char *)
+      char *error_msg = (char *)
          _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
       _mesa_sprintf (error_msg, "Alias value %s is not defined",
                      temp_var->alias_binding->name);
@@ -2141,13 +2119,12 @@ parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 {
    GLuint found;
    struct var_cache *temp_var;
-   char *error_msg;
 
    while (**inst != 0) {
       temp_var = parse_string (inst, vc_head, Program, &found);
       Program->Position = parse_position (inst);
       if (found) {
-         error_msg = (char *)
+         char *error_msg = (char *)
             _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
          _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
                         temp_var->name);
@@ -2163,10 +2140,10 @@ parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 
       if (Program->Base.NumAddressRegs >=
           ctx->Const.MaxVertexProgramAddressRegs) {
-         _mesa_set_program_error (ctx, Program->Position,
-                                  "Too many ADDRESS variables declared");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Too many ADDRESS variables declared");
+         const char *msg = "Too many ADDRESS variables declared";
+         _mesa_set_program_error(ctx, Program->Position, msg);
+                                  
+         _mesa_error(ctx, GL_INVALID_OPERATION, msg);
          return 1;
       }
 
@@ -2219,10 +2196,11 @@ parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 }
 
 /**
- * Handle the parsing out of a masked destination register
+ * Handle the parsing out of a masked destination register, either for a
+ * vertex or fragment program.
  *
  * If we are a vertex program, make sure we don't write to
- * result.position of we have specified that the program is
+ * result.position if we have specified that the program is
  * position invariant
  *
  * \param File      - The register file we write to
@@ -2234,9 +2212,9 @@ parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 static GLuint
 parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
                       struct var_cache **vc_head, struct arb_program *Program,
-                      GLint * File, GLint * Index, GLint *WriteMask)
+                      enum register_file *File, GLuint *Index, GLint *WriteMask)
 {
-   GLuint result, tmp;
+   GLuint tmp, result;
    struct var_cache *dst;
 
    /* We either have a result register specified, or a
@@ -2244,8 +2222,7 @@ parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
     */
    switch (*(*inst)++) {
       case REGISTER_RESULT:
-         if (parse_result_binding
-             (ctx, inst, &result, (GLuint *) Index, Program))
+         if (parse_result_binding(ctx, inst, Index, Program))
             return 1;
          *File = PROGRAM_OUTPUT;
          break;
@@ -2266,7 +2243,7 @@ parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
          switch (dst->type) {
             case vt_output:
                *File = PROGRAM_OUTPUT;
-               *Index = dst->output_binding_idx;
+               *Index = dst->output_binding;
                break;
 
             case vt_temp:
@@ -2479,7 +2456,8 @@ parse_extended_swizzle_mask(GLubyte **inst, GLubyte swizzle[4],
 
 static GLuint
 parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-               struct arb_program *Program, GLint * File, GLint * Index,
+               struct arb_program *Program,
+               enum register_file * File, GLint * Index,
                GLboolean *IsRelOffset )
 {
    struct var_cache *src;
@@ -2508,10 +2486,10 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
          src->attrib_is_generic  = is_generic;
          var_cache_append(vc_head, src);
          if (generic_attrib_check(*vc_head)) {
-            _mesa_set_program_error (ctx, Program->Position,
-   "Cannot use both a generic vertex attribute and a specific attribute of the same type");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-   "Cannot use both a generic vertex attribute and a specific attribute of the same type");
+            const char *msg = "Cannot use both a generic vertex attribute "
+               "and a specific attribute of the same type";
+            _mesa_set_program_error (ctx, Program->Position, msg);
+            _mesa_error (ctx, GL_INVALID_OPERATION, msg);
             return 1;
          }
          break;
@@ -2587,7 +2565,6 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
          break;
 
       case REGISTER_ESTABLISHED_NAME:
-
          src = parse_string (inst, vc_head, Program, &found);
          Program->Position = parse_position (inst);
 
@@ -2647,7 +2624,7 @@ parse_fp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
                         struct arb_program *program,
                         struct fp_src_register *reg)
 {
-   GLint file;
+   enum register_file file;
    GLint index;
    GLboolean negate;
    GLubyte swizzle[4];
@@ -2678,8 +2655,10 @@ parse_fp_dst_reg(GLcontext * ctx, GLubyte ** inst,
                 struct var_cache **vc_head, struct arb_program *Program,
                 struct fp_dst_register *reg )
 {
-   GLint file, idx, mask;
-   
+   GLint mask;
+   GLuint idx;
+   enum register_file file;
+
    if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask))
       return 1;
 
@@ -2692,16 +2671,18 @@ parse_fp_dst_reg(GLcontext * ctx, GLubyte ** inst,
 }
 
 
-
+/**
+ * Parse fragment program scalar src register.
+ */
 static GLuint
 parse_fp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
-                        struct var_cache **vc_head, struct arb_program *Program,
+                        struct var_cache **vc_head,
+                         struct arb_program *Program,
                         struct fp_src_register *reg )
 {
-
-   GLint File;
+   enum register_file File;
    GLint Index;
-   GLboolean Negate;
+   GLubyte Negate;
    GLubyte Swizzle[4];
    GLboolean IsRelOffset;
 
@@ -2740,19 +2721,11 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
    GLubyte instClass, type, code;
    GLboolean rel;
 
-   /* No condition codes in ARB_fp */
-   fp->UpdateCondRegister = 0;
+   _mesa_init_fp_instruction(fp);
 
    /* Record the position in the program string for debugging */
    fp->StringPos = Program->Position;
 
-   fp->Data = NULL;
-
-   fp->DstReg.File = 0xf;      /* mark as undef */
-   fp->SrcReg[0].File = 0xf;   /* mark as undef */
-   fp->SrcReg[1].File = 0xf;   /* mark as undef */
-   fp->SrcReg[2].File = 0xf;   /* mark as undef */
-
    /* OP_ALU_INST or OP_TEX_INST */
    instClass = *(*inst)++;
 
@@ -2774,11 +2747,6 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
          break;
    }
 
-   fp->Saturate = 0;
-   fp->Precision = FLOAT32;
-
-   fp->DstReg.CondMask = COND_TR;
-
    switch (type) {
       case OP_ALU_VECTOR:
          switch (code) {
@@ -3019,7 +2987,8 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
         {
            GLubyte swizzle[4];
            GLubyte negateMask;
-           GLint file, index;
+            enum register_file file;
+           GLint index;
 
            if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &rel))
               return 1;
@@ -3107,7 +3076,9 @@ parse_vp_dst_reg(GLcontext * ctx, GLubyte ** inst,
                 struct var_cache **vc_head, struct arb_program *Program,
                 struct vp_dst_register *reg )
 {
-   GLint file, idx, mask;
+   GLint mask;
+   GLuint idx;
+   enum register_file file;
 
    if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask))
       return 1;
@@ -3149,6 +3120,7 @@ parse_vp_address_reg (GLcontext * ctx, GLubyte ** inst,
 }
 
 /**
+ * Parse vertex program vector source register.
  */
 static GLuint
 parse_vp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
@@ -3156,14 +3128,14 @@ parse_vp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
                         struct arb_program *program,
                         struct vp_src_register *reg )
 {
-   GLint file;
+   enum register_file file;
    GLint index;
-   GLboolean negate;
+   GLubyte negateMask;
    GLubyte swizzle[4];
    GLboolean isRelOffset;
 
    /* Grab the sign */
-   negate = (parse_sign (inst) == -1) ? 0xf : 0x0;
+   negateMask = (parse_sign (inst) == -1) ? 0xf : 0x0;
 
    /* And the src reg */
    if (parse_src_reg (ctx, inst, vc_head, program, &file, &index, &isRelOffset))
@@ -3176,7 +3148,7 @@ parse_vp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
    reg->Index = index;
    reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
                                 swizzle[2], swizzle[3]);
-   reg->Negate = negate;
+   reg->Negate = negateMask;
    reg->RelAddr = isRelOffset;
    return 0;
 }
@@ -3184,13 +3156,13 @@ parse_vp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
 
 static GLuint
 parse_vp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
-                        struct var_cache **vc_head, struct arb_program *Program,
+                        struct var_cache **vc_head,
+                         struct arb_program *Program,
                         struct vp_src_register *reg )
 {
-
-   GLint File;
+   enum register_file File;
    GLint Index;
-   GLboolean Negate;
+   GLubyte Negate;
    GLubyte Swizzle[4];
    GLboolean IsRelOffset;
 
@@ -3231,15 +3203,9 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
    /* The actual opcode name */
    code = *(*inst)++;
 
+   _mesa_init_vp_instruction(vp);
    /* Record the position in the program string for debugging */
    vp->StringPos = Program->Position;
-   vp->Data = NULL;
-   vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0;
-   vp->SrcReg[0].Swizzle = SWIZZLE_NOOP;
-   vp->SrcReg[1].Swizzle = SWIZZLE_NOOP;
-   vp->SrcReg[2].Swizzle = SWIZZLE_NOOP;
-   vp->SrcReg[3].Swizzle = SWIZZLE_NOOP;
-   vp->DstReg.WriteMask = 0xf;
 
    switch (type) {
          /* XXX: */
@@ -3403,7 +3369,8 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
            GLubyte swizzle[4]; 
            GLubyte negateMask;
            GLboolean relAddr;
-           GLint file, index;
+            enum register_file file;
+           GLint index;
 
            if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
               return 1;
@@ -3678,6 +3645,33 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head,
 #endif
 
 
+/**
+ * Grow an array of fragment program instructions.
+ */
+static struct fp_instruction *
+realloc_fp_instructions(struct fp_instruction *oldArray, GLuint oldSize)
+{
+   struct fp_instruction *array = (struct fp_instruction *)
+      _mesa_realloc(oldArray,
+                    oldSize * sizeof(struct fp_instruction),
+                    (oldSize + 1) * sizeof(struct fp_instruction));
+   return array;
+}
+
+/**
+ * Grow an array of vertex program instructions.
+ */
+static struct vp_instruction *
+realloc_vp_instructions(struct vp_instruction *oldArray, GLuint oldSize)
+{
+   struct vp_instruction *array = (struct vp_instruction *)
+      _mesa_realloc(oldArray,
+                    oldSize * sizeof(struct vp_instruction),
+                    (oldSize + 1) * sizeof(struct vp_instruction));
+   return array;
+}
+
+
 /**
  * The main loop for parsing a fragment or vertex program
  *
@@ -3740,48 +3734,38 @@ parse_arb_program(GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
             Program->Position = parse_position (&inst);
 
             if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-
-               /* Check the instruction count
-                * XXX: Does END count as an instruction?
-                */
-               if (Program->Base.NumInstructions+1 == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) {
-                  _mesa_set_program_error (ctx, Program->Position,
-                      "Max instruction count exceeded!");
-                  _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Max instruction count exceeded!");
+               /* Check instruction count.  END counts as an instruction. */
+               if (Program->Base.NumInstructions + 1
+                   == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) {
+                  const char *msg = "Max instruction count exceeded";
+                  _mesa_set_program_error(ctx, Program->Position, msg);
+                  _mesa_error(ctx, GL_INVALID_OPERATION, msg);
                }
 
-               /* Realloc Program->FPInstructions */
-               Program->FPInstructions =
-                  (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
-                                                           Program->Base.NumInstructions*sizeof(struct fp_instruction),
-                                                           (Program->Base.NumInstructions+1)*sizeof (struct fp_instruction));
-
-               /* parse the current instruction   */
+               /* grow instruction list */
+               Program->FPInstructions
+                  = realloc_fp_instructions(Program->FPInstructions,
+                                            Program->Base.NumInstructions);
+               /* parse the current instruction */
                err = parse_fp_instruction (ctx, &inst, vc_head, Program,
-                                           &Program->FPInstructions[Program->Base.NumInstructions]);
-
+                      &Program->FPInstructions[Program->Base.NumInstructions]);
             }
             else {
-               /* Check the instruction count
-                * XXX: Does END count as an instruction?
-                */
-               if (Program->Base.NumInstructions+1 == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) {
-                  _mesa_set_program_error (ctx, Program->Position,
-                      "Max instruction count exceeded!");
-                  _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Max instruction count exceeded!");
+               /* Check instruction count.  END counts as an instruction. */
+               if (Program->Base.NumInstructions + 1
+                   == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) {
+                  const char *msg = "Max instruction count exceeded";
+                  _mesa_set_program_error(ctx, Program->Position, msg);
+                  _mesa_error(ctx, GL_INVALID_OPERATION, msg);
                }
 
-               /* Realloc Program->VPInstructions */
-               Program->VPInstructions =
-                  (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
-                                                           Program->Base.NumInstructions*sizeof(struct vp_instruction),
-                                                           (Program->Base.NumInstructions +1)*sizeof(struct vp_instruction));
-
-               /* parse the current instruction   */
+               /* grow instruction list */
+               Program->VPInstructions
+                  = realloc_vp_instructions(Program->VPInstructions,
+                                            Program->Base.NumInstructions);
+               /* parse the current instruction */
                err = parse_vp_instruction (ctx, &inst, vc_head, Program,
-                                           &Program->VPInstructions[Program->Base.NumInstructions]);
+                      &Program->VPInstructions[Program->Base.NumInstructions]);
             }
 
             /* increment Program->Base.NumInstructions */
@@ -3802,48 +3786,39 @@ parse_arb_program(GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
 
    /* Finally, tag on an OPCODE_END instruction */
    if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-      Program->FPInstructions =
-         (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
-                                                 Program->Base.NumInstructions*sizeof(struct fp_instruction),
-                                                  (Program->Base.NumInstructions+1)*sizeof(struct fp_instruction));
-
-      Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END;
-      Program->FPInstructions[Program->Base.NumInstructions].Saturate = 0;
-      Program->FPInstructions[Program->Base.NumInstructions].DstReg.File = 0xf;
-      Program->FPInstructions[Program->Base.NumInstructions].SrcReg[0].File = 0xf;
-      Program->FPInstructions[Program->Base.NumInstructions].SrcReg[1].File = 0xf;
-      Program->FPInstructions[Program->Base.NumInstructions].SrcReg[2].File = 0xf;
+      const GLuint numInst = Program->Base.NumInstructions;
+      Program->FPInstructions
+         = realloc_fp_instructions(Program->FPInstructions, numInst);
+      _mesa_init_fp_instruction(Program->FPInstructions + numInst);
+      Program->FPInstructions[numInst].Opcode = FP_OPCODE_END;
       /* YYY Wrong Position in program, whatever, at least not random -> crash
         Program->Position = parse_position (&inst);
       */
-      Program->FPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
-      Program->FPInstructions[Program->Base.NumInstructions].Data = NULL;
+      Program->FPInstructions[numInst].StringPos = Program->Position;
    }
    else {
-      Program->VPInstructions =
-         (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
-                                                  Program->Base.NumInstructions*sizeof(struct vp_instruction),
-                                                  (Program->Base.NumInstructions+1)*sizeof(struct vp_instruction));
-
-      Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END;
+      const GLuint numInst = Program->Base.NumInstructions;
+      Program->VPInstructions
+         = realloc_vp_instructions(Program->VPInstructions, numInst);
+      _mesa_init_vp_instruction(Program->VPInstructions + numInst);
+      Program->VPInstructions[numInst].Opcode = VP_OPCODE_END;
       /* YYY Wrong Position in program, whatever, at least not random -> crash
         Program->Position = parse_position (&inst);
       */
-      Program->VPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
-      Program->VPInstructions[Program->Base.NumInstructions].Data = NULL;
+      Program->VPInstructions[numInst].StringPos = Program->Position;
    }
-
-   /* increment Program->Base.NumInstructions */
    Program->Base.NumInstructions++;
 
    return err;
 }
 
+
 /* XXX temporary */
 __extension__ static char core_grammar_text[] =
 #include "grammar_syn.h"
 ;
 
+
 static int set_reg8 (GLcontext *ctx, grammar id, const byte *name, byte value)
 {
    char error_msg[300];
index 4f27a96eebf62fb00a7d61337f11b36a5daf06fa..520bf05627316126f47bcd45842667ba2b66317d 100644 (file)
@@ -1259,12 +1259,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
       GLubyte token[100];
 
       /* Initialize the instruction */
-      inst->SrcReg[0].File = PROGRAM_UNDEFINED;
-      inst->SrcReg[1].File = PROGRAM_UNDEFINED;
-      inst->SrcReg[2].File = PROGRAM_UNDEFINED;
-      inst->DstReg.File = PROGRAM_UNDEFINED;
-      inst->DstReg.CondSwizzle = SWIZZLE_NOOP;
-      inst->Data = NULL;
+      _mesa_init_fp_instruction(inst);
 
       /* special instructions */
       if (Parse_String(parseState, "DEFINE")) {
@@ -1823,3 +1818,24 @@ _mesa_nv_fragment_output_register_name(GLuint i)
    ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS);
    return OutputRegisters[i];
 }
+
+
+/**
+ * Initialize fragment program instruction fields to defaults.
+ */
+void
+_mesa_init_fp_instruction(struct fp_instruction *inst)
+{
+   _mesa_bzero(inst, sizeof(struct fp_instruction));
+   inst->SrcReg[0].File = PROGRAM_UNDEFINED;
+   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
+   inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+   inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+   inst->SrcReg[2].File = PROGRAM_UNDEFINED;
+   inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
+   inst->DstReg.File = PROGRAM_UNDEFINED;
+   inst->DstReg.WriteMask = 0xf;
+   inst->DstReg.CondSwizzle = SWIZZLE_NOOP;
+   inst->Precision = FLOAT32;
+   inst->DstReg.CondMask = COND_TR;
+}
index a7149cfdb94c6e68fb0ba165043d0b65c361d16b..99ec20bb8284e1201ab51b3486ba54fb8c04a72f 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.3
+ * Version:  6.5
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2005  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"),
 #include "config.h"
 #include "mtypes.h"
 
-/* output registers */
-#define FRAG_OUTPUT_COLR  0
-#define FRAG_OUTPUT_COLH  1
-#define FRAG_OUTPUT_DEPR  2
+
+/**
+ * Fragment program output registers.
+ * Note: when we fully suppport GL_ARB_draw_buffers we'll have more than
+ * one output color.
+ */
+#define FRAG_OUTPUT_COLR  0   /* fragment color */
+#define FRAG_OUTPUT_COLH  1   /* fragment color, half precision (NV) */
+#define FRAG_OUTPUT_DEPR  2   /* depth/Z */
 
 
 /* condition codes */
@@ -165,4 +170,8 @@ struct fp_instruction
 };
 
 
+extern void
+_mesa_init_fp_instruction(struct fp_instruction *inst);
+
+
 #endif
index 33bc2004acd42303d96383192fb6c1eee159e500..c48a4cb358f0a115c13cb769a7dbe02cf28c0ee2 100644 (file)
@@ -1142,11 +1142,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
       struct vp_instruction *inst = program + parseState->numInst;
 
       /* Initialize the instruction */
-      inst->SrcReg[0].File = PROGRAM_UNDEFINED;
-      inst->SrcReg[1].File = PROGRAM_UNDEFINED;
-      inst->SrcReg[2].File = PROGRAM_UNDEFINED;
-      inst->DstReg.File = PROGRAM_UNDEFINED;
-      inst->Data = NULL;
+      _mesa_init_vp_instruction(inst);
 
       if (Parse_String(parseState, "MOV")) {
          if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV))
@@ -1601,3 +1597,22 @@ _mesa_nv_vertex_output_register_name(GLuint i)
    ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
    return OutputRegisters[i];
 }
+
+
+/**
+ * Initialize vertex program instruction fields to defaults.
+ */
+void
+_mesa_init_vp_instruction(struct vp_instruction *inst)
+{
+   _mesa_bzero(inst, sizeof(struct vp_instruction));
+   inst->SrcReg[0].File = PROGRAM_UNDEFINED;
+   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
+   inst->SrcReg[1].File = PROGRAM_UNDEFINED;
+   inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+   inst->SrcReg[2].File = PROGRAM_UNDEFINED;
+   inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
+   inst->DstReg.File = PROGRAM_UNDEFINED;
+   inst->DstReg.WriteMask = 0xf;
+}
+
index b8dbe363134adc6ff3dff8e954e426d58968a935..994a324f8fc390ce012213f76a36e50cf1ffbba8 100644 (file)
@@ -108,4 +108,8 @@ struct vp_instruction
 };
 
 
+extern void
+_mesa_init_vp_instruction(struct vp_instruction *inst);
+
+
 #endif /* VERTPROG_H */