⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arbprogparse.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
                     case 5:
                        *binding = VERT_ATTRIB_FOG;
                        break;
                     case 6:
                        break;
                     case 7:
                        break;
                     default:
                        *binding = VERT_ATTRIB_TEX0 + (attrib-8);
                        break;
                  }
                  *binding_idx = attrib;
               }
            }
            break;

         default:
            err = 1;
            break;
      }
   }

   /* Can this even happen? */
   if (err) {
      _mesa_set_program_error (ctx, Program->Position,
                               "Bad attribute binding");
      _mesa_error (ctx, GL_INVALID_OPERATION, "Bad attribute binding");
   }

   Program->InputsRead |= (1 << *binding_idx);

   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
 */
static GLuint
parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding,
                      GLuint * binding_idx, struct arb_program *Program)
{
   GLuint b, out_color;

   switch (*(*inst)++) {
      case FRAGMENT_RESULT_COLOR:
         /* for frag programs, this is FRAGMENT_RESULT_COLOR */
         if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
            /* This gets result of the color buffer we're supposed to 
             * draw into
             */
            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;
         }
         /* for vtx programs, this is VERTEX_RESULT_POSITION */
         else {
            *binding_idx = 0;
         }
         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 vtx programs, this is VERTEX_RESULT_COLOR */
         else {
            GLint color_type;
            GLuint face_type = parse_face_type(inst);
	    GLint color_type_ret = parse_color_type(ctx, inst, Program, &color_type);

            /* back face */
            if (face_type) {
               if (color_type_ret) return 1;

               /* secondary color */
               if (color_type) {
                  *binding_idx = 4;
               }
               /*  primary color */
               else {
                  *binding_idx = 3;
               }
            }
            /* front face */
            else {
               /* secondary color */
               if (color_type) {
                  *binding_idx = 2;
               }
               /* primary color */
               else {
                  *binding_idx = 1;
               }
            }
         }
         break;

      case VERTEX_RESULT_FOGCOORD:
         *binding_idx = 5;
         break;

      case VERTEX_RESULT_POINTSIZE:
         *binding_idx = 6;
         break;

      case VERTEX_RESULT_TEXCOORD:
         if (parse_texcoord_num (ctx, inst, Program, &b))
            return 1;
         *binding_idx = 7 + b;
         break;
   }

   Program->OutputsWritten |= (1 << *binding_idx);

   return 0;
}

/**
 * This handles the declaration of ATTRIB variables
 *
 * XXX: Still needs
 *      parse_vert_attrib_binding(), or something like that
 *
 * \return 0 on sucess, 1 on error
 */
static GLint
parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
              struct arb_program *Program)
{
   GLuint found;
   char *error_msg;
   struct var_cache *attrib_var;

   attrib_var = parse_string (inst, vc_head, Program, &found);
   Program->Position = parse_position (inst);
   if (found) {
      error_msg = (char *)
         _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40);
      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
                     attrib_var->name);

      _mesa_set_program_error (ctx, Program->Position, error_msg);
      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);

      _mesa_free (error_msg);
      return 1;
   }

   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;
      }

   }

   Program->Base.NumAttributes++;
   return 0;
}

/**
 * \param use -- TRUE if we're called when declaring implicit parameters,
 *               FALSE if we're declaraing variables. This has to do with
 *               if we get a signed or unsigned float for scalar constants
 */
static GLuint
parse_param_elements (GLcontext * ctx, GLubyte ** inst,
                      struct var_cache *param_var,
                      struct arb_program *Program, GLboolean use)
{
   GLint idx;
   GLuint err;
   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;

