arbprogparse.c
来自「mesa-6.5-minigui源码」· C语言 代码 · 共 1,997 行 · 第 1/5 页
C
1,997 行
{ GLuint type, coord; state_tokens[0] = STATE_TEXGEN; /*state_tokens[1] = parse_integer (inst, Program);*/ /* Texture Unit */ if (parse_texcoord_num (ctx, inst, Program, &coord)) return 1; state_tokens[1] = coord; /* EYE or OBJECT */ type = *(*inst++); /* 0 - s, 1 - t, 2 - r, 3 - q */ coord = *(*inst++); if (type == TEX_GEN_EYE) { switch (coord) { case COMPONENT_X: state_tokens[2] = STATE_TEXGEN_EYE_S; break; case COMPONENT_Y: state_tokens[2] = STATE_TEXGEN_EYE_T; break; case COMPONENT_Z: state_tokens[2] = STATE_TEXGEN_EYE_R; break; case COMPONENT_W: state_tokens[2] = STATE_TEXGEN_EYE_Q; break; } } else { switch (coord) { case COMPONENT_X: state_tokens[2] = STATE_TEXGEN_OBJECT_S; break; case COMPONENT_Y: state_tokens[2] = STATE_TEXGEN_OBJECT_T; break; case COMPONENT_Z: state_tokens[2] = STATE_TEXGEN_OBJECT_R; break; case COMPONENT_W: state_tokens[2] = STATE_TEXGEN_OBJECT_Q; break; } } } break; case STATE_DEPTH: switch (*(*inst)++) { case DEPTH_RANGE: state_tokens[0] = STATE_DEPTH_RANGE; break; } break; case STATE_CLIP_PLANE: state_tokens[0] = STATE_CLIPPLANE; state_tokens[1] = parse_integer (inst, Program); if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1])) return 1; break; case STATE_POINT: switch (*(*inst++)) { case POINT_SIZE: state_tokens[0] = STATE_POINT_SIZE; break; case POINT_ATTENUATION: state_tokens[0] = STATE_POINT_ATTENUATION; break; } break; /* XXX: I think this is the correct format for a matrix row */ case STATE_MATRIX_ROWS: state_tokens[0] = STATE_MATRIX; if (parse_matrix (ctx, inst, Program, &state_tokens[1], &state_tokens[2], &state_tokens[5])) return 1; state_tokens[3] = parse_integer (inst, Program); /* The first row to grab */ if ((**inst) != 0) { /* Either the last row, 0 */ state_tokens[4] = parse_integer (inst, Program); if (state_tokens[4] < state_tokens[3]) { _mesa_set_program_error (ctx, Program->Position, "Second matrix index less than the first"); _mesa_error (ctx, GL_INVALID_OPERATION, "Second matrix index (%d) less than the first (%d)", state_tokens[4], state_tokens[3]); return 1; } } else { state_tokens[4] = state_tokens[3]; (*inst)++; } break; } return 0;}/** * This parses a state string (rather, the binary version of it) into * a 6-token similar for the state fetching code in program.c * * One might ask, why fetch these parameters into just like you fetch * state when they are already stored in other places? * * Because of array offsets -> We can stick env/local parameters in the * middle of a parameter array and then index someplace into the array * when we execute. * * One optimization might be to only do this for the cases where the * env/local parameters end up inside of an array, and leave the * single parameters (or arrays of pure env/local pareameters) in their * respective register files. * * For ENV parameters, the format is: * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM * state_tokens[1] = STATE_ENV * state_tokens[2] = the parameter index * * for LOCAL parameters, the format is: * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM * state_tokens[1] = STATE_LOCAL * state_tokens[2] = the parameter index * * \param inst - the start in the binary arry to start working from * \param state_tokens - the storage for the 6-token state description * \return - 0 on sucess, 1 on failure */static GLuintparse_program_single_item (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program, GLint * state_tokens){ if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) state_tokens[0] = STATE_FRAGMENT_PROGRAM; else state_tokens[0] = STATE_VERTEX_PROGRAM; switch (*(*inst)++) { case PROGRAM_PARAM_ENV: state_tokens[1] = STATE_ENV; state_tokens[2] = parse_integer (inst, Program); /* Check state_tokens[2] against the number of ENV parameters available */ if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && (state_tokens[2] >= (GLint) ctx->Const.FragmentProgram.MaxEnvParams)) || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && (state_tokens[2] >= (GLint) ctx->Const.VertexProgram.MaxEnvParams))) { _mesa_set_program_error (ctx, Program->Position, "Invalid Program Env Parameter"); _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid Program Env Parameter: %d", state_tokens[2]); return 1; } break; case PROGRAM_PARAM_LOCAL: state_tokens[1] = STATE_LOCAL; state_tokens[2] = parse_integer (inst, Program); /* Check state_tokens[2] against the number of LOCAL parameters available */ if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && (state_tokens[2] >= (GLint) ctx->Const.FragmentProgram.MaxLocalParams)) || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && (state_tokens[2] >= (GLint) ctx->Const.VertexProgram.MaxLocalParams))) { _mesa_set_program_error (ctx, Program->Position, "Invalid Program Local Parameter"); _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid Program Local Parameter: %d", state_tokens[2]); return 1; } break; } return 0;}/** * For ARB_vertex_program, programs are not allowed to use both an explicit * vertex attribute and a generic vertex attribute corresponding to the same * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec. * * This will walk our var_cache and make sure that nobody does anything fishy. * * \return 0 on sucess, 1 on error */static GLuintgeneric_attrib_check(struct var_cache *vc_head){ int a; struct var_cache *curr; GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS], genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS]; for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) { explicitAttrib[a] = GL_FALSE; genericAttrib[a] = GL_FALSE; } curr = vc_head; while (curr) { if (curr->type == vt_attrib) { if (curr->attrib_is_generic) genericAttrib[ curr->attrib_binding ] = GL_TRUE; else explicitAttrib[ curr->attrib_binding ] = GL_TRUE; } curr = curr->next; } for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) { if ((explicitAttrib[a]) && (genericAttrib[a])) return 1; } return 0;}/** * This will handle the binding side of an ATTRIB var declaration * * \param inputReg returns the input register index, one of the * VERT_ATTRIB_* or FRAG_ATTRIB_* values. * \return returns 0 on sucess, 1 on error */static GLuintparse_attrib_binding(GLcontext * ctx, GLubyte ** inst, struct arb_program *Program, GLuint *inputReg, GLuint *is_generic){ GLint err = 0; *is_generic = 0; if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { switch (*(*inst)++) { case FRAGMENT_ATTRIB_COLOR: { GLint coord; err = parse_color_type (ctx, inst, Program, &coord); *inputReg = FRAG_ATTRIB_COL0 + coord; } break; case FRAGMENT_ATTRIB_TEXCOORD: { GLuint texcoord; err = parse_texcoord_num (ctx, inst, Program, &texcoord); *inputReg = FRAG_ATTRIB_TEX0 + texcoord; } break; case FRAGMENT_ATTRIB_FOGCOORD: *inputReg = FRAG_ATTRIB_FOGC; break; case FRAGMENT_ATTRIB_POSITION: *inputReg = FRAG_ATTRIB_WPOS; break; default: err = 1; break; } } else { switch (*(*inst)++) { case VERTEX_ATTRIB_POSITION: *inputReg = VERT_ATTRIB_POS; break; case VERTEX_ATTRIB_WEIGHT: { const char *msg = "ARB_vertex_blend not supported"; GLint weight; err = parse_weight_num (ctx, inst, Program, &weight); *inputReg = VERT_ATTRIB_WEIGHT; _mesa_set_program_error(ctx, Program->Position, msg); _mesa_error(ctx, GL_INVALID_OPERATION, msg); } return 1; case VERTEX_ATTRIB_NORMAL: *inputReg = VERT_ATTRIB_NORMAL; break; case VERTEX_ATTRIB_COLOR: { GLint color; err = parse_color_type (ctx, inst, Program, &color); if (color) { *inputReg = VERT_ATTRIB_COLOR1; } else { *inputReg = VERT_ATTRIB_COLOR0; } } break; case VERTEX_ATTRIB_FOGCOORD: *inputReg = VERT_ATTRIB_FOG; break; case VERTEX_ATTRIB_TEXCOORD: { GLuint unit; err = parse_texcoord_num (ctx, inst, Program, &unit); *inputReg = VERT_ATTRIB_TEX0 + unit; } break; case VERTEX_ATTRIB_MATRIXINDEX: /* Not supported at this time */ { const char *msg = "ARB_palette_matrix not supported"; parse_integer (inst, Program); _mesa_set_program_error (ctx, Program->Position, msg); _mesa_error (ctx, GL_INVALID_OPERATION, msg); } return 1; case VERTEX_ATTRIB_GENERIC: { GLuint attrib; if (!parse_generic_attrib_num(ctx, inst, Program, &attrib)) { *is_generic = 1; *inputReg = attrib; } } break; default: err = 1; break; } } /* Can this even happen? */ if (err) { const char *msg = "Bad attribute binding"; _mesa_set_program_error(ctx, Program->Position, msg); _mesa_error(ctx, GL_INVALID_OPERATION, msg); } Program->Base.InputsRead |= (1 << *inputReg); 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, 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; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?