Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. %{
  2. /*
  3.  * Copyright © 2009 Intel Corporation
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include <stdarg.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29.  
  30. #include "main/mtypes.h"
  31. #include "main/imports.h"
  32. #include "program/program.h"
  33. #include "program/prog_parameter.h"
  34. #include "program/prog_parameter_layout.h"
  35. #include "program/prog_statevars.h"
  36. #include "program/prog_instruction.h"
  37.  
  38. #include "program/symbol_table.h"
  39. #include "program/program_parser.h"
  40.  
  41. extern void *yy_scan_string(char *);
  42. extern void yy_delete_buffer(void *);
  43.  
  44. static struct asm_symbol *declare_variable(struct asm_parser_state *state,
  45.     char *name, enum asm_type t, struct YYLTYPE *locp);
  46.  
  47. static int add_state_reference(struct gl_program_parameter_list *param_list,
  48.     const gl_state_index tokens[STATE_LENGTH]);
  49.  
  50. static int initialize_symbol_from_state(struct gl_program *prog,
  51.     struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
  52.  
  53. static int initialize_symbol_from_param(struct gl_program *prog,
  54.     struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
  55.  
  56. static int initialize_symbol_from_const(struct gl_program *prog,
  57.     struct asm_symbol *param_var, const struct asm_vector *vec,
  58.     GLboolean allowSwizzle);
  59.  
  60. static int yyparse(struct asm_parser_state *state);
  61.  
  62. static char *make_error_string(const char *fmt, ...);
  63.  
  64. static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
  65.     const char *s);
  66.  
  67. static int validate_inputs(struct YYLTYPE *locp,
  68.     struct asm_parser_state *state);
  69.  
  70. static void init_dst_reg(struct prog_dst_register *r);
  71.  
  72. static void set_dst_reg(struct prog_dst_register *r,
  73.                         gl_register_file file, GLint index);
  74.  
  75. static void init_src_reg(struct asm_src_register *r);
  76.  
  77. static void set_src_reg(struct asm_src_register *r,
  78.                         gl_register_file file, GLint index);
  79.  
  80. static void set_src_reg_swz(struct asm_src_register *r,
  81.                             gl_register_file file, GLint index, GLuint swizzle);
  82.  
  83. static void asm_instruction_set_operands(struct asm_instruction *inst,
  84.     const struct prog_dst_register *dst, const struct asm_src_register *src0,
  85.     const struct asm_src_register *src1, const struct asm_src_register *src2);
  86.  
  87. static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
  88.     const struct prog_dst_register *dst, const struct asm_src_register *src0,
  89.     const struct asm_src_register *src1, const struct asm_src_register *src2);
  90.  
  91. static struct asm_instruction *asm_instruction_copy_ctor(
  92.     const struct prog_instruction *base, const struct prog_dst_register *dst,
  93.     const struct asm_src_register *src0, const struct asm_src_register *src1,
  94.     const struct asm_src_register *src2);
  95.  
  96. #ifndef FALSE
  97. #define FALSE 0
  98. #define TRUE (!FALSE)
  99. #endif
  100.  
  101. #define YYLLOC_DEFAULT(Current, Rhs, N)                                 \
  102.    do {                                                                 \
  103.       if (N) {                                                  \
  104.          (Current).first_line = YYRHSLOC(Rhs, 1).first_line;            \
  105.          (Current).first_column = YYRHSLOC(Rhs, 1).first_column;        \
  106.          (Current).position = YYRHSLOC(Rhs, 1).position;                \
  107.          (Current).last_line = YYRHSLOC(Rhs, N).last_line;              \
  108.          (Current).last_column = YYRHSLOC(Rhs, N).last_column;          \
  109.       } else {                                                          \
  110.          (Current).first_line = YYRHSLOC(Rhs, 0).last_line;             \
  111.          (Current).last_line = (Current).first_line;                    \
  112.          (Current).first_column = YYRHSLOC(Rhs, 0).last_column;         \
  113.          (Current).last_column = (Current).first_column;                \
  114.          (Current).position = YYRHSLOC(Rhs, 0).position                 \
  115.             + (Current).first_column;                                   \
  116.       }                                                                 \
  117.    } while(0)
  118. %}
  119.  
  120. %pure-parser
  121. %locations
  122. %lex-param   { struct asm_parser_state *state }
  123. %parse-param { struct asm_parser_state *state }
  124. %error-verbose
  125.  
  126. %union {
  127.    struct asm_instruction *inst;
  128.    struct asm_symbol *sym;
  129.    struct asm_symbol temp_sym;
  130.    struct asm_swizzle_mask swiz_mask;
  131.    struct asm_src_register src_reg;
  132.    struct prog_dst_register dst_reg;
  133.    struct prog_instruction temp_inst;
  134.    char *string;
  135.    unsigned result;
  136.    unsigned attrib;
  137.    int integer;
  138.    float real;
  139.    gl_state_index state[STATE_LENGTH];
  140.    int negate;
  141.    struct asm_vector vector;
  142.    gl_inst_opcode opcode;
  143.  
  144.    struct {
  145.       unsigned swz;
  146.       unsigned rgba_valid:1;
  147.       unsigned xyzw_valid:1;
  148.       unsigned negate:1;
  149.    } ext_swizzle;
  150. }
  151.  
  152. %token ARBvp_10 ARBfp_10
  153.  
  154. /* Tokens for assembler pseudo-ops */
  155. %token <integer> ADDRESS
  156. %token ALIAS ATTRIB
  157. %token OPTION OUTPUT
  158. %token PARAM
  159. %token <integer> TEMP
  160. %token END
  161.  
  162.  /* Tokens for instructions */
  163. %token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
  164. %token <temp_inst> ARL KIL SWZ TXD_OP
  165.  
  166. %token <integer> INTEGER
  167. %token <real> REAL
  168.  
  169. %token AMBIENT ATTENUATION
  170. %token BACK
  171. %token CLIP COLOR
  172. %token DEPTH DIFFUSE DIRECTION
  173. %token EMISSION ENV EYE
  174. %token FOG FOGCOORD FRAGMENT FRONT
  175. %token HALF
  176. %token INVERSE INVTRANS
  177. %token LIGHT LIGHTMODEL LIGHTPROD LOCAL
  178. %token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
  179. %token NORMAL
  180. %token OBJECT
  181. %token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
  182. %token RANGE RESULT ROW
  183. %token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE
  184. %token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
  185. %token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
  186. %token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
  187. %token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D
  188. %token VERTEX VTXATTRIB
  189. %token WEIGHT
  190.  
  191. %token <string> IDENTIFIER USED_IDENTIFIER
  192. %type <string> string
  193. %token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
  194. %token DOT_DOT
  195. %token DOT
  196.  
  197. %type <inst> instruction ALU_instruction TexInstruction
  198. %type <inst> ARL_instruction VECTORop_instruction
  199. %type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
  200. %type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction
  201. %type <inst> KIL_instruction
  202.  
  203. %type <dst_reg> dstReg maskedDstReg maskedAddrReg
  204. %type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg
  205. %type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
  206. %type <ext_swizzle> extSwizComp extSwizSel
  207. %type <swiz_mask> optionalMask
  208.  
  209. %type <sym> progParamArray
  210. %type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
  211. %type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel
  212. %type <sym> addrReg
  213. %type <swiz_mask> addrComponent addrWriteMask
  214.  
  215. %type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
  216.  
  217. %type <result> resultBinding resultColBinding
  218. %type <integer> optFaceType optColorType
  219. %type <integer> optResultFaceType optResultColorType
  220.  
  221. %type <integer> optTexImageUnitNum texImageUnitNum
  222. %type <integer> optTexCoordUnitNum texCoordUnitNum
  223. %type <integer> optLegacyTexUnitNum legacyTexUnitNum
  224. %type <integer> texImageUnit texTarget
  225. %type <integer> vtxAttribNum
  226.  
  227. %type <attrib> attribBinding vtxAttribItem fragAttribItem
  228.  
  229. %type <temp_sym> paramSingleInit paramSingleItemDecl
  230. %type <integer> optArraySize
  231.  
  232. %type <state> stateSingleItem stateMultipleItem
  233. %type <state> stateMaterialItem
  234. %type <state> stateLightItem stateLightModelItem stateLightProdItem
  235. %type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem
  236. %type <state> stateMatrixItem stateMatrixRow stateMatrixRows
  237. %type <state> stateTexEnvItem stateDepthItem
  238.  
  239. %type <state> stateLModProperty
  240. %type <state> stateMatrixName optMatrixRows
  241.  
  242. %type <integer> stateMatProperty
  243. %type <integer> stateLightProperty stateSpotProperty
  244. %type <integer> stateLightNumber stateLProdProperty
  245. %type <integer> stateTexGenType stateTexGenCoord
  246. %type <integer> stateTexEnvProperty
  247. %type <integer> stateFogProperty
  248. %type <integer> stateClipPlaneNum
  249. %type <integer> statePointProperty
  250.  
  251. %type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum
  252. %type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum
  253. %type <integer> stateProgramMatNum
  254.  
  255. %type <integer> ambDiffSpecProperty
  256.  
  257. %type <state> programSingleItem progEnvParam progLocalParam
  258. %type <state> programMultipleItem progEnvParams progLocalParams
  259.  
  260. %type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem
  261. %type <temp_sym> paramSingleItemUse
  262.  
  263. %type <integer> progEnvParamNum progLocalParamNum
  264. %type <state> progEnvParamNums progLocalParamNums
  265.  
  266. %type <vector> paramConstDecl paramConstUse
  267. %type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector
  268. %type <real> signedFloatConstant
  269. %type <negate> optionalSign
  270.  
  271. %{
  272. extern int
  273. _mesa_program_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
  274.                         void *yyscanner);
  275.  
  276. static int
  277. yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
  278.       struct asm_parser_state *state)
  279. {
  280.    return _mesa_program_lexer_lex(yylval_param, yylloc_param, state->scanner);
  281. }
  282. %}
  283.  
  284. %%
  285.  
  286. program: language optionSequence statementSequence END
  287.         ;
  288.  
  289. language: ARBvp_10
  290.         {
  291.            if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
  292.               yyerror(& @1, state, "invalid fragment program header");
  293.  
  294.            }
  295.            state->mode = ARB_vertex;
  296.         }
  297.         | ARBfp_10
  298.         {
  299.            if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
  300.               yyerror(& @1, state, "invalid vertex program header");
  301.            }
  302.            state->mode = ARB_fragment;
  303.  
  304.            state->option.TexRect =
  305.               (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
  306.         }
  307.         ;
  308.  
  309. optionSequence: optionSequence option
  310.         |
  311.         ;
  312.  
  313. option: OPTION string ';'
  314.         {
  315.            int valid = 0;
  316.  
  317.            if (state->mode == ARB_vertex) {
  318.               valid = _mesa_ARBvp_parse_option(state, $2);
  319.            } else if (state->mode == ARB_fragment) {
  320.               valid = _mesa_ARBfp_parse_option(state, $2);
  321.            }
  322.  
  323.  
  324.            free($2);
  325.  
  326.            if (!valid) {
  327.               const char *const err_str = (state->mode == ARB_vertex)
  328.                  ? "invalid ARB vertex program option"
  329.                  : "invalid ARB fragment program option";
  330.  
  331.               yyerror(& @2, state, err_str);
  332.               YYERROR;
  333.            }
  334.         }
  335.         ;
  336.  
  337. statementSequence: statementSequence statement
  338.         |
  339.         ;
  340.  
  341. statement: instruction ';'
  342.         {
  343.            if ($1 != NULL) {
  344.               if (state->inst_tail == NULL) {
  345.                  state->inst_head = $1;
  346.               } else {
  347.                  state->inst_tail->next = $1;
  348.               }
  349.  
  350.               state->inst_tail = $1;
  351.               $1->next = NULL;
  352.  
  353.               state->prog->NumInstructions++;
  354.            }
  355.         }
  356.         | namingStatement ';'
  357.         ;
  358.  
  359. instruction: ALU_instruction
  360.         {
  361.            $$ = $1;
  362.            state->prog->NumAluInstructions++;
  363.         }
  364.         | TexInstruction
  365.         {
  366.            $$ = $1;
  367.            state->prog->NumTexInstructions++;
  368.         }
  369.         ;
  370.  
  371. ALU_instruction: ARL_instruction
  372.         | VECTORop_instruction
  373.         | SCALARop_instruction
  374.         | BINSCop_instruction
  375.         | BINop_instruction
  376.         | TRIop_instruction
  377.         | SWZ_instruction
  378.         ;
  379.  
  380. TexInstruction: SAMPLE_instruction
  381.         | KIL_instruction
  382.         | TXD_instruction
  383.         ;
  384.  
  385. ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
  386.         {
  387.            $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL);
  388.         }
  389.         ;
  390.  
  391. VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
  392.         {
  393.            if ($1.Opcode == OPCODE_DDY)
  394.               state->fragment.UsesDFdy = 1;
  395.            $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
  396.         }
  397.         ;
  398.  
  399. SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
  400.         {
  401.            $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
  402.         }
  403.         ;
  404.  
  405. BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
  406.         {
  407.            $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
  408.         }
  409.         ;
  410.  
  411.  
  412. BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
  413.         {
  414.            $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
  415.         }
  416.         ;
  417.  
  418. TRIop_instruction: TRI_OP maskedDstReg ','
  419.                    swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
  420.         {
  421.            $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
  422.         }
  423.         ;
  424.  
  425. SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
  426.         {
  427.            $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
  428.            if ($$ != NULL) {
  429.               const GLbitfield tex_mask = (1U << $6);
  430.               GLbitfield shadow_tex = 0;
  431.               GLbitfield target_mask = 0;
  432.  
  433.  
  434.               $$->Base.TexSrcUnit = $6;
  435.  
  436.               if ($8 < 0) {
  437.                  shadow_tex = tex_mask;
  438.  
  439.                  $$->Base.TexSrcTarget = -$8;
  440.                  $$->Base.TexShadow = 1;
  441.               } else {
  442.                  $$->Base.TexSrcTarget = $8;
  443.               }
  444.  
  445.               target_mask = (1U << $$->Base.TexSrcTarget);
  446.  
  447.               /* If this texture unit was previously accessed and that access
  448.                * had a different texture target, generate an error.
  449.                *
  450.                * If this texture unit was previously accessed and that access
  451.                * had a different shadow mode, generate an error.
  452.                */
  453.               if ((state->prog->TexturesUsed[$6] != 0)
  454.                   && ((state->prog->TexturesUsed[$6] != target_mask)
  455.                       || ((state->prog->ShadowSamplers & tex_mask)
  456.                           != shadow_tex))) {
  457.                  yyerror(& @8, state,
  458.                          "multiple targets used on one texture image unit");
  459.                  YYERROR;
  460.               }
  461.  
  462.  
  463.               state->prog->TexturesUsed[$6] |= target_mask;
  464.               state->prog->ShadowSamplers |= shadow_tex;
  465.            }
  466.         }
  467.         ;
  468.  
  469. KIL_instruction: KIL swizzleSrcReg
  470.         {
  471.            $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
  472.            state->fragment.UsesKill = 1;
  473.         }
  474.         | KIL ccTest
  475.         {
  476.            $$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
  477.            $$->Base.DstReg.CondMask = $2.CondMask;
  478.            $$->Base.DstReg.CondSwizzle = $2.CondSwizzle;
  479.            state->fragment.UsesKill = 1;
  480.         }
  481.         ;
  482.  
  483. TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
  484.         {
  485.            $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
  486.            if ($$ != NULL) {
  487.               const GLbitfield tex_mask = (1U << $10);
  488.               GLbitfield shadow_tex = 0;
  489.               GLbitfield target_mask = 0;
  490.  
  491.  
  492.               $$->Base.TexSrcUnit = $10;
  493.  
  494.               if ($12 < 0) {
  495.                  shadow_tex = tex_mask;
  496.  
  497.                  $$->Base.TexSrcTarget = -$12;
  498.                  $$->Base.TexShadow = 1;
  499.               } else {
  500.                  $$->Base.TexSrcTarget = $12;
  501.               }
  502.  
  503.               target_mask = (1U << $$->Base.TexSrcTarget);
  504.  
  505.               /* If this texture unit was previously accessed and that access
  506.                * had a different texture target, generate an error.
  507.                *
  508.                * If this texture unit was previously accessed and that access
  509.                * had a different shadow mode, generate an error.
  510.                */
  511.               if ((state->prog->TexturesUsed[$10] != 0)
  512.                   && ((state->prog->TexturesUsed[$10] != target_mask)
  513.                       || ((state->prog->ShadowSamplers & tex_mask)
  514.                           != shadow_tex))) {
  515.                  yyerror(& @12, state,
  516.                          "multiple targets used on one texture image unit");
  517.                  YYERROR;
  518.               }
  519.  
  520.  
  521.               state->prog->TexturesUsed[$10] |= target_mask;
  522.               state->prog->ShadowSamplers |= shadow_tex;
  523.            }
  524.         }
  525.         ;
  526.  
  527. texImageUnit: TEXTURE_UNIT optTexImageUnitNum
  528.         {
  529.            $$ = $2;
  530.         }
  531.         ;
  532.  
  533. texTarget: TEX_1D  { $$ = TEXTURE_1D_INDEX; }
  534.         | TEX_2D   { $$ = TEXTURE_2D_INDEX; }
  535.         | TEX_3D   { $$ = TEXTURE_3D_INDEX; }
  536.         | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; }
  537.         | TEX_RECT { $$ = TEXTURE_RECT_INDEX; }
  538.         | TEX_SHADOW1D   { $$ = -TEXTURE_1D_INDEX; }
  539.         | TEX_SHADOW2D   { $$ = -TEXTURE_2D_INDEX; }
  540.         | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; }
  541.         | TEX_ARRAY1D         { $$ = TEXTURE_1D_ARRAY_INDEX; }
  542.         | TEX_ARRAY2D         { $$ = TEXTURE_2D_ARRAY_INDEX; }
  543.         | TEX_ARRAYSHADOW1D   { $$ = -TEXTURE_1D_ARRAY_INDEX; }
  544.         | TEX_ARRAYSHADOW2D   { $$ = -TEXTURE_2D_ARRAY_INDEX; }
  545.         ;
  546.  
  547. SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
  548.         {
  549.            /* FIXME: Is this correct?  Should the extenedSwizzle be applied
  550.             * FIXME: to the existing swizzle?
  551.             */
  552.            $4.Base.Swizzle = $6.swizzle;
  553.            $4.Base.Negate = $6.mask;
  554.  
  555.            $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
  556.         }
  557.         ;
  558.  
  559. scalarSrcReg: optionalSign scalarUse
  560.         {
  561.            $$ = $2;
  562.  
  563.            if ($1) {
  564.               $$.Base.Negate = ~$$.Base.Negate;
  565.            }
  566.         }
  567.         | optionalSign '|' scalarUse '|'
  568.         {
  569.            $$ = $3;
  570.  
  571.            if (!state->option.NV_fragment) {
  572.               yyerror(& @2, state, "unexpected character '|'");
  573.               YYERROR;
  574.            }
  575.  
  576.            if ($1) {
  577.               $$.Base.Negate = ~$$.Base.Negate;
  578.            }
  579.  
  580.            $$.Base.Abs = 1;
  581.         }
  582.         ;
  583.  
  584. scalarUse:  srcReg scalarSuffix
  585.         {
  586.            $$ = $1;
  587.  
  588.            $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
  589.                                                     $2.swizzle);
  590.         }
  591.         | paramConstScalarUse
  592.         {
  593.            struct asm_symbol temp_sym;
  594.  
  595.            if (!state->option.NV_fragment) {
  596.               yyerror(& @1, state, "expected scalar suffix");
  597.               YYERROR;
  598.            }
  599.  
  600.            memset(& temp_sym, 0, sizeof(temp_sym));
  601.            temp_sym.param_binding_begin = ~0;
  602.            initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE);
  603.  
  604.            set_src_reg_swz(& $$, PROGRAM_CONSTANT,
  605.                            temp_sym.param_binding_begin,
  606.                            temp_sym.param_binding_swizzle);
  607.         }
  608.         ;
  609.  
  610. swizzleSrcReg: optionalSign srcReg swizzleSuffix
  611.         {
  612.            $$ = $2;
  613.  
  614.            if ($1) {
  615.               $$.Base.Negate = ~$$.Base.Negate;
  616.            }
  617.  
  618.            $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
  619.                                                     $3.swizzle);
  620.         }
  621.         | optionalSign '|' srcReg swizzleSuffix '|'
  622.         {
  623.            $$ = $3;
  624.  
  625.            if (!state->option.NV_fragment) {
  626.               yyerror(& @2, state, "unexpected character '|'");
  627.               YYERROR;
  628.            }
  629.  
  630.            if ($1) {
  631.               $$.Base.Negate = ~$$.Base.Negate;
  632.            }
  633.  
  634.            $$.Base.Abs = 1;
  635.            $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
  636.                                                     $4.swizzle);
  637.         }
  638.  
  639.         ;
  640.  
  641. maskedDstReg: dstReg optionalMask optionalCcMask
  642.         {
  643.            $$ = $1;
  644.            $$.WriteMask = $2.mask;
  645.            $$.CondMask = $3.CondMask;
  646.            $$.CondSwizzle = $3.CondSwizzle;
  647.  
  648.            if ($$.File == PROGRAM_OUTPUT) {
  649.               /* Technically speaking, this should check that it is in
  650.                * vertex program mode.  However, PositionInvariant can never be
  651.                * set in fragment program mode, so it is somewhat irrelevant.
  652.                */
  653.               if (state->option.PositionInvariant
  654.                && ($$.Index == VARYING_SLOT_POS)) {
  655.                  yyerror(& @1, state, "position-invariant programs cannot "
  656.                          "write position");
  657.                  YYERROR;
  658.               }
  659.  
  660.               state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
  661.            }
  662.         }
  663.         ;
  664.  
  665. maskedAddrReg: addrReg addrWriteMask
  666.         {
  667.            set_dst_reg(& $$, PROGRAM_ADDRESS, 0);
  668.            $$.WriteMask = $2.mask;
  669.         }
  670.         ;
  671.  
  672. extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
  673.         {
  674.            const unsigned xyzw_valid =
  675.               ($1.xyzw_valid << 0)
  676.               | ($3.xyzw_valid << 1)
  677.               | ($5.xyzw_valid << 2)
  678.               | ($7.xyzw_valid << 3);
  679.            const unsigned rgba_valid =
  680.               ($1.rgba_valid << 0)
  681.               | ($3.rgba_valid << 1)
  682.               | ($5.rgba_valid << 2)
  683.               | ($7.rgba_valid << 3);
  684.  
  685.            /* All of the swizzle components have to be valid in either RGBA
  686.             * or XYZW.  Note that 0 and 1 are valid in both, so both masks
  687.             * can have some bits set.
  688.             *
  689.             * We somewhat deviate from the spec here.  It would be really hard
  690.             * to figure out which component is the error, and there probably
  691.             * isn't a lot of benefit.
  692.             */
  693.            if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
  694.               yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle "
  695.                       "components");
  696.               YYERROR;
  697.            }
  698.  
  699.            $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz);
  700.            $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2)
  701.               | ($7.negate << 3);
  702.         }
  703.         ;
  704.  
  705. extSwizComp: optionalSign extSwizSel
  706.         {
  707.            $$ = $2;
  708.            $$.negate = ($1) ? 1 : 0;
  709.         }
  710.         ;
  711.  
  712. extSwizSel: INTEGER
  713.         {
  714.            if (($1 != 0) && ($1 != 1)) {
  715.               yyerror(& @1, state, "invalid extended swizzle selector");
  716.               YYERROR;
  717.            }
  718.  
  719.            $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
  720.            $$.negate = 0;
  721.  
  722.            /* 0 and 1 are valid for both RGBA swizzle names and XYZW
  723.             * swizzle names.
  724.             */
  725.            $$.xyzw_valid = 1;
  726.            $$.rgba_valid = 1;
  727.         }
  728.         | string
  729.         {
  730.            char s;
  731.  
  732.            if (strlen($1) > 1) {
  733.               yyerror(& @1, state, "invalid extended swizzle selector");
  734.               YYERROR;
  735.            }
  736.  
  737.            s = $1[0];
  738.            free($1);
  739.  
  740.            $$.rgba_valid = 0;
  741.            $$.xyzw_valid = 0;
  742.            $$.negate = 0;
  743.  
  744.            switch (s) {
  745.            case 'x':
  746.               $$.swz = SWIZZLE_X;
  747.               $$.xyzw_valid = 1;
  748.               break;
  749.            case 'y':
  750.               $$.swz = SWIZZLE_Y;
  751.               $$.xyzw_valid = 1;
  752.               break;
  753.            case 'z':
  754.               $$.swz = SWIZZLE_Z;
  755.               $$.xyzw_valid = 1;
  756.               break;
  757.            case 'w':
  758.               $$.swz = SWIZZLE_W;
  759.               $$.xyzw_valid = 1;
  760.               break;
  761.  
  762.            case 'r':
  763.               $$.swz = SWIZZLE_X;
  764.               $$.rgba_valid = 1;
  765.               break;
  766.            case 'g':
  767.               $$.swz = SWIZZLE_Y;
  768.               $$.rgba_valid = 1;
  769.               break;
  770.            case 'b':
  771.               $$.swz = SWIZZLE_Z;
  772.               $$.rgba_valid = 1;
  773.               break;
  774.            case 'a':
  775.               $$.swz = SWIZZLE_W;
  776.               $$.rgba_valid = 1;
  777.               break;
  778.  
  779.            default:
  780.               yyerror(& @1, state, "invalid extended swizzle selector");
  781.               YYERROR;
  782.               break;
  783.            }
  784.         }
  785.         ;
  786.  
  787. srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
  788.         {
  789.            struct asm_symbol *const s = (struct asm_symbol *)
  790.               _mesa_symbol_table_find_symbol(state->st, 0, $1);
  791.  
  792.            free($1);
  793.  
  794.            if (s == NULL) {
  795.               yyerror(& @1, state, "invalid operand variable");
  796.               YYERROR;
  797.            } else if ((s->type != at_param) && (s->type != at_temp)
  798.                       && (s->type != at_attrib)) {
  799.               yyerror(& @1, state, "invalid operand variable");
  800.               YYERROR;
  801.            } else if ((s->type == at_param) && s->param_is_array) {
  802.               yyerror(& @1, state, "non-array access to array PARAM");
  803.               YYERROR;
  804.            }
  805.  
  806.            init_src_reg(& $$);
  807.            switch (s->type) {
  808.            case at_temp:
  809.               set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
  810.               break;
  811.            case at_param:
  812.               set_src_reg_swz(& $$, s->param_binding_type,
  813.                               s->param_binding_begin,
  814.                               s->param_binding_swizzle);
  815.               break;
  816.            case at_attrib:
  817.               set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
  818.               state->prog->InputsRead |= BITFIELD64_BIT($$.Base.Index);
  819.  
  820.               if (!validate_inputs(& @1, state)) {
  821.                  YYERROR;
  822.               }
  823.               break;
  824.  
  825.            default:
  826.               YYERROR;
  827.               break;
  828.            }
  829.         }
  830.         | attribBinding
  831.         {
  832.            set_src_reg(& $$, PROGRAM_INPUT, $1);
  833.            state->prog->InputsRead |= BITFIELD64_BIT($$.Base.Index);
  834.  
  835.            if (!validate_inputs(& @1, state)) {
  836.               YYERROR;
  837.            }
  838.         }
  839.         | progParamArray '[' progParamArrayMem ']'
  840.         {
  841.            if (! $3.Base.RelAddr
  842.                && ((unsigned) $3.Base.Index >= $1->param_binding_length)) {
  843.               yyerror(& @3, state, "out of bounds array access");
  844.               YYERROR;
  845.            }
  846.  
  847.            init_src_reg(& $$);
  848.            $$.Base.File = $1->param_binding_type;
  849.  
  850.            if ($3.Base.RelAddr) {
  851.               state->prog->IndirectRegisterFiles |= (1 << $$.Base.File);
  852.               $1->param_accessed_indirectly = 1;
  853.  
  854.               $$.Base.RelAddr = 1;
  855.               $$.Base.Index = $3.Base.Index;
  856.               $$.Symbol = $1;
  857.            } else {
  858.               $$.Base.Index = $1->param_binding_begin + $3.Base.Index;
  859.            }
  860.         }
  861.         | paramSingleItemUse
  862.         {
  863.            gl_register_file file = ($1.name != NULL)
  864.               ? $1.param_binding_type
  865.               : PROGRAM_CONSTANT;
  866.            set_src_reg_swz(& $$, file, $1.param_binding_begin,
  867.                            $1.param_binding_swizzle);
  868.         }
  869.         ;
  870.  
  871. dstReg: resultBinding
  872.         {
  873.            set_dst_reg(& $$, PROGRAM_OUTPUT, $1);
  874.         }
  875.         | USED_IDENTIFIER /* temporaryReg | vertexResultReg */
  876.         {
  877.            struct asm_symbol *const s = (struct asm_symbol *)
  878.               _mesa_symbol_table_find_symbol(state->st, 0, $1);
  879.  
  880.            free($1);
  881.  
  882.            if (s == NULL) {
  883.               yyerror(& @1, state, "invalid operand variable");
  884.               YYERROR;
  885.            } else if ((s->type != at_output) && (s->type != at_temp)) {
  886.               yyerror(& @1, state, "invalid operand variable");
  887.               YYERROR;
  888.            }
  889.  
  890.            switch (s->type) {
  891.            case at_temp:
  892.               set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
  893.               break;
  894.            case at_output:
  895.               set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding);
  896.               break;
  897.            default:
  898.               set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin);
  899.               break;
  900.            }
  901.         }
  902.         ;
  903.  
  904. progParamArray: USED_IDENTIFIER
  905.         {
  906.            struct asm_symbol *const s = (struct asm_symbol *)
  907.               _mesa_symbol_table_find_symbol(state->st, 0, $1);
  908.  
  909.            free($1);
  910.  
  911.            if (s == NULL) {
  912.               yyerror(& @1, state, "invalid operand variable");
  913.               YYERROR;
  914.            } else if ((s->type != at_param) || !s->param_is_array) {
  915.               yyerror(& @1, state, "array access to non-PARAM variable");
  916.               YYERROR;
  917.            } else {
  918.               $$ = s;
  919.            }
  920.         }
  921.         ;
  922.  
  923. progParamArrayMem: progParamArrayAbs | progParamArrayRel;
  924.  
  925. progParamArrayAbs: INTEGER
  926.         {
  927.            init_src_reg(& $$);
  928.            $$.Base.Index = $1;
  929.         }
  930.         ;
  931.  
  932. progParamArrayRel: addrReg addrComponent addrRegRelOffset
  933.         {
  934.            /* FINISHME: Add support for multiple address registers.
  935.             */
  936.            /* FINISHME: Add support for 4-component address registers.
  937.             */
  938.            init_src_reg(& $$);
  939.            $$.Base.RelAddr = 1;
  940.            $$.Base.Index = $3;
  941.         }
  942.         ;
  943.  
  944. addrRegRelOffset:              { $$ = 0; }
  945.         | '+' addrRegPosOffset { $$ = $2; }
  946.         | '-' addrRegNegOffset { $$ = -$2; }
  947.         ;
  948.  
  949. addrRegPosOffset: INTEGER
  950.         {
  951.            if (($1 < 0) || ($1 > (state->limits->MaxAddressOffset - 1))) {
  952.               char s[100];
  953.               _mesa_snprintf(s, sizeof(s),
  954.                              "relative address offset too large (%d)", $1);
  955.               yyerror(& @1, state, s);
  956.               YYERROR;
  957.            } else {
  958.               $$ = $1;
  959.            }
  960.         }
  961.         ;
  962.  
  963. addrRegNegOffset: INTEGER
  964.         {
  965.            if (($1 < 0) || ($1 > state->limits->MaxAddressOffset)) {
  966.               char s[100];
  967.               _mesa_snprintf(s, sizeof(s),
  968.                              "relative address offset too large (%d)", $1);
  969.               yyerror(& @1, state, s);
  970.               YYERROR;
  971.            } else {
  972.               $$ = $1;
  973.            }
  974.         }
  975.         ;
  976.  
  977. addrReg: USED_IDENTIFIER
  978.         {
  979.            struct asm_symbol *const s = (struct asm_symbol *)
  980.               _mesa_symbol_table_find_symbol(state->st, 0, $1);
  981.  
  982.            free($1);
  983.  
  984.            if (s == NULL) {
  985.               yyerror(& @1, state, "invalid array member");
  986.               YYERROR;
  987.            } else if (s->type != at_address) {
  988.               yyerror(& @1, state,
  989.                       "invalid variable for indexed array access");
  990.               YYERROR;
  991.            } else {
  992.               $$ = s;
  993.            }
  994.         }
  995.         ;
  996.  
  997. addrComponent: MASK1
  998.         {
  999.            if ($1.mask != WRITEMASK_X) {
  1000.               yyerror(& @1, state, "invalid address component selector");
  1001.               YYERROR;
  1002.            } else {
  1003.               $$ = $1;
  1004.            }
  1005.         }
  1006.         ;
  1007.  
  1008. addrWriteMask: MASK1
  1009.         {
  1010.            if ($1.mask != WRITEMASK_X) {
  1011.               yyerror(& @1, state,
  1012.                       "address register write mask must be \".x\"");
  1013.               YYERROR;
  1014.            } else {
  1015.               $$ = $1;
  1016.            }
  1017.         }
  1018.         ;
  1019.  
  1020. scalarSuffix: MASK1;
  1021.  
  1022. swizzleSuffix: MASK1
  1023.         | MASK4
  1024.         | SWIZZLE
  1025.         |              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
  1026.         ;
  1027.  
  1028. optionalMask: MASK4 | MASK3 | MASK2 | MASK1
  1029.         |              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
  1030.         ;
  1031.  
  1032. optionalCcMask: '(' ccTest ')'
  1033.         {
  1034.            $$ = $2;
  1035.         }
  1036.         | '(' ccTest2 ')'
  1037.         {
  1038.            $$ = $2;
  1039.         }
  1040.         |
  1041.         {
  1042.            $$.CondMask = COND_TR;
  1043.            $$.CondSwizzle = SWIZZLE_NOOP;
  1044.         }
  1045.         ;
  1046.  
  1047. ccTest: ccMaskRule swizzleSuffix
  1048.         {
  1049.            $$ = $1;
  1050.            $$.CondSwizzle = $2.swizzle;
  1051.         }
  1052.         ;
  1053.  
  1054. ccTest2: ccMaskRule2 swizzleSuffix
  1055.         {
  1056.            $$ = $1;
  1057.            $$.CondSwizzle = $2.swizzle;
  1058.         }
  1059.         ;
  1060.  
  1061. ccMaskRule: IDENTIFIER
  1062.         {
  1063.            const int cond = _mesa_parse_cc($1);
  1064.            if ((cond == 0) || ($1[2] != '\0')) {
  1065.               char *const err_str =
  1066.                  make_error_string("invalid condition code \"%s\"", $1);
  1067.  
  1068.               yyerror(& @1, state, (err_str != NULL)
  1069.                       ? err_str : "invalid condition code");
  1070.  
  1071.               if (err_str != NULL) {
  1072.                  free(err_str);
  1073.               }
  1074.  
  1075.               YYERROR;
  1076.            }
  1077.  
  1078.            $$.CondMask = cond;
  1079.            $$.CondSwizzle = SWIZZLE_NOOP;
  1080.         }
  1081.         ;
  1082.  
  1083. ccMaskRule2: USED_IDENTIFIER
  1084.         {
  1085.            const int cond = _mesa_parse_cc($1);
  1086.            if ((cond == 0) || ($1[2] != '\0')) {
  1087.               char *const err_str =
  1088.                  make_error_string("invalid condition code \"%s\"", $1);
  1089.  
  1090.               yyerror(& @1, state, (err_str != NULL)
  1091.                       ? err_str : "invalid condition code");
  1092.  
  1093.               if (err_str != NULL) {
  1094.                  free(err_str);
  1095.               }
  1096.  
  1097.               YYERROR;
  1098.            }
  1099.  
  1100.            $$.CondMask = cond;
  1101.            $$.CondSwizzle = SWIZZLE_NOOP;
  1102.         }
  1103.         ;
  1104.  
  1105. namingStatement: ATTRIB_statement
  1106.         | PARAM_statement
  1107.         | TEMP_statement
  1108.         | ADDRESS_statement
  1109.         | OUTPUT_statement
  1110.         | ALIAS_statement
  1111.         ;
  1112.  
  1113. ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
  1114.         {
  1115.            struct asm_symbol *const s =
  1116.               declare_variable(state, $2, at_attrib, & @2);
  1117.  
  1118.            if (s == NULL) {
  1119.               free($2);
  1120.               YYERROR;
  1121.            } else {
  1122.               s->attrib_binding = $4;
  1123.               state->InputsBound |= BITFIELD64_BIT(s->attrib_binding);
  1124.  
  1125.               if (!validate_inputs(& @4, state)) {
  1126.                  YYERROR;
  1127.               }
  1128.            }
  1129.         }
  1130.         ;
  1131.  
  1132. attribBinding: VERTEX vtxAttribItem
  1133.         {
  1134.            $$ = $2;
  1135.         }
  1136.         | FRAGMENT fragAttribItem
  1137.         {
  1138.            $$ = $2;
  1139.         }
  1140.         ;
  1141.  
  1142. vtxAttribItem: POSITION
  1143.         {
  1144.            $$ = VERT_ATTRIB_POS;
  1145.         }
  1146.         | WEIGHT vtxOptWeightNum
  1147.         {
  1148.            $$ = VERT_ATTRIB_WEIGHT;
  1149.         }
  1150.         | NORMAL
  1151.         {
  1152.            $$ = VERT_ATTRIB_NORMAL;
  1153.         }
  1154.         | COLOR optColorType
  1155.         {
  1156.            $$ = VERT_ATTRIB_COLOR0 + $2;
  1157.         }
  1158.         | FOGCOORD
  1159.         {
  1160.            $$ = VERT_ATTRIB_FOG;
  1161.         }
  1162.         | TEXCOORD optTexCoordUnitNum
  1163.         {
  1164.            $$ = VERT_ATTRIB_TEX0 + $2;
  1165.         }
  1166.         | MATRIXINDEX '[' vtxWeightNum ']'
  1167.         {
  1168.            yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
  1169.            YYERROR;
  1170.         }
  1171.         | VTXATTRIB '[' vtxAttribNum ']'
  1172.         {
  1173.            $$ = VERT_ATTRIB_GENERIC0 + $3;
  1174.         }
  1175.         ;
  1176.  
  1177. vtxAttribNum: INTEGER
  1178.         {
  1179.            if ((unsigned) $1 >= state->limits->MaxAttribs) {
  1180.               yyerror(& @1, state, "invalid vertex attribute reference");
  1181.               YYERROR;
  1182.            }
  1183.  
  1184.            $$ = $1;
  1185.         }
  1186.         ;
  1187.  
  1188. vtxOptWeightNum:  | '[' vtxWeightNum ']';
  1189. vtxWeightNum: INTEGER;
  1190.  
  1191. fragAttribItem: POSITION
  1192.         {
  1193.            $$ = VARYING_SLOT_POS;
  1194.         }
  1195.         | COLOR optColorType
  1196.         {
  1197.            $$ = VARYING_SLOT_COL0 + $2;
  1198.         }
  1199.         | FOGCOORD
  1200.         {
  1201.            $$ = VARYING_SLOT_FOGC;
  1202.         }
  1203.         | TEXCOORD optTexCoordUnitNum
  1204.         {
  1205.            $$ = VARYING_SLOT_TEX0 + $2;
  1206.         }
  1207.         ;
  1208.  
  1209. PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt;
  1210.  
  1211. PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
  1212.         {
  1213.            struct asm_symbol *const s =
  1214.               declare_variable(state, $2, at_param, & @2);
  1215.  
  1216.            if (s == NULL) {
  1217.               free($2);
  1218.               YYERROR;
  1219.            } else {
  1220.               s->param_binding_type = $3.param_binding_type;
  1221.               s->param_binding_begin = $3.param_binding_begin;
  1222.               s->param_binding_length = $3.param_binding_length;
  1223.               s->param_binding_swizzle = $3.param_binding_swizzle;
  1224.               s->param_is_array = 0;
  1225.            }
  1226.         }
  1227.         ;
  1228.  
  1229. PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
  1230.         {
  1231.            if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
  1232.               free($2);
  1233.               yyerror(& @4, state,
  1234.                       "parameter array size and number of bindings must match");
  1235.               YYERROR;
  1236.            } else {
  1237.               struct asm_symbol *const s =
  1238.                  declare_variable(state, $2, $6.type, & @2);
  1239.  
  1240.               if (s == NULL) {
  1241.                  free($2);
  1242.                  YYERROR;
  1243.               } else {
  1244.                  s->param_binding_type = $6.param_binding_type;
  1245.                  s->param_binding_begin = $6.param_binding_begin;
  1246.                  s->param_binding_length = $6.param_binding_length;
  1247.                  s->param_binding_swizzle = SWIZZLE_XYZW;
  1248.                  s->param_is_array = 1;
  1249.               }
  1250.            }
  1251.         }
  1252.         ;
  1253.  
  1254. optArraySize:
  1255.         {
  1256.            $$ = 0;
  1257.         }
  1258.         | INTEGER
  1259.         {
  1260.            if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
  1261.               char msg[100];
  1262.               _mesa_snprintf(msg, sizeof(msg),
  1263.                              "invalid parameter array size (size=%d max=%u)",
  1264.                              $1, state->limits->MaxParameters);
  1265.               yyerror(& @1, state, msg);
  1266.               YYERROR;
  1267.            } else {
  1268.               $$ = $1;
  1269.            }
  1270.         }
  1271.         ;
  1272.  
  1273. paramSingleInit: '=' paramSingleItemDecl
  1274.         {
  1275.            $$ = $2;
  1276.         }
  1277.         ;
  1278.  
  1279. paramMultipleInit: '=' '{' paramMultInitList '}'
  1280.         {
  1281.            $$ = $3;
  1282.         }
  1283.         ;
  1284.  
  1285. paramMultInitList: paramMultipleItem
  1286.         | paramMultInitList ',' paramMultipleItem
  1287.         {
  1288.            $1.param_binding_length += $3.param_binding_length;
  1289.            $$ = $1;
  1290.         }
  1291.         ;
  1292.  
  1293. paramSingleItemDecl: stateSingleItem
  1294.         {
  1295.            memset(& $$, 0, sizeof($$));
  1296.            $$.param_binding_begin = ~0;
  1297.            initialize_symbol_from_state(state->prog, & $$, $1);
  1298.         }
  1299.         | programSingleItem
  1300.         {
  1301.            memset(& $$, 0, sizeof($$));
  1302.            $$.param_binding_begin = ~0;
  1303.            initialize_symbol_from_param(state->prog, & $$, $1);
  1304.         }
  1305.         | paramConstDecl
  1306.         {
  1307.            memset(& $$, 0, sizeof($$));
  1308.            $$.param_binding_begin = ~0;
  1309.            initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
  1310.         }
  1311.         ;
  1312.  
  1313. paramSingleItemUse: stateSingleItem
  1314.         {
  1315.            memset(& $$, 0, sizeof($$));
  1316.            $$.param_binding_begin = ~0;
  1317.            initialize_symbol_from_state(state->prog, & $$, $1);
  1318.         }
  1319.         | programSingleItem
  1320.         {
  1321.            memset(& $$, 0, sizeof($$));
  1322.            $$.param_binding_begin = ~0;
  1323.            initialize_symbol_from_param(state->prog, & $$, $1);
  1324.         }
  1325.         | paramConstUse
  1326.         {
  1327.            memset(& $$, 0, sizeof($$));
  1328.            $$.param_binding_begin = ~0;
  1329.            initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
  1330.         }
  1331.         ;
  1332.  
  1333. paramMultipleItem: stateMultipleItem
  1334.         {
  1335.            memset(& $$, 0, sizeof($$));
  1336.            $$.param_binding_begin = ~0;
  1337.            initialize_symbol_from_state(state->prog, & $$, $1);
  1338.         }
  1339.         | programMultipleItem
  1340.         {
  1341.            memset(& $$, 0, sizeof($$));
  1342.            $$.param_binding_begin = ~0;
  1343.            initialize_symbol_from_param(state->prog, & $$, $1);
  1344.         }
  1345.         | paramConstDecl
  1346.         {
  1347.            memset(& $$, 0, sizeof($$));
  1348.            $$.param_binding_begin = ~0;
  1349.            initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE);
  1350.         }
  1351.         ;
  1352.  
  1353. stateMultipleItem: stateSingleItem        { memcpy($$, $1, sizeof($$)); }
  1354.         | STATE stateMatrixRows           { memcpy($$, $2, sizeof($$)); }
  1355.         ;
  1356.  
  1357. stateSingleItem: STATE stateMaterialItem  { memcpy($$, $2, sizeof($$)); }
  1358.         | STATE stateLightItem            { memcpy($$, $2, sizeof($$)); }
  1359.         | STATE stateLightModelItem       { memcpy($$, $2, sizeof($$)); }
  1360.         | STATE stateLightProdItem        { memcpy($$, $2, sizeof($$)); }
  1361.         | STATE stateTexGenItem           { memcpy($$, $2, sizeof($$)); }
  1362.         | STATE stateTexEnvItem           { memcpy($$, $2, sizeof($$)); }
  1363.         | STATE stateFogItem              { memcpy($$, $2, sizeof($$)); }
  1364.         | STATE stateClipPlaneItem        { memcpy($$, $2, sizeof($$)); }
  1365.         | STATE statePointItem            { memcpy($$, $2, sizeof($$)); }
  1366.         | STATE stateMatrixRow            { memcpy($$, $2, sizeof($$)); }
  1367.         | STATE stateDepthItem            { memcpy($$, $2, sizeof($$)); }
  1368.         ;
  1369.  
  1370. stateMaterialItem: MATERIAL optFaceType stateMatProperty
  1371.         {
  1372.            memset($$, 0, sizeof($$));
  1373.            $$[0] = STATE_MATERIAL;
  1374.            $$[1] = $2;
  1375.            $$[2] = $3;
  1376.         }
  1377.         ;
  1378.  
  1379. stateMatProperty: ambDiffSpecProperty
  1380.         {
  1381.            $$ = $1;
  1382.         }
  1383.         | EMISSION
  1384.         {
  1385.            $$ = STATE_EMISSION;
  1386.         }
  1387.         | SHININESS
  1388.         {
  1389.            $$ = STATE_SHININESS;
  1390.         }
  1391.         ;
  1392.  
  1393. stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
  1394.         {
  1395.            memset($$, 0, sizeof($$));
  1396.            $$[0] = STATE_LIGHT;
  1397.            $$[1] = $3;
  1398.            $$[2] = $5;
  1399.         }
  1400.         ;
  1401.  
  1402. stateLightProperty: ambDiffSpecProperty
  1403.         {
  1404.            $$ = $1;
  1405.         }
  1406.         | POSITION
  1407.         {
  1408.            $$ = STATE_POSITION;
  1409.         }
  1410.         | ATTENUATION
  1411.         {
  1412.            if (!state->ctx->Extensions.EXT_point_parameters) {
  1413.               yyerror(& @1, state, "GL_ARB_point_parameters not supported");
  1414.               YYERROR;
  1415.            }
  1416.  
  1417.            $$ = STATE_ATTENUATION;
  1418.         }
  1419.         | SPOT stateSpotProperty
  1420.         {
  1421.            $$ = $2;
  1422.         }
  1423.         | HALF
  1424.         {
  1425.            $$ = STATE_HALF_VECTOR;
  1426.         }
  1427.         ;
  1428.  
  1429. stateSpotProperty: DIRECTION
  1430.         {
  1431.            $$ = STATE_SPOT_DIRECTION;
  1432.         }
  1433.         ;
  1434.  
  1435. stateLightModelItem: LIGHTMODEL stateLModProperty
  1436.         {
  1437.            $$[0] = $2[0];
  1438.            $$[1] = $2[1];
  1439.         }
  1440.         ;
  1441.  
  1442. stateLModProperty: AMBIENT
  1443.         {
  1444.            memset($$, 0, sizeof($$));
  1445.            $$[0] = STATE_LIGHTMODEL_AMBIENT;
  1446.         }
  1447.         | optFaceType SCENECOLOR
  1448.         {
  1449.            memset($$, 0, sizeof($$));
  1450.            $$[0] = STATE_LIGHTMODEL_SCENECOLOR;
  1451.            $$[1] = $1;
  1452.         }
  1453.         ;
  1454.  
  1455. stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty
  1456.         {
  1457.            memset($$, 0, sizeof($$));
  1458.            $$[0] = STATE_LIGHTPROD;
  1459.            $$[1] = $3;
  1460.            $$[2] = $5;
  1461.            $$[3] = $6;
  1462.         }
  1463.         ;
  1464.  
  1465. stateLProdProperty: ambDiffSpecProperty;
  1466.  
  1467. stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
  1468.         {
  1469.            memset($$, 0, sizeof($$));
  1470.            $$[0] = $3;
  1471.            $$[1] = $2;
  1472.         }
  1473.         ;
  1474.  
  1475. stateTexEnvProperty: COLOR
  1476.         {
  1477.            $$ = STATE_TEXENV_COLOR;
  1478.         }
  1479.         ;
  1480.  
  1481. ambDiffSpecProperty: AMBIENT
  1482.         {
  1483.            $$ = STATE_AMBIENT;
  1484.         }
  1485.         | DIFFUSE
  1486.         {
  1487.            $$ = STATE_DIFFUSE;
  1488.         }
  1489.         | SPECULAR
  1490.         {
  1491.            $$ = STATE_SPECULAR;
  1492.         }
  1493.         ;
  1494.  
  1495. stateLightNumber: INTEGER
  1496.         {
  1497.            if ((unsigned) $1 >= state->MaxLights) {
  1498.               yyerror(& @1, state, "invalid light selector");
  1499.               YYERROR;
  1500.            }
  1501.  
  1502.            $$ = $1;
  1503.         }
  1504.         ;
  1505.  
  1506. stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord
  1507.         {
  1508.            memset($$, 0, sizeof($$));
  1509.            $$[0] = STATE_TEXGEN;
  1510.            $$[1] = $2;
  1511.            $$[2] = $3 + $4;
  1512.         }
  1513.         ;
  1514.  
  1515. stateTexGenType: EYE
  1516.         {
  1517.            $$ = STATE_TEXGEN_EYE_S;
  1518.         }
  1519.         | OBJECT
  1520.         {
  1521.            $$ = STATE_TEXGEN_OBJECT_S;
  1522.         }
  1523.         ;
  1524. stateTexGenCoord: TEXGEN_S
  1525.         {
  1526.            $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
  1527.         }
  1528.         | TEXGEN_T
  1529.         {
  1530.            $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
  1531.         }
  1532.         | TEXGEN_R
  1533.         {
  1534.            $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
  1535.         }
  1536.         | TEXGEN_Q
  1537.         {
  1538.            $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
  1539.         }
  1540.         ;
  1541.  
  1542. stateFogItem: FOG stateFogProperty
  1543.         {
  1544.            memset($$, 0, sizeof($$));
  1545.            $$[0] = $2;
  1546.         }
  1547.         ;
  1548.  
  1549. stateFogProperty: COLOR
  1550.         {
  1551.            $$ = STATE_FOG_COLOR;
  1552.         }
  1553.         | PARAMS
  1554.         {
  1555.            $$ = STATE_FOG_PARAMS;
  1556.         }
  1557.         ;
  1558.  
  1559. stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE
  1560.         {
  1561.            memset($$, 0, sizeof($$));
  1562.            $$[0] = STATE_CLIPPLANE;
  1563.            $$[1] = $3;
  1564.         }
  1565.         ;
  1566.  
  1567. stateClipPlaneNum: INTEGER
  1568.         {
  1569.            if ((unsigned) $1 >= state->MaxClipPlanes) {
  1570.               yyerror(& @1, state, "invalid clip plane selector");
  1571.               YYERROR;
  1572.            }
  1573.  
  1574.            $$ = $1;
  1575.         }
  1576.         ;
  1577.  
  1578. statePointItem: POINT_TOK statePointProperty
  1579.         {
  1580.            memset($$, 0, sizeof($$));
  1581.            $$[0] = $2;
  1582.         }
  1583.         ;
  1584.  
  1585. statePointProperty: SIZE_TOK
  1586.         {
  1587.            $$ = STATE_POINT_SIZE;
  1588.         }
  1589.         | ATTENUATION
  1590.         {
  1591.            $$ = STATE_POINT_ATTENUATION;
  1592.         }
  1593.         ;
  1594.  
  1595. stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']'
  1596.         {
  1597.            $$[0] = $1[0];
  1598.            $$[1] = $1[1];
  1599.            $$[2] = $4;
  1600.            $$[3] = $4;
  1601.            $$[4] = $1[2];
  1602.         }
  1603.         ;
  1604.  
  1605. stateMatrixRows: stateMatrixItem optMatrixRows
  1606.         {
  1607.            $$[0] = $1[0];
  1608.            $$[1] = $1[1];
  1609.            $$[2] = $2[2];
  1610.            $$[3] = $2[3];
  1611.            $$[4] = $1[2];
  1612.         }
  1613.         ;
  1614.  
  1615. optMatrixRows:
  1616.         {
  1617.            $$[2] = 0;
  1618.            $$[3] = 3;
  1619.         }
  1620.         | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']'
  1621.         {
  1622.            /* It seems logical that the matrix row range specifier would have
  1623.             * to specify a range or more than one row (i.e., $5 > $3).
  1624.             * However, the ARB_vertex_program spec says "a program will fail
  1625.             * to load if <a> is greater than <b>."  This means that $3 == $5
  1626.             * is valid.
  1627.             */
  1628.            if ($3 > $5) {
  1629.               yyerror(& @3, state, "invalid matrix row range");
  1630.               YYERROR;
  1631.            }
  1632.  
  1633.            $$[2] = $3;
  1634.            $$[3] = $5;
  1635.         }
  1636.         ;
  1637.  
  1638. stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier
  1639.         {
  1640.            $$[0] = $2[0];
  1641.            $$[1] = $2[1];
  1642.            $$[2] = $3;
  1643.         }
  1644.         ;
  1645.  
  1646. stateOptMatModifier:
  1647.         {
  1648.            $$ = 0;
  1649.         }
  1650.         | stateMatModifier
  1651.         {
  1652.            $$ = $1;
  1653.         }
  1654.         ;
  1655.  
  1656. stateMatModifier: INVERSE
  1657.         {
  1658.            $$ = STATE_MATRIX_INVERSE;
  1659.         }
  1660.         | TRANSPOSE
  1661.         {
  1662.            $$ = STATE_MATRIX_TRANSPOSE;
  1663.         }
  1664.         | INVTRANS
  1665.         {
  1666.            $$ = STATE_MATRIX_INVTRANS;
  1667.         }
  1668.         ;
  1669.  
  1670. stateMatrixRowNum: INTEGER
  1671.         {
  1672.            if ($1 > 3) {
  1673.               yyerror(& @1, state, "invalid matrix row reference");
  1674.               YYERROR;
  1675.            }
  1676.  
  1677.            $$ = $1;
  1678.         }
  1679.         ;
  1680.  
  1681. stateMatrixName: MODELVIEW stateOptModMatNum
  1682.         {
  1683.            $$[0] = STATE_MODELVIEW_MATRIX;
  1684.            $$[1] = $2;
  1685.         }
  1686.         | PROJECTION
  1687.         {
  1688.            $$[0] = STATE_PROJECTION_MATRIX;
  1689.            $$[1] = 0;
  1690.         }
  1691.         | MVP
  1692.         {
  1693.            $$[0] = STATE_MVP_MATRIX;
  1694.            $$[1] = 0;
  1695.         }
  1696.         | TEXTURE optTexCoordUnitNum
  1697.         {
  1698.            $$[0] = STATE_TEXTURE_MATRIX;
  1699.            $$[1] = $2;
  1700.         }
  1701.         | PALETTE '[' statePaletteMatNum ']'
  1702.         {
  1703.            yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
  1704.            YYERROR;
  1705.         }
  1706.         | MAT_PROGRAM '[' stateProgramMatNum ']'
  1707.         {
  1708.            $$[0] = STATE_PROGRAM_MATRIX;
  1709.            $$[1] = $3;
  1710.         }
  1711.         ;
  1712.  
  1713. stateOptModMatNum:
  1714.         {
  1715.            $$ = 0;
  1716.         }
  1717.         | '[' stateModMatNum ']'
  1718.         {
  1719.            $$ = $2;
  1720.         }
  1721.         ;
  1722. stateModMatNum: INTEGER
  1723.         {
  1724.            /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
  1725.             * zero is valid.
  1726.             */
  1727.            if ($1 != 0) {
  1728.               yyerror(& @1, state, "invalid modelview matrix index");
  1729.               YYERROR;
  1730.            }
  1731.  
  1732.            $$ = $1;
  1733.         }
  1734.         ;
  1735. statePaletteMatNum: INTEGER
  1736.         {
  1737.            /* Since GL_ARB_matrix_palette isn't supported, just let any value
  1738.             * through here.  The error will be generated later.
  1739.             */
  1740.            $$ = $1;
  1741.         }
  1742.         ;
  1743. stateProgramMatNum: INTEGER
  1744.         {
  1745.            if ((unsigned) $1 >= state->MaxProgramMatrices) {
  1746.               yyerror(& @1, state, "invalid program matrix selector");
  1747.               YYERROR;
  1748.            }
  1749.  
  1750.            $$ = $1;
  1751.         }
  1752.         ;
  1753.  
  1754. stateDepthItem: DEPTH RANGE
  1755.         {
  1756.            memset($$, 0, sizeof($$));
  1757.            $$[0] = STATE_DEPTH_RANGE;
  1758.         }
  1759.         ;
  1760.  
  1761.  
  1762. programSingleItem: progEnvParam | progLocalParam;
  1763.  
  1764. programMultipleItem: progEnvParams | progLocalParams;
  1765.  
  1766. progEnvParams: PROGRAM ENV '[' progEnvParamNums ']'
  1767.         {
  1768.            memset($$, 0, sizeof($$));
  1769.            $$[0] = state->state_param_enum;
  1770.            $$[1] = STATE_ENV;
  1771.            $$[2] = $4[0];
  1772.            $$[3] = $4[1];
  1773.         }
  1774.         ;
  1775.  
  1776. progEnvParamNums: progEnvParamNum
  1777.         {
  1778.            $$[0] = $1;
  1779.            $$[1] = $1;
  1780.         }
  1781.         | progEnvParamNum DOT_DOT progEnvParamNum
  1782.         {
  1783.            $$[0] = $1;
  1784.            $$[1] = $3;
  1785.         }
  1786.         ;
  1787.  
  1788. progEnvParam: PROGRAM ENV '[' progEnvParamNum ']'
  1789.         {
  1790.            memset($$, 0, sizeof($$));
  1791.            $$[0] = state->state_param_enum;
  1792.            $$[1] = STATE_ENV;
  1793.            $$[2] = $4;
  1794.            $$[3] = $4;
  1795.         }
  1796.         ;
  1797.  
  1798. progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']'
  1799.         {
  1800.            memset($$, 0, sizeof($$));
  1801.            $$[0] = state->state_param_enum;
  1802.            $$[1] = STATE_LOCAL;
  1803.            $$[2] = $4[0];
  1804.            $$[3] = $4[1];
  1805.         }
  1806.  
  1807. progLocalParamNums: progLocalParamNum
  1808.         {
  1809.            $$[0] = $1;
  1810.            $$[1] = $1;
  1811.         }
  1812.         | progLocalParamNum DOT_DOT progLocalParamNum
  1813.         {
  1814.            $$[0] = $1;
  1815.            $$[1] = $3;
  1816.         }
  1817.         ;
  1818.  
  1819. progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']'
  1820.         {
  1821.            memset($$, 0, sizeof($$));
  1822.            $$[0] = state->state_param_enum;
  1823.            $$[1] = STATE_LOCAL;
  1824.            $$[2] = $4;
  1825.            $$[3] = $4;
  1826.         }
  1827.         ;
  1828.  
  1829. progEnvParamNum: INTEGER
  1830.         {
  1831.            if ((unsigned) $1 >= state->limits->MaxEnvParams) {
  1832.               yyerror(& @1, state, "invalid environment parameter reference");
  1833.               YYERROR;
  1834.            }
  1835.            $$ = $1;
  1836.         }
  1837.         ;
  1838.  
  1839. progLocalParamNum: INTEGER
  1840.         {
  1841.            if ((unsigned) $1 >= state->limits->MaxLocalParams) {
  1842.               yyerror(& @1, state, "invalid local parameter reference");
  1843.               YYERROR;
  1844.            }
  1845.            $$ = $1;
  1846.         }
  1847.         ;
  1848.  
  1849.  
  1850.  
  1851. paramConstDecl: paramConstScalarDecl | paramConstVector;
  1852. paramConstUse: paramConstScalarUse | paramConstVector;
  1853.  
  1854. paramConstScalarDecl: signedFloatConstant
  1855.         {
  1856.            $$.count = 4;
  1857.            $$.data[0].f = $1;
  1858.            $$.data[1].f = $1;
  1859.            $$.data[2].f = $1;
  1860.            $$.data[3].f = $1;
  1861.         }
  1862.         ;
  1863.  
  1864. paramConstScalarUse: REAL
  1865.         {
  1866.            $$.count = 1;
  1867.            $$.data[0].f = $1;
  1868.            $$.data[1].f = $1;
  1869.            $$.data[2].f = $1;
  1870.            $$.data[3].f = $1;
  1871.         }
  1872.         | INTEGER
  1873.         {
  1874.            $$.count = 1;
  1875.            $$.data[0].f = (float) $1;
  1876.            $$.data[1].f = (float) $1;
  1877.            $$.data[2].f = (float) $1;
  1878.            $$.data[3].f = (float) $1;
  1879.         }
  1880.         ;
  1881.  
  1882. paramConstVector: '{' signedFloatConstant '}'
  1883.         {
  1884.            $$.count = 4;
  1885.            $$.data[0].f = $2;
  1886.            $$.data[1].f = 0.0f;
  1887.            $$.data[2].f = 0.0f;
  1888.            $$.data[3].f = 1.0f;
  1889.         }
  1890.         | '{' signedFloatConstant ',' signedFloatConstant '}'
  1891.         {
  1892.            $$.count = 4;
  1893.            $$.data[0].f = $2;
  1894.            $$.data[1].f = $4;
  1895.            $$.data[2].f = 0.0f;
  1896.            $$.data[3].f = 1.0f;
  1897.         }
  1898.         | '{' signedFloatConstant ',' signedFloatConstant ','
  1899.               signedFloatConstant '}'
  1900.         {
  1901.            $$.count = 4;
  1902.            $$.data[0].f = $2;
  1903.            $$.data[1].f = $4;
  1904.            $$.data[2].f = $6;
  1905.            $$.data[3].f = 1.0f;
  1906.         }
  1907.         | '{' signedFloatConstant ',' signedFloatConstant ','
  1908.               signedFloatConstant ',' signedFloatConstant '}'
  1909.         {
  1910.            $$.count = 4;
  1911.            $$.data[0].f = $2;
  1912.            $$.data[1].f = $4;
  1913.            $$.data[2].f = $6;
  1914.            $$.data[3].f = $8;
  1915.         }
  1916.         ;
  1917.  
  1918. signedFloatConstant: optionalSign REAL
  1919.         {
  1920.            $$ = ($1) ? -$2 : $2;
  1921.         }
  1922.         | optionalSign INTEGER
  1923.         {
  1924.            $$ = (float)(($1) ? -$2 : $2);
  1925.         }
  1926.         ;
  1927.  
  1928. optionalSign: '+'        { $$ = FALSE; }
  1929.         | '-'            { $$ = TRUE;  }
  1930.         |                { $$ = FALSE; }
  1931.         ;
  1932.  
  1933. TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList
  1934.         ;
  1935.  
  1936. optVarSize: string
  1937.         {
  1938.            /* NV_fragment_program_option defines the size qualifiers in a
  1939.             * fairly broken way.  "SHORT" or "LONG" can optionally be used
  1940.             * before TEMP or OUTPUT.  However, neither is a reserved word!
  1941.             * This means that we have to parse it as an identifier, then check
  1942.             * to make sure it's one of the valid values.  *sigh*
  1943.             *
  1944.             * In addition, the grammar in the extension spec does *not* allow
  1945.             * the size specifier to be optional, but all known implementations
  1946.             * do.
  1947.             */
  1948.            if (!state->option.NV_fragment) {
  1949.               yyerror(& @1, state, "unexpected IDENTIFIER");
  1950.               YYERROR;
  1951.            }
  1952.  
  1953.            if (strcmp("SHORT", $1) == 0) {
  1954.            } else if (strcmp("LONG", $1) == 0) {
  1955.            } else {
  1956.               char *const err_str =
  1957.                  make_error_string("invalid storage size specifier \"%s\"",
  1958.                                    $1);
  1959.  
  1960.               yyerror(& @1, state, (err_str != NULL)
  1961.                       ? err_str : "invalid storage size specifier");
  1962.  
  1963.               if (err_str != NULL) {
  1964.                  free(err_str);
  1965.               }
  1966.  
  1967.               YYERROR;
  1968.            }
  1969.         }
  1970.         |
  1971.         {
  1972.         }
  1973.         ;
  1974.  
  1975. ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
  1976.         ;
  1977.  
  1978. varNameList: varNameList ',' IDENTIFIER
  1979.         {
  1980.            if (!declare_variable(state, $3, $<integer>0, & @3)) {
  1981.               free($3);
  1982.               YYERROR;
  1983.            }
  1984.         }
  1985.         | IDENTIFIER
  1986.         {
  1987.            if (!declare_variable(state, $1, $<integer>0, & @1)) {
  1988.               free($1);
  1989.               YYERROR;
  1990.            }
  1991.         }
  1992.         ;
  1993.  
  1994. OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
  1995.         {
  1996.            struct asm_symbol *const s =
  1997.               declare_variable(state, $3, at_output, & @3);
  1998.  
  1999.            if (s == NULL) {
  2000.               free($3);
  2001.               YYERROR;
  2002.            } else {
  2003.               s->output_binding = $5;
  2004.            }
  2005.         }
  2006.         ;
  2007.  
  2008. resultBinding: RESULT POSITION
  2009.         {
  2010.            if (state->mode == ARB_vertex) {
  2011.               $$ = VARYING_SLOT_POS;
  2012.            } else {
  2013.               yyerror(& @2, state, "invalid program result name");
  2014.               YYERROR;
  2015.            }
  2016.         }
  2017.         | RESULT FOGCOORD
  2018.         {
  2019.            if (state->mode == ARB_vertex) {
  2020.               $$ = VARYING_SLOT_FOGC;
  2021.            } else {
  2022.               yyerror(& @2, state, "invalid program result name");
  2023.               YYERROR;
  2024.            }
  2025.         }
  2026.         | RESULT resultColBinding
  2027.         {
  2028.            $$ = $2;
  2029.         }
  2030.         | RESULT POINTSIZE
  2031.         {
  2032.            if (state->mode == ARB_vertex) {
  2033.               $$ = VARYING_SLOT_PSIZ;
  2034.            } else {
  2035.               yyerror(& @2, state, "invalid program result name");
  2036.               YYERROR;
  2037.            }
  2038.         }
  2039.         | RESULT TEXCOORD optTexCoordUnitNum
  2040.         {
  2041.            if (state->mode == ARB_vertex) {
  2042.               $$ = VARYING_SLOT_TEX0 + $3;
  2043.            } else {
  2044.               yyerror(& @2, state, "invalid program result name");
  2045.               YYERROR;
  2046.            }
  2047.         }
  2048.         | RESULT DEPTH
  2049.         {
  2050.            if (state->mode == ARB_fragment) {
  2051.               $$ = FRAG_RESULT_DEPTH;
  2052.            } else {
  2053.               yyerror(& @2, state, "invalid program result name");
  2054.               YYERROR;
  2055.            }
  2056.         }
  2057.         ;
  2058.  
  2059. resultColBinding: COLOR optResultFaceType optResultColorType
  2060.         {
  2061.            $$ = $2 + $3;
  2062.         }
  2063.         ;
  2064.  
  2065. optResultFaceType:
  2066.         {
  2067.            if (state->mode == ARB_vertex) {
  2068.               $$ = VARYING_SLOT_COL0;
  2069.            } else {
  2070.               if (state->option.DrawBuffers)
  2071.                  $$ = FRAG_RESULT_DATA0;
  2072.               else
  2073.                  $$ = FRAG_RESULT_COLOR;
  2074.            }
  2075.         }
  2076.         | '[' INTEGER ']'
  2077.         {
  2078.            if (state->mode == ARB_vertex) {
  2079.               yyerror(& @1, state, "invalid program result name");
  2080.               YYERROR;
  2081.            } else {
  2082.               if (!state->option.DrawBuffers) {
  2083.                  /* From the ARB_draw_buffers spec (same text exists
  2084.                   * for ATI_draw_buffers):
  2085.                   *
  2086.                   *     If this option is not specified, a fragment
  2087.                   *     program that attempts to bind
  2088.                   *     "result.color[n]" will fail to load, and only
  2089.                   *     "result.color" will be allowed.
  2090.                   */
  2091.                  yyerror(& @1, state,
  2092.                          "result.color[] used without "
  2093.                          "`OPTION ARB_draw_buffers' or "
  2094.                          "`OPTION ATI_draw_buffers'");
  2095.                  YYERROR;
  2096.               } else if ($2 >= state->MaxDrawBuffers) {
  2097.                  yyerror(& @1, state,
  2098.                          "result.color[] exceeds MAX_DRAW_BUFFERS_ARB");
  2099.                  YYERROR;
  2100.               }
  2101.               $$ = FRAG_RESULT_DATA0 + $2;
  2102.            }
  2103.         }
  2104.         | FRONT
  2105.         {
  2106.            if (state->mode == ARB_vertex) {
  2107.               $$ = VARYING_SLOT_COL0;
  2108.            } else {
  2109.               yyerror(& @1, state, "invalid program result name");
  2110.               YYERROR;
  2111.            }
  2112.         }
  2113.         | BACK
  2114.         {
  2115.            if (state->mode == ARB_vertex) {
  2116.               $$ = VARYING_SLOT_BFC0;
  2117.            } else {
  2118.               yyerror(& @1, state, "invalid program result name");
  2119.               YYERROR;
  2120.            }
  2121.         }
  2122.         ;
  2123.  
  2124. optResultColorType:
  2125.         {
  2126.            $$ = 0;
  2127.         }
  2128.         | PRIMARY
  2129.         {
  2130.            if (state->mode == ARB_vertex) {
  2131.               $$ = 0;
  2132.            } else {
  2133.               yyerror(& @1, state, "invalid program result name");
  2134.               YYERROR;
  2135.            }
  2136.         }
  2137.         | SECONDARY
  2138.         {
  2139.            if (state->mode == ARB_vertex) {
  2140.               $$ = 1;
  2141.            } else {
  2142.               yyerror(& @1, state, "invalid program result name");
  2143.               YYERROR;
  2144.            }
  2145.         }
  2146.         ;
  2147.  
  2148. optFaceType:    { $$ = 0; }
  2149.         | FRONT { $$ = 0; }
  2150.         | BACK  { $$ = 1; }
  2151.         ;
  2152.  
  2153. optColorType:       { $$ = 0; }
  2154.         | PRIMARY   { $$ = 0; }
  2155.         | SECONDARY { $$ = 1; }
  2156.         ;
  2157.  
  2158. optTexCoordUnitNum:                { $$ = 0; }
  2159.         | '[' texCoordUnitNum ']'  { $$ = $2; }
  2160.         ;
  2161.  
  2162. optTexImageUnitNum:                { $$ = 0; }
  2163.         | '[' texImageUnitNum ']'  { $$ = $2; }
  2164.         ;
  2165.  
  2166. optLegacyTexUnitNum:               { $$ = 0; }
  2167.         | '[' legacyTexUnitNum ']' { $$ = $2; }
  2168.         ;
  2169.  
  2170. texCoordUnitNum: INTEGER
  2171.         {
  2172.            if ((unsigned) $1 >= state->MaxTextureCoordUnits) {
  2173.               yyerror(& @1, state, "invalid texture coordinate unit selector");
  2174.               YYERROR;
  2175.            }
  2176.  
  2177.            $$ = $1;
  2178.         }
  2179.         ;
  2180.  
  2181. texImageUnitNum: INTEGER
  2182.         {
  2183.            if ((unsigned) $1 >= state->MaxTextureImageUnits) {
  2184.               yyerror(& @1, state, "invalid texture image unit selector");
  2185.               YYERROR;
  2186.            }
  2187.  
  2188.            $$ = $1;
  2189.         }
  2190.         ;
  2191.  
  2192. legacyTexUnitNum: INTEGER
  2193.         {
  2194.            if ((unsigned) $1 >= state->MaxTextureUnits) {
  2195.               yyerror(& @1, state, "invalid texture unit selector");
  2196.               YYERROR;
  2197.            }
  2198.  
  2199.            $$ = $1;
  2200.         }
  2201.         ;
  2202.  
  2203. ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
  2204.         {
  2205.            struct asm_symbol *exist = (struct asm_symbol *)
  2206.               _mesa_symbol_table_find_symbol(state->st, 0, $2);
  2207.            struct asm_symbol *target = (struct asm_symbol *)
  2208.               _mesa_symbol_table_find_symbol(state->st, 0, $4);
  2209.  
  2210.            free($4);
  2211.  
  2212.            if (exist != NULL) {
  2213.               char m[1000];
  2214.               _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
  2215.               free($2);
  2216.               yyerror(& @2, state, m);
  2217.               YYERROR;
  2218.            } else if (target == NULL) {
  2219.               free($2);
  2220.               yyerror(& @4, state,
  2221.                       "undefined variable binding in ALIAS statement");
  2222.               YYERROR;
  2223.            } else {
  2224.               _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
  2225.            }
  2226.         }
  2227.         ;
  2228.  
  2229. string: IDENTIFIER
  2230.         | USED_IDENTIFIER
  2231.         ;
  2232.  
  2233. %%
  2234.  
  2235. void
  2236. asm_instruction_set_operands(struct asm_instruction *inst,
  2237.                              const struct prog_dst_register *dst,
  2238.                              const struct asm_src_register *src0,
  2239.                              const struct asm_src_register *src1,
  2240.                              const struct asm_src_register *src2)
  2241. {
  2242.    /* In the core ARB extensions only the KIL instruction doesn't have a
  2243.     * destination register.
  2244.     */
  2245.    if (dst == NULL) {
  2246.       init_dst_reg(& inst->Base.DstReg);
  2247.    } else {
  2248.       inst->Base.DstReg = *dst;
  2249.    }
  2250.  
  2251.    /* The only instruction that doesn't have any source registers is the
  2252.     * condition-code based KIL instruction added by NV_fragment_program_option.
  2253.     */
  2254.    if (src0 != NULL) {
  2255.       inst->Base.SrcReg[0] = src0->Base;
  2256.       inst->SrcReg[0] = *src0;
  2257.    } else {
  2258.       init_src_reg(& inst->SrcReg[0]);
  2259.    }
  2260.  
  2261.    if (src1 != NULL) {
  2262.       inst->Base.SrcReg[1] = src1->Base;
  2263.       inst->SrcReg[1] = *src1;
  2264.    } else {
  2265.       init_src_reg(& inst->SrcReg[1]);
  2266.    }
  2267.  
  2268.    if (src2 != NULL) {
  2269.       inst->Base.SrcReg[2] = src2->Base;
  2270.       inst->SrcReg[2] = *src2;
  2271.    } else {
  2272.       init_src_reg(& inst->SrcReg[2]);
  2273.    }
  2274. }
  2275.  
  2276.  
  2277. struct asm_instruction *
  2278. asm_instruction_ctor(gl_inst_opcode op,
  2279.                      const struct prog_dst_register *dst,
  2280.                      const struct asm_src_register *src0,
  2281.                      const struct asm_src_register *src1,
  2282.                      const struct asm_src_register *src2)
  2283. {
  2284.    struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
  2285.  
  2286.    if (inst) {
  2287.       _mesa_init_instructions(& inst->Base, 1);
  2288.       inst->Base.Opcode = op;
  2289.  
  2290.       asm_instruction_set_operands(inst, dst, src0, src1, src2);
  2291.    }
  2292.  
  2293.    return inst;
  2294. }
  2295.  
  2296.  
  2297. struct asm_instruction *
  2298. asm_instruction_copy_ctor(const struct prog_instruction *base,
  2299.                           const struct prog_dst_register *dst,
  2300.                           const struct asm_src_register *src0,
  2301.                           const struct asm_src_register *src1,
  2302.                           const struct asm_src_register *src2)
  2303. {
  2304.    struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
  2305.  
  2306.    if (inst) {
  2307.       _mesa_init_instructions(& inst->Base, 1);
  2308.       inst->Base.Opcode = base->Opcode;
  2309.       inst->Base.CondUpdate = base->CondUpdate;
  2310.       inst->Base.CondDst = base->CondDst;
  2311.       inst->Base.SaturateMode = base->SaturateMode;
  2312.       inst->Base.Precision = base->Precision;
  2313.  
  2314.       asm_instruction_set_operands(inst, dst, src0, src1, src2);
  2315.    }
  2316.  
  2317.    return inst;
  2318. }
  2319.  
  2320.  
  2321. void
  2322. init_dst_reg(struct prog_dst_register *r)
  2323. {
  2324.    memset(r, 0, sizeof(*r));
  2325.    r->File = PROGRAM_UNDEFINED;
  2326.    r->WriteMask = WRITEMASK_XYZW;
  2327.    r->CondMask = COND_TR;
  2328.    r->CondSwizzle = SWIZZLE_NOOP;
  2329. }
  2330.  
  2331.  
  2332. /** Like init_dst_reg() but set the File and Index fields. */
  2333. void
  2334. set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
  2335. {
  2336.    const GLint maxIndex = 1 << INST_INDEX_BITS;
  2337.    const GLint minIndex = 0;
  2338.    assert(index >= minIndex);
  2339.    (void) minIndex;
  2340.    assert(index <= maxIndex);
  2341.    (void) maxIndex;
  2342.    assert(file == PROGRAM_TEMPORARY ||
  2343.           file == PROGRAM_ADDRESS ||
  2344.           file == PROGRAM_OUTPUT);
  2345.    memset(r, 0, sizeof(*r));
  2346.    r->File = file;
  2347.    r->Index = index;
  2348.    r->WriteMask = WRITEMASK_XYZW;
  2349.    r->CondMask = COND_TR;
  2350.    r->CondSwizzle = SWIZZLE_NOOP;
  2351. }
  2352.  
  2353.  
  2354. void
  2355. init_src_reg(struct asm_src_register *r)
  2356. {
  2357.    memset(r, 0, sizeof(*r));
  2358.    r->Base.File = PROGRAM_UNDEFINED;
  2359.    r->Base.Swizzle = SWIZZLE_NOOP;
  2360.    r->Symbol = NULL;
  2361. }
  2362.  
  2363.  
  2364. /** Like init_src_reg() but set the File and Index fields.
  2365.  * \return GL_TRUE if a valid src register, GL_FALSE otherwise
  2366.  */
  2367. void
  2368. set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
  2369. {
  2370.    set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
  2371. }
  2372.  
  2373.  
  2374. void
  2375. set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
  2376.                 GLuint swizzle)
  2377. {
  2378.    const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
  2379.    const GLint minIndex = -(1 << INST_INDEX_BITS);
  2380.    assert(file < PROGRAM_FILE_MAX);
  2381.    assert(index >= minIndex);
  2382.    (void) minIndex;
  2383.    assert(index <= maxIndex);
  2384.    (void) maxIndex;
  2385.    memset(r, 0, sizeof(*r));
  2386.    r->Base.File = file;
  2387.    r->Base.Index = index;
  2388.    r->Base.Swizzle = swizzle;
  2389.    r->Symbol = NULL;
  2390. }
  2391.  
  2392.  
  2393. /**
  2394.  * Validate the set of inputs used by a program
  2395.  *
  2396.  * Validates that legal sets of inputs are used by the program.  In this case
  2397.  * "used" included both reading the input or binding the input to a name using
  2398.  * the \c ATTRIB command.
  2399.  *
  2400.  * \return
  2401.  * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
  2402.  */
  2403. int
  2404. validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
  2405. {
  2406.    const GLbitfield64 inputs = state->prog->InputsRead | state->InputsBound;
  2407.  
  2408.    if (((inputs & VERT_BIT_FF_ALL) & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) {
  2409.       yyerror(locp, state, "illegal use of generic attribute and name attribute");
  2410.       return 0;
  2411.    }
  2412.  
  2413.    return 1;
  2414. }
  2415.  
  2416.  
  2417. struct asm_symbol *
  2418. declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
  2419.                  struct YYLTYPE *locp)
  2420. {
  2421.    struct asm_symbol *s = NULL;
  2422.    struct asm_symbol *exist = (struct asm_symbol *)
  2423.       _mesa_symbol_table_find_symbol(state->st, 0, name);
  2424.  
  2425.  
  2426.    if (exist != NULL) {
  2427.       yyerror(locp, state, "redeclared identifier");
  2428.    } else {
  2429.       s = calloc(1, sizeof(struct asm_symbol));
  2430.       s->name = name;
  2431.       s->type = t;
  2432.  
  2433.       switch (t) {
  2434.       case at_temp:
  2435.          if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
  2436.             yyerror(locp, state, "too many temporaries declared");
  2437.             free(s);
  2438.             return NULL;
  2439.          }
  2440.  
  2441.          s->temp_binding = state->prog->NumTemporaries;
  2442.          state->prog->NumTemporaries++;
  2443.          break;
  2444.  
  2445.       case at_address:
  2446.          if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
  2447.             yyerror(locp, state, "too many address registers declared");
  2448.             free(s);
  2449.             return NULL;
  2450.          }
  2451.  
  2452.          /* FINISHME: Add support for multiple address registers.
  2453.           */
  2454.          state->prog->NumAddressRegs++;
  2455.          break;
  2456.  
  2457.       default:
  2458.          break;
  2459.       }
  2460.  
  2461.       _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
  2462.       s->next = state->sym;
  2463.       state->sym = s;
  2464.    }
  2465.  
  2466.    return s;
  2467. }
  2468.  
  2469.  
  2470. int add_state_reference(struct gl_program_parameter_list *param_list,
  2471.                         const gl_state_index tokens[STATE_LENGTH])
  2472. {
  2473.    const GLuint size = 4; /* XXX fix */
  2474.    char *name;
  2475.    GLint index;
  2476.  
  2477.    name = _mesa_program_state_string(tokens);
  2478.    index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
  2479.                                size, GL_NONE, NULL, tokens);
  2480.    param_list->StateFlags |= _mesa_program_state_flags(tokens);
  2481.  
  2482.    /* free name string here since we duplicated it in add_parameter() */
  2483.    free(name);
  2484.  
  2485.    return index;
  2486. }
  2487.  
  2488.  
  2489. int
  2490. initialize_symbol_from_state(struct gl_program *prog,
  2491.                              struct asm_symbol *param_var,
  2492.                              const gl_state_index tokens[STATE_LENGTH])
  2493. {
  2494.    int idx = -1;
  2495.    gl_state_index state_tokens[STATE_LENGTH];
  2496.  
  2497.  
  2498.    memcpy(state_tokens, tokens, sizeof(state_tokens));
  2499.  
  2500.    param_var->type = at_param;
  2501.    param_var->param_binding_type = PROGRAM_STATE_VAR;
  2502.  
  2503.    /* If we are adding a STATE_MATRIX that has multiple rows, we need to
  2504.     * unroll it and call add_state_reference() for each row
  2505.     */
  2506.    if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
  2507.         state_tokens[0] == STATE_PROJECTION_MATRIX ||
  2508.         state_tokens[0] == STATE_MVP_MATRIX ||
  2509.         state_tokens[0] == STATE_TEXTURE_MATRIX ||
  2510.         state_tokens[0] == STATE_PROGRAM_MATRIX)
  2511.        && (state_tokens[2] != state_tokens[3])) {
  2512.       int row;
  2513.       const int first_row = state_tokens[2];
  2514.       const int last_row = state_tokens[3];
  2515.  
  2516.       for (row = first_row; row <= last_row; row++) {
  2517.          state_tokens[2] = state_tokens[3] = row;
  2518.  
  2519.          idx = add_state_reference(prog->Parameters, state_tokens);
  2520.          if (param_var->param_binding_begin == ~0U) {
  2521.             param_var->param_binding_begin = idx;
  2522.             param_var->param_binding_swizzle = SWIZZLE_XYZW;
  2523.          }
  2524.  
  2525.          param_var->param_binding_length++;
  2526.       }
  2527.    }
  2528.    else {
  2529.       idx = add_state_reference(prog->Parameters, state_tokens);
  2530.       if (param_var->param_binding_begin == ~0U) {
  2531.          param_var->param_binding_begin = idx;
  2532.          param_var->param_binding_swizzle = SWIZZLE_XYZW;
  2533.       }
  2534.       param_var->param_binding_length++;
  2535.    }
  2536.  
  2537.    return idx;
  2538. }
  2539.  
  2540.  
  2541. int
  2542. initialize_symbol_from_param(struct gl_program *prog,
  2543.                              struct asm_symbol *param_var,
  2544.                              const gl_state_index tokens[STATE_LENGTH])
  2545. {
  2546.    int idx = -1;
  2547.    gl_state_index state_tokens[STATE_LENGTH];
  2548.  
  2549.  
  2550.    memcpy(state_tokens, tokens, sizeof(state_tokens));
  2551.  
  2552.    assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
  2553.           || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
  2554.    assert((state_tokens[1] == STATE_ENV)
  2555.           || (state_tokens[1] == STATE_LOCAL));
  2556.  
  2557.    /*
  2558.     * The param type is STATE_VAR.  The program parameter entry will
  2559.     * effectively be a pointer into the LOCAL or ENV parameter array.
  2560.     */
  2561.    param_var->type = at_param;
  2562.    param_var->param_binding_type = PROGRAM_STATE_VAR;
  2563.  
  2564.    /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
  2565.     * we need to unroll it and call add_state_reference() for each row
  2566.     */
  2567.    if (state_tokens[2] != state_tokens[3]) {
  2568.       int row;
  2569.       const int first_row = state_tokens[2];
  2570.       const int last_row = state_tokens[3];
  2571.  
  2572.       for (row = first_row; row <= last_row; row++) {
  2573.          state_tokens[2] = state_tokens[3] = row;
  2574.  
  2575.          idx = add_state_reference(prog->Parameters, state_tokens);
  2576.          if (param_var->param_binding_begin == ~0U) {
  2577.             param_var->param_binding_begin = idx;
  2578.             param_var->param_binding_swizzle = SWIZZLE_XYZW;
  2579.          }
  2580.          param_var->param_binding_length++;
  2581.       }
  2582.    }
  2583.    else {
  2584.       idx = add_state_reference(prog->Parameters, state_tokens);
  2585.       if (param_var->param_binding_begin == ~0U) {
  2586.          param_var->param_binding_begin = idx;
  2587.          param_var->param_binding_swizzle = SWIZZLE_XYZW;
  2588.       }
  2589.       param_var->param_binding_length++;
  2590.    }
  2591.  
  2592.    return idx;
  2593. }
  2594.  
  2595.  
  2596. /**
  2597.  * Put a float/vector constant/literal into the parameter list.
  2598.  * \param param_var  returns info about the parameter/constant's location,
  2599.  *                   binding, type, etc.
  2600.  * \param vec  the vector/constant to add
  2601.  * \param allowSwizzle  if true, try to consolidate constants which only differ
  2602.  *                      by a swizzle.  We don't want to do this when building
  2603.  *                      arrays of constants that may be indexed indirectly.
  2604.  * \return index of the constant in the parameter list.
  2605.  */
  2606. int
  2607. initialize_symbol_from_const(struct gl_program *prog,
  2608.                              struct asm_symbol *param_var,
  2609.                              const struct asm_vector *vec,
  2610.                              GLboolean allowSwizzle)
  2611. {
  2612.    unsigned swizzle;
  2613.    const int idx = _mesa_add_unnamed_constant(prog->Parameters,
  2614.                                               vec->data, vec->count,
  2615.                                               allowSwizzle ? &swizzle : NULL);
  2616.  
  2617.    param_var->type = at_param;
  2618.    param_var->param_binding_type = PROGRAM_CONSTANT;
  2619.  
  2620.    if (param_var->param_binding_begin == ~0U) {
  2621.       param_var->param_binding_begin = idx;
  2622.       param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
  2623.    }
  2624.    param_var->param_binding_length++;
  2625.  
  2626.    return idx;
  2627. }
  2628.  
  2629.  
  2630. char *
  2631. make_error_string(const char *fmt, ...)
  2632. {
  2633.    int length;
  2634.    char *str;
  2635.    va_list args;
  2636.  
  2637.  
  2638.    /* Call vsnprintf once to determine how large the final string is.  Call it
  2639.     * again to do the actual formatting.  from the vsnprintf manual page:
  2640.     *
  2641.     *    Upon successful return, these functions return the number of
  2642.     *    characters printed  (not including the trailing '\0' used to end
  2643.     *    output to strings).
  2644.     */
  2645.    va_start(args, fmt);
  2646.    length = 1 + vsnprintf(NULL, 0, fmt, args);
  2647.    va_end(args);
  2648.  
  2649.    str = malloc(length);
  2650.    if (str) {
  2651.       va_start(args, fmt);
  2652.       vsnprintf(str, length, fmt, args);
  2653.       va_end(args);
  2654.    }
  2655.  
  2656.    return str;
  2657. }
  2658.  
  2659.  
  2660. void
  2661. yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
  2662. {
  2663.    char *err_str;
  2664.  
  2665.  
  2666.    err_str = make_error_string("glProgramStringARB(%s)\n", s);
  2667.    if (err_str) {
  2668.       _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str);
  2669.       free(err_str);
  2670.    }
  2671.  
  2672.    err_str = make_error_string("line %u, char %u: error: %s\n",
  2673.                                locp->first_line, locp->first_column, s);
  2674.    _mesa_set_program_error(state->ctx, locp->position, err_str);
  2675.  
  2676.    if (err_str) {
  2677.       free(err_str);
  2678.    }
  2679. }
  2680.  
  2681.  
  2682. GLboolean
  2683. _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str,
  2684.                         GLsizei len, struct asm_parser_state *state)
  2685. {
  2686.    struct asm_instruction *inst;
  2687.    unsigned i;
  2688.    GLubyte *strz;
  2689.    GLboolean result = GL_FALSE;
  2690.    void *temp;
  2691.    struct asm_symbol *sym;
  2692.  
  2693.    state->ctx = ctx;
  2694.    state->prog->Target = target;
  2695.    state->prog->Parameters = _mesa_new_parameter_list();
  2696.  
  2697.    /* Make a copy of the program string and force it to be NUL-terminated.
  2698.     */
  2699.    strz = (GLubyte *) malloc(len + 1);
  2700.    if (strz == NULL) {
  2701.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
  2702.       return GL_FALSE;
  2703.    }
  2704.    memcpy (strz, str, len);
  2705.    strz[len] = '\0';
  2706.  
  2707.    state->prog->String = strz;
  2708.  
  2709.    state->st = _mesa_symbol_table_ctor();
  2710.  
  2711.    state->limits = (target == GL_VERTEX_PROGRAM_ARB)
  2712.       ? & ctx->Const.Program[MESA_SHADER_VERTEX]
  2713.       : & ctx->Const.Program[MESA_SHADER_FRAGMENT];
  2714.  
  2715.    state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
  2716.    state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
  2717.    state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
  2718.    state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
  2719.    state->MaxLights = ctx->Const.MaxLights;
  2720.    state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
  2721.    state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
  2722.  
  2723.    state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
  2724.       ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
  2725.  
  2726.    _mesa_set_program_error(ctx, -1, NULL);
  2727.  
  2728.    _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
  2729.    yyparse(state);
  2730.    _mesa_program_lexer_dtor(state->scanner);
  2731.  
  2732.  
  2733.    if (ctx->Program.ErrorPos != -1) {
  2734.       goto error;
  2735.    }
  2736.  
  2737.    if (! _mesa_layout_parameters(state)) {
  2738.       struct YYLTYPE loc;
  2739.  
  2740.       loc.first_line = 0;
  2741.       loc.first_column = 0;
  2742.       loc.position = len;
  2743.  
  2744.       yyerror(& loc, state, "invalid PARAM usage");
  2745.       goto error;
  2746.    }
  2747.  
  2748.  
  2749.    
  2750.    /* Add one instruction to store the "END" instruction.
  2751.     */
  2752.    state->prog->Instructions =
  2753.       _mesa_alloc_instructions(state->prog->NumInstructions + 1);
  2754.  
  2755.    if (state->prog->Instructions == NULL) {
  2756.       goto error;
  2757.    }
  2758.  
  2759.    inst = state->inst_head;
  2760.    for (i = 0; i < state->prog->NumInstructions; i++) {
  2761.       struct asm_instruction *const temp = inst->next;
  2762.  
  2763.       state->prog->Instructions[i] = inst->Base;
  2764.       inst = temp;
  2765.    }
  2766.  
  2767.    /* Finally, tag on an OPCODE_END instruction */
  2768.    {
  2769.       const GLuint numInst = state->prog->NumInstructions;
  2770.       _mesa_init_instructions(state->prog->Instructions + numInst, 1);
  2771.       state->prog->Instructions[numInst].Opcode = OPCODE_END;
  2772.    }
  2773.    state->prog->NumInstructions++;
  2774.  
  2775.    state->prog->NumParameters = state->prog->Parameters->NumParameters;
  2776.    state->prog->NumAttributes = _mesa_bitcount_64(state->prog->InputsRead);
  2777.  
  2778.    /*
  2779.     * Initialize native counts to logical counts.  The device driver may
  2780.     * change them if program is translated into a hardware program.
  2781.     */
  2782.    state->prog->NumNativeInstructions = state->prog->NumInstructions;
  2783.    state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
  2784.    state->prog->NumNativeParameters = state->prog->NumParameters;
  2785.    state->prog->NumNativeAttributes = state->prog->NumAttributes;
  2786.    state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
  2787.  
  2788.    result = GL_TRUE;
  2789.  
  2790. error:
  2791.    for (inst = state->inst_head; inst != NULL; inst = temp) {
  2792.       temp = inst->next;
  2793.       free(inst);
  2794.    }
  2795.  
  2796.    state->inst_head = NULL;
  2797.    state->inst_tail = NULL;
  2798.  
  2799.    for (sym = state->sym; sym != NULL; sym = temp) {
  2800.       temp = sym->next;
  2801.  
  2802.       free((void *) sym->name);
  2803.       free(sym);
  2804.    }
  2805.    state->sym = NULL;
  2806.  
  2807.    _mesa_symbol_table_dtor(state->st);
  2808.    state->st = NULL;
  2809.  
  2810.    return result;
  2811. }
  2812.