         /* If we adding STATE_MATRIX that has multiple rows, we need to
          * unroll it and call _mesa_add_state_reference() for each row
          */
         if ((state_tokens[0] == STATE_MATRIX)
             && (state_tokens[3] != state_tokens[4])) {
            GLint row;
            GLint first_row = state_tokens[3];
            GLint last_row = state_tokens[4];

            for (row = first_row; row <= last_row; row++) {
               state_tokens[3] = state_tokens[4] = row;

               idx =
                  _mesa_add_state_reference (Program->Parameters,
                                             state_tokens);
               if (param_var->param_binding_begin == ~0U)
                  param_var->param_binding_begin = idx;
               param_var->param_binding_length++;
               Program->Base.NumParameters++;
            }
         }
         else {
            idx =
               _mesa_add_state_reference (Program->Parameters, state_tokens);
            if (param_var->param_binding_begin == ~0U)
               param_var->param_binding_begin = idx;
            param_var->param_binding_length++;
            Program->Base.NumParameters++;
         }
         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);
         if (param_var->param_binding_begin == ~0U)
            param_var->param_binding_begin = idx;
         param_var->param_binding_length++;
         Program->Base.NumParameters++;

         /* Check if there is more: 0 -> we're done, else its an integer */
         if (**inst) {
            GLuint out_of_range, new_idx;
            GLuint start_idx = state_tokens[2] + 1;
            GLuint end_idx = parse_integer (inst, Program);

            out_of_range = 0;
            if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
               if (((state_tokens[1] == STATE_ENV)
                    && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams))
                   || ((state_tokens[1] == STATE_LOCAL)
                       && (end_idx >=
                           ctx->Const.MaxFragmentProgramLocalParams)))
                  out_of_range = 1;
            }
            else {
               if (((state_tokens[1] == STATE_ENV)
                    && (end_idx >= ctx->Const.MaxVertexProgramEnvParams))
                   || ((state_tokens[1] == STATE_LOCAL)
                       && (end_idx >=
                           ctx->Const.MaxVertexProgramLocalParams)))
                  out_of_range = 1;
            }
            if (out_of_range) {
               _mesa_set_program_error (ctx, Program->Position,
                                        "Invalid Program Parameter");
               _mesa_error (ctx, GL_INVALID_OPERATION,
                            "Invalid Program Parameter: %d", end_idx);
               return 1;
            }

            for (new_idx = start_idx; new_idx <= end_idx; new_idx++) {
               state_tokens[2] = new_idx;
               idx =
                  _mesa_add_state_reference (Program->Parameters,
                                             state_tokens);
               param_var->param_binding_length++;
               Program->Base.NumParameters++;
            }
         }
			else
			{
				(*inst)++;
			}
         break;

      case PARAM_CONSTANT:
         parse_constant (inst, const_values, Program, use);
         idx =
            _mesa_add_named_constant (Program->Parameters,
                                      (char *) param_var->name, const_values);
         if (param_var->param_binding_begin == ~0U)
            param_var->param_binding_begin = idx;
         param_var->param_binding_length++;
         Program->Base.NumParameters++;
         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()");
         return 1;
   }

   /* Make sure we haven't blown past our parameter limits */
   if (((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
        (Program->Base.NumParameters >=
         ctx->Const.MaxVertexProgramLocalParams))
       || ((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
           && (Program->Base.NumParameters >=
               ctx->Const.MaxFragmentProgramLocalParams))) {
      _mesa_set_program_error (ctx, Program->Position,
                               "Too many parameter variables");
      _mesa_error (ctx, GL_INVALID_OPERATION, "Too many parameter variables");
      return 1;
   }

   return err;
}

/**
 * This picks out PARAM program parameter bindings.
 *
 * XXX: This needs to be stressed & tested
 *
 * \return 0 on sucess, 1 on error
 */
static GLuint
parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
             struct arb_program *Program)
{
   GLuint found, err;
   GLint specified_length;
   char *error_msg;
   struct var_cache *param_var;

   err = 0;
   param_var = parse_string (inst, vc_head, Program, &found);
   Program->Position = parse_position (inst);

   if (found) {
      error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
                     param_var->name);

      _mesa_set_program_error (ctx, Program->Position, error_msg);
      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);

      _mesa_free (error_msg);
      return 1;
   }

   specified_length = parse_integer (inst, Program);

   if (specified_length < 0) {
      _mesa_set_program_error (ctx, Program->Position,
                               "Negative parameter array length");
      _mesa_error (ctx, GL_INVALID_OPERATION,
                   "Negative parameter array length: %d", specified_length);
      return 1;
   }

   param_var->type = vt_param;
   param_var->param_binding_length = 0;

   /* Right now, everything is shoved into the main state register file.
    *
    * In the future, it 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -