X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fshader%2Farbprogparse.c;h=74004e9b137f8d9000aad5605e2d26958836d092;hb=fda5687241f4ce5cab3bf2eac437b52d4b37dd10;hp=7a87bf015ff11e4e7d67fb59fa187e2625bbfb02;hpb=c0551f0a465b577a17698ede46370a17e29b3df7;p=mesa.git diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 7a87bf015ff..74004e9b137 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 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"), @@ -30,10 +30,10 @@ * \author Karl Rasche */ -#include "glheader.h" -#include "imports.h" +#include "main/glheader.h" +#include "main/imports.h" +#include "shader/grammar/grammar_mesa.h" #include "arbprogparse.h" -#include "grammar_mesa.h" #include "program.h" #include "prog_parameter.h" #include "prog_statevars.h" @@ -71,6 +71,7 @@ struct arb_program /* ARB_fragment_program specifics */ GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; + GLbitfield ShadowSamplers; GLuint NumAluInstructions; GLuint NumTexInstructions; GLuint NumTexIndirections; @@ -181,7 +182,7 @@ LONGSTRING static char arb_grammar_text[] = - changed and merged V_* and F_* opcode values to OP_*. - added GL_ARB_fragment_program_shadow specific tokens (michal) */ -#define REVISION 0x09 +#define REVISION 0x0a /* program type */ #define FRAGMENT_PROGRAM 0x01 @@ -209,6 +210,9 @@ LONGSTRING static char arb_grammar_text[] = /* GL_ARB_draw_buffers option */ #define ARB_DRAW_BUFFERS 0x07 +/* GL_MESA_texture_array option */ +#define MESA_TEXTURE_ARRAY 0x08 + /* GL_ARB_fragment_program instruction class */ #define OP_ALU_INST 0x00 #define OP_TEX_INST 0x01 @@ -368,6 +372,11 @@ LONGSTRING static char arb_grammar_text[] = #define TEXTARGET_SHADOW1D 0x06 #define TEXTARGET_SHADOW2D 0x07 #define TEXTARGET_SHADOWRECT 0x08 +/* GL_MESA_texture_array */ +#define TEXTARGET_1D_ARRAY 0x09 +#define TEXTARGET_2D_ARRAY 0x0a +#define TEXTARGET_SHADOW1D_ARRAY 0x0b +#define TEXTARGET_SHADOW2D_ARRAY 0x0c /* face type */ #define FACE_FRONT 0x00 @@ -624,6 +633,41 @@ program_error(GLcontext *ctx, GLint position, const char *descrip) } +/** + * As above, but with an extra string parameter for more info. + */ +static void +program_error2(GLcontext *ctx, GLint position, const char *descrip, + const char *var) +{ + if (descrip) { + const char *prefix = "glProgramString(", *suffix = ")"; + char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + + _mesa_strlen(": ") + + _mesa_strlen(var) + + _mesa_strlen(prefix) + + _mesa_strlen(suffix) + 1); + if (str) { + _mesa_sprintf(str, "%s%s: %s%s", prefix, descrip, var, suffix); + _mesa_error(ctx, GL_INVALID_OPERATION, str); + _mesa_free(str); + } + } + { + char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + + _mesa_strlen(": ") + + _mesa_strlen(var) + 1); + if (str) { + _mesa_sprintf(str, "%s: %s", descrip, var); + } + _mesa_set_program_error(ctx, position, str); + if (str) { + _mesa_free(str); + } + } +} + + /** * constructs an integer from 4 GLubytes in LE format @@ -1010,7 +1054,7 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra switch (mat) { case MATRIX_MODELVIEW: - *matrix = STATE_MODELVIEW; + *matrix = STATE_MODELVIEW_MATRIX; *matrix_idx = parse_integer (inst, Program); if (*matrix_idx > 0) { program_error(ctx, Program->Position, @@ -1020,15 +1064,15 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra break; case MATRIX_PROJECTION: - *matrix = STATE_PROJECTION; + *matrix = STATE_PROJECTION_MATRIX; break; case MATRIX_MVP: - *matrix = STATE_MVP; + *matrix = STATE_MVP_MATRIX; break; case MATRIX_TEXTURE: - *matrix = STATE_TEXTURE; + *matrix = STATE_TEXTURE_MATRIX; *matrix_idx = parse_integer (inst, Program); if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) { program_error(ctx, Program->Position, "Invalid Texture Unit"); @@ -1046,7 +1090,7 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra break; case MATRIX_PROGRAM: - *matrix = STATE_PROGRAM; + *matrix = STATE_PROGRAM_MATRIX; *matrix_idx = parse_integer (inst, Program); if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) { program_error(ctx, Program->Position, "Invalid Program Matrix"); @@ -1085,7 +1129,8 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra */ static GLuint parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, - struct arb_program *Program, GLint * state_tokens) + struct arb_program *Program, + gl_state_index state_tokens[STATE_LENGTH]) { switch (*(*inst)++) { case STATE_MATERIAL_PARSER: @@ -1138,7 +1183,7 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, state_tokens[2] = STATE_ATTENUATION; break; case LIGHT_HALF: - state_tokens[2] = STATE_HALF; + state_tokens[2] = STATE_HALF_VECTOR; break; case LIGHT_SPOT_DIRECTION: state_tokens[2] = STATE_SPOT_DIRECTION; @@ -1216,10 +1261,10 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, state_tokens[1] = coord; /* EYE or OBJECT */ - type = *(*inst++); + type = *(*inst)++; /* 0 - s, 1 - t, 2 - r, 3 - q */ - coord = *(*inst++); + coord = *(*inst)++; if (type == TEX_GEN_EYE) { switch (coord) { @@ -1235,6 +1280,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, case COMPONENT_W: state_tokens[2] = STATE_TEXGEN_EYE_Q; break; + default: + _mesa_problem(ctx, "bad texgen component in " + "parse_state_single_item()"); } } else { @@ -1251,6 +1299,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, case COMPONENT_W: state_tokens[2] = STATE_TEXGEN_OBJECT_Q; break; + default: + _mesa_problem(ctx, "bad texgen component in " + "parse_state_single_item()"); } } } @@ -1267,12 +1318,13 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, 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])) + if (parse_clipplane_num (ctx, inst, Program, + (GLint *) &state_tokens[1])) return 1; break; case STATE_POINT: - switch (*(*inst++)) { + switch (*(*inst)++) { case POINT_SIZE: state_tokens[0] = STATE_POINT_SIZE; break; @@ -1285,17 +1337,17 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, /* 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])) + if (parse_matrix(ctx, inst, Program, + (GLint *) &state_tokens[0], + (GLint *) &state_tokens[1], + (GLint *) &state_tokens[4])) return 1; - state_tokens[3] = parse_integer (inst, Program); /* The first row to grab */ + state_tokens[2] = 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]) { + state_tokens[3] = parse_integer (inst, Program); + if (state_tokens[3] < state_tokens[2]) { program_error(ctx, Program->Position, "Second matrix index less than the first"); /* state_tokens[4] vs. state_tokens[3] */ @@ -1303,7 +1355,7 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, } } else { - state_tokens[4] = state_tokens[3]; + state_tokens[3] = state_tokens[2]; (*inst)++; } break; @@ -1344,7 +1396,8 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, */ static GLuint parse_program_single_item (GLcontext * ctx, const GLubyte ** inst, - struct arb_program *Program, GLint * state_tokens) + struct arb_program *Program, + gl_state_index state_tokens[STATE_LENGTH]) { if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) state_tokens[0] = STATE_FRAGMENT_PROGRAM; @@ -1461,7 +1514,7 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst, break; case FRAGMENT_ATTRIB_TEXCOORD: { - GLuint texcoord; + GLuint texcoord = 0; err = parse_texcoord_num (ctx, inst, Program, &texcoord); *inputReg = FRAG_ATTRIB_TEX0 + texcoord; } @@ -1522,7 +1575,7 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst, case VERTEX_ATTRIB_TEXCOORD: { - GLuint unit; + GLuint unit = 0; err = parse_texcoord_num (ctx, inst, Program, &unit); *inputReg = VERT_ATTRIB_TEX0 + unit; } @@ -1565,8 +1618,6 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst, program_error(ctx, Program->Position, "Bad attribute binding"); } - Program->Base.InputsRead |= (1 << *inputReg); - return err; } @@ -1675,18 +1726,14 @@ parse_attrib (GLcontext * ctx, const 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); - program_error(ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) attrib_var->name); return 1; } @@ -1719,7 +1766,7 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, { GLint idx; GLuint err = 0; - GLint state_tokens[6]; + gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0}; GLfloat const_values[4]; switch (*(*inst)++) { @@ -1730,14 +1777,18 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, /* 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])) { + 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; - GLint first_row = state_tokens[3]; - GLint last_row = state_tokens[4]; + const GLint first_row = state_tokens[2]; + const GLint last_row = state_tokens[3]; for (row = first_row; row <= last_row; row++) { - state_tokens[3] = state_tokens[4] = row; + state_tokens[2] = state_tokens[3] = row; idx = _mesa_add_state_reference(Program->Base.Parameters, state_tokens); @@ -1809,12 +1860,14 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** 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; @@ -1860,12 +1913,9 @@ parse_param (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - param_var->name); - program_error (ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) param_var->name); return 1; } @@ -1960,12 +2010,9 @@ parse_temp (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, temp_var = parse_string (inst, vc_head, Program, &found); Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - temp_var->name); - program_error(ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) temp_var->name); return 1; } @@ -2006,12 +2053,9 @@ parse_output (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head output_var = parse_string (inst, vc_head, Program, &found); Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - output_var->name); - program_error (ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) output_var->name); return 1; } @@ -2037,12 +2081,9 @@ parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - temp_var->name); - program_error(ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) temp_var->name); return 1; } @@ -2052,12 +2093,9 @@ parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, if (!found) { - 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); - program_error (ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Undefined alias value", + (char *) temp_var->alias_binding->name); return 1; } @@ -2080,12 +2118,9 @@ parse_address (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_hea temp_var = parse_string (inst, vc_head, Program, &found); Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - temp_var->name); - program_error (ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) temp_var->name); return 1; } @@ -2438,8 +2473,9 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, Program->Position = parse_position (inst); if (!found) { - program_error(ctx, Program->Position, - "2: Undefined variable"); /* src->name */ + program_error2(ctx, Program->Position, + "Undefined variable", + (char *) src->name); return 1; } @@ -2538,26 +2574,32 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, return 1; } + /* Add attributes to InputsRead only if they are used the program. + * This avoids the handling of unused ATTRIB declarations in the drivers. */ + if (*File == PROGRAM_INPUT) + Program->Base.InputsRead |= (1 << *Index); + return 0; } + /** - * Parse fragment program vector source register. + * Parse vertex/fragment program vector source register. */ static GLuint -parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, - struct arb_program *program, - struct prog_src_register *reg) +parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst, + struct var_cache **vc_head, + struct arb_program *program, + struct prog_src_register *reg) { 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) ? NEGATE_XYZW : NEGATE_NONE; /* And the src reg */ if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset)) @@ -2568,66 +2610,66 @@ parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst, reg->File = file; reg->Index = index; - reg->NegateBase = negate; reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); + reg->NegateBase = negateMask; + reg->RelAddr = isRelOffset; return 0; } /** - * Parse fragment program destination register. - * \return 1 if error, 0 if no error. + * Parse vertex/fragment program scalar source register. */ -static GLuint -parse_fp_dst_reg(GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, struct arb_program *Program, - struct prog_dst_register *reg ) +static GLuint +parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst, + struct var_cache **vc_head, + struct arb_program *program, + struct prog_src_register *reg) { - GLint mask; - GLuint idx; enum register_file file; + GLint index; + GLubyte negateMask; + GLubyte swizzle[4]; + GLboolean isRelOffset; - if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask)) + /* Grab the sign */ + negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE; + + /* And the src reg */ + if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset)) return 1; + /* finally, the swizzle */ + parse_swizzle_mask(inst, swizzle, 1); + reg->File = file; - reg->Index = idx; - reg->WriteMask = mask; + reg->Index = index; + reg->Swizzle = (swizzle[0] << 0); + reg->NegateBase = negateMask; + reg->RelAddr = isRelOffset; return 0; } /** - * Parse fragment program scalar src register. + * Parse vertex/fragment program destination register. * \return 1 if error, 0 if no error. */ -static GLuint -parse_fp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, - struct arb_program *Program, - struct prog_src_register *reg ) +static GLuint +parse_dst_reg(GLcontext * ctx, const GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *program, + struct prog_dst_register *reg ) { - enum register_file File; - GLint Index; - GLubyte Negate; - GLubyte Swizzle[4]; - GLboolean IsRelOffset; - - /* Grab the sign */ - Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0; + GLint mask; + GLuint idx; + enum register_file file; - /* And the src reg */ - if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) + if (parse_masked_dst_reg (ctx, inst, vc_head, program, &file, &idx, &mask)) return 1; - /* finally, the swizzle */ - parse_swizzle_mask(inst, Swizzle, 1); - - reg->File = File; - reg->Index = Index; - reg->NegateBase = Negate; - reg->Swizzle = (Swizzle[0] << 0); - + reg->File = file; + reg->Index = idx; + reg->WriteMask = mask; return 0; } @@ -2646,6 +2688,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, GLuint texcoord; GLubyte instClass, type, code; GLboolean rel; + GLuint shadow_tex = 0; _mesa_init_instructions(fp, 1); @@ -2707,10 +2750,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, break; } - if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; - if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) + if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) return 1; break; @@ -2760,10 +2803,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, break; } - if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; - if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) + if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) return 1; break; @@ -2776,11 +2819,11 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, break; } - if (parse_fp_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg)) + if (parse_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg)) return 1; for (a = 0; a < 2; a++) { - if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) + if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) return 1; } break; @@ -2861,10 +2904,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, break; } - if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; for (a = 0; a < 2; a++) { - if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) + if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) return 1; } break; @@ -2890,11 +2933,11 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, break; } - if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; for (a = 0; a < 3; a++) { - if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) + if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) return 1; } break; @@ -2907,7 +2950,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, fp->Opcode = OPCODE_SWZ; break; } - if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; { @@ -2950,10 +2993,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, break; } - if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) return 1; - if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) + if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) return 1; /* texImageUnit */ @@ -2963,27 +3006,54 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, /* texTarget */ switch (*(*inst)++) { + case TEXTARGET_SHADOW1D: + shadow_tex = 1 << texcoord; + /* FALLTHROUGH */ case TEXTARGET_1D: fp->TexSrcTarget = TEXTURE_1D_INDEX; break; + case TEXTARGET_SHADOW2D: + shadow_tex = 1 << texcoord; + /* FALLTHROUGH */ case TEXTARGET_2D: fp->TexSrcTarget = TEXTURE_2D_INDEX; break; case TEXTARGET_3D: fp->TexSrcTarget = TEXTURE_3D_INDEX; break; + case TEXTARGET_SHADOWRECT: + shadow_tex = 1 << texcoord; + /* FALLTHROUGH */ case TEXTARGET_RECT: fp->TexSrcTarget = TEXTURE_RECT_INDEX; break; case TEXTARGET_CUBE: fp->TexSrcTarget = TEXTURE_CUBE_INDEX; break; - case TEXTARGET_SHADOW1D: - case TEXTARGET_SHADOW2D: - case TEXTARGET_SHADOWRECT: - /* TODO ARB_fragment_program_shadow code */ - break; + case TEXTARGET_SHADOW1D_ARRAY: + shadow_tex = 1 << texcoord; + /* FALLTHROUGH */ + case TEXTARGET_1D_ARRAY: + fp->TexSrcTarget = TEXTURE_1D_ARRAY_INDEX; + break; + case TEXTARGET_SHADOW2D_ARRAY: + shadow_tex = 1 << texcoord; + /* FALLTHROUGH */ + case TEXTARGET_2D_ARRAY: + fp->TexSrcTarget = TEXTURE_2D_ARRAY_INDEX; + break; } + + /* Don't test the first time a particular sampler is seen. Each time + * after that, make sure the shadow state is the same. + */ + if ((_mesa_bitcount(Program->TexturesUsed[texcoord]) > 0) + && ((Program->ShadowSamplers & (1 << texcoord)) != shadow_tex)) { + program_error(ctx, Program->Position, + "texture image unit used for shadow sampling and non-shadow sampling"); + return 1; + } + Program->TexturesUsed[texcoord] |= (1 << fp->TexSrcTarget); /* Check that both "2D" and "CUBE" (for example) aren't both used */ if (_mesa_bitcount(Program->TexturesUsed[texcoord]) > 1) { @@ -2991,11 +3061,14 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, "multiple targets used on one texture image unit"); return 1; } + + + Program->ShadowSamplers |= shadow_tex; break; case OP_TEX_KIL: Program->UsesKill = 1; - if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) + if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) return 1; fp->Opcode = OPCODE_KIL; break; @@ -3007,23 +3080,6 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, return 0; } -static GLuint -parse_vp_dst_reg(GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, struct arb_program *Program, - struct prog_dst_register *reg ) -{ - GLint mask; - GLuint idx; - enum register_file file; - - if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask)) - return 1; - - reg->File = file; - reg->Index = idx; - reg->WriteMask = mask; - return 0; -} /** * Handle the parsing out of a masked address register @@ -3055,71 +3111,6 @@ parse_vp_address_reg (GLcontext * ctx, const GLubyte ** inst, return 0; } -/** - * Parse vertex program vector source register. - */ -static GLuint -parse_vp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, - struct arb_program *program, - struct prog_src_register *reg ) -{ - enum register_file file; - GLint index; - GLubyte negateMask; - GLubyte swizzle[4]; - GLboolean isRelOffset; - - /* Grab the sign */ - negateMask = (parse_sign (inst) == -1) ? 0xf : 0x0; - - /* And the src reg */ - if (parse_src_reg (ctx, inst, vc_head, program, &file, &index, &isRelOffset)) - return 1; - - /* finally, the swizzle */ - parse_swizzle_mask(inst, swizzle, 4); - - reg->File = file; - reg->Index = index; - reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], - swizzle[2], swizzle[3]); - reg->NegateBase = negateMask; - reg->RelAddr = isRelOffset; - return 0; -} - - -static GLuint -parse_vp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, - struct arb_program *Program, - struct prog_src_register *reg ) -{ - enum register_file File; - GLint Index; - GLubyte Negate; - GLubyte Swizzle[4]; - GLboolean IsRelOffset; - - /* Grab the sign */ - Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0; - - /* And the src reg */ - if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) - return 1; - - /* finally, the swizzle */ - parse_swizzle_mask(inst, Swizzle, 1); - - reg->File = File; - reg->Index = Index; - reg->Swizzle = (Swizzle[0] << 0); - reg->NegateBase = Negate; - reg->RelAddr = IsRelOffset; - return 0; -} - /** * This is a big mother that handles getting opcodes into the instruction @@ -3157,7 +3148,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, vp->DstReg.File = PROGRAM_ADDRESS; /* Get a scalar src register */ - if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) + if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) return 1; break; @@ -3181,10 +3172,10 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, break; } - if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; - if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) + if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) return 1; break; @@ -3209,10 +3200,10 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, vp->Opcode = OPCODE_RSQ; break; } - if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; - if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) + if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) return 1; break; @@ -3222,11 +3213,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, vp->Opcode = OPCODE_POW; break; } - if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; for (a = 0; a < 2; a++) { - if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) + if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) return 1; } break; @@ -3270,11 +3261,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, vp->Opcode = OPCODE_XPD; break; } - if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; for (a = 0; a < 2; a++) { - if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) + if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) return 1; } break; @@ -3286,11 +3277,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, break; } - if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; for (a = 0; a < 3; a++) { - if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) + if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) return 1; } break; @@ -3308,7 +3299,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, enum register_file file; GLint index; - if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &relAddr)) @@ -3330,186 +3321,6 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, #if DEBUG_PARSING -static GLvoid -print_state_token (GLint token) -{ - switch (token) { - case STATE_MATERIAL: - fprintf (stderr, "STATE_MATERIAL "); - break; - case STATE_LIGHT: - fprintf (stderr, "STATE_LIGHT "); - break; - - case STATE_LIGHTMODEL_AMBIENT: - fprintf (stderr, "STATE_AMBIENT "); - break; - - case STATE_LIGHTMODEL_SCENECOLOR: - fprintf (stderr, "STATE_SCENECOLOR "); - break; - - case STATE_LIGHTPROD: - fprintf (stderr, "STATE_LIGHTPROD "); - break; - - case STATE_TEXGEN: - fprintf (stderr, "STATE_TEXGEN "); - break; - - case STATE_FOG_COLOR: - fprintf (stderr, "STATE_FOG_COLOR "); - break; - - case STATE_FOG_PARAMS: - fprintf (stderr, "STATE_FOG_PARAMS "); - break; - - case STATE_CLIPPLANE: - fprintf (stderr, "STATE_CLIPPLANE "); - break; - - case STATE_POINT_SIZE: - fprintf (stderr, "STATE_POINT_SIZE "); - break; - - case STATE_POINT_ATTENUATION: - fprintf (stderr, "STATE_ATTENUATION "); - break; - - case STATE_MATRIX: - fprintf (stderr, "STATE_MATRIX "); - break; - - case STATE_MODELVIEW: - fprintf (stderr, "STATE_MODELVIEW "); - break; - - case STATE_PROJECTION: - fprintf (stderr, "STATE_PROJECTION "); - break; - - case STATE_MVP: - fprintf (stderr, "STATE_MVP "); - break; - - case STATE_TEXTURE: - fprintf (stderr, "STATE_TEXTURE "); - break; - - case STATE_PROGRAM: - fprintf (stderr, "STATE_PROGRAM "); - break; - - case STATE_MATRIX_INVERSE: - fprintf (stderr, "STATE_INVERSE "); - break; - - case STATE_MATRIX_TRANSPOSE: - fprintf (stderr, "STATE_TRANSPOSE "); - break; - - case STATE_MATRIX_INVTRANS: - fprintf (stderr, "STATE_INVTRANS "); - break; - - case STATE_AMBIENT: - fprintf (stderr, "STATE_AMBIENT "); - break; - - case STATE_DIFFUSE: - fprintf (stderr, "STATE_DIFFUSE "); - break; - - case STATE_SPECULAR: - fprintf (stderr, "STATE_SPECULAR "); - break; - - case STATE_EMISSION: - fprintf (stderr, "STATE_EMISSION "); - break; - - case STATE_SHININESS: - fprintf (stderr, "STATE_SHININESS "); - break; - - case STATE_HALF: - fprintf (stderr, "STATE_HALF "); - break; - - case STATE_POSITION: - fprintf (stderr, "STATE_POSITION "); - break; - - case STATE_ATTENUATION: - fprintf (stderr, "STATE_ATTENUATION "); - break; - - case STATE_SPOT_DIRECTION: - fprintf (stderr, "STATE_DIRECTION "); - break; - - case STATE_TEXGEN_EYE_S: - fprintf (stderr, "STATE_TEXGEN_EYE_S "); - break; - - case STATE_TEXGEN_EYE_T: - fprintf (stderr, "STATE_TEXGEN_EYE_T "); - break; - - case STATE_TEXGEN_EYE_R: - fprintf (stderr, "STATE_TEXGEN_EYE_R "); - break; - - case STATE_TEXGEN_EYE_Q: - fprintf (stderr, "STATE_TEXGEN_EYE_Q "); - break; - - case STATE_TEXGEN_OBJECT_S: - fprintf (stderr, "STATE_TEXGEN_EYE_S "); - break; - - case STATE_TEXGEN_OBJECT_T: - fprintf (stderr, "STATE_TEXGEN_OBJECT_T "); - break; - - case STATE_TEXGEN_OBJECT_R: - fprintf (stderr, "STATE_TEXGEN_OBJECT_R "); - break; - - case STATE_TEXGEN_OBJECT_Q: - fprintf (stderr, "STATE_TEXGEN_OBJECT_Q "); - break; - - case STATE_TEXENV_COLOR: - fprintf (stderr, "STATE_TEXENV_COLOR "); - break; - - case STATE_DEPTH_RANGE: - fprintf (stderr, "STATE_DEPTH_RANGE "); - break; - - case STATE_VERTEX_PROGRAM: - fprintf (stderr, "STATE_VERTEX_PROGRAM "); - break; - - case STATE_FRAGMENT_PROGRAM: - fprintf (stderr, "STATE_FRAGMENT_PROGRAM "); - break; - - case STATE_ENV: - fprintf (stderr, "STATE_ENV "); - break; - - case STATE_LOCAL: - fprintf (stderr, "STATE_LOCAL "); - break; - - } - fprintf (stderr, "[%d] ", token); -} - - static GLvoid debug_variables (GLcontext * ctx, struct var_cache *vc_head, struct arb_program *Program) @@ -3517,12 +3328,12 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head, struct var_cache *vc; GLint a, b; - fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head); + fprintf (stderr, "debug_variables, vc_head: %p\n", (void*) vc_head); /* First of all, print out the contents of the var_cache */ vc = vc_head; while (vc) { - fprintf (stderr, "[%x]\n", vc); + fprintf (stderr, "[%p]\n", (void*) vc); switch (vc->type) { case vt_none: fprintf (stderr, "UNDEFINED %s\n", vc->name); @@ -3537,27 +3348,20 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head, b = vc->param_binding_begin; for (a = 0; a < vc->param_binding_length; a++) { fprintf (stderr, "%s\n", - Program->Parameters->Parameters[a + b].Name); - if (Program->Parameters->Parameters[a + b].Type == STATE) { - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[0]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[1]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[2]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[3]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[4]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[5]); + Program->Base.Parameters->Parameters[a + b].Name); + if (Program->Base.Parameters->Parameters[a + b].Type == PROGRAM_STATE_VAR) { + const char *s; + s = _mesa_program_state_string(Program->Base.Parameters->Parameters + [a + b].StateIndexes); + fprintf(stderr, "%s\n", s); + _mesa_free((char *) s); } else fprintf (stderr, "%f %f %f %f\n", - Program->Parameters->Parameters[a + b].Values[0], - Program->Parameters->Parameters[a + b].Values[1], - Program->Parameters->Parameters[a + b].Values[2], - Program->Parameters->Parameters[a + b].Values[3]); + Program->Base.Parameters->ParameterValues[a + b][0], + Program->Base.Parameters->ParameterValues[a + b][1], + Program->Base.Parameters->ParameterValues[a + b][2], + Program->Base.Parameters->ParameterValues[a + b][3]); } break; case vt_temp: @@ -3570,9 +3374,12 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head, break; case vt_alias: fprintf (stderr, "ALIAS %s\n", vc->name); - fprintf (stderr, " binding: 0x%x (%s)\n", - vc->alias_binding, vc->alias_binding->name); + fprintf (stderr, " binding: 0x%p (%s)\n", + (void*) vc->alias_binding, vc->alias_binding->name); break; + default: + /* nothing */ + ; } vc = vc->next; } @@ -3641,6 +3448,10 @@ parse_instructions(GLcontext * ctx, const GLubyte * inst, /* do nothing for now */ } break; + + case MESA_TEXTURE_ARRAY: + /* do nothing for now */ + break; } break; @@ -3705,8 +3516,8 @@ parse_instructions(GLcontext * ctx, const GLubyte * inst, /* XXX temporary */ -__extension__ static char core_grammar_text[] = -#include "grammar_syn.h" +LONGSTRING static char core_grammar_text[] = +#include "shader/grammar/grammar_syn.h" ; @@ -3761,10 +3572,10 @@ enable_parser_extensions(GLcontext *ctx, grammar id) if (ctx->Extensions.ARB_matrix_palette && !enable_ext(ctx, id, "matrix_palette")) return GL_FALSE; +#endif if (ctx->Extensions.ARB_fragment_program_shadow && !enable_ext(ctx, id, "fragment_program_shadow")) return GL_FALSE; -#endif if (ctx->Extensions.EXT_point_parameters && !enable_ext(ctx, id, "point_parameters")) return GL_FALSE; @@ -3780,7 +3591,9 @@ enable_parser_extensions(GLcontext *ctx, grammar id) if (ctx->Extensions.ARB_draw_buffers && !enable_ext(ctx, id, "draw_buffers")) return GL_FALSE; - + if (ctx->Extensions.MESA_texture_array + && !enable_ext(ctx, id, "texture_array")) + return GL_FALSE; #if 1 /* hack for Warcraft (see bug 8060) */ enable_ext(ctx, id, "vertex_blend"); @@ -3920,11 +3733,11 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, int line, col; char *s; fprintf(stderr, "program: %s\n", (char *) strz); - fprintf(stderr, "Error Pos: %d\n", ctx->program.ErrorPos); - s = (char *) _mesa_find_line_column(strz, strz+ctx->program.ErrorPos, + fprintf(stderr, "Error Pos: %d\n", ctx->Program.ErrorPos); + s = (char *) _mesa_find_line_column(strz, strz+ctx->Program.ErrorPos, &line, &col); fprintf(stderr, "line %d col %d: %s\n", line, col, s); - } while (0) + } while (0); #endif _mesa_free(strz); @@ -3959,6 +3772,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, program->HintPositionInvariant = GL_FALSE; for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++) program->TexturesUsed[a] = 0x0; + program->ShadowSamplers = 0x0; program->NumAluInstructions = program->NumTexInstructions = program->NumTexIndirections = 0; @@ -4029,17 +3843,19 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, program->Base.NumNativeParameters = ap.Base.NumNativeParameters; program->Base.NumNativeAttributes = ap.Base.NumNativeAttributes; program->Base.NumNativeAddressRegs = ap.Base.NumNativeAddressRegs; - program->NumAluInstructions = ap.NumAluInstructions; - program->NumTexInstructions = ap.NumTexInstructions; - program->NumTexIndirections = ap.NumTexIndirections; - program->NumNativeAluInstructions = ap.NumAluInstructions; - program->NumNativeTexInstructions = ap.NumTexInstructions; - program->NumNativeTexIndirections = ap.NumTexIndirections; + program->Base.NumAluInstructions = ap.Base.NumAluInstructions; + program->Base.NumTexInstructions = ap.Base.NumTexInstructions; + program->Base.NumTexIndirections = ap.Base.NumTexIndirections; + program->Base.NumNativeAluInstructions = ap.Base.NumAluInstructions; + program->Base.NumNativeTexInstructions = ap.Base.NumTexInstructions; + program->Base.NumNativeTexIndirections = ap.Base.NumTexIndirections; program->Base.InputsRead = ap.Base.InputsRead; program->Base.OutputsWritten = ap.Base.OutputsWritten; for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) - program->TexturesUsed[i] = ap.TexturesUsed[i]; + program->Base.TexturesUsed[i] = ap.TexturesUsed[i]; + program->Base.ShadowSamplers = ap.ShadowSamplers; program->FogOption = ap.FogOption; + program->UsesKill = ap.UsesKill; if (program->Base.Instructions) _mesa_free(program->Base.Instructions); @@ -4072,7 +3888,7 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, ASSERT(target == GL_VERTEX_PROGRAM_ARB); if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, &ap)) { - /* Error in the program. Just return. */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)"); return; } @@ -4103,7 +3919,7 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, program->Base.Parameters = ap.Base.Parameters; #if DEBUG_VP - _mesa_printf("____________Vertex program %u __________\n", program->Base.ID); + _mesa_printf("____________Vertex program %u __________\n", program->Base.Id); _mesa_print_program(&program->Base); #endif }