ARB prog parser: Add support for GL_ARB_fragment_program_shadow
[mesa.git] / src / mesa / shader / program_parse.y
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 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "main/mtypes.h"
29 #include "main/imports.h"
30 #include "program.h"
31 #include "prog_parameter.h"
32 #include "prog_parameter_layout.h"
33 #include "prog_statevars.h"
34 #include "prog_instruction.h"
35
36 #include "symbol_table.h"
37 #include "program_parser.h"
38
39 extern void *yy_scan_string(char *);
40 extern void yy_delete_buffer(void *);
41
42 static struct asm_symbol *declare_variable(struct asm_parser_state *state,
43 char *name, enum asm_type t, struct YYLTYPE *locp);
44
45 static int add_state_reference(struct gl_program_parameter_list *param_list,
46 const gl_state_index tokens[STATE_LENGTH]);
47
48 static int initialize_symbol_from_state(struct gl_program *prog,
49 struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
50
51 static int initialize_symbol_from_param(struct gl_program *prog,
52 struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
53
54 static int initialize_symbol_from_const(struct gl_program *prog,
55 struct asm_symbol *param_var, const struct asm_vector *vec);
56
57 static int yyparse(struct asm_parser_state *state);
58
59 static char *make_error_string(const char *fmt, ...);
60
61 static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
62 const char *s);
63
64 static int validate_inputs(struct YYLTYPE *locp,
65 struct asm_parser_state *state);
66
67 static void init_dst_reg(struct prog_dst_register *r);
68
69 static void init_src_reg(struct asm_src_register *r);
70
71 static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
72 const struct prog_dst_register *dst, const struct asm_src_register *src0,
73 const struct asm_src_register *src1, const struct asm_src_register *src2);
74
75 #ifndef FALSE
76 #define FALSE 0
77 #define TRUE (!FALSE)
78 #endif
79
80 #define YYLLOC_DEFAULT(Current, Rhs, N) \
81 do { \
82 if (YYID(N)) { \
83 (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
84 (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
85 (Current).position = YYRHSLOC(Rhs, 1).position; \
86 (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
87 (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
88 } else { \
89 (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
90 (Current).last_line = (Current).first_line; \
91 (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \
92 (Current).last_column = (Current).first_column; \
93 (Current).position = YYRHSLOC(Rhs, 0).position \
94 + (Current).first_column; \
95 } \
96 } while(YYID(0))
97
98 #define YYLEX_PARAM state->scanner
99 %}
100
101 %pure-parser
102 %locations
103 %parse-param { struct asm_parser_state *state }
104 %error-verbose
105 %lex-param { void *scanner }
106
107 %union {
108 struct asm_instruction *inst;
109 struct asm_symbol *sym;
110 struct asm_symbol temp_sym;
111 struct asm_swizzle_mask swiz_mask;
112 struct asm_src_register src_reg;
113 struct prog_dst_register dst_reg;
114 struct prog_instruction temp_inst;
115 char *string;
116 unsigned result;
117 unsigned attrib;
118 int integer;
119 float real;
120 unsigned state[5];
121 int negate;
122 struct asm_vector vector;
123 gl_inst_opcode opcode;
124 }
125
126 %token ARBvp_10 ARBfp_10
127
128 /* Tokens for assembler pseudo-ops */
129 %token <integer> ADDRESS
130 %token ALIAS ATTRIB
131 %token OPTION OUTPUT
132 %token PARAM
133 %token <integer> TEMP
134 %token END
135
136 /* Tokens for instructions */
137 %token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
138 %token <temp_inst> ARL KIL SWZ
139
140 %token <integer> INTEGER
141 %token <real> REAL
142
143 %token AMBIENT ATTENUATION
144 %token BACK
145 %token CLIP COLOR
146 %token DEPTH DIFFUSE DIRECTION
147 %token EMISSION ENV EYE
148 %token FOG FOGCOORD FRAGMENT FRONT
149 %token HALF
150 %token INVERSE INVTRANS
151 %token LIGHT LIGHTMODEL LIGHTPROD LOCAL
152 %token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
153 %token NORMAL
154 %token OBJECT
155 %token PALETTE PARAMS PLANE POINT POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
156 %token RANGE RESULT ROW
157 %token SCENECOLOR SECONDARY SHININESS SIZE SPECULAR SPOT STATE
158 %token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
159 %token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
160 %token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
161 %token VERTEX VTXATTRIB
162 %token WEIGHT
163
164 %token <string> IDENTIFIER
165 %token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
166 %token DOT_DOT
167 %token DOT
168
169 %type <inst> instruction ALU_instruction TexInstruction
170 %type <inst> ARL_instruction VECTORop_instruction
171 %type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
172 %type <inst> TRIop_instruction SWZ_instruction SAMPLE_instruction
173 %type <inst> KIL_instruction
174
175 %type <dst_reg> dstReg maskedDstReg maskedAddrReg
176 %type <src_reg> srcReg scalarSrcReg swizzleSrcReg
177 %type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle extSwizComp
178 %type <swiz_mask> optionalMask
179 %type <integer> extSwizSel
180
181 %type <sym> progParamArray
182 %type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
183 %type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel
184 %type <sym> addrReg
185 %type <swiz_mask> addrComponent addrWriteMask
186
187 %type <result> resultBinding resultColBinding
188 %type <integer> optFaceType optColorType
189 %type <integer> optResultFaceType optResultColorType
190
191 %type <integer> optTexImageUnitNum texImageUnitNum
192 %type <integer> optTexCoordUnitNum texCoordUnitNum
193 %type <integer> optLegacyTexUnitNum legacyTexUnitNum
194 %type <integer> texImageUnit texTarget
195 %type <integer> vtxAttribNum
196
197 %type <attrib> attribBinding vtxAttribItem fragAttribItem
198
199 %type <temp_sym> paramSingleInit paramSingleItemDecl
200 %type <integer> optArraySize
201
202 %type <state> stateSingleItem stateMultipleItem
203 %type <state> stateMaterialItem
204 %type <state> stateLightItem stateLightModelItem stateLightProdItem
205 %type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem
206 %type <state> stateMatrixItem stateMatrixRow stateMatrixRows
207 %type <state> stateTexEnvItem
208
209 %type <state> stateLModProperty
210 %type <state> stateMatrixName optMatrixRows
211
212 %type <integer> stateMatProperty
213 %type <integer> stateLightProperty stateSpotProperty
214 %type <integer> stateLightNumber stateLProdProperty
215 %type <integer> stateTexGenType stateTexGenCoord
216 %type <integer> stateTexEnvProperty
217 %type <integer> stateFogProperty
218 %type <integer> stateClipPlaneNum
219 %type <integer> statePointProperty
220
221 %type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum
222 %type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum
223 %type <integer> stateProgramMatNum
224
225 %type <integer> ambDiffSpecProperty
226
227 %type <state> programSingleItem progEnvParam progLocalParam
228 %type <state> programMultipleItem progEnvParams progLocalParams
229
230 %type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem
231 %type <temp_sym> paramSingleItemUse
232
233 %type <integer> progEnvParamNum progLocalParamNum
234 %type <state> progEnvParamNums progLocalParamNums
235
236 %type <vector> paramConstDecl paramConstUse
237 %type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector
238 %type <real> signedFloatConstant
239 %type <negate> optionalSign
240
241 %{
242 extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
243 void *yyscanner);
244 %}
245
246 %%
247
248 program: language optionSequence statementSequence END
249 ;
250
251 language: ARBvp_10
252 {
253 if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
254 yyerror(& @1, state, "invalid fragment program header");
255
256 }
257 state->mode = ARB_vertex;
258 }
259 | ARBfp_10
260 {
261 if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
262 yyerror(& @1, state, "invalid vertex program header");
263 }
264 state->mode = ARB_fragment;
265
266 state->option.TexRect =
267 (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
268 }
269 ;
270
271 optionSequence: optionSequence option
272 |
273 ;
274
275 option: OPTION IDENTIFIER ';'
276 {
277 int valid = 0;
278
279 if (state->mode == ARB_vertex) {
280 valid = _mesa_ARBvp_parse_option(state, $2);
281 } else if (state->mode == ARB_fragment) {
282 valid = _mesa_ARBfp_parse_option(state, $2);
283 }
284
285
286 if (!valid) {
287 yyerror(& @2, state, "invalid option string");
288 YYERROR;
289 }
290 }
291 ;
292
293 statementSequence: statementSequence statement
294 |
295 ;
296
297 statement: instruction ';'
298 {
299 if ($1 != NULL) {
300 if (state->inst_tail == NULL) {
301 state->inst_head = $1;
302 } else {
303 state->inst_tail->next = $1;
304 }
305
306 state->inst_tail = $1;
307 $1->next = NULL;
308
309 state->prog->NumInstructions++;
310 }
311 }
312 | namingStatement ';'
313 ;
314
315 instruction: ALU_instruction
316 {
317 $$ = $1;
318 state->prog->NumAluInstructions++;
319 }
320 | TexInstruction
321 {
322 $$ = $1;
323 state->prog->NumTexInstructions++;
324 }
325 ;
326
327 ALU_instruction: ARL_instruction
328 | VECTORop_instruction
329 | SCALARop_instruction
330 | BINSCop_instruction
331 | BINop_instruction
332 | TRIop_instruction
333 | SWZ_instruction
334 ;
335
336 TexInstruction: SAMPLE_instruction
337 | KIL_instruction
338 ;
339
340 ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
341 {
342 $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL);
343 }
344 ;
345
346 VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
347 {
348 $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
349 $$->Base.SaturateMode = $1.SaturateMode;
350 }
351 ;
352
353 SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
354 {
355 $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
356 $$->Base.SaturateMode = $1.SaturateMode;
357 }
358 ;
359
360 BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
361 {
362 $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL);
363 $$->Base.SaturateMode = $1.SaturateMode;
364 }
365 ;
366
367
368 BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
369 {
370 $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL);
371 $$->Base.SaturateMode = $1.SaturateMode;
372 }
373 ;
374
375 TRIop_instruction: TRI_OP maskedDstReg ','
376 swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
377 {
378 $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, & $8);
379 $$->Base.SaturateMode = $1.SaturateMode;
380 }
381 ;
382
383 SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
384 {
385 $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
386 if ($$ != NULL) {
387 const GLbitfield tex_mask = (1U << $6);
388 GLbitfield shadow_tex = 0;
389 GLbitfield target_mask = 0;
390
391
392 $$->Base.SaturateMode = $1.SaturateMode;
393 $$->Base.TexSrcUnit = $6;
394
395 if ($8 < 0) {
396 shadow_tex = tex_mask;
397
398 $$->Base.TexSrcTarget = -$8;
399 $$->Base.TexShadow = 1;
400 } else {
401 $$->Base.TexSrcTarget = $8;
402 }
403
404 target_mask = (1U << $$->Base.TexSrcTarget);
405
406 /* If this texture unit was previously accessed and that access
407 * had a different texture target, generate an error.
408 *
409 * If this texture unit was previously accessed and that access
410 * had a different shadow mode, generate an error.
411 */
412 if ((state->prog->TexturesUsed[$6] != 0)
413 && ((state->prog->TexturesUsed[$6] != target_mask)
414 || ((state->prog->ShadowSamplers & tex_mask)
415 != shadow_tex))) {
416 yyerror(& @8, state,
417 "multiple targets used on one texture image unit");
418 YYERROR;
419 }
420
421
422 state->prog->TexturesUsed[$6] |= target_mask;
423 state->prog->ShadowSamplers |= shadow_tex;
424 }
425 }
426 ;
427
428 KIL_instruction: KIL swizzleSrcReg
429 {
430 $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
431 state->fragment.UsesKill = 1;
432 }
433 ;
434
435 texImageUnit: TEXTURE_UNIT optTexImageUnitNum
436 {
437 $$ = $2;
438 }
439 ;
440
441 texTarget: TEX_1D { $$ = TEXTURE_1D_INDEX; }
442 | TEX_2D { $$ = TEXTURE_2D_INDEX; }
443 | TEX_3D { $$ = TEXTURE_3D_INDEX; }
444 | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; }
445 | TEX_RECT { $$ = TEXTURE_RECT_INDEX; }
446 | TEX_SHADOW1D { $$ = -TEXTURE_1D_INDEX; }
447 | TEX_SHADOW2D { $$ = -TEXTURE_2D_INDEX; }
448 | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; }
449 ;
450
451 SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
452 {
453 /* FIXME: Is this correct? Should the extenedSwizzle be applied
454 * FIXME: to the existing swizzle?
455 */
456 $4.Base.Swizzle = $6.swizzle;
457
458 $$ = asm_instruction_ctor(OPCODE_SWZ, & $2, & $4, NULL, NULL);
459 $$->Base.SaturateMode = $1.SaturateMode;
460 }
461 ;
462
463 scalarSrcReg: optionalSign srcReg scalarSuffix
464 {
465 $$ = $2;
466
467 if ($1) {
468 $$.Base.Negate = ~$$.Base.Negate;
469 }
470
471 $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
472 $3.swizzle);
473 }
474 ;
475
476 swizzleSrcReg: optionalSign srcReg swizzleSuffix
477 {
478 $$ = $2;
479
480 if ($1) {
481 $$.Base.Negate = ~$$.Base.Negate;
482 }
483
484 $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
485 $3.swizzle);
486 }
487 ;
488
489 maskedDstReg: dstReg optionalMask
490 {
491 $$ = $1;
492 $$.WriteMask = $2.mask;
493
494 if ($$.File == PROGRAM_OUTPUT) {
495 /* Technically speaking, this should check that it is in
496 * vertex program mode. However, PositionInvariant can never be
497 * set in fragment program mode, so it is somewhat irrelevant.
498 */
499 if (state->option.PositionInvariant
500 && ($$.Index == VERT_RESULT_HPOS)) {
501 yyerror(& @1, state, "position-invariant programs cannot "
502 "write position");
503 YYERROR;
504 }
505
506 state->prog->OutputsWritten |= (1U << $$.Index);
507 }
508 }
509 ;
510
511 maskedAddrReg: addrReg addrWriteMask
512 {
513 init_dst_reg(& $$);
514 $$.File = PROGRAM_ADDRESS;
515 $$.Index = 0;
516 $$.WriteMask = $2.mask;
517 }
518 ;
519
520 extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
521 {
522 $$.swizzle = MAKE_SWIZZLE4($1.swizzle, $3.swizzle,
523 $5.swizzle, $7.swizzle);
524 $$.mask = ($1.mask) | ($3.mask << 1) | ($5.mask << 2)
525 | ($7.mask << 3);
526 }
527 ;
528
529 extSwizComp: optionalSign extSwizSel
530 {
531 $$.swizzle = $2;
532 $$.mask = ($1) ? 1 : 0;
533 }
534 ;
535
536 extSwizSel: INTEGER
537 {
538 if (($1 != 0) && ($1 != 1)) {
539 yyerror(& @1, state, "invalid extended swizzle selector");
540 YYERROR;
541 }
542
543 $$ = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
544 }
545 | IDENTIFIER
546 {
547 if (strlen($1) > 1) {
548 yyerror(& @1, state, "invalid extended swizzle selector");
549 YYERROR;
550 }
551
552 switch ($1[0]) {
553 case 'x':
554 $$ = SWIZZLE_X;
555 break;
556 case 'y':
557 $$ = SWIZZLE_Y;
558 break;
559 case 'z':
560 $$ = SWIZZLE_Z;
561 break;
562 case 'w':
563 $$ = SWIZZLE_W;
564 break;
565 default:
566 yyerror(& @1, state, "invalid extended swizzle selector");
567 YYERROR;
568 break;
569 }
570 }
571 ;
572
573 srcReg: IDENTIFIER /* temporaryReg | progParamSingle */
574 {
575 struct asm_symbol *const s = (struct asm_symbol *)
576 _mesa_symbol_table_find_symbol(state->st, 0, $1);
577
578 if (s == NULL) {
579 yyerror(& @1, state, "invalid operand variable");
580 YYERROR;
581 } else if ((s->type != at_param) && (s->type != at_temp)
582 && (s->type != at_attrib)) {
583 yyerror(& @1, state, "invalid operand variable");
584 YYERROR;
585 } else if ((s->type == at_param) && s->param_is_array) {
586 yyerror(& @1, state, "non-array access to array PARAM");
587 YYERROR;
588 }
589
590 init_src_reg(& $$);
591 switch (s->type) {
592 case at_temp:
593 $$.Base.File = PROGRAM_TEMPORARY;
594 $$.Base.Index = s->temp_binding;
595 break;
596 case at_param:
597 $$.Base.File = s->param_binding_type;
598 $$.Base.Index = s->param_binding_begin;
599 break;
600 case at_attrib:
601 $$.Base.File = PROGRAM_INPUT;
602 $$.Base.Index = s->attrib_binding;
603 state->prog->InputsRead |= (1U << $$.Base.Index);
604
605 if (!validate_inputs(& @1, state)) {
606 YYERROR;
607 }
608 break;
609
610 default:
611 YYERROR;
612 break;
613 }
614 }
615 | attribBinding
616 {
617 init_src_reg(& $$);
618 $$.Base.File = PROGRAM_INPUT;
619 $$.Base.Index = $1;
620 state->prog->InputsRead |= (1U << $$.Base.Index);
621
622 if (!validate_inputs(& @1, state)) {
623 YYERROR;
624 }
625 }
626 | progParamArray '[' progParamArrayMem ']'
627 {
628 if (! $3.Base.RelAddr
629 && ((unsigned) $3.Base.Index >= $1->param_binding_length)) {
630 yyerror(& @3, state, "out of bounds array access");
631 YYERROR;
632 }
633
634 init_src_reg(& $$);
635 $$.Base.File = $1->param_binding_type;
636
637 if ($3.Base.RelAddr) {
638 $1->param_accessed_indirectly = 1;
639
640 $$.Base.RelAddr = 1;
641 $$.Base.Index = $3.Base.Index;
642 $$.Symbol = $1;
643 } else {
644 $$.Base.Index = $1->param_binding_begin + $3.Base.Index;
645 }
646 }
647 | paramSingleItemUse
648 {
649 init_src_reg(& $$);
650 $$.Base.File = ($1.name != NULL)
651 ? $1.param_binding_type
652 : PROGRAM_CONSTANT;
653 $$.Base.Index = $1.param_binding_begin;
654 }
655 ;
656
657 dstReg: resultBinding
658 {
659 init_dst_reg(& $$);
660 $$.File = PROGRAM_OUTPUT;
661 $$.Index = $1;
662 }
663 | IDENTIFIER /* temporaryReg | vertexResultReg */
664 {
665 struct asm_symbol *const s = (struct asm_symbol *)
666 _mesa_symbol_table_find_symbol(state->st, 0, $1);
667
668 if (s == NULL) {
669 yyerror(& @1, state, "invalid operand variable");
670 YYERROR;
671 } else if ((s->type != at_output) && (s->type != at_temp)) {
672 yyerror(& @1, state, "invalid operand variable");
673 YYERROR;
674 }
675
676 init_dst_reg(& $$);
677 if (s->type == at_temp) {
678 $$.File = PROGRAM_TEMPORARY;
679 $$.Index = s->temp_binding;
680 } else {
681 $$.File = s->param_binding_type;
682 $$.Index = s->param_binding_begin;
683 }
684 }
685 ;
686
687 progParamArray: IDENTIFIER
688 {
689 struct asm_symbol *const s = (struct asm_symbol *)
690 _mesa_symbol_table_find_symbol(state->st, 0, $1);
691
692 if (s == NULL) {
693 yyerror(& @1, state, "invalid operand variable");
694 YYERROR;
695 } else if ((s->type != at_param) || !s->param_is_array) {
696 yyerror(& @1, state, "array access to non-PARAM variable");
697 YYERROR;
698 } else {
699 $$ = s;
700 }
701 }
702 ;
703
704 progParamArrayMem: progParamArrayAbs | progParamArrayRel;
705
706 progParamArrayAbs: INTEGER
707 {
708 init_src_reg(& $$);
709 $$.Base.Index = $1;
710 }
711 ;
712
713 progParamArrayRel: addrReg addrComponent addrRegRelOffset
714 {
715 /* FINISHME: Add support for multiple address registers.
716 */
717 /* FINISHME: Add support for 4-component address registers.
718 */
719 init_src_reg(& $$);
720 $$.Base.RelAddr = 1;
721 $$.Base.Index = $3;
722 }
723 ;
724
725 addrRegRelOffset: { $$ = 0; }
726 | '+' addrRegPosOffset { $$ = $2; }
727 | '-' addrRegNegOffset { $$ = -$2; }
728 ;
729
730 addrRegPosOffset: INTEGER
731 {
732 if (($1 < 0) || ($1 > 63)) {
733 yyerror(& @1, state,
734 "relative address offset too large (positive)");
735 YYERROR;
736 } else {
737 $$ = $1;
738 }
739 }
740 ;
741
742 addrRegNegOffset: INTEGER
743 {
744 if (($1 < 0) || ($1 > 64)) {
745 yyerror(& @1, state,
746 "relative address offset too large (negative)");
747 YYERROR;
748 } else {
749 $$ = $1;
750 }
751 }
752 ;
753
754 addrReg: IDENTIFIER
755 {
756 struct asm_symbol *const s = (struct asm_symbol *)
757 _mesa_symbol_table_find_symbol(state->st, 0, $1);
758
759 if (s == NULL) {
760 yyerror(& @1, state, "invalid array member");
761 YYERROR;
762 } else if (s->type != at_address) {
763 yyerror(& @1, state,
764 "invalid variable for indexed array access");
765 YYERROR;
766 } else {
767 $$ = s;
768 }
769 }
770 ;
771
772 addrComponent: MASK1
773 {
774 if ($1.mask != WRITEMASK_X) {
775 yyerror(& @1, state, "invalid address component selector");
776 YYERROR;
777 } else {
778 $$ = $1;
779 }
780 }
781 ;
782
783 addrWriteMask: MASK1
784 {
785 if ($1.mask != WRITEMASK_X) {
786 yyerror(& @1, state,
787 "address register write mask must be \".x\"");
788 YYERROR;
789 } else {
790 $$ = $1;
791 }
792 }
793 ;
794
795 scalarSuffix: MASK1;
796
797 swizzleSuffix: MASK1
798 | MASK4
799 | SWIZZLE
800 | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
801 ;
802
803 optionalMask: MASK4 | MASK3 | MASK2 | MASK1
804 | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
805 ;
806
807 namingStatement: ATTRIB_statement
808 | PARAM_statement
809 | TEMP_statement
810 | ADDRESS_statement
811 | OUTPUT_statement
812 | ALIAS_statement
813 ;
814
815 ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
816 {
817 struct asm_symbol *const s =
818 declare_variable(state, $2, at_attrib, & @2);
819
820 if (s == NULL) {
821 YYERROR;
822 } else {
823 s->attrib_binding = $4;
824 state->InputsBound |= (1U << s->attrib_binding);
825
826 if (!validate_inputs(& @4, state)) {
827 YYERROR;
828 }
829 }
830 }
831 ;
832
833 attribBinding: VERTEX vtxAttribItem
834 {
835 $$ = $2;
836 }
837 | FRAGMENT fragAttribItem
838 {
839 $$ = $2;
840 }
841 ;
842
843 vtxAttribItem: POSITION
844 {
845 $$ = VERT_ATTRIB_POS;
846 }
847 | WEIGHT vtxOptWeightNum
848 {
849 $$ = VERT_ATTRIB_WEIGHT;
850 }
851 | NORMAL
852 {
853 $$ = VERT_ATTRIB_NORMAL;
854 }
855 | COLOR optColorType
856 {
857 if (!state->ctx->Extensions.EXT_secondary_color) {
858 yyerror(& @2, state, "GL_EXT_secondary_color not supported");
859 YYERROR;
860 }
861
862 $$ = VERT_ATTRIB_COLOR0 + $2;
863 }
864 | FOGCOORD
865 {
866 if (!state->ctx->Extensions.EXT_fog_coord) {
867 yyerror(& @1, state, "GL_EXT_fog_coord not supported");
868 YYERROR;
869 }
870
871 $$ = VERT_ATTRIB_FOG;
872 }
873 | TEXCOORD optTexCoordUnitNum
874 {
875 $$ = VERT_ATTRIB_TEX0 + $2;
876 }
877 | MATRIXINDEX '[' vtxWeightNum ']'
878 {
879 yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
880 YYERROR;
881 }
882 | VTXATTRIB '[' vtxAttribNum ']'
883 {
884 $$ = VERT_ATTRIB_GENERIC0 + $3;
885 }
886 ;
887
888 vtxAttribNum: INTEGER
889 {
890 if ((unsigned) $1 >= state->limits->MaxAttribs) {
891 yyerror(& @1, state, "invalid vertex attribute reference");
892 YYERROR;
893 }
894
895 $$ = $1;
896 }
897 ;
898
899 vtxOptWeightNum: | '[' vtxWeightNum ']';
900 vtxWeightNum: INTEGER;
901
902 fragAttribItem: POSITION
903 {
904 $$ = FRAG_ATTRIB_WPOS;
905 }
906 | COLOR optColorType
907 {
908 $$ = FRAG_ATTRIB_COL0 + $2;
909 }
910 | FOGCOORD
911 {
912 $$ = FRAG_ATTRIB_FOGC;
913 }
914 | TEXCOORD optTexCoordUnitNum
915 {
916 $$ = FRAG_ATTRIB_TEX0 + $2;
917 }
918 ;
919
920 PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt;
921
922 PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
923 {
924 struct asm_symbol *const s =
925 declare_variable(state, $2, at_param, & @2);
926
927 if (s == NULL) {
928 YYERROR;
929 } else {
930 s->param_binding_type = $3.param_binding_type;
931 s->param_binding_begin = $3.param_binding_begin;
932 s->param_binding_length = $3.param_binding_length;
933 s->param_is_array = 0;
934 }
935 }
936 ;
937
938 PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
939 {
940 if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
941 yyerror(& @4, state,
942 "parameter array size and number of bindings must match");
943 YYERROR;
944 } else {
945 struct asm_symbol *const s =
946 declare_variable(state, $2, $6.type, & @2);
947
948 if (s == NULL) {
949 YYERROR;
950 } else {
951 s->param_binding_type = $6.param_binding_type;
952 s->param_binding_begin = $6.param_binding_begin;
953 s->param_binding_length = $6.param_binding_length;
954 s->param_is_array = 1;
955 }
956 }
957 }
958 ;
959
960 optArraySize:
961 {
962 $$ = 0;
963 }
964 | INTEGER
965 {
966 if (($1 < 1) || ((unsigned) $1 >= state->limits->MaxParameters)) {
967 yyerror(& @1, state, "invalid parameter array size");
968 YYERROR;
969 } else {
970 $$ = $1;
971 }
972 }
973 ;
974
975 paramSingleInit: '=' paramSingleItemDecl
976 {
977 $$ = $2;
978 }
979 ;
980
981 paramMultipleInit: '=' '{' paramMultInitList '}'
982 {
983 $$ = $3;
984 }
985 ;
986
987 paramMultInitList: paramMultipleItem
988 | paramMultInitList ',' paramMultipleItem
989 {
990 $1.param_binding_length += $3.param_binding_length;
991 $$ = $1;
992 }
993 ;
994
995 paramSingleItemDecl: stateSingleItem
996 {
997 memset(& $$, 0, sizeof($$));
998 $$.param_binding_begin = ~0;
999 initialize_symbol_from_state(state->prog, & $$, $1);
1000 }
1001 | programSingleItem
1002 {
1003 memset(& $$, 0, sizeof($$));
1004 $$.param_binding_begin = ~0;
1005 initialize_symbol_from_param(state->prog, & $$, $1);
1006 }
1007 | paramConstDecl
1008 {
1009 memset(& $$, 0, sizeof($$));
1010 $$.param_binding_begin = ~0;
1011 initialize_symbol_from_const(state->prog, & $$, & $1);
1012 }
1013 ;
1014
1015 paramSingleItemUse: stateSingleItem
1016 {
1017 memset(& $$, 0, sizeof($$));
1018 $$.param_binding_begin = ~0;
1019 initialize_symbol_from_state(state->prog, & $$, $1);
1020 }
1021 | programSingleItem
1022 {
1023 memset(& $$, 0, sizeof($$));
1024 $$.param_binding_begin = ~0;
1025 initialize_symbol_from_param(state->prog, & $$, $1);
1026 }
1027 | paramConstUse
1028 {
1029 memset(& $$, 0, sizeof($$));
1030 $$.param_binding_begin = ~0;
1031 initialize_symbol_from_const(state->prog, & $$, & $1);
1032 }
1033 ;
1034
1035 paramMultipleItem: stateMultipleItem
1036 {
1037 memset(& $$, 0, sizeof($$));
1038 $$.param_binding_begin = ~0;
1039 initialize_symbol_from_state(state->prog, & $$, $1);
1040 }
1041 | programMultipleItem
1042 {
1043 memset(& $$, 0, sizeof($$));
1044 $$.param_binding_begin = ~0;
1045 initialize_symbol_from_param(state->prog, & $$, $1);
1046 }
1047 | paramConstDecl
1048 {
1049 memset(& $$, 0, sizeof($$));
1050 $$.param_binding_begin = ~0;
1051 initialize_symbol_from_const(state->prog, & $$, & $1);
1052 }
1053 ;
1054
1055 stateMultipleItem: stateSingleItem { memcpy($$, $1, sizeof($$)); }
1056 | STATE stateMatrixRows { memcpy($$, $2, sizeof($$)); }
1057 ;
1058
1059 stateSingleItem: STATE stateMaterialItem { memcpy($$, $2, sizeof($$)); }
1060 | STATE stateLightItem { memcpy($$, $2, sizeof($$)); }
1061 | STATE stateLightModelItem { memcpy($$, $2, sizeof($$)); }
1062 | STATE stateLightProdItem { memcpy($$, $2, sizeof($$)); }
1063 | STATE stateTexGenItem { memcpy($$, $2, sizeof($$)); }
1064 | STATE stateTexEnvItem { memcpy($$, $2, sizeof($$)); }
1065 | STATE stateFogItem { memcpy($$, $2, sizeof($$)); }
1066 | STATE stateClipPlaneItem { memcpy($$, $2, sizeof($$)); }
1067 | STATE statePointItem { memcpy($$, $2, sizeof($$)); }
1068 | STATE stateMatrixRow { memcpy($$, $2, sizeof($$)); }
1069 ;
1070
1071 stateMaterialItem: MATERIAL optFaceType stateMatProperty
1072 {
1073 memset($$, 0, sizeof($$));
1074 $$[0] = STATE_MATERIAL;
1075 $$[1] = $2;
1076 $$[2] = $3;
1077 }
1078 ;
1079
1080 stateMatProperty: ambDiffSpecProperty
1081 {
1082 $$ = $1;
1083 }
1084 | EMISSION
1085 {
1086 $$ = STATE_EMISSION;
1087 }
1088 | SHININESS
1089 {
1090 $$ = STATE_SHININESS;
1091 }
1092 ;
1093
1094 stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
1095 {
1096 memset($$, 0, sizeof($$));
1097 $$[0] = STATE_LIGHT;
1098 $$[1] = $3;
1099 $$[2] = $5;
1100 }
1101 ;
1102
1103 stateLightProperty: ambDiffSpecProperty
1104 {
1105 $$ = $1;
1106 }
1107 | POSITION
1108 {
1109 $$ = STATE_POSITION;
1110 }
1111 | ATTENUATION
1112 {
1113 if (!state->ctx->Extensions.EXT_point_parameters) {
1114 yyerror(& @1, state, "GL_ARB_point_parameters not supported");
1115 YYERROR;
1116 }
1117
1118 $$ = STATE_ATTENUATION;
1119 }
1120 | SPOT stateSpotProperty
1121 {
1122 $$ = $2;
1123 }
1124 | HALF
1125 {
1126 $$ = STATE_HALF_VECTOR;
1127 }
1128 ;
1129
1130 stateSpotProperty: DIRECTION
1131 {
1132 $$ = STATE_SPOT_DIRECTION;
1133 }
1134 ;
1135
1136 stateLightModelItem: LIGHTMODEL stateLModProperty
1137 {
1138 $$[0] = $2[0];
1139 $$[1] = $2[1];
1140 }
1141 ;
1142
1143 stateLModProperty: AMBIENT
1144 {
1145 memset($$, 0, sizeof($$));
1146 $$[0] = STATE_LIGHTMODEL_AMBIENT;
1147 }
1148 | optFaceType SCENECOLOR
1149 {
1150 memset($$, 0, sizeof($$));
1151 $$[0] = STATE_LIGHTMODEL_SCENECOLOR;
1152 $$[1] = $1;
1153 }
1154 ;
1155
1156 stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty
1157 {
1158 memset($$, 0, sizeof($$));
1159 $$[0] = STATE_LIGHTPROD;
1160 $$[1] = $3;
1161 $$[2] = $5;
1162 $$[3] = $6;
1163 }
1164 ;
1165
1166 stateLProdProperty: ambDiffSpecProperty;
1167
1168 stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
1169 {
1170 memset($$, 0, sizeof($$));
1171 $$[0] = $3;
1172 $$[1] = $2;
1173 }
1174 ;
1175
1176 stateTexEnvProperty: COLOR
1177 {
1178 $$ = STATE_TEXENV_COLOR;
1179 }
1180 ;
1181
1182 ambDiffSpecProperty: AMBIENT
1183 {
1184 $$ = STATE_AMBIENT;
1185 }
1186 | DIFFUSE
1187 {
1188 $$ = STATE_DIFFUSE;
1189 }
1190 | SPECULAR
1191 {
1192 $$ = STATE_SPECULAR;
1193 }
1194 ;
1195
1196 stateLightNumber: INTEGER
1197 {
1198 if ((unsigned) $1 >= state->MaxLights) {
1199 yyerror(& @1, state, "invalid light selector");
1200 YYERROR;
1201 }
1202
1203 $$ = $1;
1204 }
1205 ;
1206
1207 stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord
1208 {
1209 memset($$, 0, sizeof($$));
1210 $$[0] = STATE_TEXGEN;
1211 $$[1] = $2;
1212 $$[2] = $3 + $4;
1213 }
1214 ;
1215
1216 stateTexGenType: EYE
1217 {
1218 $$ = STATE_TEXGEN_EYE_S;
1219 }
1220 | OBJECT
1221 {
1222 $$ = STATE_TEXGEN_OBJECT_S;
1223 }
1224 ;
1225 stateTexGenCoord: TEXGEN_S
1226 {
1227 $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
1228 }
1229 | TEXGEN_T
1230 {
1231 $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
1232 }
1233 | TEXGEN_R
1234 {
1235 $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
1236 }
1237 | TEXGEN_Q
1238 {
1239 $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
1240 }
1241 ;
1242
1243 stateFogItem: FOG stateFogProperty
1244 {
1245 memset($$, 0, sizeof($$));
1246 $$[0] = $2;
1247 }
1248 ;
1249
1250 stateFogProperty: COLOR
1251 {
1252 $$ = STATE_FOG_COLOR;
1253 }
1254 | PARAMS
1255 {
1256 $$ = STATE_FOG_PARAMS;
1257 }
1258 ;
1259
1260 stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE
1261 {
1262 memset($$, 0, sizeof($$));
1263 $$[0] = STATE_CLIPPLANE;
1264 $$[1] = $3;
1265 }
1266 ;
1267
1268 stateClipPlaneNum: INTEGER
1269 {
1270 if ((unsigned) $1 >= state->MaxClipPlanes) {
1271 yyerror(& @1, state, "invalid clip plane selector");
1272 YYERROR;
1273 }
1274
1275 $$ = $1;
1276 }
1277 ;
1278
1279 statePointItem: POINT statePointProperty
1280 {
1281 memset($$, 0, sizeof($$));
1282 $$[0] = $2;
1283 }
1284 ;
1285
1286 statePointProperty: SIZE
1287 {
1288 $$ = STATE_POINT_SIZE;
1289 }
1290 | ATTENUATION
1291 {
1292 $$ = STATE_POINT_ATTENUATION;
1293 }
1294 ;
1295
1296 stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']'
1297 {
1298 $$[0] = $1[0];
1299 $$[1] = $1[1];
1300 $$[2] = $4;
1301 $$[3] = $4;
1302 $$[4] = $1[2];
1303 }
1304 ;
1305
1306 stateMatrixRows: stateMatrixItem optMatrixRows
1307 {
1308 $$[0] = $1[0];
1309 $$[1] = $1[1];
1310 $$[2] = $2[2];
1311 $$[3] = $2[3];
1312 $$[4] = $1[2];
1313 }
1314 ;
1315
1316 optMatrixRows:
1317 {
1318 $$[2] = 0;
1319 $$[3] = 3;
1320 }
1321 | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']'
1322 {
1323 /* It seems logical that the matrix row range specifier would have
1324 * to specify a range or more than one row (i.e., $5 > $3).
1325 * However, the ARB_vertex_program spec says "a program will fail
1326 * to load if <a> is greater than <b>." This means that $3 == $5
1327 * is valid.
1328 */
1329 if ($3 > $5) {
1330 yyerror(& @3, state, "invalid matrix row range");
1331 YYERROR;
1332 }
1333
1334 $$[2] = $3;
1335 $$[3] = $5;
1336 }
1337 ;
1338
1339 stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier
1340 {
1341 $$[0] = $2[0];
1342 $$[1] = $2[1];
1343 $$[2] = $3;
1344 }
1345 ;
1346
1347 stateOptMatModifier:
1348 {
1349 $$ = 0;
1350 }
1351 | stateMatModifier
1352 {
1353 $$ = $1;
1354 }
1355 ;
1356
1357 stateMatModifier: INVERSE
1358 {
1359 $$ = STATE_MATRIX_INVERSE;
1360 }
1361 | TRANSPOSE
1362 {
1363 $$ = STATE_MATRIX_TRANSPOSE;
1364 }
1365 | INVTRANS
1366 {
1367 $$ = STATE_MATRIX_INVTRANS;
1368 }
1369 ;
1370
1371 stateMatrixRowNum: INTEGER
1372 {
1373 if ($1 > 3) {
1374 yyerror(& @1, state, "invalid matrix row reference");
1375 YYERROR;
1376 }
1377
1378 $$ = $1;
1379 }
1380 ;
1381
1382 stateMatrixName: MODELVIEW stateOptModMatNum
1383 {
1384 $$[0] = STATE_MODELVIEW_MATRIX;
1385 $$[1] = $2;
1386 }
1387 | PROJECTION
1388 {
1389 $$[0] = STATE_PROJECTION_MATRIX;
1390 $$[1] = 0;
1391 }
1392 | MVP
1393 {
1394 $$[0] = STATE_MVP_MATRIX;
1395 $$[1] = 0;
1396 }
1397 | TEXTURE optTexCoordUnitNum
1398 {
1399 $$[0] = STATE_TEXTURE_MATRIX;
1400 $$[1] = $2;
1401 }
1402 | PALETTE '[' statePaletteMatNum ']'
1403 {
1404 yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
1405 YYERROR;
1406 }
1407 | MAT_PROGRAM '[' stateProgramMatNum ']'
1408 {
1409 $$[0] = STATE_PROGRAM_MATRIX;
1410 $$[1] = $3;
1411 }
1412 ;
1413
1414 stateOptModMatNum:
1415 {
1416 $$ = 0;
1417 }
1418 | stateModMatNum
1419 {
1420 $$ = $1;
1421 }
1422 ;
1423 stateModMatNum: INTEGER
1424 {
1425 /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
1426 * zero is valid.
1427 */
1428 if ($1 != 0) {
1429 yyerror(& @1, state, "invalid modelview matrix index");
1430 YYERROR;
1431 }
1432
1433 $$ = $1;
1434 }
1435 ;
1436 statePaletteMatNum: INTEGER
1437 {
1438 /* Since GL_ARB_matrix_palette isn't supported, just let any value
1439 * through here. The error will be generated later.
1440 */
1441 $$ = $1;
1442 }
1443 ;
1444 stateProgramMatNum: INTEGER
1445 {
1446 if ((unsigned) $1 >= state->MaxProgramMatrices) {
1447 yyerror(& @1, state, "invalid program matrix selector");
1448 YYERROR;
1449 }
1450
1451 $$ = $1;
1452 }
1453 ;
1454
1455
1456
1457 programSingleItem: progEnvParam | progLocalParam;
1458
1459 programMultipleItem: progEnvParams | progLocalParams;
1460
1461 progEnvParams: PROGRAM ENV '[' progEnvParamNums ']'
1462 {
1463 memset($$, 0, sizeof($$));
1464 $$[0] = state->state_param_enum;
1465 $$[1] = STATE_ENV;
1466 $$[2] = $4[0];
1467 $$[3] = $4[1];
1468 }
1469 ;
1470
1471 progEnvParamNums: progEnvParamNum
1472 {
1473 $$[0] = $1;
1474 $$[1] = $1;
1475 }
1476 | progEnvParamNum DOT_DOT progEnvParamNum
1477 {
1478 $$[0] = $1;
1479 $$[1] = $3;
1480 }
1481 ;
1482
1483 progEnvParam: PROGRAM ENV '[' progEnvParamNum ']'
1484 {
1485 memset($$, 0, sizeof($$));
1486 $$[0] = state->state_param_enum;
1487 $$[1] = STATE_ENV;
1488 $$[2] = $4;
1489 $$[3] = $4;
1490 }
1491 ;
1492
1493 progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']'
1494 {
1495 memset($$, 0, sizeof($$));
1496 $$[0] = state->state_param_enum;
1497 $$[1] = STATE_LOCAL;
1498 $$[2] = $4[0];
1499 $$[3] = $4[1];
1500 }
1501
1502 progLocalParamNums: progLocalParamNum
1503 {
1504 $$[0] = $1;
1505 $$[1] = $1;
1506 }
1507 | progLocalParamNum DOT_DOT progLocalParamNum
1508 {
1509 $$[0] = $1;
1510 $$[1] = $3;
1511 }
1512 ;
1513
1514 progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']'
1515 {
1516 memset($$, 0, sizeof($$));
1517 $$[0] = state->state_param_enum;
1518 $$[1] = STATE_LOCAL;
1519 $$[2] = $4;
1520 $$[3] = $4;
1521 }
1522 ;
1523
1524 progEnvParamNum: INTEGER
1525 {
1526 if ((unsigned) $1 >= state->limits->MaxEnvParams) {
1527 yyerror(& @1, state, "invalid environment parameter reference");
1528 YYERROR;
1529 }
1530 $$ = $1;
1531 }
1532 ;
1533
1534 progLocalParamNum: INTEGER
1535 {
1536 if ((unsigned) $1 >= state->limits->MaxLocalParams) {
1537 yyerror(& @1, state, "invalid local parameter reference");
1538 YYERROR;
1539 }
1540 $$ = $1;
1541 }
1542 ;
1543
1544
1545
1546 paramConstDecl: paramConstScalarDecl | paramConstVector;
1547 paramConstUse: paramConstScalarUse | paramConstVector;
1548
1549 paramConstScalarDecl: signedFloatConstant
1550 {
1551 $$.count = 1;
1552 $$.data[0] = $1;
1553 }
1554 ;
1555
1556 paramConstScalarUse: REAL
1557 {
1558 $$.count = 1;
1559 $$.data[0] = $1;
1560 }
1561 | INTEGER
1562 {
1563 $$.count = 1;
1564 $$.data[0] = (float) $1;
1565 }
1566 ;
1567
1568 paramConstVector: '{' signedFloatConstant '}'
1569 {
1570 $$.count = 1;
1571 $$.data[0] = $2;
1572 $$.data[1] = 0.0f;
1573 $$.data[2] = 0.0f;
1574 $$.data[3] = 0.0f;
1575 }
1576 | '{' signedFloatConstant ',' signedFloatConstant '}'
1577 {
1578 $$.count = 2;
1579 $$.data[0] = $2;
1580 $$.data[1] = $4;
1581 $$.data[2] = 0.0f;
1582 $$.data[3] = 0.0f;
1583 }
1584 | '{' signedFloatConstant ',' signedFloatConstant ','
1585 signedFloatConstant '}'
1586 {
1587 $$.count = 3;
1588 $$.data[0] = $2;
1589 $$.data[1] = $4;
1590 $$.data[2] = $6;
1591 $$.data[3] = 0.0f;
1592 }
1593 | '{' signedFloatConstant ',' signedFloatConstant ','
1594 signedFloatConstant ',' signedFloatConstant '}'
1595 {
1596 $$.count = 4;
1597 $$.data[0] = $2;
1598 $$.data[1] = $4;
1599 $$.data[2] = $6;
1600 $$.data[3] = $8;
1601 }
1602 ;
1603
1604 signedFloatConstant: optionalSign REAL
1605 {
1606 $$ = ($1) ? -$2 : $2;
1607 }
1608 | optionalSign INTEGER
1609 {
1610 $$ = (float)(($1) ? -$2 : $2);
1611 }
1612 ;
1613
1614 optionalSign: '+' { $$ = FALSE; }
1615 | '-' { $$ = TRUE; }
1616 | { $$ = FALSE; }
1617 ;
1618
1619 TEMP_statement: TEMP { $<integer>$ = $1; } varNameList
1620 ;
1621
1622 ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
1623 ;
1624
1625 varNameList: varNameList ',' IDENTIFIER
1626 {
1627 if (!declare_variable(state, $3, $<integer>0, & @3)) {
1628 YYERROR;
1629 }
1630 }
1631 | IDENTIFIER
1632 {
1633 if (!declare_variable(state, $1, $<integer>0, & @1)) {
1634 YYERROR;
1635 }
1636 }
1637 ;
1638
1639 OUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding
1640 {
1641 struct asm_symbol *const s =
1642 declare_variable(state, $2, at_output, & @2);
1643
1644 if (s == NULL) {
1645 YYERROR;
1646 } else {
1647 s->output_binding = $4;
1648 }
1649 }
1650 ;
1651
1652 resultBinding: RESULT POSITION
1653 {
1654 if (state->mode == ARB_vertex) {
1655 $$ = VERT_RESULT_HPOS;
1656 } else {
1657 yyerror(& @2, state, "invalid program result name");
1658 YYERROR;
1659 }
1660 }
1661 | RESULT FOGCOORD
1662 {
1663 if (state->mode == ARB_vertex) {
1664 $$ = VERT_RESULT_FOGC;
1665 } else {
1666 yyerror(& @2, state, "invalid program result name");
1667 YYERROR;
1668 }
1669 }
1670 | RESULT resultColBinding
1671 {
1672 $$ = $2;
1673 }
1674 | RESULT POINTSIZE
1675 {
1676 if (state->mode == ARB_vertex) {
1677 $$ = VERT_RESULT_PSIZ;
1678 } else {
1679 yyerror(& @2, state, "invalid program result name");
1680 YYERROR;
1681 }
1682 }
1683 | RESULT TEXCOORD optTexCoordUnitNum
1684 {
1685 if (state->mode == ARB_vertex) {
1686 $$ = VERT_RESULT_TEX0 + $3;
1687 } else {
1688 yyerror(& @2, state, "invalid program result name");
1689 YYERROR;
1690 }
1691 }
1692 | RESULT DEPTH
1693 {
1694 if (state->mode == ARB_fragment) {
1695 $$ = FRAG_RESULT_DEPTH;
1696 } else {
1697 yyerror(& @2, state, "invalid program result name");
1698 YYERROR;
1699 }
1700 }
1701 ;
1702
1703 resultColBinding: COLOR optResultFaceType optResultColorType
1704 {
1705 $$ = $2 + $3;
1706 }
1707 ;
1708
1709 optResultFaceType:
1710 {
1711 $$ = (state->mode == ARB_vertex)
1712 ? VERT_RESULT_COL0
1713 : FRAG_RESULT_COLOR;
1714 }
1715 | FRONT
1716 {
1717 if (state->mode == ARB_vertex) {
1718 $$ = VERT_RESULT_COL0;
1719 } else {
1720 yyerror(& @1, state, "invalid program result name");
1721 YYERROR;
1722 }
1723 }
1724 | BACK
1725 {
1726 if (state->mode == ARB_vertex) {
1727 $$ = VERT_RESULT_BFC0;
1728 } else {
1729 yyerror(& @1, state, "invalid program result name");
1730 YYERROR;
1731 }
1732 }
1733 ;
1734
1735 optResultColorType:
1736 {
1737 $$ = 0;
1738 }
1739 | PRIMARY
1740 {
1741 if (state->mode == ARB_vertex) {
1742 $$ = 0;
1743 } else {
1744 yyerror(& @1, state, "invalid program result name");
1745 YYERROR;
1746 }
1747 }
1748 | SECONDARY
1749 {
1750 if (state->mode == ARB_vertex) {
1751 $$ = 1;
1752 } else {
1753 yyerror(& @1, state, "invalid program result name");
1754 YYERROR;
1755 }
1756 }
1757 ;
1758
1759 optFaceType: { $$ = 0; }
1760 | FRONT { $$ = 0; }
1761 | BACK { $$ = 1; }
1762 ;
1763
1764 optColorType: { $$ = 0; }
1765 | PRIMARY { $$ = 0; }
1766 | SECONDARY { $$ = 1; }
1767 ;
1768
1769 optTexCoordUnitNum: { $$ = 0; }
1770 | '[' texCoordUnitNum ']' { $$ = $2; }
1771 ;
1772
1773 optTexImageUnitNum: { $$ = 0; }
1774 | '[' texImageUnitNum ']' { $$ = $2; }
1775 ;
1776
1777 optLegacyTexUnitNum: { $$ = 0; }
1778 | '[' legacyTexUnitNum ']' { $$ = $2; }
1779 ;
1780
1781 texCoordUnitNum: INTEGER
1782 {
1783 if ((unsigned) $1 >= state->MaxTextureCoordUnits) {
1784 yyerror(& @1, state, "invalid texture coordinate unit selector");
1785 YYERROR;
1786 }
1787
1788 $$ = $1;
1789 }
1790 ;
1791
1792 texImageUnitNum: INTEGER
1793 {
1794 if ((unsigned) $1 >= state->MaxTextureImageUnits) {
1795 yyerror(& @1, state, "invalid texture image unit selector");
1796 YYERROR;
1797 }
1798
1799 $$ = $1;
1800 }
1801 ;
1802
1803 legacyTexUnitNum: INTEGER
1804 {
1805 if ((unsigned) $1 >= state->MaxTextureUnits) {
1806 yyerror(& @1, state, "invalid texture unit selector");
1807 YYERROR;
1808 }
1809
1810 $$ = $1;
1811 }
1812 ;
1813
1814 ALIAS_statement: ALIAS IDENTIFIER '=' IDENTIFIER
1815 {
1816 struct asm_symbol *exist = (struct asm_symbol *)
1817 _mesa_symbol_table_find_symbol(state->st, 0, $2);
1818 struct asm_symbol *target = (struct asm_symbol *)
1819 _mesa_symbol_table_find_symbol(state->st, 0, $4);
1820
1821
1822 if (exist != NULL) {
1823 yyerror(& @2, state, "redeclared identifier");
1824 YYERROR;
1825 } else if (target == NULL) {
1826 yyerror(& @4, state,
1827 "undefined variable binding in ALIAS statement");
1828 YYERROR;
1829 } else {
1830 _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
1831 }
1832 }
1833 ;
1834
1835 %%
1836
1837 struct asm_instruction *
1838 asm_instruction_ctor(gl_inst_opcode op,
1839 const struct prog_dst_register *dst,
1840 const struct asm_src_register *src0,
1841 const struct asm_src_register *src1,
1842 const struct asm_src_register *src2)
1843 {
1844 struct asm_instruction *inst = calloc(1, sizeof(struct asm_instruction));
1845
1846 if (inst) {
1847 _mesa_init_instructions(& inst->Base, 1);
1848 inst->Base.Opcode = op;
1849 inst->Base.DstReg = *dst;
1850
1851 inst->Base.SrcReg[0] = src0->Base;
1852 inst->SrcReg[0] = *src0;
1853
1854 if (src1 != NULL) {
1855 inst->Base.SrcReg[1] = src1->Base;
1856 inst->SrcReg[1] = *src1;
1857 } else {
1858 init_src_reg(& inst->SrcReg[1]);
1859 }
1860
1861 if (src2 != NULL) {
1862 inst->Base.SrcReg[2] = src2->Base;
1863 inst->SrcReg[2] = *src2;
1864 } else {
1865 init_src_reg(& inst->SrcReg[2]);
1866 }
1867 }
1868
1869 return inst;
1870 }
1871
1872
1873 void
1874 init_dst_reg(struct prog_dst_register *r)
1875 {
1876 memset(r, 0, sizeof(*r));
1877 r->File = PROGRAM_UNDEFINED;
1878 r->WriteMask = WRITEMASK_XYZW;
1879 r->CondMask = COND_TR;
1880 r->CondSwizzle = SWIZZLE_NOOP;
1881 }
1882
1883
1884 void
1885 init_src_reg(struct asm_src_register *r)
1886 {
1887 memset(r, 0, sizeof(*r));
1888 r->Base.File = PROGRAM_UNDEFINED;
1889 r->Base.Swizzle = SWIZZLE_NOOP;
1890 r->Symbol = NULL;
1891 }
1892
1893
1894 /**
1895 * Validate the set of inputs used by a program
1896 *
1897 * Validates that legal sets of inputs are used by the program. In this case
1898 * "used" included both reading the input or binding the input to a name using
1899 * the \c ATTRIB command.
1900 *
1901 * \return
1902 * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
1903 */
1904 int
1905 validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
1906 {
1907 const int inputs = state->prog->InputsRead | state->InputsBound;
1908
1909 if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) {
1910 yyerror(locp, state, "illegal use of generic attribute and name attribute");
1911 return 0;
1912 }
1913
1914 return 1;
1915 }
1916
1917
1918 struct asm_symbol *
1919 declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
1920 struct YYLTYPE *locp)
1921 {
1922 struct asm_symbol *s = NULL;
1923 struct asm_symbol *exist = (struct asm_symbol *)
1924 _mesa_symbol_table_find_symbol(state->st, 0, name);
1925
1926
1927 if (exist != NULL) {
1928 yyerror(locp, state, "redeclared identifier");
1929 } else {
1930 s = calloc(1, sizeof(struct asm_symbol));
1931 s->name = name;
1932 s->type = t;
1933
1934 switch (t) {
1935 case at_temp:
1936 if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
1937 yyerror(locp, state, "too many temporaries declared");
1938 free(s);
1939 return NULL;
1940 }
1941
1942 s->temp_binding = state->prog->NumTemporaries;
1943 state->prog->NumTemporaries++;
1944 break;
1945
1946 case at_address:
1947 if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
1948 yyerror(locp, state, "too many address registers declared");
1949 free(s);
1950 return NULL;
1951 }
1952
1953 /* FINISHME: Add support for multiple address registers.
1954 */
1955 state->prog->NumAddressRegs++;
1956 break;
1957
1958 default:
1959 break;
1960 }
1961
1962 _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
1963 s->next = state->sym;
1964 state->sym = s;
1965 }
1966
1967 return s;
1968 }
1969
1970
1971 int add_state_reference(struct gl_program_parameter_list *param_list,
1972 const gl_state_index tokens[STATE_LENGTH])
1973 {
1974 const GLuint size = 4; /* XXX fix */
1975 char *name;
1976 GLint index;
1977
1978 name = _mesa_program_state_string(tokens);
1979 index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
1980 size, GL_NONE,
1981 NULL, (gl_state_index *) tokens, 0x0);
1982 param_list->StateFlags |= _mesa_program_state_flags(tokens);
1983
1984 /* free name string here since we duplicated it in add_parameter() */
1985 _mesa_free(name);
1986
1987 return index;
1988 }
1989
1990
1991 int
1992 initialize_symbol_from_state(struct gl_program *prog,
1993 struct asm_symbol *param_var,
1994 const gl_state_index tokens[STATE_LENGTH])
1995 {
1996 int idx = -1;
1997 gl_state_index state_tokens[STATE_LENGTH];
1998
1999
2000 memcpy(state_tokens, tokens, sizeof(state_tokens));
2001
2002 param_var->type = at_param;
2003 param_var->param_binding_type = PROGRAM_STATE_VAR;
2004
2005 /* If we are adding a STATE_MATRIX that has multiple rows, we need to
2006 * unroll it and call add_state_reference() for each row
2007 */
2008 if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
2009 state_tokens[0] == STATE_PROJECTION_MATRIX ||
2010 state_tokens[0] == STATE_MVP_MATRIX ||
2011 state_tokens[0] == STATE_TEXTURE_MATRIX ||
2012 state_tokens[0] == STATE_PROGRAM_MATRIX)
2013 && (state_tokens[2] != state_tokens[3])) {
2014 int row;
2015 const int first_row = state_tokens[2];
2016 const int last_row = state_tokens[3];
2017
2018 for (row = first_row; row <= last_row; row++) {
2019 state_tokens[2] = state_tokens[3] = row;
2020
2021 idx = add_state_reference(prog->Parameters, state_tokens);
2022 if (param_var->param_binding_begin == ~0U)
2023 param_var->param_binding_begin = idx;
2024 param_var->param_binding_length++;
2025 }
2026 }
2027 else {
2028 idx = add_state_reference(prog->Parameters, state_tokens);
2029 if (param_var->param_binding_begin == ~0U)
2030 param_var->param_binding_begin = idx;
2031 param_var->param_binding_length++;
2032 }
2033
2034 return idx;
2035 }
2036
2037
2038 int
2039 initialize_symbol_from_param(struct gl_program *prog,
2040 struct asm_symbol *param_var,
2041 const gl_state_index tokens[STATE_LENGTH])
2042 {
2043 int idx = -1;
2044 gl_state_index state_tokens[STATE_LENGTH];
2045
2046
2047 memcpy(state_tokens, tokens, sizeof(state_tokens));
2048
2049 assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
2050 || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
2051 assert((state_tokens[1] == STATE_ENV)
2052 || (state_tokens[1] == STATE_LOCAL));
2053
2054 param_var->type = at_param;
2055 param_var->param_binding_type = (state_tokens[1] == STATE_ENV)
2056 ? PROGRAM_ENV_PARAM : PROGRAM_LOCAL_PARAM;
2057
2058 /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
2059 * we need to unroll it and call add_state_reference() for each row
2060 */
2061 if (state_tokens[2] != state_tokens[3]) {
2062 int row;
2063 const int first_row = state_tokens[2];
2064 const int last_row = state_tokens[3];
2065
2066 for (row = first_row; row <= last_row; row++) {
2067 state_tokens[2] = state_tokens[3] = row;
2068
2069 idx = add_state_reference(prog->Parameters, state_tokens);
2070 if (param_var->param_binding_begin == ~0U)
2071 param_var->param_binding_begin = idx;
2072 param_var->param_binding_length++;
2073 }
2074 }
2075 else {
2076 idx = add_state_reference(prog->Parameters, state_tokens);
2077 if (param_var->param_binding_begin == ~0U)
2078 param_var->param_binding_begin = idx;
2079 param_var->param_binding_length++;
2080 }
2081
2082 return idx;
2083 }
2084
2085
2086 int
2087 initialize_symbol_from_const(struct gl_program *prog,
2088 struct asm_symbol *param_var,
2089 const struct asm_vector *vec)
2090 {
2091 const int idx = _mesa_add_parameter(prog->Parameters, PROGRAM_CONSTANT,
2092 NULL, vec->count, GL_NONE, vec->data,
2093 NULL, 0x0);
2094
2095 param_var->type = at_param;
2096 param_var->param_binding_type = PROGRAM_CONSTANT;
2097
2098 if (param_var->param_binding_begin == ~0U)
2099 param_var->param_binding_begin = idx;
2100 param_var->param_binding_length++;
2101
2102 return idx;
2103 }
2104
2105
2106 char *
2107 make_error_string(const char *fmt, ...)
2108 {
2109 int length;
2110 char *str;
2111 va_list args;
2112
2113 va_start(args, fmt);
2114
2115 /* Call vsnprintf once to determine how large the final string is. Call it
2116 * again to do the actual formatting. from the vsnprintf manual page:
2117 *
2118 * Upon successful return, these functions return the number of
2119 * characters printed (not including the trailing '\0' used to end
2120 * output to strings).
2121 */
2122 length = 1 + vsnprintf(NULL, 0, fmt, args);
2123
2124 str = _mesa_malloc(length);
2125 if (str) {
2126 vsnprintf(str, length, fmt, args);
2127 }
2128
2129 va_end(args);
2130
2131 return str;
2132 }
2133
2134
2135 void
2136 yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
2137 {
2138 char *err_str;
2139
2140
2141 err_str = make_error_string("glProgramStringARB(%s)\n", s);
2142 if (err_str) {
2143 _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str);
2144 _mesa_free(err_str);
2145 }
2146
2147 err_str = make_error_string("line %u, char %u: error: %s\n",
2148 locp->first_line, locp->first_column, s);
2149 _mesa_set_program_error(state->ctx, locp->position, err_str);
2150
2151 if (err_str) {
2152 _mesa_free(err_str);
2153 }
2154 }
2155
2156
2157 GLboolean
2158 _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
2159 GLsizei len, struct asm_parser_state *state)
2160 {
2161 struct gl_program_constants limits;
2162 struct asm_instruction *inst;
2163 unsigned i;
2164 GLubyte *strz;
2165 GLboolean result = GL_FALSE;
2166 void *temp;
2167 struct asm_symbol *sym;
2168
2169 state->ctx = ctx;
2170 state->prog->Target = target;
2171 state->prog->Parameters = _mesa_new_parameter_list();
2172
2173 /* Make a copy of the program string and force it to be NUL-terminated.
2174 */
2175 strz = (GLubyte *) _mesa_malloc(len + 1);
2176 if (strz == NULL) {
2177 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
2178 return GL_FALSE;
2179 }
2180 _mesa_memcpy (strz, str, len);
2181 strz[len] = '\0';
2182
2183 state->prog->String = strz;
2184
2185 state->st = _mesa_symbol_table_ctor();
2186
2187 /* All of these limits should come from ctx.
2188 */
2189 limits.MaxInstructions = 128;
2190 limits.MaxAluInstructions = 128;
2191 limits.MaxTexInstructions = 128;
2192 limits.MaxTexIndirections = 128;
2193 limits.MaxAttribs = 16;
2194 limits.MaxTemps = 128;
2195 limits.MaxAddressRegs = 1;
2196 limits.MaxParameters = 128;
2197 limits.MaxLocalParams = 256;
2198 limits.MaxEnvParams = 128;
2199 limits.MaxNativeInstructions = 128;
2200 limits.MaxNativeAluInstructions = 128;
2201 limits.MaxNativeTexInstructions = 128;
2202 limits.MaxNativeTexIndirections = 128;
2203 limits.MaxNativeAttribs = 16;
2204 limits.MaxNativeTemps = 128;
2205 limits.MaxNativeAddressRegs = 1;
2206 limits.MaxNativeParameters = 128;
2207 limits.MaxUniformComponents = 0;
2208
2209 state->limits = & limits;
2210
2211 state->MaxTextureImageUnits = 16;
2212 state->MaxTextureCoordUnits = 8;
2213 state->MaxTextureUnits = 8;
2214 state->MaxClipPlanes = 6;
2215 state->MaxLights = 8;
2216 state->MaxProgramMatrices = 8;
2217
2218 state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
2219 ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
2220
2221 _mesa_set_program_error(ctx, -1, NULL);
2222
2223 _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
2224 yyparse(state);
2225 _mesa_program_lexer_dtor(state->scanner);
2226
2227
2228 if (ctx->Program.ErrorPos != -1) {
2229 goto error;
2230 }
2231
2232 if (! _mesa_layout_parameters(state)) {
2233 struct YYLTYPE loc;
2234
2235 loc.first_line = 0;
2236 loc.first_column = 0;
2237 loc.position = len;
2238
2239 yyerror(& loc, state, "invalid PARAM usage");
2240 goto error;
2241 }
2242
2243
2244
2245 /* Add one instruction to store the "END" instruction.
2246 */
2247 state->prog->Instructions =
2248 _mesa_alloc_instructions(state->prog->NumInstructions + 1);
2249 inst = state->inst_head;
2250 for (i = 0; i < state->prog->NumInstructions; i++) {
2251 struct asm_instruction *const temp = inst->next;
2252
2253 state->prog->Instructions[i] = inst->Base;
2254 inst = temp;
2255 }
2256
2257 /* Finally, tag on an OPCODE_END instruction */
2258 {
2259 const GLuint numInst = state->prog->NumInstructions;
2260 _mesa_init_instructions(state->prog->Instructions + numInst, 1);
2261 state->prog->Instructions[numInst].Opcode = OPCODE_END;
2262 }
2263 state->prog->NumInstructions++;
2264
2265 state->prog->NumParameters = state->prog->Parameters->NumParameters;
2266
2267 /*
2268 * Initialize native counts to logical counts. The device driver may
2269 * change them if program is translated into a hardware program.
2270 */
2271 state->prog->NumNativeInstructions = state->prog->NumInstructions;
2272 state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
2273 state->prog->NumNativeParameters = state->prog->NumParameters;
2274 state->prog->NumNativeAttributes = state->prog->NumAttributes;
2275 state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
2276
2277 result = GL_TRUE;
2278
2279 error:
2280 for (inst = state->inst_head; inst != NULL; inst = temp) {
2281 temp = inst->next;
2282 _mesa_free(inst);
2283 }
2284
2285 state->inst_head = NULL;
2286 state->inst_tail = NULL;
2287
2288 for (sym = state->sym; sym != NULL; sym = temp) {
2289 temp = sym->next;
2290
2291 _mesa_free((void *) sym->name);
2292 _mesa_free(sym);
2293 }
2294 state->sym = NULL;
2295
2296 _mesa_symbol_table_dtor(state->st);
2297 state->st = NULL;
2298
2299 return result;
2300 }