diff options
Diffstat (limited to 'src/mesa/shader')
38 files changed, 14006 insertions, 8258 deletions
diff --git a/src/mesa/shader/.gitignore b/src/mesa/shader/.gitignore new file mode 100644 index 0000000000..086fd9a705 --- /dev/null +++ b/src/mesa/shader/.gitignore @@ -0,0 +1 @@ +program_parse.output diff --git a/src/mesa/shader/Makefile b/src/mesa/shader/Makefile new file mode 100644 index 0000000000..400a543bda --- /dev/null +++ b/src/mesa/shader/Makefile @@ -0,0 +1,7 @@ +all: program_parse.tab.c lex.yy.c + +program_parse.tab.c program_parse.tab.h: program_parse.y + bison -v -d $< + +lex.yy.c: program_lexer.l + flex --never-interactive $< diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 8607940dc1..05ee4f563e 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -63,3817 +63,7 @@ having three separate program parameter arrays. #include "prog_parameter.h" #include "prog_statevars.h" #include "prog_instruction.h" - -/** - * This is basically a union of the vertex_program and fragment_program - * structs that we can use to parse the program into - * - * XXX we can probably get rid of this entirely someday. - */ -struct arb_program -{ - struct gl_program Base; - - GLuint Position; /* Just used for error reporting while parsing */ - GLuint MajorVersion; - GLuint MinorVersion; - - /* ARB_vertex_progmra options */ - GLboolean HintPositionInvariant; - - /* ARB_fragment_progmra options */ - GLenum PrecisionOption; /* GL_DONT_CARE, GL_NICEST or GL_FASTEST */ - GLenum FogOption; /* GL_NONE, GL_LINEAR, GL_EXP or GL_EXP2 */ - - /* ARB_fragment_program specifics */ - GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; - GLbitfield ShadowSamplers; - GLuint NumAluInstructions; - GLuint NumTexInstructions; - GLuint NumTexIndirections; - - GLboolean UsesKill; -}; - - - -/* TODO: - * Fragment Program Stuff: - * ----------------------------------------------------- - * - * - things from Michal's email - * + overflow on atoi - * + not-overflowing floats (don't use parse_integer..) - * + can remove range checking in arbparse.c - * - * - check all limits of number of various variables - * + parameters - * - * - test! test! test! - * - * Vertex Program Stuff: - * ----------------------------------------------------- - * - Optimize param array usage and count limits correctly, see spec, - * section 2.14.3.7 - * + Record if an array is reference absolutly or relatively (or both) - * + For absolute arrays, store a bitmap of accesses - * + For single parameters, store an access flag - * + After parsing, make a parameter cleanup and merging pass, where - * relative arrays are layed out first, followed by abs arrays, and - * finally single state. - * + Remap offsets for param src and dst registers - * + Now we can properly count parameter usage - * - * - Multiple state binding errors in param arrays (see spec, just before - * section 2.14.3.3) - * - grep for XXX - * - * Mesa Stuff - * ----------------------------------------------------- - * - User clipping planes vs. PositionInvariant - * - Is it sufficient to just multiply by the mvp to transform in the - * PositionInvariant case? Or do we need something more involved? - * - * - vp_src swizzle is GLubyte, fp_src swizzle is GLuint - * - fetch state listed in program_parameters list - * + WTF should this go??? - * + currently in nvvertexec.c and s_nvfragprog.c - * - * - allow for multiple address registers (and fetch address regs properly) - * - * Cosmetic Stuff - * ----------------------------------------------------- - * - remove any leftover unused grammer.c stuff (dict_ ?) - * - fix grammer.c error handling so its not static - * - #ifdef around stuff pertaining to extentions - * - * Outstanding Questions: - * ----------------------------------------------------- - * - ARB_matrix_palette / ARB_vertex_blend -- not supported - * what gets hacked off because of this: - * + VERTEX_ATTRIB_MATRIXINDEX - * + VERTEX_ATTRIB_WEIGHT - * + MATRIX_MODELVIEW - * + MATRIX_PALETTE - * - * - When can we fetch env/local params from their own register files, and - * when to we have to fetch them into the main state register file? - * (think arrays) - * - * Grammar Changes: - * ----------------------------------------------------- - */ - -/* Changes since moving the file to shader directory - -2004-III-4 ------------------------------------------------------------ -- added #include "grammar_mesa.h" -- removed grammar specific code part (it resides now in grammar.c) -- added GL_ARB_fragment_program_shadow tokens -- modified #include "arbparse_syn.h" -- major changes inside _mesa_parse_arb_program() -- check the program string for '\0' characters -- copy the program string to a one-byte-longer location to have - it null-terminated -- position invariance test (not writing to result.position) moved - to syntax part -*/ - -typedef GLubyte *production; - - -/** - * This is the text describing the rules to parse the grammar - */ -LONGSTRING static char arb_grammar_text[] = -#include "arbprogram_syn.h" -; - -/** - * These should match up with the values defined in arbprogram.syn - */ - -/* - Changes: - - changed and merged V_* and F_* opcode values to OP_*. - - added GL_ARB_fragment_program_shadow specific tokens (michal) -*/ -#define REVISION 0x0a - -/* program type */ -#define FRAGMENT_PROGRAM 0x01 -#define VERTEX_PROGRAM 0x02 - -/* program section */ -#define OPTION 0x01 -#define INSTRUCTION 0x02 -#define DECLARATION 0x03 -#define END 0x04 - -/* GL_ARB_fragment_program option */ -#define ARB_PRECISION_HINT_FASTEST 0x00 -#define ARB_PRECISION_HINT_NICEST 0x01 -#define ARB_FOG_EXP 0x02 -#define ARB_FOG_EXP2 0x03 -#define ARB_FOG_LINEAR 0x04 - -/* GL_ARB_vertex_program option */ -#define ARB_POSITION_INVARIANT 0x05 - -/* GL_ARB_fragment_program_shadow option */ -#define ARB_FRAGMENT_PROGRAM_SHADOW 0x06 - -/* 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 - -/* GL_ARB_vertex_program instruction class */ -/* OP_ALU_INST */ - -/* GL_ARB_fragment_program instruction type */ -#define OP_ALU_VECTOR 0x00 -#define OP_ALU_SCALAR 0x01 -#define OP_ALU_BINSC 0x02 -#define OP_ALU_BIN 0x03 -#define OP_ALU_TRI 0x04 -#define OP_ALU_SWZ 0x05 -#define OP_TEX_SAMPLE 0x06 -#define OP_TEX_KIL 0x07 - -/* GL_ARB_vertex_program instruction type */ -#define OP_ALU_ARL 0x08 -/* OP_ALU_VECTOR */ -/* OP_ALU_SCALAR */ -/* OP_ALU_BINSC */ -/* OP_ALU_BIN */ -/* OP_ALU_TRI */ -/* OP_ALU_SWZ */ - -/* GL_ARB_fragment_program instruction code */ -#define OP_ABS 0x00 -#define OP_ABS_SAT 0x1B -#define OP_FLR 0x09 -#define OP_FLR_SAT 0x26 -#define OP_FRC 0x0A -#define OP_FRC_SAT 0x27 -#define OP_LIT 0x0C -#define OP_LIT_SAT 0x2A -#define OP_MOV 0x11 -#define OP_MOV_SAT 0x30 -#define OP_COS 0x1F -#define OP_COS_SAT 0x20 -#define OP_EX2 0x07 -#define OP_EX2_SAT 0x25 -#define OP_LG2 0x0B -#define OP_LG2_SAT 0x29 -#define OP_RCP 0x14 -#define OP_RCP_SAT 0x33 -#define OP_RSQ 0x15 -#define OP_RSQ_SAT 0x34 -#define OP_SIN 0x38 -#define OP_SIN_SAT 0x39 -#define OP_SCS 0x35 -#define OP_SCS_SAT 0x36 -#define OP_POW 0x13 -#define OP_POW_SAT 0x32 -#define OP_ADD 0x01 -#define OP_ADD_SAT 0x1C -#define OP_DP3 0x03 -#define OP_DP3_SAT 0x21 -#define OP_DP4 0x04 -#define OP_DP4_SAT 0x22 -#define OP_DPH 0x05 -#define OP_DPH_SAT 0x23 -#define OP_DST 0x06 -#define OP_DST_SAT 0x24 -#define OP_MAX 0x0F -#define OP_MAX_SAT 0x2E -#define OP_MIN 0x10 -#define OP_MIN_SAT 0x2F -#define OP_MUL 0x12 -#define OP_MUL_SAT 0x31 -#define OP_SGE 0x16 -#define OP_SGE_SAT 0x37 -#define OP_SLT 0x17 -#define OP_SLT_SAT 0x3A -#define OP_SUB 0x18 -#define OP_SUB_SAT 0x3B -#define OP_XPD 0x1A -#define OP_XPD_SAT 0x43 -#define OP_CMP 0x1D -#define OP_CMP_SAT 0x1E -#define OP_LRP 0x2B -#define OP_LRP_SAT 0x2C -#define OP_MAD 0x0E -#define OP_MAD_SAT 0x2D -#define OP_SWZ 0x19 -#define OP_SWZ_SAT 0x3C -#define OP_TEX 0x3D -#define OP_TEX_SAT 0x3E -#define OP_TXB 0x3F -#define OP_TXB_SAT 0x40 -#define OP_TXP 0x41 -#define OP_TXP_SAT 0x42 -#define OP_KIL 0x28 - -/* GL_ARB_vertex_program instruction code */ -#define OP_ARL 0x02 -/* OP_ABS */ -/* OP_FLR */ -/* OP_FRC */ -/* OP_LIT */ -/* OP_MOV */ -/* OP_EX2 */ -#define OP_EXP 0x08 -/* OP_LG2 */ -#define OP_LOG 0x0D -/* OP_RCP */ -/* OP_RSQ */ -/* OP_POW */ -/* OP_ADD */ -/* OP_DP3 */ -/* OP_DP4 */ -/* OP_DPH */ -/* OP_DST */ -/* OP_MAX */ -/* OP_MIN */ -/* OP_MUL */ -/* OP_SGE */ -/* OP_SLT */ -/* OP_SUB */ -/* OP_XPD */ -/* OP_MAD */ -/* OP_SWZ */ - -/* fragment attribute binding */ -#define FRAGMENT_ATTRIB_COLOR 0x01 -#define FRAGMENT_ATTRIB_TEXCOORD 0x02 -#define FRAGMENT_ATTRIB_FOGCOORD 0x03 -#define FRAGMENT_ATTRIB_POSITION 0x04 - -/* vertex attribute binding */ -#define VERTEX_ATTRIB_POSITION 0x01 -#define VERTEX_ATTRIB_WEIGHT 0x02 -#define VERTEX_ATTRIB_NORMAL 0x03 -#define VERTEX_ATTRIB_COLOR 0x04 -#define VERTEX_ATTRIB_FOGCOORD 0x05 -#define VERTEX_ATTRIB_TEXCOORD 0x06 -#define VERTEX_ATTRIB_MATRIXINDEX 0x07 -#define VERTEX_ATTRIB_GENERIC 0x08 - -/* fragment result binding */ -#define FRAGMENT_RESULT_COLOR 0x01 -#define FRAGMENT_RESULT_DEPTH 0x02 - -/* vertex result binding */ -#define VERTEX_RESULT_POSITION 0x01 -#define VERTEX_RESULT_COLOR 0x02 -#define VERTEX_RESULT_FOGCOORD 0x03 -#define VERTEX_RESULT_POINTSIZE 0x04 -#define VERTEX_RESULT_TEXCOORD 0x05 - -/* texture target */ -#define TEXTARGET_1D 0x01 -#define TEXTARGET_2D 0x02 -#define TEXTARGET_3D 0x03 -#define TEXTARGET_RECT 0x04 -#define TEXTARGET_CUBE 0x05 -/* GL_ARB_fragment_program_shadow */ -#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 -#define FACE_BACK 0x01 - -/* color type */ -#define COLOR_PRIMARY 0x00 -#define COLOR_SECONDARY 0x01 - -/* component */ -#define COMPONENT_X 0x00 -#define COMPONENT_Y 0x01 -#define COMPONENT_Z 0x02 -#define COMPONENT_W 0x03 -#define COMPONENT_0 0x04 -#define COMPONENT_1 0x05 - -/* array index type */ -#define ARRAY_INDEX_ABSOLUTE 0x00 -#define ARRAY_INDEX_RELATIVE 0x01 - -/* matrix name */ -#define MATRIX_MODELVIEW 0x01 -#define MATRIX_PROJECTION 0x02 -#define MATRIX_MVP 0x03 -#define MATRIX_TEXTURE 0x04 -#define MATRIX_PALETTE 0x05 -#define MATRIX_PROGRAM 0x06 - -/* matrix modifier */ -#define MATRIX_MODIFIER_IDENTITY 0x00 -#define MATRIX_MODIFIER_INVERSE 0x01 -#define MATRIX_MODIFIER_TRANSPOSE 0x02 -#define MATRIX_MODIFIER_INVTRANS 0x03 - -/* constant type */ -#define CONSTANT_SCALAR 0x01 -#define CONSTANT_VECTOR 0x02 - -/* program param type */ -#define PROGRAM_PARAM_ENV 0x01 -#define PROGRAM_PARAM_LOCAL 0x02 - -/* register type */ -#define REGISTER_ATTRIB 0x01 -#define REGISTER_PARAM 0x02 -#define REGISTER_RESULT 0x03 -#define REGISTER_ESTABLISHED_NAME 0x04 - -/* param binding */ -#define PARAM_NULL 0x00 -#define PARAM_ARRAY_ELEMENT 0x01 -#define PARAM_STATE_ELEMENT 0x02 -#define PARAM_PROGRAM_ELEMENT 0x03 -#define PARAM_PROGRAM_ELEMENTS 0x04 -#define PARAM_CONSTANT 0x05 - -/* param state property */ -#define STATE_MATERIAL_PARSER 0x01 -#define STATE_LIGHT_PARSER 0x02 -#define STATE_LIGHT_MODEL 0x03 -#define STATE_LIGHT_PROD 0x04 -#define STATE_FOG 0x05 -#define STATE_MATRIX_ROWS 0x06 -/* GL_ARB_fragment_program */ -#define STATE_TEX_ENV 0x07 -#define STATE_DEPTH 0x08 -/* GL_ARB_vertex_program */ -#define STATE_TEX_GEN 0x09 -#define STATE_CLIP_PLANE 0x0A -#define STATE_POINT 0x0B - -/* state material property */ -#define MATERIAL_AMBIENT 0x01 -#define MATERIAL_DIFFUSE 0x02 -#define MATERIAL_SPECULAR 0x03 -#define MATERIAL_EMISSION 0x04 -#define MATERIAL_SHININESS 0x05 - -/* state light property */ -#define LIGHT_AMBIENT 0x01 -#define LIGHT_DIFFUSE 0x02 -#define LIGHT_SPECULAR 0x03 -#define LIGHT_POSITION 0x04 -#define LIGHT_ATTENUATION 0x05 -#define LIGHT_HALF 0x06 -#define LIGHT_SPOT_DIRECTION 0x07 - -/* state light model property */ -#define LIGHT_MODEL_AMBIENT 0x01 -#define LIGHT_MODEL_SCENECOLOR 0x02 - -/* state light product property */ -#define LIGHT_PROD_AMBIENT 0x01 -#define LIGHT_PROD_DIFFUSE 0x02 -#define LIGHT_PROD_SPECULAR 0x03 - -/* state texture environment property */ -#define TEX_ENV_COLOR 0x01 - -/* state texture generation coord property */ -#define TEX_GEN_EYE 0x01 -#define TEX_GEN_OBJECT 0x02 - -/* state fog property */ -#define FOG_COLOR 0x01 -#define FOG_PARAMS 0x02 - -/* state depth property */ -#define DEPTH_RANGE 0x01 - -/* state point parameters property */ -#define POINT_SIZE 0x01 -#define POINT_ATTENUATION 0x02 - -/* declaration */ -#define ATTRIB 0x01 -#define PARAM 0x02 -#define TEMP 0x03 -#define OUTPUT 0x04 -#define ALIAS 0x05 -/* GL_ARB_vertex_program */ -#define ADDRESS 0x06 - -/*----------------------------------------------------------------------- - * From here on down is the semantic checking portion - * - */ - -/** - * Variable Table Handling functions - */ -typedef enum -{ - vt_none, - vt_address, - vt_attrib, - vt_param, - vt_temp, - vt_output, - vt_alias -} 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.. - */ -struct var_cache -{ - const GLubyte *name; /* don't free() - no need */ - var_type type; - GLuint address_binding; /* The index of the address register we should - * be using */ - GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */ - 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; /* 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, - * PROGRAM_ENV_PARAM} */ - GLuint param_binding_begin; /* This is the offset into the program_parameter_list where - * the tokens representing our bound state (or constants) - * start */ - GLuint param_binding_length; /* This is how many entries in the the program_parameter_list - * we take up with our state tokens or constants. Note that - * this is _not_ the same as the number of param registers - * we eventually use */ - struct var_cache *next; -}; - -static GLvoid -var_cache_create (struct var_cache **va) -{ - *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache)); - if (*va) { - (**va).name = NULL; - (**va).type = vt_none; - (**va).attrib_binding = ~0; - (**va).attrib_is_generic = 0; - (**va).temp_binding = ~0; - (**va).output_binding = ~0; - (**va).param_binding_type = ~0; - (**va).param_binding_begin = ~0; - (**va).param_binding_length = ~0; - (**va).alias_binding = NULL; - (**va).next = NULL; - } -} - -static GLvoid -var_cache_destroy (struct var_cache **va) -{ - if (*va) { - var_cache_destroy (&(**va).next); - _mesa_free (*va); - *va = NULL; - } -} - -static GLvoid -var_cache_append (struct var_cache **va, struct var_cache *nv) -{ - if (*va) - var_cache_append (&(**va).next, nv); - else - *va = nv; -} - -static struct var_cache * -var_cache_find (struct var_cache *va, const GLubyte * name) -{ - /*struct var_cache *first = va;*/ - - while (va) { - if (!_mesa_strcmp ( (const char*) name, (const char*) va->name)) { - if (va->type == vt_alias) - return va->alias_binding; - return va; - } - - va = va->next; - } - - return NULL; -} - - - -/** - * Called when an error is detected while parsing/compiling a program. - * Sets the ctx->Program.ErrorString field to descript and records a - * GL_INVALID_OPERATION error. - * \param position position of error in program string - * \param descrip verbose error description - */ -static void -program_error(GLcontext *ctx, GLint position, const char *descrip) -{ - if (descrip) { - const char *prefix = "glProgramString(", *suffix = ")"; - char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + - _mesa_strlen(prefix) + - _mesa_strlen(suffix) + 1); - if (str) { - _mesa_sprintf(str, "%s%s%s", prefix, descrip, suffix); - _mesa_error(ctx, GL_INVALID_OPERATION, str); - _mesa_free(str); - } - } - _mesa_set_program_error(ctx, position, 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 - */ -static GLuint -parse_position (const GLubyte ** inst) -{ - GLuint value; - - value = (GLuint) (*(*inst)++); - value += (GLuint) (*(*inst)++) * 0x100; - value += (GLuint) (*(*inst)++) * 0x10000; - value += (GLuint) (*(*inst)++) * 0x1000000; - - return value; -} - -/** - * This will, given a string, lookup the string as a variable name in the - * var cache. If the name is found, the var cache node corresponding to the - * var name is returned. If it is not found, a new entry is allocated - * - * \param I Points into the binary array where the string identifier begins - * \param found 1 if the string was found in the var_cache, 0 if it was allocated - * \return The location on the var_cache corresponding the the string starting at I - */ -static struct var_cache * -parse_string (const GLubyte ** inst, struct var_cache **vc_head, - struct arb_program *Program, GLuint * found) -{ - const GLubyte *i = *inst; - struct var_cache *va = NULL; - (void) Program; - - *inst += _mesa_strlen ((char *) i) + 1; - - va = var_cache_find (*vc_head, i); - - if (va) { - *found = 1; - return va; - } - - *found = 0; - var_cache_create (&va); - va->name = (const GLubyte *) i; - - var_cache_append (vc_head, va); - - return va; -} - -static char * -parse_string_without_adding (const GLubyte ** inst, struct arb_program *Program) -{ - const GLubyte *i = *inst; - (void) Program; - - *inst += _mesa_strlen ((char *) i) + 1; - - return (char *) i; -} - -/** - * \return -1 if we parse '-', return 1 otherwise - */ -static GLint -parse_sign (const GLubyte ** inst) -{ - /*return *(*inst)++ != '+'; */ - - if (**inst == '-') { - (*inst)++; - return -1; - } - else if (**inst == '+') { - (*inst)++; - return 1; - } - - return 1; -} - -/** - * parses and returns signed integer - */ -static GLint -parse_integer (const GLubyte ** inst, struct arb_program *Program) -{ - GLint sign; - GLint value; - - /* check if *inst points to '+' or '-' - * if yes, grab the sign and increment *inst - */ - sign = parse_sign (inst); - - /* now check if *inst points to 0 - * if yes, increment the *inst and return the default value - */ - if (**inst == 0) { - (*inst)++; - return 0; - } - - /* parse the integer as you normally would do it */ - value = _mesa_atoi (parse_string_without_adding (inst, Program)); - - /* now, after terminating 0 there is a position - * to parse it - parse_position() - */ - Program->Position = parse_position (inst); - - return value * sign; -} - -/** - Accumulate this string of digits, and return them as - a large integer represented in floating point (for range). - If scale is not NULL, also accumulates a power-of-ten - integer scale factor that represents the number of digits - in the string. -*/ -static GLdouble -parse_float_string(const GLubyte ** inst, struct arb_program *Program, GLdouble *scale) -{ - GLdouble value = 0.0; - GLdouble oscale = 1.0; - - if (**inst == 0) { /* this string of digits is empty-- do nothing */ - (*inst)++; - } - else { /* nonempty string-- parse out the digits */ - while (**inst >= '0' && **inst <= '9') { - GLubyte digit = *((*inst)++); - value = value * 10.0 + (GLint) (digit - '0'); - oscale *= 10.0; - } - assert(**inst == 0); /* integer string should end with 0 */ - (*inst)++; /* skip over terminating 0 */ - Program->Position = parse_position(inst); /* skip position (from integer) */ - } - if (scale) - *scale = oscale; - return value; -} - -/** - Parse an unsigned floating-point number from this stream of tokenized - characters. Example floating-point formats supported: - 12.34 - 12 - 0.34 - .34 - 12.34e-4 - */ -static GLfloat -parse_float (const GLubyte ** inst, struct arb_program *Program) -{ - GLint exponent; - GLdouble whole, fraction, fracScale = 1.0; - - whole = parse_float_string(inst, Program, 0); - fraction = parse_float_string(inst, Program, &fracScale); - - /* Parse signed exponent */ - exponent = parse_integer(inst, Program); /* This is the exponent */ - - /* Assemble parts of floating-point number: */ - return (GLfloat) ((whole + fraction / fracScale) * - _mesa_pow(10.0, (GLfloat) exponent)); -} - - -/** - */ -static GLfloat -parse_signed_float (const GLubyte ** inst, struct arb_program *Program) -{ - GLint sign = parse_sign (inst); - GLfloat value = parse_float (inst, Program); - return value * sign; -} - -/** - * This picks out a constant value from the parsed array. The constant vector is r - * returned in the *values array, which should be of length 4. - * - * \param values - The 4 component vector with the constant value in it - */ -static GLvoid -parse_constant (const GLubyte ** inst, GLfloat *values, struct arb_program *Program, - GLboolean use) -{ - GLuint components, i; - - - switch (*(*inst)++) { - case CONSTANT_SCALAR: - if (use == GL_TRUE) { - values[0] = - values[1] = - values[2] = values[3] = parse_float (inst, Program); - } - else { - values[0] = - values[1] = - values[2] = values[3] = parse_signed_float (inst, Program); - } - - break; - case CONSTANT_VECTOR: - values[0] = values[1] = values[2] = 0; - values[3] = 1; - components = *(*inst)++; - for (i = 0; i < components; i++) { - values[i] = parse_signed_float (inst, Program); - } - break; - } -} - -/** - * \param offset The offset from the address register that we should - * address - * - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_relative_offset(GLcontext *ctx, const GLubyte **inst, - struct arb_program *Program, GLint *offset) -{ - (void) ctx; - *offset = parse_integer(inst, Program); - return 0; -} - -/** - * \param color 0 if color type is primary, 1 if color type is secondary - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_color_type (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, - GLint * color) -{ - (void) ctx; (void) Program; - *color = *(*inst)++ != COLOR_PRIMARY; - return 0; -} - -/** - * Get an integer corresponding to a generic vertex attribute. - * - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_generic_attrib_num(GLcontext *ctx, const GLubyte ** inst, - struct arb_program *Program, GLuint *attrib) -{ - GLint i = parse_integer(inst, Program); - - if ((i < 0) || (i >= MAX_VERTEX_PROGRAM_ATTRIBS)) - { - program_error(ctx, Program->Position, - "Invalid generic vertex attribute index"); - return 1; - } - - *attrib = (GLuint) i; - - return 0; -} - - -/** - * \param color The index of the color buffer to write into - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_output_color_num (GLcontext * ctx, const GLubyte ** inst, - struct arb_program *Program, GLuint * color) -{ - GLint i = parse_integer (inst, Program); - - if ((i < 0) || (i >= (int)ctx->Const.MaxDrawBuffers)) { - *color = 0; - program_error(ctx, Program->Position, "Invalid draw buffer index"); - return 1; - } - - *color = (GLuint) i; - return 0; -} - - -/** - * Validate the index of a texture coordinate - * - * \param coord The texture unit index - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_texcoord_num (GLcontext * ctx, const GLubyte ** inst, - struct arb_program *Program, GLuint * coord) -{ - GLint i = parse_integer (inst, Program); - - if ((i < 0) || (i >= (int)ctx->Const.MaxTextureCoordUnits)) { - program_error(ctx, Program->Position, "Invalid texture coordinate index"); - return 1; - } - - *coord = (GLuint) i; - return 0; -} - - -/** - * Validate the index of a texture image unit - * - * \param coord The texture unit index - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_teximage_num (GLcontext * ctx, const GLubyte ** inst, - struct arb_program *Program, GLuint * coord) -{ - GLint i = parse_integer (inst, Program); - - if ((i < 0) || (i >= (int)ctx->Const.MaxTextureImageUnits)) { - char s[100]; - _mesa_snprintf(s, sizeof(s), "Invalid texture image index %d (%u is max)", - i, ctx->Const.MaxTextureImageUnits); - program_error(ctx, Program->Position, s); - return 1; - } - - *coord = (GLuint) i; - return 0; -} - - -/** - * \param coord The weight index - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_weight_num (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, - GLint * coord) -{ - *coord = parse_integer (inst, Program); - - if ((*coord < 0) || (*coord >= 1)) { - program_error(ctx, Program->Position, "Invalid weight index"); - return 1; - } - - return 0; -} - -/** - * \param coord The clip plane index - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_clipplane_num (GLcontext * ctx, const GLubyte ** inst, - struct arb_program *Program, GLint * coord) -{ - *coord = parse_integer (inst, Program); - - if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) { - program_error(ctx, Program->Position, "Invalid clip plane index"); - return 1; - } - - return 0; -} - - -/** - * \return 0 on front face, 1 on back face - */ -static GLuint -parse_face_type (const GLubyte ** inst) -{ - switch (*(*inst)++) { - case FACE_FRONT: - return 0; - - case FACE_BACK: - return 1; - } - return 0; -} - - -/** - * Given a matrix and a modifier token on the binary array, return tokens - * that _mesa_fetch_state() [program.c] can understand. - * - * \param matrix - the matrix we are talking about - * \param matrix_idx - the index of the matrix we have (for texture & program matricies) - * \param matrix_modifier - the matrix modifier (trans, inv, etc) - * \return 0 on sucess, 1 on failure - */ -static GLuint -parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, - GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier) -{ - GLubyte mat = *(*inst)++; - - *matrix_idx = 0; - - switch (mat) { - case MATRIX_MODELVIEW: - *matrix = STATE_MODELVIEW_MATRIX; - *matrix_idx = parse_integer (inst, Program); - if (*matrix_idx > 0) { - program_error(ctx, Program->Position, - "ARB_vertex_blend not supported"); - return 1; - } - break; - - case MATRIX_PROJECTION: - *matrix = STATE_PROJECTION_MATRIX; - break; - - case MATRIX_MVP: - *matrix = STATE_MVP_MATRIX; - break; - - case MATRIX_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"); - /* bad *matrix_id */ - return 1; - } - break; - - /* This is not currently supported (ARB_matrix_palette) */ - case MATRIX_PALETTE: - *matrix_idx = parse_integer (inst, Program); - program_error(ctx, Program->Position, - "ARB_matrix_palette not supported"); - return 1; - break; - - case MATRIX_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"); - /* bad *matrix_idx */ - return 1; - } - break; - } - - switch (*(*inst)++) { - case MATRIX_MODIFIER_IDENTITY: - *matrix_modifier = 0; - break; - case MATRIX_MODIFIER_INVERSE: - *matrix_modifier = STATE_MATRIX_INVERSE; - break; - case MATRIX_MODIFIER_TRANSPOSE: - *matrix_modifier = STATE_MATRIX_TRANSPOSE; - break; - case MATRIX_MODIFIER_INVTRANS: - *matrix_modifier = STATE_MATRIX_INVTRANS; - break; - } - - return 0; -} - - -/** - * This parses a state string (rather, the binary version of it) into - * a 6-token sequence as described in _mesa_fetch_state() [program.c] - * - * \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 error - */ -static GLuint -parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, - struct arb_program *Program, - gl_state_index state_tokens[STATE_LENGTH]) -{ - GLubyte token = *(*inst)++; - - switch (token) { - case STATE_MATERIAL_PARSER: - state_tokens[0] = STATE_MATERIAL; - state_tokens[1] = parse_face_type (inst); - switch (*(*inst)++) { - case MATERIAL_AMBIENT: - state_tokens[2] = STATE_AMBIENT; - break; - case MATERIAL_DIFFUSE: - state_tokens[2] = STATE_DIFFUSE; - break; - case MATERIAL_SPECULAR: - state_tokens[2] = STATE_SPECULAR; - break; - case MATERIAL_EMISSION: - state_tokens[2] = STATE_EMISSION; - break; - case MATERIAL_SHININESS: - state_tokens[2] = STATE_SHININESS; - break; - } - break; - - case STATE_LIGHT_PARSER: - state_tokens[0] = STATE_LIGHT; - state_tokens[1] = parse_integer (inst, Program); - - /* Check the value of state_tokens[1] against the # of lights */ - if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) { - program_error(ctx, Program->Position, "Invalid Light Number"); - /* bad state_tokens[1] */ - return 1; - } - - switch (*(*inst)++) { - case LIGHT_AMBIENT: - state_tokens[2] = STATE_AMBIENT; - break; - case LIGHT_DIFFUSE: - state_tokens[2] = STATE_DIFFUSE; - break; - case LIGHT_SPECULAR: - state_tokens[2] = STATE_SPECULAR; - break; - case LIGHT_POSITION: - state_tokens[2] = STATE_POSITION; - break; - case LIGHT_ATTENUATION: - state_tokens[2] = STATE_ATTENUATION; - break; - case LIGHT_HALF: - state_tokens[2] = STATE_HALF_VECTOR; - break; - case LIGHT_SPOT_DIRECTION: - state_tokens[2] = STATE_SPOT_DIRECTION; - break; - } - break; - - case STATE_LIGHT_MODEL: - switch (*(*inst)++) { - case LIGHT_MODEL_AMBIENT: - state_tokens[0] = STATE_LIGHTMODEL_AMBIENT; - break; - case LIGHT_MODEL_SCENECOLOR: - state_tokens[0] = STATE_LIGHTMODEL_SCENECOLOR; - state_tokens[1] = parse_face_type (inst); - break; - } - break; - - case STATE_LIGHT_PROD: - state_tokens[0] = STATE_LIGHTPROD; - state_tokens[1] = parse_integer (inst, Program); - - /* Check the value of state_tokens[1] against the # of lights */ - if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) { - program_error(ctx, Program->Position, "Invalid Light Number"); - /* bad state_tokens[1] */ - return 1; - } - - state_tokens[2] = parse_face_type (inst); - switch (*(*inst)++) { - case LIGHT_PROD_AMBIENT: - state_tokens[3] = STATE_AMBIENT; - break; - case LIGHT_PROD_DIFFUSE: - state_tokens[3] = STATE_DIFFUSE; - break; - case LIGHT_PROD_SPECULAR: - state_tokens[3] = STATE_SPECULAR; - break; - } - break; - - - case STATE_FOG: - switch (*(*inst)++) { - case FOG_COLOR: - state_tokens[0] = STATE_FOG_COLOR; - break; - case FOG_PARAMS: - state_tokens[0] = STATE_FOG_PARAMS; - break; - } - break; - - case STATE_TEX_ENV: - state_tokens[1] = parse_integer (inst, Program); - switch (*(*inst)++) { - case TEX_ENV_COLOR: - state_tokens[0] = STATE_TEXENV_COLOR; - break; - } - break; - - case STATE_TEX_GEN: - { - 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; - default: - _mesa_problem(ctx, "bad texgen component in " - "parse_state_single_item()"); - } - } - 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; - default: - _mesa_problem(ctx, "bad texgen component in " - "parse_state_single_item()"); - } - } - } - 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; - if (parse_clipplane_num (ctx, inst, Program, - (GLint *) &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: - if (parse_matrix(ctx, inst, Program, - (GLint *) &state_tokens[0], - (GLint *) &state_tokens[1], - (GLint *) &state_tokens[4])) - return 1; - - state_tokens[2] = parse_integer (inst, Program); /* The first row to grab */ - - if ((**inst) != 0) { /* Either the last row, 0 */ - 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] */ - return 1; - } - } - else { - state_tokens[3] = state_tokens[2]; - (*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 GLuint -parse_program_single_item (GLcontext * ctx, const GLubyte ** inst, - 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; - 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))) { - program_error(ctx, Program->Position, - "Invalid Program Env Parameter"); - /* bad 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))) { - program_error(ctx, Program->Position, - "Invalid Program Local Parameter"); - /* bad 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 GLuint -generic_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) { - GLuint attr = (curr->attrib_binding == 0) - ? 0 : (curr->attrib_binding - VERT_ATTRIB_GENERIC0); - assert(attr < MAX_VERTEX_PROGRAM_ATTRIBS); - genericAttrib[attr] = GL_TRUE; - } - else { - assert(curr->attrib_binding < MAX_VERTEX_PROGRAM_ATTRIBS); - 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 success, 1 on error - */ -static GLuint -parse_attrib_binding(GLcontext * ctx, const 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 = 0; - 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: - { - GLint weight; - err = parse_weight_num (ctx, inst, Program, &weight); - *inputReg = VERT_ATTRIB_WEIGHT; -#if 1 - /* hack for Warcraft (see bug 8060) */ - _mesa_warning(ctx, "Application error: vertex program uses 'vertex.weight' but GL_ARB_vertex_blend not supported."); - break; -#else - program_error(ctx, Program->Position, - "ARB_vertex_blend not supported"); - return 1; -#endif - } - - 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 = 0; - 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); - program_error(ctx, Program->Position, msg); - } - return 1; - - case VERTEX_ATTRIB_GENERIC: - { - GLuint attrib; - err = parse_generic_attrib_num(ctx, inst, Program, &attrib); - if (!err) { - *is_generic = 1; - /* Add VERT_ATTRIB_GENERIC0 here because ARB_vertex_program's - * attributes do not alias the conventional vertex - * attributes. - */ - if (attrib > 0) - *inputReg = attrib + VERT_ATTRIB_GENERIC0; - else - *inputReg = 0; - } - } - break; - - default: - err = 1; - break; - } - } - - 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 GLuint -parse_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_COLOR; - } - 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_DEPTH; - } - 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 GLint -parse_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 GLuint -parse_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++; - } - } - 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++; - } - 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++; - - /* 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++; - } - } - 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_STATE_VAR; - /* Note: when we reference this parameter in an instruction later, - * we'll check if it's really a constant/immediate and set the - * instruction register type appropriately. - */ - param_var->param_binding_length++; - break; - - default: - program_error(ctx, Program->Position, - "Unexpected token (in parse_param_elements())"); - return 1; - } - - Program->Base.NumParameters = Program->Base.Parameters->NumParameters; - - /* 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 GLuint -parse_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"); - return 1; - } - } - - (*inst)++; - - return 0; -} - -/** - * - */ -static GLuint -parse_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 (¶m_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 GLuint -parse_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", - (char *) temp_var->name); - return 1; - } - - temp_var->type = vt_temp; - - if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && - (Program->Base.NumTemporaries >= - ctx->Const.FragmentProgram.MaxTemps)) - || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) - && (Program->Base.NumTemporaries >= - ctx->Const.VertexProgram.MaxTemps))) { - program_error(ctx, Program->Position, - "Too many TEMP variables declared"); - return 1; - } - - temp_var->temp_binding = Program->Base.NumTemporaries; - Program->Base.NumTemporaries++; - } - (*inst)++; - - return 0; -} - -/** - * This handles variables of the OUTPUT variety - * - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_output (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, - struct arb_program *Program) -{ - 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) { - program_error2(ctx, Program->Position, - "Duplicate variable declaration", - (char *) output_var->name); - return 1; - } - - output_var->type = vt_output; - - err = parse_result_binding(ctx, inst, &output_var->output_binding, Program); - return err; -} - -/** - * This handles variables of the ALIAS kind - * - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, - struct arb_program *Program) -{ - GLuint found; - struct var_cache *temp_var; - - temp_var = parse_string (inst, vc_head, Program, &found); - Program->Position = parse_position (inst); - - if (found) { - program_error2(ctx, Program->Position, - "Duplicate variable declaration", - (char *) temp_var->name); - return 1; - } - - temp_var->type = vt_alias; - temp_var->alias_binding = parse_string (inst, vc_head, Program, &found); - Program->Position = parse_position (inst); - - if (!found) - { - program_error2(ctx, Program->Position, - "Undefined alias value", - (char *) temp_var->alias_binding->name); - return 1; - } - - return 0; -} - -/** - * This handles variables of the ADDRESS kind - * - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_address (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", - (char *) temp_var->name); - return 1; - } - - temp_var->type = vt_address; - - if (Program->Base.NumAddressRegs >= - ctx->Const.VertexProgram.MaxAddressRegs) { - const char *msg = "Too many ADDRESS variables declared"; - program_error(ctx, Program->Position, msg); - return 1; - } - - temp_var->address_binding = Program->Base.NumAddressRegs; - Program->Base.NumAddressRegs++; - } - (*inst)++; - - return 0; -} - -/** - * Parse a program declaration - * - * \return 0 on sucess, 1 on error - */ -static GLint -parse_declaration (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, - struct arb_program *Program) -{ - GLint err = 0; - - switch (*(*inst)++) { - case ADDRESS: - err = parse_address (ctx, inst, vc_head, Program); - break; - - case ALIAS: - err = parse_alias (ctx, inst, vc_head, Program); - break; - - case ATTRIB: - err = parse_attrib (ctx, inst, vc_head, Program); - break; - - case OUTPUT: - err = parse_output (ctx, inst, vc_head, Program); - break; - - case PARAM: - err = parse_param (ctx, inst, vc_head, Program); - break; - - case TEMP: - err = parse_temp (ctx, inst, vc_head, Program); - break; - } - - return err; -} - -/** - * 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 if we have specified that the program is - * position invariant - * - * \param File - The register file we write to - * \param Index - The register index we write to - * \param WriteMask - The mask controlling which components we write (1->write) - * - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_masked_dst_reg (GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, struct arb_program *Program, - gl_register_file *File, GLuint *Index, GLint *WriteMask) -{ - GLuint tmp, result; - struct var_cache *dst; - - /* We either have a result register specified, or a - * variable that may or may not be writable - */ - switch (*(*inst)++) { - case REGISTER_RESULT: - if (parse_result_binding(ctx, inst, Index, Program)) - return 1; - *File = PROGRAM_OUTPUT; - break; - - case REGISTER_ESTABLISHED_NAME: - dst = parse_string (inst, vc_head, Program, &result); - Program->Position = parse_position (inst); - - /* If the name has never been added to our symbol table, we're hosed */ - if (!result) { - program_error(ctx, Program->Position, "0: Undefined variable"); - return 1; - } - - switch (dst->type) { - case vt_output: - *File = PROGRAM_OUTPUT; - *Index = dst->output_binding; - break; - - case vt_temp: - *File = PROGRAM_TEMPORARY; - *Index = dst->temp_binding; - break; - - /* If the var type is not vt_output or vt_temp, no go */ - default: - program_error(ctx, Program->Position, - "Destination register is read only"); - return 1; - } - break; - - default: - program_error(ctx, Program->Position, - "Unexpected opcode in parse_masked_dst_reg()"); - return 1; - } - - - /* Position invariance test */ - /* This test is done now in syntax portion - when position invariance OPTION - is specified, "result.position" rule is disabled so there is no way - to write the position - */ - /*if ((Program->HintPositionInvariant) && (*File == PROGRAM_OUTPUT) && - (*Index == 0)) { - program_error(ctx, Program->Position, - "Vertex program specified position invariance and wrote vertex position"); - }*/ - - /* And then the mask. - * w,a -> bit 0 - * z,b -> bit 1 - * y,g -> bit 2 - * x,r -> bit 3 - * - * ==> Need to reverse the order of bits for this! - */ - tmp = (GLint) *(*inst)++; - *WriteMask = (((tmp>>3) & 0x1) | - ((tmp>>1) & 0x2) | - ((tmp<<1) & 0x4) | - ((tmp<<3) & 0x8)); - - return 0; -} - - -/** - * Handle the parsing of a address register - * - * \param Index - The register index we write to - * - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_address_reg (GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, - struct arb_program *Program, GLint * Index) -{ - struct var_cache *dst; - GLuint result; - - *Index = 0; /* XXX */ - - dst = parse_string (inst, vc_head, Program, &result); - Program->Position = parse_position (inst); - - /* If the name has never been added to our symbol table, we're hosed */ - if (!result) { - program_error(ctx, Program->Position, "Undefined variable"); - return 1; - } - - if (dst->type != vt_address) { - program_error(ctx, Program->Position, "Variable is not of type ADDRESS"); - return 1; - } - - return 0; -} - -#if 0 /* unused */ -/** - * Handle the parsing out of a masked address register - * - * \param Index - The register index we write to - * \param WriteMask - The mask controlling which components we write (1->write) - * - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_masked_address_reg (GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, - struct arb_program *Program, GLint * Index, - GLboolean * WriteMask) -{ - if (parse_address_reg (ctx, inst, vc_head, Program, Index)) - return 1; - - /* This should be 0x8 */ - (*inst)++; - - /* Writemask of .x is implied */ - WriteMask[0] = 1; - WriteMask[1] = WriteMask[2] = WriteMask[3] = 0; - - return 0; -} -#endif - -/** - * Parse out a swizzle mask. - * - * Basically convert COMPONENT_X/Y/Z/W to SWIZZLE_X/Y/Z/W - * - * The len parameter allows us to grab 4 components for a vector - * swizzle, or just 1 component for a scalar src register selection - */ -static void -parse_swizzle_mask(const GLubyte ** inst, GLubyte *swizzle, GLint len) -{ - GLint i; - - for (i = 0; i < 4; i++) - swizzle[i] = i; - - for (i = 0; i < len; i++) { - switch (*(*inst)++) { - case COMPONENT_X: - swizzle[i] = SWIZZLE_X; - break; - case COMPONENT_Y: - swizzle[i] = SWIZZLE_Y; - break; - case COMPONENT_Z: - swizzle[i] = SWIZZLE_Z; - break; - case COMPONENT_W: - swizzle[i] = SWIZZLE_W; - break; - default: - _mesa_problem(NULL, "bad component in parse_swizzle_mask()"); - return; - } - } -} - - -/** - * Parse an extended swizzle mask which is a sequence of - * four x/y/z/w/0/1 tokens. - * \return swizzle four swizzle values - * \return negateMask four element bitfield - */ -static void -parse_extended_swizzle_mask(const GLubyte **inst, GLubyte swizzle[4], - GLubyte *negateMask) -{ - GLint i; - - *negateMask = 0x0; - for (i = 0; i < 4; i++) { - GLubyte swz; - if (parse_sign(inst) == -1) - *negateMask |= (1 << i); - - swz = *(*inst)++; - - switch (swz) { - case COMPONENT_0: - swizzle[i] = SWIZZLE_ZERO; - break; - case COMPONENT_1: - swizzle[i] = SWIZZLE_ONE; - break; - case COMPONENT_X: - swizzle[i] = SWIZZLE_X; - break; - case COMPONENT_Y: - swizzle[i] = SWIZZLE_Y; - break; - case COMPONENT_Z: - swizzle[i] = SWIZZLE_Z; - break; - case COMPONENT_W: - swizzle[i] = SWIZZLE_W; - break; - default: - _mesa_problem(NULL, "bad case in parse_extended_swizzle_mask()"); - return; - } - } -} - - -static GLuint -parse_src_reg (GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, - struct arb_program *Program, - gl_register_file * File, GLint * Index, - GLboolean *IsRelOffset ) -{ - struct var_cache *src; - GLuint binding, is_generic, found; - GLint offset; - - *IsRelOffset = 0; - - /* And the binding for the src */ - switch (*(*inst)++) { - case REGISTER_ATTRIB: - if (parse_attrib_binding - (ctx, inst, Program, &binding, &is_generic)) - return 1; - *File = PROGRAM_INPUT; - *Index = binding; - - /* We need to insert a dummy variable into the var_cache so we can - * catch generic vertex attrib aliasing errors - */ - var_cache_create(&src); - src->type = vt_attrib; - src->name = (const GLubyte *) "Dummy Attrib Variable"; - src->attrib_binding = binding; - src->attrib_is_generic = is_generic; - var_cache_append(vc_head, src); - 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; - } - break; - - case REGISTER_PARAM: - switch (**inst) { - case PARAM_ARRAY_ELEMENT: - (*inst)++; - src = parse_string (inst, vc_head, Program, &found); - Program->Position = parse_position (inst); - - if (!found) { - program_error2(ctx, Program->Position, - "Undefined variable", - (char *) src->name); - return 1; - } - - *File = (gl_register_file) src->param_binding_type; - - switch (*(*inst)++) { - case ARRAY_INDEX_ABSOLUTE: - offset = parse_integer (inst, Program); - - if ((offset < 0) - || (offset >= (int)src->param_binding_length)) { - program_error(ctx, Program->Position, - "Index out of range"); - /* offset, src->name */ - return 1; - } - - *Index = src->param_binding_begin + offset; - break; - - case ARRAY_INDEX_RELATIVE: - { - GLint addr_reg_idx, rel_off; - - /* First, grab the address regiseter */ - if (parse_address_reg (ctx, inst, vc_head, Program, &addr_reg_idx)) - return 1; - - /* And the .x */ - ((*inst)++); - ((*inst)++); - ((*inst)++); - ((*inst)++); - - /* Then the relative offset */ - if (parse_relative_offset(ctx, inst, Program, &rel_off)) return 1; - - /* And store it properly */ - *Index = src->param_binding_begin + rel_off; - *IsRelOffset = 1; - } - break; - } - break; - - default: - if (parse_param_use (ctx, inst, vc_head, Program, &src)) - return 1; - - *File = (gl_register_file) src->param_binding_type; - *Index = src->param_binding_begin; - break; - } - break; - - case REGISTER_ESTABLISHED_NAME: - src = parse_string (inst, vc_head, Program, &found); - Program->Position = parse_position (inst); - - /* If the name has never been added to our symbol table, we're hosed */ - if (!found) { - program_error(ctx, Program->Position, - "3: Undefined variable"); /* src->name */ - return 1; - } - - switch (src->type) { - case vt_attrib: - *File = PROGRAM_INPUT; - *Index = src->attrib_binding; - break; - - /* XXX: We have to handle offsets someplace in here! -- or are those above? */ - case vt_param: - *File = (gl_register_file) src->param_binding_type; - *Index = src->param_binding_begin; - break; - - case vt_temp: - *File = PROGRAM_TEMPORARY; - *Index = src->temp_binding; - break; - - /* If the var type is vt_output no go */ - default: - program_error(ctx, Program->Position, - "destination register is read only"); - /* bad src->name */ - return 1; - } - break; - - default: - program_error(ctx, Program->Position, - "Unknown token in parse_src_reg"); - return 1; - } - - if (*File == PROGRAM_STATE_VAR) { - gl_register_file file; - - /* If we're referencing the Program->Parameters[] array, check if the - * parameter is really a constant/literal. If so, set File to CONSTANT. - */ - assert(*Index < (GLint) Program->Base.Parameters->NumParameters); - file = Program->Base.Parameters->Parameters[*Index].Type; - if (file == PROGRAM_CONSTANT) - *File = PROGRAM_CONSTANT; - } - - /* 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 vertex/fragment program vector source register. - */ -static GLuint -parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst, - struct var_cache **vc_head, - struct arb_program *program, - struct prog_src_register *reg) -{ - gl_register_file file; - GLint index; - GLubyte negateMask; - GLubyte swizzle[4]; - GLboolean isRelOffset; - - /* 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, 4); - - reg->File = file; - reg->Index = index; - reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); - reg->Negate = negateMask; - reg->RelAddr = isRelOffset; - return 0; -} - - -/** - * Parse vertex/fragment program scalar source register. - */ -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) -{ - gl_register_file file; - GLint index; - GLubyte negateMask; - GLubyte swizzle[4]; - GLboolean isRelOffset; - - /* 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 = index; - reg->Swizzle = (swizzle[0] << 0); - reg->Negate = negateMask; - reg->RelAddr = isRelOffset; - return 0; -} - - -/** - * Parse vertex/fragment program destination register. - * \return 1 if error, 0 if no error. - */ -static GLuint -parse_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; - gl_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; -} - - -/** - * This is a big mother that handles getting opcodes into the instruction - * and handling the src & dst registers for fragment program instructions - * \return 1 if error, 0 if no error - */ -static GLuint -parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, struct arb_program *Program, - struct prog_instruction *fp) -{ - GLint a; - GLuint texcoord; - GLubyte instClass, type, code; - GLboolean rel; - GLuint shadow_tex = 0; - - _mesa_init_instructions(fp, 1); - - /* OP_ALU_INST or OP_TEX_INST */ - instClass = *(*inst)++; - - /* OP_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ}, - * OP_TEX_{SAMPLE, KIL} - */ - type = *(*inst)++; - - /* The actual opcode name */ - code = *(*inst)++; - - /* Increment the correct count */ - switch (instClass) { - case OP_ALU_INST: - Program->NumAluInstructions++; - break; - case OP_TEX_INST: - Program->NumTexInstructions++; - break; - } - - switch (type) { - case OP_ALU_VECTOR: - switch (code) { - case OP_ABS_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_ABS: - fp->Opcode = OPCODE_ABS; - break; - - case OP_FLR_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_FLR: - fp->Opcode = OPCODE_FLR; - break; - - case OP_FRC_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_FRC: - fp->Opcode = OPCODE_FRC; - break; - - case OP_LIT_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_LIT: - fp->Opcode = OPCODE_LIT; - break; - - case OP_MOV_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_MOV: - fp->Opcode = OPCODE_MOV; - break; - } - - if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) - return 1; - - if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) - return 1; - break; - - case OP_ALU_SCALAR: - switch (code) { - case OP_COS_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_COS: - fp->Opcode = OPCODE_COS; - break; - - case OP_EX2_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_EX2: - fp->Opcode = OPCODE_EX2; - break; - - case OP_LG2_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_LG2: - fp->Opcode = OPCODE_LG2; - break; - - case OP_RCP_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_RCP: - fp->Opcode = OPCODE_RCP; - break; - - case OP_RSQ_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_RSQ: - fp->Opcode = OPCODE_RSQ; - break; - - case OP_SIN_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_SIN: - fp->Opcode = OPCODE_SIN; - break; - - case OP_SCS_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_SCS: - - fp->Opcode = OPCODE_SCS; - break; - } - - if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) - return 1; - - if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) - return 1; - break; - - case OP_ALU_BINSC: - switch (code) { - case OP_POW_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_POW: - fp->Opcode = OPCODE_POW; - break; - } - - if (parse_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg)) - return 1; - - for (a = 0; a < 2; a++) { - if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) - return 1; - } - break; - - - case OP_ALU_BIN: - switch (code) { - case OP_ADD_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_ADD: - fp->Opcode = OPCODE_ADD; - break; - - case OP_DP3_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_DP3: - fp->Opcode = OPCODE_DP3; - break; - - case OP_DP4_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_DP4: - fp->Opcode = OPCODE_DP4; - break; - - case OP_DPH_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_DPH: - fp->Opcode = OPCODE_DPH; - break; - - case OP_DST_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_DST: - fp->Opcode = OPCODE_DST; - break; - - case OP_MAX_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_MAX: - fp->Opcode = OPCODE_MAX; - break; - - case OP_MIN_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_MIN: - fp->Opcode = OPCODE_MIN; - break; - - case OP_MUL_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_MUL: - fp->Opcode = OPCODE_MUL; - break; - - case OP_SGE_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_SGE: - fp->Opcode = OPCODE_SGE; - break; - - case OP_SLT_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_SLT: - fp->Opcode = OPCODE_SLT; - break; - - case OP_SUB_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_SUB: - fp->Opcode = OPCODE_SUB; - break; - - case OP_XPD_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_XPD: - fp->Opcode = OPCODE_XPD; - break; - } - - if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) - return 1; - for (a = 0; a < 2; a++) { - if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) - return 1; - } - break; - - case OP_ALU_TRI: - switch (code) { - case OP_CMP_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_CMP: - fp->Opcode = OPCODE_CMP; - break; - - case OP_LRP_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_LRP: - fp->Opcode = OPCODE_LRP; - break; - - case OP_MAD_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_MAD: - fp->Opcode = OPCODE_MAD; - break; - } - - if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) - return 1; - - for (a = 0; a < 3; a++) { - if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) - return 1; - } - break; - - case OP_ALU_SWZ: - switch (code) { - case OP_SWZ_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_SWZ: - fp->Opcode = OPCODE_SWZ; - break; - } - if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) - return 1; - - { - GLubyte swizzle[4]; - GLubyte negateMask; - gl_register_file file; - GLint index; - - if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &rel)) - return 1; - parse_extended_swizzle_mask(inst, swizzle, &negateMask); - fp->SrcReg[0].File = file; - fp->SrcReg[0].Index = index; - fp->SrcReg[0].Negate = negateMask; - fp->SrcReg[0].Swizzle = MAKE_SWIZZLE4(swizzle[0], - swizzle[1], - swizzle[2], - swizzle[3]); - } - break; - - case OP_TEX_SAMPLE: - switch (code) { - case OP_TEX_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_TEX: - fp->Opcode = OPCODE_TEX; - break; - - case OP_TXP_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_TXP: - fp->Opcode = OPCODE_TXP; - break; - - case OP_TXB_SAT: - fp->SaturateMode = SATURATE_ZERO_ONE; - case OP_TXB: - fp->Opcode = OPCODE_TXB; - break; - } - - if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) - return 1; - - if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) - return 1; - - /* texImageUnit */ - if (parse_teximage_num (ctx, inst, Program, &texcoord)) - return 1; - fp->TexSrcUnit = texcoord; - - /* 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_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; - } - - if (shadow_tex) - fp->TexShadow = 1; - - /* 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) { - program_error(ctx, Program->Position, - "multiple targets used on one texture image unit"); - return 1; - } - - - Program->ShadowSamplers |= shadow_tex; - break; - - case OP_TEX_KIL: - Program->UsesKill = 1; - if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) - return 1; - fp->Opcode = OPCODE_KIL; - break; - default: - _mesa_problem(ctx, "bad type 0x%x in parse_fp_instruction()", type); - return 1; - } - - return 0; -} - - -/** - * Handle the parsing out of a masked address register - * - * \param Index - The register index we write to - * \param WriteMask - The mask controlling which components we write (1->write) - * - * \return 0 on sucess, 1 on error - */ -static GLuint -parse_vp_address_reg (GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, - struct arb_program *Program, - struct prog_dst_register *reg) -{ - GLint idx; - - if (parse_address_reg (ctx, inst, vc_head, Program, &idx)) - return 1; - - /* This should be 0x8 */ - (*inst)++; - - reg->File = PROGRAM_ADDRESS; - reg->Index = idx; - - /* Writemask of .x is implied */ - reg->WriteMask = 0x1; - return 0; -} - - -/** - * This is a big mother that handles getting opcodes into the instruction - * and handling the src & dst registers for vertex program instructions - */ -static GLuint -parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, - struct var_cache **vc_head, struct arb_program *Program, - struct prog_instruction *vp) -{ - GLint a; - GLubyte type, code; - - /* OP_ALU_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */ - type = *(*inst)++; - - /* The actual opcode name */ - code = *(*inst)++; - - _mesa_init_instructions(vp, 1); - - switch (type) { - /* XXX: */ - case OP_ALU_ARL: - vp->Opcode = OPCODE_ARL; - - /* Remember to set SrcReg.RelAddr; */ - - /* Get the masked address register [dst] */ - if (parse_vp_address_reg(ctx, inst, vc_head, Program, &vp->DstReg)) - return 1; - - vp->DstReg.File = PROGRAM_ADDRESS; - - /* Get a scalar src register */ - if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) - return 1; - - break; - - case OP_ALU_VECTOR: - switch (code) { - case OP_ABS: - vp->Opcode = OPCODE_ABS; - break; - case OP_FLR: - vp->Opcode = OPCODE_FLR; - break; - case OP_FRC: - vp->Opcode = OPCODE_FRC; - break; - case OP_LIT: - vp->Opcode = OPCODE_LIT; - break; - case OP_MOV: - vp->Opcode = OPCODE_MOV; - break; - } - - if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) - return 1; - - if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) - return 1; - break; - - case OP_ALU_SCALAR: - switch (code) { - case OP_EX2: - vp->Opcode = OPCODE_EX2; - break; - case OP_EXP: - vp->Opcode = OPCODE_EXP; - break; - case OP_LG2: - vp->Opcode = OPCODE_LG2; - break; - case OP_LOG: - vp->Opcode = OPCODE_LOG; - break; - case OP_RCP: - vp->Opcode = OPCODE_RCP; - break; - case OP_RSQ: - vp->Opcode = OPCODE_RSQ; - break; - } - if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) - return 1; - - if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) - return 1; - break; - - case OP_ALU_BINSC: - switch (code) { - case OP_POW: - vp->Opcode = OPCODE_POW; - break; - } - if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) - return 1; - - for (a = 0; a < 2; a++) { - if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) - return 1; - } - break; - - case OP_ALU_BIN: - switch (code) { - case OP_ADD: - vp->Opcode = OPCODE_ADD; - break; - case OP_DP3: - vp->Opcode = OPCODE_DP3; - break; - case OP_DP4: - vp->Opcode = OPCODE_DP4; - break; - case OP_DPH: - vp->Opcode = OPCODE_DPH; - break; - case OP_DST: - vp->Opcode = OPCODE_DST; - break; - case OP_MAX: - vp->Opcode = OPCODE_MAX; - break; - case OP_MIN: - vp->Opcode = OPCODE_MIN; - break; - case OP_MUL: - vp->Opcode = OPCODE_MUL; - break; - case OP_SGE: - vp->Opcode = OPCODE_SGE; - break; - case OP_SLT: - vp->Opcode = OPCODE_SLT; - break; - case OP_SUB: - vp->Opcode = OPCODE_SUB; - break; - case OP_XPD: - vp->Opcode = OPCODE_XPD; - break; - } - if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) - return 1; - - for (a = 0; a < 2; a++) { - if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) - return 1; - } - break; - - case OP_ALU_TRI: - switch (code) { - case OP_MAD: - vp->Opcode = OPCODE_MAD; - break; - } - - if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) - return 1; - - for (a = 0; a < 3; a++) { - if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) - return 1; - } - break; - - case OP_ALU_SWZ: - switch (code) { - case OP_SWZ: - vp->Opcode = OPCODE_SWZ; - break; - } - { - GLubyte swizzle[4]; - GLubyte negateMask; - GLboolean relAddr; - gl_register_file file; - GLint index; - - 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)) - return 1; - parse_extended_swizzle_mask (inst, swizzle, &negateMask); - vp->SrcReg[0].File = file; - vp->SrcReg[0].Index = index; - vp->SrcReg[0].Negate = negateMask; - vp->SrcReg[0].Swizzle = MAKE_SWIZZLE4(swizzle[0], - swizzle[1], - swizzle[2], - swizzle[3]); - vp->SrcReg[0].RelAddr = relAddr; - } - break; - } - return 0; -} - -#if DEBUG_PARSING - -static GLvoid -debug_variables (GLcontext * ctx, struct var_cache *vc_head, - struct arb_program *Program) -{ - struct var_cache *vc; - GLint a, b; - - 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, "[%p]\n", (void*) vc); - switch (vc->type) { - case vt_none: - fprintf (stderr, "UNDEFINED %s\n", vc->name); - break; - case vt_attrib: - fprintf (stderr, "ATTRIB %s\n", vc->name); - fprintf (stderr, " binding: 0x%x\n", vc->attrib_binding); - break; - case vt_param: - fprintf (stderr, "PARAM %s begin: %d len: %d\n", vc->name, - vc->param_binding_begin, vc->param_binding_length); - b = vc->param_binding_begin; - for (a = 0; a < vc->param_binding_length; a++) { - fprintf (stderr, "%s\n", - Program->Base.Parameters->Parameters[a + b].Name); - if (Program->Base.Parameters->Parameters[a + b].Type == PROGRAM_STATE_VAR) { - char *s; - s = _mesa_program_state_string(Program->Base.Parameters->Parameters - [a + b].StateIndexes); - fprintf(stderr, "%s\n", s); - _mesa_free(s); - } - else - fprintf (stderr, "%f %f %f %f\n", - 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: - fprintf (stderr, "TEMP %s\n", vc->name); - fprintf (stderr, " binding: 0x%x\n", vc->temp_binding); - break; - case vt_output: - fprintf (stderr, "OUTPUT %s\n", vc->name); - fprintf (stderr, " binding: 0x%x\n", vc->output_binding); - break; - case vt_alias: - fprintf (stderr, "ALIAS %s\n", vc->name); - fprintf (stderr, " binding: 0x%p (%s)\n", - (void*) vc->alias_binding, vc->alias_binding->name); - break; - default: - /* nothing */ - ; - } - vc = vc->next; - } -} - -#endif /* DEBUG_PARSING */ - - -/** - * The main loop for parsing a fragment or vertex program - * - * \return 1 on error, 0 on success - */ -static GLint -parse_instructions(GLcontext * ctx, const GLubyte * inst, - struct var_cache **vc_head, struct arb_program *Program) -{ - const GLuint maxInst = (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) - ? ctx->Const.FragmentProgram.MaxInstructions - : ctx->Const.VertexProgram.MaxInstructions; - GLint err = 0; - - ASSERT(MAX_PROGRAM_INSTRUCTIONS >= maxInst); - - Program->MajorVersion = (GLuint) * inst++; - Program->MinorVersion = (GLuint) * inst++; - - while (*inst != END) { - switch (*inst++) { - - case OPTION: - switch (*inst++) { - case ARB_PRECISION_HINT_FASTEST: - Program->PrecisionOption = GL_FASTEST; - break; - - case ARB_PRECISION_HINT_NICEST: - Program->PrecisionOption = GL_NICEST; - break; - - case ARB_FOG_EXP: - Program->FogOption = GL_EXP; - break; - - case ARB_FOG_EXP2: - Program->FogOption = GL_EXP2; - break; - - case ARB_FOG_LINEAR: - Program->FogOption = GL_LINEAR; - break; - - case ARB_POSITION_INVARIANT: - if (Program->Base.Target == GL_VERTEX_PROGRAM_ARB) - Program->HintPositionInvariant = GL_TRUE; - break; - - case ARB_FRAGMENT_PROGRAM_SHADOW: - if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { - /* TODO ARB_fragment_program_shadow code */ - } - break; - - case ARB_DRAW_BUFFERS: - if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { - /* do nothing for now */ - } - break; - - case MESA_TEXTURE_ARRAY: - /* do nothing for now */ - break; - } - break; - - case INSTRUCTION: - /* check length */ - if (Program->Base.NumInstructions + 1 >= maxInst) { - program_error(ctx, Program->Position, - "Max instruction count exceeded"); - return 1; - } - Program->Position = parse_position (&inst); - /* parse the current instruction */ - if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { - err = parse_fp_instruction (ctx, &inst, vc_head, Program, - &Program->Base.Instructions[Program->Base.NumInstructions]); - } - else { - err = parse_vp_instruction (ctx, &inst, vc_head, Program, - &Program->Base.Instructions[Program->Base.NumInstructions]); - } - - /* increment instuction count */ - Program->Base.NumInstructions++; - break; - - case DECLARATION: - err = parse_declaration (ctx, &inst, vc_head, Program); - break; - - default: - break; - } - - if (err) - break; - } - - /* Finally, tag on an OPCODE_END instruction */ - { - const GLuint numInst = Program->Base.NumInstructions; - _mesa_init_instructions(Program->Base.Instructions + numInst, 1); - Program->Base.Instructions[numInst].Opcode = OPCODE_END; - } - Program->Base.NumInstructions++; - - /* - * Initialize native counts to logical counts. The device driver may - * change them if program is translated into a hardware program. - */ - Program->Base.NumNativeInstructions = Program->Base.NumInstructions; - Program->Base.NumNativeTemporaries = Program->Base.NumTemporaries; - Program->Base.NumNativeParameters = Program->Base.NumParameters; - Program->Base.NumNativeAttributes = Program->Base.NumAttributes; - Program->Base.NumNativeAddressRegs = Program->Base.NumAddressRegs; - - return err; -} - - -/* XXX temporary */ -LONGSTRING static char core_grammar_text[] = -#include "shader/grammar/grammar_syn.h" -; - - -/** - * Set a grammar parameter. - * \param name the grammar parameter - * \param value the new parameter value - * \return 0 if OK, 1 if error - */ -static int -set_reg8 (GLcontext *ctx, grammar id, const char *name, GLubyte value) -{ - char error_msg[300]; - GLint error_pos; - - if (grammar_set_reg8 (id, (const byte *) name, value)) - return 0; - - grammar_get_last_error ((byte *) error_msg, 300, &error_pos); - _mesa_set_program_error (ctx, error_pos, error_msg); - _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar Register Error"); - return 1; -} - - -/** - * Enable support for the given language option in the parser. - * \return 1 if OK, 0 if error - */ -static int -enable_ext(GLcontext *ctx, grammar id, const char *name) -{ - return !set_reg8(ctx, id, name, 1); -} - - -/** - * Enable parser extensions based on which OpenGL extensions are supported - * by this rendering context. - * - * \return GL_TRUE if OK, GL_FALSE if error. - */ -static GLboolean -enable_parser_extensions(GLcontext *ctx, grammar id) -{ -#if 0 - /* These are not supported at this time */ - if ((ctx->Extensions.ARB_vertex_blend || - ctx->Extensions.EXT_vertex_weighting) - && !enable_ext(ctx, id, "vertex_blend")) - return GL_FALSE; - 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; - if (ctx->Extensions.EXT_point_parameters - && !enable_ext(ctx, id, "point_parameters")) - return GL_FALSE; - if (ctx->Extensions.EXT_secondary_color - && !enable_ext(ctx, id, "secondary_color")) - return GL_FALSE; - if (ctx->Extensions.EXT_fog_coord - && !enable_ext(ctx, id, "fog_coord")) - return GL_FALSE; - if (ctx->Extensions.NV_texture_rectangle - && !enable_ext(ctx, id, "texture_rectangle")) - return GL_FALSE; - if (!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"); -#endif - - return GL_TRUE; -} - - -/** - * This kicks everything off. - * - * \param ctx - The GL Context - * \param str - The program string - * \param len - The program string length - * \param program - The arb_program struct to return all the parsed info in - * \return GL_TRUE on sucess, GL_FALSE on error - */ -static GLboolean -_mesa_parse_arb_program(GLcontext *ctx, GLenum target, - const GLubyte *str, GLsizei len, - struct arb_program *program) -{ - GLint a, err, error_pos; - char error_msg[300]; - GLuint parsed_len; - struct var_cache *vc_head; - grammar arbprogram_syn_id; - GLubyte *parsed, *inst; - GLubyte *strz = NULL; - static int arbprogram_syn_is_ok = 0; /* XXX temporary */ - - /* set the program target before parsing */ - program->Base.Target = target; - - /* Reset error state */ - _mesa_set_program_error(ctx, -1, NULL); - - /* check if arb_grammar_text (arbprogram.syn) is syntactically correct */ - if (!arbprogram_syn_is_ok) { - /* One-time initialization of parsing system */ - grammar grammar_syn_id; - GLuint parsed_len; - - grammar_syn_id = grammar_load_from_text ((byte *) core_grammar_text); - if (grammar_syn_id == 0) { - grammar_get_last_error ((byte *) error_msg, 300, &error_pos); - /* XXX this is not a GL error - it's an implementation bug! - FIX */ - _mesa_set_program_error (ctx, error_pos, error_msg); - _mesa_error (ctx, GL_INVALID_OPERATION, - "glProgramStringARB(Error loading grammar rule set)"); - return GL_FALSE; - } - - err = !grammar_check(grammar_syn_id, (byte *) arb_grammar_text, - &parsed, &parsed_len); - - /* 'parsed' is unused here */ - _mesa_free (parsed); - parsed = NULL; - - /* NOTE: we can't destroy grammar_syn_id right here because - * grammar_destroy() can reset the last error - */ - if (err) { - /* XXX this is not a GL error - it's an implementation bug! - FIX */ - grammar_get_last_error ((byte *) error_msg, 300, &error_pos); - _mesa_set_program_error (ctx, error_pos, error_msg); - _mesa_error (ctx, GL_INVALID_OPERATION, - "glProgramString(Error loading grammar rule set"); - grammar_destroy (grammar_syn_id); - return GL_FALSE; - } - - grammar_destroy (grammar_syn_id); - - arbprogram_syn_is_ok = 1; - } - - /* create the grammar object */ - arbprogram_syn_id = grammar_load_from_text ((byte *) arb_grammar_text); - if (arbprogram_syn_id == 0) { - /* XXX this is not a GL error - it's an implementation bug! - FIX */ - grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos); - _mesa_set_program_error (ctx, error_pos, error_msg); - _mesa_error (ctx, GL_INVALID_OPERATION, - "glProgramString(Error loading grammer rule set)"); - return GL_FALSE; - } - - /* Set program_target register value */ - if (set_reg8 (ctx, arbprogram_syn_id, "program_target", - program->Base.Target == GL_FRAGMENT_PROGRAM_ARB ? 0x10 : 0x20)) { - grammar_destroy (arbprogram_syn_id); - return GL_FALSE; - } - - if (!enable_parser_extensions(ctx, arbprogram_syn_id)) { - grammar_destroy(arbprogram_syn_id); - return GL_FALSE; - } - - /* check for NULL character occurences */ - { - GLint i; - for (i = 0; i < len; i++) { - if (str[i] == '\0') { - program_error(ctx, i, "illegal character"); - grammar_destroy (arbprogram_syn_id); - return GL_FALSE; - } - } - } - - /* copy the program string to a null-terminated string */ - strz = (GLubyte *) _mesa_malloc (len + 1); - if (!strz) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); - grammar_destroy (arbprogram_syn_id); - return GL_FALSE; - } - _mesa_memcpy (strz, str, len); - strz[len] = '\0'; - - /* do a fast check on program string - initial production buffer is 4K */ - err = !grammar_fast_check(arbprogram_syn_id, strz, - &parsed, &parsed_len, 0x1000); - - /* Syntax parse error */ - if (err) { - grammar_get_last_error((GLubyte *) error_msg, 300, &error_pos); - program_error(ctx, error_pos, error_msg); - -#if DEBUG_PARSING - /* useful for debugging */ - do { - 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, - &line, &col); - fprintf(stderr, "line %d col %d: %s\n", line, col, s); - } while (0); -#endif - - _mesa_free(strz); - _mesa_free(parsed); - - grammar_destroy (arbprogram_syn_id); - return GL_FALSE; - } - - grammar_destroy (arbprogram_syn_id); - - /* - * Program string is syntactically correct at this point - * Parse the tokenized version of the program now, generating - * vertex/fragment program instructions. - */ - - /* Initialize the arb_program struct */ - program->Base.String = strz; - program->Base.Instructions = _mesa_alloc_instructions(MAX_PROGRAM_INSTRUCTIONS); - program->Base.NumInstructions = - program->Base.NumTemporaries = - program->Base.NumParameters = - program->Base.NumAttributes = program->Base.NumAddressRegs = 0; - program->Base.Parameters = _mesa_new_parameter_list (); - program->Base.InputsRead = 0x0; - program->Base.OutputsWritten = 0x0; - program->Position = 0; - program->MajorVersion = program->MinorVersion = 0; - program->PrecisionOption = GL_DONT_CARE; - program->FogOption = GL_NONE; - 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; - program->UsesKill = 0; - - vc_head = NULL; - err = GL_FALSE; - - /* Start examining the tokens in the array */ - inst = parsed; - - /* Check the grammer rev */ - if (*inst++ != REVISION) { - program_error (ctx, 0, "Grammar version mismatch"); - err = GL_TRUE; - } - else { - /* ignore program target */ - inst++; - err = parse_instructions(ctx, inst, &vc_head, program); - } - - /*debug_variables(ctx, vc_head, program); */ - - /* We're done with the parsed binary array */ - var_cache_destroy (&vc_head); - - _mesa_free (parsed); - - /* Reallocate the instruction array from size [MAX_PROGRAM_INSTRUCTIONS] - * to size [ap.Base.NumInstructions]. - */ - program->Base.Instructions - = _mesa_realloc_instructions(program->Base.Instructions, - MAX_PROGRAM_INSTRUCTIONS, - program->Base.NumInstructions); - - return !err; -} - +#include "program_parser.h" void @@ -3881,11 +71,18 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, const GLvoid *str, GLsizei len, struct gl_fragment_program *program) { - struct arb_program ap; + struct gl_program prog; + struct asm_parser_state state; GLuint i; ASSERT(target == GL_FRAGMENT_PROGRAM_ARB); - if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, &ap)) { + + memset(&prog, 0, sizeof(prog)); + memset(&state, 0, sizeof(state)); + state.prog = &prog; + + if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, + &state)) { /* Error in the program. Just return. */ return; } @@ -3893,51 +90,50 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, /* Copy the relevant contents of the arb_program struct into the * fragment_program struct. */ - program->Base.String = ap.Base.String; - program->Base.NumInstructions = ap.Base.NumInstructions; - program->Base.NumTemporaries = ap.Base.NumTemporaries; - program->Base.NumParameters = ap.Base.NumParameters; - program->Base.NumAttributes = ap.Base.NumAttributes; - program->Base.NumAddressRegs = ap.Base.NumAddressRegs; - program->Base.NumNativeInstructions = ap.Base.NumNativeInstructions; - program->Base.NumNativeTemporaries = ap.Base.NumNativeTemporaries; - program->Base.NumNativeParameters = ap.Base.NumNativeParameters; - program->Base.NumNativeAttributes = ap.Base.NumNativeAttributes; - program->Base.NumNativeAddressRegs = ap.Base.NumNativeAddressRegs; - 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; + program->Base.String = prog.String; + program->Base.NumInstructions = prog.NumInstructions; + program->Base.NumTemporaries = prog.NumTemporaries; + program->Base.NumParameters = prog.NumParameters; + program->Base.NumAttributes = prog.NumAttributes; + program->Base.NumAddressRegs = prog.NumAddressRegs; + program->Base.NumNativeInstructions = prog.NumNativeInstructions; + program->Base.NumNativeTemporaries = prog.NumNativeTemporaries; + program->Base.NumNativeParameters = prog.NumNativeParameters; + program->Base.NumNativeAttributes = prog.NumNativeAttributes; + program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs; + program->Base.NumAluInstructions = prog.NumAluInstructions; + program->Base.NumTexInstructions = prog.NumTexInstructions; + program->Base.NumTexIndirections = prog.NumTexIndirections; + program->Base.NumNativeAluInstructions = prog.NumAluInstructions; + program->Base.NumNativeTexInstructions = prog.NumTexInstructions; + program->Base.NumNativeTexIndirections = prog.NumTexIndirections; + program->Base.InputsRead = prog.InputsRead; + program->Base.OutputsWritten = prog.OutputsWritten; for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) { - program->Base.TexturesUsed[i] = ap.TexturesUsed[i]; - if (ap.TexturesUsed[i]) + program->Base.TexturesUsed[i] = prog.TexturesUsed[i]; + if (prog.TexturesUsed[i]) program->Base.SamplersUsed |= (1 << i); } - program->Base.ShadowSamplers = ap.ShadowSamplers; - program->FogOption = ap.FogOption; - program->UsesKill = ap.UsesKill; + program->Base.ShadowSamplers = prog.ShadowSamplers; + switch (state.option.Fog) { + case OPTION_FOG_EXP: program->FogOption = GL_EXP; break; + case OPTION_FOG_EXP2: program->FogOption = GL_EXP2; break; + case OPTION_FOG_LINEAR: program->FogOption = GL_LINEAR; break; + default: program->FogOption = GL_NONE; break; + } + + program->UsesKill = state.fragment.UsesKill; if (program->FogOption) program->Base.InputsRead |= FRAG_BIT_FOGC; - /* XXX: assume that ARB fragment programs don't have access to the - * FrontFacing and PointCoord values stuffed into the fog - * coordinate in GLSL shaders. - */ - if (program->Base.InputsRead & FRAG_BIT_FOGC) - program->UsesFogFragCoord = GL_TRUE; - if (program->Base.Instructions) _mesa_free(program->Base.Instructions); - program->Base.Instructions = ap.Base.Instructions; + program->Base.Instructions = prog.Instructions; if (program->Base.Parameters) _mesa_free_parameter_list(program->Base.Parameters); - program->Base.Parameters = ap.Base.Parameters; + program->Base.Parameters = prog.Parameters; /* Append fog instructions now if the program has "OPTION ARB_fog_exp" * or similar. We used to leave this up to drivers, but it appears @@ -3967,11 +163,17 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, const GLvoid *str, GLsizei len, struct gl_vertex_program *program) { - struct arb_program ap; + struct gl_program prog; + struct asm_parser_state state; ASSERT(target == GL_VERTEX_PROGRAM_ARB); - if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, &ap)) { + memset(&prog, 0, sizeof(prog)); + memset(&state, 0, sizeof(state)); + state.prog = &prog; + + if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, + &state)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)"); return; } @@ -3979,28 +181,29 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, /* Copy the relevant contents of the arb_program struct into the * vertex_program struct. */ - program->Base.String = ap.Base.String; - program->Base.NumInstructions = ap.Base.NumInstructions; - program->Base.NumTemporaries = ap.Base.NumTemporaries; - program->Base.NumParameters = ap.Base.NumParameters; - program->Base.NumAttributes = ap.Base.NumAttributes; - program->Base.NumAddressRegs = ap.Base.NumAddressRegs; - program->Base.NumNativeInstructions = ap.Base.NumNativeInstructions; - program->Base.NumNativeTemporaries = ap.Base.NumNativeTemporaries; - program->Base.NumNativeParameters = ap.Base.NumNativeParameters; - program->Base.NumNativeAttributes = ap.Base.NumNativeAttributes; - program->Base.NumNativeAddressRegs = ap.Base.NumNativeAddressRegs; - program->Base.InputsRead = ap.Base.InputsRead; - program->Base.OutputsWritten = ap.Base.OutputsWritten; - program->IsPositionInvariant = ap.HintPositionInvariant; + program->Base.String = prog.String; + program->Base.NumInstructions = prog.NumInstructions; + program->Base.NumTemporaries = prog.NumTemporaries; + program->Base.NumParameters = prog.NumParameters; + program->Base.NumAttributes = prog.NumAttributes; + program->Base.NumAddressRegs = prog.NumAddressRegs; + program->Base.NumNativeInstructions = prog.NumNativeInstructions; + program->Base.NumNativeTemporaries = prog.NumNativeTemporaries; + program->Base.NumNativeParameters = prog.NumNativeParameters; + program->Base.NumNativeAttributes = prog.NumNativeAttributes; + program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs; + program->Base.InputsRead = prog.InputsRead; + program->Base.OutputsWritten = prog.OutputsWritten; + program->IsPositionInvariant = (state.option.PositionInvariant) + ? GL_TRUE : GL_FALSE; if (program->Base.Instructions) _mesa_free(program->Base.Instructions); - program->Base.Instructions = ap.Base.Instructions; + program->Base.Instructions = prog.Instructions; if (program->Base.Parameters) _mesa_free_parameter_list(program->Base.Parameters); - program->Base.Parameters = ap.Base.Parameters; + program->Base.Parameters = prog.Parameters; #if DEBUG_VP _mesa_printf("____________Vertex program %u __________\n", program->Base.Id); diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c index a0331054bb..4d8cff0700 100644 --- a/src/mesa/shader/arbprogram.c +++ b/src/mesa/shader/arbprogram.c @@ -74,8 +74,6 @@ _mesa_BindProgram(GLenum target, GLuint id) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - /* Error-check target and get curProg */ if ((target == GL_VERTEX_PROGRAM_ARB) && /* == GL_VERTEX_PROGRAM_NV */ (ctx->Extensions.NV_vertex_program || @@ -132,6 +130,9 @@ _mesa_BindProgram(GLenum target, GLuint id) return; } + /* signal new program (and its new constants) */ + FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + /* bind newProg */ if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, @@ -253,6 +254,8 @@ _mesa_EnableVertexAttribArrayARB(GLuint index) return; } + ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); + FLUSH_VERTICES(ctx, _NEW_ARRAY); ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_TRUE; ctx->Array.ArrayObj->_Enabled |= _NEW_ARRAY_ATTRIB(index); @@ -272,6 +275,8 @@ _mesa_DisableVertexAttribArrayARB(GLuint index) return; } + ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); + FLUSH_VERTICES(ctx, _NEW_ARRAY); ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_FALSE; ctx->Array.ArrayObj->_Enabled &= ~_NEW_ARRAY_ATTRIB(index); @@ -298,32 +303,41 @@ _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params) } +/** + * Return info for a generic vertex attribute array (no alias with + * legacy vertex attributes (pos, normal, color, etc)). + */ void GLAPIENTRY _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) { + const struct gl_client_array *array; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index >= MAX_VERTEX_GENERIC_ATTRIBS) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)"); return; } + ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); + + array = &ctx->Array.ArrayObj->VertexAttrib[index]; + switch (pname) { case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: - params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Enabled; + params[0] = (GLfloat) array->Enabled; break; case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: - params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Size; + params[0] = (GLfloat) array->Size; break; case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: - params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Stride; + params[0] = (GLfloat) array->Stride; break; case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: - params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Type; + params[0] = (GLfloat) array->Type; break; case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: - params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Normalized; + params[0] = array->Normalized; break; case GL_CURRENT_VERTEX_ATTRIB_ARB: if (index == 0) { @@ -335,7 +349,7 @@ _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]); break; case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: - params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].BufferObj->Name; + params[0] = (GLfloat) array->BufferObj->Name; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)"); @@ -379,6 +393,8 @@ _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer) return; } + ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); + *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr; } @@ -489,7 +505,7 @@ _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { @@ -537,7 +553,7 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, GLfloat * dest; ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); if (count <= 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)"); @@ -631,7 +647,7 @@ _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index, struct gl_program *prog; ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); if ((target == GL_FRAGMENT_PROGRAM_NV && ctx->Extensions.NV_fragment_program) || @@ -685,7 +701,7 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, GLint i; ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); if (count <= 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)"); diff --git a/src/mesa/shader/arbprogram.syn b/src/mesa/shader/arbprogram.syn deleted file mode 100644 index b12c6a0eda..0000000000 --- a/src/mesa/shader/arbprogram.syn +++ /dev/null @@ -1,2824 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.2 - * - * Copyright (C) 1999-2004 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"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - /** - * \file arbprogram.syn - * ARB_fragment/vertex_program syntax - * \author Michal Krol - */ - -.syntax program; - -/* - This value must be incremented every time emit code values or structure of the production - array changes. This value is placed at the beginning of the production array. The loader - compares the value with its REVISION value. If they do not match, the loader is not up - to date. -*/ -.emtcode REVISION 0x0a - -/* program type */ -.emtcode FRAGMENT_PROGRAM 0x01 -.emtcode VERTEX_PROGRAM 0x02 - -/* program section */ -.emtcode OPTION 0x01 -.emtcode INSTRUCTION 0x02 -.emtcode DECLARATION 0x03 -.emtcode END 0x04 - -/* GL_ARB_fragment_program option */ -.emtcode ARB_PRECISION_HINT_FASTEST 0x00 -.emtcode ARB_PRECISION_HINT_NICEST 0x01 -.emtcode ARB_FOG_EXP 0x02 -.emtcode ARB_FOG_EXP2 0x03 -.emtcode ARB_FOG_LINEAR 0x04 - -/* GL_ARB_vertex_program option */ -.emtcode ARB_POSITION_INVARIANT 0x05 - -/* GL_ARB_fragment_program_shadow option */ -.emtcode ARB_FRAGMENT_PROGRAM_SHADOW 0x06 - -/* GL_ARB_draw_buffers option */ -.emtcode ARB_DRAW_BUFFERS 0x07 - -/* GL_MESA_texture_array option */ -.emtcode MESA_TEXTURE_ARRAY 0x08 - -/* GL_ARB_fragment_program instruction class */ -.emtcode OP_ALU_INST 0x00 -.emtcode OP_TEX_INST 0x01 - -/* GL_ARB_vertex_program instruction class */ -/* OP_ALU_INST */ - -/* GL_ARB_fragment_program instruction type */ -.emtcode OP_ALU_VECTOR 0x00 -.emtcode OP_ALU_SCALAR 0x01 -.emtcode OP_ALU_BINSC 0x02 -.emtcode OP_ALU_BIN 0x03 -.emtcode OP_ALU_TRI 0x04 -.emtcode OP_ALU_SWZ 0x05 -.emtcode OP_TEX_SAMPLE 0x06 -.emtcode OP_TEX_KIL 0x07 - -/* GL_ARB_vertex_program instruction type */ -.emtcode OP_ALU_ARL 0x08 -/* OP_ALU_VECTOR */ -/* OP_ALU_SCALAR */ -/* OP_ALU_BINSC */ -/* OP_ALU_BIN */ -/* OP_ALU_TRI */ -/* OP_ALU_SWZ */ - -/* GL_ARB_fragment_program instruction code */ -.emtcode OP_ABS 0x00 -.emtcode OP_ABS_SAT 0x1B -.emtcode OP_FLR 0x09 -.emtcode OP_FLR_SAT 0x26 -.emtcode OP_FRC 0x0A -.emtcode OP_FRC_SAT 0x27 -.emtcode OP_LIT 0x0C -.emtcode OP_LIT_SAT 0x2A -.emtcode OP_MOV 0x11 -.emtcode OP_MOV_SAT 0x30 -.emtcode OP_COS 0x1F -.emtcode OP_COS_SAT 0x20 -.emtcode OP_EX2 0x07 -.emtcode OP_EX2_SAT 0x25 -.emtcode OP_LG2 0x0B -.emtcode OP_LG2_SAT 0x29 -.emtcode OP_RCP 0x14 -.emtcode OP_RCP_SAT 0x33 -.emtcode OP_RSQ 0x15 -.emtcode OP_RSQ_SAT 0x34 -.emtcode OP_SIN 0x38 -.emtcode OP_SIN_SAT 0x39 -.emtcode OP_SCS 0x35 -.emtcode OP_SCS_SAT 0x36 -.emtcode OP_POW 0x13 -.emtcode OP_POW_SAT 0x32 -.emtcode OP_ADD 0x01 -.emtcode OP_ADD_SAT 0x1C -.emtcode OP_DP3 0x03 -.emtcode OP_DP3_SAT 0x21 -.emtcode OP_DP4 0x04 -.emtcode OP_DP4_SAT 0x22 -.emtcode OP_DPH 0x05 -.emtcode OP_DPH_SAT 0x23 -.emtcode OP_DST 0x06 -.emtcode OP_DST_SAT 0x24 -.emtcode OP_MAX 0x0F -.emtcode OP_MAX_SAT 0x2E -.emtcode OP_MIN 0x10 -.emtcode OP_MIN_SAT 0x2F -.emtcode OP_MUL 0x12 -.emtcode OP_MUL_SAT 0x31 -.emtcode OP_SGE 0x16 -.emtcode OP_SGE_SAT 0x37 -.emtcode OP_SLT 0x17 -.emtcode OP_SLT_SAT 0x3A -.emtcode OP_SUB 0x18 -.emtcode OP_SUB_SAT 0x3B -.emtcode OP_XPD 0x1A -.emtcode OP_XPD_SAT 0x43 -.emtcode OP_CMP 0x1D -.emtcode OP_CMP_SAT 0x1E -.emtcode OP_LRP 0x2B -.emtcode OP_LRP_SAT 0x2C -.emtcode OP_MAD 0x0E -.emtcode OP_MAD_SAT 0x2D -.emtcode OP_SWZ 0x19 -.emtcode OP_SWZ_SAT 0x3C -.emtcode OP_TEX 0x3D -.emtcode OP_TEX_SAT 0x3E -.emtcode OP_TXB 0x3F -.emtcode OP_TXB_SAT 0x40 -.emtcode OP_TXP 0x41 -.emtcode OP_TXP_SAT 0x42 -.emtcode OP_KIL 0x28 - -/* GL_ARB_vertex_program instruction code */ -.emtcode OP_ARL 0x02 -/* OP_ABS */ -/* OP_FLR */ -/* OP_FRC */ -/* OP_LIT */ -/* OP_MOV */ -/* OP_EX2 */ -.emtcode OP_EXP 0x08 -/* OP_LG2 */ -.emtcode OP_LOG 0x0D -/* OP_RCP */ -/* OP_RSQ */ -/* OP_POW */ -/* OP_ADD */ -/* OP_DP3 */ -/* OP_DP4 */ -/* OP_DPH */ -/* OP_DST */ -/* OP_MAX */ -/* OP_MIN */ -/* OP_MUL */ -/* OP_SGE */ -/* OP_SLT */ -/* OP_SUB */ -/* OP_XPD */ -/* OP_MAD */ -/* OP_SWZ */ - -/* fragment attribute binding */ -.emtcode FRAGMENT_ATTRIB_COLOR 0x01 -.emtcode FRAGMENT_ATTRIB_TEXCOORD 0x02 -.emtcode FRAGMENT_ATTRIB_FOGCOORD 0x03 -.emtcode FRAGMENT_ATTRIB_POSITION 0x04 - -/* vertex attribute binding */ -.emtcode VERTEX_ATTRIB_POSITION 0x01 -.emtcode VERTEX_ATTRIB_WEIGHT 0x02 -.emtcode VERTEX_ATTRIB_NORMAL 0x03 -.emtcode VERTEX_ATTRIB_COLOR 0x04 -.emtcode VERTEX_ATTRIB_FOGCOORD 0x05 -.emtcode VERTEX_ATTRIB_TEXCOORD 0x06 -.emtcode VERTEX_ATTRIB_MATRIXINDEX 0x07 -.emtcode VERTEX_ATTRIB_GENERIC 0x08 - -/* fragment result binding */ -.emtcode FRAGMENT_RESULT_COLOR 0x01 -.emtcode FRAGMENT_RESULT_DEPTH 0x02 - -/* vertex result binding */ -.emtcode VERTEX_RESULT_POSITION 0x01 -.emtcode VERTEX_RESULT_COLOR 0x02 -.emtcode VERTEX_RESULT_FOGCOORD 0x03 -.emtcode VERTEX_RESULT_POINTSIZE 0x04 -.emtcode VERTEX_RESULT_TEXCOORD 0x05 - -/* texture target */ -.emtcode TEXTARGET_1D 0x01 -.emtcode TEXTARGET_2D 0x02 -.emtcode TEXTARGET_3D 0x03 -.emtcode TEXTARGET_RECT 0x04 -.emtcode TEXTARGET_CUBE 0x05 -/* GL_ARB_fragment_program_shadow */ -.emtcode TEXTARGET_SHADOW1D 0x06 -.emtcode TEXTARGET_SHADOW2D 0x07 -.emtcode TEXTARGET_SHADOWRECT 0x08 -/* GL_MESA_texture_array */ -.emtcode TEXTARGET_1D_ARRAY 0x09 -.emtcode TEXTARGET_2D_ARRAY 0x0a -.emtcode TEXTARGET_SHADOW1D_ARRAY 0x0b -.emtcode TEXTARGET_SHADOW2D_ARRAY 0x0c - -/* face type */ -.emtcode FACE_FRONT 0x00 -.emtcode FACE_BACK 0x01 - -/* color type */ -.emtcode COLOR_PRIMARY 0x00 -.emtcode COLOR_SECONDARY 0x01 - -/* component */ -.emtcode COMPONENT_X 0x00 -.emtcode COMPONENT_Y 0x01 -.emtcode COMPONENT_Z 0x02 -.emtcode COMPONENT_W 0x03 -.emtcode COMPONENT_0 0x04 -.emtcode COMPONENT_1 0x05 - -/* array index type */ -.emtcode ARRAY_INDEX_ABSOLUTE 0x00 -.emtcode ARRAY_INDEX_RELATIVE 0x01 - -/* matrix name */ -.emtcode MATRIX_MODELVIEW 0x01 -.emtcode MATRIX_PROJECTION 0x02 -.emtcode MATRIX_MVP 0x03 -.emtcode MATRIX_TEXTURE 0x04 -.emtcode MATRIX_PALETTE 0x05 -.emtcode MATRIX_PROGRAM 0x06 - -/* matrix modifier */ -.emtcode MATRIX_MODIFIER_IDENTITY 0x00 -.emtcode MATRIX_MODIFIER_INVERSE 0x01 -.emtcode MATRIX_MODIFIER_TRANSPOSE 0x02 -.emtcode MATRIX_MODIFIER_INVTRANS 0x03 - -/* constant type */ -.emtcode CONSTANT_SCALAR 0x01 -.emtcode CONSTANT_VECTOR 0x02 - -/* program param type */ -.emtcode PROGRAM_PARAM_ENV 0x01 -.emtcode PROGRAM_PARAM_LOCAL 0x02 - -/* register type */ -.emtcode REGISTER_ATTRIB 0x01 -.emtcode REGISTER_PARAM 0x02 -.emtcode REGISTER_RESULT 0x03 -.emtcode REGISTER_ESTABLISHED_NAME 0x04 - -/* param binding */ -.emtcode PARAM_NULL 0x00 -.emtcode PARAM_ARRAY_ELEMENT 0x01 -.emtcode PARAM_STATE_ELEMENT 0x02 -.emtcode PARAM_PROGRAM_ELEMENT 0x03 -.emtcode PARAM_PROGRAM_ELEMENTS 0x04 -.emtcode PARAM_CONSTANT 0x05 - -/* param state property */ -.emtcode STATE_MATERIAL 0x01 -.emtcode STATE_LIGHT 0x02 -.emtcode STATE_LIGHT_MODEL 0x03 -.emtcode STATE_LIGHT_PROD 0x04 -.emtcode STATE_FOG 0x05 -.emtcode STATE_MATRIX_ROWS 0x06 -/* GL_ARB_fragment_program */ -.emtcode STATE_TEX_ENV 0x07 -.emtcode STATE_DEPTH 0x08 -/* GL_ARB_vertex_program */ -.emtcode STATE_TEX_GEN 0x09 -.emtcode STATE_CLIP_PLANE 0x0A -.emtcode STATE_POINT 0x0B - -/* state material property */ -.emtcode MATERIAL_AMBIENT 0x01 -.emtcode MATERIAL_DIFFUSE 0x02 -.emtcode MATERIAL_SPECULAR 0x03 -.emtcode MATERIAL_EMISSION 0x04 -.emtcode MATERIAL_SHININESS 0x05 - -/* state light property */ -.emtcode LIGHT_AMBIENT 0x01 -.emtcode LIGHT_DIFFUSE 0x02 -.emtcode LIGHT_SPECULAR 0x03 -.emtcode LIGHT_POSITION 0x04 -.emtcode LIGHT_ATTENUATION 0x05 -.emtcode LIGHT_HALF 0x06 -.emtcode LIGHT_SPOT_DIRECTION 0x07 - -/* state light model property */ -.emtcode LIGHT_MODEL_AMBIENT 0x01 -.emtcode LIGHT_MODEL_SCENECOLOR 0x02 - -/* state light product property */ -.emtcode LIGHT_PROD_AMBIENT 0x01 -.emtcode LIGHT_PROD_DIFFUSE 0x02 -.emtcode LIGHT_PROD_SPECULAR 0x03 - -/* state texture environment property */ -.emtcode TEX_ENV_COLOR 0x01 - -/* state texture generation coord property */ -.emtcode TEX_GEN_EYE 0x01 -.emtcode TEX_GEN_OBJECT 0x02 - -/* state fog property */ -.emtcode FOG_COLOR 0x01 -.emtcode FOG_PARAMS 0x02 - -/* state depth property */ -.emtcode DEPTH_RANGE 0x01 - -/* state point parameters property */ -.emtcode POINT_SIZE 0x01 -.emtcode POINT_ATTENUATION 0x02 - -/* declaration */ -.emtcode ATTRIB 0x01 -.emtcode PARAM 0x02 -.emtcode TEMP 0x03 -.emtcode OUTPUT 0x04 -.emtcode ALIAS 0x05 -/* GL_ARB_vertex_program */ -.emtcode ADDRESS 0x06 - -/* error messages */ -.errtext UNKNOWN_PROGRAM_SIGNATURE "1001: '$e_signature$': unknown program signature" -.errtext MISSING_END_OR_INVALID_STATEMENT "1002: '$e_statement$': invalid statement" -.errtext CODE_AFTER_END "1003: '$e_statement$': code after 'END' keyword" -.errtext INVALID_PROGRAM_OPTION "1004: '$e_identifier$': invalid program option" -.errtext EXT_SWIZ_COMP_EXPECTED "1005: extended swizzle component expected but '$e_token$' found" -.errtext TEX_TARGET_EXPECTED "1006: texture target expected but '$e_token$' found" -.errtext TEXTURE_EXPECTED "1007: 'texture' expected but '$e_identifier$' found" -.errtext SOURCE_REGISTER_EXPECTED "1008: source register expected but '$e_token$' found" -.errtext DESTINATION_REGISTER_EXPECTED "1009: destination register expected but '$e_token$' found" -.errtext INVALID_ADDRESS_COMPONENT "1010: '$e_identifier$': invalid address component" -.errtext INVALID_ADDRESS_WRITEMASK "1011: '$e_identifier$': invalid address writemask" -.errtext INVALID_COMPONENT "1012: '$e_charordigit$': invalid component" -.errtext INVALID_SUFFIX "1013: '$e_identifier$': invalid suffix" -.errtext INVALID_WRITEMASK "1014: '$e_identifier$': invalid writemask" -.errtext FRAGMENT_EXPECTED "1015: 'fragment' expected but '$e_identifier$' found" -.errtext VERTEX_EXPECTED "1016: 'vertex' expected but '$e_identifier$' found" -.errtext INVALID_FRAGMENT_PROPERTY "1017: '$e_identifier$': invalid fragment property" -.errtext INVALID_VERTEX_PROPERTY "1018: '$e_identifier$': invalid vertex property" -.errtext INVALID_STATE_PROPERTY "1019: '$e_identifier$': invalid state property" -.errtext INVALID_MATERIAL_PROPERTY "1020: '$e_identifier$': invalid material property" -.errtext INVALID_LIGHT_PROPERTY "1021: '$e_identifier$': invalid light property" -.errtext INVALID_SPOT_PROPERTY "1022: '$e_identifier$': invalid spot property" -.errtext INVALID_LIGHTMODEL_PROPERTY "1023: '$e_identifier$': invalid light model property" -.errtext INVALID_LIGHTPROD_PROPERTY "1024: '$e_identifier$': invalid light product property" -.errtext INVALID_TEXENV_PROPERTY "1025: '$e_identifier$': invalid texture environment property" -.errtext INVALID_TEXGEN_PROPERTY "1026: '$e_identifier$': invalid texture generating property" -.errtext INVALID_TEXGEN_COORD "1027: '$e_identifier$': invalid texture generating coord" -.errtext INVALID_FOG_PROPERTY "1028: '$e_identifier$': invalid fog property" -.errtext INVALID_DEPTH_PROPERTY "1029: '$e_identifier$': invalid depth property" -.errtext INVALID_CLIPPLANE_PROPERTY "1030: '$e_identifier$': invalid clip plane property" -.errtext INVALID_POINT_PROPERTY "1031: '$e_identifier$': invalid point property" -.errtext MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED "1032: matrix row selector or modifier expected but '$e_token$' found" -.errtext INVALID_MATRIX_NAME "1033: '$e_identifier$': invalid matrix name" -.errtext INVALID_PROGRAM_PROPERTY "1034: '$e_identifier$': invalid program property" -.errtext RESULT_EXPECTED "1035: 'result' expected but '$e_token$' found" -.errtext INVALID_RESULT_PROPERTY "1036: '$e_identifier$': invalid result property" -.errtext INVALID_FACE_PROPERTY "1037: '$e_identifier$': invalid face property" -.errtext INVALID_COLOR_PROPERTY "1038: '$e_identifier$': invalid color property" -.errtext IDENTIFIER_EXPECTED "1039: identifier expected but '$e_token$' found" -.errtext RESERVED_KEYWORD "1040: use of reserved keyword as an identifier" -.errtext INTEGER_EXPECTED "1041: integer value expected but '$e_token$' found" -.errtext MISSING_SEMICOLON "1042: ';' expected but '$e_token$' found" -.errtext MISSING_COMMA "1043: ',' expected but '$e_token$' found" -.errtext MISSING_LBRACKET "1044: '[' expected but '$e_token$' found" -.errtext MISSING_RBRACKET "1045: ']' expected but '$e_token$' found" -.errtext MISSING_DOT "1046: '.' expected but '$e_token$' found" -.errtext MISSING_EQUAL "1047: '=' expected but '$e_token$' found" -.errtext MISSING_LBRACE "1048: '{' expected but '$e_token$' found" -.errtext MISSING_RBRACE "1049: '}' expected but '$e_token$' found" -.errtext MISSING_DOTDOT "1050: '..' expected but '$e_token$' found" -.errtext MISSING_FRACTION_OR_EXPONENT "1051: missing fraction part or exponent" -.errtext MISSING_DOT_OR_EXPONENT "1052: missing '.' or exponent" -.errtext EXPONENT_VALUE_EXPECTED "1053: exponent value expected" -.errtext INTEGER_OUT_OF_RANGE "1054: integer value out of range" -.errtext OPERATION_NEEDS_DESTINATION_VARIABLE "1055: operation needs destination variable" -.errtext OPERATION_NEEDS_SOURCE_VARIABLE "1056: operation needs source variable" -.errtext ADDRESS_REGISTER_EXPECTED "1057: address register expected but '$e_token$' found" -.errtext ADDRESS_REGISTER_OR_INTEGER_EXPECTED "1058: address register or integer literal expected but '$e_token$' found" - -/* extension presence condition registers */ - -/* GL_ARB_vertex_blend */ -/* GL_EXT_vertex_weighting */ -.regbyte vertex_blend 0x00 - -/* GL_ARB_matrix_palette */ -.regbyte matrix_palette 0x00 - -/* GL_ARB_point_parameters */ -/* GL_EXT_point_parameters */ -.regbyte point_parameters 0x00 - -/* GL_EXT_secondary_color */ -.regbyte secondary_color 0x00 - -/* GL_EXT_fog_coord */ -.regbyte fog_coord 0x00 - -/* GL_EXT_texture_rectangle */ -/* GL_NV_texture_rectangle */ -.regbyte texture_rectangle 0x00 - -/* GL_ARB_fragment_program_shadow */ -.regbyte fragment_program_shadow 0x00 - -/* GL_ARB_draw_buffers */ -.regbyte draw_buffers 0x00 - -/* GL_MESA_texture_array */ -.regbyte texture_array 0x00 - -/* option presence condition registers */ -/* they are all initially set to zero - when a particular OPTION is encountered, the appropriate */ -/* register is set to 1 to indicate that the OPTION was specified. */ - -/* GL_ARB_fragment_program */ -.regbyte ARB_precision_hint_fastest 0x00 -.regbyte ARB_precision_hint_nicest 0x00 -.regbyte ARB_fog_exp 0x00 -.regbyte ARB_fog_exp2 0x00 -.regbyte ARB_fog_linear 0x00 - -/* GL_ARB_vertex_program */ -.regbyte ARB_position_invariant 0x00 - -/* GL_ARB_fragment_program_shadow */ -.regbyte ARB_fragment_program_shadow 0x00 - -/* GL_ARB_draw_buffers */ -.regbyte ARB_draw_buffers 0x00 - -/* GL_MESA_texture_array */ -.regbyte MESA_texture_array 0x00 - -/* program target condition register */ -/* this syntax script deals with two program targets - VERTEX_PROGRAM and FRAGMENT_PROGRAM. */ -/* to distinguish between them we need a register that will store for us the current target. */ -/* the client will typically set the register to apropriate value before parsing a particular */ -/* program. the mapping between program targets and their values is listed below. */ -/* */ -/* program target register value */ -/* ---------------------------------------------- */ -/* FRAGMENT_PROGRAM 0x10 */ -/* VERTEX_PROGRAM 0x20 */ -/* */ -/* the initial value of the register is 0 to catch potential errors with not setting the register */ -/* with the proper value. */ -.regbyte program_target 0x00 - -/* - <program> ::= <optionSequence> <statementSequence> "END" -*/ -program - programs .error UNKNOWN_PROGRAM_SIGNATURE .emit REVISION; -programs - .if (program_target == 0x10) frag_program_1_0 .emit FRAGMENT_PROGRAM .emit 0x01 .emit 0x00 .or - .if (program_target == 0x20) vert_program_1_0 .emit VERTEX_PROGRAM .emit 0x01 .emit 0x00; -frag_program_1_0 - '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'f' .and 'p' .and '1' .and '.' .and '0' .and - optional_space .and fp_optionSequence .and fp_statementSequence .and - "END" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and - '\0' .error CODE_AFTER_END; -vert_program_1_0 - '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'v' .and 'p' .and '1' .and '.' .and '0' .and - optional_space .and vp_optionSequence .and vp_statementSequence .and - "END" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and - '\0' .error CODE_AFTER_END; - -/* - <optionSequence> ::= <optionSequence> <option> - | "" -*/ -fp_optionSequence - .loop fp_option; -vp_optionSequence - .loop vp_option; - -/* - <option> ::= "OPTION" <identifier> ";" - -NOTE: options ARB_precision_hint_nicest and ARB_precision_hint_fastest are exclusive. When one of - these options is encountered, the other one is automatically disabled. - the same applies to options ARB_fog_exp, ARB_fog_exp2 and ARB_fog_linear. -*/ -fp_option - "OPTION" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and - fp_optionString .error INVALID_PROGRAM_OPTION .and semicolon; -vp_option - "OPTION" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and - vp_optionString .error INVALID_PROGRAM_OPTION .and semicolon; -fp_optionString - .if (ARB_precision_hint_nicest == 0x00) "ARB_precision_hint_fastest" - .emit ARB_PRECISION_HINT_FASTEST .load ARB_precision_hint_fastest 0x01 .or - .if (ARB_precision_hint_fastest == 0x00) "ARB_precision_hint_nicest" - .emit ARB_PRECISION_HINT_NICEST .load ARB_precision_hint_nicest 0x01 .or - fp_ARB_fog_exp .emit ARB_FOG_EXP .load ARB_fog_exp 0x01 .or - fp_ARB_fog_exp2 .emit ARB_FOG_EXP2 .load ARB_fog_exp2 0x01 .or - fp_ARB_fog_linear .emit ARB_FOG_LINEAR .load ARB_fog_linear 0x01 .or - .if (fragment_program_shadow != 0x00) "ARB_fragment_program_shadow" - .emit ARB_FRAGMENT_PROGRAM_SHADOW .load ARB_fragment_program_shadow 0x01 .or - .if (draw_buffers != 0x00) "ARB_draw_buffers" .emit ARB_DRAW_BUFFERS - .load ARB_draw_buffers 0x01 .or - .if (texture_array != 0x00) "MESA_texture_array" .emit MESA_TEXTURE_ARRAY - .load MESA_texture_array 0x01; -vp_optionString - "ARB_position_invariant" .emit ARB_POSITION_INVARIANT .load ARB_position_invariant 0x01; -fp_ARB_fog_exp - .if (ARB_fog_exp2 == 0x00) .true .and .if (ARB_fog_linear == 0x00) "ARB_fog_exp"; -fp_ARB_fog_exp2 - .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_linear == 0x00) "ARB_fog_exp2"; -fp_ARB_fog_linear - .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_exp2 == 0x00) "ARB_fog_linear"; - -/* - <statementSequence> ::= <statementSequence> <statement> - | "" -*/ -fp_statementSequence - .loop fp_statement; -vp_statementSequence - .loop vp_statement; - -/* - <statement> ::= <instruction> ";" - | <namingStatement> ";" - -NOTE: ".emit $" in the definitions below means that we output instruction position (offset of - the first character of instruction) for program debugging purposes. -*/ -fp_statement - fp_statement_1 .or fp_statement_2; -vp_statement - vp_statement_1 .or vp_statement_2; -fp_statement_1 - fp_instruction .emit INSTRUCTION .emit $ .and semicolon; -fp_statement_2 - fp_namingStatement .emit DECLARATION .and semicolon; -vp_statement_1 - vp_instruction .emit INSTRUCTION .emit $ .and semicolon; -vp_statement_2 - vp_namingStatement .emit DECLARATION .and semicolon; - -/* -fragment program - <instruction> ::= <ALUInstruction> - | <TexInstruction> - -vertex program - <instruction> ::= <ARL_instruction> - | <VECTORop_instruction> - | <SCALARop_instruction> - | <BINSCop_instruction> - | <BINop_instruction> - | <TRIop_instruction> - | <SWZ_instruction> -*/ -fp_instruction - ALUInstruction .emit OP_ALU_INST .or - TexInstruction .emit OP_TEX_INST; -vp_instruction - ARL_instruction .emit OP_ALU_ARL .or - vp_VECTORop_instruction .emit OP_ALU_VECTOR .or - vp_SCALARop_instruction .emit OP_ALU_SCALAR .or - vp_BINSCop_instruction .emit OP_ALU_BINSC .or - vp_BINop_instruction .emit OP_ALU_BIN .or - vp_TRIop_instruction .emit OP_ALU_TRI .or - vp_SWZ_instruction .emit OP_ALU_SWZ; - -/* -fragment program - <ALUInstruction> ::= <VECTORop_instruction> - | <SCALARop_instruction> - | <BINSCop_instruction> - | <BINop_instruction> - | <TRIop_instruction> - | <SWZ_instruction> -*/ -ALUInstruction - fp_VECTORop_instruction .emit OP_ALU_VECTOR .or - fp_SCALARop_instruction .emit OP_ALU_SCALAR .or - fp_BINSCop_instruction .emit OP_ALU_BINSC .or - fp_BINop_instruction .emit OP_ALU_BIN .or - fp_TRIop_instruction .emit OP_ALU_TRI .or - fp_SWZ_instruction .emit OP_ALU_SWZ; - -/* -fragment program - <TexInstruction> ::= <SAMPLE_instruction> - | <KIL_instruction> -*/ -TexInstruction - SAMPLE_instruction .emit OP_TEX_SAMPLE .or - KIL_instruction .emit OP_TEX_KIL; - -/* -vertex program - <ARL_instruction> ::= "ARL" <maskedAddrReg> "," <scalarSrcReg> -*/ -ARL_instruction - "ARL" .emit OP_ARL .and space_dst .and maskedAddrReg .and comma .and vp_scalarSrcReg; - -/* -fragment program - <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," - <vectorSrcReg> - -vertex program - <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," <swizzleSrcReg> -*/ -fp_VECTORop_instruction - fp_VECTORop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg; -vp_VECTORop_instruction - vp_VECTORop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg; - -/* -fragment program - <VECTORop> ::= "ABS" | "ABS_SAT" - | "FLR" | "FLR_SAT" - | "FRC" | "FRC_SAT" - | "LIT" | "LIT_SAT" - | "MOV" | "MOV_SAT" - -vertex program - <VECTORop> ::= "ABS" - | "FLR" - | "FRC" - | "LIT" - | "MOV" -*/ -fp_VECTORop - "ABS" .emit OP_ABS .or "ABS_SAT" .emit OP_ABS_SAT .or - "FLR" .emit OP_FLR .or "FLR_SAT" .emit OP_FLR_SAT .or - "FRC" .emit OP_FRC .or "FRC_SAT" .emit OP_FRC_SAT .or - "LIT" .emit OP_LIT .or "LIT_SAT" .emit OP_LIT_SAT .or - "MOV" .emit OP_MOV .or "MOV_SAT" .emit OP_MOV_SAT; -vp_VECTORop - "ABS" .emit OP_ABS .or - "FLR" .emit OP_FLR .or - "FRC" .emit OP_FRC .or - "LIT" .emit OP_LIT .or - "MOV" .emit OP_MOV; - -/* - <SCALARop_instruction> ::= <SCALARop> <maskedDstReg> "," <scalarSrcReg> -*/ -fp_SCALARop_instruction - fp_SCALARop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg; -vp_SCALARop_instruction - vp_SCALARop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg; - -/* -fragment program - <SCALARop> ::= "COS" | "COS_SAT" - | "EX2" | "EX2_SAT" - | "LG2" | "LG2_SAT" - | "RCP" | "RCP_SAT" - | "RSQ" | "RSQ_SAT" - | "SIN" | "SIN_SAT" - | "SCS" | "SCS_SAT" - -vertex program - <SCALARop> ::= "EX2" - | "EXP" - | "LG2" - | "LOG" - | "RCP" - | "RSQ" -*/ -fp_SCALARop - "COS" .emit OP_COS .or "COS_SAT" .emit OP_COS_SAT .or - "EX2" .emit OP_EX2 .or "EX2_SAT" .emit OP_EX2_SAT .or - "LG2" .emit OP_LG2 .or "LG2_SAT" .emit OP_LG2_SAT .or - "RCP" .emit OP_RCP .or "RCP_SAT" .emit OP_RCP_SAT .or - "RSQ" .emit OP_RSQ .or "RSQ_SAT" .emit OP_RSQ_SAT .or - "SIN" .emit OP_SIN .or "SIN_SAT" .emit OP_SIN_SAT .or - "SCS" .emit OP_SCS .or "SCS_SAT" .emit OP_SCS_SAT; -vp_SCALARop - "EX2" .emit OP_EX2 .or - "EXP" .emit OP_EXP .or - "LG2" .emit OP_LG2 .or - "LOG" .emit OP_LOG .or - "RCP" .emit OP_RCP .or - "RSQ" .emit OP_RSQ; - -/* - <BINSCop_instruction> ::= <BINSCop> <maskedDstReg> "," <scalarSrcReg> "," - <scalarSrcReg> -*/ -fp_BINSCop_instruction - fp_BINSCop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg .and comma .and - fp_scalarSrcReg; -vp_BINSCop_instruction - vp_BINSCop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg .and comma .and - vp_scalarSrcReg; - -/* -fragment program - <BINSCop> ::= "POW" | "POW_SAT" - -vertex program - <BINSCop> ::= "POW" -*/ -fp_BINSCop - "POW" .emit OP_POW .or "POW_SAT" .emit OP_POW_SAT; -vp_BINSCop - "POW" .emit OP_POW; - -/* -fragment program - <BINop_instruction> ::= <BINop> <maskedDstReg> "," - <vectorSrcReg> "," <vectorSrcReg> - -vertex program - <BINop_instruction> ::= <BINop> <maskedDstReg> "," - <swizzleSrcReg> "," <swizzleSrcReg> -*/ -fp_BINop_instruction - fp_BINop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and - vectorSrcReg; -vp_BINop_instruction - vp_BINop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and - swizzleSrcReg; - -/* -fragment program - <BINop> ::= "ADD" | "ADD_SAT" - | "DP3" | "DP3_SAT" - | "DP4" | "DP4_SAT" - | "DPH" | "DPH_SAT" - | "DST" | "DST_SAT" - | "MAX" | "MAX_SAT" - | "MIN" | "MIN_SAT" - | "MUL" | "MUL_SAT" - | "SGE" | "SGE_SAT" - | "SLT" | "SLT_SAT" - | "SUB" | "SUB_SAT" - | "XPD" | "XPD_SAT" - -vertex program - <BINop> ::= "ADD" - | "DP3" - | "DP4" - | "DPH" - | "DST" - | "MAX" - | "MIN" - | "MUL" - | "SGE" - | "SLT" - | "SUB" - | "XPD" -*/ -fp_BINop - "ADD" .emit OP_ADD .or "ADD_SAT" .emit OP_ADD_SAT .or - "DP3" .emit OP_DP3 .or "DP3_SAT" .emit OP_DP3_SAT .or - "DP4" .emit OP_DP4 .or "DP4_SAT" .emit OP_DP4_SAT .or - "DPH" .emit OP_DPH .or "DPH_SAT" .emit OP_DPH_SAT .or - "DST" .emit OP_DST .or "DST_SAT" .emit OP_DST_SAT .or - "MAX" .emit OP_MAX .or "MAX_SAT" .emit OP_MAX_SAT .or - "MIN" .emit OP_MIN .or "MIN_SAT" .emit OP_MIN_SAT .or - "MUL" .emit OP_MUL .or "MUL_SAT" .emit OP_MUL_SAT .or - "SGE" .emit OP_SGE .or "SGE_SAT" .emit OP_SGE_SAT .or - "SLT" .emit OP_SLT .or "SLT_SAT" .emit OP_SLT_SAT .or - "SUB" .emit OP_SUB .or "SUB_SAT" .emit OP_SUB_SAT .or - "XPD" .emit OP_XPD .or "XPD_SAT" .emit OP_XPD_SAT; -vp_BINop - "ADD" .emit OP_ADD .or - "DP3" .emit OP_DP3 .or - "DP4" .emit OP_DP4 .or - "DPH" .emit OP_DPH .or - "DST" .emit OP_DST .or - "MAX" .emit OP_MAX .or - "MIN" .emit OP_MIN .or - "MUL" .emit OP_MUL .or - "SGE" .emit OP_SGE .or - "SLT" .emit OP_SLT .or - "SUB" .emit OP_SUB .or - "XPD" .emit OP_XPD; - -/* -fragment program - <TRIop_instruction> ::= <TRIop> <maskedDstReg> "," - <vectorSrcReg> "," <vectorSrcReg> "," - <vectorSrcReg> - -vertex program - <TRIop_instruction> ::= <TRIop> <maskedDstReg> "," - <swizzleSrcReg> "," <swizzleSrcReg> "," - <swizzleSrcReg> -*/ -fp_TRIop_instruction - fp_TRIop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and - vectorSrcReg .and comma .and vectorSrcReg; -vp_TRIop_instruction - vp_TRIop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and - swizzleSrcReg .and comma .and swizzleSrcReg; - -/* -fragment program - <TRIop> ::= "CMP" | "CMP_SAT" - | "LRP" | "LRP_SAT" - | "MAD" | "MAD_SAT" - -vertex program - <TRIop> ::= "MAD" -*/ -fp_TRIop - "CMP" .emit OP_CMP .or "CMP_SAT" .emit OP_CMP_SAT .or - "LRP" .emit OP_LRP .or "LRP_SAT" .emit OP_LRP_SAT .or - "MAD" .emit OP_MAD .or "MAD_SAT" .emit OP_MAD_SAT; -vp_TRIop - "MAD" .emit OP_MAD; - -/* -fragment program - <SWZ_instruction> ::= <SWZop> <maskedDstReg> "," - <srcReg> "," <extendedSwizzle> - -vertex program - <SWZ_instruction> ::= "SWZ" <maskedDstReg> "," <srcReg> "," - <extendedSwizzle> -*/ -fp_SWZ_instruction - SWZop .and space_dst .and fp_maskedDstReg .and comma .and fp_srcReg .and comma .and - fp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED; -vp_SWZ_instruction - "SWZ" .emit OP_SWZ .and space_dst .and vp_maskedDstReg .and comma .and vp_srcReg .and comma .and - vp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED; - -/* -fragment program - <SWZop> ::= "SWZ" | "SWZ_SAT" -*/ -SWZop - "SWZ" .emit OP_SWZ .or "SWZ_SAT" .emit OP_SWZ_SAT; - -/* -fragment program - <SAMPLE_instruction> ::= <SAMPLEop> <maskedDstReg> "," - <vectorSrcReg> "," <texImageUnit> "," - <texTarget> -*/ -SAMPLE_instruction - SAMPLEop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and - texImageUnit .and comma .and texTarget .error TEX_TARGET_EXPECTED; - -/* -fragment program - <SAMPLEop> ::= "TEX" | "TEX_SAT" - | "TXP" | "TXP_SAT" - | "TXB" | "TXB_SAT" -*/ -SAMPLEop - "TEX" .emit OP_TEX .or "TEX_SAT" .emit OP_TEX_SAT .or - "TXB" .emit OP_TXB .or "TXB_SAT" .emit OP_TXB_SAT .or - "TXP" .emit OP_TXP .or "TXP_SAT" .emit OP_TXP_SAT; - -/* -fragment program - <KIL_instruction> ::= "KIL" <vectorSrcReg> -*/ -KIL_instruction - "KIL" .emit OP_KIL .and space_src .and vectorSrcReg; - -/* -fragment program - <texImageUnit> ::= "texture" <optTexImageUnitNum> -*/ -texImageUnit - "texture" .error TEXTURE_EXPECTED .and optTexImageUnitNum; - -/* -fragment program - <texTarget> ::= "1D" - | "2D" - | "3D" - | "CUBE" - | "RECT" - | <shadowTarget> (if option ARB_fragment_program_shadow present) - | <arrayTarget> (if option MESA_texture_array present) -*/ -texTarget - "1D" .emit TEXTARGET_1D .or - "2D" .emit TEXTARGET_2D .or - "3D" .emit TEXTARGET_3D .or - .if (texture_rectangle != 0x00) "RECT" .emit TEXTARGET_RECT .or - "CUBE" .emit TEXTARGET_CUBE .or - .if (ARB_fragment_program_shadow != 0x00) shadowTarget .or - .if (MESA_texture_array != 0x00) arrayTarget; - -/* -GL_ARB_fragment_program_shadow - <shadowTarget> ::= "SHADOW1D" - | "SHADOW2D" - | "SHADOWRECT" - | <shadowArrayTarget> (if option MESA_texture_array present) -*/ -shadowTarget - "SHADOW1D" .emit TEXTARGET_SHADOW1D .or - "SHADOW2D" .emit TEXTARGET_SHADOW2D .or - .if (texture_rectangle != 0x00) "SHADOWRECT" .emit TEXTARGET_SHADOWRECT .or - .if (MESA_texture_array != 0x00) shadowArrayTarget; - -/* -GL_MESA_texture_array - - <arrayTarget> ::= "ARRAY1D" - | "ARRAY2D" - - <shadowArrayTarget> ::= "SHADOWARRAY1D" - | "SHADOWARRAY2D" -*/ - -arrayTarget - "ARRAY1D" .emit TEXTARGET_1D_ARRAY .or - "ARRAY2D" .emit TEXTARGET_2D_ARRAY; - -shadowArrayTarget - "SHADOWARRAY1D" .emit TEXTARGET_SHADOW1D_ARRAY .or - "SHADOWARRAY2D" .emit TEXTARGET_SHADOW2D_ARRAY; - -/* -fragment program - <optTexImageUnitNum> ::= "" - | "[" <texImageUnitNum> "]" -*/ -optTexImageUnitNum - optTexImageUnitNum_1 .or .true .emit 0x00; -optTexImageUnitNum_1 - lbracket_ne .and texImageUnitNum .and rbracket; - -/* -fragment program - <texImageUnitNum> ::= <integer> from 0 to - MAX_TEXTURE_IMAGE_UNITS_ARB-1 -*/ -texImageUnitNum - integer; - -/* - <scalarSrcReg> ::= <optionalSign> <srcReg> <scalarSuffix> -*/ -fp_scalarSrcReg - optionalSign .and fp_srcReg .and fp_scalarSuffix; -vp_scalarSrcReg - optionalSign .and vp_srcReg .and vp_scalarSuffix; - -/* -vertex program - <swizzleSrcReg> ::= <optionalSign> <srcReg> <swizzleSuffix> -*/ -swizzleSrcReg - optionalSign .and vp_srcReg .and swizzleSuffix; - -/* -fragment program - <vectorSrcReg> ::= <optionalSign> <srcReg> <optionalSuffix> -*/ -vectorSrcReg - optionalSign .and fp_srcReg .and optionalSuffix; - -/* - <maskedDstReg> ::= <dstReg> <optionalMask> -*/ -fp_maskedDstReg - fp_dstReg .and fp_optionalMask; -vp_maskedDstReg - vp_dstReg .and vp_optionalMask; - -/* -vertex program - <maskedAddrReg> ::= <addrReg> <addrWriteMask> -*/ -maskedAddrReg - addrReg .error ADDRESS_REGISTER_EXPECTED .and addrWriteMask; - -/* -fragment program - <extendedSwizzle> ::= <xyzwExtendedSwizzle> - | <rgbaExtendedSwizzle> - -vertex program - <extendedSwizzle> ::= <extSwizComp> "," <extSwizComp> "," - <extSwizComp> "," <extSwizComp> - -NOTE: do NOT change the order of <rgbaExtendedSwizzle> and <xyzwExtendedSwizzle> rulez -*/ -fp_extendedSwizzle - rgbaExtendedSwizzle .or xyzwExtendedSwizzle; -vp_extendedSwizzle - extSwizComp .and comma .and - extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and - extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and - extSwizComp .error EXT_SWIZ_COMP_EXPECTED; - -/* -fragment program - <xyzwExtendedSwizzle> ::= <xyzwExtSwizComp> "," <xyzwExtSwizComp> "," - <xyzwExtSwizComp> "," <xyzwExtSwizComp> -*/ -xyzwExtendedSwizzle - xyzwExtSwizComp .and comma .and - xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and - xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and - xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED; - -/* -fragment program - <rgbaExtendedSwizzle> ::= <rgbaExtSwizComp> "," <rgbaExtSwizComp> "," - <rgbaExtSwizComp> "," <rgbaExtSwizComp> -*/ -rgbaExtendedSwizzle - rgbaExtendedSwizzle_1 .or rgbaExtendedSwizzle_2 .or rgbaExtendedSwizzle_3 .or - rgbaExtendedSwizzle_4; -rgbaExtendedSwizzle_1 - rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and - rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp; -rgbaExtendedSwizzle_2 - rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and - rgbaExtSwizComp_alpha .and comma .and rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED; -rgbaExtendedSwizzle_3 - rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_alpha .and comma .and - rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and - rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED; -rgbaExtendedSwizzle_4 - rgbaExtSwizComp_alpha .and comma .and - rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and - rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and - rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED; - -/* -fragment program - <xyzwExtSwizComp> ::= <optionalSign> <xyzwExtSwizSel> -*/ -xyzwExtSwizComp - optionalSign .and xyzwExtSwizSel; - -/* -fragment program - <rgbaExtSwizComp> ::= <optionalSign> <rgbaExtSwizSel> -*/ -rgbaExtSwizComp - optionalSign .and rgbaExtSwizSel; -rgbaExtSwizComp_digit - optionalSign .and rgbaExtSwizSel_digit; -rgbaExtSwizComp_alpha - optionalSign .and rgbaExtSwizSel_alpha; - -/* -vertex program - <extSwizComp> ::= <optionalSign> <extSwizSel> -*/ -extSwizComp - optionalSign .and extSwizSel; - -/* -fragment program - <xyzwExtSwizSel> ::= "0" - | "1" - | <xyzwComponent> -*/ -xyzwExtSwizSel - "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1 .or xyzwComponent_single; - -/* -fragment program - <rgbaExtSwizSel> ::= "0" - | "1" - | <rgbaComponent> -*/ -rgbaExtSwizSel - rgbaExtSwizSel_digit .or rgbaExtSwizSel_alpha; -rgbaExtSwizSel_digit - "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1; -rgbaExtSwizSel_alpha - rgbaComponent_single; - -/* -vertex program - <extSwizSel> ::= "0" - | "1" - | <component> -*/ -extSwizSel - "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1 .or vp_component_single; - -/* -fragment program - <srcReg> ::= <fragmentAttribReg> - | <temporaryReg> - | <progParamReg> - -vertex program - <srcReg> ::= <vertexAttribReg> - | <temporaryReg> - | <progParamReg> -*/ -fp_srcReg - fp_srcReg_1 .error SOURCE_REGISTER_EXPECTED; -vp_srcReg - vp_srcReg_1 .error SOURCE_REGISTER_EXPECTED; -fp_srcReg_1 - fragmentAttribReg .emit REGISTER_ATTRIB .or - fp_progParamReg .emit REGISTER_PARAM .or - fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME; -vp_srcReg_1 - vertexAttribReg .emit REGISTER_ATTRIB .or - vp_progParamReg .emit REGISTER_PARAM .or - vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME; - -/* -fragment program - <dstReg> ::= <temporaryReg> - | <fragmentResultReg> - -vertex program - <dstReg> ::= <temporaryReg> - | <vertexResultReg> -*/ -fp_dstReg - fp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED; -vp_dstReg - vp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED; -fp_dstReg_1 - fragmentResultReg .emit REGISTER_RESULT .or - fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME; -vp_dstReg_1 - vertexResultReg .emit REGISTER_RESULT .or - vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME; - -/* -fragment program - <fragmentAttribReg> ::= <establishedName> - | <fragAttribBinding> - -NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg> -*/ -fragmentAttribReg - /*fp_establishedName .or */fragAttribBinding; - -/* -vertex program - <vertexAttribReg> ::= <establishedName> - | <vtxAttribBinding> - -NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg> -*/ -vertexAttribReg - vtxAttribBinding; - -/* - <temporaryReg> ::= <establishedName> -*/ -fp_temporaryReg - fp_establishedName_no_error_on_identifier; -vp_temporaryReg - vp_establishedName_no_error_on_identifier; - -/* -fragment program - <progParamReg> ::= <progParamSingle> - | <progParamArray> "[" <progParamArrayAbs> "]" - | <paramSingleItemUse> - -vertex program - <progParamReg> ::= <progParamSingle> - | <progParamArray> "[" <progParamArrayMem> "]" - | <paramSingleItemUse> -*/ -fp_progParamReg - fp_paramSingleItemUse .or fp_progParamReg_1 .or fp_progParamSingle; -vp_progParamReg - vp_paramSingleItemUse .or vp_progParamReg_1 .or vp_progParamSingle; -fp_progParamReg_1 - fp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayAbs .and - rbracket; -vp_progParamReg_1 - vp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayMem .and - rbracket; - -/* - <progParamSingle> ::= <establishedName> - -NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg> -*/ -fp_progParamSingle - .false; -vp_progParamSingle - .false; - -/* - <progParamArray> ::= <establishedName> -*/ -fp_progParamArray - fp_establishedName_no_error_on_identifier; -vp_progParamArray - vp_establishedName_no_error_on_identifier; - -/* -vertex program - <progParamArrayMem> ::= <progParamArrayAbs> - | <progParamArrayRel> -*/ -progParamArrayMem - progParamArrayAbs .or progParamArrayRel; - -/* - <progParamArrayAbs> ::= <integer> -*/ -progParamArrayAbs - integer_ne .emit ARRAY_INDEX_ABSOLUTE; - -/* -vertex program - <progParamArrayRel> ::= <addrReg> <addrComponent> <addrRegRelOffset> -*/ -progParamArrayRel - addrReg .error ADDRESS_REGISTER_OR_INTEGER_EXPECTED .emit ARRAY_INDEX_RELATIVE .and - addrComponent .and addrRegRelOffset; - -/* -vertex program - <addrRegRelOffset> ::= "" - | "+" <addrRegPosOffset> - | "-" <addrRegNegOffset> -*/ -addrRegRelOffset - addrRegRelOffset_1 .or addrRegRelOffset_2 .or .true .emit 0x00; -addrRegRelOffset_1 - plus_ne .and addrRegPosOffset; -addrRegRelOffset_2 - minus_ne .and addrRegNegOffset; - -/* -vertex program - <addrRegPosOffset> ::= <integer> from 0 to 63 -*/ -addrRegPosOffset - integer_0_63; - -/* -vertex program - <addrRegNegOffset> ::= <integer> from 0 to 64 -*/ -addrRegNegOffset - integer_0_64; - -/* -fragment program - <fragmentResultReg> ::= <establishedName> - | <resultBinding> - -NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <dstReg> -*/ -fragmentResultReg - fp_resultBinding; - -/* -vertex program - <vertexResultReg> ::= <establishedName> - | <resultBinding> - -NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <dstReg> -*/ -vertexResultReg - vp_resultBinding; - -/* -vertex program - <addrReg> ::= <establishedName> -*/ -addrReg - vp_establishedName_no_error_on_identifier; - -/* -vertex program - <addrComponent> ::= "." "x" -*/ -addrComponent - dot .and "x" .error INVALID_ADDRESS_COMPONENT .emit COMPONENT_X .emit COMPONENT_X - .emit COMPONENT_X .emit COMPONENT_X; - -/* -vertex program - <addrWriteMask> ::= "." "x" -*/ -addrWriteMask - dot .and "x" .error INVALID_ADDRESS_WRITEMASK .emit 0x08; - -/* - <scalarSuffix> ::= "." <component> -*/ -fp_scalarSuffix - dot .and fp_component_single .error INVALID_COMPONENT; -vp_scalarSuffix - dot .and vp_component_single .error INVALID_COMPONENT; - -/* -vertex program - <swizzleSuffix> ::= "" - | "." <component> - | "." <component> <component> - <component> <component> -*/ -swizzleSuffix - swizzleSuffix_1 .or - .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W; -swizzleSuffix_1 - dot_ne .and swizzleSuffix_2 .error INVALID_SUFFIX; -swizzleSuffix_2 - swizzleSuffix_3 .or swizzleSuffix_4; -swizzleSuffix_3 - vp_component_multi .and vp_component_multi .and vp_component_multi .error INVALID_COMPONENT .and - vp_component_multi .error INVALID_COMPONENT; -swizzleSuffix_4 - "x" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or - "y" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or - "z" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or - "w" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W; - -/* -fragment program - <optionalSuffix> ::= "" - | "." <component> - | "." <xyzwComponent> <xyzwComponent> - <xyzwComponent> <xyzwComponent> - | "." <rgbaComponent> <rgbaComponent> - <rgbaComponent> <rgbaComponent> -*/ -optionalSuffix - optionalSuffix_1 .or - .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W; -optionalSuffix_1 - dot_ne .and optionalSuffix_2 .error INVALID_SUFFIX; -optionalSuffix_2 - optionalSuffix_3 .or optionalSuffix_4 .or optionalSuffix_5; -optionalSuffix_3 - xyzwComponent_multi .and xyzwComponent_multi .and - xyzwComponent_multi .error INVALID_COMPONENT .and xyzwComponent_multi .error INVALID_COMPONENT; -optionalSuffix_4 - rgbaComponent_multi .and rgbaComponent_multi .and - rgbaComponent_multi .error INVALID_COMPONENT .and rgbaComponent_multi .error INVALID_COMPONENT; -optionalSuffix_5 - "x" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or - "y" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or - "z" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or - "w" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .or - "r" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or - "g" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or - "b" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or - "a" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W; - -/* -fragment program - <component> ::= <xyzwComponent> - | <rgbaComponent> - -vertex program - <component> ::= "x" - | "y" - | "z" - | "w" -*/ -fp_component_single - xyzwComponent_single .or rgbaComponent_single; -vp_component_multi - 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or - 'w' .emit COMPONENT_W; -vp_component_single - "x" .emit COMPONENT_X .or "y" .emit COMPONENT_Y .or "z" .emit COMPONENT_Z .or - "w" .emit COMPONENT_W; - -/* -fragment program - <xyzwComponent> ::= "x" | "y" | "z" | "w" -*/ -xyzwComponent_multi - 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or - 'w' .emit COMPONENT_W; -xyzwComponent_single - "x" .emit COMPONENT_X .or "y" .emit COMPONENT_Y .or "z" .emit COMPONENT_Z .or - "w" .emit COMPONENT_W; - -/* -fragment program - <rgbaComponent> ::= "r" | "g" | "b" | "a" -*/ -rgbaComponent_multi - 'r' .emit COMPONENT_X .or 'g' .emit COMPONENT_Y .or 'b' .emit COMPONENT_Z .or - 'a' .emit COMPONENT_W; -rgbaComponent_single - "r" .emit COMPONENT_X .or "g" .emit COMPONENT_Y .or "b" .emit COMPONENT_Z .or - "a" .emit COMPONENT_W; - -/* -fragment program - <optionalMask> ::= "" - | <xyzwMask> - | <rgbaMask> - -vertex program - <optionalMask> ::= "" - | "." "x" - | "." "y" - | "." "xy" - | "." "z" - | "." "xz" - | "." "yz" - | "." "xyz" - | "." "w" - | "." "xw" - | "." "yw" - | "." "xyw" - | "." "zw" - | "." "xzw" - | "." "yzw" - | "." "xyzw" - -NOTE: do NOT change the order of <rgbaMask> and <xyzwMask> rulez -*/ -fp_optionalMask - rgbaMask .or xyzwMask .or .true .emit 0x0F; -vp_optionalMask - xyzwMask .or .true .emit 0x0F; - -/* -fragment program - <xyzwMask> ::= "." "x" - | "." "y" - | "." "xy" - | "." "z" - | "." "xz" - | "." "yz" - | "." "xyz" - | "." "w" - | "." "xw" - | "." "yw" - | "." "xyw" - | "." "zw" - | "." "xzw" - | "." "yzw" - | "." "xyzw" - -NOTE: <xyzwMask> is also referenced by the vertex program symbol <optionalMask>. -*/ -xyzwMask - dot_ne .and xyzwMask_1 .error INVALID_WRITEMASK; -xyzwMask_1 - "xyzw" .emit 0x0F .or "xyz" .emit 0x0E .or "xyw" .emit 0x0D .or "xy" .emit 0x0C .or - "xzw" .emit 0x0B .or "xz" .emit 0x0A .or "xw" .emit 0x09 .or "x" .emit 0x08 .or - "yzw" .emit 0x07 .or "yz" .emit 0x06 .or "yw" .emit 0x05 .or "y" .emit 0x04 .or - "zw" .emit 0x03 .or "z" .emit 0x02 .or "w" .emit 0x01; - -/* -fragment program - <rgbaMask> ::= "." "r" - | "." "g" - | "." "rg" - | "." "b" - | "." "rb" - | "." "gb" - | "." "rgb" - | "." "a" - | "." "ra" - | "." "ga" - | "." "rga" - | "." "ba" - | "." "rba" - | "." "gba" - | "." "rgba" -*/ -rgbaMask - dot_ne .and rgbaMask_1; -rgbaMask_1 - "rgba" .emit 0x0F .or "rgb" .emit 0x0E .or "rga" .emit 0x0D .or "rg" .emit 0x0C .or - "rba" .emit 0x0B .or "rb" .emit 0x0A .or "ra" .emit 0x09 .or "r" .emit 0x08 .or - "gba" .emit 0x07 .or "gb" .emit 0x06 .or "ga" .emit 0x05 .or "g" .emit 0x04 .or - "ba" .emit 0x03 .or "b" .emit 0x02 .or "a" .emit 0x01; - -/* -fragment program - <namingStatement> ::= <ATTRIB_statement> - | <PARAM_statement> - | <TEMP_statement> - | <OUTPUT_statement> - | <ALIAS_statement> - -vertex program - <namingStatement> ::= <ATTRIB_statement> - | <PARAM_statement> - | <TEMP_statement> - | <ADDRESS_statement> - | <OUTPUT_statement> - | <ALIAS_statement> -*/ -fp_namingStatement - fp_ATTRIB_statement .emit ATTRIB .or - fp_PARAM_statement .emit PARAM .or - fp_TEMP_statement .emit TEMP .or - fp_OUTPUT_statement .emit OUTPUT .or - fp_ALIAS_statement .emit ALIAS; -vp_namingStatement - vp_ATTRIB_statement .emit ATTRIB .or - vp_PARAM_statement .emit PARAM .or - vp_TEMP_statement .emit TEMP .or - ADDRESS_statement .emit ADDRESS .or - vp_OUTPUT_statement .emit OUTPUT .or - vp_ALIAS_statement .emit ALIAS; - -/* -fragment program - <ATTRIB_statement> ::= "ATTRIB" <establishName> "=" - <fragAttribBinding> - -vertex program - <ATTRIB_statement> ::= "ATTRIB" <establishName> "=" - <vtxAttribBinding> -*/ -fp_ATTRIB_statement - "ATTRIB" .and space .and fp_establishName .and equal .and - fragAttribBinding .error FRAGMENT_EXPECTED; -vp_ATTRIB_statement - "ATTRIB" .and space .and vp_establishName .and equal .and - vtxAttribBinding .error VERTEX_EXPECTED; - -/* -fragment program - <fragAttribBinding> ::= "fragment" "." <fragAttribItem> -*/ -fragAttribBinding - "fragment" .and dot .and fragAttribItem .error INVALID_FRAGMENT_PROPERTY; - -/* -vertex program - <vtxAttribBinding> ::= "vertex" "." <vtxAttribItem> -*/ -vtxAttribBinding - "vertex" .and dot .and vtxAttribItem .error INVALID_VERTEX_PROPERTY; - -/* -fragment program - <fragAttribItem> ::= "color" <optColorType> - | "texcoord" <optTexCoordNum> - | "fogcoord" - | "position" -*/ -fragAttribItem - fragAttribItem_1 .emit FRAGMENT_ATTRIB_COLOR .or - fragAttribItem_2 .emit FRAGMENT_ATTRIB_TEXCOORD .or - .if (fog_coord != 0x00) "fogcoord" .emit FRAGMENT_ATTRIB_FOGCOORD .or - "position" .emit FRAGMENT_ATTRIB_POSITION; -fragAttribItem_1 - "color" .and optColorType; -fragAttribItem_2 - "texcoord" .and optTexCoordNum; - -/* -vertex program - <vtxAttribItem> ::= "position" - | "weight" <vtxOptWeightNum> - | "normal" - | "color" <optColorType> - | "fogcoord" - | "texcoord" <optTexCoordNum> - | "matrixindex" "[" <vtxWeightNum> "]" - | "attrib" "[" <vtxAttribNum> "]" -*/ -vtxAttribItem - "position" .emit VERTEX_ATTRIB_POSITION .or - .if (vertex_blend != 0x00) vtxAttribItem_1 .emit VERTEX_ATTRIB_WEIGHT .or - "normal" .emit VERTEX_ATTRIB_NORMAL .or - vtxAttribItem_2 .emit VERTEX_ATTRIB_COLOR .or - "fogcoord" .emit VERTEX_ATTRIB_FOGCOORD .or - vtxAttribItem_3 .emit VERTEX_ATTRIB_TEXCOORD .or - .if (matrix_palette != 0x00) vtxAttribItem_4 .emit VERTEX_ATTRIB_MATRIXINDEX .or - vtxAttribItem_5 .emit VERTEX_ATTRIB_GENERIC; -vtxAttribItem_1 - "weight" .and vtxOptWeightNum; -vtxAttribItem_2 - "color" .and optColorType; -vtxAttribItem_3 - "texcoord" .and optTexCoordNum; -vtxAttribItem_4 - "matrixindex" .and lbracket .and vtxWeightNum .and rbracket; -vtxAttribItem_5 - "attrib" .and lbracket .and vtxAttribNum .and rbracket; - -/* -vertex program - <vtxAttribNum> ::= <integer> from 0 to MAX_VERTEX_ATTRIBS_ARB-1 -*/ -vtxAttribNum - integer; - -/* -vertex program - <vtxOptWeightNum> ::= "" - | "[" <vtxWeightNum> "]" -*/ -vtxOptWeightNum - vtxOptWeightNum_1 .or .true .emit 0x00; -vtxOptWeightNum_1 - lbracket_ne .and vtxWeightNum .and rbracket; - -/* -vertex program - <vtxWeightNum> ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1, - must be divisible by four -*/ -vtxWeightNum - integer; - -/* - <PARAM_statement> ::= <PARAM_singleStmt> - | <PARAM_multipleStmt> -*/ -fp_PARAM_statement - fp_PARAM_multipleStmt .or fp_PARAM_singleStmt; -vp_PARAM_statement - vp_PARAM_multipleStmt .or vp_PARAM_singleStmt; - -/* - <PARAM_singleStmt> ::= "PARAM" <establishName> <paramSingleInit> -*/ -fp_PARAM_singleStmt - "PARAM" .and space .and fp_establishName .and .true .emit 0x00 .and fp_paramSingleInit .and - .true .emit PARAM_NULL; -vp_PARAM_singleStmt - "PARAM" .and space .and vp_establishName .and .true .emit 0x00 .and vp_paramSingleInit .and - .true .emit PARAM_NULL; - -/* - <PARAM_multipleStmt> ::= "PARAM" <establishName> "[" <optArraySize> "]" - <paramMultipleInit> -*/ -fp_PARAM_multipleStmt - "PARAM" .and space .and fp_establishName .and lbracket_ne .and optArraySize .and rbracket .and - fp_paramMultipleInit .and .true .emit PARAM_NULL; -vp_PARAM_multipleStmt - "PARAM" .and space .and vp_establishName .and lbracket_ne .and optArraySize .and rbracket .and - vp_paramMultipleInit .and .true .emit PARAM_NULL; - -/* - <optArraySize> ::= "" - | <integer> from 1 to MAX_PROGRAM_PARAMETERS_ARB - (maximum number of allowed program - parameter bindings) -*/ -optArraySize - optional_integer; - -/* - <paramSingleInit> ::= "=" <paramSingleItemDecl> -*/ -fp_paramSingleInit - equal .and fp_paramSingleItemDecl; -vp_paramSingleInit - equal .and vp_paramSingleItemDecl; - -/* - <paramMultipleInit> ::= "=" "{" <paramMultInitList> "}" -*/ -fp_paramMultipleInit - equal .and lbrace .and fp_paramMultInitList .and rbrace; -vp_paramMultipleInit - equal .and lbrace .and vp_paramMultInitList .and rbrace; - -/* - <paramMultInitList> ::= <paramMultipleItem> - | <paramMultipleItem> "," <paramMultiInitList> -*/ -fp_paramMultInitList - fp_paramMultInitList_1 .or fp_paramMultipleItem; -vp_paramMultInitList - vp_paramMultInitList_1 .or vp_paramMultipleItem; -fp_paramMultInitList_1 - fp_paramMultipleItem .and comma_ne .and fp_paramMultInitList; -vp_paramMultInitList_1 - vp_paramMultipleItem .and comma_ne .and vp_paramMultInitList; - -/* - <paramSingleItemDecl> ::= <stateSingleItem> - | <programSingleItem> - | <paramConstDecl> -*/ -fp_paramSingleItemDecl - fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or - programSingleItem .emit PARAM_PROGRAM_ELEMENT .or - paramConstDecl .emit PARAM_CONSTANT; -vp_paramSingleItemDecl - vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or - programSingleItem .emit PARAM_PROGRAM_ELEMENT .or - paramConstDecl .emit PARAM_CONSTANT; - -/* - <paramSingleItemUse> ::= <stateSingleItem> - | <programSingleItem> - | <paramConstUse> -*/ -fp_paramSingleItemUse - fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or - programSingleItem .emit PARAM_PROGRAM_ELEMENT .or - paramConstUse .emit PARAM_CONSTANT; -vp_paramSingleItemUse - vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or - programSingleItem .emit PARAM_PROGRAM_ELEMENT .or - paramConstUse .emit PARAM_CONSTANT; - -/* - <paramMultipleItem> ::= <stateMultipleItem> - | <programMultipleItem> - | <paramConstDecl> -*/ -fp_paramMultipleItem - fp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or - programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or - paramConstDecl .emit PARAM_CONSTANT; -vp_paramMultipleItem - vp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or - programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or - paramConstDecl .emit PARAM_CONSTANT; - -/* - <stateMultipleItem> ::= <stateSingleItem> - | "state" "." <stateMatrixRows> -*/ -fp_stateMultipleItem - stateMultipleItem_1 .or fp_stateSingleItem; -vp_stateMultipleItem - stateMultipleItem_1 .or vp_stateSingleItem; -stateMultipleItem_1 - "state" .and dot .and stateMatrixRows .emit STATE_MATRIX_ROWS; - -/* -fragment program - <stateSingleItem> ::= "state" "." <stateMaterialItem> - | "state" "." <stateLightItem> - | "state" "." <stateLightModelItem> - | "state" "." <stateLightProdItem> - | "state" "." <stateTexEnvItem> - | "state" "." <stateFogItem> - | "state" "." <stateDepthItem> - | "state" "." <stateMatrixRow> - -vertex program - <stateSingleItem> ::= "state" "." <stateMaterialItem> - | "state" "." <stateLightItem> - | "state" "." <stateLightModelItem> - | "state" "." <stateLightProdItem> - | "state" "." <stateTexGenItem> - | "state" "." <stateFogItem> - | "state" "." <stateClipPlaneItem> - | "state" "." <statePointItem> - | "state" "." <stateMatrixRow> -*/ -fp_stateSingleItem - "state" .and dot .and fp_stateSingleItem_1 .error INVALID_STATE_PROPERTY; -vp_stateSingleItem - "state" .and dot .and vp_stateSingleItem_1 .error INVALID_STATE_PROPERTY; -fp_stateSingleItem_1 - stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or - stateSingleItem_5 .or stateSingleItem_7 .or stateSingleItem_8 .or stateSingleItem_11; -vp_stateSingleItem_1 - stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or - stateSingleItem_6 .or stateSingleItem_7 .or stateSingleItem_9 .or stateSingleItem_10 .or - stateSingleItem_11; -stateSingleItem_1 - stateMaterialItem .emit STATE_MATERIAL; -stateSingleItem_2 - stateLightItem .emit STATE_LIGHT; -stateSingleItem_3 - stateLightModelItem .emit STATE_LIGHT_MODEL; -stateSingleItem_4 - stateLightProdItem .emit STATE_LIGHT_PROD; -stateSingleItem_5 - stateTexEnvItem .emit STATE_TEX_ENV; -stateSingleItem_6 - stateTexGenItem .emit STATE_TEX_GEN; -stateSingleItem_7 - stateFogItem .emit STATE_FOG; -stateSingleItem_8 - stateDepthItem .emit STATE_DEPTH; -stateSingleItem_9 - stateClipPlaneItem .emit STATE_CLIP_PLANE; -stateSingleItem_10 - statePointItem .emit STATE_POINT; -stateSingleItem_11 - stateMatrixRow .emit STATE_MATRIX_ROWS; - -/* - <stateMaterialItem> ::= "material" <optFaceType> "." <stateMatProperty> -*/ -stateMaterialItem - "material" .and optFaceType .and dot .and stateMatProperty .error INVALID_MATERIAL_PROPERTY; - -/* - <stateMatProperty> ::= "ambient" - | "diffuse" - | "specular" - | "emission" - | "shininess" -*/ -stateMatProperty - "ambient" .emit MATERIAL_AMBIENT .or - "diffuse" .emit MATERIAL_DIFFUSE .or - "specular" .emit MATERIAL_SPECULAR .or - "emission" .emit MATERIAL_EMISSION .or - "shininess" .emit MATERIAL_SHININESS; - -/* - <stateLightItem> ::= "light" "[" <stateLightNumber> "]" "." - <stateLightProperty> -*/ -stateLightItem - "light" .and lbracket .and stateLightNumber .and rbracket .and dot .and - stateLightProperty .error INVALID_LIGHT_PROPERTY; - -/* - <stateLightProperty> ::= "ambient" - | "diffuse" - | "specular" - | "position" - | "attenuation" - | "spot" "." <stateSpotProperty> - | "half" -*/ -stateLightProperty - "ambient" .emit LIGHT_AMBIENT .or - "diffuse" .emit LIGHT_DIFFUSE .or - "specular" .emit LIGHT_SPECULAR .or - "position" .emit LIGHT_POSITION .or - "attenuation" .emit LIGHT_ATTENUATION .or - stateLightProperty_1 .emit LIGHT_SPOT_DIRECTION .or - "half" .emit LIGHT_HALF; -stateLightProperty_1 - "spot" .and dot .and stateSpotProperty .error INVALID_SPOT_PROPERTY; - -/* - <stateSpotProperty> ::= "direction" -*/ -stateSpotProperty - "direction"; - -/* - <stateLightModelItem> ::= "lightmodel" <stateLModProperty> -*/ -stateLightModelItem - "lightmodel" .and stateLModProperty .error INVALID_LIGHTMODEL_PROPERTY; - -/* - <stateLModProperty> ::= "." "ambient" - | <optFaceType> "." "scenecolor" -*/ -stateLModProperty - stateLModProperty_1 .or stateLModProperty_2; -stateLModProperty_1 - dot .and "ambient" .emit LIGHT_MODEL_AMBIENT; -stateLModProperty_2 - stateLModProperty_3 .emit LIGHT_MODEL_SCENECOLOR; -stateLModProperty_3 - optFaceType .and dot .and "scenecolor"; - -/* - <stateLightProdItem> ::= "lightprod" "[" <stateLightNumber> "]" - <optFaceType> "." <stateLProdProperty> -*/ -stateLightProdItem - "lightprod" .and lbracket .and stateLightNumber .and rbracket .and optFaceType .and dot .and - stateLProdProperty .error INVALID_LIGHTPROD_PROPERTY; - -/* - <stateLProdProperty> ::= "ambient" - | "diffuse" - | "specular" -*/ -stateLProdProperty - "ambient" .emit LIGHT_PROD_AMBIENT .or - "diffuse" .emit LIGHT_PROD_DIFFUSE .or - "specular" .emit LIGHT_PROD_SPECULAR; - -/* - <stateLightNumber> ::= <integer> from 0 to MAX_LIGHTS-1 -*/ -stateLightNumber - integer; - -/* -fragment program - <stateTexEnvItem> ::= "texenv" <optLegacyTexUnitNum> "." - <stateTexEnvProperty> -*/ -stateTexEnvItem - "texenv" .and optLegacyTexUnitNum .and dot .and - stateTexEnvProperty .error INVALID_TEXENV_PROPERTY; - -/* -fragment program - <stateTexEnvProperty> ::= "color" -*/ -stateTexEnvProperty - "color" .emit TEX_ENV_COLOR; - -/* -fragment program - <optLegacyTexUnitNum> ::= "" - | "[" <legacyTexUnitNum> "]" -*/ -optLegacyTexUnitNum - optLegacyTexUnitNum_1 .or .true .emit 0x00; -optLegacyTexUnitNum_1 - lbracket_ne .and legacyTexUnitNum .and rbracket; - -/* -fragment program - <legacyTexUnitNum> ::= <integer> from 0 to MAX_TEXTURE_UNITS-1 -*/ -legacyTexUnitNum - integer; - -/* -vertex program - <stateTexGenItem> ::= "texgen" <optTexCoordNum> "." - <stateTexGenType> "." <stateTexGenCoord> -*/ -stateTexGenItem - "texgen" .and optTexCoordNum .and dot .and stateTexGenType .error INVALID_TEXGEN_PROPERTY .and - dot .and stateTexGenCoord .error INVALID_TEXGEN_COORD; - -/* -vertex program - <stateTexGenType> ::= "eye" - | "object" -*/ -stateTexGenType - "eye" .emit TEX_GEN_EYE .or - "object" .emit TEX_GEN_OBJECT; - -/* -vertex program - <stateTexGenCoord> ::= "s" - | "t" - | "r" - | "q" -*/ -stateTexGenCoord - "s" .emit COMPONENT_X .or - "t" .emit COMPONENT_Y .or - "r" .emit COMPONENT_Z .or - "q" .emit COMPONENT_W; - -/* - <stateFogItem> ::= "fog" "." <stateFogProperty> -*/ -stateFogItem - "fog" .and dot .and stateFogProperty .error INVALID_FOG_PROPERTY; - -/* - <stateFogProperty> ::= "color" - | "params" -*/ -stateFogProperty - "color" .emit FOG_COLOR .or - "params" .emit FOG_PARAMS; - -/* -fragment program - <stateDepthItem> ::= "depth" "." <stateDepthProperty> -*/ -stateDepthItem - "depth" .and dot .and stateDepthProperty .error INVALID_DEPTH_PROPERTY; - -/* -fragment program - <stateDepthProperty> ::= "range" -*/ -stateDepthProperty - "range" .emit DEPTH_RANGE; - -/* -vertex program - <stateClipPlaneItem> ::= "clip" "[" <stateClipPlaneNum> "]" "." "plane" -*/ -stateClipPlaneItem - "clip" .and lbracket .and stateClipPlaneNum .and rbracket .and dot .and - "plane" .error INVALID_CLIPPLANE_PROPERTY; - -/* -vertex program - <stateClipPlaneNum> ::= <integer> from 0 to MAX_CLIP_PLANES-1 -*/ -stateClipPlaneNum - integer; - -/* -vertex program - <statePointItem> ::= "point" "." <statePointProperty> -*/ -statePointItem - "point" .and dot .and statePointProperty .error INVALID_POINT_PROPERTY; - -/* -vertex program - <statePointProperty> ::= "size" - | "attenuation" -*/ -statePointProperty - "size" .emit POINT_SIZE .or - .if (point_parameters != 0x00) "attenuation" .emit POINT_ATTENUATION; - -/* - <stateMatrixRow> ::= <stateMatrixItem> "." "row" "[" - <stateMatrixRowNum> "]" -*/ -stateMatrixRow - stateMatrixItem .and dot .and "row" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and - lbracket .and stateMatrixRowNum .and rbracket .emit 0x0; - -/* - <stateMatrixRows> ::= <stateMatrixItem> <optMatrixRows> -*/ -stateMatrixRows - stateMatrixItem .and optMatrixRows; - -/* - <optMatrixRows> ::= "" - | "." "row" "[" <stateMatrixRowNum> ".." - <stateMatrixRowNum> "]" -*/ -optMatrixRows - optMatrixRows_1 .or .true .emit 0x0 .emit '3' .emit 0x0 .emit $; -optMatrixRows_1 - dot_ne .and "row" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and lbracket .and - stateMatrixRowNum .and dotdot .and stateMatrixRowNum .and rbracket; - -/* - <stateMatrixItem> ::= "matrix" "." <stateMatrixName> - <stateOptMatModifier> -*/ -stateMatrixItem - "matrix" .and dot .and stateMatrixName .error INVALID_MATRIX_NAME .and stateOptMatModifier; - -/* - <stateOptMatModifier> ::= "" - | "." <stateMatModifier> -*/ -stateOptMatModifier - stateOptMatModifier_1 .or .true .emit MATRIX_MODIFIER_IDENTITY; -stateOptMatModifier_1 - dot_ne .and stateMatModifier; - -/* - <stateMatModifier> ::= "inverse" - | "transpose" - | "invtrans" -*/ -stateMatModifier - "inverse" .emit MATRIX_MODIFIER_INVERSE .or - "transpose" .emit MATRIX_MODIFIER_TRANSPOSE .or - "invtrans" .emit MATRIX_MODIFIER_INVTRANS; - -/* - <stateMatrixRowNum> ::= <integer> from 0 to 3 -*/ -stateMatrixRowNum - integer_0_3; - -/* - <stateMatrixName> ::= "modelview" <stateOptModMatNum> - | "projection" - | "mvp" - | "texture" <optTexCoordNum> - | "palette" "[" <statePaletteMatNum> "]" - | "program" "[" <stateProgramMatNum> "]" -*/ -stateMatrixName - stateMatrixName_1_1 .emit MATRIX_MODELVIEW .or - "projection" .emit MATRIX_PROJECTION .or - "mvp" .emit MATRIX_MVP .or - stateMatrixName_1_2 .emit MATRIX_TEXTURE .or - .if (matrix_palette != 0x00) stateMatrixName_1_3 .emit MATRIX_PALETTE .or - stateMatrixName_1_4 .emit MATRIX_PROGRAM; -stateMatrixName_1_1 - "modelview" .and stateOptModMatNum; -stateMatrixName_1_2 - "texture" .and optTexCoordNum; -stateMatrixName_1_3 - "palette" .and lbracket .and statePaletteMatNum .and rbracket; -stateMatrixName_1_4 - "program" .and lbracket .and stateProgramMatNum .and rbracket; - -/* - <stateOptModMatNum> ::= "" - | "[" <stateModMatNum> "]" -*/ -stateOptModMatNum - .if (vertex_blend != 0x00) stateOptModMatNum_1 .or - .true .emit 0x00; -stateOptModMatNum_1 - lbracket_ne .and stateModMatNum .and rbracket; - -/* - <stateModMatNum> ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1 -*/ -stateModMatNum - integer; - -/* - <optTexCoordNum> ::= "" - | "[" <texCoordNum> "]" -*/ -optTexCoordNum - optTexCoordNum_1 .or .true .emit 0x00; -optTexCoordNum_1 - lbracket_ne .and texCoordNum .and rbracket; - -/* - <texCoordNum> ::= <integer> from 0 to MAX_TEXTURE_COORDS_ARB-1 -*/ -texCoordNum - integer; - -/* - <statePaletteMatNum> ::= <integer> from 0 to MAX_PALETTE_MATRICES_ARB-1 -*/ -statePaletteMatNum - integer; - -/* - <stateProgramMatNum> ::= <integer> from 0 to MAX_PROGRAM_MATRICES_ARB-1 -*/ -stateProgramMatNum - integer; - -/* - <programSingleItem> ::= <progEnvParam> - | <progLocalParam> - -NOTE: <programSingleItem> has been modified for correct error handling. If program property - is neither "env" nor "local" INVALID_PROGRAM_PROPERTY is generated. -*/ -programSingleItem - "program" .and dot .and programSingleItem_1 .error INVALID_PROGRAM_PROPERTY; -programSingleItem_1 - progEnvParam .or progLocalParam; - -/* - <programMultipleItem> ::= <progEnvParams> - | <progLocalParams> - -NOTE: <programMultipleItem> has been modified for correct error handling. If program property - is neither "env" nor "local" INVALID_PROGRAM_PROPERTY is generated. -*/ -programMultipleItem - "program" .and dot .and programMultipleItem_1 .error INVALID_PROGRAM_PROPERTY; -programMultipleItem_1 - progEnvParams .or progLocalParams; - -/* - <progEnvParams> ::= "program" "." "env" - "[" <progEnvParamNums> "]" - -NOTE: "program" "." has been moved to <programMultipleItem>. -*/ -progEnvParams - "env" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNums .and rbracket; - -/* - <progEnvParamNums> ::= <progEnvParamNum> - | <progEnvParamNum> ".." <progEnvParamNum> -*/ -progEnvParamNums - progEnvParamNums_1 .or progEnvParamNums_2; -progEnvParamNums_1 - progEnvParamNum .and dotdot_ne .and progEnvParamNum; -progEnvParamNums_2 - progEnvParamNum .and .true .emit 0x00; - -/* - <progEnvParam> ::= "program" "." "env" - "[" <progEnvParamNum> "]" - -NOTE: "program" "." has been moved to <programSingleItem>. -*/ -progEnvParam - "env" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00; - -/* - <progLocalParams> ::= "program" "." "local" - "[" <progLocalParamNums> "]" - -NOTE: "program" "." has been moved to <programMultipleItem>. -*/ -progLocalParams - "local" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket; - -/* - <progLocalParamNums> ::= <progLocalParamNum> - | <progLocalParamNum> ".." <progLocalParamNum> -*/ -progLocalParamNums - progLocalParamNums_1 .or progLocalParamNums_2; -progLocalParamNums_1 - progLocalParamNum .and dotdot_ne .and progLocalParamNum; -progLocalParamNums_2 - progLocalParamNum .and .true .emit 0x00; - -/* - <progLocalParam> ::= "program" "." "local" - "[" <progLocalParamNum> "]" - -NOTE: "program" "." has been moved to <programSingleItem>. -*/ -progLocalParam - "local" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00; - -/* - <progEnvParamNum> ::= <integer> from 0 to - MAX_PROGRAM_ENV_PARAMETERS_ARB - 1 -*/ -progEnvParamNum - integer; - -/* - <progLocalParamNum> ::= <integer> from 0 to - MAX_PROGRAM_LOCAL_PARAMETERS_ARB - 1 -*/ -progLocalParamNum - integer; - -/* - <paramConstDecl> ::= <paramConstScalarDecl> - | <paramConstVector> -*/ -paramConstDecl - paramConstScalarDecl .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR; - -/* - <paramConstUse> ::= <paramConstScalarUse> - | <paramConstVector> -*/ -paramConstUse - paramConstScalarUse .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR; - -/* - <paramConstScalarDecl> ::= <signedFloatConstant> -*/ -paramConstScalarDecl - signedFloatConstant; - -/* - <paramConstScalarUse> ::= <floatConstant> -*/ -paramConstScalarUse - floatConstant; - -/* - <paramConstVector> ::= "{" <signedFloatConstant> "}" - | "{" <signedFloatConstant> "," - <signedFloatConstant> "}" - | "{" <signedFloatConstant> "," - <signedFloatConstant> "," - <signedFloatConstant> "}" - | "{" <signedFloatConstant> "," - <signedFloatConstant> "," - <signedFloatConstant> "," - <signedFloatConstant> "}" -*/ -paramConstVector - paramConstVector_4 .emit 0x04 .or paramConstVector_3 .emit 0x03 .or - paramConstVector_2 .emit 0x02 .or paramConstVector_1 .emit 0x01; -paramConstVector_1 - lbrace_ne .and signedFloatConstant .and rbrace; -paramConstVector_2 - lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace; -paramConstVector_3 - lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and - signedFloatConstant .and rbrace; -paramConstVector_4 - lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and - signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace; - -/* - <signedFloatConstant> ::= <optionalSign> <floatConstant> -*/ -signedFloatConstant - optionalSign .and floatConstant; - -/* - <floatConstant> ::= see text - The <floatConstant> rule matches a floating-point constant consisting - of an integer part, a decimal point, a fraction part, an "e" or - "E", and an optionally signed integer exponent. The integer and - fraction parts both consist of a sequence of one or more digits ("0" - through "9"). Either the integer part or the fraction parts (not - both) may be missing; either the decimal point or the "e" (or "E") - and the exponent (not both) may be missing. -*/ -floatConstant - float; - -/* - <optionalSign> ::= "" - | "-" - | "+" -*/ -optionalSign - optional_sign_ne; - -/* - <TEMP_statement> ::= "TEMP" <varNameList> -*/ -fp_TEMP_statement - "TEMP" .and space .and fp_varNameList .and .true .emit 0x00; -vp_TEMP_statement - "TEMP" .and space .and vp_varNameList .and .true .emit 0x00; - -/* -vertex program - <ADDRESS_statement> ::= "ADDRESS" <varNameList> -*/ -ADDRESS_statement - "ADDRESS" .and space .and vp_varNameList .and .true .emit 0x00; - -/* - <varNameList> ::= <establishName> - | <establishName> "," <varNameList> -*/ -fp_varNameList - fp_varNameList_1 .or fp_establishName; -vp_varNameList - vp_varNameList_1 .or vp_establishName; -fp_varNameList_1 - fp_establishName .and comma_ne .and fp_varNameList; -vp_varNameList_1 - vp_establishName .and comma_ne .and vp_varNameList; - -/* - <OUTPUT_statement> ::= "OUTPUT" <establishName> "=" - <resultBinding> -*/ -fp_OUTPUT_statement - "OUTPUT" .and space .and fp_establishName .and equal .and - fp_resultBinding .error RESULT_EXPECTED; -vp_OUTPUT_statement - "OUTPUT" .and space .and vp_establishName .and equal .and - vp_resultBinding .error RESULT_EXPECTED; - -/* -fragment program - <resultBinding> ::= "result" "." "color" - | "result" "." "color" <optOutputColorNum> (if option ARB_draw_buffers present) - | "result" "." "depth" - -vertex program - <resultBinding> ::= "result" "." "position" - | "result" "." <resultColBinding> - | "result" "." "fogcoord" - | "result" "." "pointsize" - | "result" "." "texcoord" <optTexCoordNum> -*/ -fp_resultBinding - "result" .and dot .and fp_resultBinding_1 .error INVALID_RESULT_PROPERTY; -vp_resultBinding - "result" .and dot .and vp_resultBinding_1 .error INVALID_RESULT_PROPERTY; -fp_resultBinding_1 - fp_resultBinding_2 .emit FRAGMENT_RESULT_COLOR .or - "depth" .emit FRAGMENT_RESULT_DEPTH; -fp_resultBinding_2 - "color" .and optOutputColorNum; -vp_resultBinding_1 - .if (ARB_position_invariant == 0x00) "position" .emit VERTEX_RESULT_POSITION .or - resultColBinding .emit VERTEX_RESULT_COLOR .or - "fogcoord" .emit VERTEX_RESULT_FOGCOORD .or - "pointsize" .emit VERTEX_RESULT_POINTSIZE .or - vp_resultBinding_2 .emit VERTEX_RESULT_TEXCOORD; -vp_resultBinding_2 - "texcoord" .and optTexCoordNum; - -/* -GL_ARB_draw_buffers - <optOutputColorNum> ::= "" - | "[" <outputColorNum> "]" -*/ -optOutputColorNum - .if (ARB_draw_buffers != 0x00) optOutputColorNum_1 .or .true .emit 0x00; -optOutputColorNum_1 - lbracket_ne .and outputColorNum .and rbracket; - -/* -GL_ARB_draw_buffers - <outputColorNum> ::= <integer> from 0 to MAX_DRAW_BUFFERS_ARB-1 -*/ -outputColorNum - integer; - -/* -vertex program - <resultColBinding> ::= "color" <optFaceType> <optColorType> -*/ -resultColBinding - "color" .and optFaceType .and optColorType; - -/* - <optFaceType> ::= "" - | "." "front" - | "." "back" -*/ -optFaceType - FaceType .or .true .emit FACE_FRONT; -FaceType - dot_ne .and FaceProperty; -FaceProperty - "front" .emit FACE_FRONT .or "back" .emit FACE_BACK; - -/* - <optColorType> ::= "" - | "." "primary" - | "." "secondary" -*/ -optColorType - ColorType .or .true .emit COLOR_PRIMARY; -ColorType - dot_ne .and ColorProperty; -ColorProperty - "primary" .emit COLOR_PRIMARY .or - .if (secondary_color != 0x00) "secondary" .emit COLOR_SECONDARY; - -/* - <ALIAS_statement> ::= "ALIAS" <establishName> "=" - <establishedName> -*/ -fp_ALIAS_statement - "ALIAS" .and fp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and fp_establishedName; -vp_ALIAS_statement - "ALIAS" .and vp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and vp_establishedName; -fp_ALIAS_statement_1 - space .and fp_establishName; -vp_ALIAS_statement_1 - space .and vp_establishName; - -/* - <establishName> ::= <identifier> -*/ -fp_establishName - fp_identifier; -vp_establishName - vp_identifier; - -/* - <establishedName> ::= <identifier> -*/ -fp_establishedName - fp_identifier; -vp_establishedName - vp_identifier; -fp_establishedName_no_error_on_identifier - fp_identifier_ne; -vp_establishedName_no_error_on_identifier - vp_identifier_ne; - -/* -fragment program - <identifier> ::= see text - The <identifier> rule matches a sequence of one or more letters ("A" - through "Z", "a" through "z"), digits ("0" through "9), underscores - ("_"), or dollar signs ("$"); the first character must not be a - number. Upper and lower case letters are considered different - (names are case-sensitive). The following strings are reserved - keywords and may not be used as identifiers: - - ABS, ABS_SAT, ADD, ADD_SAT, ALIAS, ATTRIB, CMP, CMP_SAT, COS, - COS_SAT, DP3, DP3_SAT, DP4, DP4_SAT, DPH, DPH_SAT, DST, DST_SAT, - END, EX2, EX2_SAT, FLR, FLR_SAT, FRC, FRC_SAT, KIL, LG2, - LG2_SAT, LIT, LIT_SAT, LRP, LRP_SAT, MAD, MAD_SAT, MAX, MAX_SAT, - MIN, MIN_SAT, MOV, MOV_SAT, MUL, MUL_SAT, OPTION, OUTPUT, PARAM, - POW, POW_SAT, RCP, RCP_SAT, RSQ, RSQ_SAT, SIN, SIN_SAT, SCS, - SCS_SAT, SGE, SGE_SAT, SLT, SLT_SAT, SUB, SUB_SAT, SWZ, SWZ_SAT, - TEMP, TEX, TEX_SAT, TXB, TXB_SAT, TXP, TXP_SAT, XPD, XPD_SAT, - fragment, program, result, state, and texture. - -vertex program - <identifier> ::= see text - The <identifier> rule matches a sequence of one or more letters ("A" - through "Z", "a" through "z"), digits ("0" through "9), underscores ("_"), - or dollar signs ("$"); the first character must not be a number. Upper - and lower case letters are considered different (names are - case-sensitive). The following strings are reserved keywords and may not - be used as identifiers: - - ABS, ADD, ADDRESS, ALIAS, ARL, ATTRIB, DP3, DP4, DPH, DST, END, EX2, - EXP, FLR, FRC, LG2, LIT, LOG, MAD, MAX, MIN, MOV, MUL, OPTION, OUTPUT, - PARAM, POW, RCP, RSQ, SGE, SLT, SUB, SWZ, TEMP, XPD, program, result, - state, and vertex. -*/ -fp_identifier - fp_identifier_ne .error IDENTIFIER_EXPECTED; -vp_identifier - vp_identifier_ne .error IDENTIFIER_EXPECTED; -fp_identifier_ne - fp_not_reserved_identifier .and identifier_ne; -vp_identifier_ne - vp_not_reserved_identifier .and identifier_ne; - -fp_not_reserved_identifier - fp_not_reserved_identifier_1 .or .true; -fp_not_reserved_identifier_1 - fp_reserved_identifier .and .false .error RESERVED_KEYWORD; -vp_not_reserved_identifier - vp_not_reserved_identifier_1 .or .true; -vp_not_reserved_identifier_1 - vp_reserved_identifier .and .false .error RESERVED_KEYWORD; - -fp_reserved_identifier - "ABS" .or "ABS_SAT" .or "ADD" .or "ADD_SAT" .or "ALIAS" .or "ATTRIB" .or "CMP" .or "CMP_SAT" .or - "COS" .or "COS_SAT" .or "DP3" .or "DP3_SAT" .or "DP4" .or "DP4_SAT" .or "DPH" .or "DPH_SAT" .or - "DST" .or "DST_SAT" .or "END" .or "EX2" .or "EX2_SAT" .or "FLR" .or "FLR_SAT" .or "FRC" .or - "FRC_SAT" .or "KIL" .or "LG2" .or "LG2_SAT" .or "LIT" .or "LIT_SAT" .or "LRP" .or "LRP_SAT" .or - "MAD" .or "MAD_SAT" .or "MAX" .or "MAX_SAT" .or "MIN" .or "MIN_SAT" .or "MOV" .or "MOV_SAT" .or - "MUL" .or "MUL_SAT" .or "OPTION" .or "OUTPUT" .or "PARAM" .or "POW" .or "POW_SAT" .or "RCP" .or - "RCP_SAT" .or "RSQ" .or "RSQ_SAT" .or "SIN" .or "SIN_SAT" .or "SCS" .or "SCS_SAT" .or "SGE" .or - "SGE_SAT" .or "SLT" .or "SLT_SAT" .or "SUB" .or "SUB_SAT" .or "SWZ" .or "SWZ_SAT" .or "TEMP" .or - "TEX" .or "TEX_SAT" .or "TXB" .or "TXB_SAT" .or "TXP" .or "TXP_SAT" .or "XPD" .or "XPD_SAT" .or - "fragment" .or "program" .or "result" .or "state" .or "texture"; -vp_reserved_identifier - "ABS" .or "ADD" .or "ADDRESS" .or "ALIAS" .or "ARL" .or "ATTRIB" .or "DP3" .or "DP4" .or - "DPH" .or "DST" .or "END" .or "EX2" .or "EXP" .or "FLR" .or "FRC" .or "LG2" .or "LIT" .or - "LOG" .or "MAD" .or "MAX" .or "MIN" .or "MOV" .or "MUL" .or "OPTION" .or "OUTPUT" .or - "PARAM" .or "POW" .or "RCP" .or "RSQ" .or "SGE" .or "SLT" .or "SUB" .or "SWZ" .or "TEMP" .or - "XPD" .or "program" .or "result" .or "state" .or "vertex"; - -/* - The <integer> rule matches an integer constant. The integer consists - of a sequence of one or more digits ("0" through "9"). -*/ -integer - integer_ne .error INTEGER_EXPECTED; - -zero - '0'; - -leading_zeroes - .loop zero; - -no_digit - no_digit_1 .or .true; -no_digit_1 - digit10 .and .false .error INTEGER_OUT_OF_RANGE; - -all_zeroes - all_zeroes_1 .or no_digit_1; -all_zeroes_1 - '0' .and .loop zero .and no_digit; - -integer_0_3 - integer_0_3_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $; -integer_0_3_1 - integer_0_3_2 .or all_zeroes .emit '0'; -integer_0_3_2 /* [1, 3] */ - leading_zeroes .and '1'-'3' .emit * .and no_digit; - -integer_0_63 - integer_0_63_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $; -integer_0_63_1 - integer_0_63_2 .or integer_0_63_3 .or integer_0_63_4 .or integer_0_63_5 .or - all_zeroes .emit '0'; -integer_0_63_2 /* [7, 9] */ - leading_zeroes .and '7'-'9' .emit * .and no_digit; -integer_0_63_3 /* [10, 59] */ - leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit; -integer_0_63_4 /* [60, 63] */ - leading_zeroes .and '6' .emit * .and '0'-'3' .emit * .and no_digit; -integer_0_63_5 /* [1, 6] */ - leading_zeroes .and '1'-'6' .emit * .and no_digit; - -integer_0_64 - integer_0_64_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $; -integer_0_64_1 - integer_0_64_2 .or integer_0_64_3 .or integer_0_64_4 .or integer_0_64_5 .or - all_zeroes .emit '0'; -integer_0_64_2 /* [7, 9] */ - leading_zeroes .and '7'-'9' .emit * .and no_digit; -integer_0_64_3 /* [10, 59] */ - leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit; -integer_0_64_4 /* [60, 64] */ - leading_zeroes .and '6' .emit * .and '0'-'4' .emit * .and no_digit; -integer_0_64_5 /* [1, 6] */ - leading_zeroes .and '1'-'6' .emit * .and no_digit; - -optional_space - space .or .true; - -space_dst - space .error OPERATION_NEEDS_DESTINATION_VARIABLE; - -space_src - space .error OPERATION_NEEDS_SOURCE_VARIABLE; - -space - single_space .and .loop single_space; - -single_space - white_char .or comment_block; - -white_char - ' ' .or '\t' .or '\n' .or '\r'; - -comment_block - '#' .and .loop comment_char .and optional_new_line; - -/* All ASCII characters except '\r', '\n' and '\0' */ -comment_char - '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C'; - -optional_new_line - '\n' .or crlf .or .true; - -crlf - '\r' .and '\n'; - -semicolon - optional_space .and ';' .error MISSING_SEMICOLON .and optional_space; - -comma - optional_space .and ',' .error MISSING_COMMA .and optional_space; - -comma_ne - optional_space .and ',' .and optional_space; - -lbracket - optional_space .and '[' .error MISSING_LBRACKET .and optional_space; - -lbracket_ne - optional_space .and '[' .and optional_space; - -rbracket - optional_space .and ']' .error MISSING_RBRACKET .and optional_space; - -dot - optional_space .and '.' .error MISSING_DOT .and optional_space; - -dot_ne - optional_space .and '.' .and optional_space; - -equal - optional_space .and '=' .error MISSING_EQUAL .and optional_space; - -lbrace - optional_space .and '{' .error MISSING_LBRACE .and optional_space; - -lbrace_ne - optional_space .and '{' .and optional_space; - -rbrace - optional_space .and '}' .error MISSING_RBRACE .and optional_space; - -dotdot - optional_space .and '.' .and '.' .error MISSING_DOTDOT .and optional_space; - -dotdot_ne - optional_space .and '.' .and '.' .and optional_space; - -/* - The definition below accepts the following floating point number formats: - .99 .99e99 99. 99.99 99.99e99 99.e99 99e99 - Also 99 format was considered and accepted because of a large number of existing program - strings with such a format. -*/ -float - float_1 .or float_2 .or float_legacy; -float_1 - '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent; -float_2 - integer_ne .and float_3; -float_3 - float_4 .or float_5; -float_4 - '.' .and optional_integer .and optional_exponent; -float_5 - exponent .emit 0x00; -float_legacy - integer_ne .and .true .emit 0x00 .emit 0x00; - -/* - Below is a correct version of <float> definiton. -*/ -/* -float - float_1 .or float_2; -float_1 - '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent; -float_2 - integer_ne .and float_3 .error MISSING_DOT_OR_EXPONENT; -float_3 - float_4 .or float_5; -float_4 - '.' .and optional_integer .and optional_exponent; -float_5 - exponent .emit 0x00; -*/ - -integer_ne - integer_ne_1 .and .true .emit 0x00 .emit $; -integer_ne_1 - digit10 .emit * .and .loop digit10 .emit *; - -optional_integer - integer_ne .or .true .emit 0x00; - -/* -NOTE: If exponent part is omited we treat it as if it was "E+1". -*/ -optional_exponent - exponent .or .true .emit 0x00; - -exponent - exponent_1 .and optional_sign_ne .and integer_ne .error EXPONENT_VALUE_EXPECTED; -exponent_1 - 'e' .or 'E'; - -optional_sign_ne - minus_ne .or plus_ne .or .true; - -plus_ne - optional_space .and '+' .and optional_space; - -minus_ne - optional_space .and '-' .emit '-' .and optional_space; - -identifier_ne - first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit 0x00 .emit $; - -follow_idchar - first_idchar .or digit10; - -first_idchar - 'a'-'z' .or 'A'-'Z' .or '_' .or '$'; - -digit10 - '0'-'9'; - -/* - string filtering - if a string is encountered in grammar ("blabla"), the symbol below is - executed to create the string. The symbol must not throw any errors and emit bytes - it should - stop if it encounters invalid character. After this the resulting string (from starting - position up to the invalid character (but without it) is compared with the grammar string. -*/ -.string __string_filter; - -__string_filter - .loop __identifier_char; - -__identifier_char - 'a'-'z' .or 'A'-'Z' .or '_' .or '$' .or '0'-'9'; - -/* - error token filtering -*/ -e_signature - e_signature_char .and .loop e_signature_char; -e_signature_char - '!' .or '.' .or 'A'-'Z' .or 'a'-'z' .or '0'-'9'; - -e_statement - .loop e_statement_not_term; -/* All ASCII characters to one of '\r', '\n', '\0' and ';' */ -e_statement_not_term - '\x3C'-'\xFF' .or '\x0E'-'\x3A' .or '\x01'-'\x09' .or '\x0B'-'\x0C'; - -e_identifier - e_identifier_first .and .loop e_identifier_next; -e_identifier_first - 'a'-'z' .or 'A'-'Z' .or '_' .or '$'; -e_identifier_next - e_identifier_first .or '0'-'9'; - -e_token - e_identifier .or e_token_number .or '[' .or ']' .or '.' .or '{' .or '}' .or '=' .or '+' .or - '-' .or ',' .or ';'; -e_token_number - e_token_digit .and .loop e_token_digit; -e_token_digit - '0'-'9'; - -e_charordigit - 'A'-'Z' .or 'a'-'z' .or '0'-'9'; - diff --git a/src/mesa/shader/arbprogram_syn.h b/src/mesa/shader/arbprogram_syn.h deleted file mode 100644 index d95a5dede4..0000000000 --- a/src/mesa/shader/arbprogram_syn.h +++ /dev/null @@ -1,1350 +0,0 @@ - -/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE .syn FILE */ - -" \n" -".syntax program;\n" -".emtcode REVISION 0x0a\n" -".emtcode FRAGMENT_PROGRAM 0x01\n" -".emtcode VERTEX_PROGRAM 0x02\n" -".emtcode OPTION 0x01\n" -".emtcode INSTRUCTION 0x02\n" -".emtcode DECLARATION 0x03\n" -".emtcode END 0x04\n" -".emtcode ARB_PRECISION_HINT_FASTEST 0x00\n" -".emtcode ARB_PRECISION_HINT_NICEST 0x01\n" -".emtcode ARB_FOG_EXP 0x02\n" -".emtcode ARB_FOG_EXP2 0x03\n" -".emtcode ARB_FOG_LINEAR 0x04\n" -".emtcode ARB_POSITION_INVARIANT 0x05\n" -".emtcode ARB_FRAGMENT_PROGRAM_SHADOW 0x06\n" -".emtcode ARB_DRAW_BUFFERS 0x07\n" -".emtcode MESA_TEXTURE_ARRAY 0x08\n" -".emtcode OP_ALU_INST 0x00\n" -".emtcode OP_TEX_INST 0x01\n" -".emtcode OP_ALU_VECTOR 0x00\n" -".emtcode OP_ALU_SCALAR 0x01\n" -".emtcode OP_ALU_BINSC 0x02\n" -".emtcode OP_ALU_BIN 0x03\n" -".emtcode OP_ALU_TRI 0x04\n" -".emtcode OP_ALU_SWZ 0x05\n" -".emtcode OP_TEX_SAMPLE 0x06\n" -".emtcode OP_TEX_KIL 0x07\n" -".emtcode OP_ALU_ARL 0x08\n" -".emtcode OP_ABS 0x00\n" -".emtcode OP_ABS_SAT 0x1B\n" -".emtcode OP_FLR 0x09\n" -".emtcode OP_FLR_SAT 0x26\n" -".emtcode OP_FRC 0x0A\n" -".emtcode OP_FRC_SAT 0x27\n" -".emtcode OP_LIT 0x0C\n" -".emtcode OP_LIT_SAT 0x2A\n" -".emtcode OP_MOV 0x11\n" -".emtcode OP_MOV_SAT 0x30\n" -".emtcode OP_COS 0x1F\n" -".emtcode OP_COS_SAT 0x20\n" -".emtcode OP_EX2 0x07\n" -".emtcode OP_EX2_SAT 0x25\n" -".emtcode OP_LG2 0x0B\n" -".emtcode OP_LG2_SAT 0x29\n" -".emtcode OP_RCP 0x14\n" -".emtcode OP_RCP_SAT 0x33\n" -".emtcode OP_RSQ 0x15\n" -".emtcode OP_RSQ_SAT 0x34\n" -".emtcode OP_SIN 0x38\n" -".emtcode OP_SIN_SAT 0x39\n" -".emtcode OP_SCS 0x35\n" -".emtcode OP_SCS_SAT 0x36\n" -".emtcode OP_POW 0x13\n" -".emtcode OP_POW_SAT 0x32\n" -".emtcode OP_ADD 0x01\n" -".emtcode OP_ADD_SAT 0x1C\n" -".emtcode OP_DP3 0x03\n" -".emtcode OP_DP3_SAT 0x21\n" -".emtcode OP_DP4 0x04\n" -".emtcode OP_DP4_SAT 0x22\n" -".emtcode OP_DPH 0x05\n" -".emtcode OP_DPH_SAT 0x23\n" -".emtcode OP_DST 0x06\n" -".emtcode OP_DST_SAT 0x24\n" -".emtcode OP_MAX 0x0F\n" -".emtcode OP_MAX_SAT 0x2E\n" -".emtcode OP_MIN 0x10\n" -".emtcode OP_MIN_SAT 0x2F\n" -".emtcode OP_MUL 0x12\n" -".emtcode OP_MUL_SAT 0x31\n" -".emtcode OP_SGE 0x16\n" -".emtcode OP_SGE_SAT 0x37\n" -".emtcode OP_SLT 0x17\n" -".emtcode OP_SLT_SAT 0x3A\n" -".emtcode OP_SUB 0x18\n" -".emtcode OP_SUB_SAT 0x3B\n" -".emtcode OP_XPD 0x1A\n" -".emtcode OP_XPD_SAT 0x43\n" -".emtcode OP_CMP 0x1D\n" -".emtcode OP_CMP_SAT 0x1E\n" -".emtcode OP_LRP 0x2B\n" -".emtcode OP_LRP_SAT 0x2C\n" -".emtcode OP_MAD 0x0E\n" -".emtcode OP_MAD_SAT 0x2D\n" -".emtcode OP_SWZ 0x19\n" -".emtcode OP_SWZ_SAT 0x3C\n" -".emtcode OP_TEX 0x3D\n" -".emtcode OP_TEX_SAT 0x3E\n" -".emtcode OP_TXB 0x3F\n" -".emtcode OP_TXB_SAT 0x40\n" -".emtcode OP_TXP 0x41\n" -".emtcode OP_TXP_SAT 0x42\n" -".emtcode OP_KIL 0x28\n" -".emtcode OP_ARL 0x02\n" -".emtcode OP_EXP 0x08\n" -".emtcode OP_LOG 0x0D\n" -".emtcode FRAGMENT_ATTRIB_COLOR 0x01\n" -".emtcode FRAGMENT_ATTRIB_TEXCOORD 0x02\n" -".emtcode FRAGMENT_ATTRIB_FOGCOORD 0x03\n" -".emtcode FRAGMENT_ATTRIB_POSITION 0x04\n" -".emtcode VERTEX_ATTRIB_POSITION 0x01\n" -".emtcode VERTEX_ATTRIB_WEIGHT 0x02\n" -".emtcode VERTEX_ATTRIB_NORMAL 0x03\n" -".emtcode VERTEX_ATTRIB_COLOR 0x04\n" -".emtcode VERTEX_ATTRIB_FOGCOORD 0x05\n" -".emtcode VERTEX_ATTRIB_TEXCOORD 0x06\n" -".emtcode VERTEX_ATTRIB_MATRIXINDEX 0x07\n" -".emtcode VERTEX_ATTRIB_GENERIC 0x08\n" -".emtcode FRAGMENT_RESULT_COLOR 0x01\n" -".emtcode FRAGMENT_RESULT_DEPTH 0x02\n" -".emtcode VERTEX_RESULT_POSITION 0x01\n" -".emtcode VERTEX_RESULT_COLOR 0x02\n" -".emtcode VERTEX_RESULT_FOGCOORD 0x03\n" -".emtcode VERTEX_RESULT_POINTSIZE 0x04\n" -".emtcode VERTEX_RESULT_TEXCOORD 0x05\n" -".emtcode TEXTARGET_1D 0x01\n" -".emtcode TEXTARGET_2D 0x02\n" -".emtcode TEXTARGET_3D 0x03\n" -".emtcode TEXTARGET_RECT 0x04\n" -".emtcode TEXTARGET_CUBE 0x05\n" -".emtcode TEXTARGET_SHADOW1D 0x06\n" -".emtcode TEXTARGET_SHADOW2D 0x07\n" -".emtcode TEXTARGET_SHADOWRECT 0x08\n" -".emtcode TEXTARGET_1D_ARRAY 0x09\n" -".emtcode TEXTARGET_2D_ARRAY 0x0a\n" -".emtcode TEXTARGET_SHADOW1D_ARRAY 0x0b\n" -".emtcode TEXTARGET_SHADOW2D_ARRAY 0x0c\n" -".emtcode FACE_FRONT 0x00\n" -".emtcode FACE_BACK 0x01\n" -".emtcode COLOR_PRIMARY 0x00\n" -".emtcode COLOR_SECONDARY 0x01\n" -".emtcode COMPONENT_X 0x00\n" -".emtcode COMPONENT_Y 0x01\n" -".emtcode COMPONENT_Z 0x02\n" -".emtcode COMPONENT_W 0x03\n" -".emtcode COMPONENT_0 0x04\n" -".emtcode COMPONENT_1 0x05\n" -".emtcode ARRAY_INDEX_ABSOLUTE 0x00\n" -".emtcode ARRAY_INDEX_RELATIVE 0x01\n" -".emtcode MATRIX_MODELVIEW 0x01\n" -".emtcode MATRIX_PROJECTION 0x02\n" -".emtcode MATRIX_MVP 0x03\n" -".emtcode MATRIX_TEXTURE 0x04\n" -".emtcode MATRIX_PALETTE 0x05\n" -".emtcode MATRIX_PROGRAM 0x06\n" -".emtcode MATRIX_MODIFIER_IDENTITY 0x00\n" -".emtcode MATRIX_MODIFIER_INVERSE 0x01\n" -".emtcode MATRIX_MODIFIER_TRANSPOSE 0x02\n" -".emtcode MATRIX_MODIFIER_INVTRANS 0x03\n" -".emtcode CONSTANT_SCALAR 0x01\n" -".emtcode CONSTANT_VECTOR 0x02\n" -".emtcode PROGRAM_PARAM_ENV 0x01\n" -".emtcode PROGRAM_PARAM_LOCAL 0x02\n" -".emtcode REGISTER_ATTRIB 0x01\n" -".emtcode REGISTER_PARAM 0x02\n" -".emtcode REGISTER_RESULT 0x03\n" -".emtcode REGISTER_ESTABLISHED_NAME 0x04\n" -".emtcode PARAM_NULL 0x00\n" -".emtcode PARAM_ARRAY_ELEMENT 0x01\n" -".emtcode PARAM_STATE_ELEMENT 0x02\n" -".emtcode PARAM_PROGRAM_ELEMENT 0x03\n" -".emtcode PARAM_PROGRAM_ELEMENTS 0x04\n" -".emtcode PARAM_CONSTANT 0x05\n" -".emtcode STATE_MATERIAL 0x01\n" -".emtcode STATE_LIGHT 0x02\n" -".emtcode STATE_LIGHT_MODEL 0x03\n" -".emtcode STATE_LIGHT_PROD 0x04\n" -".emtcode STATE_FOG 0x05\n" -".emtcode STATE_MATRIX_ROWS 0x06\n" -".emtcode STATE_TEX_ENV 0x07\n" -".emtcode STATE_DEPTH 0x08\n" -".emtcode STATE_TEX_GEN 0x09\n" -".emtcode STATE_CLIP_PLANE 0x0A\n" -".emtcode STATE_POINT 0x0B\n" -".emtcode MATERIAL_AMBIENT 0x01\n" -".emtcode MATERIAL_DIFFUSE 0x02\n" -".emtcode MATERIAL_SPECULAR 0x03\n" -".emtcode MATERIAL_EMISSION 0x04\n" -".emtcode MATERIAL_SHININESS 0x05\n" -".emtcode LIGHT_AMBIENT 0x01\n" -".emtcode LIGHT_DIFFUSE 0x02\n" -".emtcode LIGHT_SPECULAR 0x03\n" -".emtcode LIGHT_POSITION 0x04\n" -".emtcode LIGHT_ATTENUATION 0x05\n" -".emtcode LIGHT_HALF 0x06\n" -".emtcode LIGHT_SPOT_DIRECTION 0x07\n" -".emtcode LIGHT_MODEL_AMBIENT 0x01\n" -".emtcode LIGHT_MODEL_SCENECOLOR 0x02\n" -".emtcode LIGHT_PROD_AMBIENT 0x01\n" -".emtcode LIGHT_PROD_DIFFUSE 0x02\n" -".emtcode LIGHT_PROD_SPECULAR 0x03\n" -".emtcode TEX_ENV_COLOR 0x01\n" -".emtcode TEX_GEN_EYE 0x01\n" -".emtcode TEX_GEN_OBJECT 0x02\n" -".emtcode FOG_COLOR 0x01\n" -".emtcode FOG_PARAMS 0x02\n" -".emtcode DEPTH_RANGE 0x01\n" -".emtcode POINT_SIZE 0x01\n" -".emtcode POINT_ATTENUATION 0x02\n" -".emtcode ATTRIB 0x01\n" -".emtcode PARAM 0x02\n" -".emtcode TEMP 0x03\n" -".emtcode OUTPUT 0x04\n" -".emtcode ALIAS 0x05\n" -".emtcode ADDRESS 0x06\n" -".errtext UNKNOWN_PROGRAM_SIGNATURE \"1001: '$e_signature$': unknown program signature\"\n" -".errtext MISSING_END_OR_INVALID_STATEMENT \"1002: '$e_statement$': invalid statement\"\n" -".errtext CODE_AFTER_END \"1003: '$e_statement$': code after 'END' keyword\"\n" -".errtext INVALID_PROGRAM_OPTION \"1004: '$e_identifier$': invalid program option\"\n" -".errtext EXT_SWIZ_COMP_EXPECTED \"1005: extended swizzle component expected but '$e_token$' found\"\n" -".errtext TEX_TARGET_EXPECTED \"1006: texture target expected but '$e_token$' found\"\n" -".errtext TEXTURE_EXPECTED \"1007: 'texture' expected but '$e_identifier$' found\"\n" -".errtext SOURCE_REGISTER_EXPECTED \"1008: source register expected but '$e_token$' found\"\n" -".errtext DESTINATION_REGISTER_EXPECTED \"1009: destination register expected but '$e_token$' found\"\n" -".errtext INVALID_ADDRESS_COMPONENT \"1010: '$e_identifier$': invalid address component\"\n" -".errtext INVALID_ADDRESS_WRITEMASK \"1011: '$e_identifier$': invalid address writemask\"\n" -".errtext INVALID_COMPONENT \"1012: '$e_charordigit$': invalid component\"\n" -".errtext INVALID_SUFFIX \"1013: '$e_identifier$': invalid suffix\"\n" -".errtext INVALID_WRITEMASK \"1014: '$e_identifier$': invalid writemask\"\n" -".errtext FRAGMENT_EXPECTED \"1015: 'fragment' expected but '$e_identifier$' found\"\n" -".errtext VERTEX_EXPECTED \"1016: 'vertex' expected but '$e_identifier$' found\"\n" -".errtext INVALID_FRAGMENT_PROPERTY \"1017: '$e_identifier$': invalid fragment property\"\n" -".errtext INVALID_VERTEX_PROPERTY \"1018: '$e_identifier$': invalid vertex property\"\n" -".errtext INVALID_STATE_PROPERTY \"1019: '$e_identifier$': invalid state property\"\n" -".errtext INVALID_MATERIAL_PROPERTY \"1020: '$e_identifier$': invalid material property\"\n" -".errtext INVALID_LIGHT_PROPERTY \"1021: '$e_identifier$': invalid light property\"\n" -".errtext INVALID_SPOT_PROPERTY \"1022: '$e_identifier$': invalid spot property\"\n" -".errtext INVALID_LIGHTMODEL_PROPERTY \"1023: '$e_identifier$': invalid light model property\"\n" -".errtext INVALID_LIGHTPROD_PROPERTY \"1024: '$e_identifier$': invalid light product property\"\n" -".errtext INVALID_TEXENV_PROPERTY \"1025: '$e_identifier$': invalid texture environment property\"\n" -".errtext INVALID_TEXGEN_PROPERTY \"1026: '$e_identifier$': invalid texture generating property\"\n" -".errtext INVALID_TEXGEN_COORD \"1027: '$e_identifier$': invalid texture generating coord\"\n" -".errtext INVALID_FOG_PROPERTY \"1028: '$e_identifier$': invalid fog property\"\n" -".errtext INVALID_DEPTH_PROPERTY \"1029: '$e_identifier$': invalid depth property\"\n" -".errtext INVALID_CLIPPLANE_PROPERTY \"1030: '$e_identifier$': invalid clip plane property\"\n" -".errtext INVALID_POINT_PROPERTY \"1031: '$e_identifier$': invalid point property\"\n" -".errtext MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED \"1032: matrix row selector or modifier expected but '$e_token$' found\"\n" -".errtext INVALID_MATRIX_NAME \"1033: '$e_identifier$': invalid matrix name\"\n" -".errtext INVALID_PROGRAM_PROPERTY \"1034: '$e_identifier$': invalid program property\"\n" -".errtext RESULT_EXPECTED \"1035: 'result' expected but '$e_token$' found\"\n" -".errtext INVALID_RESULT_PROPERTY \"1036: '$e_identifier$': invalid result property\"\n" -".errtext INVALID_FACE_PROPERTY \"1037: '$e_identifier$': invalid face property\"\n" -".errtext INVALID_COLOR_PROPERTY \"1038: '$e_identifier$': invalid color property\"\n" -".errtext IDENTIFIER_EXPECTED \"1039: identifier expected but '$e_token$' found\"\n" -".errtext RESERVED_KEYWORD \"1040: use of reserved keyword as an identifier\"\n" -".errtext INTEGER_EXPECTED \"1041: integer value expected but '$e_token$' found\"\n" -".errtext MISSING_SEMICOLON \"1042: ';' expected but '$e_token$' found\"\n" -".errtext MISSING_COMMA \"1043: ',' expected but '$e_token$' found\"\n" -".errtext MISSING_LBRACKET \"1044: '[' expected but '$e_token$' found\"\n" -".errtext MISSING_RBRACKET \"1045: ']' expected but '$e_token$' found\"\n" -".errtext MISSING_DOT \"1046: '.' expected but '$e_token$' found\"\n" -".errtext MISSING_EQUAL \"1047: '=' expected but '$e_token$' found\"\n" -".errtext MISSING_LBRACE \"1048: '{' expected but '$e_token$' found\"\n" -".errtext MISSING_RBRACE \"1049: '}' expected but '$e_token$' found\"\n" -".errtext MISSING_DOTDOT \"1050: '..' expected but '$e_token$' found\"\n" -".errtext MISSING_FRACTION_OR_EXPONENT \"1051: missing fraction part or exponent\"\n" -".errtext MISSING_DOT_OR_EXPONENT \"1052: missing '.' or exponent\"\n" -".errtext EXPONENT_VALUE_EXPECTED \"1053: exponent value expected\"\n" -".errtext INTEGER_OUT_OF_RANGE \"1054: integer value out of range\"\n" -".errtext OPERATION_NEEDS_DESTINATION_VARIABLE \"1055: operation needs destination variable\"\n" -".errtext OPERATION_NEEDS_SOURCE_VARIABLE \"1056: operation needs source variable\"\n" -".errtext ADDRESS_REGISTER_EXPECTED \"1057: address register expected but '$e_token$' found\"\n" -".errtext ADDRESS_REGISTER_OR_INTEGER_EXPECTED \"1058: address register or integer literal expected but '$e_token$' found\"\n" -".regbyte vertex_blend 0x00\n" -".regbyte matrix_palette 0x00\n" -".regbyte point_parameters 0x00\n" -".regbyte secondary_color 0x00\n" -".regbyte fog_coord 0x00\n" -".regbyte texture_rectangle 0x00\n" -".regbyte fragment_program_shadow 0x00\n" -".regbyte draw_buffers 0x00\n" -".regbyte texture_array 0x00\n" -".regbyte ARB_precision_hint_fastest 0x00\n" -".regbyte ARB_precision_hint_nicest 0x00\n" -".regbyte ARB_fog_exp 0x00\n" -".regbyte ARB_fog_exp2 0x00\n" -".regbyte ARB_fog_linear 0x00\n" -".regbyte ARB_position_invariant 0x00\n" -".regbyte ARB_fragment_program_shadow 0x00\n" -".regbyte ARB_draw_buffers 0x00\n" -".regbyte MESA_texture_array 0x00\n" -".regbyte program_target 0x00\n" -"program\n" -" programs .error UNKNOWN_PROGRAM_SIGNATURE .emit REVISION;\n" -"programs\n" -" .if (program_target == 0x10) frag_program_1_0 .emit FRAGMENT_PROGRAM .emit 0x01 .emit 0x00 .or\n" -" .if (program_target == 0x20) vert_program_1_0 .emit VERTEX_PROGRAM .emit 0x01 .emit 0x00;\n" -"frag_program_1_0\n" -" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'f' .and 'p' .and '1' .and '.' .and '0' .and\n" -" optional_space .and fp_optionSequence .and fp_statementSequence .and\n" -" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n" -" '\\0' .error CODE_AFTER_END;\n" -"vert_program_1_0\n" -" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'v' .and 'p' .and '1' .and '.' .and '0' .and\n" -" optional_space .and vp_optionSequence .and vp_statementSequence .and\n" -" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n" -" '\\0' .error CODE_AFTER_END;\n" -"fp_optionSequence\n" -" .loop fp_option;\n" -"vp_optionSequence\n" -" .loop vp_option;\n" -"fp_option\n" -" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n" -" fp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n" -"vp_option\n" -" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n" -" vp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n" -"fp_optionString\n" -" .if (ARB_precision_hint_nicest == 0x00) \"ARB_precision_hint_fastest\"\n" -" .emit ARB_PRECISION_HINT_FASTEST .load ARB_precision_hint_fastest 0x01 .or\n" -" .if (ARB_precision_hint_fastest == 0x00) \"ARB_precision_hint_nicest\"\n" -" .emit ARB_PRECISION_HINT_NICEST .load ARB_precision_hint_nicest 0x01 .or\n" -" fp_ARB_fog_exp .emit ARB_FOG_EXP .load ARB_fog_exp 0x01 .or\n" -" fp_ARB_fog_exp2 .emit ARB_FOG_EXP2 .load ARB_fog_exp2 0x01 .or\n" -" fp_ARB_fog_linear .emit ARB_FOG_LINEAR .load ARB_fog_linear 0x01 .or\n" -" .if (fragment_program_shadow != 0x00) \"ARB_fragment_program_shadow\"\n" -" .emit ARB_FRAGMENT_PROGRAM_SHADOW .load ARB_fragment_program_shadow 0x01 .or\n" -" .if (draw_buffers != 0x00) \"ARB_draw_buffers\" .emit ARB_DRAW_BUFFERS\n" -" .load ARB_draw_buffers 0x01 .or\n" -" .if (texture_array != 0x00) \"MESA_texture_array\" .emit MESA_TEXTURE_ARRAY\n" -" .load MESA_texture_array 0x01;\n" -"vp_optionString\n" -" \"ARB_position_invariant\" .emit ARB_POSITION_INVARIANT .load ARB_position_invariant 0x01;\n" -"fp_ARB_fog_exp\n" -" .if (ARB_fog_exp2 == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp\";\n" -"fp_ARB_fog_exp2\n" -" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp2\";\n" -"fp_ARB_fog_linear\n" -" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_exp2 == 0x00) \"ARB_fog_linear\";\n" -"fp_statementSequence\n" -" .loop fp_statement;\n" -"vp_statementSequence\n" -" .loop vp_statement;\n" -"fp_statement\n" -" fp_statement_1 .or fp_statement_2;\n" -"vp_statement\n" -" vp_statement_1 .or vp_statement_2;\n" -"fp_statement_1\n" -" fp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n" -"fp_statement_2\n" -" fp_namingStatement .emit DECLARATION .and semicolon;\n" -"vp_statement_1\n" -" vp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n" -"vp_statement_2\n" -" vp_namingStatement .emit DECLARATION .and semicolon;\n" -"fp_instruction\n" -" ALUInstruction .emit OP_ALU_INST .or\n" -" TexInstruction .emit OP_TEX_INST;\n" -"vp_instruction\n" -" ARL_instruction .emit OP_ALU_ARL .or\n" -" vp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n" -" vp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n" -" vp_BINSCop_instruction .emit OP_ALU_BINSC .or\n" -" vp_BINop_instruction .emit OP_ALU_BIN .or\n" -" vp_TRIop_instruction .emit OP_ALU_TRI .or\n" -" vp_SWZ_instruction .emit OP_ALU_SWZ;\n" -"ALUInstruction\n" -" fp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n" -" fp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n" -" fp_BINSCop_instruction .emit OP_ALU_BINSC .or\n" -" fp_BINop_instruction .emit OP_ALU_BIN .or\n" -" fp_TRIop_instruction .emit OP_ALU_TRI .or\n" -" fp_SWZ_instruction .emit OP_ALU_SWZ;\n" -"TexInstruction\n" -" SAMPLE_instruction .emit OP_TEX_SAMPLE .or\n" -" KIL_instruction .emit OP_TEX_KIL;\n" -"ARL_instruction\n" -" \"ARL\" .emit OP_ARL .and space_dst .and maskedAddrReg .and comma .and vp_scalarSrcReg;\n" -"fp_VECTORop_instruction\n" -" fp_VECTORop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg;\n" -"vp_VECTORop_instruction\n" -" vp_VECTORop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg;\n" -"fp_VECTORop\n" -" \"ABS\" .emit OP_ABS .or \"ABS_SAT\" .emit OP_ABS_SAT .or\n" -" \"FLR\" .emit OP_FLR .or \"FLR_SAT\" .emit OP_FLR_SAT .or\n" -" \"FRC\" .emit OP_FRC .or \"FRC_SAT\" .emit OP_FRC_SAT .or\n" -" \"LIT\" .emit OP_LIT .or \"LIT_SAT\" .emit OP_LIT_SAT .or\n" -" \"MOV\" .emit OP_MOV .or \"MOV_SAT\" .emit OP_MOV_SAT;\n" -"vp_VECTORop\n" -" \"ABS\" .emit OP_ABS .or\n" -" \"FLR\" .emit OP_FLR .or\n" -" \"FRC\" .emit OP_FRC .or\n" -" \"LIT\" .emit OP_LIT .or\n" -" \"MOV\" .emit OP_MOV;\n" -"fp_SCALARop_instruction\n" -" fp_SCALARop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg;\n" -"vp_SCALARop_instruction\n" -" vp_SCALARop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg;\n" -"fp_SCALARop\n" -" \"COS\" .emit OP_COS .or \"COS_SAT\" .emit OP_COS_SAT .or\n" -" \"EX2\" .emit OP_EX2 .or \"EX2_SAT\" .emit OP_EX2_SAT .or\n" -" \"LG2\" .emit OP_LG2 .or \"LG2_SAT\" .emit OP_LG2_SAT .or\n" -" \"RCP\" .emit OP_RCP .or \"RCP_SAT\" .emit OP_RCP_SAT .or\n" -" \"RSQ\" .emit OP_RSQ .or \"RSQ_SAT\" .emit OP_RSQ_SAT .or\n" -" \"SIN\" .emit OP_SIN .or \"SIN_SAT\" .emit OP_SIN_SAT .or\n" -" \"SCS\" .emit OP_SCS .or \"SCS_SAT\" .emit OP_SCS_SAT;\n" -"vp_SCALARop\n" -" \"EX2\" .emit OP_EX2 .or\n" -" \"EXP\" .emit OP_EXP .or\n" -" \"LG2\" .emit OP_LG2 .or\n" -" \"LOG\" .emit OP_LOG .or\n" -" \"RCP\" .emit OP_RCP .or\n" -" \"RSQ\" .emit OP_RSQ;\n" -"fp_BINSCop_instruction\n" -" fp_BINSCop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg .and comma .and\n" -" fp_scalarSrcReg;\n" -"vp_BINSCop_instruction\n" -" vp_BINSCop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg .and comma .and\n" -" vp_scalarSrcReg;\n" -"fp_BINSCop\n" -" \"POW\" .emit OP_POW .or \"POW_SAT\" .emit OP_POW_SAT;\n" -"vp_BINSCop\n" -" \"POW\" .emit OP_POW;\n" -"fp_BINop_instruction\n" -" fp_BINop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n" -" vectorSrcReg;\n" -"vp_BINop_instruction\n" -" vp_BINop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n" -" swizzleSrcReg;\n" -"fp_BINop\n" -" \"ADD\" .emit OP_ADD .or \"ADD_SAT\" .emit OP_ADD_SAT .or\n" -" \"DP3\" .emit OP_DP3 .or \"DP3_SAT\" .emit OP_DP3_SAT .or\n" -" \"DP4\" .emit OP_DP4 .or \"DP4_SAT\" .emit OP_DP4_SAT .or\n" -" \"DPH\" .emit OP_DPH .or \"DPH_SAT\" .emit OP_DPH_SAT .or\n" -" \"DST\" .emit OP_DST .or \"DST_SAT\" .emit OP_DST_SAT .or\n" -" \"MAX\" .emit OP_MAX .or \"MAX_SAT\" .emit OP_MAX_SAT .or\n" -" \"MIN\" .emit OP_MIN .or \"MIN_SAT\" .emit OP_MIN_SAT .or\n" -" \"MUL\" .emit OP_MUL .or \"MUL_SAT\" .emit OP_MUL_SAT .or\n" -" \"SGE\" .emit OP_SGE .or \"SGE_SAT\" .emit OP_SGE_SAT .or\n" -" \"SLT\" .emit OP_SLT .or \"SLT_SAT\" .emit OP_SLT_SAT .or\n" -" \"SUB\" .emit OP_SUB .or \"SUB_SAT\" .emit OP_SUB_SAT .or\n" -" \"XPD\" .emit OP_XPD .or \"XPD_SAT\" .emit OP_XPD_SAT;\n" -"vp_BINop\n" -" \"ADD\" .emit OP_ADD .or\n" -" \"DP3\" .emit OP_DP3 .or\n" -" \"DP4\" .emit OP_DP4 .or\n" -" \"DPH\" .emit OP_DPH .or\n" -" \"DST\" .emit OP_DST .or\n" -" \"MAX\" .emit OP_MAX .or\n" -" \"MIN\" .emit OP_MIN .or\n" -" \"MUL\" .emit OP_MUL .or\n" -" \"SGE\" .emit OP_SGE .or\n" -" \"SLT\" .emit OP_SLT .or\n" -" \"SUB\" .emit OP_SUB .or\n" -" \"XPD\" .emit OP_XPD;\n" -"fp_TRIop_instruction\n" -" fp_TRIop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n" -" vectorSrcReg .and comma .and vectorSrcReg;\n" -"vp_TRIop_instruction\n" -" vp_TRIop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n" -" swizzleSrcReg .and comma .and swizzleSrcReg;\n" -"fp_TRIop\n" -" \"CMP\" .emit OP_CMP .or \"CMP_SAT\" .emit OP_CMP_SAT .or\n" -" \"LRP\" .emit OP_LRP .or \"LRP_SAT\" .emit OP_LRP_SAT .or\n" -" \"MAD\" .emit OP_MAD .or \"MAD_SAT\" .emit OP_MAD_SAT;\n" -"vp_TRIop\n" -" \"MAD\" .emit OP_MAD;\n" -"fp_SWZ_instruction\n" -" SWZop .and space_dst .and fp_maskedDstReg .and comma .and fp_srcReg .and comma .and\n" -" fp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n" -"vp_SWZ_instruction\n" -" \"SWZ\" .emit OP_SWZ .and space_dst .and vp_maskedDstReg .and comma .and vp_srcReg .and comma .and\n" -" vp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n" -"SWZop\n" -" \"SWZ\" .emit OP_SWZ .or \"SWZ_SAT\" .emit OP_SWZ_SAT;\n" -"SAMPLE_instruction\n" -" SAMPLEop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n" -" texImageUnit .and comma .and texTarget .error TEX_TARGET_EXPECTED;\n" -"SAMPLEop\n" -" \"TEX\" .emit OP_TEX .or \"TEX_SAT\" .emit OP_TEX_SAT .or\n" -" \"TXB\" .emit OP_TXB .or \"TXB_SAT\" .emit OP_TXB_SAT .or\n" -" \"TXP\" .emit OP_TXP .or \"TXP_SAT\" .emit OP_TXP_SAT;\n" -"KIL_instruction\n" -" \"KIL\" .emit OP_KIL .and space_src .and vectorSrcReg;\n" -"texImageUnit\n" -" \"texture\" .error TEXTURE_EXPECTED .and optTexImageUnitNum;\n" -"texTarget\n" -" \"1D\" .emit TEXTARGET_1D .or\n" -" \"2D\" .emit TEXTARGET_2D .or\n" -" \"3D\" .emit TEXTARGET_3D .or\n" -" .if (texture_rectangle != 0x00) \"RECT\" .emit TEXTARGET_RECT .or\n" -" \"CUBE\" .emit TEXTARGET_CUBE .or\n" -" .if (ARB_fragment_program_shadow != 0x00) shadowTarget .or\n" -" .if (MESA_texture_array != 0x00) arrayTarget;\n" -"shadowTarget\n" -" \"SHADOW1D\" .emit TEXTARGET_SHADOW1D .or\n" -" \"SHADOW2D\" .emit TEXTARGET_SHADOW2D .or\n" -" .if (texture_rectangle != 0x00) \"SHADOWRECT\" .emit TEXTARGET_SHADOWRECT .or\n" -" .if (MESA_texture_array != 0x00) shadowArrayTarget;\n" -"arrayTarget\n" -" \"ARRAY1D\" .emit TEXTARGET_1D_ARRAY .or\n" -" \"ARRAY2D\" .emit TEXTARGET_2D_ARRAY;\n" -"shadowArrayTarget\n" -" \"SHADOWARRAY1D\" .emit TEXTARGET_SHADOW1D_ARRAY .or\n" -" \"SHADOWARRAY2D\" .emit TEXTARGET_SHADOW2D_ARRAY;\n" -"optTexImageUnitNum\n" -" optTexImageUnitNum_1 .or .true .emit 0x00;\n" -"optTexImageUnitNum_1\n" -" lbracket_ne .and texImageUnitNum .and rbracket;\n" -"texImageUnitNum\n" -" integer;\n" -"fp_scalarSrcReg\n" -" optionalSign .and fp_srcReg .and fp_scalarSuffix;\n" -"vp_scalarSrcReg\n" -" optionalSign .and vp_srcReg .and vp_scalarSuffix;\n" -"swizzleSrcReg\n" -" optionalSign .and vp_srcReg .and swizzleSuffix;\n" -"vectorSrcReg\n" -" optionalSign .and fp_srcReg .and optionalSuffix;\n" -"fp_maskedDstReg\n" -" fp_dstReg .and fp_optionalMask;\n" -"vp_maskedDstReg\n" -" vp_dstReg .and vp_optionalMask;\n" -"maskedAddrReg\n" -" addrReg .error ADDRESS_REGISTER_EXPECTED .and addrWriteMask;\n" -"fp_extendedSwizzle\n" -" rgbaExtendedSwizzle .or xyzwExtendedSwizzle;\n" -"vp_extendedSwizzle\n" -" extSwizComp .and comma .and\n" -" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" -" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" -" extSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" -"xyzwExtendedSwizzle\n" -" xyzwExtSwizComp .and comma .and\n" -" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" -" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" -" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" -"rgbaExtendedSwizzle\n" -" rgbaExtendedSwizzle_1 .or rgbaExtendedSwizzle_2 .or rgbaExtendedSwizzle_3 .or\n" -" rgbaExtendedSwizzle_4;\n" -"rgbaExtendedSwizzle_1\n" -" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n" -" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp;\n" -"rgbaExtendedSwizzle_2\n" -" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n" -" rgbaExtSwizComp_alpha .and comma .and rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" -"rgbaExtendedSwizzle_3\n" -" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_alpha .and comma .and\n" -" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" -" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" -"rgbaExtendedSwizzle_4\n" -" rgbaExtSwizComp_alpha .and comma .and \n" -"rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" -" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" -" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" -"xyzwExtSwizComp\n" -" optionalSign .and xyzwExtSwizSel;\n" -"rgbaExtSwizComp\n" -" optionalSign .and rgbaExtSwizSel;\n" -"rgbaExtSwizComp_digit\n" -" optionalSign .and rgbaExtSwizSel_digit;\n" -"rgbaExtSwizComp_alpha\n" -" optionalSign .and rgbaExtSwizSel_alpha;\n" -"extSwizComp\n" -" optionalSign .and extSwizSel;\n" -"xyzwExtSwizSel\n" -" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or xyzwComponent_single;\n" -"rgbaExtSwizSel\n" -" rgbaExtSwizSel_digit .or rgbaExtSwizSel_alpha;\n" -"rgbaExtSwizSel_digit\n" -" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1;\n" -"rgbaExtSwizSel_alpha\n" -" rgbaComponent_single;\n" -"extSwizSel\n" -" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or vp_component_single;\n" -"fp_srcReg\n" -" fp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n" -"vp_srcReg\n" -" vp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n" -"fp_srcReg_1\n" -" fragmentAttribReg .emit REGISTER_ATTRIB .or\n" -" fp_progParamReg .emit REGISTER_PARAM .or\n" -" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n" -"vp_srcReg_1\n" -" vertexAttribReg .emit REGISTER_ATTRIB .or\n" -" vp_progParamReg .emit REGISTER_PARAM .or\n" -" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n" -"fp_dstReg\n" -" fp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n" -"vp_dstReg\n" -" vp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n" -"fp_dstReg_1\n" -" fragmentResultReg .emit REGISTER_RESULT .or\n" -" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n" -"vp_dstReg_1\n" -" vertexResultReg .emit REGISTER_RESULT .or\n" -" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n" -"fragmentAttribReg\n" -" fragAttribBinding;\n" -"vertexAttribReg\n" -" vtxAttribBinding;\n" -"fp_temporaryReg\n" -" fp_establishedName_no_error_on_identifier;\n" -"vp_temporaryReg\n" -" vp_establishedName_no_error_on_identifier;\n" -"fp_progParamReg\n" -" fp_paramSingleItemUse .or fp_progParamReg_1 .or fp_progParamSingle;\n" -"vp_progParamReg\n" -" vp_paramSingleItemUse .or vp_progParamReg_1 .or vp_progParamSingle;\n" -"fp_progParamReg_1\n" -" fp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayAbs .and\n" -" rbracket;\n" -"vp_progParamReg_1\n" -" vp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayMem .and\n" -" rbracket;\n" -"fp_progParamSingle\n" -" .false;\n" -"vp_progParamSingle\n" -" .false;\n" -"fp_progParamArray\n" -" fp_establishedName_no_error_on_identifier;\n" -"vp_progParamArray\n" -" vp_establishedName_no_error_on_identifier;\n" -"progParamArrayMem\n" -" progParamArrayAbs .or progParamArrayRel;\n" -"progParamArrayAbs\n" -" integer_ne .emit ARRAY_INDEX_ABSOLUTE;\n" -"progParamArrayRel\n" -" addrReg .error ADDRESS_REGISTER_OR_INTEGER_EXPECTED .emit ARRAY_INDEX_RELATIVE .and\n" -" addrComponent .and addrRegRelOffset;\n" -"addrRegRelOffset\n" -" addrRegRelOffset_1 .or addrRegRelOffset_2 .or .true .emit 0x00;\n" -"addrRegRelOffset_1\n" -" plus_ne .and addrRegPosOffset;\n" -"addrRegRelOffset_2\n" -" minus_ne .and addrRegNegOffset;\n" -"addrRegPosOffset\n" -" integer_0_63;\n" -"addrRegNegOffset\n" -" integer_0_64;\n" -"fragmentResultReg\n" -" fp_resultBinding;\n" -"vertexResultReg\n" -" vp_resultBinding;\n" -"addrReg\n" -" vp_establishedName_no_error_on_identifier;\n" -"addrComponent\n" -" dot .and \"x\" .error INVALID_ADDRESS_COMPONENT .emit COMPONENT_X .emit COMPONENT_X\n" -" .emit COMPONENT_X .emit COMPONENT_X;\n" -"addrWriteMask\n" -" dot .and \"x\" .error INVALID_ADDRESS_WRITEMASK .emit 0x08;\n" -"fp_scalarSuffix\n" -" dot .and fp_component_single .error INVALID_COMPONENT;\n" -"vp_scalarSuffix\n" -" dot .and vp_component_single .error INVALID_COMPONENT;\n" -"swizzleSuffix\n" -" swizzleSuffix_1 .or\n" -" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n" -"swizzleSuffix_1\n" -" dot_ne .and swizzleSuffix_2 .error INVALID_SUFFIX;\n" -"swizzleSuffix_2\n" -" swizzleSuffix_3 .or swizzleSuffix_4;\n" -"swizzleSuffix_3\n" -" vp_component_multi .and vp_component_multi .and vp_component_multi .error INVALID_COMPONENT .and\n" -" vp_component_multi .error INVALID_COMPONENT;\n" -"swizzleSuffix_4\n" -" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n" -" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n" -" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n" -" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n" -"optionalSuffix\n" -" optionalSuffix_1 .or\n" -" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n" -"optionalSuffix_1\n" -" dot_ne .and optionalSuffix_2 .error INVALID_SUFFIX;\n" -"optionalSuffix_2\n" -" optionalSuffix_3 .or optionalSuffix_4 .or optionalSuffix_5;\n" -"optionalSuffix_3\n" -" xyzwComponent_multi .and xyzwComponent_multi .and\n" -" xyzwComponent_multi .error INVALID_COMPONENT .and xyzwComponent_multi .error INVALID_COMPONENT;\n" -"optionalSuffix_4\n" -" rgbaComponent_multi .and rgbaComponent_multi .and\n" -" rgbaComponent_multi .error INVALID_COMPONENT .and rgbaComponent_multi .error INVALID_COMPONENT;\n" -"optionalSuffix_5\n" -" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n" -" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n" -" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n" -" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .or\n" -" \"r\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n" -" \"g\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n" -" \"b\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n" -" \"a\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n" -"fp_component_single\n" -" xyzwComponent_single .or rgbaComponent_single;\n" -"vp_component_multi\n" -" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n" -" 'w' .emit COMPONENT_W;\n" -"vp_component_single\n" -" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n" -" \"w\" .emit COMPONENT_W;\n" -"xyzwComponent_multi\n" -" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n" -" 'w' .emit COMPONENT_W;\n" -"xyzwComponent_single\n" -" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n" -" \"w\" .emit COMPONENT_W;\n" -"rgbaComponent_multi\n" -" 'r' .emit COMPONENT_X .or 'g' .emit COMPONENT_Y .or 'b' .emit COMPONENT_Z .or\n" -" 'a' .emit COMPONENT_W;\n" -"rgbaComponent_single\n" -" \"r\" .emit COMPONENT_X .or \"g\" .emit COMPONENT_Y .or \"b\" .emit COMPONENT_Z .or\n" -" \"a\" .emit COMPONENT_W;\n" -"fp_optionalMask\n" -" rgbaMask .or xyzwMask .or .true .emit 0x0F;\n" -"vp_optionalMask\n" -" xyzwMask .or .true .emit 0x0F;\n" -"xyzwMask\n" -" dot_ne .and xyzwMask_1 .error INVALID_WRITEMASK;\n" -"xyzwMask_1\n" -" \"xyzw\" .emit 0x0F .or \"xyz\" .emit 0x0E .or \"xyw\" .emit 0x0D .or \"xy\" .emit 0x0C .or\n" -" \"xzw\" .emit 0x0B .or \"xz\" .emit 0x0A .or \"xw\" .emit 0x09 .or \"x\" .emit 0x08 .or\n" -" \"yzw\" .emit 0x07 .or \"yz\" .emit 0x06 .or \"yw\" .emit 0x05 .or \"y\" .emit 0x04 .or\n" -" \"zw\" .emit 0x03 .or \"z\" .emit 0x02 .or \"w\" .emit 0x01;\n" -"rgbaMask\n" -" dot_ne .and rgbaMask_1;\n" -"rgbaMask_1\n" -" \"rgba\" .emit 0x0F .or \"rgb\" .emit 0x0E .or \"rga\" .emit 0x0D .or \"rg\" .emit 0x0C .or\n" -" \"rba\" .emit 0x0B .or \"rb\" .emit 0x0A .or \"ra\" .emit 0x09 .or \"r\" .emit 0x08 .or\n" -" \"gba\" .emit 0x07 .or \"gb\" .emit 0x06 .or \"ga\" .emit 0x05 .or \"g\" .emit 0x04 .or\n" -" \"ba\" .emit 0x03 .or \"b\" .emit 0x02 .or \"a\" .emit 0x01;\n" -"fp_namingStatement\n" -" fp_ATTRIB_statement .emit ATTRIB .or\n" -" fp_PARAM_statement .emit PARAM .or\n" -" fp_TEMP_statement .emit TEMP .or\n" -" fp_OUTPUT_statement .emit OUTPUT .or\n" -" fp_ALIAS_statement .emit ALIAS;\n" -"vp_namingStatement\n" -" vp_ATTRIB_statement .emit ATTRIB .or\n" -" vp_PARAM_statement .emit PARAM .or\n" -" vp_TEMP_statement .emit TEMP .or\n" -" ADDRESS_statement .emit ADDRESS .or\n" -" vp_OUTPUT_statement .emit OUTPUT .or\n" -" vp_ALIAS_statement .emit ALIAS;\n" -"fp_ATTRIB_statement\n" -" \"ATTRIB\" .and space .and fp_establishName .and equal .and\n" -" fragAttribBinding .error FRAGMENT_EXPECTED;\n" -"vp_ATTRIB_statement\n" -" \"ATTRIB\" .and space .and vp_establishName .and equal .and\n" -" vtxAttribBinding .error VERTEX_EXPECTED;\n" -"fragAttribBinding\n" -" \"fragment\" .and dot .and fragAttribItem .error INVALID_FRAGMENT_PROPERTY;\n" -"vtxAttribBinding\n" -" \"vertex\" .and dot .and vtxAttribItem .error INVALID_VERTEX_PROPERTY;\n" -"fragAttribItem\n" -" fragAttribItem_1 .emit FRAGMENT_ATTRIB_COLOR .or\n" -" fragAttribItem_2 .emit FRAGMENT_ATTRIB_TEXCOORD .or\n" -" .if (fog_coord != 0x00) \"fogcoord\" .emit FRAGMENT_ATTRIB_FOGCOORD .or\n" -" \"position\" .emit FRAGMENT_ATTRIB_POSITION;\n" -"fragAttribItem_1\n" -" \"color\" .and optColorType;\n" -"fragAttribItem_2\n" -" \"texcoord\" .and optTexCoordNum;\n" -"vtxAttribItem\n" -" \"position\" .emit VERTEX_ATTRIB_POSITION .or\n" -" .if (vertex_blend != 0x00) vtxAttribItem_1 .emit VERTEX_ATTRIB_WEIGHT .or\n" -" \"normal\" .emit VERTEX_ATTRIB_NORMAL .or\n" -" vtxAttribItem_2 .emit VERTEX_ATTRIB_COLOR .or\n" -" \"fogcoord\" .emit VERTEX_ATTRIB_FOGCOORD .or\n" -" vtxAttribItem_3 .emit VERTEX_ATTRIB_TEXCOORD .or\n" -" .if (matrix_palette != 0x00) vtxAttribItem_4 .emit VERTEX_ATTRIB_MATRIXINDEX .or\n" -" vtxAttribItem_5 .emit VERTEX_ATTRIB_GENERIC;\n" -"vtxAttribItem_1\n" -" \"weight\" .and vtxOptWeightNum;\n" -"vtxAttribItem_2\n" -" \"color\" .and optColorType;\n" -"vtxAttribItem_3\n" -" \"texcoord\" .and optTexCoordNum;\n" -"vtxAttribItem_4\n" -" \"matrixindex\" .and lbracket .and vtxWeightNum .and rbracket;\n" -"vtxAttribItem_5\n" -" \"attrib\" .and lbracket .and vtxAttribNum .and rbracket;\n" -"vtxAttribNum\n" -" integer;\n" -"vtxOptWeightNum\n" -" vtxOptWeightNum_1 .or .true .emit 0x00;\n" -"vtxOptWeightNum_1\n" -" lbracket_ne .and vtxWeightNum .and rbracket;\n" -"vtxWeightNum\n" -" integer;\n" -"fp_PARAM_statement\n" -" fp_PARAM_multipleStmt .or fp_PARAM_singleStmt;\n" -"vp_PARAM_statement\n" -" vp_PARAM_multipleStmt .or vp_PARAM_singleStmt;\n" -"fp_PARAM_singleStmt\n" -" \"PARAM\" .and space .and fp_establishName .and .true .emit 0x00 .and fp_paramSingleInit .and\n" -" .true .emit PARAM_NULL;\n" -"vp_PARAM_singleStmt\n" -" \"PARAM\" .and space .and vp_establishName .and .true .emit 0x00 .and vp_paramSingleInit .and\n" -" .true .emit PARAM_NULL;\n" -"fp_PARAM_multipleStmt\n" -" \"PARAM\" .and space .and fp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n" -" fp_paramMultipleInit .and .true .emit PARAM_NULL;\n" -"vp_PARAM_multipleStmt\n" -" \"PARAM\" .and space .and vp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n" -" vp_paramMultipleInit .and .true .emit PARAM_NULL;\n" -"optArraySize\n" -" optional_integer;\n" -"fp_paramSingleInit\n" -" equal .and fp_paramSingleItemDecl;\n" -"vp_paramSingleInit\n" -" equal .and vp_paramSingleItemDecl;\n" -"fp_paramMultipleInit\n" -" equal .and lbrace .and fp_paramMultInitList .and rbrace;\n" -"vp_paramMultipleInit\n" -" equal .and lbrace .and vp_paramMultInitList .and rbrace;\n" -"fp_paramMultInitList\n" -" fp_paramMultInitList_1 .or fp_paramMultipleItem;\n" -"vp_paramMultInitList\n" -" vp_paramMultInitList_1 .or vp_paramMultipleItem;\n" -"fp_paramMultInitList_1\n" -" fp_paramMultipleItem .and comma_ne .and fp_paramMultInitList;\n" -"vp_paramMultInitList_1\n" -" vp_paramMultipleItem .and comma_ne .and vp_paramMultInitList;\n" -"fp_paramSingleItemDecl\n" -" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n" -" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n" -" paramConstDecl .emit PARAM_CONSTANT;\n" -"vp_paramSingleItemDecl\n" -" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n" -" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n" -" paramConstDecl .emit PARAM_CONSTANT;\n" -"fp_paramSingleItemUse\n" -" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n" -" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n" -" paramConstUse .emit PARAM_CONSTANT;\n" -"vp_paramSingleItemUse\n" -" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n" -" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n" -" paramConstUse .emit PARAM_CONSTANT;\n" -"fp_paramMultipleItem\n" -" fp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n" -" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n" -" paramConstDecl .emit PARAM_CONSTANT;\n" -"vp_paramMultipleItem\n" -" vp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n" -" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n" -" paramConstDecl .emit PARAM_CONSTANT;\n" -"fp_stateMultipleItem\n" -" stateMultipleItem_1 .or fp_stateSingleItem;\n" -"vp_stateMultipleItem\n" -" stateMultipleItem_1 .or vp_stateSingleItem;\n" -"stateMultipleItem_1\n" -" \"state\" .and dot .and stateMatrixRows .emit STATE_MATRIX_ROWS;\n" -"fp_stateSingleItem\n" -" \"state\" .and dot .and fp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n" -"vp_stateSingleItem\n" -" \"state\" .and dot .and vp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n" -"fp_stateSingleItem_1\n" -" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n" -" stateSingleItem_5 .or stateSingleItem_7 .or stateSingleItem_8 .or stateSingleItem_11;\n" -"vp_stateSingleItem_1\n" -" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n" -" stateSingleItem_6 .or stateSingleItem_7 .or stateSingleItem_9 .or stateSingleItem_10 .or\n" -" stateSingleItem_11;\n" -"stateSingleItem_1\n" -" stateMaterialItem .emit STATE_MATERIAL;\n" -"stateSingleItem_2\n" -" stateLightItem .emit STATE_LIGHT;\n" -"stateSingleItem_3\n" -" stateLightModelItem .emit STATE_LIGHT_MODEL;\n" -"stateSingleItem_4\n" -" stateLightProdItem .emit STATE_LIGHT_PROD;\n" -"stateSingleItem_5\n" -" stateTexEnvItem .emit STATE_TEX_ENV;\n" -"stateSingleItem_6\n" -" stateTexGenItem .emit STATE_TEX_GEN;\n" -"stateSingleItem_7\n" -" stateFogItem .emit STATE_FOG;\n" -"stateSingleItem_8\n" -" stateDepthItem .emit STATE_DEPTH;\n" -"stateSingleItem_9\n" -" stateClipPlaneItem .emit STATE_CLIP_PLANE;\n" -"stateSingleItem_10\n" -" statePointItem .emit STATE_POINT;\n" -"stateSingleItem_11\n" -" stateMatrixRow .emit STATE_MATRIX_ROWS;\n" -"stateMaterialItem\n" -" \"material\" .and optFaceType .and dot .and stateMatProperty .error INVALID_MATERIAL_PROPERTY;\n" -"stateMatProperty\n" -" \"ambient\" .emit MATERIAL_AMBIENT .or\n" -" \"diffuse\" .emit MATERIAL_DIFFUSE .or\n" -" \"specular\" .emit MATERIAL_SPECULAR .or\n" -" \"emission\" .emit MATERIAL_EMISSION .or\n" -" \"shininess\" .emit MATERIAL_SHININESS;\n" -"stateLightItem\n" -" \"light\" .and lbracket .and stateLightNumber .and rbracket .and dot .and\n" -" stateLightProperty .error INVALID_LIGHT_PROPERTY;\n" -"stateLightProperty\n" -" \"ambient\" .emit LIGHT_AMBIENT .or\n" -" \"diffuse\" .emit LIGHT_DIFFUSE .or\n" -" \"specular\" .emit LIGHT_SPECULAR .or\n" -" \"position\" .emit LIGHT_POSITION .or\n" -" \"attenuation\" .emit LIGHT_ATTENUATION .or\n" -" stateLightProperty_1 .emit LIGHT_SPOT_DIRECTION .or\n" -" \"half\" .emit LIGHT_HALF;\n" -"stateLightProperty_1\n" -" \"spot\" .and dot .and stateSpotProperty .error INVALID_SPOT_PROPERTY;\n" -"stateSpotProperty\n" -" \"direction\";\n" -"stateLightModelItem\n" -" \"lightmodel\" .and stateLModProperty .error INVALID_LIGHTMODEL_PROPERTY;\n" -"stateLModProperty\n" -" stateLModProperty_1 .or stateLModProperty_2;\n" -"stateLModProperty_1\n" -" dot .and \"ambient\" .emit LIGHT_MODEL_AMBIENT;\n" -"stateLModProperty_2\n" -" stateLModProperty_3 .emit LIGHT_MODEL_SCENECOLOR;\n" -"stateLModProperty_3\n" -" optFaceType .and dot .and \"scenecolor\";\n" -"stateLightProdItem\n" -" \"lightprod\" .and lbracket .and stateLightNumber .and rbracket .and optFaceType .and dot .and\n" -" stateLProdProperty .error INVALID_LIGHTPROD_PROPERTY;\n" -"stateLProdProperty\n" -" \"ambient\" .emit LIGHT_PROD_AMBIENT .or\n" -" \"diffuse\" .emit LIGHT_PROD_DIFFUSE .or\n" -" \"specular\" .emit LIGHT_PROD_SPECULAR;\n" -"stateLightNumber\n" -" integer;\n" -"stateTexEnvItem\n" -" \"texenv\" .and optLegacyTexUnitNum .and dot .and\n" -" stateTexEnvProperty .error INVALID_TEXENV_PROPERTY;\n" -"stateTexEnvProperty\n" -" \"color\" .emit TEX_ENV_COLOR;\n" -"optLegacyTexUnitNum\n" -" optLegacyTexUnitNum_1 .or .true .emit 0x00;\n" -"optLegacyTexUnitNum_1\n" -" lbracket_ne .and legacyTexUnitNum .and rbracket;\n" -"legacyTexUnitNum\n" -" integer;\n" -"stateTexGenItem\n" -" \"texgen\" .and optTexCoordNum .and dot .and stateTexGenType .error INVALID_TEXGEN_PROPERTY .and\n" -" dot .and stateTexGenCoord .error INVALID_TEXGEN_COORD;\n" -"stateTexGenType\n" -" \"eye\" .emit TEX_GEN_EYE .or\n" -" \"object\" .emit TEX_GEN_OBJECT;\n" -"stateTexGenCoord\n" -" \"s\" .emit COMPONENT_X .or\n" -" \"t\" .emit COMPONENT_Y .or\n" -" \"r\" .emit COMPONENT_Z .or\n" -" \"q\" .emit COMPONENT_W;\n" -"stateFogItem\n" -" \"fog\" .and dot .and stateFogProperty .error INVALID_FOG_PROPERTY;\n" -"stateFogProperty\n" -" \"color\" .emit FOG_COLOR .or\n" -" \"params\" .emit FOG_PARAMS;\n" -"stateDepthItem\n" -" \"depth\" .and dot .and stateDepthProperty .error INVALID_DEPTH_PROPERTY;\n" -"stateDepthProperty\n" -" \"range\" .emit DEPTH_RANGE;\n" -"stateClipPlaneItem\n" -" \"clip\" .and lbracket .and stateClipPlaneNum .and rbracket .and dot .and\n" -" \"plane\" .error INVALID_CLIPPLANE_PROPERTY;\n" -"stateClipPlaneNum\n" -" integer;\n" -"statePointItem\n" -" \"point\" .and dot .and statePointProperty .error INVALID_POINT_PROPERTY;\n" -"statePointProperty\n" -" \"size\" .emit POINT_SIZE .or\n" -" .if (point_parameters != 0x00) \"attenuation\" .emit POINT_ATTENUATION;\n" -"stateMatrixRow\n" -" stateMatrixItem .and dot .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and\n" -" lbracket .and stateMatrixRowNum .and rbracket .emit 0x0;\n" -"stateMatrixRows\n" -" stateMatrixItem .and optMatrixRows;\n" -"optMatrixRows\n" -" optMatrixRows_1 .or .true .emit 0x0 .emit '3' .emit 0x0 .emit $;\n" -"optMatrixRows_1\n" -" dot_ne .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and lbracket .and\n" -" stateMatrixRowNum .and dotdot .and stateMatrixRowNum .and rbracket;\n" -"stateMatrixItem\n" -" \"matrix\" .and dot .and stateMatrixName .error INVALID_MATRIX_NAME .and stateOptMatModifier;\n" -"stateOptMatModifier\n" -" stateOptMatModifier_1 .or .true .emit MATRIX_MODIFIER_IDENTITY;\n" -"stateOptMatModifier_1\n" -" dot_ne .and stateMatModifier;\n" -"stateMatModifier\n" -" \"inverse\" .emit MATRIX_MODIFIER_INVERSE .or\n" -" \"transpose\" .emit MATRIX_MODIFIER_TRANSPOSE .or\n" -" \"invtrans\" .emit MATRIX_MODIFIER_INVTRANS;\n" -"stateMatrixRowNum\n" -" integer_0_3;\n" -"stateMatrixName\n" -" stateMatrixName_1_1 .emit MATRIX_MODELVIEW .or\n" -" \"projection\" .emit MATRIX_PROJECTION .or\n" -" \"mvp\" .emit MATRIX_MVP .or\n" -" stateMatrixName_1_2 .emit MATRIX_TEXTURE .or\n" -" .if (matrix_palette != 0x00) stateMatrixName_1_3 .emit MATRIX_PALETTE .or\n" -" stateMatrixName_1_4 .emit MATRIX_PROGRAM;\n" -"stateMatrixName_1_1\n" -" \"modelview\" .and stateOptModMatNum;\n" -"stateMatrixName_1_2\n" -" \"texture\" .and optTexCoordNum;\n" -"stateMatrixName_1_3\n" -" \"palette\" .and lbracket .and statePaletteMatNum .and rbracket;\n" -"stateMatrixName_1_4\n" -" \"program\" .and lbracket .and stateProgramMatNum .and rbracket;\n" -"stateOptModMatNum\n" -" .if (vertex_blend != 0x00) stateOptModMatNum_1 .or\n" -" .true .emit 0x00;\n" -"stateOptModMatNum_1\n" -" lbracket_ne .and stateModMatNum .and rbracket;\n" -"stateModMatNum\n" -" integer;\n" -"optTexCoordNum\n" -" optTexCoordNum_1 .or .true .emit 0x00;\n" -"optTexCoordNum_1\n" -" lbracket_ne .and texCoordNum .and rbracket;\n" -"texCoordNum\n" -" integer;\n" -"statePaletteMatNum\n" -" integer;\n" -"stateProgramMatNum\n" -" integer;\n" -"programSingleItem\n" -" \"program\" .and dot .and programSingleItem_1 .error INVALID_PROGRAM_PROPERTY;\n" -"programSingleItem_1\n" -" progEnvParam .or progLocalParam;\n" -"programMultipleItem\n" -" \"program\" .and dot .and programMultipleItem_1 .error INVALID_PROGRAM_PROPERTY;\n" -"programMultipleItem_1\n" -" progEnvParams .or progLocalParams;\n" -"progEnvParams\n" -" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNums .and rbracket;\n" -"progEnvParamNums\n" -" progEnvParamNums_1 .or progEnvParamNums_2;\n" -"progEnvParamNums_1\n" -" progEnvParamNum .and dotdot_ne .and progEnvParamNum;\n" -"progEnvParamNums_2\n" -" progEnvParamNum .and .true .emit 0x00;\n" -"progEnvParam\n" -" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;\n" -"progLocalParams\n" -" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;\n" -"progLocalParamNums\n" -" progLocalParamNums_1 .or progLocalParamNums_2;\n" -"progLocalParamNums_1\n" -" progLocalParamNum .and dotdot_ne .and progLocalParamNum;\n" -"progLocalParamNums_2\n" -" progLocalParamNum .and .true .emit 0x00;\n" -"progLocalParam\n" -" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;\n" -"progEnvParamNum\n" -" integer;\n" -"progLocalParamNum\n" -" integer;\n" -"paramConstDecl\n" -" paramConstScalarDecl .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n" -"paramConstUse\n" -" paramConstScalarUse .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n" -"paramConstScalarDecl\n" -" signedFloatConstant;\n" -"paramConstScalarUse\n" -" floatConstant;\n" -"paramConstVector\n" -" paramConstVector_4 .emit 0x04 .or paramConstVector_3 .emit 0x03 .or\n" -" paramConstVector_2 .emit 0x02 .or paramConstVector_1 .emit 0x01;\n" -"paramConstVector_1\n" -" lbrace_ne .and signedFloatConstant .and rbrace;\n" -"paramConstVector_2\n" -" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n" -"paramConstVector_3\n" -" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n" -" signedFloatConstant .and rbrace;\n" -"paramConstVector_4\n" -" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n" -" signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n" -"signedFloatConstant\n" -" optionalSign .and floatConstant;\n" -"floatConstant\n" -" float;\n" -"optionalSign\n" -" optional_sign_ne;\n" -"fp_TEMP_statement\n" -" \"TEMP\" .and space .and fp_varNameList .and .true .emit 0x00;\n" -"vp_TEMP_statement\n" -" \"TEMP\" .and space .and vp_varNameList .and .true .emit 0x00;\n" -"ADDRESS_statement\n" -" \"ADDRESS\" .and space .and vp_varNameList .and .true .emit 0x00;\n" -"fp_varNameList\n" -" fp_varNameList_1 .or fp_establishName;\n" -"vp_varNameList\n" -" vp_varNameList_1 .or vp_establishName;\n" -"fp_varNameList_1\n" -" fp_establishName .and comma_ne .and fp_varNameList;\n" -"vp_varNameList_1\n" -" vp_establishName .and comma_ne .and vp_varNameList;\n" -"fp_OUTPUT_statement\n" -" \"OUTPUT\" .and space .and fp_establishName .and equal .and\n" -" fp_resultBinding .error RESULT_EXPECTED;\n" -"vp_OUTPUT_statement\n" -" \"OUTPUT\" .and space .and vp_establishName .and equal .and\n" -" vp_resultBinding .error RESULT_EXPECTED;\n" -"fp_resultBinding\n" -" \"result\" .and dot .and fp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n" -"vp_resultBinding\n" -" \"result\" .and dot .and vp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n" -"fp_resultBinding_1\n" -" fp_resultBinding_2 .emit FRAGMENT_RESULT_COLOR .or\n" -" \"depth\" .emit FRAGMENT_RESULT_DEPTH;\n" -"fp_resultBinding_2\n" -" \"color\" .and optOutputColorNum;\n" -"vp_resultBinding_1\n" -" .if (ARB_position_invariant == 0x00) \"position\" .emit VERTEX_RESULT_POSITION .or\n" -" resultColBinding .emit VERTEX_RESULT_COLOR .or\n" -" \"fogcoord\" .emit VERTEX_RESULT_FOGCOORD .or\n" -" \"pointsize\" .emit VERTEX_RESULT_POINTSIZE .or\n" -" vp_resultBinding_2 .emit VERTEX_RESULT_TEXCOORD;\n" -"vp_resultBinding_2\n" -" \"texcoord\" .and optTexCoordNum;\n" -"optOutputColorNum\n" -" .if (ARB_draw_buffers != 0x00) optOutputColorNum_1 .or .true .emit 0x00;\n" -"optOutputColorNum_1\n" -" lbracket_ne .and outputColorNum .and rbracket;\n" -"outputColorNum\n" -" integer;\n" -"resultColBinding\n" -" \"color\" .and optFaceType .and optColorType;\n" -"optFaceType\n" -" FaceType .or .true .emit FACE_FRONT;\n" -"FaceType\n" -" dot_ne .and FaceProperty;\n" -"FaceProperty\n" -" \"front\" .emit FACE_FRONT .or \"back\" .emit FACE_BACK;\n" -"optColorType\n" -" ColorType .or .true .emit COLOR_PRIMARY;\n" -"ColorType\n" -" dot_ne .and ColorProperty;\n" -"ColorProperty\n" -" \"primary\" .emit COLOR_PRIMARY .or\n" -" .if (secondary_color != 0x00) \"secondary\" .emit COLOR_SECONDARY;\n" -"fp_ALIAS_statement\n" -" \"ALIAS\" .and fp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and fp_establishedName;\n" -"vp_ALIAS_statement\n" -" \"ALIAS\" .and vp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and vp_establishedName;\n" -"fp_ALIAS_statement_1\n" -" space .and fp_establishName;\n" -"vp_ALIAS_statement_1\n" -" space .and vp_establishName;\n" -"fp_establishName\n" -" fp_identifier;\n" -"vp_establishName\n" -" vp_identifier;\n" -"fp_establishedName\n" -" fp_identifier;\n" -"vp_establishedName\n" -" vp_identifier;\n" -"fp_establishedName_no_error_on_identifier\n" -" fp_identifier_ne;\n" -"vp_establishedName_no_error_on_identifier\n" -" vp_identifier_ne;\n" -"fp_identifier\n" -" fp_identifier_ne .error IDENTIFIER_EXPECTED;\n" -"vp_identifier\n" -" vp_identifier_ne .error IDENTIFIER_EXPECTED;\n" -"fp_identifier_ne\n" -" fp_not_reserved_identifier .and identifier_ne;\n" -"vp_identifier_ne\n" -" vp_not_reserved_identifier .and identifier_ne;\n" -"fp_not_reserved_identifier\n" -" fp_not_reserved_identifier_1 .or .true;\n" -"fp_not_reserved_identifier_1\n" -" fp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n" -"vp_not_reserved_identifier\n" -" vp_not_reserved_identifier_1 .or .true;\n" -"vp_not_reserved_identifier_1\n" -" vp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n" -"fp_reserved_identifier\n" -" \"ABS\" .or \"ABS_SAT\" .or \"ADD\" .or \"ADD_SAT\" .or \"ALIAS\" .or \"ATTRIB\" .or \"CMP\" .or \"CMP_SAT\" .or\n" -" \"COS\" .or \"COS_SAT\" .or \"DP3\" .or \"DP3_SAT\" .or \"DP4\" .or \"DP4_SAT\" .or \"DPH\" .or \"DPH_SAT\" .or\n" -" \"DST\" .or \"DST_SAT\" .or \"END\" .or \"EX2\" .or \"EX2_SAT\" .or \"FLR\" .or \"FLR_SAT\" .or \"FRC\" .or\n" -" \"FRC_SAT\" .or \"KIL\" .or \"LG2\" .or \"LG2_SAT\" .or \"LIT\" .or \"LIT_SAT\" .or \"LRP\" .or \"LRP_SAT\" .or\n" -" \"MAD\" .or \"MAD_SAT\" .or \"MAX\" .or \"MAX_SAT\" .or \"MIN\" .or \"MIN_SAT\" .or \"MOV\" .or \"MOV_SAT\" .or\n" -" \"MUL\" .or \"MUL_SAT\" .or \"OPTION\" .or \"OUTPUT\" .or \"PARAM\" .or \"POW\" .or \"POW_SAT\" .or \"RCP\" .or\n" -" \"RCP_SAT\" .or \"RSQ\" .or \"RSQ_SAT\" .or \"SIN\" .or \"SIN_SAT\" .or \"SCS\" .or \"SCS_SAT\" .or \"SGE\" .or\n" -" \"SGE_SAT\" .or \"SLT\" .or \"SLT_SAT\" .or \"SUB\" .or \"SUB_SAT\" .or \"SWZ\" .or \"SWZ_SAT\" .or \"TEMP\" .or\n" -" \"TEX\" .or \"TEX_SAT\" .or \"TXB\" .or \"TXB_SAT\" .or \"TXP\" .or \"TXP_SAT\" .or \"XPD\" .or \"XPD_SAT\" .or\n" -" \"fragment\" .or \"program\" .or \"result\" .or \"state\" .or \"texture\";\n" -"vp_reserved_identifier\n" -" \"ABS\" .or \"ADD\" .or \"ADDRESS\" .or \"ALIAS\" .or \"ARL\" .or \"ATTRIB\" .or \"DP3\" .or \"DP4\" .or\n" -" \"DPH\" .or \"DST\" .or \"END\" .or \"EX2\" .or \"EXP\" .or \"FLR\" .or \"FRC\" .or \"LG2\" .or \"LIT\" .or\n" -" \"LOG\" .or \"MAD\" .or \"MAX\" .or \"MIN\" .or \"MOV\" .or \"MUL\" .or \"OPTION\" .or \"OUTPUT\" .or\n" -" \"PARAM\" .or \"POW\" .or \"RCP\" .or \"RSQ\" .or \"SGE\" .or \"SLT\" .or \"SUB\" .or \"SWZ\" .or \"TEMP\" .or\n" -" \"XPD\" .or \"program\" .or \"result\" .or \"state\" .or \"vertex\";\n" -"integer\n" -" integer_ne .error INTEGER_EXPECTED;\n" -"zero\n" -" '0';\n" -"leading_zeroes\n" -" .loop zero;\n" -"no_digit\n" -" no_digit_1 .or .true;\n" -"no_digit_1\n" -" digit10 .and .false .error INTEGER_OUT_OF_RANGE;\n" -"all_zeroes\n" -" all_zeroes_1 .or no_digit_1;\n" -"all_zeroes_1\n" -" '0' .and .loop zero .and no_digit;\n" -"integer_0_3\n" -" integer_0_3_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n" -"integer_0_3_1\n" -" integer_0_3_2 .or all_zeroes .emit '0';\n" -"integer_0_3_2 \n" -" leading_zeroes .and '1'-'3' .emit * .and no_digit;\n" -"integer_0_63\n" -" integer_0_63_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n" -"integer_0_63_1\n" -" integer_0_63_2 .or integer_0_63_3 .or integer_0_63_4 .or integer_0_63_5 .or\n" -" all_zeroes .emit '0';\n" -"integer_0_63_2 \n" -" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n" -"integer_0_63_3 \n" -" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n" -"integer_0_63_4 \n" -" leading_zeroes .and '6' .emit * .and '0'-'3' .emit * .and no_digit;\n" -"integer_0_63_5 \n" -" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n" -"integer_0_64\n" -" integer_0_64_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n" -"integer_0_64_1\n" -" integer_0_64_2 .or integer_0_64_3 .or integer_0_64_4 .or integer_0_64_5 .or\n" -" all_zeroes .emit '0';\n" -"integer_0_64_2 \n" -" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n" -"integer_0_64_3 \n" -" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n" -"integer_0_64_4 \n" -" leading_zeroes .and '6' .emit * .and '0'-'4' .emit * .and no_digit;\n" -"integer_0_64_5 \n" -" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n" -"optional_space\n" -" space .or .true;\n" -"space_dst\n" -" space .error OPERATION_NEEDS_DESTINATION_VARIABLE;\n" -"space_src\n" -" space .error OPERATION_NEEDS_SOURCE_VARIABLE;\n" -"space\n" -" single_space .and .loop single_space;\n" -"single_space\n" -" white_char .or comment_block;\n" -"white_char\n" -" ' ' .or '\\t' .or '\\n' .or '\\r';\n" -"comment_block\n" -" '#' .and .loop comment_char .and optional_new_line;\n" -"comment_char\n" -" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n" -"optional_new_line\n" -" '\\n' .or crlf .or .true;\n" -"crlf\n" -" '\\r' .and '\\n';\n" -"semicolon\n" -" optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\n" -"comma\n" -" optional_space .and ',' .error MISSING_COMMA .and optional_space;\n" -"comma_ne\n" -" optional_space .and ',' .and optional_space;\n" -"lbracket\n" -" optional_space .and '[' .error MISSING_LBRACKET .and optional_space;\n" -"lbracket_ne\n" -" optional_space .and '[' .and optional_space;\n" -"rbracket\n" -" optional_space .and ']' .error MISSING_RBRACKET .and optional_space;\n" -"dot\n" -" optional_space .and '.' .error MISSING_DOT .and optional_space;\n" -"dot_ne\n" -" optional_space .and '.' .and optional_space;\n" -"equal\n" -" optional_space .and '=' .error MISSING_EQUAL .and optional_space;\n" -"lbrace\n" -" optional_space .and '{' .error MISSING_LBRACE .and optional_space;\n" -"lbrace_ne\n" -" optional_space .and '{' .and optional_space;\n" -"rbrace\n" -" optional_space .and '}' .error MISSING_RBRACE .and optional_space;\n" -"dotdot\n" -" optional_space .and '.' .and '.' .error MISSING_DOTDOT .and optional_space;\n" -"dotdot_ne\n" -" optional_space .and '.' .and '.' .and optional_space;\n" -"float\n" -" float_1 .or float_2 .or float_legacy;\n" -"float_1\n" -" '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;\n" -"float_2\n" -" integer_ne .and float_3;\n" -"float_3\n" -" float_4 .or float_5;\n" -"float_4\n" -" '.' .and optional_integer .and optional_exponent;\n" -"float_5\n" -" exponent .emit 0x00;\n" -"float_legacy\n" -" integer_ne .and .true .emit 0x00 .emit 0x00;\n" -"integer_ne\n" -" integer_ne_1 .and .true .emit 0x00 .emit $;\n" -"integer_ne_1\n" -" digit10 .emit * .and .loop digit10 .emit *;\n" -"optional_integer\n" -" integer_ne .or .true .emit 0x00;\n" -"optional_exponent\n" -" exponent .or .true .emit 0x00;\n" -"exponent\n" -" exponent_1 .and optional_sign_ne .and integer_ne .error EXPONENT_VALUE_EXPECTED;\n" -"exponent_1\n" -" 'e' .or 'E';\n" -"optional_sign_ne\n" -" minus_ne .or plus_ne .or .true;\n" -"plus_ne\n" -" optional_space .and '+' .and optional_space;\n" -"minus_ne\n" -" optional_space .and '-' .emit '-' .and optional_space;\n" -"identifier_ne\n" -" first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit 0x00 .emit $;\n" -"follow_idchar\n" -" first_idchar .or digit10;\n" -"first_idchar\n" -" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n" -"digit10\n" -" '0'-'9';\n" -".string __string_filter;\n" -"__string_filter\n" -" .loop __identifier_char;\n" -"__identifier_char\n" -" 'a'-'z' .or 'A'-'Z' .or '_' .or '$' .or '0'-'9';\n" -"e_signature\n" -" e_signature_char .and .loop e_signature_char;\n" -"e_signature_char\n" -" '!' .or '.' .or 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n" -"e_statement\n" -" .loop e_statement_not_term;\n" -"e_statement_not_term\n" -" '\\x3C'-'\\xFF' .or '\\x0E'-'\\x3A' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n" -"e_identifier\n" -" e_identifier_first .and .loop e_identifier_next;\n" -"e_identifier_first\n" -" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n" -"e_identifier_next\n" -" e_identifier_first .or '0'-'9';\n" -"e_token\n" -" e_identifier .or e_token_number .or '[' .or ']' .or '.' .or '{' .or '}' .or '=' .or '+' .or\n" -" '-' .or ',' .or ';';\n" -"e_token_number\n" -" e_token_digit .and .loop e_token_digit;\n" -"e_token_digit\n" -" '0'-'9';\n" -"e_charordigit\n" -" 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n" -"" diff --git a/src/mesa/shader/hash_table.c b/src/mesa/shader/hash_table.c new file mode 100644 index 0000000000..881179f9d8 --- /dev/null +++ b/src/mesa/shader/hash_table.c @@ -0,0 +1,163 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file hash_table.c + * \brief Implementation of a generic, opaque hash table data type. + * + * \author Ian Romanick <ian.d.romanick@intel.com> + */ +#include <stdlib.h> +#include <string.h> + +#include <assert.h> + +#include "main/imports.h" +#include "main/simple_list.h" +#include "hash_table.h" + +struct node { + struct node *next; + struct node *prev; +}; + +struct hash_table { + hash_func_t hash; + hash_compare_func_t compare; + + unsigned num_buckets; + struct node buckets[1]; +}; + + +struct hash_node { + struct node link; + const void *key; + void *data; +}; + + +struct hash_table * +hash_table_ctor(unsigned num_buckets, hash_func_t hash, + hash_compare_func_t compare) +{ + struct hash_table *ht; + unsigned i; + + + if (num_buckets < 16) { + num_buckets = 16; + } + + ht = _mesa_malloc(sizeof(*ht) + ((num_buckets - 1) + * sizeof(ht->buckets[0]))); + if (ht != NULL) { + ht->hash = hash; + ht->compare = compare; + ht->num_buckets = num_buckets; + + for (i = 0; i < num_buckets; i++) { + make_empty_list(& ht->buckets[i]); + } + } + + return ht; +} + + +void +hash_table_dtor(struct hash_table *ht) +{ + hash_table_clear(ht); + _mesa_free(ht); +} + + +void +hash_table_clear(struct hash_table *ht) +{ + struct node *node; + struct node *temp; + unsigned i; + + + for (i = 0; i < ht->num_buckets; i++) { + foreach_s(node, temp, & ht->buckets[i]) { + remove_from_list(node); + _mesa_free(node); + } + + assert(is_empty_list(& ht->buckets[i])); + } +} + + +void * +hash_table_find(struct hash_table *ht, const void *key) +{ + const unsigned hash_value = (*ht->hash)(key); + const unsigned bucket = hash_value % ht->num_buckets; + struct node *node; + + foreach(node, & ht->buckets[bucket]) { + struct hash_node *hn = (struct hash_node *) node; + + if ((*ht->compare)(hn->key, key) == 0) { + return hn->data; + } + } + + return NULL; +} + + +void +hash_table_insert(struct hash_table *ht, void *data, const void *key) +{ + const unsigned hash_value = (*ht->hash)(key); + const unsigned bucket = hash_value % ht->num_buckets; + struct hash_node *node; + + node = _mesa_calloc(sizeof(*node)); + + node->data = data; + node->key = key; + + insert_at_head(& ht->buckets[bucket], & node->link); +} + + +unsigned +hash_table_string_hash(const void *key) +{ + const char *str = (const char *) key; + unsigned hash = 5381; + + + while (*str != '\0') { + hash = (hash * 33) + *str; + str++; + } + + return hash; +} diff --git a/src/mesa/shader/hash_table.h b/src/mesa/shader/hash_table.h new file mode 100644 index 0000000000..7b302f5dbe --- /dev/null +++ b/src/mesa/shader/hash_table.h @@ -0,0 +1,117 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file hash_table.h + * \brief Implementation of a generic, opaque hash table data type. + * + * \author Ian Romanick <ian.d.romanick@intel.com> + */ + +#ifndef HASH_TABLE_H +#define HASH_TABLE_H + +#include <string.h> + +struct hash_table; + +typedef unsigned (*hash_func_t)(const void *key); +typedef int (*hash_compare_func_t)(const void *key1, const void *key2); + +/** + * Hash table constructor + * + * Creates a hash table with the specified number of buckets. The supplied + * \c hash and \c compare routines are used when adding elements to the table + * and when searching for elements in the table. + * + * \param num_buckets Number of buckets (bins) in the hash table. + * \param hash Function used to compute hash value of input keys. + * \param compare Function used to compare keys. + */ +extern struct hash_table *hash_table_ctor(unsigned num_buckets, + hash_func_t hash, hash_compare_func_t compare); + + +/** + * Release all memory associated with a hash table + * + * \warning + * This function cannot release memory occupied either by keys or data. + */ +extern void hash_table_dtor(struct hash_table *ht); + + +/** + * Flush all entries from a hash table + * + * \param ht Table to be cleared of its entries. + */ +extern void hash_table_clear(struct hash_table *ht); + + +/** + * Search a hash table for a specific element + * + * \param ht Table to be searched + * \param key Key of the desired element + * + * \return + * The \c data value supplied to \c hash_table_insert when the element with + * the matching key was added. If no matching key exists in the table, + * \c NULL is returned. + */ +extern void *hash_table_find(struct hash_table *ht, const void *key); + + +/** + * Add an element to a hash table + */ +extern void hash_table_insert(struct hash_table *ht, void *data, + const void *key); + + +/** + * Compute hash value of a string + * + * Computes the hash value of a string using the DJB2 algorithm developed by + * Professor Daniel J. Bernstein. It was published on comp.lang.c once upon + * a time. I was unable to find the original posting in the archives. + * + * \param key Pointer to a NUL terminated string to be hashed. + * + * \sa hash_table_string_compare + */ +extern unsigned hash_table_string_hash(const void *key); + + +/** + * Compare two strings used as keys + * + * This is just a macro wrapper around \c strcmp. + * + * \sa hash_table_string_hash + */ +#define hash_table_string_compare ((hash_compare_func_t) strcmp) + +#endif /* HASH_TABLE_H */ diff --git a/src/mesa/shader/lex.yy.c b/src/mesa/shader/lex.yy.c new file mode 100644 index 0000000000..6d661bd187 --- /dev/null +++ b/src/mesa/shader/lex.yy.c @@ -0,0 +1,3587 @@ + +#line 3 "lex.yy.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ,yyscanner ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void yyrestart (FILE *input_file ,yyscan_t yyscanner ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void yypop_buffer_state (yyscan_t yyscanner ); + +static void yyensure_buffer_stack (yyscan_t yyscanner ); +static void yy_load_buffer_state (yyscan_t yyscanner ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); + +void *yyalloc (yy_size_t ,yyscan_t yyscanner ); +void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void yyfree (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); +static int yy_get_next_buffer (yyscan_t yyscanner ); +static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yyg->yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 183 +#define YY_END_OF_BUFFER 184 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[675] = + { 0, + 0, 0, 184, 182, 180, 179, 182, 182, 152, 178, + 154, 154, 154, 154, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 180, 0, 0, 181, 152, 0, + 153, 155, 175, 175, 0, 0, 0, 0, 175, 0, + 0, 0, 0, 0, 0, 0, 132, 176, 133, 134, + 166, 166, 166, 166, 0, 154, 0, 140, 141, 142, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 174, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 173, 173, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 163, 163, 163, 164, 164, 165, 156, + 155, 156, 0, 157, 11, 13, 152, 15, 152, 152, + 16, 18, 152, 20, 22, 24, 26, 6, 28, 30, + 31, 33, 35, 38, 36, 40, 41, 43, 45, 47, + + 49, 51, 152, 152, 152, 53, 55, 152, 57, 59, + 61, 152, 63, 65, 67, 69, 152, 71, 73, 75, + 77, 152, 152, 152, 152, 152, 152, 0, 0, 0, + 0, 155, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 93, 94, 96, 0, 171, 0, 0, 0, + 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 170, 169, 169, 122, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 160, 160, + 161, 162, 0, 158, 152, 152, 152, 152, 152, 152, + 152, 152, 143, 152, 152, 152, 152, 152, 152, 152, + + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 144, 152, 152, 152, 152, 152, 152, + 152, 152, 10, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 0, 177, 0, 0, 0, 86, 87, + 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, + 126, 0, 128, 0, 0, 0, 0, 0, 0, 167, + 159, 152, 152, 152, 4, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + + 152, 152, 152, 152, 152, 152, 9, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 82, 152, 152, 0, 0, 0, + 0, 0, 88, 89, 0, 0, 0, 0, 97, 0, + 0, 101, 104, 0, 0, 0, 0, 0, 0, 0, + 115, 116, 0, 0, 0, 0, 121, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 152, 152, 152, + 152, 152, 152, 5, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 7, 8, 152, 152, 152, 152, 152, 152, 152, + + 152, 152, 152, 152, 152, 152, 152, 152, 152, 83, + 152, 79, 0, 0, 0, 0, 137, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 107, 0, 111, 112, + 0, 114, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 130, 131, 0, 0, 138, 12, 3, 14, + 148, 149, 152, 17, 19, 21, 23, 25, 27, 29, + 32, 34, 39, 37, 42, 44, 46, 48, 50, 52, + 54, 56, 58, 60, 62, 152, 152, 152, 64, 66, + 68, 70, 72, 74, 76, 78, 152, 81, 139, 0, + 0, 84, 0, 90, 0, 0, 0, 99, 0, 0, + + 0, 0, 0, 0, 113, 0, 0, 119, 106, 0, + 0, 0, 0, 0, 0, 135, 0, 152, 145, 146, + 152, 80, 0, 0, 0, 0, 92, 95, 100, 0, + 0, 105, 0, 0, 0, 118, 0, 0, 0, 0, + 127, 129, 0, 152, 152, 2, 1, 0, 91, 0, + 103, 0, 109, 117, 0, 0, 124, 125, 136, 152, + 147, 0, 102, 0, 120, 123, 152, 85, 108, 152, + 152, 150, 151, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 1, 6, 7, 1, 1, 1, 1, + 1, 1, 8, 1, 8, 9, 1, 10, 11, 12, + 13, 14, 15, 15, 15, 15, 15, 1, 1, 1, + 1, 1, 1, 1, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 7, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 1, 1, 1, 1, 41, 1, 42, 43, 44, 45, + + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[68] = + { 0, + 1, 1, 1, 1, 1, 1, 2, 1, 3, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2 + } ; + +static yyconst flex_int16_t yy_base[678] = + { 0, + 0, 0, 954, 955, 66, 955, 948, 949, 0, 69, + 85, 128, 140, 152, 151, 58, 39, 48, 75, 927, + 158, 160, 73, 59, 71, 170, 54, 920, 890, 889, + 901, 885, 899, 898, 142, 927, 939, 955, 0, 206, + 955, 189, 168, 171, 53, 27, 66, 119, 175, 899, + 885, 123, 170, 883, 895, 183, 955, 198, 225, 99, + 212, 219, 223, 227, 285, 297, 308, 955, 955, 955, + 904, 917, 911, 165, 900, 903, 899, 914, 224, 896, + 910, 194, 896, 909, 900, 913, 890, 901, 892, 294, + 893, 884, 893, 884, 883, 884, 878, 884, 895, 881, + + 878, 890, 893, 880, 873, 889, 865, 193, 139, 885, + 861, 846, 841, 858, 834, 839, 865, 167, 854, 259, + 849, 325, 282, 851, 832, 302, 842, 838, 833, 43, + 839, 825, 841, 838, 829, 305, 309, 831, 820, 834, + 837, 819, 834, 821, 818, 825, 275, 833, 254, 299, + 317, 327, 331, 810, 827, 828, 821, 803, 310, 804, + 826, 817, 316, 327, 331, 335, 339, 343, 347, 955, + 405, 416, 422, 428, 825, 240, 849, 0, 848, 831, + 821, 820, 840, 818, 817, 816, 815, 0, 814, 0, + 813, 812, 0, 811, 810, 0, 809, 808, 807, 806, + + 805, 804, 820, 813, 826, 800, 799, 805, 797, 796, + 795, 816, 793, 792, 791, 790, 800, 788, 787, 786, + 785, 777, 776, 761, 761, 760, 759, 802, 774, 762, + 434, 442, 416, 766, 186, 763, 757, 757, 751, 764, + 764, 749, 955, 955, 764, 752, 418, 759, 281, 756, + 762, 308, 757, 955, 748, 755, 754, 757, 743, 742, + 746, 741, 278, 746, 420, 428, 430, 955, 738, 736, + 736, 744, 745, 727, 421, 732, 738, 419, 426, 430, + 434, 438, 496, 502, 752, 764, 750, 749, 742, 756, + 746, 745, 0, 744, 743, 742, 741, 740, 739, 738, + + 737, 736, 735, 734, 733, 732, 731, 730, 733, 726, + 733, 726, 725, 0, 724, 723, 722, 725, 720, 719, + 718, 717, 0, 716, 715, 714, 713, 691, 685, 690, + 696, 679, 694, 315, 955, 693, 683, 687, 955, 955, + 677, 686, 672, 689, 672, 675, 669, 955, 670, 669, + 666, 673, 666, 674, 670, 680, 677, 659, 665, 672, + 656, 655, 673, 655, 667, 666, 955, 665, 655, 659, + 955, 646, 955, 651, 651, 659, 642, 643, 653, 955, + 955, 685, 667, 683, 0, 507, 681, 681, 680, 679, + 678, 677, 676, 675, 674, 673, 672, 671, 670, 669, + + 668, 667, 666, 665, 652, 645, 0, 662, 661, 660, + 659, 658, 636, 656, 655, 654, 653, 652, 651, 650, + 649, 618, 621, 601, 0, 602, 595, 602, 601, 602, + 594, 612, 955, 955, 594, 592, 602, 595, 955, 590, + 607, 330, 955, 598, 582, 583, 592, 583, 582, 582, + 955, 581, 590, 580, 596, 593, 955, 592, 590, 579, + 580, 576, 568, 575, 570, 571, 566, 592, 592, 590, + 604, 603, 598, 0, 586, 585, 584, 583, 582, 581, + 580, 579, 578, 577, 576, 575, 574, 573, 572, 571, + 570, 0, 0, 569, 568, 567, 566, 565, 509, 564, + + 563, 562, 561, 560, 559, 558, 557, 535, 535, 0, + 542, 0, 576, 575, 524, 542, 955, 537, 532, 525, + 521, 533, 523, 521, 517, 533, 524, 523, 955, 955, + 526, 955, 521, 514, 503, 514, 506, 510, 523, 518, + 521, 503, 955, 955, 515, 504, 955, 0, 0, 0, + 0, 0, 543, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 539, 538, 536, 0, 0, + 0, 0, 0, 0, 0, 0, 494, 0, 0, 545, + 544, 955, 491, 955, 495, 495, 504, 955, 488, 502, + + 483, 485, 482, 490, 955, 468, 479, 955, 955, 483, + 479, 472, 470, 470, 483, 955, 467, 507, 0, 0, + 507, 0, 514, 513, 472, 433, 955, 955, 955, 435, + 435, 955, 429, 386, 377, 955, 366, 365, 323, 328, + 955, 955, 339, 348, 337, 955, 955, 307, 955, 305, + 955, 257, 955, 955, 247, 221, 955, 955, 955, 236, + 0, 213, 955, 150, 955, 955, 232, 955, 955, 162, + 138, 0, 0, 955, 541, 108, 544 + } ; + +static yyconst flex_int16_t yy_def[678] = + { 0, + 674, 1, 674, 674, 674, 674, 674, 675, 676, 674, + 674, 674, 674, 674, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 674, 674, 675, 674, 676, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 677, 674, 674, 674, 674, 674, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 676, 676, 676, + 676, 676, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 676, 676, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 676, + 676, 674, 674, 674, 674, 674, 676, 674, 674, 676, + 676, 676, 676, 0, 674, 674, 674 + } ; + +static yyconst flex_int16_t yy_nxt[1023] = + { 0, + 4, 5, 6, 5, 7, 8, 9, 4, 10, 11, + 12, 13, 14, 11, 11, 15, 9, 16, 17, 18, + 19, 9, 9, 9, 20, 21, 22, 9, 23, 24, + 9, 25, 26, 27, 9, 9, 9, 28, 9, 9, + 9, 9, 9, 9, 9, 9, 29, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 30, 9, 31, 32, + 33, 9, 34, 9, 9, 9, 9, 35, 79, 35, + 40, 80, 129, 108, 96, 81, 130, 41, 42, 42, + 42, 42, 42, 42, 76, 82, 77, 97, 98, 240, + 99, 109, 78, 65, 66, 66, 66, 66, 66, 66, + + 83, 241, 94, 100, 67, 127, 84, 95, 128, 39, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 131, + 132, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 67, 133, 61, 62, 63, 64, 65, 66, 66, 66, + 66, 66, 66, 35, 160, 35, 68, 67, 65, 66, + 66, 66, 66, 66, 66, 219, 673, 161, 69, 67, + 65, 66, 66, 66, 66, 66, 66, 71, 220, 72, + 70, 67, 140, 67, 134, 90, 73, 135, 141, 86, + 672, 87, 74, 91, 75, 67, 88, 101, 92, 89, + 178, 102, 103, 104, 93, 105, 179, 67, 42, 42, + + 42, 42, 42, 42, 106, 189, 107, 40, 122, 123, + 123, 142, 126, 123, 669, 123, 136, 137, 123, 217, + 124, 124, 123, 190, 147, 143, 123, 125, 125, 123, + 218, 337, 144, 123, 122, 148, 184, 185, 149, 151, + 152, 150, 670, 671, 338, 153, 186, 118, 119, 45, + 46, 47, 48, 154, 50, 51, 123, 162, 52, 53, + 54, 55, 56, 57, 120, 59, 60, 668, 155, 121, + 156, 286, 667, 157, 158, 163, 163, 163, 163, 666, + 287, 159, 164, 163, 165, 166, 167, 163, 163, 168, + 169, 163, 163, 163, 171, 171, 171, 171, 171, 171, + + 230, 665, 664, 260, 172, 65, 66, 66, 66, 66, + 66, 66, 198, 261, 154, 173, 67, 174, 174, 174, + 174, 174, 174, 233, 233, 364, 349, 257, 365, 233, + 172, 199, 231, 258, 232, 232, 232, 232, 232, 232, + 233, 350, 67, 233, 233, 236, 233, 233, 262, 233, + 247, 233, 233, 353, 263, 273, 233, 663, 233, 233, + 233, 428, 662, 233, 233, 274, 354, 233, 265, 233, + 661, 264, 266, 267, 233, 233, 660, 429, 233, 278, + 278, 278, 278, 524, 659, 233, 525, 658, 657, 233, + 278, 278, 278, 278, 279, 278, 278, 280, 281, 278, + + 278, 278, 278, 278, 278, 278, 282, 278, 278, 278, + 278, 278, 278, 278, 42, 42, 42, 42, 42, 42, + 656, 655, 654, 283, 122, 284, 284, 284, 284, 284, + 284, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 232, 232, 232, 232, 232, 232, 653, + 122, 232, 232, 232, 232, 232, 232, 335, 335, 335, + 335, 335, 335, 335, 374, 335, 375, 335, 376, 335, + 335, 367, 335, 652, 335, 335, 335, 335, 335, 651, + 650, 377, 380, 380, 380, 380, 335, 649, 335, 380, + 380, 380, 380, 381, 380, 380, 380, 380, 380, 380, + + 380, 380, 380, 380, 380, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 471, 472, 576, + 577, 648, 647, 646, 645, 644, 643, 642, 641, 640, + 639, 638, 637, 636, 635, 634, 633, 632, 631, 473, + 578, 37, 37, 37, 170, 170, 630, 629, 628, 627, + 626, 625, 624, 623, 622, 621, 620, 619, 618, 617, + 616, 615, 614, 613, 612, 611, 610, 609, 608, 607, + 606, 605, 604, 603, 602, 601, 600, 599, 598, 597, + 596, 595, 594, 593, 592, 591, 590, 589, 588, 587, + 586, 585, 584, 583, 582, 581, 580, 579, 575, 574, + + 573, 572, 571, 570, 569, 568, 567, 566, 565, 564, + 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, + 553, 552, 551, 550, 549, 548, 547, 546, 545, 544, + 543, 542, 541, 540, 539, 538, 537, 536, 535, 534, + 533, 532, 531, 530, 529, 528, 527, 526, 523, 522, + 521, 520, 519, 518, 517, 516, 515, 514, 513, 512, + 511, 510, 509, 508, 507, 506, 505, 504, 503, 502, + 501, 500, 499, 498, 497, 496, 495, 494, 493, 492, + 491, 490, 489, 488, 487, 486, 485, 484, 483, 482, + 481, 480, 479, 478, 477, 476, 475, 474, 470, 469, + + 468, 467, 466, 465, 464, 463, 462, 461, 460, 459, + 458, 457, 456, 455, 454, 453, 452, 451, 450, 449, + 448, 447, 446, 445, 444, 443, 442, 441, 440, 439, + 438, 437, 436, 435, 434, 433, 432, 431, 430, 427, + 426, 425, 424, 423, 422, 421, 420, 419, 418, 417, + 416, 415, 414, 413, 412, 411, 410, 409, 408, 407, + 406, 405, 404, 403, 402, 401, 400, 399, 398, 397, + 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, + 386, 385, 384, 383, 382, 379, 378, 373, 372, 371, + 370, 369, 368, 366, 363, 362, 361, 360, 359, 358, + + 357, 356, 355, 352, 351, 348, 347, 346, 345, 344, + 343, 342, 341, 340, 339, 336, 264, 236, 334, 333, + 332, 331, 330, 329, 328, 327, 326, 325, 324, 323, + 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, + 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, + 302, 301, 300, 299, 298, 297, 296, 295, 294, 293, + 292, 291, 290, 289, 288, 285, 277, 276, 275, 272, + 271, 270, 269, 268, 259, 256, 255, 254, 253, 252, + 251, 250, 249, 248, 246, 245, 244, 243, 242, 239, + 238, 237, 235, 234, 162, 229, 228, 227, 226, 225, + + 224, 223, 222, 221, 216, 215, 214, 213, 212, 211, + 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, + 200, 197, 196, 195, 194, 193, 192, 191, 188, 187, + 183, 182, 181, 180, 177, 176, 175, 146, 145, 139, + 138, 38, 117, 116, 115, 114, 113, 112, 111, 110, + 85, 38, 36, 674, 3, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674 + } ; + +static yyconst flex_int16_t yy_chk[1023] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 5, 17, 5, + 10, 17, 46, 27, 24, 18, 46, 10, 10, 10, + 10, 10, 10, 10, 16, 18, 16, 24, 25, 130, + 25, 27, 16, 11, 11, 11, 11, 11, 11, 11, + + 19, 130, 23, 25, 11, 45, 19, 23, 45, 676, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 47, + 47, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 11, 47, 10, 10, 10, 10, 12, 12, 12, 12, + 12, 12, 12, 35, 60, 35, 12, 12, 13, 13, + 13, 13, 13, 13, 13, 109, 671, 60, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 15, 109, 15, + 14, 14, 52, 12, 48, 22, 15, 48, 52, 21, + 670, 21, 15, 22, 15, 13, 21, 26, 22, 21, + 74, 26, 26, 26, 22, 26, 74, 14, 42, 42, + + 42, 42, 42, 42, 26, 82, 26, 40, 42, 43, + 43, 53, 44, 44, 664, 43, 49, 49, 44, 108, + 118, 43, 49, 82, 56, 53, 43, 118, 43, 44, + 108, 235, 53, 49, 42, 56, 79, 79, 56, 58, + 58, 56, 667, 667, 235, 58, 79, 40, 40, 40, + 40, 40, 40, 58, 40, 40, 58, 61, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 662, 59, 40, + 59, 176, 660, 59, 59, 61, 61, 61, 61, 656, + 176, 59, 62, 62, 62, 62, 63, 63, 63, 63, + 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, + + 120, 655, 652, 149, 65, 66, 66, 66, 66, 66, + 66, 66, 90, 149, 120, 67, 66, 67, 67, 67, + 67, 67, 67, 123, 123, 263, 249, 147, 263, 123, + 65, 90, 122, 147, 122, 122, 122, 122, 122, 122, + 123, 249, 66, 126, 126, 126, 136, 136, 150, 126, + 137, 137, 136, 252, 150, 159, 137, 650, 151, 151, + 126, 334, 648, 136, 151, 159, 252, 137, 152, 152, + 645, 151, 153, 153, 152, 151, 644, 334, 153, 163, + 163, 163, 163, 442, 643, 152, 442, 640, 639, 153, + 164, 164, 164, 164, 165, 165, 165, 165, 166, 166, + + 166, 166, 167, 167, 167, 167, 168, 168, 168, 168, + 169, 169, 169, 169, 171, 171, 171, 171, 171, 171, + 638, 637, 635, 172, 171, 172, 172, 172, 172, 172, + 172, 173, 173, 173, 173, 173, 173, 174, 174, 174, + 174, 174, 174, 231, 231, 231, 231, 231, 231, 634, + 171, 232, 232, 232, 232, 232, 232, 233, 233, 247, + 247, 265, 265, 233, 275, 247, 275, 265, 275, 266, + 266, 267, 267, 633, 233, 266, 247, 267, 265, 631, + 630, 275, 278, 278, 278, 278, 266, 626, 267, 279, + 279, 279, 279, 280, 280, 280, 280, 281, 281, 281, + + 281, 282, 282, 282, 282, 283, 283, 283, 283, 283, + 283, 284, 284, 284, 284, 284, 284, 386, 386, 499, + 499, 625, 624, 623, 621, 618, 617, 615, 614, 613, + 612, 611, 610, 607, 606, 604, 603, 602, 601, 386, + 499, 675, 675, 675, 677, 677, 600, 599, 597, 596, + 595, 593, 591, 590, 587, 578, 577, 576, 553, 546, + 545, 542, 541, 540, 539, 538, 537, 536, 535, 534, + 533, 531, 528, 527, 526, 525, 524, 523, 522, 521, + 520, 519, 518, 516, 515, 514, 513, 511, 509, 508, + 507, 506, 505, 504, 503, 502, 501, 500, 498, 497, + + 496, 495, 494, 491, 490, 489, 488, 487, 486, 485, + 484, 483, 482, 481, 480, 479, 478, 477, 476, 475, + 473, 472, 471, 470, 469, 468, 467, 466, 465, 464, + 463, 462, 461, 460, 459, 458, 456, 455, 454, 453, + 452, 450, 449, 448, 447, 446, 445, 444, 441, 440, + 438, 437, 436, 435, 432, 431, 430, 429, 428, 427, + 426, 424, 423, 422, 421, 420, 419, 418, 417, 416, + 415, 414, 413, 412, 411, 410, 409, 408, 406, 405, + 404, 403, 402, 401, 400, 399, 398, 397, 396, 395, + 394, 393, 392, 391, 390, 389, 388, 387, 384, 383, + + 382, 379, 378, 377, 376, 375, 374, 372, 370, 369, + 368, 366, 365, 364, 363, 362, 361, 360, 359, 358, + 357, 356, 355, 354, 353, 352, 351, 350, 349, 347, + 346, 345, 344, 343, 342, 341, 338, 337, 336, 333, + 332, 331, 330, 329, 328, 327, 326, 325, 324, 322, + 321, 320, 319, 318, 317, 316, 315, 313, 312, 311, + 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, + 300, 299, 298, 297, 296, 295, 294, 292, 291, 290, + 289, 288, 287, 286, 285, 277, 276, 274, 273, 272, + 271, 270, 269, 264, 262, 261, 260, 259, 258, 257, + + 256, 255, 253, 251, 250, 248, 246, 245, 242, 241, + 240, 239, 238, 237, 236, 234, 230, 229, 228, 227, + 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, + 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, + 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, + 195, 194, 192, 191, 189, 187, 186, 185, 184, 183, + 182, 181, 180, 179, 177, 175, 162, 161, 160, 158, + 157, 156, 155, 154, 148, 146, 145, 144, 143, 142, + 141, 140, 139, 138, 135, 134, 133, 132, 131, 129, + 128, 127, 125, 124, 121, 119, 117, 116, 115, 114, + + 113, 112, 111, 110, 107, 106, 105, 104, 103, 102, + 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, + 91, 89, 88, 87, 86, 85, 84, 83, 81, 80, + 78, 77, 76, 75, 73, 72, 71, 55, 54, 51, + 50, 37, 36, 34, 33, 32, 31, 30, 29, 28, + 20, 8, 7, 3, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "program_lexer.l" +#line 2 "program_lexer.l" +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include "main/glheader.h" +#include "prog_instruction.h" + +#include "program_parser.h" +#include "program_parse.tab.h" + +#define require_ARB_vp (yyextra->mode == ARB_vertex) +#define require_ARB_fp (yyextra->mode == ARB_fragment) +#define require_shadow (yyextra->option.Shadow) +#define require_rect (yyextra->option.TexRect) +#define require_texarray (yyextra->option.TexArray) + +#define return_token_or_IDENTIFIER(condition, token) \ + do { \ + if (condition) { \ + return token; \ + } else { \ + yylval->string = strdup(yytext); \ + return IDENTIFIER; \ + } \ + } while (0) + +#define return_token_or_DOT(condition, token) \ + do { \ + if (condition) { \ + return token; \ + } else { \ + yyless(1); \ + return DOT; \ + } \ + } while (0) + + +#define return_opcode(condition, token, opcode, sat) \ + do { \ + if (condition) { \ + yylval->temp_inst.Opcode = OPCODE_ ## opcode; \ + yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \ + return token; \ + } else { \ + yylval->string = strdup(yytext); \ + return IDENTIFIER; \ + } \ + } while (0) + +#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \ + SWIZZLE_NIL, SWIZZLE_NIL) + +static unsigned +mask_from_char(char c) +{ + switch (c) { + case 'x': + case 'r': + return WRITEMASK_X; + case 'y': + case 'g': + return WRITEMASK_Y; + case 'z': + case 'b': + return WRITEMASK_Z; + case 'w': + case 'a': + return WRITEMASK_W; + } + + return 0; +} + +static unsigned +swiz_from_char(char c) +{ + switch (c) { + case 'x': + case 'r': + return SWIZZLE_X; + case 'y': + case 'g': + return SWIZZLE_Y; + case 'z': + case 'b': + return SWIZZLE_Z; + case 'w': + case 'a': + return SWIZZLE_W; + } + + return 0; +} + +#define YY_USER_ACTION \ + do { \ + yylloc->first_column = yylloc->last_column; \ + yylloc->last_column += yyleng; \ + if ((yylloc->first_line == 1) \ + && (yylloc->first_column == 1)) { \ + yylloc->position = 1; \ + } else { \ + yylloc->position += yylloc->last_column - yylloc->first_column; \ + } \ + } while(0); + +#define YY_EXTRA_TYPE struct asm_parser_state * +#line 1015 "lex.yy.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + int yy_n_chars; + int yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + YYSTYPE * yylval_r; + + YYLTYPE * yylloc_r; + + }; /* end struct yyguts_t */ + +static int yy_init_globals (yyscan_t yyscanner ); + + /* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ + # define yylval yyg->yylval_r + + # define yylloc yyg->yylloc_r + +int yylex_init (yyscan_t* scanner); + +int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (yyscan_t yyscanner ); + +int yyget_debug (yyscan_t yyscanner ); + +void yyset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *yyget_in (yyscan_t yyscanner ); + +void yyset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *yyget_out (yyscan_t yyscanner ); + +void yyset_out (FILE * out_str ,yyscan_t yyscanner ); + +int yyget_leng (yyscan_t yyscanner ); + +char *yyget_text (yyscan_t yyscanner ); + +int yyget_lineno (yyscan_t yyscanner ); + +void yyset_lineno (int line_number ,yyscan_t yyscanner ); + +YYSTYPE * yyget_lval (yyscan_t yyscanner ); + +void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + + YYLTYPE *yyget_lloc (yyscan_t yyscanner ); + + void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (yyscan_t yyscanner ); +#else +extern int yywrap (yyscan_t yyscanner ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner ); +#else +static int input (yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex \ + (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); + +#define YY_DECL int yylex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + +#line 135 "program_lexer.l" + + +#line 1264 "lex.yy.c" + + yylval = yylval_param; + + yylloc = yylloc_param; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + yy_load_buffer_state(yyscanner ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yyg->yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 675 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 955 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 137 "program_lexer.l" +{ return ARBvp_10; } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 138 "program_lexer.l" +{ return ARBfp_10; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 139 "program_lexer.l" +{ + yylval->integer = at_address; + return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS); +} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 143 "program_lexer.l" +{ return ALIAS; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 144 "program_lexer.l" +{ return ATTRIB; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 145 "program_lexer.l" +{ return END; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 146 "program_lexer.l" +{ return OPTION; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 147 "program_lexer.l" +{ return OUTPUT; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 148 "program_lexer.l" +{ return PARAM; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 149 "program_lexer.l" +{ yylval->integer = at_temp; return TEMP; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 151 "program_lexer.l" +{ return_opcode( 1, VECTOR_OP, ABS, OFF); } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 152 "program_lexer.l" +{ return_opcode(require_ARB_fp, VECTOR_OP, ABS, ZERO_ONE); } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 153 "program_lexer.l" +{ return_opcode( 1, BIN_OP, ADD, OFF); } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 154 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, ADD, ZERO_ONE); } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 155 "program_lexer.l" +{ return_opcode(require_ARB_vp, ARL, ARL, OFF); } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 157 "program_lexer.l" +{ return_opcode(require_ARB_fp, TRI_OP, CMP, OFF); } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 158 "program_lexer.l" +{ return_opcode(require_ARB_fp, TRI_OP, CMP, ZERO_ONE); } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 159 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, COS, OFF); } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 160 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, COS, ZERO_ONE); } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 162 "program_lexer.l" +{ return_opcode( 1, BIN_OP, DP3, OFF); } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 163 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, DP3, ZERO_ONE); } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 164 "program_lexer.l" +{ return_opcode( 1, BIN_OP, DP4, OFF); } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 165 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, DP4, ZERO_ONE); } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 166 "program_lexer.l" +{ return_opcode( 1, BIN_OP, DPH, OFF); } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 167 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, DPH, ZERO_ONE); } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 168 "program_lexer.l" +{ return_opcode( 1, BIN_OP, DST, OFF); } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 169 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, DST, ZERO_ONE); } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 171 "program_lexer.l" +{ return_opcode( 1, SCALAR_OP, EX2, OFF); } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 172 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, EX2, ZERO_ONE); } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 173 "program_lexer.l" +{ return_opcode(require_ARB_vp, SCALAR_OP, EXP, OFF); } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 175 "program_lexer.l" +{ return_opcode( 1, VECTOR_OP, FLR, OFF); } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 176 "program_lexer.l" +{ return_opcode(require_ARB_fp, VECTOR_OP, FLR, ZERO_ONE); } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 177 "program_lexer.l" +{ return_opcode( 1, VECTOR_OP, FRC, OFF); } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 178 "program_lexer.l" +{ return_opcode(require_ARB_fp, VECTOR_OP, FRC, ZERO_ONE); } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 180 "program_lexer.l" +{ return_opcode(require_ARB_fp, KIL, KIL, OFF); } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 182 "program_lexer.l" +{ return_opcode( 1, VECTOR_OP, LIT, OFF); } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 183 "program_lexer.l" +{ return_opcode(require_ARB_fp, VECTOR_OP, LIT, ZERO_ONE); } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 184 "program_lexer.l" +{ return_opcode( 1, SCALAR_OP, LG2, OFF); } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 185 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, LG2, ZERO_ONE); } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 186 "program_lexer.l" +{ return_opcode(require_ARB_vp, SCALAR_OP, LOG, OFF); } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 187 "program_lexer.l" +{ return_opcode(require_ARB_fp, TRI_OP, LRP, OFF); } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 188 "program_lexer.l" +{ return_opcode(require_ARB_fp, TRI_OP, LRP, ZERO_ONE); } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 190 "program_lexer.l" +{ return_opcode( 1, TRI_OP, MAD, OFF); } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 191 "program_lexer.l" +{ return_opcode(require_ARB_fp, TRI_OP, MAD, ZERO_ONE); } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 192 "program_lexer.l" +{ return_opcode( 1, BIN_OP, MAX, OFF); } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 193 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, MAX, ZERO_ONE); } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 194 "program_lexer.l" +{ return_opcode( 1, BIN_OP, MIN, OFF); } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 195 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, MIN, ZERO_ONE); } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 196 "program_lexer.l" +{ return_opcode( 1, VECTOR_OP, MOV, OFF); } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 197 "program_lexer.l" +{ return_opcode(require_ARB_fp, VECTOR_OP, MOV, ZERO_ONE); } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 198 "program_lexer.l" +{ return_opcode( 1, BIN_OP, MUL, OFF); } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 199 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, MUL, ZERO_ONE); } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 201 "program_lexer.l" +{ return_opcode( 1, BINSC_OP, POW, OFF); } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 202 "program_lexer.l" +{ return_opcode(require_ARB_fp, BINSC_OP, POW, ZERO_ONE); } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 204 "program_lexer.l" +{ return_opcode( 1, SCALAR_OP, RCP, OFF); } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 205 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, RCP, ZERO_ONE); } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 206 "program_lexer.l" +{ return_opcode( 1, SCALAR_OP, RSQ, OFF); } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 207 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, RSQ, ZERO_ONE); } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 209 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, SCS, OFF); } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 210 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, SCS, ZERO_ONE); } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 211 "program_lexer.l" +{ return_opcode( 1, BIN_OP, SGE, OFF); } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 212 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, SGE, ZERO_ONE); } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 213 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, SIN, OFF); } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 214 "program_lexer.l" +{ return_opcode(require_ARB_fp, SCALAR_OP, SIN, ZERO_ONE); } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 215 "program_lexer.l" +{ return_opcode( 1, BIN_OP, SLT, OFF); } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 216 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, SLT, ZERO_ONE); } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 217 "program_lexer.l" +{ return_opcode( 1, BIN_OP, SUB, OFF); } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 218 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, SUB, ZERO_ONE); } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 219 "program_lexer.l" +{ return_opcode( 1, SWZ, SWZ, OFF); } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 220 "program_lexer.l" +{ return_opcode(require_ARB_fp, SWZ, SWZ, ZERO_ONE); } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 222 "program_lexer.l" +{ return_opcode(require_ARB_fp, SAMPLE_OP, TEX, OFF); } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 223 "program_lexer.l" +{ return_opcode(require_ARB_fp, SAMPLE_OP, TEX, ZERO_ONE); } + YY_BREAK +case 73: +YY_RULE_SETUP +#line 224 "program_lexer.l" +{ return_opcode(require_ARB_fp, SAMPLE_OP, TXB, OFF); } + YY_BREAK +case 74: +YY_RULE_SETUP +#line 225 "program_lexer.l" +{ return_opcode(require_ARB_fp, SAMPLE_OP, TXB, ZERO_ONE); } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 226 "program_lexer.l" +{ return_opcode(require_ARB_fp, SAMPLE_OP, TXP, OFF); } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 227 "program_lexer.l" +{ return_opcode(require_ARB_fp, SAMPLE_OP, TXP, ZERO_ONE); } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 229 "program_lexer.l" +{ return_opcode( 1, BIN_OP, XPD, OFF); } + YY_BREAK +case 78: +YY_RULE_SETUP +#line 230 "program_lexer.l" +{ return_opcode(require_ARB_fp, BIN_OP, XPD, ZERO_ONE); } + YY_BREAK +case 79: +YY_RULE_SETUP +#line 232 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); } + YY_BREAK +case 80: +YY_RULE_SETUP +#line 233 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); } + YY_BREAK +case 81: +YY_RULE_SETUP +#line 234 "program_lexer.l" +{ return PROGRAM; } + YY_BREAK +case 82: +YY_RULE_SETUP +#line 235 "program_lexer.l" +{ return STATE; } + YY_BREAK +case 83: +YY_RULE_SETUP +#line 236 "program_lexer.l" +{ return RESULT; } + YY_BREAK +case 84: +YY_RULE_SETUP +#line 238 "program_lexer.l" +{ return AMBIENT; } + YY_BREAK +case 85: +YY_RULE_SETUP +#line 239 "program_lexer.l" +{ return ATTENUATION; } + YY_BREAK +case 86: +YY_RULE_SETUP +#line 240 "program_lexer.l" +{ return BACK; } + YY_BREAK +case 87: +YY_RULE_SETUP +#line 241 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, CLIP); } + YY_BREAK +case 88: +YY_RULE_SETUP +#line 242 "program_lexer.l" +{ return COLOR; } + YY_BREAK +case 89: +YY_RULE_SETUP +#line 243 "program_lexer.l" +{ return_token_or_DOT(require_ARB_fp, DEPTH); } + YY_BREAK +case 90: +YY_RULE_SETUP +#line 244 "program_lexer.l" +{ return DIFFUSE; } + YY_BREAK +case 91: +YY_RULE_SETUP +#line 245 "program_lexer.l" +{ return DIRECTION; } + YY_BREAK +case 92: +YY_RULE_SETUP +#line 246 "program_lexer.l" +{ return EMISSION; } + YY_BREAK +case 93: +YY_RULE_SETUP +#line 247 "program_lexer.l" +{ return ENV; } + YY_BREAK +case 94: +YY_RULE_SETUP +#line 248 "program_lexer.l" +{ return EYE; } + YY_BREAK +case 95: +YY_RULE_SETUP +#line 249 "program_lexer.l" +{ return FOGCOORD; } + YY_BREAK +case 96: +YY_RULE_SETUP +#line 250 "program_lexer.l" +{ return FOG; } + YY_BREAK +case 97: +YY_RULE_SETUP +#line 251 "program_lexer.l" +{ return FRONT; } + YY_BREAK +case 98: +YY_RULE_SETUP +#line 252 "program_lexer.l" +{ return HALF; } + YY_BREAK +case 99: +YY_RULE_SETUP +#line 253 "program_lexer.l" +{ return INVERSE; } + YY_BREAK +case 100: +YY_RULE_SETUP +#line 254 "program_lexer.l" +{ return INVTRANS; } + YY_BREAK +case 101: +YY_RULE_SETUP +#line 255 "program_lexer.l" +{ return LIGHT; } + YY_BREAK +case 102: +YY_RULE_SETUP +#line 256 "program_lexer.l" +{ return LIGHTMODEL; } + YY_BREAK +case 103: +YY_RULE_SETUP +#line 257 "program_lexer.l" +{ return LIGHTPROD; } + YY_BREAK +case 104: +YY_RULE_SETUP +#line 258 "program_lexer.l" +{ return LOCAL; } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 259 "program_lexer.l" +{ return MATERIAL; } + YY_BREAK +case 106: +YY_RULE_SETUP +#line 260 "program_lexer.l" +{ return MAT_PROGRAM; } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 261 "program_lexer.l" +{ return MATRIX; } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 262 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, MATRIXINDEX); } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 263 "program_lexer.l" +{ return MODELVIEW; } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 264 "program_lexer.l" +{ return MVP; } + YY_BREAK +case 111: +YY_RULE_SETUP +#line 265 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, NORMAL); } + YY_BREAK +case 112: +YY_RULE_SETUP +#line 266 "program_lexer.l" +{ return OBJECT; } + YY_BREAK +case 113: +YY_RULE_SETUP +#line 267 "program_lexer.l" +{ return PALETTE; } + YY_BREAK +case 114: +YY_RULE_SETUP +#line 268 "program_lexer.l" +{ return PARAMS; } + YY_BREAK +case 115: +YY_RULE_SETUP +#line 269 "program_lexer.l" +{ return PLANE; } + YY_BREAK +case 116: +YY_RULE_SETUP +#line 270 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, POINT); } + YY_BREAK +case 117: +YY_RULE_SETUP +#line 271 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, POINTSIZE); } + YY_BREAK +case 118: +YY_RULE_SETUP +#line 272 "program_lexer.l" +{ return POSITION; } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 273 "program_lexer.l" +{ return PRIMARY; } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 274 "program_lexer.l" +{ return PROJECTION; } + YY_BREAK +case 121: +YY_RULE_SETUP +#line 275 "program_lexer.l" +{ return_token_or_DOT(require_ARB_fp, RANGE); } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 276 "program_lexer.l" +{ return ROW; } + YY_BREAK +case 123: +YY_RULE_SETUP +#line 277 "program_lexer.l" +{ return SCENECOLOR; } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 278 "program_lexer.l" +{ return SECONDARY; } + YY_BREAK +case 125: +YY_RULE_SETUP +#line 279 "program_lexer.l" +{ return SHININESS; } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 280 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, SIZE); } + YY_BREAK +case 127: +YY_RULE_SETUP +#line 281 "program_lexer.l" +{ return SPECULAR; } + YY_BREAK +case 128: +YY_RULE_SETUP +#line 282 "program_lexer.l" +{ return SPOT; } + YY_BREAK +case 129: +YY_RULE_SETUP +#line 283 "program_lexer.l" +{ return TEXCOORD; } + YY_BREAK +case 130: +YY_RULE_SETUP +#line 284 "program_lexer.l" +{ return_token_or_DOT(require_ARB_fp, TEXENV); } + YY_BREAK +case 131: +YY_RULE_SETUP +#line 285 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, TEXGEN); } + YY_BREAK +case 132: +YY_RULE_SETUP +#line 286 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, TEXGEN_Q); } + YY_BREAK +case 133: +YY_RULE_SETUP +#line 287 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, TEXGEN_S); } + YY_BREAK +case 134: +YY_RULE_SETUP +#line 288 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, TEXGEN_T); } + YY_BREAK +case 135: +YY_RULE_SETUP +#line 289 "program_lexer.l" +{ return TEXTURE; } + YY_BREAK +case 136: +YY_RULE_SETUP +#line 290 "program_lexer.l" +{ return TRANSPOSE; } + YY_BREAK +case 137: +YY_RULE_SETUP +#line 291 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, VTXATTRIB); } + YY_BREAK +case 138: +YY_RULE_SETUP +#line 292 "program_lexer.l" +{ return_token_or_DOT(require_ARB_vp, WEIGHT); } + YY_BREAK +case 139: +YY_RULE_SETUP +#line 294 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); } + YY_BREAK +case 140: +YY_RULE_SETUP +#line 295 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); } + YY_BREAK +case 141: +YY_RULE_SETUP +#line 296 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); } + YY_BREAK +case 142: +YY_RULE_SETUP +#line 297 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); } + YY_BREAK +case 143: +YY_RULE_SETUP +#line 298 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); } + YY_BREAK +case 144: +YY_RULE_SETUP +#line 299 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); } + YY_BREAK +case 145: +YY_RULE_SETUP +#line 300 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); } + YY_BREAK +case 146: +YY_RULE_SETUP +#line 301 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); } + YY_BREAK +case 147: +YY_RULE_SETUP +#line 302 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); } + YY_BREAK +case 148: +YY_RULE_SETUP +#line 303 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); } + YY_BREAK +case 149: +YY_RULE_SETUP +#line 304 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); } + YY_BREAK +case 150: +YY_RULE_SETUP +#line 305 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); } + YY_BREAK +case 151: +YY_RULE_SETUP +#line 306 "program_lexer.l" +{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); } + YY_BREAK +case 152: +YY_RULE_SETUP +#line 308 "program_lexer.l" +{ + yylval->string = strdup(yytext); + return IDENTIFIER; +} + YY_BREAK +case 153: +YY_RULE_SETUP +#line 313 "program_lexer.l" +{ return DOT_DOT; } + YY_BREAK +case 154: +YY_RULE_SETUP +#line 315 "program_lexer.l" +{ + yylval->integer = strtol(yytext, NULL, 10); + return INTEGER; +} + YY_BREAK +case 155: +YY_RULE_SETUP +#line 319 "program_lexer.l" +{ + yylval->real = strtod(yytext, NULL); + return REAL; +} + YY_BREAK +case 156: +/* rule 156 can match eol */ +*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ +yyg->yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 323 "program_lexer.l" +{ + yylval->real = strtod(yytext, NULL); + return REAL; +} + YY_BREAK +case 157: +YY_RULE_SETUP +#line 327 "program_lexer.l" +{ + yylval->real = strtod(yytext, NULL); + return REAL; +} + YY_BREAK +case 158: +YY_RULE_SETUP +#line 331 "program_lexer.l" +{ + yylval->real = strtod(yytext, NULL); + return REAL; +} + YY_BREAK +case 159: +YY_RULE_SETUP +#line 336 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_NOOP; + yylval->swiz_mask.mask = WRITEMASK_XYZW; + return MASK4; +} + YY_BREAK +case 160: +YY_RULE_SETUP +#line 342 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XY + | mask_from_char(yytext[3]); + return MASK3; +} + YY_BREAK +case 161: +YY_RULE_SETUP +#line 348 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XZW; + return MASK3; +} + YY_BREAK +case 162: +YY_RULE_SETUP +#line 353 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_YZW; + return MASK3; +} + YY_BREAK +case 163: +YY_RULE_SETUP +#line 359 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_X + | mask_from_char(yytext[2]); + return MASK2; +} + YY_BREAK +case 164: +YY_RULE_SETUP +#line 365 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_Y + | mask_from_char(yytext[2]); + return MASK2; +} + YY_BREAK +case 165: +YY_RULE_SETUP +#line 371 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_ZW; + return MASK2; +} + YY_BREAK +case 166: +YY_RULE_SETUP +#line 377 "program_lexer.l" +{ + const unsigned s = swiz_from_char(yytext[1]); + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); + yylval->swiz_mask.mask = mask_from_char(yytext[1]); + return MASK1; +} + YY_BREAK +case 167: +YY_RULE_SETUP +#line 384 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), + swiz_from_char(yytext[2]), + swiz_from_char(yytext[3]), + swiz_from_char(yytext[4])); + yylval->swiz_mask.mask = 0; + return SWIZZLE; +} + YY_BREAK +case 168: +YY_RULE_SETUP +#line 393 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_NOOP; + yylval->swiz_mask.mask = WRITEMASK_XYZW; + return_token_or_DOT(require_ARB_fp, MASK4); +} + YY_BREAK +case 169: +YY_RULE_SETUP +#line 399 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XY + | mask_from_char(yytext[3]); + return_token_or_DOT(require_ARB_fp, MASK3); +} + YY_BREAK +case 170: +YY_RULE_SETUP +#line 405 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XZW; + return_token_or_DOT(require_ARB_fp, MASK3); +} + YY_BREAK +case 171: +YY_RULE_SETUP +#line 410 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_YZW; + return_token_or_DOT(require_ARB_fp, MASK3); +} + YY_BREAK +case 172: +YY_RULE_SETUP +#line 416 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_X + | mask_from_char(yytext[2]); + return_token_or_DOT(require_ARB_fp, MASK2); +} + YY_BREAK +case 173: +YY_RULE_SETUP +#line 422 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_Y + | mask_from_char(yytext[2]); + return_token_or_DOT(require_ARB_fp, MASK2); +} + YY_BREAK +case 174: +YY_RULE_SETUP +#line 428 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_ZW; + return_token_or_DOT(require_ARB_fp, MASK2); +} + YY_BREAK +case 175: +YY_RULE_SETUP +#line 434 "program_lexer.l" +{ + const unsigned s = swiz_from_char(yytext[1]); + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); + yylval->swiz_mask.mask = mask_from_char(yytext[1]); + return_token_or_DOT(require_ARB_fp, MASK1); +} + YY_BREAK +case 176: +YY_RULE_SETUP +#line 442 "program_lexer.l" +{ + if (require_ARB_vp) { + return TEXGEN_R; + } else { + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, + SWIZZLE_X, SWIZZLE_X); + yylval->swiz_mask.mask = WRITEMASK_X; + return MASK1; + } +} + YY_BREAK +case 177: +YY_RULE_SETUP +#line 453 "program_lexer.l" +{ + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), + swiz_from_char(yytext[2]), + swiz_from_char(yytext[3]), + swiz_from_char(yytext[4])); + yylval->swiz_mask.mask = 0; + return_token_or_DOT(require_ARB_fp, SWIZZLE); +} + YY_BREAK +case 178: +YY_RULE_SETUP +#line 462 "program_lexer.l" +{ return DOT; } + YY_BREAK +case 179: +/* rule 179 can match eol */ +YY_RULE_SETUP +#line 464 "program_lexer.l" +{ + yylloc->first_line++; + yylloc->first_column = 1; + yylloc->last_line++; + yylloc->last_column = 1; + yylloc->position++; +} + YY_BREAK +case 180: +YY_RULE_SETUP +#line 471 "program_lexer.l" +/* eat whitespace */ ; + YY_BREAK +case 181: +*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ +yyg->yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 472 "program_lexer.l" +/* eat comments */ ; + YY_BREAK +case 182: +YY_RULE_SETUP +#line 473 "program_lexer.l" +{ return yytext[0]; } + YY_BREAK +case 183: +YY_RULE_SETUP +#line 474 "program_lexer.l" +ECHO; + YY_BREAK +#line 2396 "lex.yy.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( yywrap(yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = yyg->yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ,yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yyg->yy_start; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 675 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +{ + register int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + register char *yy_cp = yyg->yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 675 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 674); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) +{ + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_cp = yyg->yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yyg->yy_hold_char; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yyg->yy_n_chars + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + yyg->yytext_ptr = yy_bp; + yyg->yy_hold_char = *yy_cp; + yyg->yy_c_buf_p = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (yyscan_t yyscanner) +#else + static int input (yyscan_t yyscanner) +#endif + +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap(yyscanner ) ) + return EOF; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + yy_load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void yy_load_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * @param yyscanner The scanner object. + */ + void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ,yyscanner ); + + yyfree((void *) b ,yyscanner ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ + void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state(yyscanner ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(yyscanner); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void yypop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (yyscan_t yyscanner) +{ + int num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ,yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yyg->yy_hold_char; \ + yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ + yyg->yy_hold_char = *yyg->yy_c_buf_p; \ + *yyg->yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int yyget_lineno (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int yyget_column (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_out (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +int yyget_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *yyget_text (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/** Set the current line number. + * @param line_number + * @param yyscanner The scanner object. + */ +void yyset_lineno (int line_number , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void yyset_column (int column_no , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "yyset_column called with no buffer" , yyscanner); + + yycolumn = column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * @param yyscanner The scanner object. + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void yyset_out (FILE * out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int yyget_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void yyset_debug (int bdebug , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; +} + +/* Accessor methods for yylval and yylloc */ + +YYSTYPE * yyget_lval (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylval; +} + +void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylval = yylval_param; +} + +YYLTYPE *yyget_lloc (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylloc; +} + +void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylloc = yylloc_param; +} + +/* User-visible API */ + +/* yylex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ + +int yylex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* yylex_init_extra has the same functionality as yylex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to yyalloc in + * the yyextra field. + */ + +int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + yyset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + yyset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +static int yy_init_globals (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + yyfree(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + yyfree(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + yyfree ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size , yyscan_t yyscanner) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr , yyscan_t yyscanner) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 474 "program_lexer.l" + + + +void +_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state, + const char *string, size_t len) +{ + yylex_init_extra(state,scanner); + yy_scan_bytes(string,len,*scanner); +} + +void +_mesa_program_lexer_dtor(void *scanner) +{ + yylex_destroy(scanner); +} + diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c index 5142c2a4a5..d6469b17be 100644 --- a/src/mesa/shader/nvprogram.c +++ b/src/mesa/shader/nvprogram.c @@ -354,6 +354,7 @@ _mesa_GetTrackMatrixivNV(GLenum target, GLuint address, void GLAPIENTRY _mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params) { + const struct gl_client_array *array; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -362,15 +363,17 @@ _mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params) return; } + array = &ctx->Array.ArrayObj->VertexAttrib[index]; + switch (pname) { case GL_ATTRIB_ARRAY_SIZE_NV: - params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Size; + params[0] = array->Size; break; case GL_ATTRIB_ARRAY_STRIDE_NV: - params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Stride; + params[0] = array->Stride; break; case GL_ATTRIB_ARRAY_TYPE_NV: - params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Type; + params[0] = array->Type; break; case GL_CURRENT_ATTRIB_NV: if (index == 0) { @@ -395,6 +398,7 @@ _mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params) void GLAPIENTRY _mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params) { + const struct gl_client_array *array; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -403,15 +407,17 @@ _mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params) return; } + array = &ctx->Array.ArrayObj->VertexAttrib[index]; + switch (pname) { case GL_ATTRIB_ARRAY_SIZE_NV: - params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Size; + params[0] = (GLfloat) array->Size; break; case GL_ATTRIB_ARRAY_STRIDE_NV: - params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Stride; + params[0] = (GLfloat) array->Stride; break; case GL_ATTRIB_ARRAY_TYPE_NV: - params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Type; + params[0] = (GLfloat) array->Type; break; case GL_CURRENT_ATTRIB_NV: if (index == 0) { @@ -436,6 +442,7 @@ _mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params) void GLAPIENTRY _mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params) { + const struct gl_client_array *array; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -444,15 +451,17 @@ _mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params) return; } + array = &ctx->Array.ArrayObj->VertexAttrib[index]; + switch (pname) { case GL_ATTRIB_ARRAY_SIZE_NV: - params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Size; + params[0] = array->Size; break; case GL_ATTRIB_ARRAY_STRIDE_NV: - params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Stride; + params[0] = array->Stride; break; case GL_ATTRIB_ARRAY_TYPE_NV: - params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Type; + params[0] = array->Type; break; case GL_CURRENT_ATTRIB_NV: if (index == 0) { @@ -467,7 +476,7 @@ _mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params) params[3] = (GLint) ctx->Current.Attrib[index][3]; break; case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: - params[0] = ctx->Array.ArrayObj->VertexAttrib[index].BufferObj->Name; + params[0] = array->BufferObj->Name; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV"); @@ -706,7 +715,7 @@ _mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); prog = _mesa_lookup_program(ctx, id); if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) { diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 68a59350a1..f4beb9a78b 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -225,6 +225,13 @@ fetch_vector4(const struct prog_src_register *source, result[2] = -result[2]; result[3] = -result[3]; } + +#ifdef NAN_CHECK + assert(!IS_INF_OR_NAN(result[0])); + assert(!IS_INF_OR_NAN(result[0])); + assert(!IS_INF_OR_NAN(result[0])); + assert(!IS_INF_OR_NAN(result[0])); +#endif } @@ -479,6 +486,13 @@ store_vector4(const struct prog_instruction *inst, } } +#ifdef NAN_CHECK + assert(!IS_INF_OR_NAN(value[0])); + assert(!IS_INF_OR_NAN(value[0])); + assert(!IS_INF_OR_NAN(value[0])); + assert(!IS_INF_OR_NAN(value[0])); +#endif + if (writeMask & WRITEMASK_X) dst[0] = value[0]; if (writeMask & WRITEMASK_Y) @@ -832,10 +846,14 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_EX2: /* Exponential base 2 */ { - GLfloat a[4], result[4]; + GLfloat a[4], result[4], val; fetch_vector1(&inst->SrcReg[0], machine, a); - result[0] = result[1] = result[2] = result[3] = - (GLfloat) _mesa_pow(2.0, a[0]); + val = (GLfloat) _mesa_pow(2.0, a[0]); + /* + if (IS_INF_OR_NAN(val)) + val = 1.0e10; + */ + result[0] = result[1] = result[2] = result[3] = val; store_vector4(inst, machine, result); } break; @@ -911,12 +929,17 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_LG2: /* log base 2 */ { - GLfloat a[4], result[4]; + GLfloat a[4], result[4], val; fetch_vector1(&inst->SrcReg[0], machine, a); /* The fast LOG2 macro doesn't meet the precision requirements. */ - result[0] = result[1] = result[2] = result[3] = - (log(a[0]) * 1.442695F); + if (a[0] == 0.0F) { + val = 0.0F; + } + else { + val = log(a[0]) * 1.442695F; + } + result[0] = result[1] = result[2] = result[3] = val; store_vector4(inst, machine, result); } break; diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index ae3a003fee..44c961927a 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -343,7 +343,10 @@ _mesa_opcode_string(gl_inst_opcode opcode) { if (opcode < MAX_OPCODE) return InstInfo[opcode].Name; - else - return "OP?"; + else { + static char s[20]; + _mesa_snprintf(s, sizeof(s), "OP%u", opcode); + return s; + } } diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index 40ad998f79..39a221eeab 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -133,6 +133,7 @@ #define NEGATE_Y 0x2 #define NEGATE_Z 0x4 #define NEGATE_W 0x8 +#define NEGATE_XYZ 0x7 #define NEGATE_XYZW 0xf #define NEGATE_NONE 0x0 /*@}*/ @@ -303,11 +304,11 @@ struct prog_dst_register * Condition code swizzle value. */ GLuint CondSwizzle:12; - + /** * Selects the condition code register to use for conditional destination * update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only - * condition code register 0 is available. In NV_vertex_program3 mode, + * condition code register 0 is available. In NV_vertex_program3 mode, * condition code registers 0 and 1 are available. */ GLuint CondSrc:1; @@ -359,7 +360,7 @@ struct prog_instruction * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3. */ GLuint SaturateMode:2; - + /** * Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12. * @@ -374,7 +375,7 @@ struct prog_instruction /*@{*/ /** Source texture unit. */ GLuint TexSrcUnit:5; - + /** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */ GLuint TexSrcTarget:3; diff --git a/src/mesa/shader/prog_optimize.c b/src/mesa/shader/prog_optimize.c index 6ba2e76ff9..be903106a0 100644 --- a/src/mesa/shader/prog_optimize.c +++ b/src/mesa/shader/prog_optimize.c @@ -547,15 +547,13 @@ update_interval(GLint intBegin[], GLint intEnd[], GLuint index, GLuint ic) /** - * Find the live intervals for each temporary register in the program. - * For register R, the interval [A,B] indicates that R is referenced - * from instruction A through instruction B. - * Special consideration is needed for loops and subroutines. - * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason + * Find first/last instruction that references each temporary register. */ -static GLboolean -find_live_intervals(struct gl_program *prog, - struct interval_list *liveIntervals) +GLboolean +_mesa_find_temp_intervals(const struct prog_instruction *instructions, + GLuint numInstructions, + GLint intBegin[MAX_PROGRAM_TEMPS], + GLint intEnd[MAX_PROGRAM_TEMPS]) { struct loop_info { @@ -563,26 +561,15 @@ find_live_intervals(struct gl_program *prog, }; struct loop_info loopStack[MAX_LOOP_NESTING]; GLuint loopStackDepth = 0; - GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS]; GLuint i; - /* - * Note: we'll return GL_FALSE below if we find relative indexing - * into the TEMP register file. We can't handle that yet. - * We also give up on subroutines for now. - */ - - if (dbg) { - _mesa_printf("Optimize: Begin find intervals\n"); - } - for (i = 0; i < MAX_PROGRAM_TEMPS; i++){ intBegin[i] = intEnd[i] = -1; } /* Scan instructions looking for temporary registers */ - for (i = 0; i < prog->NumInstructions; i++) { - const struct prog_instruction *inst = prog->Instructions + i; + for (i = 0; i < numInstructions; i++) { + const struct prog_instruction *inst = instructions + i; if (inst->Opcode == OPCODE_BGNLOOP) { loopStack[loopStackDepth].Start = i; loopStack[loopStackDepth].End = inst->BranchTarget; @@ -595,7 +582,7 @@ find_live_intervals(struct gl_program *prog, return GL_FALSE; } else { - const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); + const GLuint numSrc = 3;/*_mesa_num_inst_src_regs(inst->Opcode);*/ GLuint j; for (j = 0; j < numSrc; j++) { if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { @@ -624,6 +611,39 @@ find_live_intervals(struct gl_program *prog, } } + return GL_TRUE; +} + + +/** + * Find the live intervals for each temporary register in the program. + * For register R, the interval [A,B] indicates that R is referenced + * from instruction A through instruction B. + * Special consideration is needed for loops and subroutines. + * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason + */ +static GLboolean +find_live_intervals(struct gl_program *prog, + struct interval_list *liveIntervals) +{ + GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS]; + GLuint i; + + /* + * Note: we'll return GL_FALSE below if we find relative indexing + * into the TEMP register file. We can't handle that yet. + * We also give up on subroutines for now. + */ + + if (dbg) { + _mesa_printf("Optimize: Begin find intervals\n"); + } + + /* build intermediate arrays */ + if (!_mesa_find_temp_intervals(prog->Instructions, prog->NumInstructions, + intBegin, intEnd)) + return GL_FALSE; + /* Build live intervals list from intermediate arrays */ liveIntervals->Num = 0; for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { @@ -792,8 +812,6 @@ _mesa_reallocate_registers(struct gl_program *prog) } - - /** * Apply optimizations to the given program to eliminate unnecessary * instructions, temp regs, etc. diff --git a/src/mesa/shader/prog_optimize.h b/src/mesa/shader/prog_optimize.h index d102cfd9fc..43894a2723 100644 --- a/src/mesa/shader/prog_optimize.h +++ b/src/mesa/shader/prog_optimize.h @@ -25,7 +25,19 @@ #ifndef PROG_OPT_H #define PROG_OPT_H + +#include "main/config.h" + + struct gl_program; +struct prog_instruction; + + +extern GLboolean +_mesa_find_temp_intervals(const struct prog_instruction *instructions, + GLuint numInstructions, + GLint intBegin[MAX_PROGRAM_TEMPS], + GLint intEnd[MAX_PROGRAM_TEMPS]); extern void _mesa_optimize_program(GLcontext *ctx, struct gl_program *program); diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index bcd8c5d9dc..6b9e73b2cb 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -44,6 +44,34 @@ _mesa_new_parameter_list(void) } +struct gl_program_parameter_list * +_mesa_new_parameter_list_sized(unsigned size) +{ + struct gl_program_parameter_list *p = _mesa_new_parameter_list(); + + if ((p != NULL) && (size != 0)) { + p->Size = size; + + /* alloc arrays */ + p->Parameters = (struct gl_program_parameter *) + _mesa_calloc(size * sizeof(struct gl_program_parameter)); + + p->ParameterValues = (GLfloat (*)[4]) + _mesa_align_malloc(size * 4 *sizeof(GLfloat), 16); + + + if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) { + _mesa_free(p->Parameters); + _mesa_align_free(p->ParameterValues); + _mesa_free(p); + p = NULL; + } + } + + return p; +} + + /** * Free a parameter list and all its parameters */ diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index 01f5a0e179..d1fcf47e61 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -84,6 +84,9 @@ struct gl_program_parameter_list extern struct gl_program_parameter_list * _mesa_new_parameter_list(void); +extern struct gl_program_parameter_list * +_mesa_new_parameter_list_sized(unsigned size); + extern void _mesa_free_parameter_list(struct gl_program_parameter_list *paramList); diff --git a/src/mesa/shader/prog_parameter_layout.c b/src/mesa/shader/prog_parameter_layout.c new file mode 100644 index 0000000000..1c37b3a7a5 --- /dev/null +++ b/src/mesa/shader/prog_parameter_layout.c @@ -0,0 +1,217 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file prog_parameter_layout.c + * \brief Helper functions to layout storage for program parameters + * + * \author Ian Romanick <ian.d.romanick@intel.com> + */ + +#include "main/mtypes.h" +#include "prog_parameter.h" +#include "prog_parameter_layout.h" +#include "prog_instruction.h" +#include "program_parser.h" + +unsigned +_mesa_combine_swizzles(unsigned base, unsigned applied) +{ + unsigned swiz = 0; + unsigned i; + + for (i = 0; i < 4; i++) { + const unsigned s = GET_SWZ(applied, i); + + swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3); + } + + return swiz; +} + + +/** + * Copy indirect access array from one parameter list to another + * + * \param src Parameter array copied from + * \param dst Parameter array copied to + * \param first Index of first element in \c src to copy + * \param count Number of elements to copy + * + * \return + * The location in \c dst of the first element copied from \c src on + * success. -1 on failure. + * + * \warning + * This function assumes that there is already enough space available in + * \c dst to hold all of the elements that will be copied over. + */ +static int +copy_indirect_accessed_array(struct gl_program_parameter_list *src, + struct gl_program_parameter_list *dst, + unsigned first, unsigned count) +{ + const int base = dst->NumParameters; + unsigned i; + unsigned j; + + + for (i = first; i < (first + count); i++) { + struct gl_program_parameter *curr = & src->Parameters[i]; + + + if (curr->Type == PROGRAM_CONSTANT) { + j = dst->NumParameters; + } else { + for (j = 0; j < dst->NumParameters; j++) { + if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes, + sizeof(curr->StateIndexes)) == 0) { + return -1; + } + } + } + + assert(j == dst->NumParameters); + + memcpy(& dst->Parameters[j], curr, + sizeof(dst->Parameters[j])); + memcpy(dst->ParameterValues[j], src->ParameterValues[i], + sizeof(GLfloat) * 4); + curr->Name = NULL; + + dst->NumParameters++; + } + + return base; +} + + +/** + * XXX description??? + * \return GL_TRUE for success, GL_FALSE for failure + */ +GLboolean +_mesa_layout_parameters(struct asm_parser_state *state) +{ + struct gl_program_parameter_list *layout; + struct asm_instruction *inst; + unsigned i; + + + layout = + _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters); + + + /* PASS 1: Move any parameters that are accessed indirectly from the + * original parameter list to the new parameter list. + */ + for (inst = state->inst_head; inst != NULL; inst = inst->next) { + for (i = 0; i < 3; i++) { + if (inst->SrcReg[i].Base.RelAddr) { + /* Only attempt to add the to the new parameter list once. + */ + if (!inst->SrcReg[i].Symbol->pass1_done) { + const int new_begin = + copy_indirect_accessed_array(state->prog->Parameters, layout, + inst->SrcReg[i].Symbol->param_binding_begin, + inst->SrcReg[i].Symbol->param_binding_length); + + if (new_begin < 0) { + return GL_FALSE; + } + + inst->SrcReg[i].Symbol->param_binding_begin = new_begin; + inst->SrcReg[i].Symbol->pass1_done = 1; + } + + /* Previously the Index was just the offset from the parameter + * array. Now that the base of the parameter array is known, the + * index can be updated to its actual value. + */ + inst->Base.SrcReg[i] = inst->SrcReg[i].Base; + inst->Base.SrcReg[i].Index += + inst->SrcReg[i].Symbol->param_binding_begin; + } + } + } + + + /* PASS 2: Move any parameters that are not accessed indirectly from the + * original parameter list to the new parameter list. + */ + for (inst = state->inst_head; inst != NULL; inst = inst->next) { + for (i = 0; i < 3; i++) { + const struct gl_program_parameter *p; + const int idx = inst->SrcReg[i].Base.Index; + unsigned swizzle = SWIZZLE_NOOP; + + + /* All relative addressed operands were processed on the first + * pass. Just skip them here. + */ + if (inst->SrcReg[i].Base.RelAddr) { + continue; + } + + + if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING ) + || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) { + continue; + } + + inst->Base.SrcReg[i] = inst->SrcReg[i].Base; + p = & state->prog->Parameters->Parameters[idx]; + + switch (p->Type) { + case PROGRAM_CONSTANT: { + const float *const v = + state->prog->Parameters->ParameterValues[idx]; + + inst->Base.SrcReg[i].Index = + _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle); + + inst->Base.SrcReg[i].Swizzle = + _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle); + break; + } + + case PROGRAM_STATE_VAR: + inst->Base.SrcReg[i].Index = + _mesa_add_state_reference(layout, p->StateIndexes); + break; + + default: + break; + } + + inst->SrcReg[i].Base.File = p->Type; + inst->Base.SrcReg[i].File = p->Type; + } + } + + + _mesa_free_parameter_list(state->prog->Parameters); + state->prog->Parameters = layout; + + return GL_TRUE; +} diff --git a/src/mesa/shader/prog_parameter_layout.h b/src/mesa/shader/prog_parameter_layout.h new file mode 100644 index 0000000000..99a7b6c726 --- /dev/null +++ b/src/mesa/shader/prog_parameter_layout.h @@ -0,0 +1,42 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file prog_parameter_layout.h + * \brief Helper functions to layout storage for program parameters + * + * \author Ian Romanick <ian.d.romanick@intel.com> + */ + +#pragma once + +#ifndef PROG_PARAMETER_LAYOUT_H +#define PROG_PARAMETER_LAYOUT_H + +extern unsigned _mesa_combine_swizzles(unsigned base, unsigned applied); + +struct asm_parser_state; + +extern GLboolean _mesa_layout_parameters(struct asm_parser_state *state); + +#endif /* PROG_PARAMETER_LAYOUT_H */ diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 9967f2978d..c8346d4293 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -75,7 +75,11 @@ file_string(gl_register_file f, gl_prog_print_mode mode) case PROGRAM_UNDEFINED: return "UNDEFINED"; default: - return "Unknown program file!"; + { + static char s[20]; + _mesa_snprintf(s, sizeof(s), "FILE%u", f); + return s; + } } } @@ -537,7 +541,7 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, /** * Print a single vertex/fragment program instruction. */ -static GLint +GLint _mesa_fprint_instruction_opt(FILE *f, const struct prog_instruction *inst, GLint indent, @@ -736,7 +740,10 @@ _mesa_fprint_instruction_opt(FILE *f, mode, prog); } else { - _mesa_fprintf(f, "Other opcode %d\n", inst->Opcode); + fprint_alu_instruction(f, inst, + _mesa_opcode_string(inst->Opcode), + 3/*_mesa_num_inst_src_regs(inst->Opcode)*/, + mode, prog); } break; } @@ -809,7 +816,30 @@ _mesa_fprint_program_opt(FILE *f, void _mesa_print_program(const struct gl_program *prog) { - _mesa_fprint_program_opt(stdout, prog, PROG_PRINT_DEBUG, GL_TRUE); + _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE); +} + + +/** + * Return binary representation of value (as a string). + * Insert a comma to separate each group of 8 bits. + * XXX move to imports.[ch] if useful elsewhere. + */ +static const char * +binary(GLbitfield val) +{ + static char buf[50]; + GLint i, len = 0; + for (i = 31; i >= 0; --i) { + if (val & (1 << i)) + buf[len++] = '1'; + else if (len > 0 || i == 0) + buf[len++] = '0'; + if (len > 0 && ((i-1) % 8) == 7) + buf[len++] = ','; + } + buf[len] = '\0'; + return buf; } @@ -823,13 +853,17 @@ _mesa_fprint_program_parameters(FILE *f, { GLuint i; - _mesa_fprintf(f, "InputsRead: 0x%x\n", prog->InputsRead); - _mesa_fprintf(f, "OutputsWritten: 0x%x\n", prog->OutputsWritten); + _mesa_fprintf(f, "InputsRead: 0x%x (0b%s)\n", + prog->InputsRead, binary(prog->InputsRead)); + _mesa_fprintf(f, "OutputsWritten: 0x%x (0b%s)\n", + prog->OutputsWritten, binary(prog->OutputsWritten)); _mesa_fprintf(f, "NumInstructions=%d\n", prog->NumInstructions); _mesa_fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries); _mesa_fprintf(f, "NumParameters=%d\n", prog->NumParameters); _mesa_fprintf(f, "NumAttributes=%d\n", prog->NumAttributes); _mesa_fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs); + _mesa_fprintf(f, "SamplersUsed: 0x%x (0b%s)\n", + prog->SamplersUsed, binary(prog->SamplersUsed)); _mesa_fprintf(f, "Samplers=[ "); for (i = 0; i < MAX_SAMPLERS; i++) { _mesa_fprintf(f, "%d ", prog->SamplerUnits[i]); @@ -926,7 +960,7 @@ _mesa_write_shader_to_file(const struct gl_shader *shader) return; } - fprintf(f, "/* Shader %u source */\n", shader->Name); + fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum); fputs(shader->Source, f); fprintf(f, "\n"); @@ -941,9 +975,45 @@ _mesa_write_shader_to_file(const struct gl_shader *shader) fprintf(f, "/*\n"); _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE); fprintf(f, "*/\n"); + fprintf(f, "/* Parameters / constants */\n"); + fprintf(f, "/*\n"); + _mesa_fprint_parameter_list(f, shader->Program->Parameters); + fprintf(f, "*/\n"); } fclose(f); } +/** + * Append the shader's uniform info/values to the shader log file. + * The log file will typically have been created by the + * _mesa_write_shader_to_file function. + */ +void +_mesa_append_uniforms_to_file(const struct gl_shader *shader, + const struct gl_program *prog) +{ + const char *type; + char filename[100]; + FILE *f; + + if (shader->Type == GL_FRAGMENT_SHADER) + type = "frag"; + else + type = "vert"; + + _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type); + f = fopen(filename, "a"); /* append */ + if (!f) { + fprintf(stderr, "Unable to open %s for appending\n", filename); + return; + } + + fprintf(f, "/* First-draw parameters / constants */\n"); + fprintf(f, "/*\n"); + _mesa_fprint_parameter_list(f, prog->Parameters); + fprintf(f, "*/\n"); + + fclose(f); +} diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index d55661cebb..fc286ded54 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -57,6 +57,13 @@ extern void _mesa_print_instruction(const struct prog_instruction *inst); extern GLint +_mesa_fprint_instruction_opt(FILE *f, + const struct prog_instruction *inst, + GLint indent, + gl_prog_print_mode mode, + const struct gl_program *prog); + +extern GLint _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, gl_prog_print_mode mode, const struct gl_program *prog); @@ -79,5 +86,9 @@ _mesa_print_parameter_list(const struct gl_program_parameter_list *list); extern void _mesa_write_shader_to_file(const struct gl_shader *shader); +extern void +_mesa_append_uniforms_to_file(const struct gl_shader *shader, + const struct gl_program *prog); + #endif /* PROG_PRINT_H */ diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index d270bf9e1c..963478fccd 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -62,6 +62,12 @@ _mesa_init_program(GLcontext *ctx) ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents / 4 <= (1 << INST_INDEX_BITS)); + /* If this fails, increase prog_instruction::TexSrcUnit size */ + ASSERT(MAX_TEXTURE_UNITS < (1 << 5)); + + /* If this fails, increase prog_instruction::TexSrcTarget size */ + ASSERT(NUM_TEXTURE_TARGETS < (1 << 3)); + ctx->Program.ErrorPos = -1; ctx->Program.ErrorString = _mesa_strdup(""); @@ -820,3 +826,63 @@ _mesa_find_free_register(const struct gl_program *prog, GLuint regFile) return -1; } + + + +/** + * "Post-process" a GPU program. This is intended to be used for debugging. + * Example actions include no-op'ing instructions or changing instruction + * behaviour. + */ +void +_mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog) +{ + static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 }; + GLuint i; + GLuint whiteSwizzle; + GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters, + white, 4, &whiteSwizzle); + + (void) whiteIndex; + + for (i = 0; i < prog->NumInstructions; i++) { + struct prog_instruction *inst = prog->Instructions + i; + const GLuint n = _mesa_num_inst_src_regs(inst->Opcode); + + (void) n; + + if (_mesa_is_tex_instruction(inst->Opcode)) { +#if 0 + /* replace TEX/TXP/TXB with MOV */ + inst->Opcode = OPCODE_MOV; + inst->DstReg.WriteMask = WRITEMASK_XYZW; + inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; + inst->SrcReg[0].Negate = NEGATE_NONE; +#endif + +#if 0 + /* disable shadow texture mode */ + inst->TexShadow = 0; +#endif + } + + if (inst->Opcode == OPCODE_TXP) { +#if 0 + inst->Opcode = OPCODE_MOV; + inst->DstReg.WriteMask = WRITEMASK_XYZW; + inst->SrcReg[0].File = PROGRAM_CONSTANT; + inst->SrcReg[0].Index = whiteIndex; + inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; + inst->SrcReg[0].Negate = NEGATE_NONE; +#endif +#if 0 + inst->TexShadow = 0; +#endif +#if 0 + inst->Opcode = OPCODE_TEX; + inst->TexShadow = 0; +#endif + } + + } +} diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 48176162c3..56a4191f57 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -122,6 +122,8 @@ _mesa_combine_programs(GLcontext *ctx, extern GLint _mesa_find_free_register(const struct gl_program *prog, GLuint regFile); +extern void +_mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog); #endif /* PROGRAM_H */ diff --git a/src/mesa/shader/program_lexer.l b/src/mesa/shader/program_lexer.l new file mode 100644 index 0000000000..c50c7c5739 --- /dev/null +++ b/src/mesa/shader/program_lexer.l @@ -0,0 +1,488 @@ +%{ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include "main/glheader.h" +#include "prog_instruction.h" + +#include "program_parser.h" +#include "program_parse.tab.h" + +#define require_ARB_vp (yyextra->mode == ARB_vertex) +#define require_ARB_fp (yyextra->mode == ARB_fragment) +#define require_shadow (yyextra->option.Shadow) +#define require_rect (yyextra->option.TexRect) +#define require_texarray (yyextra->option.TexArray) + +#define return_token_or_IDENTIFIER(condition, token) \ + do { \ + if (condition) { \ + return token; \ + } else { \ + yylval->string = strdup(yytext); \ + return IDENTIFIER; \ + } \ + } while (0) + +#define return_token_or_DOT(condition, token) \ + do { \ + if (condition) { \ + return token; \ + } else { \ + yyless(1); \ + return DOT; \ + } \ + } while (0) + + +#define return_opcode(condition, token, opcode, sat) \ + do { \ + if (condition) { \ + yylval->temp_inst.Opcode = OPCODE_ ## opcode; \ + yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \ + return token; \ + } else { \ + yylval->string = strdup(yytext); \ + return IDENTIFIER; \ + } \ + } while (0) + +#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \ + SWIZZLE_NIL, SWIZZLE_NIL) + +static unsigned +mask_from_char(char c) +{ + switch (c) { + case 'x': + case 'r': + return WRITEMASK_X; + case 'y': + case 'g': + return WRITEMASK_Y; + case 'z': + case 'b': + return WRITEMASK_Z; + case 'w': + case 'a': + return WRITEMASK_W; + } + + return 0; +} + +static unsigned +swiz_from_char(char c) +{ + switch (c) { + case 'x': + case 'r': + return SWIZZLE_X; + case 'y': + case 'g': + return SWIZZLE_Y; + case 'z': + case 'b': + return SWIZZLE_Z; + case 'w': + case 'a': + return SWIZZLE_W; + } + + return 0; +} + +#define YY_USER_ACTION \ + do { \ + yylloc->first_column = yylloc->last_column; \ + yylloc->last_column += yyleng; \ + if ((yylloc->first_line == 1) \ + && (yylloc->first_column == 1)) { \ + yylloc->position = 1; \ + } else { \ + yylloc->position += yylloc->last_column - yylloc->first_column; \ + } \ + } while(0); + +#define YY_EXTRA_TYPE struct asm_parser_state * +%} + +num [0-9]+ +exp [Ee][-+]?[0-9]+ +frac "."[0-9]+ +dot "."[ \t]* + +%option bison-bridge bison-locations reentrant noyywrap +%% + +"!!ARBvp1.0" { return ARBvp_10; } +"!!ARBfp1.0" { return ARBfp_10; } +ADDRESS { + yylval->integer = at_address; + return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS); +} +ALIAS { return ALIAS; } +ATTRIB { return ATTRIB; } +END { return END; } +OPTION { return OPTION; } +OUTPUT { return OUTPUT; } +PARAM { return PARAM; } +TEMP { yylval->integer = at_temp; return TEMP; } + +ABS { return_opcode( 1, VECTOR_OP, ABS, OFF); } +ABS_SAT { return_opcode(require_ARB_fp, VECTOR_OP, ABS, ZERO_ONE); } +ADD { return_opcode( 1, BIN_OP, ADD, OFF); } +ADD_SAT { return_opcode(require_ARB_fp, BIN_OP, ADD, ZERO_ONE); } +ARL { return_opcode(require_ARB_vp, ARL, ARL, OFF); } + +CMP { return_opcode(require_ARB_fp, TRI_OP, CMP, OFF); } +CMP_SAT { return_opcode(require_ARB_fp, TRI_OP, CMP, ZERO_ONE); } +COS { return_opcode(require_ARB_fp, SCALAR_OP, COS, OFF); } +COS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, COS, ZERO_ONE); } + +DP3 { return_opcode( 1, BIN_OP, DP3, OFF); } +DP3_SAT { return_opcode(require_ARB_fp, BIN_OP, DP3, ZERO_ONE); } +DP4 { return_opcode( 1, BIN_OP, DP4, OFF); } +DP4_SAT { return_opcode(require_ARB_fp, BIN_OP, DP4, ZERO_ONE); } +DPH { return_opcode( 1, BIN_OP, DPH, OFF); } +DPH_SAT { return_opcode(require_ARB_fp, BIN_OP, DPH, ZERO_ONE); } +DST { return_opcode( 1, BIN_OP, DST, OFF); } +DST_SAT { return_opcode(require_ARB_fp, BIN_OP, DST, ZERO_ONE); } + +EX2 { return_opcode( 1, SCALAR_OP, EX2, OFF); } +EX2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, EX2, ZERO_ONE); } +EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, OFF); } + +FLR { return_opcode( 1, VECTOR_OP, FLR, OFF); } +FLR_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FLR, ZERO_ONE); } +FRC { return_opcode( 1, VECTOR_OP, FRC, OFF); } +FRC_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FRC, ZERO_ONE); } + +KIL { return_opcode(require_ARB_fp, KIL, KIL, OFF); } + +LIT { return_opcode( 1, VECTOR_OP, LIT, OFF); } +LIT_SAT { return_opcode(require_ARB_fp, VECTOR_OP, LIT, ZERO_ONE); } +LG2 { return_opcode( 1, SCALAR_OP, LG2, OFF); } +LG2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, LG2, ZERO_ONE); } +LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, OFF); } +LRP { return_opcode(require_ARB_fp, TRI_OP, LRP, OFF); } +LRP_SAT { return_opcode(require_ARB_fp, TRI_OP, LRP, ZERO_ONE); } + +MAD { return_opcode( 1, TRI_OP, MAD, OFF); } +MAD_SAT { return_opcode(require_ARB_fp, TRI_OP, MAD, ZERO_ONE); } +MAX { return_opcode( 1, BIN_OP, MAX, OFF); } +MAX_SAT { return_opcode(require_ARB_fp, BIN_OP, MAX, ZERO_ONE); } +MIN { return_opcode( 1, BIN_OP, MIN, OFF); } +MIN_SAT { return_opcode(require_ARB_fp, BIN_OP, MIN, ZERO_ONE); } +MOV { return_opcode( 1, VECTOR_OP, MOV, OFF); } +MOV_SAT { return_opcode(require_ARB_fp, VECTOR_OP, MOV, ZERO_ONE); } +MUL { return_opcode( 1, BIN_OP, MUL, OFF); } +MUL_SAT { return_opcode(require_ARB_fp, BIN_OP, MUL, ZERO_ONE); } + +POW { return_opcode( 1, BINSC_OP, POW, OFF); } +POW_SAT { return_opcode(require_ARB_fp, BINSC_OP, POW, ZERO_ONE); } + +RCP { return_opcode( 1, SCALAR_OP, RCP, OFF); } +RCP_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RCP, ZERO_ONE); } +RSQ { return_opcode( 1, SCALAR_OP, RSQ, OFF); } +RSQ_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RSQ, ZERO_ONE); } + +SCS { return_opcode(require_ARB_fp, SCALAR_OP, SCS, OFF); } +SCS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SCS, ZERO_ONE); } +SGE { return_opcode( 1, BIN_OP, SGE, OFF); } +SGE_SAT { return_opcode(require_ARB_fp, BIN_OP, SGE, ZERO_ONE); } +SIN { return_opcode(require_ARB_fp, SCALAR_OP, SIN, OFF); } +SIN_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SIN, ZERO_ONE); } +SLT { return_opcode( 1, BIN_OP, SLT, OFF); } +SLT_SAT { return_opcode(require_ARB_fp, BIN_OP, SLT, ZERO_ONE); } +SUB { return_opcode( 1, BIN_OP, SUB, OFF); } +SUB_SAT { return_opcode(require_ARB_fp, BIN_OP, SUB, ZERO_ONE); } +SWZ { return_opcode( 1, SWZ, SWZ, OFF); } +SWZ_SAT { return_opcode(require_ARB_fp, SWZ, SWZ, ZERO_ONE); } + +TEX { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, OFF); } +TEX_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, ZERO_ONE); } +TXB { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, OFF); } +TXB_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, ZERO_ONE); } +TXP { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, OFF); } +TXP_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, ZERO_ONE); } + +XPD { return_opcode( 1, BIN_OP, XPD, OFF); } +XPD_SAT { return_opcode(require_ARB_fp, BIN_OP, XPD, ZERO_ONE); } + +vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); } +fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); } +program { return PROGRAM; } +state { return STATE; } +result { return RESULT; } + +{dot}ambient { return AMBIENT; } +{dot}attenuation { return ATTENUATION; } +{dot}back { return BACK; } +{dot}clip { return_token_or_DOT(require_ARB_vp, CLIP); } +{dot}color { return COLOR; } +{dot}depth { return_token_or_DOT(require_ARB_fp, DEPTH); } +{dot}diffuse { return DIFFUSE; } +{dot}direction { return DIRECTION; } +{dot}emission { return EMISSION; } +{dot}env { return ENV; } +{dot}eye { return EYE; } +{dot}fogcoord { return FOGCOORD; } +{dot}fog { return FOG; } +{dot}front { return FRONT; } +{dot}half { return HALF; } +{dot}inverse { return INVERSE; } +{dot}invtrans { return INVTRANS; } +{dot}light { return LIGHT; } +{dot}lightmodel { return LIGHTMODEL; } +{dot}lightprod { return LIGHTPROD; } +{dot}local { return LOCAL; } +{dot}material { return MATERIAL; } +{dot}program { return MAT_PROGRAM; } +{dot}matrix { return MATRIX; } +{dot}matrixindex { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); } +{dot}modelview { return MODELVIEW; } +{dot}mvp { return MVP; } +{dot}normal { return_token_or_DOT(require_ARB_vp, NORMAL); } +{dot}object { return OBJECT; } +{dot}palette { return PALETTE; } +{dot}params { return PARAMS; } +{dot}plane { return PLANE; } +{dot}point { return_token_or_DOT(require_ARB_vp, POINT); } +{dot}pointsize { return_token_or_DOT(require_ARB_vp, POINTSIZE); } +{dot}position { return POSITION; } +{dot}primary { return PRIMARY; } +{dot}projection { return PROJECTION; } +{dot}range { return_token_or_DOT(require_ARB_fp, RANGE); } +{dot}row { return ROW; } +{dot}scenecolor { return SCENECOLOR; } +{dot}secondary { return SECONDARY; } +{dot}shininess { return SHININESS; } +{dot}size { return_token_or_DOT(require_ARB_vp, SIZE); } +{dot}specular { return SPECULAR; } +{dot}spot { return SPOT; } +{dot}texcoord { return TEXCOORD; } +{dot}texenv { return_token_or_DOT(require_ARB_fp, TEXENV); } +{dot}texgen { return_token_or_DOT(require_ARB_vp, TEXGEN); } +{dot}q { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); } +{dot}s { return_token_or_DOT(require_ARB_vp, TEXGEN_S); } +{dot}t { return_token_or_DOT(require_ARB_vp, TEXGEN_T); } +{dot}texture { return TEXTURE; } +{dot}transpose { return TRANSPOSE; } +{dot}attrib { return_token_or_DOT(require_ARB_vp, VTXATTRIB); } +{dot}weight { return_token_or_DOT(require_ARB_vp, WEIGHT); } + +texture { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); } +1D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); } +2D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); } +3D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); } +CUBE { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); } +RECT { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); } +SHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); } +SHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); } +SHADOWRECT { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); } +ARRAY1D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); } +ARRAY2D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); } +ARRAYSHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); } +ARRAYSHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); } + +[_a-zA-Z$][_a-zA-Z0-9$]* { + yylval->string = strdup(yytext); + return IDENTIFIER; +} + +".." { return DOT_DOT; } + +{num} { + yylval->integer = strtol(yytext, NULL, 10); + return INTEGER; +} +{num}?{frac}{exp}? { + yylval->real = strtod(yytext, NULL); + return REAL; +} +{num}"."/[^.] { + yylval->real = strtod(yytext, NULL); + return REAL; +} +{num}{exp} { + yylval->real = strtod(yytext, NULL); + return REAL; +} +{num}"."{exp} { + yylval->real = strtod(yytext, NULL); + return REAL; +} + +".xyzw" { + yylval->swiz_mask.swizzle = SWIZZLE_NOOP; + yylval->swiz_mask.mask = WRITEMASK_XYZW; + return MASK4; +} + +".xy"[zw] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XY + | mask_from_char(yytext[3]); + return MASK3; +} +".xzw" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XZW; + return MASK3; +} +".yzw" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_YZW; + return MASK3; +} + +".x"[yzw] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_X + | mask_from_char(yytext[2]); + return MASK2; +} +".y"[zw] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_Y + | mask_from_char(yytext[2]); + return MASK2; +} +".zw" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_ZW; + return MASK2; +} + +"."[xyzw] { + const unsigned s = swiz_from_char(yytext[1]); + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); + yylval->swiz_mask.mask = mask_from_char(yytext[1]); + return MASK1; +} + +"."[xyzw]{4} { + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), + swiz_from_char(yytext[2]), + swiz_from_char(yytext[3]), + swiz_from_char(yytext[4])); + yylval->swiz_mask.mask = 0; + return SWIZZLE; +} + +".rgba" { + yylval->swiz_mask.swizzle = SWIZZLE_NOOP; + yylval->swiz_mask.mask = WRITEMASK_XYZW; + return_token_or_DOT(require_ARB_fp, MASK4); +} + +".rg"[ba] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XY + | mask_from_char(yytext[3]); + return_token_or_DOT(require_ARB_fp, MASK3); +} +".rba" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_XZW; + return_token_or_DOT(require_ARB_fp, MASK3); +} +".gba" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_YZW; + return_token_or_DOT(require_ARB_fp, MASK3); +} + +".r"[gba] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_X + | mask_from_char(yytext[2]); + return_token_or_DOT(require_ARB_fp, MASK2); +} +".g"[ba] { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_Y + | mask_from_char(yytext[2]); + return_token_or_DOT(require_ARB_fp, MASK2); +} +".ba" { + yylval->swiz_mask.swizzle = SWIZZLE_INVAL; + yylval->swiz_mask.mask = WRITEMASK_ZW; + return_token_or_DOT(require_ARB_fp, MASK2); +} + +"."[gba] { + const unsigned s = swiz_from_char(yytext[1]); + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); + yylval->swiz_mask.mask = mask_from_char(yytext[1]); + return_token_or_DOT(require_ARB_fp, MASK1); +} + + +".r" { + if (require_ARB_vp) { + return TEXGEN_R; + } else { + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, + SWIZZLE_X, SWIZZLE_X); + yylval->swiz_mask.mask = WRITEMASK_X; + return MASK1; + } +} + +"."[rgba]{4} { + yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), + swiz_from_char(yytext[2]), + swiz_from_char(yytext[3]), + swiz_from_char(yytext[4])); + yylval->swiz_mask.mask = 0; + return_token_or_DOT(require_ARB_fp, SWIZZLE); +} + +"." { return DOT; } + +\n { + yylloc->first_line++; + yylloc->first_column = 1; + yylloc->last_line++; + yylloc->last_column = 1; + yylloc->position++; +} +[ \t\r]+ /* eat whitespace */ ; +#.*$ /* eat comments */ ; +. { return yytext[0]; } +%% + +void +_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state, + const char *string, size_t len) +{ + yylex_init_extra(state, scanner); + yy_scan_bytes(string, len, *scanner); +} + +void +_mesa_program_lexer_dtor(void *scanner) +{ + yylex_destroy(scanner); +} diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c new file mode 100644 index 0000000000..5c604c2fd1 --- /dev/null +++ b/src/mesa/shader/program_parse.tab.c @@ -0,0 +1,5250 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 1 + + + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 1 "program_parse.y" + +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "main/mtypes.h" +#include "main/imports.h" +#include "program.h" +#include "prog_parameter.h" +#include "prog_parameter_layout.h" +#include "prog_statevars.h" +#include "prog_instruction.h" + +#include "symbol_table.h" +#include "program_parser.h" + +extern void *yy_scan_string(char *); +extern void yy_delete_buffer(void *); + +static struct asm_symbol *declare_variable(struct asm_parser_state *state, + char *name, enum asm_type t, struct YYLTYPE *locp); + +static int add_state_reference(struct gl_program_parameter_list *param_list, + const gl_state_index tokens[STATE_LENGTH]); + +static int initialize_symbol_from_state(struct gl_program *prog, + struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]); + +static int initialize_symbol_from_param(struct gl_program *prog, + struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]); + +static int initialize_symbol_from_const(struct gl_program *prog, + struct asm_symbol *param_var, const struct asm_vector *vec); + +static int yyparse(struct asm_parser_state *state); + +static char *make_error_string(const char *fmt, ...); + +static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state, + const char *s); + +static int validate_inputs(struct YYLTYPE *locp, + struct asm_parser_state *state); + +static void init_dst_reg(struct prog_dst_register *r); + +static void init_src_reg(struct asm_src_register *r); + +static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op, + const struct prog_dst_register *dst, const struct asm_src_register *src0, + const struct asm_src_register *src1, const struct asm_src_register *src2); + +#ifndef FALSE +#define FALSE 0 +#define TRUE (!FALSE) +#endif + +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do { \ + if (YYID(N)) { \ + (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ + (Current).position = YYRHSLOC(Rhs, 1).position; \ + (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ + } else { \ + (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ + (Current).last_line = (Current).first_line; \ + (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \ + (Current).last_column = (Current).first_column; \ + (Current).position = YYRHSLOC(Rhs, 0).position \ + + (Current).first_column; \ + } \ + } while(YYID(0)) + +#define YYLEX_PARAM state->scanner + + +/* Line 189 of yacc.c */ +#line 174 "program_parse.tab.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ARBvp_10 = 258, + ARBfp_10 = 259, + ADDRESS = 260, + ALIAS = 261, + ATTRIB = 262, + OPTION = 263, + OUTPUT = 264, + PARAM = 265, + TEMP = 266, + END = 267, + BIN_OP = 268, + BINSC_OP = 269, + SAMPLE_OP = 270, + SCALAR_OP = 271, + TRI_OP = 272, + VECTOR_OP = 273, + ARL = 274, + KIL = 275, + SWZ = 276, + INTEGER = 277, + REAL = 278, + AMBIENT = 279, + ATTENUATION = 280, + BACK = 281, + CLIP = 282, + COLOR = 283, + DEPTH = 284, + DIFFUSE = 285, + DIRECTION = 286, + EMISSION = 287, + ENV = 288, + EYE = 289, + FOG = 290, + FOGCOORD = 291, + FRAGMENT = 292, + FRONT = 293, + HALF = 294, + INVERSE = 295, + INVTRANS = 296, + LIGHT = 297, + LIGHTMODEL = 298, + LIGHTPROD = 299, + LOCAL = 300, + MATERIAL = 301, + MAT_PROGRAM = 302, + MATRIX = 303, + MATRIXINDEX = 304, + MODELVIEW = 305, + MVP = 306, + NORMAL = 307, + OBJECT = 308, + PALETTE = 309, + PARAMS = 310, + PLANE = 311, + POINT = 312, + POINTSIZE = 313, + POSITION = 314, + PRIMARY = 315, + PROGRAM = 316, + PROJECTION = 317, + RANGE = 318, + RESULT = 319, + ROW = 320, + SCENECOLOR = 321, + SECONDARY = 322, + SHININESS = 323, + SIZE = 324, + SPECULAR = 325, + SPOT = 326, + STATE = 327, + TEXCOORD = 328, + TEXENV = 329, + TEXGEN = 330, + TEXGEN_Q = 331, + TEXGEN_R = 332, + TEXGEN_S = 333, + TEXGEN_T = 334, + TEXTURE = 335, + TRANSPOSE = 336, + TEXTURE_UNIT = 337, + TEX_1D = 338, + TEX_2D = 339, + TEX_3D = 340, + TEX_CUBE = 341, + TEX_RECT = 342, + TEX_SHADOW1D = 343, + TEX_SHADOW2D = 344, + TEX_SHADOWRECT = 345, + TEX_ARRAY1D = 346, + TEX_ARRAY2D = 347, + TEX_ARRAYSHADOW1D = 348, + TEX_ARRAYSHADOW2D = 349, + VERTEX = 350, + VTXATTRIB = 351, + WEIGHT = 352, + IDENTIFIER = 353, + MASK4 = 354, + MASK3 = 355, + MASK2 = 356, + MASK1 = 357, + SWIZZLE = 358, + DOT_DOT = 359, + DOT = 360 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 214 of yacc.c */ +#line 107 "program_parse.y" + + struct asm_instruction *inst; + struct asm_symbol *sym; + struct asm_symbol temp_sym; + struct asm_swizzle_mask swiz_mask; + struct asm_src_register src_reg; + struct prog_dst_register dst_reg; + struct prog_instruction temp_inst; + char *string; + unsigned result; + unsigned attrib; + int integer; + float real; + unsigned state[5]; + int negate; + struct asm_vector vector; + gl_inst_opcode opcode; + + struct { + unsigned swz; + unsigned rgba_valid:1; + unsigned xyzw_valid:1; + unsigned negate:1; + } ext_swizzle; + + + +/* Line 214 of yacc.c */ +#line 343 "program_parse.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + +/* Copy the second part of user declarations. */ + +/* Line 264 of yacc.c */ +#line 249 "program_parse.y" + +extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, + void *yyscanner); + + +/* Line 264 of yacc.c */ +#line 374 "program_parse.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 5 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 340 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 115 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 134 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 264 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 434 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 360 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 110, 107, 111, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 106, + 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 108, 2, 109, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 113, 2, 114, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 8, 10, 12, 15, 16, 20, 23, + 24, 27, 30, 32, 34, 36, 38, 40, 42, 44, + 46, 48, 50, 52, 57, 62, 67, 74, 81, 90, + 99, 102, 105, 107, 109, 111, 113, 115, 117, 119, + 121, 123, 125, 127, 129, 136, 140, 144, 147, 150, + 158, 161, 163, 165, 167, 169, 174, 176, 178, 180, + 182, 184, 186, 188, 192, 193, 196, 199, 201, 203, + 205, 207, 209, 211, 213, 215, 217, 218, 220, 222, + 224, 226, 227, 229, 231, 233, 235, 237, 239, 244, + 247, 250, 252, 255, 257, 260, 262, 265, 270, 275, + 277, 278, 282, 284, 286, 289, 291, 294, 296, 298, + 302, 309, 310, 312, 315, 320, 322, 326, 328, 330, + 332, 334, 336, 338, 340, 342, 344, 346, 349, 352, + 355, 358, 361, 364, 367, 370, 373, 376, 379, 382, + 386, 388, 390, 392, 398, 400, 402, 404, 407, 409, + 411, 414, 416, 419, 426, 428, 432, 434, 436, 438, + 440, 442, 447, 449, 451, 453, 455, 457, 459, 462, + 464, 466, 472, 474, 477, 479, 481, 487, 490, 491, + 498, 502, 503, 505, 507, 509, 511, 513, 516, 518, + 520, 523, 528, 533, 534, 536, 538, 540, 542, 545, + 547, 549, 551, 553, 559, 561, 565, 571, 577, 579, + 583, 589, 591, 593, 595, 597, 599, 601, 603, 605, + 607, 611, 617, 625, 635, 638, 641, 643, 645, 646, + 647, 651, 652, 656, 660, 662, 667, 670, 673, 676, + 679, 683, 686, 690, 691, 693, 695, 696, 698, 700, + 701, 703, 705, 706, 708, 710, 711, 715, 716, 720, + 721, 725, 727, 729, 731 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int16 yyrhs[] = +{ + 116, 0, -1, 117, 118, 120, 12, -1, 3, -1, + 4, -1, 118, 119, -1, -1, 8, 98, 106, -1, + 120, 121, -1, -1, 122, 106, -1, 158, 106, -1, + 123, -1, 124, -1, 125, -1, 126, -1, 127, -1, + 128, -1, 129, -1, 130, -1, 135, -1, 131, -1, + 132, -1, 19, 139, 107, 136, -1, 18, 138, 107, + 137, -1, 16, 138, 107, 136, -1, 14, 138, 107, + 136, 107, 136, -1, 13, 138, 107, 137, 107, 137, + -1, 17, 138, 107, 137, 107, 137, 107, 137, -1, + 15, 138, 107, 137, 107, 133, 107, 134, -1, 20, + 137, -1, 82, 243, -1, 83, -1, 84, -1, 85, + -1, 86, -1, 87, -1, 88, -1, 89, -1, 90, + -1, 91, -1, 92, -1, 93, -1, 94, -1, 21, + 138, 107, 143, 107, 140, -1, 229, 143, 155, -1, + 229, 143, 156, -1, 144, 157, -1, 152, 154, -1, + 141, 107, 141, 107, 141, 107, 141, -1, 229, 142, + -1, 22, -1, 98, -1, 98, -1, 160, -1, 145, + 108, 146, 109, -1, 174, -1, 236, -1, 98, -1, + 98, -1, 147, -1, 148, -1, 22, -1, 152, 153, + 149, -1, -1, 110, 150, -1, 111, 151, -1, 22, + -1, 22, -1, 98, -1, 102, -1, 102, -1, 102, + -1, 102, -1, 99, -1, 103, -1, -1, 99, -1, + 100, -1, 101, -1, 102, -1, -1, 159, -1, 166, + -1, 230, -1, 232, -1, 235, -1, 248, -1, 7, + 98, 112, 160, -1, 95, 161, -1, 37, 165, -1, + 59, -1, 97, 163, -1, 52, -1, 28, 241, -1, + 36, -1, 73, 242, -1, 49, 108, 164, 109, -1, + 96, 108, 162, 109, -1, 22, -1, -1, 108, 164, + 109, -1, 22, -1, 59, -1, 28, 241, -1, 36, + -1, 73, 242, -1, 167, -1, 168, -1, 10, 98, + 170, -1, 10, 98, 108, 169, 109, 171, -1, -1, + 22, -1, 112, 173, -1, 112, 113, 172, 114, -1, + 175, -1, 172, 107, 175, -1, 177, -1, 213, -1, + 223, -1, 177, -1, 213, -1, 224, -1, 176, -1, + 214, -1, 223, -1, 177, -1, 72, 201, -1, 72, + 178, -1, 72, 180, -1, 72, 183, -1, 72, 185, + -1, 72, 191, -1, 72, 187, -1, 72, 194, -1, + 72, 196, -1, 72, 198, -1, 72, 200, -1, 72, + 212, -1, 46, 240, 179, -1, 189, -1, 32, -1, + 68, -1, 42, 108, 190, 109, 181, -1, 189, -1, + 59, -1, 25, -1, 71, 182, -1, 39, -1, 31, + -1, 43, 184, -1, 24, -1, 240, 66, -1, 44, + 108, 190, 109, 240, 186, -1, 189, -1, 74, 244, + 188, -1, 28, -1, 24, -1, 30, -1, 70, -1, + 22, -1, 75, 242, 192, 193, -1, 34, -1, 53, + -1, 78, -1, 79, -1, 77, -1, 76, -1, 35, + 195, -1, 28, -1, 55, -1, 27, 108, 197, 109, + 56, -1, 22, -1, 57, 199, -1, 69, -1, 25, + -1, 203, 65, 108, 206, 109, -1, 203, 202, -1, + -1, 65, 108, 206, 104, 206, 109, -1, 48, 207, + 204, -1, -1, 205, -1, 40, -1, 81, -1, 41, + -1, 22, -1, 50, 208, -1, 62, -1, 51, -1, + 80, 242, -1, 54, 108, 210, 109, -1, 47, 108, + 211, 109, -1, -1, 209, -1, 22, -1, 22, -1, + 22, -1, 29, 63, -1, 217, -1, 220, -1, 215, + -1, 218, -1, 61, 33, 108, 216, 109, -1, 221, + -1, 221, 104, 221, -1, 61, 33, 108, 221, 109, + -1, 61, 45, 108, 219, 109, -1, 222, -1, 222, + 104, 222, -1, 61, 45, 108, 222, 109, -1, 22, + -1, 22, -1, 225, -1, 227, -1, 226, -1, 227, + -1, 228, -1, 23, -1, 22, -1, 113, 228, 114, + -1, 113, 228, 107, 228, 114, -1, 113, 228, 107, + 228, 107, 228, 114, -1, 113, 228, 107, 228, 107, + 228, 107, 228, 114, -1, 229, 23, -1, 229, 22, + -1, 110, -1, 111, -1, -1, -1, 11, 231, 234, + -1, -1, 5, 233, 234, -1, 234, 107, 98, -1, + 98, -1, 9, 98, 112, 236, -1, 64, 59, -1, + 64, 36, -1, 64, 237, -1, 64, 58, -1, 64, + 73, 242, -1, 64, 29, -1, 28, 238, 239, -1, + -1, 38, -1, 26, -1, -1, 60, -1, 67, -1, + -1, 38, -1, 26, -1, -1, 60, -1, 67, -1, + -1, 108, 245, 109, -1, -1, 108, 246, 109, -1, + -1, 108, 247, 109, -1, 22, -1, 22, -1, 22, + -1, 6, 98, 112, 98, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 256, 256, 259, 267, 279, 280, 283, 305, 306, + 309, 324, 327, 332, 339, 340, 341, 342, 343, 344, + 345, 348, 349, 352, 358, 365, 372, 380, 387, 395, + 440, 447, 453, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 467, 480, 493, 506, 528, 537, + 570, 577, 592, 642, 684, 695, 716, 726, 732, 763, + 780, 780, 782, 789, 801, 802, 803, 806, 818, 830, + 848, 859, 871, 873, 874, 875, 876, 879, 879, 879, + 879, 880, 883, 884, 885, 886, 887, 888, 891, 909, + 913, 919, 923, 927, 931, 940, 949, 953, 958, 964, + 975, 975, 976, 978, 982, 986, 990, 996, 996, 998, + 1014, 1037, 1040, 1051, 1057, 1063, 1064, 1071, 1077, 1083, + 1091, 1097, 1103, 1111, 1117, 1123, 1131, 1132, 1135, 1136, + 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1148, + 1157, 1161, 1165, 1171, 1180, 1184, 1188, 1197, 1201, 1207, + 1213, 1220, 1225, 1233, 1243, 1245, 1253, 1259, 1263, 1267, + 1273, 1284, 1293, 1297, 1302, 1306, 1310, 1314, 1320, 1327, + 1331, 1337, 1345, 1356, 1363, 1367, 1373, 1383, 1394, 1398, + 1416, 1425, 1428, 1434, 1438, 1442, 1448, 1459, 1464, 1469, + 1474, 1479, 1484, 1492, 1495, 1500, 1513, 1521, 1532, 1540, + 1540, 1542, 1542, 1544, 1554, 1559, 1566, 1576, 1585, 1590, + 1597, 1607, 1617, 1629, 1629, 1630, 1630, 1632, 1642, 1650, + 1660, 1668, 1676, 1685, 1696, 1700, 1706, 1707, 1708, 1711, + 1711, 1714, 1714, 1717, 1723, 1731, 1744, 1753, 1762, 1766, + 1775, 1784, 1795, 1802, 1807, 1816, 1828, 1831, 1840, 1851, + 1852, 1853, 1856, 1857, 1858, 1861, 1862, 1865, 1866, 1869, + 1870, 1873, 1884, 1895, 1906 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "ARBvp_10", "ARBfp_10", "ADDRESS", + "ALIAS", "ATTRIB", "OPTION", "OUTPUT", "PARAM", "TEMP", "END", "BIN_OP", + "BINSC_OP", "SAMPLE_OP", "SCALAR_OP", "TRI_OP", "VECTOR_OP", "ARL", + "KIL", "SWZ", "INTEGER", "REAL", "AMBIENT", "ATTENUATION", "BACK", + "CLIP", "COLOR", "DEPTH", "DIFFUSE", "DIRECTION", "EMISSION", "ENV", + "EYE", "FOG", "FOGCOORD", "FRAGMENT", "FRONT", "HALF", "INVERSE", + "INVTRANS", "LIGHT", "LIGHTMODEL", "LIGHTPROD", "LOCAL", "MATERIAL", + "MAT_PROGRAM", "MATRIX", "MATRIXINDEX", "MODELVIEW", "MVP", "NORMAL", + "OBJECT", "PALETTE", "PARAMS", "PLANE", "POINT", "POINTSIZE", "POSITION", + "PRIMARY", "PROGRAM", "PROJECTION", "RANGE", "RESULT", "ROW", + "SCENECOLOR", "SECONDARY", "SHININESS", "SIZE", "SPECULAR", "SPOT", + "STATE", "TEXCOORD", "TEXENV", "TEXGEN", "TEXGEN_Q", "TEXGEN_R", + "TEXGEN_S", "TEXGEN_T", "TEXTURE", "TRANSPOSE", "TEXTURE_UNIT", "TEX_1D", + "TEX_2D", "TEX_3D", "TEX_CUBE", "TEX_RECT", "TEX_SHADOW1D", + "TEX_SHADOW2D", "TEX_SHADOWRECT", "TEX_ARRAY1D", "TEX_ARRAY2D", + "TEX_ARRAYSHADOW1D", "TEX_ARRAYSHADOW2D", "VERTEX", "VTXATTRIB", + "WEIGHT", "IDENTIFIER", "MASK4", "MASK3", "MASK2", "MASK1", "SWIZZLE", + "DOT_DOT", "DOT", "';'", "','", "'['", "']'", "'+'", "'-'", "'='", "'{'", + "'}'", "$accept", "program", "language", "optionSequence", "option", + "statementSequence", "statement", "instruction", "ALU_instruction", + "TexInstruction", "ARL_instruction", "VECTORop_instruction", + "SCALARop_instruction", "BINSCop_instruction", "BINop_instruction", + "TRIop_instruction", "SAMPLE_instruction", "KIL_instruction", + "texImageUnit", "texTarget", "SWZ_instruction", "scalarSrcReg", + "swizzleSrcReg", "maskedDstReg", "maskedAddrReg", "extendedSwizzle", + "extSwizComp", "extSwizSel", "srcReg", "dstReg", "progParamArray", + "progParamArrayMem", "progParamArrayAbs", "progParamArrayRel", + "addrRegRelOffset", "addrRegPosOffset", "addrRegNegOffset", "addrReg", + "addrComponent", "addrWriteMask", "scalarSuffix", "swizzleSuffix", + "optionalMask", "namingStatement", "ATTRIB_statement", "attribBinding", + "vtxAttribItem", "vtxAttribNum", "vtxOptWeightNum", "vtxWeightNum", + "fragAttribItem", "PARAM_statement", "PARAM_singleStmt", + "PARAM_multipleStmt", "optArraySize", "paramSingleInit", + "paramMultipleInit", "paramMultInitList", "paramSingleItemDecl", + "paramSingleItemUse", "paramMultipleItem", "stateMultipleItem", + "stateSingleItem", "stateMaterialItem", "stateMatProperty", + "stateLightItem", "stateLightProperty", "stateSpotProperty", + "stateLightModelItem", "stateLModProperty", "stateLightProdItem", + "stateLProdProperty", "stateTexEnvItem", "stateTexEnvProperty", + "ambDiffSpecProperty", "stateLightNumber", "stateTexGenItem", + "stateTexGenType", "stateTexGenCoord", "stateFogItem", + "stateFogProperty", "stateClipPlaneItem", "stateClipPlaneNum", + "statePointItem", "statePointProperty", "stateMatrixRow", + "stateMatrixRows", "optMatrixRows", "stateMatrixItem", + "stateOptMatModifier", "stateMatModifier", "stateMatrixRowNum", + "stateMatrixName", "stateOptModMatNum", "stateModMatNum", + "statePaletteMatNum", "stateProgramMatNum", "stateDepthItem", + "programSingleItem", "programMultipleItem", "progEnvParams", + "progEnvParamNums", "progEnvParam", "progLocalParams", + "progLocalParamNums", "progLocalParam", "progEnvParamNum", + "progLocalParamNum", "paramConstDecl", "paramConstUse", + "paramConstScalarDecl", "paramConstScalarUse", "paramConstVector", + "signedFloatConstant", "optionalSign", "TEMP_statement", "@1", + "ADDRESS_statement", "@2", "varNameList", "OUTPUT_statement", + "resultBinding", "resultColBinding", "optResultFaceType", + "optResultColorType", "optFaceType", "optColorType", + "optTexCoordUnitNum", "optTexImageUnitNum", "optLegacyTexUnitNum", + "texCoordUnitNum", "texImageUnitNum", "legacyTexUnitNum", + "ALIAS_statement", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 59, 44, 91, 93, + 43, 45, 61, 123, 125 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 115, 116, 117, 117, 118, 118, 119, 120, 120, + 121, 121, 122, 122, 123, 123, 123, 123, 123, 123, + 123, 124, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 142, 143, 143, 143, 143, 144, 144, 145, + 146, 146, 147, 148, 149, 149, 149, 150, 151, 152, + 153, 154, 155, 156, 156, 156, 156, 157, 157, 157, + 157, 157, 158, 158, 158, 158, 158, 158, 159, 160, + 160, 161, 161, 161, 161, 161, 161, 161, 161, 162, + 163, 163, 164, 165, 165, 165, 165, 166, 166, 167, + 168, 169, 169, 170, 171, 172, 172, 173, 173, 173, + 174, 174, 174, 175, 175, 175, 176, 176, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 178, + 179, 179, 179, 180, 181, 181, 181, 181, 181, 182, + 183, 184, 184, 185, 186, 187, 188, 189, 189, 189, + 190, 191, 192, 192, 193, 193, 193, 193, 194, 195, + 195, 196, 197, 198, 199, 199, 200, 201, 202, 202, + 203, 204, 204, 205, 205, 205, 206, 207, 207, 207, + 207, 207, 207, 208, 208, 209, 210, 211, 212, 213, + 213, 214, 214, 215, 216, 216, 217, 218, 219, 219, + 220, 221, 222, 223, 223, 224, 224, 225, 226, 226, + 227, 227, 227, 227, 228, 228, 229, 229, 229, 231, + 230, 233, 232, 234, 234, 235, 236, 236, 236, 236, + 236, 236, 237, 238, 238, 238, 239, 239, 239, 240, + 240, 240, 241, 241, 241, 242, 242, 243, 243, 244, + 244, 245, 246, 247, 248 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 4, 1, 1, 2, 0, 3, 2, 0, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 4, 4, 4, 6, 6, 8, 8, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 6, 3, 3, 2, 2, 7, + 2, 1, 1, 1, 1, 4, 1, 1, 1, 1, + 1, 1, 1, 3, 0, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 4, 2, + 2, 1, 2, 1, 2, 1, 2, 4, 4, 1, + 0, 3, 1, 1, 2, 1, 2, 1, 1, 3, + 6, 0, 1, 2, 4, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, + 1, 1, 1, 5, 1, 1, 1, 2, 1, 1, + 2, 1, 2, 6, 1, 3, 1, 1, 1, 1, + 1, 4, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 5, 1, 2, 1, 1, 5, 2, 0, 6, + 3, 0, 1, 1, 1, 1, 1, 2, 1, 1, + 2, 4, 4, 0, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 5, 1, 3, 5, 5, 1, 3, + 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 5, 7, 9, 2, 2, 1, 1, 0, 0, + 3, 0, 3, 3, 1, 4, 2, 2, 2, 2, + 3, 2, 3, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 0, 3, 0, 3, 0, + 3, 1, 1, 1, 4 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 0, 3, 4, 0, 6, 1, 9, 0, 5, 0, + 0, 231, 0, 0, 0, 0, 229, 2, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 8, 0, 12, + 13, 14, 15, 16, 17, 18, 19, 21, 22, 20, + 0, 82, 83, 107, 108, 84, 85, 86, 87, 7, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 81, + 57, 0, 0, 0, 0, 0, 69, 0, 0, 226, + 227, 30, 0, 0, 10, 11, 234, 232, 0, 0, + 0, 111, 228, 109, 230, 243, 241, 237, 239, 236, + 255, 238, 228, 77, 78, 79, 80, 47, 228, 228, + 228, 228, 228, 228, 71, 48, 219, 218, 0, 0, + 0, 0, 53, 228, 76, 0, 54, 56, 120, 121, + 199, 200, 122, 215, 216, 0, 0, 264, 88, 235, + 112, 0, 113, 117, 118, 119, 213, 214, 217, 0, + 245, 244, 246, 0, 240, 0, 0, 0, 0, 25, + 0, 24, 23, 252, 105, 103, 255, 90, 0, 0, + 0, 0, 0, 0, 249, 0, 249, 0, 0, 259, + 255, 128, 129, 130, 131, 133, 132, 134, 135, 136, + 137, 0, 138, 252, 95, 0, 93, 91, 255, 0, + 100, 89, 0, 74, 73, 75, 46, 0, 0, 233, + 0, 225, 224, 247, 248, 242, 261, 0, 228, 228, + 0, 0, 228, 253, 254, 104, 106, 0, 0, 0, + 198, 169, 170, 168, 0, 151, 251, 250, 150, 0, + 0, 0, 0, 193, 189, 0, 188, 255, 181, 175, + 174, 173, 0, 0, 0, 0, 94, 0, 96, 0, + 0, 92, 228, 220, 62, 0, 60, 61, 0, 228, + 0, 110, 256, 27, 26, 72, 45, 257, 0, 0, + 211, 0, 212, 0, 172, 0, 160, 0, 152, 0, + 157, 158, 141, 142, 159, 139, 140, 0, 195, 187, + 194, 0, 190, 183, 185, 184, 180, 182, 263, 0, + 156, 155, 162, 163, 0, 0, 102, 0, 99, 0, + 0, 0, 55, 70, 64, 44, 0, 0, 228, 0, + 31, 0, 228, 206, 210, 0, 0, 249, 197, 0, + 196, 0, 260, 167, 166, 164, 165, 161, 186, 0, + 97, 98, 101, 228, 221, 0, 0, 63, 228, 51, + 52, 50, 0, 0, 0, 115, 123, 126, 124, 201, + 202, 125, 262, 0, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 29, 28, 171, 146, + 148, 145, 0, 143, 144, 0, 192, 191, 176, 0, + 67, 65, 68, 66, 0, 0, 0, 127, 178, 228, + 114, 258, 149, 147, 153, 154, 228, 222, 228, 0, + 0, 0, 177, 116, 0, 0, 0, 204, 0, 208, + 0, 223, 228, 203, 0, 207, 0, 0, 49, 205, + 209, 0, 0, 179 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 3, 4, 6, 8, 9, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 268, 376, + 39, 146, 71, 58, 67, 315, 316, 351, 114, 59, + 115, 255, 256, 257, 347, 391, 393, 68, 314, 105, + 266, 196, 97, 40, 41, 116, 191, 309, 251, 307, + 157, 42, 43, 44, 131, 83, 261, 354, 132, 117, + 355, 356, 118, 171, 285, 172, 383, 403, 173, 228, + 174, 404, 175, 301, 286, 277, 176, 304, 337, 177, + 223, 178, 275, 179, 241, 180, 397, 412, 181, 296, + 297, 339, 238, 289, 290, 331, 329, 182, 119, 358, + 359, 416, 120, 360, 418, 121, 271, 273, 361, 122, + 136, 123, 124, 138, 72, 45, 55, 46, 50, 77, + 47, 60, 91, 142, 205, 229, 215, 144, 320, 243, + 207, 363, 299, 48 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -334 +static const yytype_int16 yypact[] = +{ + 134, -334, -334, 41, -334, -334, 47, -49, -334, 169, + 20, -334, 34, 61, 75, 115, -334, -334, -19, -19, + -19, -19, -19, -19, 116, 44, -19, -334, 109, -334, + -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, + 110, -334, -334, -334, -334, -334, -334, -334, -334, -334, + 119, 106, 107, 111, -22, 119, 4, -334, 5, 104, + -334, 113, 114, 117, 118, 120, -334, 121, 124, -334, + -334, -334, -15, 122, -334, -334, -334, 123, 133, -14, + 158, 210, -11, -334, 123, 21, -334, -334, -334, -334, + 127, -334, 44, -334, -334, -334, -334, -334, 44, 44, + 44, 44, 44, 44, -334, -334, -334, -334, 1, 68, + 87, -1, 132, 44, 65, 135, -334, -334, -334, -334, + -334, -334, -334, -334, -334, -15, 141, -334, -334, -334, + -334, 136, -334, -334, -334, -334, -334, -334, -334, 149, + -334, -334, 58, 219, -334, 137, 139, -15, 140, -334, + 142, -334, -334, 74, -334, -334, 127, -334, 143, 144, + 145, 179, 15, 146, 81, 147, 83, 89, 0, 148, + 127, -334, -334, -334, -334, -334, -334, -334, -334, -334, + -334, 183, -334, 74, -334, 150, -334, -334, 127, 151, + 152, -334, 43, -334, -334, -334, -334, -10, 155, -334, + 138, -334, -334, -334, -334, -334, -334, 154, 44, 44, + 162, 175, 44, -334, -334, -334, -334, 243, 245, 246, + -334, -334, -334, -334, 247, -334, -334, -334, -334, 204, + 247, -4, 163, 250, -334, 165, -334, 127, 27, -334, + -334, -334, 252, 248, 18, 167, -334, 255, -334, 256, + 255, -334, 44, -334, -334, 170, -334, -334, 178, 44, + 168, -334, -334, -334, -334, -334, -334, 174, 176, 177, + -334, 180, -334, 181, -334, 182, -334, 184, -334, 185, + -334, -334, -334, -334, -334, -334, -334, 263, -334, -334, + -334, 264, -334, -334, -334, -334, -334, -334, -334, 186, + -334, -334, -334, -334, 131, 265, -334, 188, -334, 189, + 190, 46, -334, -334, 101, -334, 193, -5, -7, 266, + -334, 108, 44, -334, -334, 236, 14, 83, -334, 192, + -334, 194, -334, -334, -334, -334, -334, -334, -334, 195, + -334, -334, -334, 44, -334, 280, 283, -334, 44, -334, + -334, -334, 78, 87, 49, -334, -334, -334, -334, -334, + -334, -334, -334, 197, -334, -334, -334, -334, -334, -334, + -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, + -334, -334, 276, -334, -334, 6, -334, -334, -334, 51, + -334, -334, -334, -334, 201, 202, 203, -334, 244, -7, + -334, -334, -334, -334, -334, -334, 44, -334, 44, 243, + 245, 205, -334, -334, 198, 207, 206, 212, 211, 217, + 265, -334, 44, -334, 243, -334, 245, -17, -334, -334, + -334, 265, 213, -334 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, + -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, + -334, -94, -88, 126, -334, -334, -333, -334, -91, -334, + -334, -334, -334, -334, -334, -334, -334, 128, -334, -334, + -334, -334, -334, -334, -334, 249, -334, -334, -334, 73, + -334, -334, -334, -334, -334, -334, -334, -334, -334, -334, + -72, -334, -81, -334, -334, -334, -334, -334, -334, -334, + -334, -334, -334, -334, -307, 99, -334, -334, -334, -334, + -334, -334, -334, -334, -334, -334, -334, -334, -23, -334, + -334, -303, -334, -334, -334, -334, -334, -334, 251, -334, + -334, -334, -334, -334, -334, -334, -327, -316, 253, -334, + -334, -334, -80, -110, -82, -334, -334, -334, -334, 277, + -334, 254, -334, -334, -334, -161, 153, -146, -334, -334, + -334, -334, -334, -334 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -60 +static const yytype_int16 yytable[] = +{ + 139, 133, 137, 192, 145, 231, 149, 106, 107, 152, + 216, 148, 254, 150, 151, 394, 147, 349, 147, 384, + 280, 147, 108, 108, 244, 239, 281, 183, 282, 153, + 280, 139, 85, 86, 198, 184, 281, 154, 280, 379, + 87, 5, 248, 221, 281, 56, 109, 140, 185, 10, + 109, 186, 302, 380, 352, 7, 210, 110, 187, 141, + 155, 110, 88, 89, 283, 353, 284, 293, 294, 240, + 222, 303, 188, 381, 156, 415, 284, 90, 405, 57, + 111, 111, 417, 112, 284, 382, 81, 431, 66, 428, + 82, 292, 388, 350, 419, 189, 190, 429, 113, 69, + 70, 158, 113, 69, 70, 225, 113, 226, 295, 226, + 430, 395, 92, 159, 160, 264, 161, 427, 203, 227, + 263, 227, 162, 396, 269, 204, 49, 147, 432, 163, + 164, 165, 51, 166, 213, 167, 232, 1, 2, 233, + 234, 214, 311, 235, 168, 61, 62, 63, 64, 65, + 252, 236, 73, 343, 69, 70, 399, 253, 406, 52, + 344, 169, 170, 400, 193, 407, 385, 194, 195, 237, + 139, 201, 202, 53, 11, 12, 13, 317, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 93, 94, 95, 96, 333, 334, 335, + 336, 345, 346, 54, 66, 74, 75, 76, 78, 79, + 98, 99, 56, 80, 100, 101, 104, 102, 103, 125, + 126, 127, 130, 389, 377, 143, 139, 357, 137, 199, + -59, 206, 220, 197, 208, 200, 209, 211, 245, 212, + 260, 217, 218, 219, 224, 230, 242, 267, 247, 249, + 250, 139, 259, 262, 265, 270, 317, 272, 274, 276, + 278, 287, 288, 291, 298, 305, 300, 306, 308, 312, + 313, 318, 319, 321, 322, 328, 330, 338, 362, 323, + 324, 325, 378, 326, 327, 332, 414, 340, 341, 342, + 348, 386, 390, 387, 388, 392, 401, 402, 408, 411, + 409, 410, 421, 420, 422, 423, 424, 139, 357, 137, + 425, 426, 433, 310, 139, 258, 317, 413, 128, 279, + 398, 0, 84, 134, 129, 135, 246, 0, 0, 0, + 317 +}; + +static const yytype_int16 yycheck[] = +{ + 82, 82, 82, 113, 92, 166, 100, 22, 23, 103, + 156, 99, 22, 101, 102, 348, 98, 22, 100, 326, + 24, 103, 37, 37, 170, 25, 30, 28, 32, 28, + 24, 113, 28, 29, 125, 36, 30, 36, 24, 25, + 36, 0, 188, 28, 30, 64, 61, 26, 49, 98, + 61, 52, 34, 39, 61, 8, 147, 72, 59, 38, + 59, 72, 58, 59, 68, 72, 70, 40, 41, 69, + 55, 53, 73, 59, 73, 408, 70, 73, 385, 98, + 95, 95, 409, 98, 70, 71, 108, 104, 98, 422, + 112, 237, 109, 98, 410, 96, 97, 424, 113, 110, + 111, 33, 113, 110, 111, 24, 113, 26, 81, 26, + 426, 33, 107, 45, 27, 209, 29, 420, 60, 38, + 208, 38, 35, 45, 212, 67, 106, 209, 431, 42, + 43, 44, 98, 46, 60, 48, 47, 3, 4, 50, + 51, 67, 252, 54, 57, 19, 20, 21, 22, 23, + 107, 62, 26, 107, 110, 111, 107, 114, 107, 98, + 114, 74, 75, 114, 99, 114, 327, 102, 103, 80, + 252, 22, 23, 98, 5, 6, 7, 259, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 99, 100, 101, 102, 76, 77, 78, + 79, 110, 111, 98, 98, 106, 106, 98, 112, 112, + 107, 107, 64, 112, 107, 107, 102, 107, 107, 107, + 107, 98, 22, 343, 322, 108, 318, 318, 318, 98, + 108, 22, 63, 108, 107, 109, 107, 107, 65, 107, + 112, 108, 108, 108, 108, 108, 108, 82, 108, 108, + 108, 343, 107, 109, 102, 22, 348, 22, 22, 22, + 66, 108, 22, 108, 22, 108, 28, 22, 22, 109, + 102, 113, 108, 107, 107, 22, 22, 22, 22, 109, + 109, 109, 56, 109, 109, 109, 406, 109, 109, 109, + 107, 109, 22, 109, 109, 22, 109, 31, 107, 65, + 108, 108, 114, 108, 107, 109, 104, 399, 399, 399, + 109, 104, 109, 250, 406, 197, 408, 399, 79, 230, + 353, -1, 55, 82, 80, 82, 183, -1, -1, -1, + 422 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 4, 116, 117, 0, 118, 8, 119, 120, + 98, 5, 6, 7, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 135, + 158, 159, 166, 167, 168, 230, 232, 235, 248, 106, + 233, 98, 98, 98, 98, 231, 64, 98, 138, 144, + 236, 138, 138, 138, 138, 138, 98, 139, 152, 110, + 111, 137, 229, 138, 106, 106, 98, 234, 112, 112, + 112, 108, 112, 170, 234, 28, 29, 36, 58, 59, + 73, 237, 107, 99, 100, 101, 102, 157, 107, 107, + 107, 107, 107, 107, 102, 154, 22, 23, 37, 61, + 72, 95, 98, 113, 143, 145, 160, 174, 177, 213, + 217, 220, 224, 226, 227, 107, 107, 98, 160, 236, + 22, 169, 173, 177, 213, 223, 225, 227, 228, 229, + 26, 38, 238, 108, 242, 137, 136, 229, 137, 136, + 137, 137, 136, 28, 36, 59, 73, 165, 33, 45, + 27, 29, 35, 42, 43, 44, 46, 48, 57, 74, + 75, 178, 180, 183, 185, 187, 191, 194, 196, 198, + 200, 203, 212, 28, 36, 49, 52, 59, 73, 96, + 97, 161, 228, 99, 102, 103, 156, 108, 143, 98, + 109, 22, 23, 60, 67, 239, 22, 245, 107, 107, + 143, 107, 107, 60, 67, 241, 242, 108, 108, 108, + 63, 28, 55, 195, 108, 24, 26, 38, 184, 240, + 108, 240, 47, 50, 51, 54, 62, 80, 207, 25, + 69, 199, 108, 244, 242, 65, 241, 108, 242, 108, + 108, 163, 107, 114, 22, 146, 147, 148, 152, 107, + 112, 171, 109, 137, 136, 102, 155, 82, 133, 137, + 22, 221, 22, 222, 22, 197, 22, 190, 66, 190, + 24, 30, 32, 68, 70, 179, 189, 108, 22, 208, + 209, 108, 242, 40, 41, 81, 204, 205, 22, 247, + 28, 188, 34, 53, 192, 108, 22, 164, 22, 162, + 164, 228, 109, 102, 153, 140, 141, 229, 113, 108, + 243, 107, 107, 109, 109, 109, 109, 109, 22, 211, + 22, 210, 109, 76, 77, 78, 79, 193, 22, 206, + 109, 109, 109, 107, 114, 110, 111, 149, 107, 22, + 98, 142, 61, 72, 172, 175, 176, 177, 214, 215, + 218, 223, 22, 246, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 134, 137, 56, 25, + 39, 59, 71, 181, 189, 240, 109, 109, 109, 228, + 22, 150, 22, 151, 141, 33, 45, 201, 203, 107, + 114, 109, 31, 182, 186, 189, 107, 114, 107, 108, + 108, 65, 202, 175, 228, 141, 216, 221, 219, 222, + 108, 114, 107, 109, 104, 109, 104, 206, 141, 221, + 222, 104, 206, 109 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, &yylloc, scanner) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, Location, state); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + struct asm_parser_state *state; +#endif +{ + if (!yyvaluep) + return; + YYUSE (yylocationp); + YYUSE (state); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + struct asm_parser_state *state; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct asm_parser_state *state) +#else +static void +yy_reduce_print (yyvsp, yylsp, yyrule, state) + YYSTYPE *yyvsp; + YYLTYPE *yylsp; + int yyrule; + struct asm_parser_state *state; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , &(yylsp[(yyi + 1) - (yynrhs)]) , state); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, yylsp, Rule, state); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct asm_parser_state *state) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, yylocationp, state) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + YYLTYPE *yylocationp; + struct asm_parser_state *state; +#endif +{ + YYUSE (yyvaluep); + YYUSE (yylocationp); + YYUSE (state); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (struct asm_parser_state *state); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (struct asm_parser_state *state) +#else +int +yyparse (state) + struct asm_parser_state *state; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Location data for the lookahead symbol. */ +YYLTYPE yylloc; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2]; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + YYLTYPE yyloc; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + yylsp = yyls; + +#if YYLTYPE_IS_TRIVIAL + /* Initialize the default location before parsing starts. */ + yylloc.first_line = yylloc.last_line = 1; + yylloc.first_column = yylloc.last_column = 1; +#endif + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + + yyls = yyls1; + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + *++yylsp = yylloc; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: + +/* Line 1455 of yacc.c */ +#line 260 "program_parse.y" + { + if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid fragment program header"); + + } + state->mode = ARB_vertex; + ;} + break; + + case 4: + +/* Line 1455 of yacc.c */ +#line 268 "program_parse.y" + { + if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex program header"); + } + state->mode = ARB_fragment; + + state->option.TexRect = + (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE); + ;} + break; + + case 7: + +/* Line 1455 of yacc.c */ +#line 284 "program_parse.y" + { + int valid = 0; + + if (state->mode == ARB_vertex) { + valid = _mesa_ARBvp_parse_option(state, (yyvsp[(2) - (3)].string)); + } else if (state->mode == ARB_fragment) { + valid = _mesa_ARBfp_parse_option(state, (yyvsp[(2) - (3)].string)); + } + + + if (!valid) { + const char *const err_str = (state->mode == ARB_vertex) + ? "invalid ARB vertex program option" + : "invalid ARB fragment program option"; + + yyerror(& (yylsp[(2) - (3)]), state, err_str); + YYERROR; + } + ;} + break; + + case 10: + +/* Line 1455 of yacc.c */ +#line 310 "program_parse.y" + { + if ((yyvsp[(1) - (2)].inst) != NULL) { + if (state->inst_tail == NULL) { + state->inst_head = (yyvsp[(1) - (2)].inst); + } else { + state->inst_tail->next = (yyvsp[(1) - (2)].inst); + } + + state->inst_tail = (yyvsp[(1) - (2)].inst); + (yyvsp[(1) - (2)].inst)->next = NULL; + + state->prog->NumInstructions++; + } + ;} + break; + + case 12: + +/* Line 1455 of yacc.c */ +#line 328 "program_parse.y" + { + (yyval.inst) = (yyvsp[(1) - (1)].inst); + state->prog->NumAluInstructions++; + ;} + break; + + case 13: + +/* Line 1455 of yacc.c */ +#line 333 "program_parse.y" + { + (yyval.inst) = (yyvsp[(1) - (1)].inst); + state->prog->NumTexInstructions++; + ;} + break; + + case 23: + +/* Line 1455 of yacc.c */ +#line 353 "program_parse.y" + { + (yyval.inst) = asm_instruction_ctor(OPCODE_ARL, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL); + ;} + break; + + case 24: + +/* Line 1455 of yacc.c */ +#line 359 "program_parse.y" + { + (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (4)].temp_inst).Opcode, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL); + (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (4)].temp_inst).SaturateMode; + ;} + break; + + case 25: + +/* Line 1455 of yacc.c */ +#line 366 "program_parse.y" + { + (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (4)].temp_inst).Opcode, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL); + (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (4)].temp_inst).SaturateMode; + ;} + break; + + case 26: + +/* Line 1455 of yacc.c */ +#line 373 "program_parse.y" + { + (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (6)].temp_inst).Opcode, & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL); + (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (6)].temp_inst).SaturateMode; + ;} + break; + + case 27: + +/* Line 1455 of yacc.c */ +#line 381 "program_parse.y" + { + (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (6)].temp_inst).Opcode, & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL); + (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (6)].temp_inst).SaturateMode; + ;} + break; + + case 28: + +/* Line 1455 of yacc.c */ +#line 389 "program_parse.y" + { + (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (8)].temp_inst).Opcode, & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), & (yyvsp[(6) - (8)].src_reg), & (yyvsp[(8) - (8)].src_reg)); + (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (8)].temp_inst).SaturateMode; + ;} + break; + + case 29: + +/* Line 1455 of yacc.c */ +#line 396 "program_parse.y" + { + (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (8)].temp_inst).Opcode, & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), NULL, NULL); + if ((yyval.inst) != NULL) { + const GLbitfield tex_mask = (1U << (yyvsp[(6) - (8)].integer)); + GLbitfield shadow_tex = 0; + GLbitfield target_mask = 0; + + + (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (8)].temp_inst).SaturateMode; + (yyval.inst)->Base.TexSrcUnit = (yyvsp[(6) - (8)].integer); + + if ((yyvsp[(8) - (8)].integer) < 0) { + shadow_tex = tex_mask; + + (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(8) - (8)].integer); + (yyval.inst)->Base.TexShadow = 1; + } else { + (yyval.inst)->Base.TexSrcTarget = (yyvsp[(8) - (8)].integer); + } + + target_mask = (1U << (yyval.inst)->Base.TexSrcTarget); + + /* If this texture unit was previously accessed and that access + * had a different texture target, generate an error. + * + * If this texture unit was previously accessed and that access + * had a different shadow mode, generate an error. + */ + if ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != 0) + && ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != target_mask) + || ((state->prog->ShadowSamplers & tex_mask) + != shadow_tex))) { + yyerror(& (yylsp[(8) - (8)]), state, + "multiple targets used on one texture image unit"); + YYERROR; + } + + + state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] |= target_mask; + state->prog->ShadowSamplers |= shadow_tex; + } + ;} + break; + + case 30: + +/* Line 1455 of yacc.c */ +#line 441 "program_parse.y" + { + (yyval.inst) = asm_instruction_ctor(OPCODE_KIL, NULL, & (yyvsp[(2) - (2)].src_reg), NULL, NULL); + state->fragment.UsesKill = 1; + ;} + break; + + case 31: + +/* Line 1455 of yacc.c */ +#line 448 "program_parse.y" + { + (yyval.integer) = (yyvsp[(2) - (2)].integer); + ;} + break; + + case 32: + +/* Line 1455 of yacc.c */ +#line 453 "program_parse.y" + { (yyval.integer) = TEXTURE_1D_INDEX; ;} + break; + + case 33: + +/* Line 1455 of yacc.c */ +#line 454 "program_parse.y" + { (yyval.integer) = TEXTURE_2D_INDEX; ;} + break; + + case 34: + +/* Line 1455 of yacc.c */ +#line 455 "program_parse.y" + { (yyval.integer) = TEXTURE_3D_INDEX; ;} + break; + + case 35: + +/* Line 1455 of yacc.c */ +#line 456 "program_parse.y" + { (yyval.integer) = TEXTURE_CUBE_INDEX; ;} + break; + + case 36: + +/* Line 1455 of yacc.c */ +#line 457 "program_parse.y" + { (yyval.integer) = TEXTURE_RECT_INDEX; ;} + break; + + case 37: + +/* Line 1455 of yacc.c */ +#line 458 "program_parse.y" + { (yyval.integer) = -TEXTURE_1D_INDEX; ;} + break; + + case 38: + +/* Line 1455 of yacc.c */ +#line 459 "program_parse.y" + { (yyval.integer) = -TEXTURE_2D_INDEX; ;} + break; + + case 39: + +/* Line 1455 of yacc.c */ +#line 460 "program_parse.y" + { (yyval.integer) = -TEXTURE_RECT_INDEX; ;} + break; + + case 40: + +/* Line 1455 of yacc.c */ +#line 461 "program_parse.y" + { (yyval.integer) = TEXTURE_1D_ARRAY_INDEX; ;} + break; + + case 41: + +/* Line 1455 of yacc.c */ +#line 462 "program_parse.y" + { (yyval.integer) = TEXTURE_2D_ARRAY_INDEX; ;} + break; + + case 42: + +/* Line 1455 of yacc.c */ +#line 463 "program_parse.y" + { (yyval.integer) = -TEXTURE_1D_ARRAY_INDEX; ;} + break; + + case 43: + +/* Line 1455 of yacc.c */ +#line 464 "program_parse.y" + { (yyval.integer) = -TEXTURE_2D_ARRAY_INDEX; ;} + break; + + case 44: + +/* Line 1455 of yacc.c */ +#line 468 "program_parse.y" + { + /* FIXME: Is this correct? Should the extenedSwizzle be applied + * FIXME: to the existing swizzle? + */ + (yyvsp[(4) - (6)].src_reg).Base.Swizzle = (yyvsp[(6) - (6)].swiz_mask).swizzle; + (yyvsp[(4) - (6)].src_reg).Base.Negate = (yyvsp[(6) - (6)].swiz_mask).mask; + + (yyval.inst) = asm_instruction_ctor(OPCODE_SWZ, & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), NULL, NULL); + (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (6)].temp_inst).SaturateMode; + ;} + break; + + case 45: + +/* Line 1455 of yacc.c */ +#line 481 "program_parse.y" + { + (yyval.src_reg) = (yyvsp[(2) - (3)].src_reg); + + if ((yyvsp[(1) - (3)].negate)) { + (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate; + } + + (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle, + (yyvsp[(3) - (3)].swiz_mask).swizzle); + ;} + break; + + case 46: + +/* Line 1455 of yacc.c */ +#line 494 "program_parse.y" + { + (yyval.src_reg) = (yyvsp[(2) - (3)].src_reg); + + if ((yyvsp[(1) - (3)].negate)) { + (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate; + } + + (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle, + (yyvsp[(3) - (3)].swiz_mask).swizzle); + ;} + break; + + case 47: + +/* Line 1455 of yacc.c */ +#line 507 "program_parse.y" + { + (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg); + (yyval.dst_reg).WriteMask = (yyvsp[(2) - (2)].swiz_mask).mask; + + if ((yyval.dst_reg).File == PROGRAM_OUTPUT) { + /* Technically speaking, this should check that it is in + * vertex program mode. However, PositionInvariant can never be + * set in fragment program mode, so it is somewhat irrelevant. + */ + if (state->option.PositionInvariant + && ((yyval.dst_reg).Index == VERT_RESULT_HPOS)) { + yyerror(& (yylsp[(1) - (2)]), state, "position-invariant programs cannot " + "write position"); + YYERROR; + } + + state->prog->OutputsWritten |= (1U << (yyval.dst_reg).Index); + } + ;} + break; + + case 48: + +/* Line 1455 of yacc.c */ +#line 529 "program_parse.y" + { + init_dst_reg(& (yyval.dst_reg)); + (yyval.dst_reg).File = PROGRAM_ADDRESS; + (yyval.dst_reg).Index = 0; + (yyval.dst_reg).WriteMask = (yyvsp[(2) - (2)].swiz_mask).mask; + ;} + break; + + case 49: + +/* Line 1455 of yacc.c */ +#line 538 "program_parse.y" + { + const unsigned xyzw_valid = + ((yyvsp[(1) - (7)].ext_swizzle).xyzw_valid << 0) + | ((yyvsp[(3) - (7)].ext_swizzle).xyzw_valid << 1) + | ((yyvsp[(5) - (7)].ext_swizzle).xyzw_valid << 2) + | ((yyvsp[(7) - (7)].ext_swizzle).xyzw_valid << 3); + const unsigned rgba_valid = + ((yyvsp[(1) - (7)].ext_swizzle).rgba_valid << 0) + | ((yyvsp[(3) - (7)].ext_swizzle).rgba_valid << 1) + | ((yyvsp[(5) - (7)].ext_swizzle).rgba_valid << 2) + | ((yyvsp[(7) - (7)].ext_swizzle).rgba_valid << 3); + + /* All of the swizzle components have to be valid in either RGBA + * or XYZW. Note that 0 and 1 are valid in both, so both masks + * can have some bits set. + * + * We somewhat deviate from the spec here. It would be really hard + * to figure out which component is the error, and there probably + * isn't a lot of benefit. + */ + if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) { + yyerror(& (yylsp[(1) - (7)]), state, "cannot combine RGBA and XYZW swizzle " + "components"); + YYERROR; + } + + (yyval.swiz_mask).swizzle = MAKE_SWIZZLE4((yyvsp[(1) - (7)].ext_swizzle).swz, (yyvsp[(3) - (7)].ext_swizzle).swz, (yyvsp[(5) - (7)].ext_swizzle).swz, (yyvsp[(7) - (7)].ext_swizzle).swz); + (yyval.swiz_mask).mask = ((yyvsp[(1) - (7)].ext_swizzle).negate) | ((yyvsp[(3) - (7)].ext_swizzle).negate << 1) | ((yyvsp[(5) - (7)].ext_swizzle).negate << 2) + | ((yyvsp[(7) - (7)].ext_swizzle).negate << 3); + ;} + break; + + case 50: + +/* Line 1455 of yacc.c */ +#line 571 "program_parse.y" + { + (yyval.ext_swizzle) = (yyvsp[(2) - (2)].ext_swizzle); + (yyval.ext_swizzle).negate = ((yyvsp[(1) - (2)].negate)) ? 1 : 0; + ;} + break; + + case 51: + +/* Line 1455 of yacc.c */ +#line 578 "program_parse.y" + { + if (((yyvsp[(1) - (1)].integer) != 0) && ((yyvsp[(1) - (1)].integer) != 1)) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector"); + YYERROR; + } + + (yyval.ext_swizzle).swz = ((yyvsp[(1) - (1)].integer) == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE; + + /* 0 and 1 are valid for both RGBA swizzle names and XYZW + * swizzle names. + */ + (yyval.ext_swizzle).xyzw_valid = 1; + (yyval.ext_swizzle).rgba_valid = 1; + ;} + break; + + case 52: + +/* Line 1455 of yacc.c */ +#line 593 "program_parse.y" + { + if (strlen((yyvsp[(1) - (1)].string)) > 1) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector"); + YYERROR; + } + + switch ((yyvsp[(1) - (1)].string)[0]) { + case 'x': + (yyval.ext_swizzle).swz = SWIZZLE_X; + (yyval.ext_swizzle).xyzw_valid = 1; + break; + case 'y': + (yyval.ext_swizzle).swz = SWIZZLE_Y; + (yyval.ext_swizzle).xyzw_valid = 1; + break; + case 'z': + (yyval.ext_swizzle).swz = SWIZZLE_Z; + (yyval.ext_swizzle).xyzw_valid = 1; + break; + case 'w': + (yyval.ext_swizzle).swz = SWIZZLE_W; + (yyval.ext_swizzle).xyzw_valid = 1; + break; + + case 'r': + (yyval.ext_swizzle).swz = SWIZZLE_X; + (yyval.ext_swizzle).rgba_valid = 1; + break; + case 'g': + (yyval.ext_swizzle).swz = SWIZZLE_Y; + (yyval.ext_swizzle).rgba_valid = 1; + break; + case 'b': + (yyval.ext_swizzle).swz = SWIZZLE_Z; + (yyval.ext_swizzle).rgba_valid = 1; + break; + case 'a': + (yyval.ext_swizzle).swz = SWIZZLE_W; + (yyval.ext_swizzle).rgba_valid = 1; + break; + + default: + yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector"); + YYERROR; + break; + } + ;} + break; + + case 53: + +/* Line 1455 of yacc.c */ +#line 643 "program_parse.y" + { + struct asm_symbol *const s = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); + + if (s == NULL) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); + YYERROR; + } else if ((s->type != at_param) && (s->type != at_temp) + && (s->type != at_attrib)) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); + YYERROR; + } else if ((s->type == at_param) && s->param_is_array) { + yyerror(& (yylsp[(1) - (1)]), state, "non-array access to array PARAM"); + YYERROR; + } + + init_src_reg(& (yyval.src_reg)); + switch (s->type) { + case at_temp: + (yyval.src_reg).Base.File = PROGRAM_TEMPORARY; + (yyval.src_reg).Base.Index = s->temp_binding; + break; + case at_param: + (yyval.src_reg).Base.File = s->param_binding_type; + (yyval.src_reg).Base.Index = s->param_binding_begin; + break; + case at_attrib: + (yyval.src_reg).Base.File = PROGRAM_INPUT; + (yyval.src_reg).Base.Index = s->attrib_binding; + state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index); + + if (!validate_inputs(& (yylsp[(1) - (1)]), state)) { + YYERROR; + } + break; + + default: + YYERROR; + break; + } + ;} + break; + + case 54: + +/* Line 1455 of yacc.c */ +#line 685 "program_parse.y" + { + init_src_reg(& (yyval.src_reg)); + (yyval.src_reg).Base.File = PROGRAM_INPUT; + (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].attrib); + state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index); + + if (!validate_inputs(& (yylsp[(1) - (1)]), state)) { + YYERROR; + } + ;} + break; + + case 55: + +/* Line 1455 of yacc.c */ +#line 696 "program_parse.y" + { + if (! (yyvsp[(3) - (4)].src_reg).Base.RelAddr + && ((unsigned) (yyvsp[(3) - (4)].src_reg).Base.Index >= (yyvsp[(1) - (4)].sym)->param_binding_length)) { + yyerror(& (yylsp[(3) - (4)]), state, "out of bounds array access"); + YYERROR; + } + + init_src_reg(& (yyval.src_reg)); + (yyval.src_reg).Base.File = (yyvsp[(1) - (4)].sym)->param_binding_type; + + if ((yyvsp[(3) - (4)].src_reg).Base.RelAddr) { + (yyvsp[(1) - (4)].sym)->param_accessed_indirectly = 1; + + (yyval.src_reg).Base.RelAddr = 1; + (yyval.src_reg).Base.Index = (yyvsp[(3) - (4)].src_reg).Base.Index; + (yyval.src_reg).Symbol = (yyvsp[(1) - (4)].sym); + } else { + (yyval.src_reg).Base.Index = (yyvsp[(1) - (4)].sym)->param_binding_begin + (yyvsp[(3) - (4)].src_reg).Base.Index; + } + ;} + break; + + case 56: + +/* Line 1455 of yacc.c */ +#line 717 "program_parse.y" + { + init_src_reg(& (yyval.src_reg)); + (yyval.src_reg).Base.File = ((yyvsp[(1) - (1)].temp_sym).name != NULL) + ? (yyvsp[(1) - (1)].temp_sym).param_binding_type + : PROGRAM_CONSTANT; + (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].temp_sym).param_binding_begin; + ;} + break; + + case 57: + +/* Line 1455 of yacc.c */ +#line 727 "program_parse.y" + { + init_dst_reg(& (yyval.dst_reg)); + (yyval.dst_reg).File = PROGRAM_OUTPUT; + (yyval.dst_reg).Index = (yyvsp[(1) - (1)].result); + ;} + break; + + case 58: + +/* Line 1455 of yacc.c */ +#line 733 "program_parse.y" + { + struct asm_symbol *const s = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); + + if (s == NULL) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); + YYERROR; + } else if ((s->type != at_output) && (s->type != at_temp)) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); + YYERROR; + } + + init_dst_reg(& (yyval.dst_reg)); + switch (s->type) { + case at_temp: + (yyval.dst_reg).File = PROGRAM_TEMPORARY; + (yyval.dst_reg).Index = s->temp_binding; + break; + case at_output: + (yyval.dst_reg).File = PROGRAM_OUTPUT; + (yyval.dst_reg).Index = s->output_binding; + break; + default: + (yyval.dst_reg).File = s->param_binding_type; + (yyval.dst_reg).Index = s->param_binding_begin; + break; + } + ;} + break; + + case 59: + +/* Line 1455 of yacc.c */ +#line 764 "program_parse.y" + { + struct asm_symbol *const s = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); + + if (s == NULL) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); + YYERROR; + } else if ((s->type != at_param) || !s->param_is_array) { + yyerror(& (yylsp[(1) - (1)]), state, "array access to non-PARAM variable"); + YYERROR; + } else { + (yyval.sym) = s; + } + ;} + break; + + case 62: + +/* Line 1455 of yacc.c */ +#line 783 "program_parse.y" + { + init_src_reg(& (yyval.src_reg)); + (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 63: + +/* Line 1455 of yacc.c */ +#line 790 "program_parse.y" + { + /* FINISHME: Add support for multiple address registers. + */ + /* FINISHME: Add support for 4-component address registers. + */ + init_src_reg(& (yyval.src_reg)); + (yyval.src_reg).Base.RelAddr = 1; + (yyval.src_reg).Base.Index = (yyvsp[(3) - (3)].integer); + ;} + break; + + case 64: + +/* Line 1455 of yacc.c */ +#line 801 "program_parse.y" + { (yyval.integer) = 0; ;} + break; + + case 65: + +/* Line 1455 of yacc.c */ +#line 802 "program_parse.y" + { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;} + break; + + case 66: + +/* Line 1455 of yacc.c */ +#line 803 "program_parse.y" + { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;} + break; + + case 67: + +/* Line 1455 of yacc.c */ +#line 807 "program_parse.y" + { + if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 63)) { + yyerror(& (yylsp[(1) - (1)]), state, + "relative address offset too large (positive)"); + YYERROR; + } else { + (yyval.integer) = (yyvsp[(1) - (1)].integer); + } + ;} + break; + + case 68: + +/* Line 1455 of yacc.c */ +#line 819 "program_parse.y" + { + if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 64)) { + yyerror(& (yylsp[(1) - (1)]), state, + "relative address offset too large (negative)"); + YYERROR; + } else { + (yyval.integer) = (yyvsp[(1) - (1)].integer); + } + ;} + break; + + case 69: + +/* Line 1455 of yacc.c */ +#line 831 "program_parse.y" + { + struct asm_symbol *const s = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); + + if (s == NULL) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid array member"); + YYERROR; + } else if (s->type != at_address) { + yyerror(& (yylsp[(1) - (1)]), state, + "invalid variable for indexed array access"); + YYERROR; + } else { + (yyval.sym) = s; + } + ;} + break; + + case 70: + +/* Line 1455 of yacc.c */ +#line 849 "program_parse.y" + { + if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector"); + YYERROR; + } else { + (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask); + } + ;} + break; + + case 71: + +/* Line 1455 of yacc.c */ +#line 860 "program_parse.y" + { + if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) { + yyerror(& (yylsp[(1) - (1)]), state, + "address register write mask must be \".x\""); + YYERROR; + } else { + (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask); + } + ;} + break; + + case 76: + +/* Line 1455 of yacc.c */ +#line 876 "program_parse.y" + { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;} + break; + + case 81: + +/* Line 1455 of yacc.c */ +#line 880 "program_parse.y" + { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;} + break; + + case 88: + +/* Line 1455 of yacc.c */ +#line 892 "program_parse.y" + { + struct asm_symbol *const s = + declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)])); + + if (s == NULL) { + YYERROR; + } else { + s->attrib_binding = (yyvsp[(4) - (4)].attrib); + state->InputsBound |= (1U << s->attrib_binding); + + if (!validate_inputs(& (yylsp[(4) - (4)]), state)) { + YYERROR; + } + } + ;} + break; + + case 89: + +/* Line 1455 of yacc.c */ +#line 910 "program_parse.y" + { + (yyval.attrib) = (yyvsp[(2) - (2)].attrib); + ;} + break; + + case 90: + +/* Line 1455 of yacc.c */ +#line 914 "program_parse.y" + { + (yyval.attrib) = (yyvsp[(2) - (2)].attrib); + ;} + break; + + case 91: + +/* Line 1455 of yacc.c */ +#line 920 "program_parse.y" + { + (yyval.attrib) = VERT_ATTRIB_POS; + ;} + break; + + case 92: + +/* Line 1455 of yacc.c */ +#line 924 "program_parse.y" + { + (yyval.attrib) = VERT_ATTRIB_WEIGHT; + ;} + break; + + case 93: + +/* Line 1455 of yacc.c */ +#line 928 "program_parse.y" + { + (yyval.attrib) = VERT_ATTRIB_NORMAL; + ;} + break; + + case 94: + +/* Line 1455 of yacc.c */ +#line 932 "program_parse.y" + { + if (!state->ctx->Extensions.EXT_secondary_color) { + yyerror(& (yylsp[(2) - (2)]), state, "GL_EXT_secondary_color not supported"); + YYERROR; + } + + (yyval.attrib) = VERT_ATTRIB_COLOR0 + (yyvsp[(2) - (2)].integer); + ;} + break; + + case 95: + +/* Line 1455 of yacc.c */ +#line 941 "program_parse.y" + { + if (!state->ctx->Extensions.EXT_fog_coord) { + yyerror(& (yylsp[(1) - (1)]), state, "GL_EXT_fog_coord not supported"); + YYERROR; + } + + (yyval.attrib) = VERT_ATTRIB_FOG; + ;} + break; + + case 96: + +/* Line 1455 of yacc.c */ +#line 950 "program_parse.y" + { + (yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer); + ;} + break; + + case 97: + +/* Line 1455 of yacc.c */ +#line 954 "program_parse.y" + { + yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported"); + YYERROR; + ;} + break; + + case 98: + +/* Line 1455 of yacc.c */ +#line 959 "program_parse.y" + { + (yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer); + ;} + break; + + case 99: + +/* Line 1455 of yacc.c */ +#line 965 "program_parse.y" + { + if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference"); + YYERROR; + } + + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 103: + +/* Line 1455 of yacc.c */ +#line 979 "program_parse.y" + { + (yyval.attrib) = FRAG_ATTRIB_WPOS; + ;} + break; + + case 104: + +/* Line 1455 of yacc.c */ +#line 983 "program_parse.y" + { + (yyval.attrib) = FRAG_ATTRIB_COL0 + (yyvsp[(2) - (2)].integer); + ;} + break; + + case 105: + +/* Line 1455 of yacc.c */ +#line 987 "program_parse.y" + { + (yyval.attrib) = FRAG_ATTRIB_FOGC; + ;} + break; + + case 106: + +/* Line 1455 of yacc.c */ +#line 991 "program_parse.y" + { + (yyval.attrib) = FRAG_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer); + ;} + break; + + case 109: + +/* Line 1455 of yacc.c */ +#line 999 "program_parse.y" + { + struct asm_symbol *const s = + declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)])); + + if (s == NULL) { + YYERROR; + } else { + s->param_binding_type = (yyvsp[(3) - (3)].temp_sym).param_binding_type; + s->param_binding_begin = (yyvsp[(3) - (3)].temp_sym).param_binding_begin; + s->param_binding_length = (yyvsp[(3) - (3)].temp_sym).param_binding_length; + s->param_is_array = 0; + } + ;} + break; + + case 110: + +/* Line 1455 of yacc.c */ +#line 1015 "program_parse.y" + { + if (((yyvsp[(4) - (6)].integer) != 0) && ((unsigned) (yyvsp[(4) - (6)].integer) != (yyvsp[(6) - (6)].temp_sym).param_binding_length)) { + yyerror(& (yylsp[(4) - (6)]), state, + "parameter array size and number of bindings must match"); + YYERROR; + } else { + struct asm_symbol *const s = + declare_variable(state, (yyvsp[(2) - (6)].string), (yyvsp[(6) - (6)].temp_sym).type, & (yylsp[(2) - (6)])); + + if (s == NULL) { + YYERROR; + } else { + s->param_binding_type = (yyvsp[(6) - (6)].temp_sym).param_binding_type; + s->param_binding_begin = (yyvsp[(6) - (6)].temp_sym).param_binding_begin; + s->param_binding_length = (yyvsp[(6) - (6)].temp_sym).param_binding_length; + s->param_is_array = 1; + } + } + ;} + break; + + case 111: + +/* Line 1455 of yacc.c */ +#line 1037 "program_parse.y" + { + (yyval.integer) = 0; + ;} + break; + + case 112: + +/* Line 1455 of yacc.c */ +#line 1041 "program_parse.y" + { + if (((yyvsp[(1) - (1)].integer) < 1) || ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxParameters)) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid parameter array size"); + YYERROR; + } else { + (yyval.integer) = (yyvsp[(1) - (1)].integer); + } + ;} + break; + + case 113: + +/* Line 1455 of yacc.c */ +#line 1052 "program_parse.y" + { + (yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym); + ;} + break; + + case 114: + +/* Line 1455 of yacc.c */ +#line 1058 "program_parse.y" + { + (yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym); + ;} + break; + + case 116: + +/* Line 1455 of yacc.c */ +#line 1065 "program_parse.y" + { + (yyvsp[(1) - (3)].temp_sym).param_binding_length += (yyvsp[(3) - (3)].temp_sym).param_binding_length; + (yyval.temp_sym) = (yyvsp[(1) - (3)].temp_sym); + ;} + break; + + case 117: + +/* Line 1455 of yacc.c */ +#line 1072 "program_parse.y" + { + memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); + (yyval.temp_sym).param_binding_begin = ~0; + initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); + ;} + break; + + case 118: + +/* Line 1455 of yacc.c */ +#line 1078 "program_parse.y" + { + memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); + (yyval.temp_sym).param_binding_begin = ~0; + initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); + ;} + break; + + case 119: + +/* Line 1455 of yacc.c */ +#line 1084 "program_parse.y" + { + memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); + (yyval.temp_sym).param_binding_begin = ~0; + initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector)); + ;} + break; + + case 120: + +/* Line 1455 of yacc.c */ +#line 1092 "program_parse.y" + { + memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); + (yyval.temp_sym).param_binding_begin = ~0; + initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); + ;} + break; + + case 121: + +/* Line 1455 of yacc.c */ +#line 1098 "program_parse.y" + { + memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); + (yyval.temp_sym).param_binding_begin = ~0; + initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); + ;} + break; + + case 122: + +/* Line 1455 of yacc.c */ +#line 1104 "program_parse.y" + { + memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); + (yyval.temp_sym).param_binding_begin = ~0; + initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector)); + ;} + break; + + case 123: + +/* Line 1455 of yacc.c */ +#line 1112 "program_parse.y" + { + memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); + (yyval.temp_sym).param_binding_begin = ~0; + initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); + ;} + break; + + case 124: + +/* Line 1455 of yacc.c */ +#line 1118 "program_parse.y" + { + memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); + (yyval.temp_sym).param_binding_begin = ~0; + initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); + ;} + break; + + case 125: + +/* Line 1455 of yacc.c */ +#line 1124 "program_parse.y" + { + memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); + (yyval.temp_sym).param_binding_begin = ~0; + initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector)); + ;} + break; + + case 126: + +/* Line 1455 of yacc.c */ +#line 1131 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); ;} + break; + + case 127: + +/* Line 1455 of yacc.c */ +#line 1132 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 128: + +/* Line 1455 of yacc.c */ +#line 1135 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 129: + +/* Line 1455 of yacc.c */ +#line 1136 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 130: + +/* Line 1455 of yacc.c */ +#line 1137 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 131: + +/* Line 1455 of yacc.c */ +#line 1138 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 132: + +/* Line 1455 of yacc.c */ +#line 1139 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 133: + +/* Line 1455 of yacc.c */ +#line 1140 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 134: + +/* Line 1455 of yacc.c */ +#line 1141 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 135: + +/* Line 1455 of yacc.c */ +#line 1142 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 136: + +/* Line 1455 of yacc.c */ +#line 1143 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 137: + +/* Line 1455 of yacc.c */ +#line 1144 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 138: + +/* Line 1455 of yacc.c */ +#line 1145 "program_parse.y" + { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} + break; + + case 139: + +/* Line 1455 of yacc.c */ +#line 1149 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = STATE_MATERIAL; + (yyval.state)[1] = (yyvsp[(2) - (3)].integer); + (yyval.state)[2] = (yyvsp[(3) - (3)].integer); + ;} + break; + + case 140: + +/* Line 1455 of yacc.c */ +#line 1158 "program_parse.y" + { + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 141: + +/* Line 1455 of yacc.c */ +#line 1162 "program_parse.y" + { + (yyval.integer) = STATE_EMISSION; + ;} + break; + + case 142: + +/* Line 1455 of yacc.c */ +#line 1166 "program_parse.y" + { + (yyval.integer) = STATE_SHININESS; + ;} + break; + + case 143: + +/* Line 1455 of yacc.c */ +#line 1172 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = STATE_LIGHT; + (yyval.state)[1] = (yyvsp[(3) - (5)].integer); + (yyval.state)[2] = (yyvsp[(5) - (5)].integer); + ;} + break; + + case 144: + +/* Line 1455 of yacc.c */ +#line 1181 "program_parse.y" + { + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 145: + +/* Line 1455 of yacc.c */ +#line 1185 "program_parse.y" + { + (yyval.integer) = STATE_POSITION; + ;} + break; + + case 146: + +/* Line 1455 of yacc.c */ +#line 1189 "program_parse.y" + { + if (!state->ctx->Extensions.EXT_point_parameters) { + yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported"); + YYERROR; + } + + (yyval.integer) = STATE_ATTENUATION; + ;} + break; + + case 147: + +/* Line 1455 of yacc.c */ +#line 1198 "program_parse.y" + { + (yyval.integer) = (yyvsp[(2) - (2)].integer); + ;} + break; + + case 148: + +/* Line 1455 of yacc.c */ +#line 1202 "program_parse.y" + { + (yyval.integer) = STATE_HALF_VECTOR; + ;} + break; + + case 149: + +/* Line 1455 of yacc.c */ +#line 1208 "program_parse.y" + { + (yyval.integer) = STATE_SPOT_DIRECTION; + ;} + break; + + case 150: + +/* Line 1455 of yacc.c */ +#line 1214 "program_parse.y" + { + (yyval.state)[0] = (yyvsp[(2) - (2)].state)[0]; + (yyval.state)[1] = (yyvsp[(2) - (2)].state)[1]; + ;} + break; + + case 151: + +/* Line 1455 of yacc.c */ +#line 1221 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT; + ;} + break; + + case 152: + +/* Line 1455 of yacc.c */ +#line 1226 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR; + (yyval.state)[1] = (yyvsp[(1) - (2)].integer); + ;} + break; + + case 153: + +/* Line 1455 of yacc.c */ +#line 1234 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = STATE_LIGHTPROD; + (yyval.state)[1] = (yyvsp[(3) - (6)].integer); + (yyval.state)[2] = (yyvsp[(5) - (6)].integer); + (yyval.state)[3] = (yyvsp[(6) - (6)].integer); + ;} + break; + + case 155: + +/* Line 1455 of yacc.c */ +#line 1246 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = (yyvsp[(3) - (3)].integer); + (yyval.state)[1] = (yyvsp[(2) - (3)].integer); + ;} + break; + + case 156: + +/* Line 1455 of yacc.c */ +#line 1254 "program_parse.y" + { + (yyval.integer) = STATE_TEXENV_COLOR; + ;} + break; + + case 157: + +/* Line 1455 of yacc.c */ +#line 1260 "program_parse.y" + { + (yyval.integer) = STATE_AMBIENT; + ;} + break; + + case 158: + +/* Line 1455 of yacc.c */ +#line 1264 "program_parse.y" + { + (yyval.integer) = STATE_DIFFUSE; + ;} + break; + + case 159: + +/* Line 1455 of yacc.c */ +#line 1268 "program_parse.y" + { + (yyval.integer) = STATE_SPECULAR; + ;} + break; + + case 160: + +/* Line 1455 of yacc.c */ +#line 1274 "program_parse.y" + { + if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector"); + YYERROR; + } + + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 161: + +/* Line 1455 of yacc.c */ +#line 1285 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = STATE_TEXGEN; + (yyval.state)[1] = (yyvsp[(2) - (4)].integer); + (yyval.state)[2] = (yyvsp[(3) - (4)].integer) + (yyvsp[(4) - (4)].integer); + ;} + break; + + case 162: + +/* Line 1455 of yacc.c */ +#line 1294 "program_parse.y" + { + (yyval.integer) = STATE_TEXGEN_EYE_S; + ;} + break; + + case 163: + +/* Line 1455 of yacc.c */ +#line 1298 "program_parse.y" + { + (yyval.integer) = STATE_TEXGEN_OBJECT_S; + ;} + break; + + case 164: + +/* Line 1455 of yacc.c */ +#line 1303 "program_parse.y" + { + (yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S; + ;} + break; + + case 165: + +/* Line 1455 of yacc.c */ +#line 1307 "program_parse.y" + { + (yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S; + ;} + break; + + case 166: + +/* Line 1455 of yacc.c */ +#line 1311 "program_parse.y" + { + (yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S; + ;} + break; + + case 167: + +/* Line 1455 of yacc.c */ +#line 1315 "program_parse.y" + { + (yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S; + ;} + break; + + case 168: + +/* Line 1455 of yacc.c */ +#line 1321 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = (yyvsp[(2) - (2)].integer); + ;} + break; + + case 169: + +/* Line 1455 of yacc.c */ +#line 1328 "program_parse.y" + { + (yyval.integer) = STATE_FOG_COLOR; + ;} + break; + + case 170: + +/* Line 1455 of yacc.c */ +#line 1332 "program_parse.y" + { + (yyval.integer) = STATE_FOG_PARAMS; + ;} + break; + + case 171: + +/* Line 1455 of yacc.c */ +#line 1338 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = STATE_CLIPPLANE; + (yyval.state)[1] = (yyvsp[(3) - (5)].integer); + ;} + break; + + case 172: + +/* Line 1455 of yacc.c */ +#line 1346 "program_parse.y" + { + if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector"); + YYERROR; + } + + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 173: + +/* Line 1455 of yacc.c */ +#line 1357 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = (yyvsp[(2) - (2)].integer); + ;} + break; + + case 174: + +/* Line 1455 of yacc.c */ +#line 1364 "program_parse.y" + { + (yyval.integer) = STATE_POINT_SIZE; + ;} + break; + + case 175: + +/* Line 1455 of yacc.c */ +#line 1368 "program_parse.y" + { + (yyval.integer) = STATE_POINT_ATTENUATION; + ;} + break; + + case 176: + +/* Line 1455 of yacc.c */ +#line 1374 "program_parse.y" + { + (yyval.state)[0] = (yyvsp[(1) - (5)].state)[0]; + (yyval.state)[1] = (yyvsp[(1) - (5)].state)[1]; + (yyval.state)[2] = (yyvsp[(4) - (5)].integer); + (yyval.state)[3] = (yyvsp[(4) - (5)].integer); + (yyval.state)[4] = (yyvsp[(1) - (5)].state)[2]; + ;} + break; + + case 177: + +/* Line 1455 of yacc.c */ +#line 1384 "program_parse.y" + { + (yyval.state)[0] = (yyvsp[(1) - (2)].state)[0]; + (yyval.state)[1] = (yyvsp[(1) - (2)].state)[1]; + (yyval.state)[2] = (yyvsp[(2) - (2)].state)[2]; + (yyval.state)[3] = (yyvsp[(2) - (2)].state)[3]; + (yyval.state)[4] = (yyvsp[(1) - (2)].state)[2]; + ;} + break; + + case 178: + +/* Line 1455 of yacc.c */ +#line 1394 "program_parse.y" + { + (yyval.state)[2] = 0; + (yyval.state)[3] = 3; + ;} + break; + + case 179: + +/* Line 1455 of yacc.c */ +#line 1399 "program_parse.y" + { + /* It seems logical that the matrix row range specifier would have + * to specify a range or more than one row (i.e., $5 > $3). + * However, the ARB_vertex_program spec says "a program will fail + * to load if <a> is greater than <b>." This means that $3 == $5 + * is valid. + */ + if ((yyvsp[(3) - (6)].integer) > (yyvsp[(5) - (6)].integer)) { + yyerror(& (yylsp[(3) - (6)]), state, "invalid matrix row range"); + YYERROR; + } + + (yyval.state)[2] = (yyvsp[(3) - (6)].integer); + (yyval.state)[3] = (yyvsp[(5) - (6)].integer); + ;} + break; + + case 180: + +/* Line 1455 of yacc.c */ +#line 1417 "program_parse.y" + { + (yyval.state)[0] = (yyvsp[(2) - (3)].state)[0]; + (yyval.state)[1] = (yyvsp[(2) - (3)].state)[1]; + (yyval.state)[2] = (yyvsp[(3) - (3)].integer); + ;} + break; + + case 181: + +/* Line 1455 of yacc.c */ +#line 1425 "program_parse.y" + { + (yyval.integer) = 0; + ;} + break; + + case 182: + +/* Line 1455 of yacc.c */ +#line 1429 "program_parse.y" + { + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 183: + +/* Line 1455 of yacc.c */ +#line 1435 "program_parse.y" + { + (yyval.integer) = STATE_MATRIX_INVERSE; + ;} + break; + + case 184: + +/* Line 1455 of yacc.c */ +#line 1439 "program_parse.y" + { + (yyval.integer) = STATE_MATRIX_TRANSPOSE; + ;} + break; + + case 185: + +/* Line 1455 of yacc.c */ +#line 1443 "program_parse.y" + { + (yyval.integer) = STATE_MATRIX_INVTRANS; + ;} + break; + + case 186: + +/* Line 1455 of yacc.c */ +#line 1449 "program_parse.y" + { + if ((yyvsp[(1) - (1)].integer) > 3) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference"); + YYERROR; + } + + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 187: + +/* Line 1455 of yacc.c */ +#line 1460 "program_parse.y" + { + (yyval.state)[0] = STATE_MODELVIEW_MATRIX; + (yyval.state)[1] = (yyvsp[(2) - (2)].integer); + ;} + break; + + case 188: + +/* Line 1455 of yacc.c */ +#line 1465 "program_parse.y" + { + (yyval.state)[0] = STATE_PROJECTION_MATRIX; + (yyval.state)[1] = 0; + ;} + break; + + case 189: + +/* Line 1455 of yacc.c */ +#line 1470 "program_parse.y" + { + (yyval.state)[0] = STATE_MVP_MATRIX; + (yyval.state)[1] = 0; + ;} + break; + + case 190: + +/* Line 1455 of yacc.c */ +#line 1475 "program_parse.y" + { + (yyval.state)[0] = STATE_TEXTURE_MATRIX; + (yyval.state)[1] = (yyvsp[(2) - (2)].integer); + ;} + break; + + case 191: + +/* Line 1455 of yacc.c */ +#line 1480 "program_parse.y" + { + yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported"); + YYERROR; + ;} + break; + + case 192: + +/* Line 1455 of yacc.c */ +#line 1485 "program_parse.y" + { + (yyval.state)[0] = STATE_PROGRAM_MATRIX; + (yyval.state)[1] = (yyvsp[(3) - (4)].integer); + ;} + break; + + case 193: + +/* Line 1455 of yacc.c */ +#line 1492 "program_parse.y" + { + (yyval.integer) = 0; + ;} + break; + + case 194: + +/* Line 1455 of yacc.c */ +#line 1496 "program_parse.y" + { + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 195: + +/* Line 1455 of yacc.c */ +#line 1501 "program_parse.y" + { + /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix + * zero is valid. + */ + if ((yyvsp[(1) - (1)].integer) != 0) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid modelview matrix index"); + YYERROR; + } + + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 196: + +/* Line 1455 of yacc.c */ +#line 1514 "program_parse.y" + { + /* Since GL_ARB_matrix_palette isn't supported, just let any value + * through here. The error will be generated later. + */ + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 197: + +/* Line 1455 of yacc.c */ +#line 1522 "program_parse.y" + { + if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector"); + YYERROR; + } + + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 198: + +/* Line 1455 of yacc.c */ +#line 1533 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = STATE_DEPTH_RANGE; + ;} + break; + + case 203: + +/* Line 1455 of yacc.c */ +#line 1545 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = state->state_param_enum; + (yyval.state)[1] = STATE_ENV; + (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0]; + (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1]; + ;} + break; + + case 204: + +/* Line 1455 of yacc.c */ +#line 1555 "program_parse.y" + { + (yyval.state)[0] = (yyvsp[(1) - (1)].integer); + (yyval.state)[1] = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 205: + +/* Line 1455 of yacc.c */ +#line 1560 "program_parse.y" + { + (yyval.state)[0] = (yyvsp[(1) - (3)].integer); + (yyval.state)[1] = (yyvsp[(3) - (3)].integer); + ;} + break; + + case 206: + +/* Line 1455 of yacc.c */ +#line 1567 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = state->state_param_enum; + (yyval.state)[1] = STATE_ENV; + (yyval.state)[2] = (yyvsp[(4) - (5)].integer); + (yyval.state)[3] = (yyvsp[(4) - (5)].integer); + ;} + break; + + case 207: + +/* Line 1455 of yacc.c */ +#line 1577 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = state->state_param_enum; + (yyval.state)[1] = STATE_LOCAL; + (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0]; + (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1]; + ;} + break; + + case 208: + +/* Line 1455 of yacc.c */ +#line 1586 "program_parse.y" + { + (yyval.state)[0] = (yyvsp[(1) - (1)].integer); + (yyval.state)[1] = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 209: + +/* Line 1455 of yacc.c */ +#line 1591 "program_parse.y" + { + (yyval.state)[0] = (yyvsp[(1) - (3)].integer); + (yyval.state)[1] = (yyvsp[(3) - (3)].integer); + ;} + break; + + case 210: + +/* Line 1455 of yacc.c */ +#line 1598 "program_parse.y" + { + memset((yyval.state), 0, sizeof((yyval.state))); + (yyval.state)[0] = state->state_param_enum; + (yyval.state)[1] = STATE_LOCAL; + (yyval.state)[2] = (yyvsp[(4) - (5)].integer); + (yyval.state)[3] = (yyvsp[(4) - (5)].integer); + ;} + break; + + case 211: + +/* Line 1455 of yacc.c */ +#line 1608 "program_parse.y" + { + if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference"); + YYERROR; + } + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 212: + +/* Line 1455 of yacc.c */ +#line 1618 "program_parse.y" + { + if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference"); + YYERROR; + } + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 217: + +/* Line 1455 of yacc.c */ +#line 1633 "program_parse.y" + { + (yyval.vector).count = 4; + (yyval.vector).data[0] = (yyvsp[(1) - (1)].real); + (yyval.vector).data[1] = (yyvsp[(1) - (1)].real); + (yyval.vector).data[2] = (yyvsp[(1) - (1)].real); + (yyval.vector).data[3] = (yyvsp[(1) - (1)].real); + ;} + break; + + case 218: + +/* Line 1455 of yacc.c */ +#line 1643 "program_parse.y" + { + (yyval.vector).count = 1; + (yyval.vector).data[0] = (yyvsp[(1) - (1)].real); + (yyval.vector).data[1] = (yyvsp[(1) - (1)].real); + (yyval.vector).data[2] = (yyvsp[(1) - (1)].real); + (yyval.vector).data[3] = (yyvsp[(1) - (1)].real); + ;} + break; + + case 219: + +/* Line 1455 of yacc.c */ +#line 1651 "program_parse.y" + { + (yyval.vector).count = 1; + (yyval.vector).data[0] = (float) (yyvsp[(1) - (1)].integer); + (yyval.vector).data[1] = (float) (yyvsp[(1) - (1)].integer); + (yyval.vector).data[2] = (float) (yyvsp[(1) - (1)].integer); + (yyval.vector).data[3] = (float) (yyvsp[(1) - (1)].integer); + ;} + break; + + case 220: + +/* Line 1455 of yacc.c */ +#line 1661 "program_parse.y" + { + (yyval.vector).count = 4; + (yyval.vector).data[0] = (yyvsp[(2) - (3)].real); + (yyval.vector).data[1] = 0.0f; + (yyval.vector).data[2] = 0.0f; + (yyval.vector).data[3] = 1.0f; + ;} + break; + + case 221: + +/* Line 1455 of yacc.c */ +#line 1669 "program_parse.y" + { + (yyval.vector).count = 4; + (yyval.vector).data[0] = (yyvsp[(2) - (5)].real); + (yyval.vector).data[1] = (yyvsp[(4) - (5)].real); + (yyval.vector).data[2] = 0.0f; + (yyval.vector).data[3] = 1.0f; + ;} + break; + + case 222: + +/* Line 1455 of yacc.c */ +#line 1678 "program_parse.y" + { + (yyval.vector).count = 4; + (yyval.vector).data[0] = (yyvsp[(2) - (7)].real); + (yyval.vector).data[1] = (yyvsp[(4) - (7)].real); + (yyval.vector).data[2] = (yyvsp[(6) - (7)].real); + (yyval.vector).data[3] = 1.0f; + ;} + break; + + case 223: + +/* Line 1455 of yacc.c */ +#line 1687 "program_parse.y" + { + (yyval.vector).count = 4; + (yyval.vector).data[0] = (yyvsp[(2) - (9)].real); + (yyval.vector).data[1] = (yyvsp[(4) - (9)].real); + (yyval.vector).data[2] = (yyvsp[(6) - (9)].real); + (yyval.vector).data[3] = (yyvsp[(8) - (9)].real); + ;} + break; + + case 224: + +/* Line 1455 of yacc.c */ +#line 1697 "program_parse.y" + { + (yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real); + ;} + break; + + case 225: + +/* Line 1455 of yacc.c */ +#line 1701 "program_parse.y" + { + (yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer)); + ;} + break; + + case 226: + +/* Line 1455 of yacc.c */ +#line 1706 "program_parse.y" + { (yyval.negate) = FALSE; ;} + break; + + case 227: + +/* Line 1455 of yacc.c */ +#line 1707 "program_parse.y" + { (yyval.negate) = TRUE; ;} + break; + + case 228: + +/* Line 1455 of yacc.c */ +#line 1708 "program_parse.y" + { (yyval.negate) = FALSE; ;} + break; + + case 229: + +/* Line 1455 of yacc.c */ +#line 1711 "program_parse.y" + { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} + break; + + case 231: + +/* Line 1455 of yacc.c */ +#line 1714 "program_parse.y" + { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} + break; + + case 233: + +/* Line 1455 of yacc.c */ +#line 1718 "program_parse.y" + { + if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) { + YYERROR; + } + ;} + break; + + case 234: + +/* Line 1455 of yacc.c */ +#line 1724 "program_parse.y" + { + if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) { + YYERROR; + } + ;} + break; + + case 235: + +/* Line 1455 of yacc.c */ +#line 1732 "program_parse.y" + { + struct asm_symbol *const s = + declare_variable(state, (yyvsp[(2) - (4)].string), at_output, & (yylsp[(2) - (4)])); + + if (s == NULL) { + YYERROR; + } else { + s->output_binding = (yyvsp[(4) - (4)].result); + } + ;} + break; + + case 236: + +/* Line 1455 of yacc.c */ +#line 1745 "program_parse.y" + { + if (state->mode == ARB_vertex) { + (yyval.result) = VERT_RESULT_HPOS; + } else { + yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name"); + YYERROR; + } + ;} + break; + + case 237: + +/* Line 1455 of yacc.c */ +#line 1754 "program_parse.y" + { + if (state->mode == ARB_vertex) { + (yyval.result) = VERT_RESULT_FOGC; + } else { + yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name"); + YYERROR; + } + ;} + break; + + case 238: + +/* Line 1455 of yacc.c */ +#line 1763 "program_parse.y" + { + (yyval.result) = (yyvsp[(2) - (2)].result); + ;} + break; + + case 239: + +/* Line 1455 of yacc.c */ +#line 1767 "program_parse.y" + { + if (state->mode == ARB_vertex) { + (yyval.result) = VERT_RESULT_PSIZ; + } else { + yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name"); + YYERROR; + } + ;} + break; + + case 240: + +/* Line 1455 of yacc.c */ +#line 1776 "program_parse.y" + { + if (state->mode == ARB_vertex) { + (yyval.result) = VERT_RESULT_TEX0 + (yyvsp[(3) - (3)].integer); + } else { + yyerror(& (yylsp[(2) - (3)]), state, "invalid program result name"); + YYERROR; + } + ;} + break; + + case 241: + +/* Line 1455 of yacc.c */ +#line 1785 "program_parse.y" + { + if (state->mode == ARB_fragment) { + (yyval.result) = FRAG_RESULT_DEPTH; + } else { + yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name"); + YYERROR; + } + ;} + break; + + case 242: + +/* Line 1455 of yacc.c */ +#line 1796 "program_parse.y" + { + (yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer); + ;} + break; + + case 243: + +/* Line 1455 of yacc.c */ +#line 1802 "program_parse.y" + { + (yyval.integer) = (state->mode == ARB_vertex) + ? VERT_RESULT_COL0 + : FRAG_RESULT_COLOR; + ;} + break; + + case 244: + +/* Line 1455 of yacc.c */ +#line 1808 "program_parse.y" + { + if (state->mode == ARB_vertex) { + (yyval.integer) = VERT_RESULT_COL0; + } else { + yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name"); + YYERROR; + } + ;} + break; + + case 245: + +/* Line 1455 of yacc.c */ +#line 1817 "program_parse.y" + { + if (state->mode == ARB_vertex) { + (yyval.integer) = VERT_RESULT_BFC0; + } else { + yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name"); + YYERROR; + } + ;} + break; + + case 246: + +/* Line 1455 of yacc.c */ +#line 1828 "program_parse.y" + { + (yyval.integer) = 0; + ;} + break; + + case 247: + +/* Line 1455 of yacc.c */ +#line 1832 "program_parse.y" + { + if (state->mode == ARB_vertex) { + (yyval.integer) = 0; + } else { + yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name"); + YYERROR; + } + ;} + break; + + case 248: + +/* Line 1455 of yacc.c */ +#line 1841 "program_parse.y" + { + if (state->mode == ARB_vertex) { + (yyval.integer) = 1; + } else { + yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name"); + YYERROR; + } + ;} + break; + + case 249: + +/* Line 1455 of yacc.c */ +#line 1851 "program_parse.y" + { (yyval.integer) = 0; ;} + break; + + case 250: + +/* Line 1455 of yacc.c */ +#line 1852 "program_parse.y" + { (yyval.integer) = 0; ;} + break; + + case 251: + +/* Line 1455 of yacc.c */ +#line 1853 "program_parse.y" + { (yyval.integer) = 1; ;} + break; + + case 252: + +/* Line 1455 of yacc.c */ +#line 1856 "program_parse.y" + { (yyval.integer) = 0; ;} + break; + + case 253: + +/* Line 1455 of yacc.c */ +#line 1857 "program_parse.y" + { (yyval.integer) = 0; ;} + break; + + case 254: + +/* Line 1455 of yacc.c */ +#line 1858 "program_parse.y" + { (yyval.integer) = 1; ;} + break; + + case 255: + +/* Line 1455 of yacc.c */ +#line 1861 "program_parse.y" + { (yyval.integer) = 0; ;} + break; + + case 256: + +/* Line 1455 of yacc.c */ +#line 1862 "program_parse.y" + { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} + break; + + case 257: + +/* Line 1455 of yacc.c */ +#line 1865 "program_parse.y" + { (yyval.integer) = 0; ;} + break; + + case 258: + +/* Line 1455 of yacc.c */ +#line 1866 "program_parse.y" + { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} + break; + + case 259: + +/* Line 1455 of yacc.c */ +#line 1869 "program_parse.y" + { (yyval.integer) = 0; ;} + break; + + case 260: + +/* Line 1455 of yacc.c */ +#line 1870 "program_parse.y" + { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} + break; + + case 261: + +/* Line 1455 of yacc.c */ +#line 1874 "program_parse.y" + { + if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector"); + YYERROR; + } + + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 262: + +/* Line 1455 of yacc.c */ +#line 1885 "program_parse.y" + { + if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector"); + YYERROR; + } + + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 263: + +/* Line 1455 of yacc.c */ +#line 1896 "program_parse.y" + { + if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) { + yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector"); + YYERROR; + } + + (yyval.integer) = (yyvsp[(1) - (1)].integer); + ;} + break; + + case 264: + +/* Line 1455 of yacc.c */ +#line 1907 "program_parse.y" + { + struct asm_symbol *exist = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string)); + struct asm_symbol *target = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(4) - (4)].string)); + + + if (exist != NULL) { + yyerror(& (yylsp[(2) - (4)]), state, "redeclared identifier"); + YYERROR; + } else if (target == NULL) { + yyerror(& (yylsp[(4) - (4)]), state, + "undefined variable binding in ALIAS statement"); + YYERROR; + } else { + _mesa_symbol_table_add_symbol(state->st, 0, (yyvsp[(2) - (4)].string), target); + } + ;} + break; + + + +/* Line 1455 of yacc.c */ +#line 4577 "program_parse.tab.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + *++yylsp = yyloc; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (&yylloc, state, YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (&yylloc, state, yymsg); + } + else + { + yyerror (&yylloc, state, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + yyerror_range[0] = yylloc; + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, &yylloc, state); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + yyerror_range[0] = yylsp[1-yylen]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + yyerror_range[0] = *yylsp; + yydestruct ("Error: popping", + yystos[yystate], yyvsp, yylsp, state); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + yyerror_range[1] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the lookahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + *++yylsp = yyloc; + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (&yylloc, state, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc, state); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, yylsp, state); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1675 of yacc.c */ +#line 1927 "program_parse.y" + + +struct asm_instruction * +asm_instruction_ctor(gl_inst_opcode op, + const struct prog_dst_register *dst, + const struct asm_src_register *src0, + const struct asm_src_register *src1, + const struct asm_src_register *src2) +{ + struct asm_instruction *inst = calloc(1, sizeof(struct asm_instruction)); + + if (inst) { + _mesa_init_instructions(& inst->Base, 1); + inst->Base.Opcode = op; + + /* In the core ARB extensions only the KIL instruction doesn't have a + * destination register. + */ + if (dst == NULL) { + init_dst_reg(& inst->Base.DstReg); + } else { + inst->Base.DstReg = *dst; + } + + inst->Base.SrcReg[0] = src0->Base; + inst->SrcReg[0] = *src0; + + if (src1 != NULL) { + inst->Base.SrcReg[1] = src1->Base; + inst->SrcReg[1] = *src1; + } else { + init_src_reg(& inst->SrcReg[1]); + } + + if (src2 != NULL) { + inst->Base.SrcReg[2] = src2->Base; + inst->SrcReg[2] = *src2; + } else { + init_src_reg(& inst->SrcReg[2]); + } + } + + return inst; +} + + +void +init_dst_reg(struct prog_dst_register *r) +{ + memset(r, 0, sizeof(*r)); + r->File = PROGRAM_UNDEFINED; + r->WriteMask = WRITEMASK_XYZW; + r->CondMask = COND_TR; + r->CondSwizzle = SWIZZLE_NOOP; +} + + +void +init_src_reg(struct asm_src_register *r) +{ + memset(r, 0, sizeof(*r)); + r->Base.File = PROGRAM_UNDEFINED; + r->Base.Swizzle = SWIZZLE_NOOP; + r->Symbol = NULL; +} + + +/** + * Validate the set of inputs used by a program + * + * Validates that legal sets of inputs are used by the program. In this case + * "used" included both reading the input or binding the input to a name using + * the \c ATTRIB command. + * + * \return + * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise. + */ +int +validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state) +{ + const int inputs = state->prog->InputsRead | state->InputsBound; + + if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) { + yyerror(locp, state, "illegal use of generic attribute and name attribute"); + return 0; + } + + return 1; +} + + +struct asm_symbol * +declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, + struct YYLTYPE *locp) +{ + struct asm_symbol *s = NULL; + struct asm_symbol *exist = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, name); + + + if (exist != NULL) { + yyerror(locp, state, "redeclared identifier"); + } else { + s = calloc(1, sizeof(struct asm_symbol)); + s->name = name; + s->type = t; + + switch (t) { + case at_temp: + if (state->prog->NumTemporaries >= state->limits->MaxTemps) { + yyerror(locp, state, "too many temporaries declared"); + free(s); + return NULL; + } + + s->temp_binding = state->prog->NumTemporaries; + state->prog->NumTemporaries++; + break; + + case at_address: + if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) { + yyerror(locp, state, "too many address registers declared"); + free(s); + return NULL; + } + + /* FINISHME: Add support for multiple address registers. + */ + state->prog->NumAddressRegs++; + break; + + default: + break; + } + + _mesa_symbol_table_add_symbol(state->st, 0, s->name, s); + s->next = state->sym; + state->sym = s; + } + + return s; +} + + +int add_state_reference(struct gl_program_parameter_list *param_list, + const gl_state_index tokens[STATE_LENGTH]) +{ + const GLuint size = 4; /* XXX fix */ + char *name; + GLint index; + + name = _mesa_program_state_string(tokens); + index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name, + size, GL_NONE, + NULL, (gl_state_index *) tokens, 0x0); + param_list->StateFlags |= _mesa_program_state_flags(tokens); + + /* free name string here since we duplicated it in add_parameter() */ + _mesa_free(name); + + return index; +} + + +int +initialize_symbol_from_state(struct gl_program *prog, + struct asm_symbol *param_var, + const gl_state_index tokens[STATE_LENGTH]) +{ + int idx = -1; + gl_state_index state_tokens[STATE_LENGTH]; + + + memcpy(state_tokens, tokens, sizeof(state_tokens)); + + param_var->type = at_param; + param_var->param_binding_type = PROGRAM_STATE_VAR; + + /* If we are adding a STATE_MATRIX that has multiple rows, we need to + * unroll it and call 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])) { + int row; + const int first_row = state_tokens[2]; + const int last_row = state_tokens[3]; + + for (row = first_row; row <= last_row; row++) { + state_tokens[2] = state_tokens[3] = row; + + idx = add_state_reference(prog->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + } + } + else { + idx = add_state_reference(prog->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + } + + return idx; +} + + +int +initialize_symbol_from_param(struct gl_program *prog, + struct asm_symbol *param_var, + const gl_state_index tokens[STATE_LENGTH]) +{ + int idx = -1; + gl_state_index state_tokens[STATE_LENGTH]; + + + memcpy(state_tokens, tokens, sizeof(state_tokens)); + + assert((state_tokens[0] == STATE_VERTEX_PROGRAM) + || (state_tokens[0] == STATE_FRAGMENT_PROGRAM)); + assert((state_tokens[1] == STATE_ENV) + || (state_tokens[1] == STATE_LOCAL)); + + param_var->type = at_param; + param_var->param_binding_type = (state_tokens[1] == STATE_ENV) + ? PROGRAM_ENV_PARAM : PROGRAM_LOCAL_PARAM; + + /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements, + * we need to unroll it and call add_state_reference() for each row + */ + if (state_tokens[2] != state_tokens[3]) { + int row; + const int first_row = state_tokens[2]; + const int last_row = state_tokens[3]; + + for (row = first_row; row <= last_row; row++) { + state_tokens[2] = state_tokens[3] = row; + + idx = add_state_reference(prog->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + } + } + else { + idx = add_state_reference(prog->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + } + + return idx; +} + + +int +initialize_symbol_from_const(struct gl_program *prog, + struct asm_symbol *param_var, + const struct asm_vector *vec) +{ + const int idx = _mesa_add_parameter(prog->Parameters, PROGRAM_CONSTANT, + NULL, vec->count, GL_NONE, vec->data, + NULL, 0x0); + + param_var->type = at_param; + param_var->param_binding_type = PROGRAM_CONSTANT; + + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + + return idx; +} + + +char * +make_error_string(const char *fmt, ...) +{ + int length; + char *str; + va_list args; + + va_start(args, fmt); + + /* Call vsnprintf once to determine how large the final string is. Call it + * again to do the actual formatting. from the vsnprintf manual page: + * + * Upon successful return, these functions return the number of + * characters printed (not including the trailing '\0' used to end + * output to strings). + */ + length = 1 + vsnprintf(NULL, 0, fmt, args); + + str = _mesa_malloc(length); + if (str) { + vsnprintf(str, length, fmt, args); + } + + va_end(args); + + return str; +} + + +void +yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s) +{ + char *err_str; + + + err_str = make_error_string("glProgramStringARB(%s)\n", s); + if (err_str) { + _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str); + _mesa_free(err_str); + } + + err_str = make_error_string("line %u, char %u: error: %s\n", + locp->first_line, locp->first_column, s); + _mesa_set_program_error(state->ctx, locp->position, err_str); + + if (err_str) { + _mesa_free(err_str); + } +} + + +GLboolean +_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, + GLsizei len, struct asm_parser_state *state) +{ + struct asm_instruction *inst; + unsigned i; + GLubyte *strz; + GLboolean result = GL_FALSE; + void *temp; + struct asm_symbol *sym; + + state->ctx = ctx; + state->prog->Target = target; + state->prog->Parameters = _mesa_new_parameter_list(); + + /* Make a copy of the program string and force it to be NUL-terminated. + */ + strz = (GLubyte *) _mesa_malloc(len + 1); + if (strz == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); + return GL_FALSE; + } + _mesa_memcpy (strz, str, len); + strz[len] = '\0'; + + state->prog->String = strz; + + state->st = _mesa_symbol_table_ctor(); + + state->limits = (target == GL_VERTEX_PROGRAM_ARB) + ? & ctx->Const.VertexProgram + : & ctx->Const.FragmentProgram; + + state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; + state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; + state->MaxTextureUnits = ctx->Const.MaxTextureUnits; + state->MaxClipPlanes = ctx->Const.MaxClipPlanes; + state->MaxLights = ctx->Const.MaxLights; + state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices; + + state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB) + ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM; + + _mesa_set_program_error(ctx, -1, NULL); + + _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len); + yyparse(state); + _mesa_program_lexer_dtor(state->scanner); + + + if (ctx->Program.ErrorPos != -1) { + goto error; + } + + if (! _mesa_layout_parameters(state)) { + struct YYLTYPE loc; + + loc.first_line = 0; + loc.first_column = 0; + loc.position = len; + + yyerror(& loc, state, "invalid PARAM usage"); + goto error; + } + + + + /* Add one instruction to store the "END" instruction. + */ + state->prog->Instructions = + _mesa_alloc_instructions(state->prog->NumInstructions + 1); + inst = state->inst_head; + for (i = 0; i < state->prog->NumInstructions; i++) { + struct asm_instruction *const temp = inst->next; + + state->prog->Instructions[i] = inst->Base; + inst = temp; + } + + /* Finally, tag on an OPCODE_END instruction */ + { + const GLuint numInst = state->prog->NumInstructions; + _mesa_init_instructions(state->prog->Instructions + numInst, 1); + state->prog->Instructions[numInst].Opcode = OPCODE_END; + } + state->prog->NumInstructions++; + + state->prog->NumParameters = state->prog->Parameters->NumParameters; + state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead); + + /* + * Initialize native counts to logical counts. The device driver may + * change them if program is translated into a hardware program. + */ + state->prog->NumNativeInstructions = state->prog->NumInstructions; + state->prog->NumNativeTemporaries = state->prog->NumTemporaries; + state->prog->NumNativeParameters = state->prog->NumParameters; + state->prog->NumNativeAttributes = state->prog->NumAttributes; + state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs; + + result = GL_TRUE; + +error: + for (inst = state->inst_head; inst != NULL; inst = temp) { + temp = inst->next; + _mesa_free(inst); + } + + state->inst_head = NULL; + state->inst_tail = NULL; + + for (sym = state->sym; sym != NULL; sym = temp) { + temp = sym->next; + + _mesa_free((void *) sym->name); + _mesa_free(sym); + } + state->sym = NULL; + + _mesa_symbol_table_dtor(state->st); + state->st = NULL; + + return result; +} + diff --git a/src/mesa/shader/program_parse.tab.h b/src/mesa/shader/program_parse.tab.h new file mode 100644 index 0000000000..de08fb747f --- /dev/null +++ b/src/mesa/shader/program_parse.tab.h @@ -0,0 +1,207 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ARBvp_10 = 258, + ARBfp_10 = 259, + ADDRESS = 260, + ALIAS = 261, + ATTRIB = 262, + OPTION = 263, + OUTPUT = 264, + PARAM = 265, + TEMP = 266, + END = 267, + BIN_OP = 268, + BINSC_OP = 269, + SAMPLE_OP = 270, + SCALAR_OP = 271, + TRI_OP = 272, + VECTOR_OP = 273, + ARL = 274, + KIL = 275, + SWZ = 276, + INTEGER = 277, + REAL = 278, + AMBIENT = 279, + ATTENUATION = 280, + BACK = 281, + CLIP = 282, + COLOR = 283, + DEPTH = 284, + DIFFUSE = 285, + DIRECTION = 286, + EMISSION = 287, + ENV = 288, + EYE = 289, + FOG = 290, + FOGCOORD = 291, + FRAGMENT = 292, + FRONT = 293, + HALF = 294, + INVERSE = 295, + INVTRANS = 296, + LIGHT = 297, + LIGHTMODEL = 298, + LIGHTPROD = 299, + LOCAL = 300, + MATERIAL = 301, + MAT_PROGRAM = 302, + MATRIX = 303, + MATRIXINDEX = 304, + MODELVIEW = 305, + MVP = 306, + NORMAL = 307, + OBJECT = 308, + PALETTE = 309, + PARAMS = 310, + PLANE = 311, + POINT = 312, + POINTSIZE = 313, + POSITION = 314, + PRIMARY = 315, + PROGRAM = 316, + PROJECTION = 317, + RANGE = 318, + RESULT = 319, + ROW = 320, + SCENECOLOR = 321, + SECONDARY = 322, + SHININESS = 323, + SIZE = 324, + SPECULAR = 325, + SPOT = 326, + STATE = 327, + TEXCOORD = 328, + TEXENV = 329, + TEXGEN = 330, + TEXGEN_Q = 331, + TEXGEN_R = 332, + TEXGEN_S = 333, + TEXGEN_T = 334, + TEXTURE = 335, + TRANSPOSE = 336, + TEXTURE_UNIT = 337, + TEX_1D = 338, + TEX_2D = 339, + TEX_3D = 340, + TEX_CUBE = 341, + TEX_RECT = 342, + TEX_SHADOW1D = 343, + TEX_SHADOW2D = 344, + TEX_SHADOWRECT = 345, + TEX_ARRAY1D = 346, + TEX_ARRAY2D = 347, + TEX_ARRAYSHADOW1D = 348, + TEX_ARRAYSHADOW2D = 349, + VERTEX = 350, + VTXATTRIB = 351, + WEIGHT = 352, + IDENTIFIER = 353, + MASK4 = 354, + MASK3 = 355, + MASK2 = 356, + MASK1 = 357, + SWIZZLE = 358, + DOT_DOT = 359, + DOT = 360 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 1676 of yacc.c */ +#line 107 "program_parse.y" + + struct asm_instruction *inst; + struct asm_symbol *sym; + struct asm_symbol temp_sym; + struct asm_swizzle_mask swiz_mask; + struct asm_src_register src_reg; + struct prog_dst_register dst_reg; + struct prog_instruction temp_inst; + char *string; + unsigned result; + unsigned attrib; + int integer; + float real; + unsigned state[5]; + int negate; + struct asm_vector vector; + gl_inst_opcode opcode; + + struct { + unsigned swz; + unsigned rgba_valid:1; + unsigned xyzw_valid:1; + unsigned negate:1; + } ext_swizzle; + + + +/* Line 1676 of yacc.c */ +#line 185 "program_parse.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + + diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y new file mode 100644 index 0000000000..e2e83e484f --- /dev/null +++ b/src/mesa/shader/program_parse.y @@ -0,0 +1,2380 @@ +%{ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "main/mtypes.h" +#include "main/imports.h" +#include "program.h" +#include "prog_parameter.h" +#include "prog_parameter_layout.h" +#include "prog_statevars.h" +#include "prog_instruction.h" + +#include "symbol_table.h" +#include "program_parser.h" + +extern void *yy_scan_string(char *); +extern void yy_delete_buffer(void *); + +static struct asm_symbol *declare_variable(struct asm_parser_state *state, + char *name, enum asm_type t, struct YYLTYPE *locp); + +static int add_state_reference(struct gl_program_parameter_list *param_list, + const gl_state_index tokens[STATE_LENGTH]); + +static int initialize_symbol_from_state(struct gl_program *prog, + struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]); + +static int initialize_symbol_from_param(struct gl_program *prog, + struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]); + +static int initialize_symbol_from_const(struct gl_program *prog, + struct asm_symbol *param_var, const struct asm_vector *vec); + +static int yyparse(struct asm_parser_state *state); + +static char *make_error_string(const char *fmt, ...); + +static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state, + const char *s); + +static int validate_inputs(struct YYLTYPE *locp, + struct asm_parser_state *state); + +static void init_dst_reg(struct prog_dst_register *r); + +static void init_src_reg(struct asm_src_register *r); + +static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op, + const struct prog_dst_register *dst, const struct asm_src_register *src0, + const struct asm_src_register *src1, const struct asm_src_register *src2); + +#ifndef FALSE +#define FALSE 0 +#define TRUE (!FALSE) +#endif + +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do { \ + if (YYID(N)) { \ + (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ + (Current).position = YYRHSLOC(Rhs, 1).position; \ + (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ + } else { \ + (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ + (Current).last_line = (Current).first_line; \ + (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \ + (Current).last_column = (Current).first_column; \ + (Current).position = YYRHSLOC(Rhs, 0).position \ + + (Current).first_column; \ + } \ + } while(YYID(0)) + +#define YYLEX_PARAM state->scanner +%} + +%pure-parser +%locations +%parse-param { struct asm_parser_state *state } +%error-verbose +%lex-param { void *scanner } + +%union { + struct asm_instruction *inst; + struct asm_symbol *sym; + struct asm_symbol temp_sym; + struct asm_swizzle_mask swiz_mask; + struct asm_src_register src_reg; + struct prog_dst_register dst_reg; + struct prog_instruction temp_inst; + char *string; + unsigned result; + unsigned attrib; + int integer; + float real; + unsigned state[5]; + int negate; + struct asm_vector vector; + gl_inst_opcode opcode; + + struct { + unsigned swz; + unsigned rgba_valid:1; + unsigned xyzw_valid:1; + unsigned negate:1; + } ext_swizzle; +} + +%token ARBvp_10 ARBfp_10 + +/* Tokens for assembler pseudo-ops */ +%token <integer> ADDRESS +%token ALIAS ATTRIB +%token OPTION OUTPUT +%token PARAM +%token <integer> TEMP +%token END + + /* Tokens for instructions */ +%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP +%token <temp_inst> ARL KIL SWZ + +%token <integer> INTEGER +%token <real> REAL + +%token AMBIENT ATTENUATION +%token BACK +%token CLIP COLOR +%token DEPTH DIFFUSE DIRECTION +%token EMISSION ENV EYE +%token FOG FOGCOORD FRAGMENT FRONT +%token HALF +%token INVERSE INVTRANS +%token LIGHT LIGHTMODEL LIGHTPROD LOCAL +%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP +%token NORMAL +%token OBJECT +%token PALETTE PARAMS PLANE POINT POINTSIZE POSITION PRIMARY PROGRAM PROJECTION +%token RANGE RESULT ROW +%token SCENECOLOR SECONDARY SHININESS SIZE SPECULAR SPOT STATE +%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE +%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT +%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT +%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D +%token VERTEX VTXATTRIB +%token WEIGHT + +%token <string> IDENTIFIER +%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE +%token DOT_DOT +%token DOT + +%type <inst> instruction ALU_instruction TexInstruction +%type <inst> ARL_instruction VECTORop_instruction +%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction +%type <inst> TRIop_instruction SWZ_instruction SAMPLE_instruction +%type <inst> KIL_instruction + +%type <dst_reg> dstReg maskedDstReg maskedAddrReg +%type <src_reg> srcReg scalarSrcReg swizzleSrcReg +%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle +%type <ext_swizzle> extSwizComp extSwizSel +%type <swiz_mask> optionalMask + +%type <sym> progParamArray +%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset +%type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel +%type <sym> addrReg +%type <swiz_mask> addrComponent addrWriteMask + +%type <result> resultBinding resultColBinding +%type <integer> optFaceType optColorType +%type <integer> optResultFaceType optResultColorType + +%type <integer> optTexImageUnitNum texImageUnitNum +%type <integer> optTexCoordUnitNum texCoordUnitNum +%type <integer> optLegacyTexUnitNum legacyTexUnitNum +%type <integer> texImageUnit texTarget +%type <integer> vtxAttribNum + +%type <attrib> attribBinding vtxAttribItem fragAttribItem + +%type <temp_sym> paramSingleInit paramSingleItemDecl +%type <integer> optArraySize + +%type <state> stateSingleItem stateMultipleItem +%type <state> stateMaterialItem +%type <state> stateLightItem stateLightModelItem stateLightProdItem +%type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem +%type <state> stateMatrixItem stateMatrixRow stateMatrixRows +%type <state> stateTexEnvItem stateDepthItem + +%type <state> stateLModProperty +%type <state> stateMatrixName optMatrixRows + +%type <integer> stateMatProperty +%type <integer> stateLightProperty stateSpotProperty +%type <integer> stateLightNumber stateLProdProperty +%type <integer> stateTexGenType stateTexGenCoord +%type <integer> stateTexEnvProperty +%type <integer> stateFogProperty +%type <integer> stateClipPlaneNum +%type <integer> statePointProperty + +%type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum +%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum +%type <integer> stateProgramMatNum + +%type <integer> ambDiffSpecProperty + +%type <state> programSingleItem progEnvParam progLocalParam +%type <state> programMultipleItem progEnvParams progLocalParams + +%type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem +%type <temp_sym> paramSingleItemUse + +%type <integer> progEnvParamNum progLocalParamNum +%type <state> progEnvParamNums progLocalParamNums + +%type <vector> paramConstDecl paramConstUse +%type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector +%type <real> signedFloatConstant +%type <negate> optionalSign + +%{ +extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, + void *yyscanner); +%} + +%% + +program: language optionSequence statementSequence END + ; + +language: ARBvp_10 + { + if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) { + yyerror(& @1, state, "invalid fragment program header"); + + } + state->mode = ARB_vertex; + } + | ARBfp_10 + { + if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) { + yyerror(& @1, state, "invalid vertex program header"); + } + state->mode = ARB_fragment; + + state->option.TexRect = + (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE); + } + ; + +optionSequence: optionSequence option + | + ; + +option: OPTION IDENTIFIER ';' + { + int valid = 0; + + if (state->mode == ARB_vertex) { + valid = _mesa_ARBvp_parse_option(state, $2); + } else if (state->mode == ARB_fragment) { + valid = _mesa_ARBfp_parse_option(state, $2); + } + + + if (!valid) { + const char *const err_str = (state->mode == ARB_vertex) + ? "invalid ARB vertex program option" + : "invalid ARB fragment program option"; + + yyerror(& @2, state, err_str); + YYERROR; + } + } + ; + +statementSequence: statementSequence statement + | + ; + +statement: instruction ';' + { + if ($1 != NULL) { + if (state->inst_tail == NULL) { + state->inst_head = $1; + } else { + state->inst_tail->next = $1; + } + + state->inst_tail = $1; + $1->next = NULL; + + state->prog->NumInstructions++; + } + } + | namingStatement ';' + ; + +instruction: ALU_instruction + { + $$ = $1; + state->prog->NumAluInstructions++; + } + | TexInstruction + { + $$ = $1; + state->prog->NumTexInstructions++; + } + ; + +ALU_instruction: ARL_instruction + | VECTORop_instruction + | SCALARop_instruction + | BINSCop_instruction + | BINop_instruction + | TRIop_instruction + | SWZ_instruction + ; + +TexInstruction: SAMPLE_instruction + | KIL_instruction + ; + +ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg + { + $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL); + } + ; + +VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg + { + $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL); + $$->Base.SaturateMode = $1.SaturateMode; + } + ; + +SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg + { + $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL); + $$->Base.SaturateMode = $1.SaturateMode; + } + ; + +BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg + { + $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL); + $$->Base.SaturateMode = $1.SaturateMode; + } + ; + + +BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg + { + $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL); + $$->Base.SaturateMode = $1.SaturateMode; + } + ; + +TRIop_instruction: TRI_OP maskedDstReg ',' + swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg + { + $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, & $8); + $$->Base.SaturateMode = $1.SaturateMode; + } + ; + +SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget + { + $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL); + if ($$ != NULL) { + const GLbitfield tex_mask = (1U << $6); + GLbitfield shadow_tex = 0; + GLbitfield target_mask = 0; + + + $$->Base.SaturateMode = $1.SaturateMode; + $$->Base.TexSrcUnit = $6; + + if ($8 < 0) { + shadow_tex = tex_mask; + + $$->Base.TexSrcTarget = -$8; + $$->Base.TexShadow = 1; + } else { + $$->Base.TexSrcTarget = $8; + } + + target_mask = (1U << $$->Base.TexSrcTarget); + + /* If this texture unit was previously accessed and that access + * had a different texture target, generate an error. + * + * If this texture unit was previously accessed and that access + * had a different shadow mode, generate an error. + */ + if ((state->prog->TexturesUsed[$6] != 0) + && ((state->prog->TexturesUsed[$6] != target_mask) + || ((state->prog->ShadowSamplers & tex_mask) + != shadow_tex))) { + yyerror(& @8, state, + "multiple targets used on one texture image unit"); + YYERROR; + } + + + state->prog->TexturesUsed[$6] |= target_mask; + state->prog->ShadowSamplers |= shadow_tex; + } + } + ; + +KIL_instruction: KIL swizzleSrcReg + { + $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL); + state->fragment.UsesKill = 1; + } + ; + +texImageUnit: TEXTURE_UNIT optTexImageUnitNum + { + $$ = $2; + } + ; + +texTarget: TEX_1D { $$ = TEXTURE_1D_INDEX; } + | TEX_2D { $$ = TEXTURE_2D_INDEX; } + | TEX_3D { $$ = TEXTURE_3D_INDEX; } + | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; } + | TEX_RECT { $$ = TEXTURE_RECT_INDEX; } + | TEX_SHADOW1D { $$ = -TEXTURE_1D_INDEX; } + | TEX_SHADOW2D { $$ = -TEXTURE_2D_INDEX; } + | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; } + | TEX_ARRAY1D { $$ = TEXTURE_1D_ARRAY_INDEX; } + | TEX_ARRAY2D { $$ = TEXTURE_2D_ARRAY_INDEX; } + | TEX_ARRAYSHADOW1D { $$ = -TEXTURE_1D_ARRAY_INDEX; } + | TEX_ARRAYSHADOW2D { $$ = -TEXTURE_2D_ARRAY_INDEX; } + ; + +SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle + { + /* FIXME: Is this correct? Should the extenedSwizzle be applied + * FIXME: to the existing swizzle? + */ + $4.Base.Swizzle = $6.swizzle; + $4.Base.Negate = $6.mask; + + $$ = asm_instruction_ctor(OPCODE_SWZ, & $2, & $4, NULL, NULL); + $$->Base.SaturateMode = $1.SaturateMode; + } + ; + +scalarSrcReg: optionalSign srcReg scalarSuffix + { + $$ = $2; + + if ($1) { + $$.Base.Negate = ~$$.Base.Negate; + } + + $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle, + $3.swizzle); + } + ; + +swizzleSrcReg: optionalSign srcReg swizzleSuffix + { + $$ = $2; + + if ($1) { + $$.Base.Negate = ~$$.Base.Negate; + } + + $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle, + $3.swizzle); + } + ; + +maskedDstReg: dstReg optionalMask + { + $$ = $1; + $$.WriteMask = $2.mask; + + if ($$.File == PROGRAM_OUTPUT) { + /* Technically speaking, this should check that it is in + * vertex program mode. However, PositionInvariant can never be + * set in fragment program mode, so it is somewhat irrelevant. + */ + if (state->option.PositionInvariant + && ($$.Index == VERT_RESULT_HPOS)) { + yyerror(& @1, state, "position-invariant programs cannot " + "write position"); + YYERROR; + } + + state->prog->OutputsWritten |= (1U << $$.Index); + } + } + ; + +maskedAddrReg: addrReg addrWriteMask + { + init_dst_reg(& $$); + $$.File = PROGRAM_ADDRESS; + $$.Index = 0; + $$.WriteMask = $2.mask; + } + ; + +extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp + { + const unsigned xyzw_valid = + ($1.xyzw_valid << 0) + | ($3.xyzw_valid << 1) + | ($5.xyzw_valid << 2) + | ($7.xyzw_valid << 3); + const unsigned rgba_valid = + ($1.rgba_valid << 0) + | ($3.rgba_valid << 1) + | ($5.rgba_valid << 2) + | ($7.rgba_valid << 3); + + /* All of the swizzle components have to be valid in either RGBA + * or XYZW. Note that 0 and 1 are valid in both, so both masks + * can have some bits set. + * + * We somewhat deviate from the spec here. It would be really hard + * to figure out which component is the error, and there probably + * isn't a lot of benefit. + */ + if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) { + yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle " + "components"); + YYERROR; + } + + $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz); + $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2) + | ($7.negate << 3); + } + ; + +extSwizComp: optionalSign extSwizSel + { + $$ = $2; + $$.negate = ($1) ? 1 : 0; + } + ; + +extSwizSel: INTEGER + { + if (($1 != 0) && ($1 != 1)) { + yyerror(& @1, state, "invalid extended swizzle selector"); + YYERROR; + } + + $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE; + + /* 0 and 1 are valid for both RGBA swizzle names and XYZW + * swizzle names. + */ + $$.xyzw_valid = 1; + $$.rgba_valid = 1; + } + | IDENTIFIER + { + if (strlen($1) > 1) { + yyerror(& @1, state, "invalid extended swizzle selector"); + YYERROR; + } + + switch ($1[0]) { + case 'x': + $$.swz = SWIZZLE_X; + $$.xyzw_valid = 1; + break; + case 'y': + $$.swz = SWIZZLE_Y; + $$.xyzw_valid = 1; + break; + case 'z': + $$.swz = SWIZZLE_Z; + $$.xyzw_valid = 1; + break; + case 'w': + $$.swz = SWIZZLE_W; + $$.xyzw_valid = 1; + break; + + case 'r': + $$.swz = SWIZZLE_X; + $$.rgba_valid = 1; + break; + case 'g': + $$.swz = SWIZZLE_Y; + $$.rgba_valid = 1; + break; + case 'b': + $$.swz = SWIZZLE_Z; + $$.rgba_valid = 1; + break; + case 'a': + $$.swz = SWIZZLE_W; + $$.rgba_valid = 1; + break; + + default: + yyerror(& @1, state, "invalid extended swizzle selector"); + YYERROR; + break; + } + } + ; + +srcReg: IDENTIFIER /* temporaryReg | progParamSingle */ + { + struct asm_symbol *const s = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, $1); + + if (s == NULL) { + yyerror(& @1, state, "invalid operand variable"); + YYERROR; + } else if ((s->type != at_param) && (s->type != at_temp) + && (s->type != at_attrib)) { + yyerror(& @1, state, "invalid operand variable"); + YYERROR; + } else if ((s->type == at_param) && s->param_is_array) { + yyerror(& @1, state, "non-array access to array PARAM"); + YYERROR; + } + + init_src_reg(& $$); + switch (s->type) { + case at_temp: + $$.Base.File = PROGRAM_TEMPORARY; + $$.Base.Index = s->temp_binding; + break; + case at_param: + $$.Base.File = s->param_binding_type; + $$.Base.Index = s->param_binding_begin; + break; + case at_attrib: + $$.Base.File = PROGRAM_INPUT; + $$.Base.Index = s->attrib_binding; + state->prog->InputsRead |= (1U << $$.Base.Index); + + if (!validate_inputs(& @1, state)) { + YYERROR; + } + break; + + default: + YYERROR; + break; + } + } + | attribBinding + { + init_src_reg(& $$); + $$.Base.File = PROGRAM_INPUT; + $$.Base.Index = $1; + state->prog->InputsRead |= (1U << $$.Base.Index); + + if (!validate_inputs(& @1, state)) { + YYERROR; + } + } + | progParamArray '[' progParamArrayMem ']' + { + if (! $3.Base.RelAddr + && ((unsigned) $3.Base.Index >= $1->param_binding_length)) { + yyerror(& @3, state, "out of bounds array access"); + YYERROR; + } + + init_src_reg(& $$); + $$.Base.File = $1->param_binding_type; + + if ($3.Base.RelAddr) { + $1->param_accessed_indirectly = 1; + + $$.Base.RelAddr = 1; + $$.Base.Index = $3.Base.Index; + $$.Symbol = $1; + } else { + $$.Base.Index = $1->param_binding_begin + $3.Base.Index; + } + } + | paramSingleItemUse + { + init_src_reg(& $$); + $$.Base.File = ($1.name != NULL) + ? $1.param_binding_type + : PROGRAM_CONSTANT; + $$.Base.Index = $1.param_binding_begin; + } + ; + +dstReg: resultBinding + { + init_dst_reg(& $$); + $$.File = PROGRAM_OUTPUT; + $$.Index = $1; + } + | IDENTIFIER /* temporaryReg | vertexResultReg */ + { + struct asm_symbol *const s = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, $1); + + if (s == NULL) { + yyerror(& @1, state, "invalid operand variable"); + YYERROR; + } else if ((s->type != at_output) && (s->type != at_temp)) { + yyerror(& @1, state, "invalid operand variable"); + YYERROR; + } + + init_dst_reg(& $$); + switch (s->type) { + case at_temp: + $$.File = PROGRAM_TEMPORARY; + $$.Index = s->temp_binding; + break; + case at_output: + $$.File = PROGRAM_OUTPUT; + $$.Index = s->output_binding; + break; + default: + $$.File = s->param_binding_type; + $$.Index = s->param_binding_begin; + break; + } + } + ; + +progParamArray: IDENTIFIER + { + struct asm_symbol *const s = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, $1); + + if (s == NULL) { + yyerror(& @1, state, "invalid operand variable"); + YYERROR; + } else if ((s->type != at_param) || !s->param_is_array) { + yyerror(& @1, state, "array access to non-PARAM variable"); + YYERROR; + } else { + $$ = s; + } + } + ; + +progParamArrayMem: progParamArrayAbs | progParamArrayRel; + +progParamArrayAbs: INTEGER + { + init_src_reg(& $$); + $$.Base.Index = $1; + } + ; + +progParamArrayRel: addrReg addrComponent addrRegRelOffset + { + /* FINISHME: Add support for multiple address registers. + */ + /* FINISHME: Add support for 4-component address registers. + */ + init_src_reg(& $$); + $$.Base.RelAddr = 1; + $$.Base.Index = $3; + } + ; + +addrRegRelOffset: { $$ = 0; } + | '+' addrRegPosOffset { $$ = $2; } + | '-' addrRegNegOffset { $$ = -$2; } + ; + +addrRegPosOffset: INTEGER + { + if (($1 < 0) || ($1 > 63)) { + yyerror(& @1, state, + "relative address offset too large (positive)"); + YYERROR; + } else { + $$ = $1; + } + } + ; + +addrRegNegOffset: INTEGER + { + if (($1 < 0) || ($1 > 64)) { + yyerror(& @1, state, + "relative address offset too large (negative)"); + YYERROR; + } else { + $$ = $1; + } + } + ; + +addrReg: IDENTIFIER + { + struct asm_symbol *const s = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, $1); + + if (s == NULL) { + yyerror(& @1, state, "invalid array member"); + YYERROR; + } else if (s->type != at_address) { + yyerror(& @1, state, + "invalid variable for indexed array access"); + YYERROR; + } else { + $$ = s; + } + } + ; + +addrComponent: MASK1 + { + if ($1.mask != WRITEMASK_X) { + yyerror(& @1, state, "invalid address component selector"); + YYERROR; + } else { + $$ = $1; + } + } + ; + +addrWriteMask: MASK1 + { + if ($1.mask != WRITEMASK_X) { + yyerror(& @1, state, + "address register write mask must be \".x\""); + YYERROR; + } else { + $$ = $1; + } + } + ; + +scalarSuffix: MASK1; + +swizzleSuffix: MASK1 + | MASK4 + | SWIZZLE + | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; } + ; + +optionalMask: MASK4 | MASK3 | MASK2 | MASK1 + | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; } + ; + +namingStatement: ATTRIB_statement + | PARAM_statement + | TEMP_statement + | ADDRESS_statement + | OUTPUT_statement + | ALIAS_statement + ; + +ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding + { + struct asm_symbol *const s = + declare_variable(state, $2, at_attrib, & @2); + + if (s == NULL) { + YYERROR; + } else { + s->attrib_binding = $4; + state->InputsBound |= (1U << s->attrib_binding); + + if (!validate_inputs(& @4, state)) { + YYERROR; + } + } + } + ; + +attribBinding: VERTEX vtxAttribItem + { + $$ = $2; + } + | FRAGMENT fragAttribItem + { + $$ = $2; + } + ; + +vtxAttribItem: POSITION + { + $$ = VERT_ATTRIB_POS; + } + | WEIGHT vtxOptWeightNum + { + $$ = VERT_ATTRIB_WEIGHT; + } + | NORMAL + { + $$ = VERT_ATTRIB_NORMAL; + } + | COLOR optColorType + { + if (!state->ctx->Extensions.EXT_secondary_color) { + yyerror(& @2, state, "GL_EXT_secondary_color not supported"); + YYERROR; + } + + $$ = VERT_ATTRIB_COLOR0 + $2; + } + | FOGCOORD + { + if (!state->ctx->Extensions.EXT_fog_coord) { + yyerror(& @1, state, "GL_EXT_fog_coord not supported"); + YYERROR; + } + + $$ = VERT_ATTRIB_FOG; + } + | TEXCOORD optTexCoordUnitNum + { + $$ = VERT_ATTRIB_TEX0 + $2; + } + | MATRIXINDEX '[' vtxWeightNum ']' + { + yyerror(& @1, state, "GL_ARB_matrix_palette not supported"); + YYERROR; + } + | VTXATTRIB '[' vtxAttribNum ']' + { + $$ = VERT_ATTRIB_GENERIC0 + $3; + } + ; + +vtxAttribNum: INTEGER + { + if ((unsigned) $1 >= state->limits->MaxAttribs) { + yyerror(& @1, state, "invalid vertex attribute reference"); + YYERROR; + } + + $$ = $1; + } + ; + +vtxOptWeightNum: | '[' vtxWeightNum ']'; +vtxWeightNum: INTEGER; + +fragAttribItem: POSITION + { + $$ = FRAG_ATTRIB_WPOS; + } + | COLOR optColorType + { + $$ = FRAG_ATTRIB_COL0 + $2; + } + | FOGCOORD + { + $$ = FRAG_ATTRIB_FOGC; + } + | TEXCOORD optTexCoordUnitNum + { + $$ = FRAG_ATTRIB_TEX0 + $2; + } + ; + +PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt; + +PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit + { + struct asm_symbol *const s = + declare_variable(state, $2, at_param, & @2); + + if (s == NULL) { + YYERROR; + } else { + s->param_binding_type = $3.param_binding_type; + s->param_binding_begin = $3.param_binding_begin; + s->param_binding_length = $3.param_binding_length; + s->param_is_array = 0; + } + } + ; + +PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit + { + if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) { + yyerror(& @4, state, + "parameter array size and number of bindings must match"); + YYERROR; + } else { + struct asm_symbol *const s = + declare_variable(state, $2, $6.type, & @2); + + if (s == NULL) { + YYERROR; + } else { + s->param_binding_type = $6.param_binding_type; + s->param_binding_begin = $6.param_binding_begin; + s->param_binding_length = $6.param_binding_length; + s->param_is_array = 1; + } + } + } + ; + +optArraySize: + { + $$ = 0; + } + | INTEGER + { + if (($1 < 1) || ((unsigned) $1 >= state->limits->MaxParameters)) { + yyerror(& @1, state, "invalid parameter array size"); + YYERROR; + } else { + $$ = $1; + } + } + ; + +paramSingleInit: '=' paramSingleItemDecl + { + $$ = $2; + } + ; + +paramMultipleInit: '=' '{' paramMultInitList '}' + { + $$ = $3; + } + ; + +paramMultInitList: paramMultipleItem + | paramMultInitList ',' paramMultipleItem + { + $1.param_binding_length += $3.param_binding_length; + $$ = $1; + } + ; + +paramSingleItemDecl: stateSingleItem + { + memset(& $$, 0, sizeof($$)); + $$.param_binding_begin = ~0; + initialize_symbol_from_state(state->prog, & $$, $1); + } + | programSingleItem + { + memset(& $$, 0, sizeof($$)); + $$.param_binding_begin = ~0; + initialize_symbol_from_param(state->prog, & $$, $1); + } + | paramConstDecl + { + memset(& $$, 0, sizeof($$)); + $$.param_binding_begin = ~0; + initialize_symbol_from_const(state->prog, & $$, & $1); + } + ; + +paramSingleItemUse: stateSingleItem + { + memset(& $$, 0, sizeof($$)); + $$.param_binding_begin = ~0; + initialize_symbol_from_state(state->prog, & $$, $1); + } + | programSingleItem + { + memset(& $$, 0, sizeof($$)); + $$.param_binding_begin = ~0; + initialize_symbol_from_param(state->prog, & $$, $1); + } + | paramConstUse + { + memset(& $$, 0, sizeof($$)); + $$.param_binding_begin = ~0; + initialize_symbol_from_const(state->prog, & $$, & $1); + } + ; + +paramMultipleItem: stateMultipleItem + { + memset(& $$, 0, sizeof($$)); + $$.param_binding_begin = ~0; + initialize_symbol_from_state(state->prog, & $$, $1); + } + | programMultipleItem + { + memset(& $$, 0, sizeof($$)); + $$.param_binding_begin = ~0; + initialize_symbol_from_param(state->prog, & $$, $1); + } + | paramConstDecl + { + memset(& $$, 0, sizeof($$)); + $$.param_binding_begin = ~0; + initialize_symbol_from_const(state->prog, & $$, & $1); + } + ; + +stateMultipleItem: stateSingleItem { memcpy($$, $1, sizeof($$)); } + | STATE stateMatrixRows { memcpy($$, $2, sizeof($$)); } + ; + +stateSingleItem: STATE stateMaterialItem { memcpy($$, $2, sizeof($$)); } + | STATE stateLightItem { memcpy($$, $2, sizeof($$)); } + | STATE stateLightModelItem { memcpy($$, $2, sizeof($$)); } + | STATE stateLightProdItem { memcpy($$, $2, sizeof($$)); } + | STATE stateTexGenItem { memcpy($$, $2, sizeof($$)); } + | STATE stateTexEnvItem { memcpy($$, $2, sizeof($$)); } + | STATE stateFogItem { memcpy($$, $2, sizeof($$)); } + | STATE stateClipPlaneItem { memcpy($$, $2, sizeof($$)); } + | STATE statePointItem { memcpy($$, $2, sizeof($$)); } + | STATE stateMatrixRow { memcpy($$, $2, sizeof($$)); } + | STATE stateDepthItem { memcpy($$, $2, sizeof($$)); } + ; + +stateMaterialItem: MATERIAL optFaceType stateMatProperty + { + memset($$, 0, sizeof($$)); + $$[0] = STATE_MATERIAL; + $$[1] = $2; + $$[2] = $3; + } + ; + +stateMatProperty: ambDiffSpecProperty + { + $$ = $1; + } + | EMISSION + { + $$ = STATE_EMISSION; + } + | SHININESS + { + $$ = STATE_SHININESS; + } + ; + +stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty + { + memset($$, 0, sizeof($$)); + $$[0] = STATE_LIGHT; + $$[1] = $3; + $$[2] = $5; + } + ; + +stateLightProperty: ambDiffSpecProperty + { + $$ = $1; + } + | POSITION + { + $$ = STATE_POSITION; + } + | ATTENUATION + { + if (!state->ctx->Extensions.EXT_point_parameters) { + yyerror(& @1, state, "GL_ARB_point_parameters not supported"); + YYERROR; + } + + $$ = STATE_ATTENUATION; + } + | SPOT stateSpotProperty + { + $$ = $2; + } + | HALF + { + $$ = STATE_HALF_VECTOR; + } + ; + +stateSpotProperty: DIRECTION + { + $$ = STATE_SPOT_DIRECTION; + } + ; + +stateLightModelItem: LIGHTMODEL stateLModProperty + { + $$[0] = $2[0]; + $$[1] = $2[1]; + } + ; + +stateLModProperty: AMBIENT + { + memset($$, 0, sizeof($$)); + $$[0] = STATE_LIGHTMODEL_AMBIENT; + } + | optFaceType SCENECOLOR + { + memset($$, 0, sizeof($$)); + $$[0] = STATE_LIGHTMODEL_SCENECOLOR; + $$[1] = $1; + } + ; + +stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty + { + memset($$, 0, sizeof($$)); + $$[0] = STATE_LIGHTPROD; + $$[1] = $3; + $$[2] = $5; + $$[3] = $6; + } + ; + +stateLProdProperty: ambDiffSpecProperty; + +stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty + { + memset($$, 0, sizeof($$)); + $$[0] = $3; + $$[1] = $2; + } + ; + +stateTexEnvProperty: COLOR + { + $$ = STATE_TEXENV_COLOR; + } + ; + +ambDiffSpecProperty: AMBIENT + { + $$ = STATE_AMBIENT; + } + | DIFFUSE + { + $$ = STATE_DIFFUSE; + } + | SPECULAR + { + $$ = STATE_SPECULAR; + } + ; + +stateLightNumber: INTEGER + { + if ((unsigned) $1 >= state->MaxLights) { + yyerror(& @1, state, "invalid light selector"); + YYERROR; + } + + $$ = $1; + } + ; + +stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord + { + memset($$, 0, sizeof($$)); + $$[0] = STATE_TEXGEN; + $$[1] = $2; + $$[2] = $3 + $4; + } + ; + +stateTexGenType: EYE + { + $$ = STATE_TEXGEN_EYE_S; + } + | OBJECT + { + $$ = STATE_TEXGEN_OBJECT_S; + } + ; +stateTexGenCoord: TEXGEN_S + { + $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S; + } + | TEXGEN_T + { + $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S; + } + | TEXGEN_R + { + $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S; + } + | TEXGEN_Q + { + $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S; + } + ; + +stateFogItem: FOG stateFogProperty + { + memset($$, 0, sizeof($$)); + $$[0] = $2; + } + ; + +stateFogProperty: COLOR + { + $$ = STATE_FOG_COLOR; + } + | PARAMS + { + $$ = STATE_FOG_PARAMS; + } + ; + +stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE + { + memset($$, 0, sizeof($$)); + $$[0] = STATE_CLIPPLANE; + $$[1] = $3; + } + ; + +stateClipPlaneNum: INTEGER + { + if ((unsigned) $1 >= state->MaxClipPlanes) { + yyerror(& @1, state, "invalid clip plane selector"); + YYERROR; + } + + $$ = $1; + } + ; + +statePointItem: POINT statePointProperty + { + memset($$, 0, sizeof($$)); + $$[0] = $2; + } + ; + +statePointProperty: SIZE + { + $$ = STATE_POINT_SIZE; + } + | ATTENUATION + { + $$ = STATE_POINT_ATTENUATION; + } + ; + +stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']' + { + $$[0] = $1[0]; + $$[1] = $1[1]; + $$[2] = $4; + $$[3] = $4; + $$[4] = $1[2]; + } + ; + +stateMatrixRows: stateMatrixItem optMatrixRows + { + $$[0] = $1[0]; + $$[1] = $1[1]; + $$[2] = $2[2]; + $$[3] = $2[3]; + $$[4] = $1[2]; + } + ; + +optMatrixRows: + { + $$[2] = 0; + $$[3] = 3; + } + | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']' + { + /* It seems logical that the matrix row range specifier would have + * to specify a range or more than one row (i.e., $5 > $3). + * However, the ARB_vertex_program spec says "a program will fail + * to load if <a> is greater than <b>." This means that $3 == $5 + * is valid. + */ + if ($3 > $5) { + yyerror(& @3, state, "invalid matrix row range"); + YYERROR; + } + + $$[2] = $3; + $$[3] = $5; + } + ; + +stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier + { + $$[0] = $2[0]; + $$[1] = $2[1]; + $$[2] = $3; + } + ; + +stateOptMatModifier: + { + $$ = 0; + } + | stateMatModifier + { + $$ = $1; + } + ; + +stateMatModifier: INVERSE + { + $$ = STATE_MATRIX_INVERSE; + } + | TRANSPOSE + { + $$ = STATE_MATRIX_TRANSPOSE; + } + | INVTRANS + { + $$ = STATE_MATRIX_INVTRANS; + } + ; + +stateMatrixRowNum: INTEGER + { + if ($1 > 3) { + yyerror(& @1, state, "invalid matrix row reference"); + YYERROR; + } + + $$ = $1; + } + ; + +stateMatrixName: MODELVIEW stateOptModMatNum + { + $$[0] = STATE_MODELVIEW_MATRIX; + $$[1] = $2; + } + | PROJECTION + { + $$[0] = STATE_PROJECTION_MATRIX; + $$[1] = 0; + } + | MVP + { + $$[0] = STATE_MVP_MATRIX; + $$[1] = 0; + } + | TEXTURE optTexCoordUnitNum + { + $$[0] = STATE_TEXTURE_MATRIX; + $$[1] = $2; + } + | PALETTE '[' statePaletteMatNum ']' + { + yyerror(& @1, state, "GL_ARB_matrix_palette not supported"); + YYERROR; + } + | MAT_PROGRAM '[' stateProgramMatNum ']' + { + $$[0] = STATE_PROGRAM_MATRIX; + $$[1] = $3; + } + ; + +stateOptModMatNum: + { + $$ = 0; + } + | stateModMatNum + { + $$ = $1; + } + ; +stateModMatNum: INTEGER + { + /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix + * zero is valid. + */ + if ($1 != 0) { + yyerror(& @1, state, "invalid modelview matrix index"); + YYERROR; + } + + $$ = $1; + } + ; +statePaletteMatNum: INTEGER + { + /* Since GL_ARB_matrix_palette isn't supported, just let any value + * through here. The error will be generated later. + */ + $$ = $1; + } + ; +stateProgramMatNum: INTEGER + { + if ((unsigned) $1 >= state->MaxProgramMatrices) { + yyerror(& @1, state, "invalid program matrix selector"); + YYERROR; + } + + $$ = $1; + } + ; + +stateDepthItem: DEPTH RANGE + { + memset($$, 0, sizeof($$)); + $$[0] = STATE_DEPTH_RANGE; + } + ; + + +programSingleItem: progEnvParam | progLocalParam; + +programMultipleItem: progEnvParams | progLocalParams; + +progEnvParams: PROGRAM ENV '[' progEnvParamNums ']' + { + memset($$, 0, sizeof($$)); + $$[0] = state->state_param_enum; + $$[1] = STATE_ENV; + $$[2] = $4[0]; + $$[3] = $4[1]; + } + ; + +progEnvParamNums: progEnvParamNum + { + $$[0] = $1; + $$[1] = $1; + } + | progEnvParamNum DOT_DOT progEnvParamNum + { + $$[0] = $1; + $$[1] = $3; + } + ; + +progEnvParam: PROGRAM ENV '[' progEnvParamNum ']' + { + memset($$, 0, sizeof($$)); + $$[0] = state->state_param_enum; + $$[1] = STATE_ENV; + $$[2] = $4; + $$[3] = $4; + } + ; + +progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']' + { + memset($$, 0, sizeof($$)); + $$[0] = state->state_param_enum; + $$[1] = STATE_LOCAL; + $$[2] = $4[0]; + $$[3] = $4[1]; + } + +progLocalParamNums: progLocalParamNum + { + $$[0] = $1; + $$[1] = $1; + } + | progLocalParamNum DOT_DOT progLocalParamNum + { + $$[0] = $1; + $$[1] = $3; + } + ; + +progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']' + { + memset($$, 0, sizeof($$)); + $$[0] = state->state_param_enum; + $$[1] = STATE_LOCAL; + $$[2] = $4; + $$[3] = $4; + } + ; + +progEnvParamNum: INTEGER + { + if ((unsigned) $1 >= state->limits->MaxEnvParams) { + yyerror(& @1, state, "invalid environment parameter reference"); + YYERROR; + } + $$ = $1; + } + ; + +progLocalParamNum: INTEGER + { + if ((unsigned) $1 >= state->limits->MaxLocalParams) { + yyerror(& @1, state, "invalid local parameter reference"); + YYERROR; + } + $$ = $1; + } + ; + + + +paramConstDecl: paramConstScalarDecl | paramConstVector; +paramConstUse: paramConstScalarUse | paramConstVector; + +paramConstScalarDecl: signedFloatConstant + { + $$.count = 4; + $$.data[0] = $1; + $$.data[1] = $1; + $$.data[2] = $1; + $$.data[3] = $1; + } + ; + +paramConstScalarUse: REAL + { + $$.count = 1; + $$.data[0] = $1; + $$.data[1] = $1; + $$.data[2] = $1; + $$.data[3] = $1; + } + | INTEGER + { + $$.count = 1; + $$.data[0] = (float) $1; + $$.data[1] = (float) $1; + $$.data[2] = (float) $1; + $$.data[3] = (float) $1; + } + ; + +paramConstVector: '{' signedFloatConstant '}' + { + $$.count = 4; + $$.data[0] = $2; + $$.data[1] = 0.0f; + $$.data[2] = 0.0f; + $$.data[3] = 1.0f; + } + | '{' signedFloatConstant ',' signedFloatConstant '}' + { + $$.count = 4; + $$.data[0] = $2; + $$.data[1] = $4; + $$.data[2] = 0.0f; + $$.data[3] = 1.0f; + } + | '{' signedFloatConstant ',' signedFloatConstant ',' + signedFloatConstant '}' + { + $$.count = 4; + $$.data[0] = $2; + $$.data[1] = $4; + $$.data[2] = $6; + $$.data[3] = 1.0f; + } + | '{' signedFloatConstant ',' signedFloatConstant ',' + signedFloatConstant ',' signedFloatConstant '}' + { + $$.count = 4; + $$.data[0] = $2; + $$.data[1] = $4; + $$.data[2] = $6; + $$.data[3] = $8; + } + ; + +signedFloatConstant: optionalSign REAL + { + $$ = ($1) ? -$2 : $2; + } + | optionalSign INTEGER + { + $$ = (float)(($1) ? -$2 : $2); + } + ; + +optionalSign: '+' { $$ = FALSE; } + | '-' { $$ = TRUE; } + | { $$ = FALSE; } + ; + +TEMP_statement: TEMP { $<integer>$ = $1; } varNameList + ; + +ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList + ; + +varNameList: varNameList ',' IDENTIFIER + { + if (!declare_variable(state, $3, $<integer>0, & @3)) { + YYERROR; + } + } + | IDENTIFIER + { + if (!declare_variable(state, $1, $<integer>0, & @1)) { + YYERROR; + } + } + ; + +OUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding + { + struct asm_symbol *const s = + declare_variable(state, $2, at_output, & @2); + + if (s == NULL) { + YYERROR; + } else { + s->output_binding = $4; + } + } + ; + +resultBinding: RESULT POSITION + { + if (state->mode == ARB_vertex) { + $$ = VERT_RESULT_HPOS; + } else { + yyerror(& @2, state, "invalid program result name"); + YYERROR; + } + } + | RESULT FOGCOORD + { + if (state->mode == ARB_vertex) { + $$ = VERT_RESULT_FOGC; + } else { + yyerror(& @2, state, "invalid program result name"); + YYERROR; + } + } + | RESULT resultColBinding + { + $$ = $2; + } + | RESULT POINTSIZE + { + if (state->mode == ARB_vertex) { + $$ = VERT_RESULT_PSIZ; + } else { + yyerror(& @2, state, "invalid program result name"); + YYERROR; + } + } + | RESULT TEXCOORD optTexCoordUnitNum + { + if (state->mode == ARB_vertex) { + $$ = VERT_RESULT_TEX0 + $3; + } else { + yyerror(& @2, state, "invalid program result name"); + YYERROR; + } + } + | RESULT DEPTH + { + if (state->mode == ARB_fragment) { + $$ = FRAG_RESULT_DEPTH; + } else { + yyerror(& @2, state, "invalid program result name"); + YYERROR; + } + } + ; + +resultColBinding: COLOR optResultFaceType optResultColorType + { + $$ = $2 + $3; + } + ; + +optResultFaceType: + { + $$ = (state->mode == ARB_vertex) + ? VERT_RESULT_COL0 + : FRAG_RESULT_COLOR; + } + | FRONT + { + if (state->mode == ARB_vertex) { + $$ = VERT_RESULT_COL0; + } else { + yyerror(& @1, state, "invalid program result name"); + YYERROR; + } + } + | BACK + { + if (state->mode == ARB_vertex) { + $$ = VERT_RESULT_BFC0; + } else { + yyerror(& @1, state, "invalid program result name"); + YYERROR; + } + } + ; + +optResultColorType: + { + $$ = 0; + } + | PRIMARY + { + if (state->mode == ARB_vertex) { + $$ = 0; + } else { + yyerror(& @1, state, "invalid program result name"); + YYERROR; + } + } + | SECONDARY + { + if (state->mode == ARB_vertex) { + $$ = 1; + } else { + yyerror(& @1, state, "invalid program result name"); + YYERROR; + } + } + ; + +optFaceType: { $$ = 0; } + | FRONT { $$ = 0; } + | BACK { $$ = 1; } + ; + +optColorType: { $$ = 0; } + | PRIMARY { $$ = 0; } + | SECONDARY { $$ = 1; } + ; + +optTexCoordUnitNum: { $$ = 0; } + | '[' texCoordUnitNum ']' { $$ = $2; } + ; + +optTexImageUnitNum: { $$ = 0; } + | '[' texImageUnitNum ']' { $$ = $2; } + ; + +optLegacyTexUnitNum: { $$ = 0; } + | '[' legacyTexUnitNum ']' { $$ = $2; } + ; + +texCoordUnitNum: INTEGER + { + if ((unsigned) $1 >= state->MaxTextureCoordUnits) { + yyerror(& @1, state, "invalid texture coordinate unit selector"); + YYERROR; + } + + $$ = $1; + } + ; + +texImageUnitNum: INTEGER + { + if ((unsigned) $1 >= state->MaxTextureImageUnits) { + yyerror(& @1, state, "invalid texture image unit selector"); + YYERROR; + } + + $$ = $1; + } + ; + +legacyTexUnitNum: INTEGER + { + if ((unsigned) $1 >= state->MaxTextureUnits) { + yyerror(& @1, state, "invalid texture unit selector"); + YYERROR; + } + + $$ = $1; + } + ; + +ALIAS_statement: ALIAS IDENTIFIER '=' IDENTIFIER + { + struct asm_symbol *exist = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, $2); + struct asm_symbol *target = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, $4); + + + if (exist != NULL) { + yyerror(& @2, state, "redeclared identifier"); + YYERROR; + } else if (target == NULL) { + yyerror(& @4, state, + "undefined variable binding in ALIAS statement"); + YYERROR; + } else { + _mesa_symbol_table_add_symbol(state->st, 0, $2, target); + } + } + ; + +%% + +struct asm_instruction * +asm_instruction_ctor(gl_inst_opcode op, + const struct prog_dst_register *dst, + const struct asm_src_register *src0, + const struct asm_src_register *src1, + const struct asm_src_register *src2) +{ + struct asm_instruction *inst = calloc(1, sizeof(struct asm_instruction)); + + if (inst) { + _mesa_init_instructions(& inst->Base, 1); + inst->Base.Opcode = op; + + /* In the core ARB extensions only the KIL instruction doesn't have a + * destination register. + */ + if (dst == NULL) { + init_dst_reg(& inst->Base.DstReg); + } else { + inst->Base.DstReg = *dst; + } + + inst->Base.SrcReg[0] = src0->Base; + inst->SrcReg[0] = *src0; + + if (src1 != NULL) { + inst->Base.SrcReg[1] = src1->Base; + inst->SrcReg[1] = *src1; + } else { + init_src_reg(& inst->SrcReg[1]); + } + + if (src2 != NULL) { + inst->Base.SrcReg[2] = src2->Base; + inst->SrcReg[2] = *src2; + } else { + init_src_reg(& inst->SrcReg[2]); + } + } + + return inst; +} + + +void +init_dst_reg(struct prog_dst_register *r) +{ + memset(r, 0, sizeof(*r)); + r->File = PROGRAM_UNDEFINED; + r->WriteMask = WRITEMASK_XYZW; + r->CondMask = COND_TR; + r->CondSwizzle = SWIZZLE_NOOP; +} + + +void +init_src_reg(struct asm_src_register *r) +{ + memset(r, 0, sizeof(*r)); + r->Base.File = PROGRAM_UNDEFINED; + r->Base.Swizzle = SWIZZLE_NOOP; + r->Symbol = NULL; +} + + +/** + * Validate the set of inputs used by a program + * + * Validates that legal sets of inputs are used by the program. In this case + * "used" included both reading the input or binding the input to a name using + * the \c ATTRIB command. + * + * \return + * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise. + */ +int +validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state) +{ + const int inputs = state->prog->InputsRead | state->InputsBound; + + if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) { + yyerror(locp, state, "illegal use of generic attribute and name attribute"); + return 0; + } + + return 1; +} + + +struct asm_symbol * +declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, + struct YYLTYPE *locp) +{ + struct asm_symbol *s = NULL; + struct asm_symbol *exist = (struct asm_symbol *) + _mesa_symbol_table_find_symbol(state->st, 0, name); + + + if (exist != NULL) { + yyerror(locp, state, "redeclared identifier"); + } else { + s = calloc(1, sizeof(struct asm_symbol)); + s->name = name; + s->type = t; + + switch (t) { + case at_temp: + if (state->prog->NumTemporaries >= state->limits->MaxTemps) { + yyerror(locp, state, "too many temporaries declared"); + free(s); + return NULL; + } + + s->temp_binding = state->prog->NumTemporaries; + state->prog->NumTemporaries++; + break; + + case at_address: + if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) { + yyerror(locp, state, "too many address registers declared"); + free(s); + return NULL; + } + + /* FINISHME: Add support for multiple address registers. + */ + state->prog->NumAddressRegs++; + break; + + default: + break; + } + + _mesa_symbol_table_add_symbol(state->st, 0, s->name, s); + s->next = state->sym; + state->sym = s; + } + + return s; +} + + +int add_state_reference(struct gl_program_parameter_list *param_list, + const gl_state_index tokens[STATE_LENGTH]) +{ + const GLuint size = 4; /* XXX fix */ + char *name; + GLint index; + + name = _mesa_program_state_string(tokens); + index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name, + size, GL_NONE, + NULL, (gl_state_index *) tokens, 0x0); + param_list->StateFlags |= _mesa_program_state_flags(tokens); + + /* free name string here since we duplicated it in add_parameter() */ + _mesa_free(name); + + return index; +} + + +int +initialize_symbol_from_state(struct gl_program *prog, + struct asm_symbol *param_var, + const gl_state_index tokens[STATE_LENGTH]) +{ + int idx = -1; + gl_state_index state_tokens[STATE_LENGTH]; + + + memcpy(state_tokens, tokens, sizeof(state_tokens)); + + param_var->type = at_param; + param_var->param_binding_type = PROGRAM_STATE_VAR; + + /* If we are adding a STATE_MATRIX that has multiple rows, we need to + * unroll it and call 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])) { + int row; + const int first_row = state_tokens[2]; + const int last_row = state_tokens[3]; + + for (row = first_row; row <= last_row; row++) { + state_tokens[2] = state_tokens[3] = row; + + idx = add_state_reference(prog->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + } + } + else { + idx = add_state_reference(prog->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + } + + return idx; +} + + +int +initialize_symbol_from_param(struct gl_program *prog, + struct asm_symbol *param_var, + const gl_state_index tokens[STATE_LENGTH]) +{ + int idx = -1; + gl_state_index state_tokens[STATE_LENGTH]; + + + memcpy(state_tokens, tokens, sizeof(state_tokens)); + + assert((state_tokens[0] == STATE_VERTEX_PROGRAM) + || (state_tokens[0] == STATE_FRAGMENT_PROGRAM)); + assert((state_tokens[1] == STATE_ENV) + || (state_tokens[1] == STATE_LOCAL)); + + param_var->type = at_param; + param_var->param_binding_type = (state_tokens[1] == STATE_ENV) + ? PROGRAM_ENV_PARAM : PROGRAM_LOCAL_PARAM; + + /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements, + * we need to unroll it and call add_state_reference() for each row + */ + if (state_tokens[2] != state_tokens[3]) { + int row; + const int first_row = state_tokens[2]; + const int last_row = state_tokens[3]; + + for (row = first_row; row <= last_row; row++) { + state_tokens[2] = state_tokens[3] = row; + + idx = add_state_reference(prog->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + } + } + else { + idx = add_state_reference(prog->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + } + + return idx; +} + + +int +initialize_symbol_from_const(struct gl_program *prog, + struct asm_symbol *param_var, + const struct asm_vector *vec) +{ + const int idx = _mesa_add_parameter(prog->Parameters, PROGRAM_CONSTANT, + NULL, vec->count, GL_NONE, vec->data, + NULL, 0x0); + + param_var->type = at_param; + param_var->param_binding_type = PROGRAM_CONSTANT; + + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + + return idx; +} + + +char * +make_error_string(const char *fmt, ...) +{ + int length; + char *str; + va_list args; + + va_start(args, fmt); + + /* Call vsnprintf once to determine how large the final string is. Call it + * again to do the actual formatting. from the vsnprintf manual page: + * + * Upon successful return, these functions return the number of + * characters printed (not including the trailing '\0' used to end + * output to strings). + */ + length = 1 + vsnprintf(NULL, 0, fmt, args); + + str = _mesa_malloc(length); + if (str) { + vsnprintf(str, length, fmt, args); + } + + va_end(args); + + return str; +} + + +void +yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s) +{ + char *err_str; + + + err_str = make_error_string("glProgramStringARB(%s)\n", s); + if (err_str) { + _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str); + _mesa_free(err_str); + } + + err_str = make_error_string("line %u, char %u: error: %s\n", + locp->first_line, locp->first_column, s); + _mesa_set_program_error(state->ctx, locp->position, err_str); + + if (err_str) { + _mesa_free(err_str); + } +} + + +GLboolean +_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, + GLsizei len, struct asm_parser_state *state) +{ + struct asm_instruction *inst; + unsigned i; + GLubyte *strz; + GLboolean result = GL_FALSE; + void *temp; + struct asm_symbol *sym; + + state->ctx = ctx; + state->prog->Target = target; + state->prog->Parameters = _mesa_new_parameter_list(); + + /* Make a copy of the program string and force it to be NUL-terminated. + */ + strz = (GLubyte *) _mesa_malloc(len + 1); + if (strz == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); + return GL_FALSE; + } + _mesa_memcpy (strz, str, len); + strz[len] = '\0'; + + state->prog->String = strz; + + state->st = _mesa_symbol_table_ctor(); + + state->limits = (target == GL_VERTEX_PROGRAM_ARB) + ? & ctx->Const.VertexProgram + : & ctx->Const.FragmentProgram; + + state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; + state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; + state->MaxTextureUnits = ctx->Const.MaxTextureUnits; + state->MaxClipPlanes = ctx->Const.MaxClipPlanes; + state->MaxLights = ctx->Const.MaxLights; + state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices; + + state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB) + ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM; + + _mesa_set_program_error(ctx, -1, NULL); + + _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len); + yyparse(state); + _mesa_program_lexer_dtor(state->scanner); + + + if (ctx->Program.ErrorPos != -1) { + goto error; + } + + if (! _mesa_layout_parameters(state)) { + struct YYLTYPE loc; + + loc.first_line = 0; + loc.first_column = 0; + loc.position = len; + + yyerror(& loc, state, "invalid PARAM usage"); + goto error; + } + + + + /* Add one instruction to store the "END" instruction. + */ + state->prog->Instructions = + _mesa_alloc_instructions(state->prog->NumInstructions + 1); + inst = state->inst_head; + for (i = 0; i < state->prog->NumInstructions; i++) { + struct asm_instruction *const temp = inst->next; + + state->prog->Instructions[i] = inst->Base; + inst = temp; + } + + /* Finally, tag on an OPCODE_END instruction */ + { + const GLuint numInst = state->prog->NumInstructions; + _mesa_init_instructions(state->prog->Instructions + numInst, 1); + state->prog->Instructions[numInst].Opcode = OPCODE_END; + } + state->prog->NumInstructions++; + + state->prog->NumParameters = state->prog->Parameters->NumParameters; + state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead); + + /* + * Initialize native counts to logical counts. The device driver may + * change them if program is translated into a hardware program. + */ + state->prog->NumNativeInstructions = state->prog->NumInstructions; + state->prog->NumNativeTemporaries = state->prog->NumTemporaries; + state->prog->NumNativeParameters = state->prog->NumParameters; + state->prog->NumNativeAttributes = state->prog->NumAttributes; + state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs; + + result = GL_TRUE; + +error: + for (inst = state->inst_head; inst != NULL; inst = temp) { + temp = inst->next; + _mesa_free(inst); + } + + state->inst_head = NULL; + state->inst_tail = NULL; + + for (sym = state->sym; sym != NULL; sym = temp) { + temp = sym->next; + + _mesa_free((void *) sym->name); + _mesa_free(sym); + } + state->sym = NULL; + + _mesa_symbol_table_dtor(state->st); + state->st = NULL; + + return result; +} diff --git a/src/mesa/shader/program_parse_extra.c b/src/mesa/shader/program_parse_extra.c new file mode 100644 index 0000000000..8e4be606f1 --- /dev/null +++ b/src/mesa/shader/program_parse_extra.c @@ -0,0 +1,117 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <string.h> +#include "main/mtypes.h" +#include "prog_instruction.h" +#include "program_parser.h" + + +/** + * Extra assembly-level parser routines + * + * \author Ian Romanick <ian.d.romanick@intel.com> + */ + +int +_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option) +{ + if (strcmp(option, "ARB_position_invariant") == 0) { + state->option.PositionInvariant = 1; + return 1; + } + + return 0; +} + + +int +_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option) +{ + /* All of the options currently supported start with "ARB_". The code is + * currently structured with nested if-statements because eventually options + * that start with "NV_" will be supported. This structure will result in + * less churn when those options are added. + */ + if (strncmp(option, "ARB_", 4) == 0) { + /* Advance the pointer past the "ARB_" prefix. + */ + option += 4; + + + if (strncmp(option, "fog_", 4) == 0) { + option += 4; + + if (state->option.Fog == OPTION_NONE) { + if (strcmp(option, "exp") == 0) { + state->option.Fog = OPTION_FOG_EXP; + return 1; + } else if (strcmp(option, "exp2") == 0) { + state->option.Fog = OPTION_FOG_EXP2; + return 1; + } else if (strcmp(option, "linear") == 0) { + state->option.Fog = OPTION_FOG_LINEAR; + return 1; + } + } + + return 0; + } else if (strncmp(option, "precision_hint_", 15) == 0) { + option += 15; + + if (state->option.PrecisionHint == OPTION_NONE) { + if (strcmp(option, "nicest") == 0) { + state->option.PrecisionHint = OPTION_NICEST; + return 1; + } else if (strcmp(option, "fastest") == 0) { + state->option.PrecisionHint = OPTION_FASTEST; + return 1; + } + } + + return 0; + } else if (strcmp(option, "draw_buffers") == 0) { + /* Don't need to check extension availability because all Mesa-based + * drivers support GL_ARB_draw_buffers. + */ + state->option.DrawBuffers = 1; + return 1; + } else if (strcmp(option, "fragment_program_shadow") == 0) { + if (state->ctx->Extensions.ARB_fragment_program_shadow) { + state->option.Shadow = 1; + return 1; + } + } + } else if (strncmp(option, "MESA_", 5) == 0) { + option += 5; + + if (strcmp(option, "texture_array") == 0) { + if (state->ctx->Extensions.MESA_texture_array) { + state->option.TexArray = 1; + return 1; + } + } + } + + return 0; +} diff --git a/src/mesa/shader/program_parser.h b/src/mesa/shader/program_parser.h new file mode 100644 index 0000000000..fa47d84565 --- /dev/null +++ b/src/mesa/shader/program_parser.h @@ -0,0 +1,266 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include "main/config.h" + +#ifndef MTYPES_H +struct __GLcontextRec; +typedef struct __GLcontextRec GLcontext; +#endif + +enum asm_type { + at_none, + at_address, + at_attrib, + at_param, + at_temp, + at_output, +}; + +struct asm_symbol { + struct asm_symbol *next; /**< List linkage for freeing. */ + const char *name; + enum asm_type type; + unsigned attrib_binding; + unsigned output_binding; /**< Output / result register number. */ + + /** + * One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM. + */ + unsigned param_binding_type; + + /** + * Offset into the program_parameter_list where the tokens representing our + * bound state (or constants) start. + */ + unsigned param_binding_begin; + + /* This is how many entries in the the program_parameter_list we take up + * with our state tokens or constants. Note that this is _not_ the same as + * the number of param registers we eventually use. + */ + unsigned param_binding_length; + + /** + * Index of the temp register assigned to this variable. + */ + unsigned temp_binding; + + /** + * Flag whether or not a PARAM is an array + */ + unsigned param_is_array:1; + + + /** + * Flag whether or not a PARAM array is accessed indirectly + */ + unsigned param_accessed_indirectly:1; + + + /** + * \brief Is first pass of parameter layout done with this variable? + * + * The parameter layout routine operates in two passes. This flag tracks + * whether or not the first pass has handled this variable. + * + * \sa _mesa_layout_parameters + */ + unsigned pass1_done:1; +}; + + +struct asm_vector { + unsigned count; + float data[4]; +}; + + +struct asm_swizzle_mask { + unsigned swizzle:12; + unsigned mask:4; +}; + + +struct asm_src_register { + struct prog_src_register Base; + + /** + * Symbol associated with indirect access to parameter arrays. + * + * If \c Base::RelAddr is 1, this will point to the symbol for the parameter + * that is being dereferenced. Further, \c Base::Index will be the offset + * from the address register being used. + */ + struct asm_symbol *Symbol; +}; + + +struct asm_instruction { + struct prog_instruction Base; + struct asm_instruction *next; + struct asm_src_register SrcReg[3]; +}; + + +struct asm_parser_state { + GLcontext *ctx; + struct gl_program *prog; + + /** + * Per-program target limits + */ + struct gl_program_constants *limits; + + struct _mesa_symbol_table *st; + + /** + * Linked list of symbols + * + * This list is \b only used when cleaning up compiler state and freeing + * memory. + */ + struct asm_symbol *sym; + + /** + * State for the lexer. + */ + void *scanner; + + /** + * Linked list of instructions generated during parsing. + */ + /*@{*/ + struct asm_instruction *inst_head; + struct asm_instruction *inst_tail; + /*@}*/ + + + /** + * Selected limits copied from gl_constants + * + * These are limits from the GL context, but various bits in the program + * must be validated against these values. + */ + /*@{*/ + unsigned MaxTextureCoordUnits; + unsigned MaxTextureImageUnits; + unsigned MaxTextureUnits; + unsigned MaxClipPlanes; + unsigned MaxLights; + unsigned MaxProgramMatrices; + /*@}*/ + + /** + * Value to use in state vector accessors for environment and local + * parameters + */ + unsigned state_param_enum; + + + /** + * Input attributes bound to specific names + * + * This is only needed so that errors can be properly produced when + * multiple ATTRIB statements bind illegal combinations of vertex + * attributes. + */ + unsigned InputsBound; + + enum { + invalid_mode = 0, + ARB_vertex, + ARB_fragment + } mode; + + struct { + unsigned PositionInvariant:1; + unsigned Fog:2; + unsigned PrecisionHint:2; + unsigned DrawBuffers:1; + unsigned Shadow:1; + unsigned TexRect:1; + unsigned TexArray:1; + } option; + + struct { + unsigned UsesKill:1; + } fragment; +}; + +#define OPTION_NONE 0 +#define OPTION_FOG_EXP 1 +#define OPTION_FOG_EXP2 2 +#define OPTION_FOG_LINEAR 3 +#define OPTION_NICEST 1 +#define OPTION_FASTEST 2 + +typedef struct YYLTYPE { + int first_line; + int first_column; + int last_line; + int last_column; + int position; +} YYLTYPE; + +#define YYLTYPE_IS_DECLARED 1 +#define YYLTYPE_IS_TRIVIAL 1 + + +extern GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target, + const GLubyte *str, GLsizei len, struct asm_parser_state *state); + + + +/* From program_lexer.l. */ +extern void _mesa_program_lexer_dtor(void *scanner); + +extern void _mesa_program_lexer_ctor(void **scanner, + struct asm_parser_state *state, const char *string, size_t len); + + +/** + *\name From program_parse_extra.c + */ +/*@{*/ + +/** + * Parses and processes an option string to an ARB vertex program + * + * \return + * Non-zero on success, zero on failure. + */ +extern int _mesa_ARBvp_parse_option(struct asm_parser_state *state, + const char *option); + +/** + * Parses and processes an option string to an ARB fragment program + * + * \return + * Non-zero on success, zero on failure. + */ +extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state, + const char *option); + +/*@}*/ diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index ac5fe0f691..f70c75cec8 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -396,7 +396,6 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) fprog->Base.Instructions = newInst; fprog->Base.NumInstructions = inst - newInst; fprog->Base.InputsRead |= FRAG_BIT_FOGC; - fprog->UsesFogFragCoord = GL_TRUE; /* XXX do this? fprog->FogOption = GL_NONE; */ } diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index c36fc271a0..54a25dfaf0 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 7.5 + * Version: 7.6 * * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. * Copyright (C) 2009 VMware, Inc. All Rights Reserved. @@ -1431,6 +1431,9 @@ _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source) } sh->Source = source; sh->CompileStatus = GL_FALSE; +#ifdef DEBUG + sh->SourceChecksum = _mesa_str_checksum(sh->Source); +#endif } @@ -1488,7 +1491,7 @@ _mesa_use_program(GLcontext *ctx, GLuint program) return; } - FLUSH_VERTICES(ctx, _NEW_PROGRAM); + FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); if (program) { shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram"); @@ -1506,10 +1509,15 @@ _mesa_use_program(GLcontext *ctx, GLuint program) GLuint i; _mesa_printf("Use Shader %u\n", shProg->Name); for (i = 0; i < shProg->NumShaders; i++) { - _mesa_printf(" shader %u, type 0x%x\n", + _mesa_printf(" shader %u, type 0x%x, checksum %u\n", shProg->Shaders[i]->Name, - shProg->Shaders[i]->Type); + shProg->Shaders[i]->Type, + shProg->Shaders[i]->SourceChecksum); } + if (shProg->VertexProgram) + printf(" vert prog %u\n", shProg->VertexProgram->Base.Id); + if (shProg->FragmentProgram) + printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id); } } else { @@ -1545,10 +1553,11 @@ _mesa_update_shader_textures_used(struct gl_program *prog) for (s = 0; s < MAX_SAMPLERS; s++) { if (prog->SamplersUsed & (1 << s)) { - GLuint u = prog->SamplerUnits[s]; - GLuint t = prog->SamplerTargets[s]; - assert(u < MAX_TEXTURE_IMAGE_UNITS); - prog->TexturesUsed[u] |= (1 << t); + GLuint unit = prog->SamplerUnits[s]; + GLuint tgt = prog->SamplerTargets[s]; + assert(unit < MAX_TEXTURE_IMAGE_UNITS); + assert(tgt < NUM_TEXTURE_TARGETS); + prog->TexturesUsed[unit] |= (1 << tgt); } } } @@ -1603,10 +1612,8 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, GLenum type, GLsizei count, GLint elems, const void *values) { - struct gl_program_parameter *param = + const struct gl_program_parameter *param = &program->Parameters->Parameters[index]; - const GLboolean isUniformBool = is_boolean_type(param->DataType); - const GLboolean areIntValues = is_integer_type(type); assert(offset >= 0); assert(elems >= 1); @@ -1627,17 +1634,10 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, GLboolean changed = GL_FALSE; GLint i; - /* data type for setting samplers must be int */ - if (type != GL_INT) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUniform(only glUniform1i can be used " - "to set sampler uniforms)"); - return; - } + /* this should have been caught by the compatible_types() check */ + ASSERT(type == GL_INT); - /* XXX arrays of samplers haven't been tested much, but it's not a - * common thing... - */ + /* loop over number of samplers to change */ for (i = 0; i < count; i++) { GLuint sampler = (GLuint) program->Parameters->ParameterValues[index + offset + i][0]; @@ -1676,9 +1676,11 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, } else { /* ordinary uniform variable */ - GLsizei k, i; + const GLboolean isUniformBool = is_boolean_type(param->DataType); + const GLboolean areIntValues = is_integer_type(type); const GLint slots = (param->Size + 3) / 4; const GLint typeSize = sizeof_glsl_type(param->DataType); + GLsizei k, i; if (param->Size > typeSize) { /* an array */ @@ -1805,7 +1807,7 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, return; } - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); uniform = &shProg->Uniforms->Uniforms[location]; @@ -1945,7 +1947,7 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, return; } - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); uniform = &shProg->Uniforms->Uniforms[location]; @@ -1973,19 +1975,74 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, } -static void -_mesa_validate_program(GLcontext *ctx, GLuint program) +/** + * Validate a program's samplers. + * Specifically, check that there aren't two samplers of different types + * pointing to the same texture unit. + * \return GL_TRUE if valid, GL_FALSE if invalid + */ +static GLboolean +validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg) { - struct gl_shader_program *shProg; + static const char *targetName[] = { + "TEXTURE_2D_ARRAY", + "TEXTURE_1D_ARRAY", + "TEXTURE_CUBE", + "TEXTURE_3D", + "TEXTURE_RECT", + "TEXTURE_2D", + "TEXTURE_1D", + }; + GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS]; + GLbitfield samplersUsed = prog->SamplersUsed; + GLuint i; - shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram"); - if (!shProg) { - return; + assert(Elements(targetName) == NUM_TEXTURE_TARGETS); + + if (samplersUsed == 0x0) + return GL_TRUE; + + for (i = 0; i < Elements(targetUsed); i++) + targetUsed[i] = -1; + + /* walk over bits which are set in 'samplers' */ + while (samplersUsed) { + GLuint unit; + gl_texture_index target; + GLint sampler = _mesa_ffs(samplersUsed) - 1; + assert(sampler >= 0); + assert(sampler < MAX_TEXTURE_IMAGE_UNITS); + unit = prog->SamplerUnits[sampler]; + target = prog->SamplerTargets[sampler]; + if (targetUsed[unit] != -1 && targetUsed[unit] != target) { + _mesa_snprintf(errMsg, 100, + "Texture unit %d is accessed both as %s and %s", + unit, targetName[targetUsed[unit]], targetName[target]); + return GL_FALSE; + } + targetUsed[unit] = target; + samplersUsed ^= (1 << sampler); } + return GL_TRUE; +} + + +/** + * Do validation of the given shader program. + * \param errMsg returns error message if validation fails. + * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg) + */ +GLboolean +_mesa_validate_shader_program(GLcontext *ctx, + const struct gl_shader_program *shProg, + char *errMsg) +{ + const struct gl_vertex_program *vp = shProg->VertexProgram; + const struct gl_fragment_program *fp = shProg->FragmentProgram; + if (!shProg->LinkStatus) { - shProg->Validated = GL_FALSE; - return; + return GL_FALSE; } /* From the GL spec, a program is invalid if any of these are true: @@ -2003,7 +2060,44 @@ _mesa_validate_program(GLcontext *ctx, GLuint program) image units allowed. */ - shProg->Validated = GL_TRUE; + + /* + * Check: any two active samplers in the current program object are of + * different types, but refer to the same texture image unit, + */ + if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) { + return GL_FALSE; + } + if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) { + return GL_FALSE; + } + + return GL_TRUE; +} + + +/** + * Called via glValidateProgram() + */ +static void +_mesa_validate_program(GLcontext *ctx, GLuint program) +{ + struct gl_shader_program *shProg; + char errMsg[100]; + + shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram"); + if (!shProg) { + return; + } + + shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg); + if (!shProg->Validated) { + /* update info log */ + if (shProg->InfoLog) { + _mesa_free(shProg->InfoLog); + } + shProg->InfoLog = _mesa_strdup(errMsg); + } } diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h index ec1996ee98..d08d47373e 100644 --- a/src/mesa/shader/shader_api.h +++ b/src/mesa/shader/shader_api.h @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.6 * * Copyright (C) 2004-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. 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"), @@ -87,6 +88,11 @@ extern void _mesa_use_program(GLcontext *ctx, GLuint program); +extern GLboolean +_mesa_validate_shader_program(GLcontext *ctx, + const struct gl_shader_program *shProg, + char *errMsg); + extern void _mesa_init_glsl_driver_functions(struct dd_function_table *driver); diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c index 4e67241f3b..bef0f85653 100644 --- a/src/mesa/shader/slang/slang_builtin.c +++ b/src/mesa/shader/slang/slang_builtin.c @@ -710,3 +710,186 @@ _slang_alloc_statevar(slang_ir_node *n, *direct = GL_FALSE; return alloc_state_var_array(n->Var, paramList); } + + + + +#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W) + + +/** Predefined shader inputs */ +struct input_info +{ + const char *Name; + GLuint Attrib; + GLenum Type; + GLuint Swizzle; +}; + +/** Predefined vertex shader inputs/attributes */ +static const struct input_info vertInputs[] = { + { "gl_Vertex", VERT_ATTRIB_POS, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_Normal", VERT_ATTRIB_NORMAL, GL_FLOAT_VEC3, SWIZZLE_NOOP }, + { "gl_Color", VERT_ATTRIB_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_FogCoord", VERT_ATTRIB_FOG, GL_FLOAT, SWIZZLE_XXXX }, + { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { NULL, 0, SWIZZLE_NOOP } +}; + +/** Predefined fragment shader inputs */ +static const struct input_info fragInputs[] = { + { "gl_FragCoord", FRAG_ATTRIB_WPOS, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_Color", FRAG_ATTRIB_COL0, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_SecondaryColor", FRAG_ATTRIB_COL1, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + { "gl_TexCoord", FRAG_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP }, + /* note: we're packing several quantities into the fogcoord vector */ + { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, GL_FLOAT, SWIZZLE_XXXX }, + { "gl_FrontFacing", FRAG_ATTRIB_FACE, GL_FLOAT, SWIZZLE_XXXX }, + { "gl_PointCoord", FRAG_ATTRIB_PNTC, GL_FLOAT_VEC2, SWIZZLE_XYZW }, + { NULL, 0, SWIZZLE_NOOP } +}; + + +/** + * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to + * a vertex or fragment program input variable. Return -1 if the input + * name is invalid. + * XXX return size too + */ +GLint +_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut) +{ + const struct input_info *inputs; + GLuint i; + + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + inputs = vertInputs; + break; + case GL_FRAGMENT_PROGRAM_ARB: + inputs = fragInputs; + break; + /* XXX geom program */ + default: + _mesa_problem(NULL, "bad target in _slang_input_index"); + return -1; + } + + ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */ + + for (i = 0; inputs[i].Name; i++) { + if (strcmp(inputs[i].Name, name) == 0) { + /* found */ + *swizzleOut = inputs[i].Swizzle; + return inputs[i].Attrib; + } + } + return -1; +} + + +/** + * Return name of the given vertex attribute (VERT_ATTRIB_x). + */ +const char * +_slang_vert_attrib_name(GLuint attrib) +{ + GLuint i; + assert(attrib < VERT_ATTRIB_GENERIC0); + for (i = 0; vertInputs[i].Name; i++) { + if (vertInputs[i].Attrib == attrib) + return vertInputs[i].Name; + } + return NULL; +} + + +/** + * Return type (GL_FLOAT, GL_FLOAT_VEC2, etc) of the given vertex + * attribute (VERT_ATTRIB_x). + */ +GLenum +_slang_vert_attrib_type(GLuint attrib) +{ + GLuint i; + assert(attrib < VERT_ATTRIB_GENERIC0); + for (i = 0; vertInputs[i].Name; i++) { + if (vertInputs[i].Attrib == attrib) + return vertInputs[i].Type; + } + return GL_NONE; +} + + + + + +/** Predefined shader output info */ +struct output_info +{ + const char *Name; + GLuint Attrib; +}; + +/** Predefined vertex shader outputs */ +static const struct output_info vertOutputs[] = { + { "gl_Position", VERT_RESULT_HPOS }, + { "gl_FrontColor", VERT_RESULT_COL0 }, + { "gl_BackColor", VERT_RESULT_BFC0 }, + { "gl_FrontSecondaryColor", VERT_RESULT_COL1 }, + { "gl_BackSecondaryColor", VERT_RESULT_BFC1 }, + { "gl_TexCoord", VERT_RESULT_TEX0 }, + { "gl_FogFragCoord", VERT_RESULT_FOGC }, + { "gl_PointSize", VERT_RESULT_PSIZ }, + { NULL, 0 } +}; + +/** Predefined fragment shader outputs */ +static const struct output_info fragOutputs[] = { + { "gl_FragColor", FRAG_RESULT_COLOR }, + { "gl_FragDepth", FRAG_RESULT_DEPTH }, + { "gl_FragData", FRAG_RESULT_DATA0 }, + { NULL, 0 } +}; + + +/** + * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to + * a vertex or fragment program output variable. Return -1 for an invalid + * output name. + */ +GLint +_slang_output_index(const char *name, GLenum target) +{ + const struct output_info *outputs; + GLuint i; + + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + outputs = vertOutputs; + break; + case GL_FRAGMENT_PROGRAM_ARB: + outputs = fragOutputs; + break; + /* XXX geom program */ + default: + _mesa_problem(NULL, "bad target in _slang_output_index"); + return -1; + } + + for (i = 0; outputs[i].Name; i++) { + if (strcmp(outputs[i].Name, name) == 0) { + /* found */ + return outputs[i].Attrib; + } + } + return -1; +} diff --git a/src/mesa/shader/slang/slang_builtin.h b/src/mesa/shader/slang/slang_builtin.h index 7f6fe80fcc..f814d11ac7 100644 --- a/src/mesa/shader/slang/slang_builtin.h +++ b/src/mesa/shader/slang/slang_builtin.h @@ -37,4 +37,18 @@ _slang_alloc_statevar(slang_ir_node *n, GLboolean *direct); +extern GLint +_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut); + +extern GLint +_slang_output_index(const char *name, GLenum target); + + +extern const char * +_slang_vert_attrib_name(GLuint attrib); + +extern GLenum +_slang_vert_attrib_type(GLuint attrib); + + #endif /* SLANG_BUILTIN_H */ diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 2b7e781f98..349f432dec 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -46,6 +46,7 @@ #include "shader/prog_print.h" #include "shader/prog_statevars.h" #include "slang_typeinfo.h" +#include "slang_builtin.h" #include "slang_codegen.h" #include "slang_compile.h" #include "slang_label.h" @@ -342,109 +343,6 @@ slang_operation_identifier(slang_operation *oper, } -#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W) - -/** - * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to - * a vertex or fragment program input variable. Return -1 if the input - * name is invalid. - * XXX return size too - */ -static GLint -_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut) -{ - struct input_info { - const char *Name; - GLuint Attrib; - GLuint Swizzle; - }; - static const struct input_info vertInputs[] = { - { "gl_Vertex", VERT_ATTRIB_POS, SWIZZLE_NOOP }, - { "gl_Normal", VERT_ATTRIB_NORMAL, SWIZZLE_NOOP }, - { "gl_Color", VERT_ATTRIB_COLOR0, SWIZZLE_NOOP }, - { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, SWIZZLE_NOOP }, - { "gl_FogCoord", VERT_ATTRIB_FOG, SWIZZLE_XXXX }, - { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, SWIZZLE_NOOP }, - { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, SWIZZLE_NOOP }, - { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, SWIZZLE_NOOP }, - { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, SWIZZLE_NOOP }, - { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, SWIZZLE_NOOP }, - { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, SWIZZLE_NOOP }, - { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, SWIZZLE_NOOP }, - { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, SWIZZLE_NOOP }, - { NULL, 0, SWIZZLE_NOOP } - }; - static const struct input_info fragInputs[] = { - { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP }, - { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP }, - { "gl_SecondaryColor", FRAG_ATTRIB_COL1, SWIZZLE_NOOP }, - { "gl_TexCoord", FRAG_ATTRIB_TEX0, SWIZZLE_NOOP }, - /* note: we're packing several quantities into the fogcoord vector */ - { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX }, - { "gl_FrontFacing", FRAG_ATTRIB_FOGC, SWIZZLE_YYYY }, /*XXX*/ - { "gl_PointCoord", FRAG_ATTRIB_FOGC, SWIZZLE_ZWWW }, - { NULL, 0, SWIZZLE_NOOP } - }; - GLuint i; - const struct input_info *inputs - = (target == GL_VERTEX_PROGRAM_ARB) ? vertInputs : fragInputs; - - ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */ - - for (i = 0; inputs[i].Name; i++) { - if (strcmp(inputs[i].Name, name) == 0) { - /* found */ - *swizzleOut = inputs[i].Swizzle; - return inputs[i].Attrib; - } - } - return -1; -} - - -/** - * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to - * a vertex or fragment program output variable. Return -1 for an invalid - * output name. - */ -static GLint -_slang_output_index(const char *name, GLenum target) -{ - struct output_info { - const char *Name; - GLuint Attrib; - }; - static const struct output_info vertOutputs[] = { - { "gl_Position", VERT_RESULT_HPOS }, - { "gl_FrontColor", VERT_RESULT_COL0 }, - { "gl_BackColor", VERT_RESULT_BFC0 }, - { "gl_FrontSecondaryColor", VERT_RESULT_COL1 }, - { "gl_BackSecondaryColor", VERT_RESULT_BFC1 }, - { "gl_TexCoord", VERT_RESULT_TEX0 }, - { "gl_FogFragCoord", VERT_RESULT_FOGC }, - { "gl_PointSize", VERT_RESULT_PSIZ }, - { NULL, 0 } - }; - static const struct output_info fragOutputs[] = { - { "gl_FragColor", FRAG_RESULT_COLOR }, - { "gl_FragDepth", FRAG_RESULT_DEPTH }, - { "gl_FragData", FRAG_RESULT_DATA0 }, - { NULL, 0 } - }; - GLuint i; - const struct output_info *outputs - = (target == GL_VERTEX_PROGRAM_ARB) ? vertOutputs : fragOutputs; - - for (i = 0; outputs[i].Name; i++) { - if (strcmp(outputs[i].Name, name) == 0) { - /* found */ - return outputs[i].Attrib; - } - } - return -1; -} - - /** * Called when we begin code/IR generation for a new while/do/for loop. */ diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 387659ff30..169c07f8ce 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -40,6 +40,7 @@ #include "shader/prog_statevars.h" #include "shader/prog_uniform.h" #include "shader/shader_api.h" +#include "slang_builtin.h" #include "slang_link.h" @@ -287,6 +288,7 @@ link_uniform_vars(GLcontext *ctx, for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; if (_mesa_is_tex_instruction(inst->Opcode)) { + /* here, inst->TexSrcUnit is really the sampler unit */ const GLint oldSampNum = inst->TexSrcUnit; #if 0 @@ -294,7 +296,6 @@ link_uniform_vars(GLcontext *ctx, inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]); #endif - /* here, texUnit is really samplerUnit */ if (oldSampNum < Elements(samplerMap)) { const GLuint newSampNum = samplerMap[oldSampNum]; inst->TexSrcUnit = newSampNum; @@ -327,6 +328,7 @@ _slang_resolve_attributes(struct gl_shader_program *shProg, GLint attribMap[MAX_VERTEX_GENERIC_ATTRIBS]; GLuint i, j; GLbitfield usedAttributes; /* generics only, not legacy attributes */ + GLbitfield inputsRead = 0x0; assert(origProg != linkedProg); assert(origProg->Target == GL_VERTEX_PROGRAM_ARB); @@ -370,6 +372,10 @@ _slang_resolve_attributes(struct gl_shader_program *shProg, for (i = 0; i < linkedProg->NumInstructions; i++) { struct prog_instruction *inst = linkedProg->Instructions + i; for (j = 0; j < 3; j++) { + if (inst->SrcReg[j].File == PROGRAM_INPUT) { + inputsRead |= (1 << inst->SrcReg[j].Index); + } + if (inst->SrcReg[j].File == PROGRAM_INPUT && inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) { /* @@ -431,6 +437,20 @@ _slang_resolve_attributes(struct gl_shader_program *shProg, } } + /* Handle pre-defined attributes here (gl_Vertex, gl_Normal, etc). + * When the user queries the active attributes we need to include both + * the user-defined attributes and the built-in ones. + */ + for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_GENERIC0; i++) { + if (inputsRead & (1 << i)) { + _mesa_add_attribute(linkedProg->Attributes, + _slang_vert_attrib_name(i), + 4, /* size in floats */ + _slang_vert_attrib_type(i), + -1 /* attrib/input */); + } + } + return GL_TRUE; } @@ -484,20 +504,6 @@ _slang_update_inputs_outputs(struct gl_program *prog) for (j = 0; j < numSrc; j++) { if (inst->SrcReg[j].File == PROGRAM_INPUT) { prog->InputsRead |= 1 << inst->SrcReg[j].Index; - if (prog->Target == GL_FRAGMENT_PROGRAM_ARB && - inst->SrcReg[j].Index == FRAG_ATTRIB_FOGC) { - /* The fragment shader FOGC input is used for fog, - * front-facing and sprite/point coord. - */ - struct gl_fragment_program *fp = fragment_program(prog); - const GLint swz = GET_SWZ(inst->SrcReg[j].Swizzle, 0); - if (swz == SWIZZLE_X) - fp->UsesFogFragCoord = GL_TRUE; - else if (swz == SWIZZLE_Y) - fp->UsesFrontFacing = GL_TRUE; - else if (swz == SWIZZLE_Z || swz == SWIZZLE_W) - fp->UsesPointCoord = GL_TRUE; - } } else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) { maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1)); @@ -717,6 +723,8 @@ _slang_link(GLcontext *ctx, struct gl_vertex_program *linked_vprog = vertex_program(_mesa_clone_program(ctx, &vertProg->Base)); shProg->VertexProgram = linked_vprog; /* refcount OK */ + /* vertex program ID not significant; just set Id for debugging purposes */ + shProg->VertexProgram->Base.Id = shProg->Name; ASSERT(shProg->VertexProgram->Base.RefCount == 1); } @@ -725,6 +733,8 @@ _slang_link(GLcontext *ctx, struct gl_fragment_program *linked_fprog = fragment_program(_mesa_clone_program(ctx, &fragProg->Base)); shProg->FragmentProgram = linked_fprog; /* refcount OK */ + /* vertex program ID not significant; just set Id for debugging purposes */ + shProg->FragmentProgram->Base.Id = shProg->Name; ASSERT(shProg->FragmentProgram->Base.RefCount == 1); } @@ -839,6 +849,14 @@ _slang_link(GLcontext *ctx, } } + /* Debug: */ + if (0) { + if (shProg->VertexProgram) + _mesa_postprocess_program(ctx, &shProg->VertexProgram->Base); + if (shProg->FragmentProgram) + _mesa_postprocess_program(ctx, &shProg->FragmentProgram->Base); + } + if (ctx->Shader.Flags & GLSL_DUMP) { _mesa_printf("Varying vars:\n"); _mesa_print_parameter_list(shProg->Varying); diff --git a/src/mesa/shader/symbol_table.c b/src/mesa/shader/symbol_table.c new file mode 100644 index 0000000000..71ce1287f5 --- /dev/null +++ b/src/mesa/shader/symbol_table.c @@ -0,0 +1,348 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <assert.h> + +#include "symbol_table.h" +#include "hash_table.h" + +struct symbol { + /** + * Link to the next symbol in the table with the same name + * + * The linked list of symbols with the same name is ordered by scope + * from inner-most to outer-most. + */ + struct symbol *next_with_same_name; + + + /** + * Link to the next symbol in the table with the same scope + * + * The linked list of symbols with the same scope is unordered. Symbols + * in this list my have unique names. + */ + struct symbol *next_with_same_scope; + + + /** + * Header information for the list of symbols with the same name. + */ + struct symbol_header *hdr; + + + /** + * Name space of the symbol + * + * Name space are arbitrary user assigned integers. No two symbols can + * exist in the same name space at the same scope level. + */ + int name_space; + + + /** + * Arbitrary user supplied data. + */ + void *data; +}; + + +/** + */ +struct symbol_header { + /** Symbol name. */ + const char *name; + + /** Linked list of symbols with the same name. */ + struct symbol *symbols; +}; + + +/** + * Element of the scope stack. + */ +struct scope_level { + /** Link to next (inner) scope level. */ + struct scope_level *next; + + /** Linked list of symbols with the same scope. */ + struct symbol *symbols; +}; + + +/** + * + */ +struct _mesa_symbol_table { + /** Hash table containing all symbols in the symbol table. */ + struct hash_table *ht; + + /** Top of scope stack. */ + struct scope_level *current_scope; +}; + + +struct _mesa_symbol_table_iterator { + /** + * Name space of symbols returned by this iterator. + */ + int name_space; + + + /** + * Currently iterated symbol + * + * The next call to \c _mesa_symbol_table_iterator_get will return this + * value. It will also update this value to the value that should be + * returned by the next call. + */ + struct symbol *curr; +}; + + +static void +check_symbol_table(struct _mesa_symbol_table *table) +{ +#if 1 + struct scope_level *scope; + + for (scope = table->current_scope; scope != NULL; scope = scope->next) { + struct symbol *sym; + + for (sym = scope->symbols + ; sym != NULL + ; sym = sym->next_with_same_name) { + const struct symbol_header *const hdr = sym->hdr; + struct symbol *sym2; + + for (sym2 = hdr->symbols + ; sym2 != NULL + ; sym2 = sym2->next_with_same_name) { + assert(sym2->hdr == hdr); + } + } + } +#endif +} + +void +_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table) +{ + struct scope_level *const scope = table->current_scope; + struct symbol *sym = scope->symbols; + + table->current_scope = scope->next; + + free(scope); + + while (sym != NULL) { + struct symbol *const next = sym->next_with_same_scope; + struct symbol_header *const hdr = sym->hdr; + + assert(hdr->symbols == sym); + + hdr->symbols = sym->next_with_same_name; + + free(sym); + + sym = next; + } + + check_symbol_table(table); +} + + +void +_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table) +{ + struct scope_level *const scope = calloc(1, sizeof(*scope)); + + scope->next = table->current_scope; + table->current_scope = scope; +} + + +static struct symbol_header * +find_symbol(struct _mesa_symbol_table *table, const char *name) +{ + return (struct symbol_header *) hash_table_find(table->ht, name); +} + + +struct _mesa_symbol_table_iterator * +_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table, + int name_space, const char *name) +{ + struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter)); + struct symbol_header *const hdr = find_symbol(table, name); + + iter->name_space = name_space; + + if (hdr != NULL) { + struct symbol *sym; + + for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { + assert(sym->hdr == hdr); + + if ((name_space == -1) || (sym->name_space == name_space)) { + iter->curr = sym; + break; + } + } + } + + return iter; +} + + +void +_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter) +{ + free(iter); +} + + +void * +_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter) +{ + return (iter->curr == NULL) ? NULL : iter->curr->data; +} + + +int +_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter) +{ + struct symbol_header *hdr; + + if (iter->curr == NULL) { + return 0; + } + + hdr = iter->curr->hdr; + iter->curr = iter->curr->next_with_same_name; + + while (iter->curr != NULL) { + assert(iter->curr->hdr == hdr); + + if ((iter->name_space == -1) + || (iter->curr->name_space == iter->name_space)) { + return 1; + } + + iter->curr = iter->curr->next_with_same_name; + } + + return 0; +} + + +void * +_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table, + int name_space, const char *name) +{ + struct symbol_header *const hdr = find_symbol(table, name); + + if (hdr != NULL) { + struct symbol *sym; + + + for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { + assert(sym->hdr == hdr); + + if ((name_space == -1) || (sym->name_space == name_space)) { + return sym->data; + } + } + } + + return NULL; +} + + +int +_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table, + int name_space, const char *name, + void *declaration) +{ + check_symbol_table(table); + + struct symbol_header *hdr = find_symbol(table, name); + struct symbol *sym; + + check_symbol_table(table); + + if (hdr == NULL) { + hdr = calloc(1, sizeof(*hdr)); + hdr->name = name; + + hash_table_insert(table->ht, hdr, name); + } + + check_symbol_table(table); + + sym = calloc(1, sizeof(*sym)); + sym->next_with_same_name = hdr->symbols; + sym->next_with_same_scope = table->current_scope->symbols; + sym->hdr = hdr; + sym->name_space = name_space; + sym->data = declaration; + + assert(sym->hdr == hdr); + + hdr->symbols = sym; + table->current_scope->symbols = sym; + + check_symbol_table(table); + return 0; +} + + +struct _mesa_symbol_table * +_mesa_symbol_table_ctor(void) +{ + struct _mesa_symbol_table *table = calloc(1, sizeof(*table)); + + if (table != NULL) { + table->ht = hash_table_ctor(32, hash_table_string_hash, + hash_table_string_compare); + + _mesa_symbol_table_push_scope(table); + } + + return table; +} + + +void +_mesa_symbol_table_dtor(struct _mesa_symbol_table *table) +{ + while (table->current_scope != NULL) { + _mesa_symbol_table_pop_scope(table); + } + + hash_table_dtor(table->ht); + free(table); +} diff --git a/src/mesa/shader/symbol_table.h b/src/mesa/shader/symbol_table.h new file mode 100644 index 0000000000..0c054ef139 --- /dev/null +++ b/src/mesa/shader/symbol_table.h @@ -0,0 +1,55 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef MESA_SYMBOL_TABLE_H +#define MESA_SYMBOL_TABLE_H + +struct _mesa_symbol_table; +struct _mesa_symbol_table_iterator; + +extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table); + +extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table); + +extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab, + int name_space, const char *name, void *declaration); + +extern void *_mesa_symbol_table_find_symbol( + struct _mesa_symbol_table *symtab, int name_space, const char *name); + +extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void); + +extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *); + +extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor( + struct _mesa_symbol_table *table, int name_space, const char *name); + +extern void _mesa_symbol_table_iterator_dtor( + struct _mesa_symbol_table_iterator *); + +extern void *_mesa_symbol_table_iterator_get( + struct _mesa_symbol_table_iterator *iter); + +extern int _mesa_symbol_table_iterator_next( + struct _mesa_symbol_table_iterator *iter); + +#endif /* MESA_SYMBOL_TABLE_H */ |