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

📄 arbprogparse.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
   if (err) {      program_error(ctx, Program->Position, "Bad attribute binding");   }   return err;}/** * This translates between a binary token for an output variable type * and the mesa token for the same thing. * * \param inst       The parsed tokens * \param outputReg  Returned index/number of the output register, *                   one of the VERT_RESULT_* or FRAG_RESULT_* values. */static GLuintparse_result_binding(GLcontext *ctx, const GLubyte **inst,                     GLuint *outputReg, struct arb_program *Program){   const GLubyte token = *(*inst)++;   switch (token) {      case 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.  This pertains to GL_ARB_draw_buffers.             */            parse_output_color_num(ctx, inst, Program, &out_color);            ASSERT(out_color < MAX_DRAW_BUFFERS);            *outputReg = FRAG_RESULT_COLR;         }         else {            /* for vtx programs, this is VERTEX_RESULT_POSITION */            *outputReg = VERT_RESULT_HPOS;         }         break;      case FRAGMENT_RESULT_DEPTH:         if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {            /* for frag programs, this is FRAGMENT_RESULT_DEPTH */            *outputReg = FRAG_RESULT_DEPR;         }         else {            /* for vtx programs, this is VERTEX_RESULT_COLOR */            GLint color_type;            GLuint face_type = parse_face_type(inst);	    GLint err = parse_color_type(ctx, inst, Program, &color_type);            if (err)               return 1;            if (face_type) {               /* back face */               if (color_type) {                  *outputReg = VERT_RESULT_BFC1; /* secondary color */               }               else {                  *outputReg = VERT_RESULT_BFC0; /* primary color */               }            }            else {               /* front face */               if (color_type) {                  *outputReg = VERT_RESULT_COL1; /* secondary color */               }               /* primary color */               else {                  *outputReg = VERT_RESULT_COL0; /* primary color */               }            }         }         break;      case VERTEX_RESULT_FOGCOORD:         *outputReg = VERT_RESULT_FOGC;         break;      case VERTEX_RESULT_POINTSIZE:         *outputReg = VERT_RESULT_PSIZ;         break;      case VERTEX_RESULT_TEXCOORD:         {            GLuint unit;            if (parse_texcoord_num (ctx, inst, Program, &unit))               return 1;            *outputReg = VERT_RESULT_TEX0 + unit;         }         break;   }   Program->Base.OutputsWritten |= (1 << *outputReg);   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 GLintparse_attrib (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,              struct arb_program *Program){   GLuint found;   struct var_cache *attrib_var;   attrib_var = parse_string (inst, vc_head, Program, &found);   Program->Position = parse_position (inst);   if (found) {      program_error2(ctx, Program->Position,                     "Duplicate variable declaration",                     (char *) attrib_var->name);      return 1;   }   attrib_var->type = vt_attrib;   if (parse_attrib_binding(ctx, inst, Program, &attrib_var->attrib_binding,                            &attrib_var->attrib_is_generic))      return 1;   if (generic_attrib_check(*vc_head)) {      program_error(ctx, Program->Position,                    "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 GLuintparse_param_elements (GLcontext * ctx, const GLubyte ** inst,                      struct var_cache *param_var,                      struct arb_program *Program, GLboolean use){   GLint idx;   GLuint err = 0;   gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};   GLfloat const_values[4];   GLubyte token = *(*inst)++;   switch (token) {      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_MODELVIEW_MATRIX ||              state_tokens[0] == STATE_PROJECTION_MATRIX ||              state_tokens[0] == STATE_MVP_MATRIX ||              state_tokens[0] == STATE_TEXTURE_MATRIX ||              state_tokens[0] == STATE_PROGRAM_MATRIX)             && (state_tokens[2] != state_tokens[3])) {            GLint row;            const GLint first_row = state_tokens[2];            const GLint last_row = state_tokens[3];            for (row = first_row; row <= last_row; row++) {               state_tokens[2] = state_tokens[3] = row;               idx = _mesa_add_state_reference(Program->Base.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->Base.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->Base.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.FragmentProgram.MaxEnvParams))                   || ((state_tokens[1] == STATE_LOCAL)                       && (end_idx >=                           ctx->Const.FragmentProgram.MaxLocalParams)))                  out_of_range = 1;            }            else {               if (((state_tokens[1] == STATE_ENV)                    && (end_idx >= ctx->Const.VertexProgram.MaxEnvParams))                   || ((state_tokens[1] == STATE_LOCAL)                       && (end_idx >=                           ctx->Const.VertexProgram.MaxLocalParams)))                  out_of_range = 1;            }            if (out_of_range) {               program_error(ctx, Program->Position,                             "Invalid Program Parameter"); /*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->Base.Parameters,                                               state_tokens);               param_var->param_binding_length++;               Program->Base.NumParameters++;            }         }         else {            (*inst)++;         }         break;      case PARAM_CONSTANT:         /* parsing something like {1.0, 2.0, 3.0, 4.0} */         parse_constant (inst, const_values, Program, use);         idx = _mesa_add_named_constant(Program->Base.Parameters,                                        (char *) param_var->name,                                        const_values, 4);         if (param_var->param_binding_begin == ~0U)            param_var->param_binding_begin = idx;         param_var->param_binding_type = PROGRAM_CONSTANT;         param_var->param_binding_length++;         Program->Base.NumParameters++;         break;      default:         program_error(ctx, Program->Position,                       "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.VertexProgram.MaxLocalParams))       || ((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)           && (Program->Base.NumParameters >=               ctx->Const.FragmentProgram.MaxLocalParams))) {      program_error(ctx, Program->Position, "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 GLuintparse_param (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,             struct arb_program *Program){   GLuint found, err;   GLint specified_length;   struct var_cache *param_var;   err = 0;   param_var = parse_string (inst, vc_head, Program, &found);   Program->Position = parse_position (inst);   if (found) {      program_error2(ctx, Program->Position,                     "Duplicate variable declaration",                     (char *) param_var->name);      return 1;   }   specified_length = parse_integer (inst, Program);   if (specified_length < 0) {      program_error(ctx, Program->Position, "Negative parameter array 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 would be nice to leave things ENV/LOCAL params    * in their respective register files, if possible    */   param_var->param_binding_type = PROGRAM_STATE_VAR;   /* Remember to:    * *   - add each guy to the parameter list    * *   - increment the param_var->param_binding_len    * *   - store the param_var->param_binding_begin for the first one    * *   - compare the actual len to the specified len at the end    */   while (**inst != PARAM_NULL) {      if (parse_param_elements (ctx, inst, param_var, Program, GL_FALSE))         return 1;   }   /* Test array length here! */   if (specified_length) {      if (specified_length != (int)param_var->param_binding_length) {         program_error(ctx, Program->Position,              "Declared parameter array length does not match parameter list");      }   }   (*inst)++;   return 0;}/** * */static GLuintparse_param_use (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,                 struct arb_program *Program, struct var_cache **new_var){   struct var_cache *param_var;   /* First, insert a dummy entry into the var_cache */   var_cache_create (&param_var);   param_var->name = (const GLubyte *) " ";   param_var->type = vt_param;   param_var->param_binding_length = 0;   /* Don't fill in binding_begin; We use the default value of -1    * to tell if its already initialized, elsewhere.    *    * param_var->param_binding_begin  = 0;    */   param_var->param_binding_type = PROGRAM_STATE_VAR;   var_cache_append (vc_head, param_var);   /* Then fill it with juicy parameter goodness */   if (parse_param_elements (ctx, inst, param_var, Program, GL_TRUE))      return 1;   *new_var = param_var;   return 0;}/** * This handles the declaration of TEMP variables * * \return 0 on sucess, 1 on error */static GLuintparse_temp (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,            struct arb_program *Program){   GLuint found;   struct var_cache *temp_var;   while (**inst != 0) {      temp_var = parse_string (inst, vc_head, Program, &found);      Program->Position = parse_position (inst);      if (found) {         program_error2(ctx, Program->Position,                        "Duplicate variable declaration",           

⌨️ 快捷键说明

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