Remove things having to do with ARB_matrix_palette/ARB_vertex_blend
[mesa.git] / src / mesa / main / arbparse.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #define DEBUG_PARSING 0
26
27 /**
28 * \file arbparse.c
29 * ARB_*_program parser core
30 * \author Michal Krol, Karl Rasche
31 */
32
33
34 #include "mtypes.h"
35 #include "glheader.h"
36 #include "context.h"
37 #include "hash.h"
38 #include "imports.h"
39 #include "macros.h"
40 #include "program.h"
41 #include "nvvertprog.h"
42 #include "nvfragprog.h"
43 #include "arbparse.h"
44
45 /* TODO:
46 * Fragment Program Stuff:
47 * -----------------------------------------------------
48 * - How does negating on SWZ work?? If any of the components have a -,
49 * negate?
50 * - how does thing like 'foo[N]' work in src registers?
51 *
52 * - things from Michal's email
53 * + overflow on atoi
54 * + not-overflowing floats (don't use parse_integer..)
55 * + test for 0 on matrix rows, or give a default value to parse_integer()
56 *
57 * - check all limits of number of various variables
58 * + parameters
59 *
60 * - test! test! test!
61 *
62 * Vertex Program Stuff:
63 * -----------------------------------------------------
64 * - ARRAY_INDEX_RELATIVE
65 * - grep for XXX
66 *
67 * Mesa Stuff
68 * -----------------------------------------------------
69 * - vp_src swizzle is GLubyte, fp_src swizzle is GLuint
70 * - fetch state listed in program_parameters list
71 * + WTF should this go???
72 * + currently in nvvertexec.c and s_nvfragprog.c
73 *
74 * - allow for multiple address registers (and fetch address regs properly)
75 *
76 * Cosmetic Stuff
77 * -----------------------------------------------------
78 * - remove any leftover unused grammer.c stuff (dict_ ?)
79 * - fix grammer.c error handling so its not static
80 * - #ifdef around stuff pertaining to extentions
81 *
82 * Outstanding Questions:
83 * -----------------------------------------------------
84 * - ARB_matrix_palette / ARB_vertex_blend -- not supported
85 * what gets hacked off because of this:
86 * + VERTEX_ATTRIB_MATRIXINDEX
87 * + VERTEX_ATTRIB_WEIGHT
88 * + MATRIX_MODELVIEW
89 * + MATRIX_PALETTE
90 *
91 * - When can we fetch env/local params from their own register files, and
92 * when to we have to fetch them into the main state register file?
93 * (think arrays)
94 *
95 * Grammar Changes:
96 * -----------------------------------------------------
97 */
98
99 typedef GLubyte *production;
100
101 /*-----------------------------------------------------------------------
102 * From here on down is the syntax checking portion
103 */
104
105 /* VERSION: 0.4 */
106
107 /*
108 INTRODUCTION
109 ------------
110
111 The task is to check the syntax of an input string. Input string is a
112 stream of ASCII characters terminated with null-character
113 ('\0'). Checking it using C language is difficult and hard to
114 implement without bugs. It is hard to maintain and change prior to
115 further syntax changes.
116
117 This is because of high redundancy of the C code. Large blocks of code
118 are duplicated with only small changes. Even using macros does not
119 solve the problem, because macros cannot erase the complexity of the
120 code.
121
122 The resolution is to create a new language that will be highly
123 oriented to our task. Once we describe particular syntax, we are
124 done. We can then focus on the code that implements the language. The
125 size and complexity of it is relatively small than the code that
126 directly checks the syntax.
127
128 First, we must implement our new language. Here, the language is
129 implemented in C, but it could also be implemented in any other
130 language. The code is listed below. We must take a good care that it
131 is bug free. This is simple because the code is simple and clean.
132
133 Next, we must describe the syntax of our new language in itself. Once
134 created and checked manually that it is correct, we can use it to
135 check another scripts.
136
137 Note that our new language loading code does not have to check the
138 syntax. It is because we assume that the script describing itself is
139 correct, and other scripts can be syntactically checked by the former
140 script. The loading code must only do semantic checking which leads us
141 to simple resolving references.
142
143 THE LANGUAGE
144 ------------
145
146 Here I will describe the syntax of the new language (further called
147 "Synek"). It is mainly a sequence of declarations terminated by a
148 semicolon. The declaration consists of a symbol, which is an
149 identifier, and its definition. A definition is in turn a sequence of
150 specifiers connected with ".and" or ".or" operator. These operators
151 cannot be mixed together in a one definition. Specifier can be a
152 symbol, string, character, character range or a special keyword
153 ".true" or ".false".
154
155 On the very beginning of the script there is a declaration of a root
156 symbol and is in the form:
157 .syntax <root_symbol>;
158
159 The <root_symbol> must be on of the symbols in declaration
160 sequence. The syntax is correct if the root symbol evaluates to
161 true. A symbol evaluates to true if the definition associated with the
162 symbol evaluates to true. Definition evaluation depends on the
163 operator used to connect specifiers in the definition. If ".and"
164 operator is used, definition evaluates to true if and only if all the
165 specifiers evaluate to true. If ".or" operator is used, definition
166 evalutes to true if any of the specifiers evaluates to true. If
167 definition contains only one specifier, it is evaluated as if it was
168 connected with ".true" keyword by ".and" operator.
169
170 If specifier is a ".true" keyword, it always evaluates to true.
171
172 If specifier is a ".false" keyword, it always evaluates to
173 false. Specifier evaluates to false when it does not evaluate to true.
174
175 Character range specifier is in the form:
176 '<first_character>' - '<second_character>'
177
178 If specifier is a character range, it evaluates to true if character
179 in the stream is greater or equal to <first_character> and less or
180 equal to <second_character>. In that situation the stream pointer is
181 advanced to point to next character in the stream. All C-style escape
182 sequences are supported although trigraph sequences are not. The
183 comparisions are performed on 8-bit unsigned integers.
184
185 Character specifier is in the form:
186 '<single_character>'
187
188 It evaluates to true if the following character range specifier evaluates to
189 true:
190 '<single_character>' - '<single_character>'
191
192 String specifier is in the form:
193 "<string>"
194
195 Let N be the number of characters in <string>. Let <string>[i]
196 designate i-th character in <string>. Then the string specifier
197 evaluates to true if and only if for i in the range [0, N) the
198 following character specifier evaluates to true:
199 '<string>[i]'
200
201 If <string>[i] is a quotation mark, '<string>[i]' is replaced with
202 '\<string>[i]'.
203
204 Symbol specifier can be optionally preceded by a ".loop" keyword in the form:
205 .loop <symbol> (1)
206 where <symbol> is defined as follows:
207 <symbol> <definition>; (2)
208 Construction (1) is replaced by the following code:
209 <symbol$1>
210 and declaration (2) is replaced by the following:
211 <symbol$1> <symbol$2> .or .true;
212 <symbol$2> <symbol> .and <symbol$1>;
213 <symbol> <definition>;
214
215
216 ESCAPE SEQUENCES
217 ----------------
218
219 Synek supports all escape sequences in character specifiers. The
220 mapping table is listed below. All occurences of the characters in
221 the first column are replaced with the corresponding character in the
222 second column.
223
224 Escape sequence Represents
225 -----------------------------------------------------------------------
226 \a Bell (alert)
227 \b Backspace
228 \f Formfeed
229 \n New line
230 \r Carriage return
231 \t Horizontal tab
232 \v Vertical tab
233 \' Single quotation mark
234 \" Double quotation mark
235 \\ Backslash
236 \? Literal question mark
237 \ooo ASCII character in octal notation
238 \xhhh ASCII character in hexadecimal notation
239 -----------------------------------------------------------------------
240
241
242 RAISING ERRORS
243 --------------
244
245 Any specifier can be followed by a special construction that is
246 executed when the specifier evaluates to false. The construction is in
247 the form:
248 .error <ERROR_TEXT>
249
250 <ERROR_TEXT> is an identifier declared earlier by error text
251 declaration. The declaration is in the form:
252
253 .errtext <ERROR_TEXT> "<error_desc>"
254
255 When specifier evaluates to false and this construction is present,
256 parsing is stopped immediately and <error_desc> is returned as a
257 result of parsing. The error position is also returned and it is meant
258 as an offset from the beggining of the stream to the character that
259 was valid so far. Example:
260
261 (**** syntax script ****)
262
263 .syntax program;
264 .errtext MISSING_SEMICOLON "missing ';'"
265 program declaration .and .loop space .and ';'
266 .error MISSING_SEMICOLON .and
267 .loop space .and '\0';
268 declaration "declare" .and .loop space .and identifier;
269 space ' ';
270 (**** sample code ****)
271 declare foo ,
272
273 In the example above checking the sample code will result in error
274 message "missing ';'" and error position 12. The sample code is not
275 correct. Note the presence of '\0' specifier to assure that there is
276 no code after semicolon - only spaces. <error_desc> can optionally
277 contain identifier surrounded by dollar signs $. In such a case, the
278 identifier and dollar signs are replaced by a string retrieved by
279 invoking symbol with the identifier name. The starting position is the
280 error position. The lenght of the resulting string is the position
281 after invoking the symbol.
282
283
284 PRODUCTION
285 ----------
286
287 Synek not only checks the syntax but it can also produce (emit) bytes
288 associated with specifiers that evaluate to true. That is, every
289 specifier and optional error construction can be followed by a number
290 of emit constructions that are in the form:
291 .emit <parameter>
292
293 <paramater> can be a HEX number, identifier, a star * or a dollar
294 $. HEX number is preceded by 0x or 0X. If <parameter> is an
295 identifier, it must be earlier declared by emit code declaration in
296 the form:
297 .emtcode <identifier> <hex_number>
298
299 When given specifier evaluates to true, all emits associated with the
300 specifier are output in order they were declared. A star means that
301 last-read character should be output instead of constant
302 value. Example:
303
304 (**** syntax script ****)
305
306 .syntax foobar;
307 .emtcode WORD_FOO 0x01
308 .emtcode WORD_BAR 0x02
309 foobar FOO .emit WORD_FOO .or BAR .emit WORD_BAR .or .true .emit 0x00;
310 FOO "foo" .and SPACE;
311 BAR "bar" .and SPACE;
312 SPACE ' ' .or '\0';
313
314 (**** sample text 1 ****)
315
316 foo
317
318 (**** sample text 2 ****)
319
320 foobar
321
322 For both samples the result will be one-element array. For first
323 sample text it will be value 1, for second - 0. Note that every text
324 will be accepted because of presence of .true as an alternative.
325
326 Another example:
327
328 (**** syntax script ****)
329
330 .syntax declaration;
331 .emtcode VARIABLE 0x01
332 declaration "declare" .and .loop space .and
333 identifier .emit VARIABLE .and (1)
334 .true .emit 0x00 .and (2)
335 .loop space .and ';';
336 space ' ' .or '\t';
337 identifier .loop id_char .emit *; (3)
338 id_char 'a'-'z' .or 'A'-'Z' .or '_';
339 (**** sample code ****)
340 declare fubar;
341
342 In specifier (1) symbol <identifier> is followed by .emit VARIABLE. If
343 it evaluates to true, VARIABLE constant and then production of the
344 symbol is output. Specifier (2) is used to terminate the string with
345 null to signal when the string ends. Specifier (3) outputs all
346 characters that make declared identifier. The result of sample code
347 will be the following array:
348 { 1, 'f', 'u', 'b', 'a', 'r', 0 }
349
350 If .emit is followed by dollar $, it means that current position
351 should be output. Current position is a 32-bit unsigned integer
352 distance from the very beginning of the parsed string to first
353 character consumed by the specifier associated with the .emit
354 instruction. Current position is stored in the output buffer in
355 Little-Endian convention (the lowest byte comes first). */
356
357
358 /**
359 * This is the text describing the rules to parse the grammar
360 */
361 #include "arbparse_syn.h"
362
363 /**
364 * These should match up with the values defined in arbparse.syn.h
365 */
366
367 #define REVISION 0x04
368
369 /* program type */
370 #define FRAGMENT_PROGRAM 0x01
371 #define VERTEX_PROGRAM 0x02
372
373 /* program section */
374 #define OPTION 0x01
375 #define INSTRUCTION 0x02
376 #define DECLARATION 0x03
377 #define END 0x04
378
379 /* fragment program option flags */
380 #define ARB_PRECISION_HINT_FASTEST 0x01
381 #define ARB_PRECISION_HINT_NICEST 0x02
382 #define ARB_FOG_EXP 0x04
383 #define ARB_FOG_EXP2 0x08
384 #define ARB_FOG_LINEAR 0x10
385
386 /* vertex program option flags */
387 /*
388 $4: changed from 0x01 to 0x20.
389 */
390 #define ARB_POSITION_INVARIANT 0x20
391
392 /* fragment program instruction class */
393 #define F_ALU_INST 0x01
394 #define F_TEX_INST 0x02
395
396 /* fragment program instruction type */
397 #define F_ALU_VECTOR 0x01
398 #define F_ALU_SCALAR 0x02
399 #define F_ALU_BINSC 0x03
400 #define F_ALU_BIN 0x04
401 #define F_ALU_TRI 0x05
402 #define F_ALU_SWZ 0x06
403 #define F_TEX_SAMPLE 0x07
404 #define F_TEX_KIL 0x08
405
406 /* vertex program instruction type */
407 #define V_GEN_ARL 0x01
408 #define V_GEN_VECTOR 0x02
409 #define V_GEN_SCALAR 0x03
410 #define V_GEN_BINSC 0x04
411 #define V_GEN_BIN 0x05
412 #define V_GEN_TRI 0x06
413 #define V_GEN_SWZ 0x07
414
415 /* fragment program instruction code */
416 #define F_ABS 0x00
417 #define F_ABS_SAT 0x01
418 #define F_FLR 0x02
419 #define F_FLR_SAT 0x03
420 #define F_FRC 0x04
421 #define F_FRC_SAT 0x05
422 #define F_LIT 0x06
423 #define F_LIT_SAT 0x07
424 #define F_MOV 0x08
425 #define F_MOV_SAT 0x09
426 #define F_COS 0x0A
427 #define F_COS_SAT 0x0B
428 #define F_EX2 0x0C
429 #define F_EX2_SAT 0x0D
430 #define F_LG2 0x0E
431 #define F_LG2_SAT 0x0F
432 #define F_RCP 0x10
433 #define F_RCP_SAT 0x11
434 #define F_RSQ 0x12
435 #define F_RSQ_SAT 0x13
436 #define F_SIN 0x14
437 #define F_SIN_SAT 0x15
438 #define F_SCS 0x16
439 #define F_SCS_SAT 0x17
440 #define F_POW 0x18
441 #define F_POW_SAT 0x19
442 #define F_ADD 0x1A
443 #define F_ADD_SAT 0x1B
444 #define F_DP3 0x1C
445 #define F_DP3_SAT 0x1D
446 #define F_DP4 0x1E
447 #define F_DP4_SAT 0x1F
448 #define F_DPH 0x20
449 #define F_DPH_SAT 0x21
450 #define F_DST 0x22
451 #define F_DST_SAT 0x23
452 #define F_MAX 0x24
453 #define F_MAX_SAT 0x25
454 #define F_MIN 0x26
455 #define F_MIN_SAT 0x27
456 #define F_MUL 0x28
457 #define F_MUL_SAT 0x29
458 #define F_SGE 0x2A
459 #define F_SGE_SAT 0x2B
460 #define F_SLT 0x2C
461 #define F_SLT_SAT 0x2D
462 #define F_SUB 0x2E
463 #define F_SUB_SAT 0x2F
464 #define F_XPD 0x30
465 #define F_XPD_SAT 0x31
466 #define F_CMP 0x32
467 #define F_CMP_SAT 0x33
468 #define F_LRP 0x34
469 #define F_LRP_SAT 0x35
470 #define F_MAD 0x36
471 #define F_MAD_SAT 0x37
472 #define F_SWZ 0x38
473 #define F_SWZ_SAT 0x39
474 #define F_TEX 0x3A
475 #define F_TEX_SAT 0x3B
476 #define F_TXB 0x3C
477 #define F_TXB_SAT 0x3D
478 #define F_TXP 0x3E
479 #define F_TXP_SAT 0x3F
480 #define F_KIL 0x40
481
482 /* vertex program instruction code */
483 #define V_ARL 0x01
484 #define V_ABS 0x02
485 #define V_FLR 0x03
486 #define V_FRC 0x04
487 #define V_LIT 0x05
488 #define V_MOV 0x06
489 #define V_EX2 0x07
490 #define V_EXP 0x08
491 #define V_LG2 0x09
492 #define V_LOG 0x0A
493 #define V_RCP 0x0B
494 #define V_RSQ 0x0C
495 #define V_POW 0x0D
496 #define V_ADD 0x0E
497 #define V_DP3 0x0F
498 #define V_DP4 0x10
499 #define V_DPH 0x11
500 #define V_DST 0x12
501 #define V_MAX 0x13
502 #define V_MIN 0x14
503 #define V_MUL 0x15
504 #define V_SGE 0x16
505 #define V_SLT 0x17
506 #define V_SUB 0x18
507 #define V_XPD 0x19
508 #define V_MAD 0x1A
509 #define V_SWZ 0x1B
510
511 /* fragment attribute binding */
512 #define FRAGMENT_ATTRIB_COLOR 0x01
513 #define FRAGMENT_ATTRIB_TEXCOORD 0x02
514 #define FRAGMENT_ATTRIB_FOGCOORD 0x03
515 #define FRAGMENT_ATTRIB_POSITION 0x04
516
517 /* vertex attribute binding */
518 #define VERTEX_ATTRIB_POSITION 0x01
519 #define VERTEX_ATTRIB_WEIGHT 0x02
520 #define VERTEX_ATTRIB_NORMAL 0x03
521 #define VERTEX_ATTRIB_COLOR 0x04
522 #define VERTEX_ATTRIB_FOGCOORD 0x05
523 #define VERTEX_ATTRIB_TEXCOORD 0x06
524 #define VERTEX_ATTRIB_MATRIXINDEX 0x07
525 #define VERTEX_ATTRIB_GENERIC 0x08
526
527 /* fragment result binding */
528 #define FRAGMENT_RESULT_COLOR 0x01
529 #define FRAGMENT_RESULT_DEPTH 0x02
530
531 /* vertex result binding */
532 #define VERTEX_RESULT_POSITION 0x01
533 #define VERTEX_RESULT_COLOR 0x02
534 #define VERTEX_RESULT_FOGCOORD 0x03
535 #define VERTEX_RESULT_POINTSIZE 0x04
536 #define VERTEX_RESULT_TEXCOORD 0x05
537
538 /* texture target */
539 #define TEXTARGET_1D 0x01
540 #define TEXTARGET_2D 0x02
541 #define TEXTARGET_3D 0x03
542 #define TEXTARGET_RECT 0x04
543 #define TEXTARGET_CUBE 0x05
544
545 /* sign */
546 /*
547 $3: removed. '+' and '-' are used instead.
548 */
549 /*
550 #define SIGN_PLUS 0x00
551 #define SIGN_MINUS 0x01
552 */
553
554 /* face type */
555 #define FACE_FRONT 0x00
556 #define FACE_BACK 0x01
557
558 /* color type */
559 #define COLOR_PRIMARY 0x00
560 #define COLOR_SECONDARY 0x01
561
562 /* component */
563 /*
564 $3: Added enumerants.
565 */
566 #define COMPONENT_X 0x00
567 #define COMPONENT_Y 0x01
568 #define COMPONENT_Z 0x02
569 #define COMPONENT_W 0x03
570 #define COMPONENT_0 0x04
571 #define COMPONENT_1 0x05
572
573 #define ARRAY_INDEX_ABSOLUTE 0x00
574 #define ARRAY_INDEX_RELATIVE 0x01
575
576 /* matrix name */
577 #define MATRIX_MODELVIEW 0x01
578 #define MATRIX_PROJECTION 0x02
579 #define MATRIX_MVP 0x03
580 #define MATRIX_TEXTURE 0x04
581 #define MATRIX_PALETTE 0x05
582 #define MATRIX_PROGRAM 0x06
583
584 /* matrix modifier */
585 #define MATRIX_MODIFIER_IDENTITY 0x00
586 #define MATRIX_MODIFIER_INVERSE 0x01
587 #define MATRIX_MODIFIER_TRANSPOSE 0x02
588 #define MATRIX_MODIFIER_INVTRANS 0x03
589
590 /* constant type */
591 #define CONSTANT_SCALAR 0x01
592 #define CONSTANT_VECTOR 0x02
593
594 /* program param type */
595 #define PROGRAM_PARAM_ENV 0x01
596 #define PROGRAM_PARAM_LOCAL 0x02
597
598 /* register type */
599 #define REGISTER_ATTRIB 0x01
600 #define REGISTER_PARAM 0x02
601 #define REGISTER_RESULT 0x03
602 #define REGISTER_ESTABLISHED_NAME 0x04
603
604 /* param binding */
605 #define PARAM_NULL 0x00
606 #define PARAM_ARRAY_ELEMENT 0x01
607 #define PARAM_STATE_ELEMENT 0x02
608 #define PARAM_PROGRAM_ELEMENT 0x03
609 #define PARAM_PROGRAM_ELEMENTS 0x04
610 #define PARAM_CONSTANT 0x05
611
612 /* param state property */
613 #define STATE_MATERIAL_PARSER 0x01
614 #define STATE_LIGHT_PARSER 0x02
615 #define STATE_LIGHT_MODEL 0x03
616 #define STATE_LIGHT_PROD 0x04
617 #define STATE_FOG 0x05
618 #define STATE_MATRIX_ROWS 0x06
619 /* fragment program only */
620 #define STATE_TEX_ENV 0x07
621 #define STATE_DEPTH 0x08
622 /* vertex program only */
623 /*
624 $4: incremented all the three emit codes by two to not collide with other STATE_* emit codes.
625 */
626 #define STATE_TEX_GEN 0x09
627 #define STATE_CLIP_PLANE 0x0A
628 #define STATE_POINT 0x0B
629
630 /* state material property */
631 #define MATERIAL_AMBIENT 0x01
632 #define MATERIAL_DIFFUSE 0x02
633 #define MATERIAL_SPECULAR 0x03
634 #define MATERIAL_EMISSION 0x04
635 #define MATERIAL_SHININESS 0x05
636
637 /* state light property */
638 #define LIGHT_AMBIENT 0x01
639 #define LIGHT_DIFFUSE 0x02
640 #define LIGHT_SPECULAR 0x03
641 #define LIGHT_POSITION 0x04
642 #define LIGHT_ATTENUATION 0x05
643 #define LIGHT_HALF 0x06
644 #define LIGHT_SPOT_DIRECTION 0x07
645
646 /* state light model property */
647 #define LIGHT_MODEL_AMBIENT 0x01
648 #define LIGHT_MODEL_SCENECOLOR 0x02
649
650 /* state light product property */
651 #define LIGHT_PROD_AMBIENT 0x01
652 #define LIGHT_PROD_DIFFUSE 0x02
653 #define LIGHT_PROD_SPECULAR 0x03
654
655 /* state texture environment property */
656 #define TEX_ENV_COLOR 0x01
657
658 /* state texture generation coord property */
659 #define TEX_GEN_EYE 0x01
660 #define TEX_GEN_OBJECT 0x02
661
662 /* state fog property */
663 #define FOG_COLOR 0x01
664 #define FOG_PARAMS 0x02
665
666 /* state depth property */
667 #define DEPTH_RANGE 0x01
668
669 /* state point parameters property */
670 #define POINT_SIZE 0x01
671 #define POINT_ATTENUATION 0x02
672
673 /* declaration */
674 #define ATTRIB 0x01
675 #define PARAM 0x02
676 #define TEMP 0x03
677 #define OUTPUT 0x04
678 #define ALIAS 0x05
679 /* vertex program 1.0 only */
680 #define ADDRESS 0x06
681
682 /*
683 memory management routines
684 */
685 static GLvoid *mem_alloc (GLsizei);
686 static GLvoid mem_free (GLvoid **);
687 static GLvoid *mem_realloc (GLvoid *, GLsizei, GLsizei);
688 static GLubyte *str_duplicate (const GLubyte *);
689
690 /*
691 internal error messages
692 */
693 static const GLubyte *OUT_OF_MEMORY =
694 (GLubyte *) "internal error 1001: out of physical memory";
695 static const GLubyte *UNRESOLVED_REFERENCE =
696 (GLubyte *) "internal error 1002: unresolved reference '$'";
697 /*
698 static const GLubyte *INVALID_PARAMETER =
699 (GLubyte *) "internal error 1003: invalid parameter";
700 */
701
702 static const GLubyte *error_message = NULL;
703 static GLubyte *error_param = NULL; /* this is inserted into error_message in place of $ */
704 static GLint error_position = -1;
705
706 static GLubyte *unknown = (GLubyte *) "???";
707
708 static GLvoid
709 clear_last_error ()
710 {
711 /* reset error message */
712 error_message = NULL;
713
714 /* free error parameter - if error_param is a "???" don't free it - it's static */
715 if (error_param != unknown)
716 mem_free ((GLvoid **) & error_param);
717 else
718 error_param = NULL;
719
720 /* reset error position */
721 error_position = -1;
722 }
723
724 static GLvoid
725 set_last_error (const GLubyte * msg, GLubyte * param, GLint pos)
726 {
727 if (error_message != NULL)
728 return;
729
730 error_message = msg;
731 if (param != NULL)
732 error_param = param;
733 else
734 error_param = unknown;
735
736 error_position = pos;
737 }
738
739 /*
740 * memory management routines
741 */
742 static GLvoid *
743 mem_alloc (GLsizei size)
744 {
745 GLvoid *ptr = _mesa_malloc (size);
746 if (ptr == NULL)
747 set_last_error (OUT_OF_MEMORY, NULL, -1);
748 return ptr;
749 }
750
751 static GLvoid
752 mem_free (GLvoid ** ptr)
753 {
754 _mesa_free (*ptr);
755 *ptr = NULL;
756 }
757
758 static GLvoid *
759 mem_realloc (GLvoid * ptr, GLsizei old_size, GLsizei new_size)
760 {
761 GLvoid *ptr2 = _mesa_realloc (ptr, old_size, new_size);
762 if (ptr2 == NULL)
763 set_last_error (OUT_OF_MEMORY, NULL, -1);
764 return ptr2;
765 }
766
767 static GLubyte *
768 str_duplicate (const GLubyte * str)
769 {
770 return (GLubyte *) _mesa_strdup ((const char *) str);
771 }
772
773 /*
774 * emit type typedef
775 */
776 typedef enum emit_type_
777 {
778 et_byte, /* explicit number */
779 et_stream, /* eaten character */
780 et_position /* current position */
781 }
782 emit_type;
783
784 /*
785 * emit typedef
786 */
787 typedef struct emit_
788 {
789 emit_type m_emit_type;
790 GLubyte m_byte; /* et_byte */
791 struct emit_ *m_next;
792 }
793 emit;
794
795 static GLvoid
796 emit_create (emit ** em)
797 {
798 *em = (emit *) mem_alloc (sizeof (emit));
799 if (*em) {
800 (**em).m_emit_type = et_byte;
801 (**em).m_byte = 0;
802 (**em).m_next = NULL;
803 }
804 }
805
806 static GLvoid
807 emit_destroy (emit ** em)
808 {
809 if (*em) {
810 emit_destroy (&(**em).m_next);
811 mem_free ((GLvoid **) em);
812 }
813 }
814
815 static GLvoid
816 emit_append (emit ** em, emit ** ne)
817 {
818 if (*em)
819 emit_append (&(**em).m_next, ne);
820 else
821 *em = *ne;
822 }
823
824 /*
825 * error typedef
826 */
827 typedef struct error_
828 {
829 GLubyte *m_text;
830 GLubyte *m_token_name;
831 struct defntn_ *m_token;
832 }
833 error;
834
835 static GLvoid
836 error_create (error ** er)
837 {
838 *er = (error *) mem_alloc (sizeof (error));
839 if (*er) {
840 (**er).m_text = NULL;
841 (**er).m_token_name = NULL;
842 (**er).m_token = NULL;
843 }
844 }
845
846 static GLvoid
847 error_destroy (error ** er)
848 {
849 if (*er) {
850 mem_free ((GLvoid **) & (**er).m_text);
851 mem_free ((GLvoid **) & (**er).m_token_name);
852 mem_free ((GLvoid **) er);
853 }
854 }
855
856 struct dict_;
857 static GLubyte *error_get_token (error *, struct dict_ *, const GLubyte *, GLuint);
858
859 /*
860 * specifier type typedef
861 */
862 typedef enum spec_type_
863 {
864 st_false,
865 st_true,
866 st_byte,
867 st_byte_range,
868 st_string,
869 st_identifier,
870 st_identifier_loop,
871 st_debug
872 } spec_type;
873
874
875 /*
876 * specifier typedef
877 */
878 typedef struct spec_
879 {
880 spec_type m_spec_type;
881 GLubyte m_byte[2]; /* st_byte, st_byte_range */
882 GLubyte *m_string; /* st_string */
883 struct defntn_ *m_defntn; /* st_identifier, st_identifier_loop */
884 emit *m_emits;
885 error *m_errtext;
886 struct spec_ *m_next;
887 } spec;
888
889
890 static GLvoid
891 spec_create (spec ** sp)
892 {
893 *sp = (spec *) mem_alloc (sizeof (spec));
894 if (*sp) {
895 (**sp).m_spec_type = st_false;
896 (**sp).m_byte[0] = '\0';
897 (**sp).m_byte[1] = '\0';
898 (**sp).m_string = NULL;
899 (**sp).m_defntn = NULL;
900 (**sp).m_emits = NULL;
901 (**sp).m_errtext = NULL;
902 (**sp).m_next = NULL;
903 }
904 }
905
906 static GLvoid
907 spec_destroy (spec ** sp)
908 {
909 if (*sp) {
910 spec_destroy (&(**sp).m_next);
911 emit_destroy (&(**sp).m_emits);
912 error_destroy (&(**sp).m_errtext);
913 mem_free ((GLvoid **) & (**sp).m_string);
914 mem_free ((GLvoid **) sp);
915 }
916 }
917
918 static GLvoid
919 spec_append (spec ** sp, spec ** ns)
920 {
921 if (*sp)
922 spec_append (&(**sp).m_next, ns);
923 else
924 *sp = *ns;
925 }
926
927 /*
928 * operator typedef
929 */
930 typedef enum oper_
931 {
932 op_none,
933 op_and,
934 op_or
935 } oper;
936
937
938 /*
939 * definition typedef
940 */
941 typedef struct defntn_
942 {
943 oper m_oper;
944 spec *m_specs;
945 struct defntn_ *m_next;
946 #ifndef NDEBUG
947 GLint m_referenced;
948 #endif
949 } defntn;
950
951
952 static GLvoid
953 defntn_create (defntn ** de)
954 {
955 *de = (defntn *) mem_alloc (sizeof (defntn));
956 if (*de) {
957 (**de).m_oper = op_none;
958 (**de).m_specs = NULL;
959 (**de).m_next = NULL;
960 #ifndef NDEBUG
961 (**de).m_referenced = 0;
962 #endif
963 }
964 }
965
966 static GLvoid
967 defntn_destroy (defntn ** de)
968 {
969 if (*de) {
970 defntn_destroy (&(**de).m_next);
971 spec_destroy (&(**de).m_specs);
972 mem_free ((GLvoid **) de);
973 }
974 }
975
976 static GLvoid
977 defntn_append (defntn ** de, defntn ** nd)
978 {
979 if (*de)
980 defntn_append (&(**de).m_next, nd);
981 else
982 *de = *nd;
983 }
984
985 /*
986 * dictionary typedef
987 */
988 typedef struct dict_
989 {
990 defntn *m_defntns;
991 defntn *m_syntax;
992 defntn *m_string;
993 struct dict_ *m_next;
994 } dict;
995
996
997 static GLvoid
998 dict_create (dict ** di)
999 {
1000 *di = (dict *) mem_alloc (sizeof (dict));
1001 if (*di) {
1002 (**di).m_defntns = NULL;
1003 (**di).m_syntax = NULL;
1004 (**di).m_string = NULL;
1005 (**di).m_next = NULL;
1006 }
1007 }
1008
1009 static GLvoid
1010 dict_destroy (dict ** di)
1011 {
1012 if (*di) {
1013 dict_destroy (&(**di).m_next);
1014 defntn_destroy (&(**di).m_defntns);
1015 mem_free ((GLvoid **) di);
1016 }
1017 }
1018
1019 /*
1020 * GLubyte array typedef
1021 */
1022 typedef struct barray_
1023 {
1024 GLubyte *data;
1025 GLuint len;
1026 } barray;
1027
1028
1029 static GLvoid
1030 barray_create (barray ** ba)
1031 {
1032 *ba = (barray *) mem_alloc (sizeof (barray));
1033 if (*ba) {
1034 (**ba).data = NULL;
1035 (**ba).len = 0;
1036 }
1037 }
1038
1039 static GLvoid
1040 barray_destroy (barray ** ba)
1041 {
1042 if (*ba) {
1043 mem_free ((GLvoid **) & (**ba).data);
1044 mem_free ((GLvoid **) ba);
1045 }
1046 }
1047
1048 /*
1049 * reallocates GLubyte array to requested size,
1050 * returns 0 on success,
1051 * returns 1 otherwise
1052 */
1053 static GLint
1054 barray_resize (barray ** ba, GLuint nlen)
1055 {
1056 GLubyte *new_pointer;
1057
1058 if (nlen == 0) {
1059 mem_free ((void **) &(**ba).data);
1060 (**ba).data = NULL;
1061 (**ba).len = 0;
1062
1063 return 0;
1064 }
1065 else {
1066 new_pointer = (GLubyte *)
1067 mem_realloc ((**ba).data, (**ba).len * sizeof (GLubyte),
1068 nlen * sizeof (GLubyte));
1069 if (new_pointer) {
1070 (**ba).data = new_pointer;
1071 (**ba).len = nlen;
1072
1073 return 0;
1074 }
1075 }
1076
1077 return 1;
1078 }
1079
1080 /*
1081 * adds GLubyte array pointed by *nb to the end of array pointed by *ba,
1082 * returns 0 on success,
1083 * returns 1 otherwise
1084 */
1085 static GLint
1086 barray_append (barray ** ba, barray ** nb)
1087 {
1088 GLuint i;
1089 const GLuint len = (**ba).len;
1090
1091 if (barray_resize (ba, (**ba).len + (**nb).len))
1092 return 1;
1093
1094 for (i = 0; i < (**nb).len; i++)
1095 (**ba).data[len + i] = (**nb).data[i];
1096
1097 return 0;
1098 }
1099
1100
1101 /**
1102 * Adds emit chain pointed by em to the end of array pointed by *ba.
1103 * \return 0 on success, 1 otherwise.
1104 */
1105 static GLint
1106 barray_push (barray ** ba, emit * em, GLubyte c, GLuint pos)
1107 {
1108 emit *temp = em;
1109 GLuint count = 0;
1110
1111 while (temp) {
1112 if (temp->m_emit_type == et_position)
1113 count += 4; /* position is a 32-bit unsigned integer */
1114 else
1115 count++;
1116
1117 temp = temp->m_next;
1118 }
1119
1120 if (barray_resize (ba, (**ba).len + count))
1121 return 1;
1122
1123 while (em) {
1124 if (em->m_emit_type == et_byte)
1125 (**ba).data[(**ba).len - count--] = em->m_byte;
1126 else if (em->m_emit_type == et_stream)
1127 (**ba).data[(**ba).len - count--] = c;
1128
1129 /* This is where the position is emitted into the stream */
1130 else { /* em->type == et_position */
1131 #if 0
1132 (**ba).data[(**ba).len - count--] = (GLubyte) pos,
1133 (**ba).data[(**ba).len - count--] = (GLubyte) (pos >> 8),
1134 (**ba).data[(**ba).len - count--] = (GLubyte) (pos >> 16),
1135 (**ba).data[(**ba).len - count--] = (GLubyte) (pos >> 24);
1136 #else
1137 (**ba).data[(**ba).len - count--] = (GLubyte) pos;
1138 (**ba).data[(**ba).len - count--] = (GLubyte) (pos / 0x100);
1139 (**ba).data[(**ba).len - count--] = (GLubyte) (pos / 0x10000);
1140 (**ba).data[(**ba).len - count--] = (GLubyte) (pos / 0x1000000);
1141 #endif
1142 }
1143
1144 em = em->m_next;
1145 }
1146
1147 return 0;
1148 }
1149
1150 /**
1151 * string to string map typedef
1152 */
1153 typedef struct map_str_
1154 {
1155 GLubyte *key;
1156 GLubyte *data;
1157 struct map_str_ *next;
1158 } map_str;
1159
1160
1161 static GLvoid
1162 map_str_create (map_str ** ma)
1163 {
1164 *ma = (map_str *) mem_alloc (sizeof (map_str));
1165 if (*ma) {
1166 (**ma).key = NULL;
1167 (**ma).data = NULL;
1168 (**ma).next = NULL;
1169 }
1170 }
1171
1172 static GLvoid
1173 map_str_destroy (map_str ** ma)
1174 {
1175 if (*ma) {
1176 map_str_destroy (&(**ma).next);
1177 mem_free ((GLvoid **) & (**ma).key);
1178 mem_free ((GLvoid **) & (**ma).data);
1179 mem_free ((GLvoid **) ma);
1180 }
1181 }
1182
1183 static GLvoid
1184 map_str_append (map_str ** ma, map_str ** nm)
1185 {
1186 if (*ma)
1187 map_str_append (&(**ma).next, nm);
1188 else
1189 *ma = *nm;
1190 }
1191
1192 /**
1193 * searches the map for specified key,
1194 * if the key is matched, *data is filled with data associated with the key,
1195 * \return 0 if the key is matched, 1 otherwise
1196 */
1197 static GLint
1198 map_str_find (map_str ** ma, const GLubyte * key, GLubyte ** data)
1199 {
1200 while (*ma) {
1201 if (strcmp ((const char *) (**ma).key, (const char *) key) == 0) {
1202 *data = str_duplicate ((**ma).data);
1203 if (*data == NULL)
1204 return 1;
1205
1206 return 0;
1207 }
1208
1209 ma = &(**ma).next;
1210 }
1211
1212 set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
1213 return 1;
1214 }
1215
1216 /**
1217 * string to GLubyte map typedef
1218 */
1219 typedef struct map_byte_
1220 {
1221 GLubyte *key;
1222 GLubyte data;
1223 struct map_byte_ *next;
1224 } map_byte;
1225
1226 static GLvoid
1227 map_byte_create (map_byte ** ma)
1228 {
1229 *ma = (map_byte *) mem_alloc (sizeof (map_byte));
1230 if (*ma) {
1231 (**ma).key = NULL;
1232 (**ma).data = 0;
1233 (**ma).next = NULL;
1234 }
1235 }
1236
1237 static GLvoid
1238 map_byte_destroy (map_byte ** ma)
1239 {
1240 if (*ma) {
1241 map_byte_destroy (&(**ma).next);
1242 mem_free ((GLvoid **) & (**ma).key);
1243 mem_free ((GLvoid **) ma);
1244 }
1245 }
1246
1247 static GLvoid
1248 map_byte_append (map_byte ** ma, map_byte ** nm)
1249 {
1250 if (*ma)
1251 map_byte_append (&(**ma).next, nm);
1252 else
1253 *ma = *nm;
1254 }
1255
1256 /**
1257 * Searches the map for specified key,
1258 * If the key is matched, *data is filled with data associated with the key,
1259 * \return 0 if the is matched, 1 otherwise
1260 */
1261 static GLint
1262 map_byte_find (map_byte ** ma, const GLubyte * key, GLubyte * data)
1263 {
1264 while (*ma) {
1265 if (strcmp ((const char *) (**ma).key, (const char *) key) == 0) {
1266 *data = (**ma).data;
1267 return 0;
1268 }
1269
1270 ma = &(**ma).next;
1271 }
1272
1273 set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
1274 return 1;
1275 }
1276
1277 /*
1278 * string to defntn map typedef
1279 */
1280 typedef struct map_def_
1281 {
1282 GLubyte *key;
1283 defntn *data;
1284 struct map_def_ *next;
1285 } map_def;
1286
1287 static GLvoid
1288 map_def_create (map_def ** ma)
1289 {
1290 *ma = (map_def *) mem_alloc (sizeof (map_def));
1291 if (*ma) {
1292 (**ma).key = NULL;
1293 (**ma).data = NULL;
1294 (**ma).next = NULL;
1295 }
1296 }
1297
1298 static GLvoid
1299 map_def_destroy (map_def ** ma)
1300 {
1301 if (*ma) {
1302 map_def_destroy (&(**ma).next);
1303 mem_free ((GLvoid **) & (**ma).key);
1304 mem_free ((GLvoid **) ma);
1305 }
1306 }
1307
1308 static GLvoid
1309 map_def_append (map_def ** ma, map_def ** nm)
1310 {
1311 if (*ma)
1312 map_def_append (&(**ma).next, nm);
1313 else
1314 *ma = *nm;
1315 }
1316
1317 /**
1318 * searches the map for specified key,
1319 * if the key is matched, *data is filled with data associated with the key,
1320 * \return 0 if the is matched, 1 otherwise
1321 */
1322 static GLint
1323 map_def_find (map_def ** ma, const GLubyte * key, defntn ** data)
1324 {
1325 while (*ma) {
1326 if (_mesa_strcmp ((const char *) (**ma).key, (const char *) key) == 0) {
1327 *data = (**ma).data;
1328
1329 return 0;
1330 }
1331
1332 ma = &(**ma).next;
1333 }
1334
1335 set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
1336 return 1;
1337 }
1338
1339 /*
1340 * returns 1 if given character is a space,
1341 * returns 0 otherwise
1342 */
1343 static GLint
1344 is_space (GLubyte c)
1345 {
1346 return c == ' ' || c == '\t' || c == '\n' || c == '\r';
1347 }
1348
1349 /*
1350 * advances text pointer by 1 if character pointed by *text is a space,
1351 * returns 1 if a space has been eaten,
1352 * returns 0 otherwise
1353 */
1354 static GLint
1355 eat_space (const GLubyte ** text)
1356 {
1357 if (is_space (**text)) {
1358 (*text)++;
1359
1360 return 1;
1361 }
1362
1363 return 0;
1364 }
1365
1366 /*
1367 * returns 1 if text points to C-style comment start string "/ *",
1368 * returns 0 otherwise
1369 */
1370 static GLint
1371 is_comment_start (const GLubyte * text)
1372 {
1373 return text[0] == '/' && text[1] == '*';
1374 }
1375
1376 /*
1377 * advances text pointer to first character after C-style comment block - if any,
1378 * returns 1 if C-style comment block has been encountered and eaten,
1379 * returns 0 otherwise
1380 */
1381 static GLint
1382 eat_comment (const GLubyte ** text)
1383 {
1384 if (is_comment_start (*text)) {
1385 /* *text points to comment block - skip two characters to enter comment body */
1386 *text += 2;
1387 /* skip any character except consecutive '*' and '/' */
1388 while (!((*text)[0] == '*' && (*text)[1] == '/'))
1389 (*text)++;
1390 /* skip those two terminating characters */
1391 *text += 2;
1392
1393 return 1;
1394 }
1395
1396 return 0;
1397 }
1398
1399 /*
1400 * advances text pointer to first character that is neither space nor C-style comment block
1401 */
1402 static GLvoid
1403 eat_spaces (const GLubyte ** text)
1404 {
1405 while (eat_space (text) || eat_comment (text));
1406 }
1407
1408 /*
1409 * resizes string pointed by *ptr to successfully add character c to the end of the string,
1410 * returns 0 on success,
1411 * returns 1 otherwise
1412 */
1413 static GLint
1414 string_grow (GLubyte ** ptr, GLuint * len, GLubyte c)
1415 {
1416 /* reallocate the string in 16-length increments */
1417 if ((*len & 0x0F) == 0x0F || *ptr == NULL) {
1418 GLubyte *tmp = (GLubyte *) mem_realloc (*ptr, (*len) * sizeof (GLubyte),
1419 ((*len + 1 + 1 +
1420 0x0F) & ~0x0F) * sizeof (GLubyte));
1421 if (tmp == NULL)
1422 return 1;
1423
1424 *ptr = tmp;
1425 }
1426
1427 if (c) {
1428 /* append given character */
1429 (*ptr)[*len] = c;
1430 (*len)++;
1431 }
1432 (*ptr)[*len] = '\0';
1433
1434 return 0;
1435 }
1436
1437 /*
1438 * returns 1 if given character is valid identifier character a-z, A-Z, 0-9 or _
1439 * returns 0 otherwise
1440 */
1441 static GLint
1442 is_identifier (GLubyte c)
1443 {
1444 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
1445 (c >= '0' && c <= '9') || c == '_';
1446 }
1447
1448 /*
1449 * copies characters from *text to *id until non-identifier character is encountered,
1450 * assumes that *id points to NULL object - caller is responsible for later freeing the string,
1451 * text pointer is advanced to point past the copied identifier,
1452 * returns 0 if identifier was successfully copied,
1453 * returns 1 otherwise
1454 */
1455 static GLint
1456 get_identifier (const GLubyte ** text, GLubyte ** id)
1457 {
1458 const GLubyte *t = *text;
1459 GLubyte *p = NULL;
1460 GLuint len = 0;
1461
1462 if (string_grow (&p, &len, '\0'))
1463 return 1;
1464
1465 /* loop while next character in buffer is valid for identifiers */
1466 while (is_identifier (*t)) {
1467 if (string_grow (&p, &len, *t++)) {
1468 mem_free ((GLvoid **) & p);
1469 return 1;
1470 }
1471 }
1472
1473 *text = t;
1474 *id = p;
1475
1476 return 0;
1477 }
1478
1479 /*
1480 * returns 1 if given character is HEX digit 0-9, A-F or a-f,
1481 * returns 0 otherwise
1482 */
1483 static GLint
1484 is_hex (GLubyte c)
1485 {
1486 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a'
1487 && c <= 'f');
1488 }
1489
1490 /*
1491 * returns value of passed character as if it was HEX digit
1492 */
1493 static GLuint
1494 hex2dec (GLubyte c)
1495 {
1496 if (c >= '0' && c <= '9')
1497 return c - '0';
1498 if (c >= 'A' && c <= 'F')
1499 return c - 'A' + 10;
1500 return c - 'a' + 10;
1501 }
1502
1503 /*
1504 * converts sequence of HEX digits pointed by *text until non-HEX digit is encountered,
1505 * advances text pointer past the converted sequence,
1506 * returns the converted value
1507 */
1508 static GLuint
1509 hex_convert (const GLubyte ** text)
1510 {
1511 GLuint value = 0;
1512
1513 while (is_hex (**text)) {
1514 value = value * 0x10 + hex2dec (**text);
1515 (*text)++;
1516 }
1517
1518 return value;
1519 }
1520
1521 /*
1522 * returns 1 if given character is OCT digit 0-7,
1523 * returns 0 otherwise
1524 */
1525 static GLint
1526 is_oct (GLubyte c)
1527 {
1528 return c >= '0' && c <= '7';
1529 }
1530
1531 /*
1532 * returns value of passed character as if it was OCT digit
1533 */
1534 static GLint
1535 oct2dec (GLubyte c)
1536 {
1537 return c - '0';
1538 }
1539
1540 static GLubyte
1541 get_escape_sequence (const GLubyte ** text)
1542 {
1543 GLint value = 0;
1544
1545 /* skip '\' character */
1546 (*text)++;
1547
1548 switch (*(*text)++) {
1549 case '\'':
1550 return '\'';
1551 case '"':
1552 return '\"';
1553 case '?':
1554 return '\?';
1555 case '\\':
1556 return '\\';
1557 case 'a':
1558 return '\a';
1559 case 'b':
1560 return '\b';
1561 case 'f':
1562 return '\f';
1563 case 'n':
1564 return '\n';
1565 case 'r':
1566 return '\r';
1567 case 't':
1568 return '\t';
1569 case 'v':
1570 return '\v';
1571 case 'x':
1572 return (GLubyte) hex_convert (text);
1573 }
1574
1575 (*text)--;
1576 if (is_oct (**text)) {
1577 value = oct2dec (*(*text)++);
1578 if (is_oct (**text)) {
1579 value = value * 010 + oct2dec (*(*text)++);
1580 if (is_oct (**text))
1581 value = value * 010 + oct2dec (*(*text)++);
1582 }
1583 }
1584
1585 return (GLubyte) value;
1586 }
1587
1588 /*
1589 * copies characters from *text to *str until " or ' character is encountered,
1590 * assumes that *str points to NULL object - caller is responsible for later freeing the string,
1591 * assumes that *text points to " or ' character that starts the string,
1592 * text pointer is advanced to point past the " or ' character,
1593 * returns 0 if string was successfully copied,
1594 * returns 1 otherwise
1595 */
1596 static GLint
1597 get_string (const GLubyte ** text, GLubyte ** str)
1598 {
1599 const GLubyte *t = *text;
1600 GLubyte *p = NULL;
1601 GLuint len = 0;
1602 GLubyte term_char;
1603
1604 if (string_grow (&p, &len, '\0'))
1605 return 1;
1606
1607 /* read " or ' character that starts the string */
1608 term_char = *t++;
1609 /* while next character is not the terminating character */
1610 while (*t && *t != term_char) {
1611 GLubyte c;
1612
1613 if (*t == '\\')
1614 c = get_escape_sequence (&t);
1615 else
1616 c = *t++;
1617
1618 if (string_grow (&p, &len, c)) {
1619 mem_free ((GLvoid **) & p);
1620 return 1;
1621 }
1622 }
1623
1624 /* skip " or ' character that ends the string */
1625 t++;
1626
1627 *text = t;
1628 *str = p;
1629 return 0;
1630 }
1631
1632 /*
1633 * gets emit code, the syntax is: ".emtcode" " " <symbol> " " ("0x" | "0X") <hex_value>
1634 * assumes that *text already points to <symbol>,
1635 * returns 0 if emit code is successfully read,
1636 * returns 1 otherwise
1637 */
1638 static GLint
1639 get_emtcode (const GLubyte ** text, map_byte ** ma)
1640 {
1641 const GLubyte *t = *text;
1642 map_byte *m = NULL;
1643
1644 map_byte_create (&m);
1645 if (m == NULL)
1646 return 1;
1647
1648 if (get_identifier (&t, &m->key)) {
1649 map_byte_destroy (&m);
1650 return 1;
1651 }
1652 eat_spaces (&t);
1653
1654 if (*t == '\'') {
1655 GLubyte *c;
1656
1657 if (get_string (&t, &c)) {
1658 map_byte_destroy (&m);
1659 return 1;
1660 }
1661
1662 m->data = (GLubyte) c[0];
1663 mem_free ((GLvoid **) & c);
1664 }
1665 else {
1666 /* skip HEX "0x" or "0X" prefix */
1667 t += 2;
1668 m->data = (GLubyte) hex_convert (&t);
1669 }
1670
1671 eat_spaces (&t);
1672
1673 *text = t;
1674 *ma = m;
1675 return 0;
1676 }
1677
1678 /*
1679 * returns 0 on success,
1680 * returns 1 otherwise
1681 */
1682 static GLint
1683 get_errtext (const GLubyte ** text, map_str ** ma)
1684 {
1685 const GLubyte *t = *text;
1686 map_str *m = NULL;
1687
1688 map_str_create (&m);
1689 if (m == NULL)
1690 return 1;
1691
1692 if (get_identifier (&t, &m->key)) {
1693 map_str_destroy (&m);
1694 return 1;
1695 }
1696 eat_spaces (&t);
1697
1698 if (get_string (&t, &m->data)) {
1699 map_str_destroy (&m);
1700 return 1;
1701 }
1702 eat_spaces (&t);
1703
1704 *text = t;
1705 *ma = m;
1706 return 0;
1707 }
1708
1709 /*
1710 * returns 0 on success,
1711 * returns 1 otherwise,
1712 */
1713 static GLint
1714 get_error (const GLubyte ** text, error ** er, map_str * maps)
1715 {
1716 const GLubyte *t = *text;
1717 GLubyte *temp = NULL;
1718
1719 if (*t != '.')
1720 return 0;
1721
1722 t++;
1723 if (get_identifier (&t, &temp))
1724 return 1;
1725 eat_spaces (&t);
1726
1727 if (_mesa_strcmp ("error", (char *) temp) != 0) {
1728 mem_free ((GLvoid **) & temp);
1729 return 0;
1730 }
1731
1732 mem_free ((GLvoid **) & temp);
1733
1734 error_create (er);
1735 if (*er == NULL)
1736 return 1;
1737
1738 if (*t == '\"') {
1739 if (get_string (&t, &(**er).m_text)) {
1740 error_destroy (er);
1741 return 1;
1742 }
1743 eat_spaces (&t);
1744 }
1745 else {
1746 if (get_identifier (&t, &temp)) {
1747 error_destroy (er);
1748 return 1;
1749 }
1750 eat_spaces (&t);
1751
1752 if (map_str_find (&maps, temp, &(**er).m_text)) {
1753 mem_free ((GLvoid **) & temp);
1754 error_destroy (er);
1755 return 1;
1756 }
1757
1758 mem_free ((GLvoid **) & temp);
1759 }
1760
1761 /* try to extract "token" from "...$token$..." */
1762 {
1763 char *processed = NULL;
1764 GLuint len = 0, i = 0;
1765
1766 if (string_grow ((GLubyte **) (&processed), &len, '\0')) {
1767 error_destroy (er);
1768 return 1;
1769 }
1770
1771 while (i < _mesa_strlen ((char *) ((**er).m_text))) {
1772 /* check if the dollar sign is repeated - if so skip it */
1773 if ((**er).m_text[i] == '$' && (**er).m_text[i + 1] == '$') {
1774 if (string_grow ((GLubyte **) (&processed), &len, '$')) {
1775 mem_free ((GLvoid **) & processed);
1776 error_destroy (er);
1777 return 1;
1778 }
1779
1780 i += 2;
1781 }
1782 else if ((**er).m_text[i] != '$') {
1783 if (string_grow ((GLubyte **) (&processed), &len, (**er).m_text[i])) {
1784 mem_free ((GLvoid **) & processed);
1785 error_destroy (er);
1786 return 1;
1787 }
1788
1789 i++;
1790 }
1791 else {
1792 if (string_grow ((GLubyte **) (&processed), &len, '$')) {
1793 mem_free ((GLvoid **) & processed);
1794 error_destroy (er);
1795 return 1;
1796 }
1797
1798 {
1799 /* length of token being extracted */
1800 GLuint tlen = 0;
1801
1802 if (string_grow (&(**er).m_token_name, &tlen, '\0')) {
1803 mem_free ((GLvoid **) & processed);
1804 error_destroy (er);
1805 return 1;
1806 }
1807
1808 /* skip the dollar sign */
1809 i++;
1810
1811 while ((**er).m_text[i] != '$') {
1812 if (string_grow
1813 (&(**er).m_token_name, &tlen, (**er).m_text[i])) {
1814 mem_free ((GLvoid **) & processed);
1815 error_destroy (er);
1816 return 1;
1817 }
1818
1819 i++;
1820 }
1821
1822 /* skip the dollar sign */
1823 i++;
1824 }
1825 }
1826 }
1827
1828 mem_free ((GLvoid **) & (**er).m_text);
1829 (**er).m_text = (GLubyte *) processed;
1830 }
1831
1832 *text = t;
1833 return 0;
1834 }
1835
1836 /*
1837 * returns 0 on success,
1838 * returns 1 otherwise,
1839 */
1840 static GLint
1841 get_emits (const GLubyte ** text, emit ** em, map_byte * mapb)
1842 {
1843 const GLubyte *t = *text;
1844 GLubyte *temp = NULL;
1845 emit *e = NULL;
1846
1847 if (*t != '.')
1848 return 0;
1849
1850 t++;
1851 if (get_identifier (&t, &temp))
1852 return 1;
1853 eat_spaces (&t);
1854
1855 /* .emit */
1856 if (_mesa_strcmp ("emit", (char *) temp) != 0) {
1857 mem_free ((GLvoid **) & temp);
1858 return 0;
1859 }
1860
1861 mem_free ((GLvoid **) & temp);
1862
1863 emit_create (&e);
1864 if (e == NULL)
1865 return 1;
1866
1867 /* 0xNN */
1868 if (*t == '0') {
1869 t += 2;
1870 e->m_byte = (GLubyte) hex_convert (&t);
1871
1872 e->m_emit_type = et_byte;
1873 }
1874 /* * */
1875 else if (*t == '*') {
1876 t++;
1877
1878 e->m_emit_type = et_stream;
1879 }
1880 /* $ */
1881 else if (*t == '$') {
1882 t++;
1883
1884 e->m_emit_type = et_position;
1885 }
1886 /* 'c' */
1887 else if (*t == '\'') {
1888 if (get_string (&t, &temp)) {
1889 emit_destroy (&e);
1890 return 1;
1891 }
1892 e->m_byte = (GLubyte) temp[0];
1893
1894 mem_free ((GLvoid **) & temp);
1895
1896 e->m_emit_type = et_byte;
1897 }
1898 else {
1899 if (get_identifier (&t, &temp)) {
1900 emit_destroy (&e);
1901 return 1;
1902 }
1903
1904 if (map_byte_find (&mapb, temp, &e->m_byte)) {
1905 mem_free ((GLvoid **) & temp);
1906 emit_destroy (&e);
1907 return 1;
1908 }
1909
1910 mem_free ((GLvoid **) & temp);
1911
1912 e->m_emit_type = et_byte;
1913 }
1914
1915 eat_spaces (&t);
1916
1917 if (get_emits (&t, &e->m_next, mapb)) {
1918 emit_destroy (&e);
1919 return 1;
1920 }
1921
1922 *text = t;
1923 *em = e;
1924 return 0;
1925 }
1926
1927 /*
1928 * returns 0 on success,
1929 * returns 1 otherwise,
1930 */
1931 static GLint
1932 get_spec (const GLubyte ** text, spec ** sp, map_str * maps, map_byte * mapb)
1933 {
1934 const GLubyte *t = *text;
1935 spec *s = NULL;
1936
1937 spec_create (&s);
1938 if (s == NULL)
1939 return 1;
1940
1941 if (*t == '\'') {
1942 GLubyte *temp = NULL;
1943
1944 if (get_string (&t, &temp)) {
1945 spec_destroy (&s);
1946 return 1;
1947 }
1948 eat_spaces (&t);
1949
1950 if (*t == '-') {
1951 GLubyte *temp2 = NULL;
1952
1953 /* skip the '-' character */
1954 t++;
1955 eat_spaces (&t);
1956
1957 if (get_string (&t, &temp2)) {
1958 mem_free ((GLvoid **) & temp);
1959 spec_destroy (&s);
1960 return 1;
1961 }
1962 eat_spaces (&t);
1963
1964 s->m_spec_type = st_byte_range;
1965 s->m_byte[0] = *temp;
1966 s->m_byte[1] = *temp2;
1967
1968 mem_free ((GLvoid **) & temp2);
1969 }
1970 else {
1971 s->m_spec_type = st_byte;
1972 *s->m_byte = *temp;
1973 }
1974
1975 mem_free ((GLvoid **) & temp);
1976 }
1977 else if (*t == '"') {
1978 if (get_string (&t, &s->m_string)) {
1979 spec_destroy (&s);
1980 return 1;
1981 }
1982 eat_spaces (&t);
1983
1984 s->m_spec_type = st_string;
1985 }
1986 else if (*t == '.') {
1987 GLubyte *keyword = NULL;
1988
1989 /* skip the dot */
1990 t++;
1991
1992 if (get_identifier (&t, &keyword)) {
1993 spec_destroy (&s);
1994 return 1;
1995 }
1996 eat_spaces (&t);
1997
1998 /* .true */
1999 if (_mesa_strcmp ("true", (char *) keyword) == 0) {
2000 s->m_spec_type = st_true;
2001 }
2002 /* .false */
2003 else if (_mesa_strcmp ("false", (char *) keyword) == 0) {
2004 s->m_spec_type = st_false;
2005 }
2006 /* .debug */
2007 else if (_mesa_strcmp ("debug", (char *) keyword) == 0) {
2008 s->m_spec_type = st_debug;
2009 }
2010 /* .loop */
2011 else if (_mesa_strcmp ("loop", (char *) keyword) == 0) {
2012 if (get_identifier (&t, &s->m_string)) {
2013 mem_free ((GLvoid **) & keyword);
2014 spec_destroy (&s);
2015 return 1;
2016 }
2017 eat_spaces (&t);
2018
2019 s->m_spec_type = st_identifier_loop;
2020 }
2021
2022 mem_free ((GLvoid **) & keyword);
2023 }
2024 else {
2025 if (get_identifier (&t, &s->m_string)) {
2026 spec_destroy (&s);
2027 return 1;
2028 }
2029 eat_spaces (&t);
2030
2031 s->m_spec_type = st_identifier;
2032 }
2033
2034 if (get_error (&t, &s->m_errtext, maps)) {
2035 spec_destroy (&s);
2036 return 1;
2037 }
2038
2039 if (get_emits (&t, &s->m_emits, mapb)) {
2040 spec_destroy (&s);
2041 return 1;
2042 }
2043
2044 *text = t;
2045 *sp = s;
2046 return 0;
2047 }
2048
2049 /*
2050 * returns 0 on success,
2051 * returns 1 otherwise,
2052 */
2053 static GLint
2054 get_definition (const GLubyte ** text, defntn ** de, map_str * maps,
2055 map_byte * mapb)
2056 {
2057 const GLubyte *t = *text;
2058 defntn *d = NULL;
2059
2060 defntn_create (&d);
2061 if (d == NULL)
2062 return 1;
2063
2064 if (get_spec (&t, &d->m_specs, maps, mapb)) {
2065 defntn_destroy (&d);
2066 return 1;
2067 }
2068
2069 while (*t != ';') {
2070 GLubyte *op = NULL;
2071 spec *sp = NULL;
2072
2073 /* skip the dot that precedes "and" or "or" */
2074 t++;
2075
2076 /* read "and" or "or" keyword */
2077 if (get_identifier (&t, &op)) {
2078 defntn_destroy (&d);
2079 return 1;
2080 }
2081 eat_spaces (&t);
2082
2083 if (d->m_oper == op_none) {
2084 /* .and */
2085 if (_mesa_strcmp ("and", (char *) op) == 0)
2086 d->m_oper = op_and;
2087 /* .or */
2088 else
2089 d->m_oper = op_or;
2090 }
2091
2092 mem_free ((GLvoid **) & op);
2093
2094 if (get_spec (&t, &sp, maps, mapb)) {
2095 defntn_destroy (&d);
2096 return 1;
2097 }
2098
2099 spec_append (&d->m_specs, &sp);
2100 }
2101
2102 /* skip the semicolon */
2103 t++;
2104 eat_spaces (&t);
2105
2106 *text = t;
2107 *de = d;
2108 return 0;
2109 }
2110
2111 /*
2112 * returns 0 on success,
2113 * returns 1 otherwise,
2114 */
2115 static GLint
2116 update_dependency (map_def * mapd, GLubyte * symbol, defntn ** def)
2117 {
2118 if (map_def_find (&mapd, symbol, def))
2119 return 1;
2120
2121 #ifndef NDEBUG
2122 (**def).m_referenced = 1;
2123 #endif
2124
2125 return 0;
2126 }
2127
2128 /*
2129 * returns 0 on success,
2130 * returns 1 otherwise,
2131 */
2132 static GLint
2133 update_dependencies (dict * di, map_def * mapd, GLubyte ** syntax_symbol,
2134 GLubyte ** string_symbol)
2135 {
2136 defntn *de = di->m_defntns;
2137
2138 if (update_dependency (mapd, *syntax_symbol, &di->m_syntax) ||
2139 (*string_symbol != NULL
2140 && update_dependency (mapd, *string_symbol, &di->m_string)))
2141 return 1;
2142
2143 mem_free ((GLvoid **) syntax_symbol);
2144 mem_free ((GLvoid **) string_symbol);
2145
2146 while (de) {
2147 spec *sp = de->m_specs;
2148
2149 while (sp) {
2150 if (sp->m_spec_type == st_identifier
2151 || sp->m_spec_type == st_identifier_loop) {
2152 if (update_dependency (mapd, sp->m_string, &sp->m_defntn))
2153 return 1;
2154
2155 mem_free ((GLvoid **) & sp->m_string);
2156 }
2157
2158 if (sp->m_errtext && sp->m_errtext->m_token_name) {
2159 if (update_dependency
2160 (mapd, sp->m_errtext->m_token_name, &sp->m_errtext->m_token))
2161 return 1;
2162
2163 mem_free ((GLvoid **) & sp->m_errtext->m_token_name);
2164 }
2165
2166 sp = sp->m_next;
2167 }
2168
2169 de = de->m_next;
2170 }
2171
2172 return 0;
2173 }
2174
2175 typedef enum match_result_
2176 {
2177 mr_not_matched, /* the examined string does not match */
2178 mr_matched, /* the examined string matches */
2179 mr_error_raised, /* mr_not_matched + error has been raised */
2180 mr_dont_emit, /* used by identifier loops only */
2181 mr_internal_error /* an internal error has occured such as out of memory */
2182 } match_result;
2183
2184 static match_result
2185 match (dict * di, const GLubyte * text, GLuint * index, defntn * de,
2186 barray ** ba, GLint filtering_string)
2187 {
2188 GLuint ind = *index;
2189 match_result status = mr_not_matched;
2190 spec *sp = de->m_specs;
2191
2192 /* for every specifier in the definition */
2193 while (sp) {
2194 GLuint i, len, save_ind = ind;
2195 barray *array = NULL;
2196
2197 switch (sp->m_spec_type) {
2198 case st_identifier:
2199 barray_create (&array);
2200 if (array == NULL)
2201 return mr_internal_error;
2202
2203 status =
2204 match (di, text, &ind, sp->m_defntn, &array, filtering_string);
2205 if (status == mr_internal_error) {
2206 barray_destroy (&array);
2207 return mr_internal_error;
2208 }
2209 break;
2210 case st_string:
2211 len = _mesa_strlen ((char *) (sp->m_string));
2212
2213 /* prefilter the stream */
2214 if (!filtering_string && di->m_string) {
2215 barray *ba;
2216 GLuint filter_index = 0;
2217 match_result result;
2218
2219 barray_create (&ba);
2220 if (ba == NULL)
2221 return mr_internal_error;
2222
2223 result =
2224 match (di, text + ind, &filter_index, di->m_string, &ba, 1);
2225
2226 if (result == mr_internal_error) {
2227 barray_destroy (&ba);
2228 return mr_internal_error;
2229 }
2230
2231 if (result != mr_matched) {
2232 barray_destroy (&ba);
2233 status = mr_not_matched;
2234 break;
2235 }
2236
2237 barray_destroy (&ba);
2238
2239 if (filter_index != len
2240 || _mesa_strncmp ((char *)sp->m_string, (char *)(text + ind), len)) {
2241 status = mr_not_matched;
2242 break;
2243 }
2244
2245 status = mr_matched;
2246 ind += len;
2247 }
2248 else {
2249 status = mr_matched;
2250 for (i = 0; status == mr_matched && i < len; i++)
2251 if (text[ind + i] != sp->m_string[i])
2252 status = mr_not_matched;
2253 if (status == mr_matched)
2254 ind += len;
2255 }
2256 break;
2257 case st_byte:
2258 status = text[ind] == *sp->m_byte ? mr_matched : mr_not_matched;
2259 if (status == mr_matched)
2260 ind++;
2261 break;
2262 case st_byte_range:
2263 status = (text[ind] >= sp->m_byte[0]
2264 && text[ind] <=
2265 sp->m_byte[1]) ? mr_matched : mr_not_matched;
2266 if (status == mr_matched)
2267 ind++;
2268 break;
2269 case st_true:
2270 status = mr_matched;
2271 break;
2272 case st_false:
2273 status = mr_not_matched;
2274 break;
2275 case st_debug:
2276 status = mr_matched;
2277 break;
2278 case st_identifier_loop:
2279 barray_create (&array);
2280 if (array == NULL)
2281 return mr_internal_error;
2282
2283 status = mr_dont_emit;
2284 for (;;) {
2285 match_result result;
2286
2287 save_ind = ind;
2288 result =
2289 match (di, text, &ind, sp->m_defntn, &array,
2290 filtering_string);
2291
2292 if (result == mr_error_raised) {
2293 status = result;
2294 break;
2295 }
2296 else if (result == mr_matched) {
2297 if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind)
2298 || barray_append (ba, &array)) {
2299 barray_destroy (&array);
2300 return mr_internal_error;
2301 }
2302 barray_destroy (&array);
2303 barray_create (&array);
2304 if (array == NULL)
2305 return mr_internal_error;
2306 }
2307 else if (result == mr_internal_error) {
2308 barray_destroy (&array);
2309 return mr_internal_error;
2310 }
2311 else
2312 break;
2313 }
2314 break;
2315 };
2316
2317 if (status == mr_error_raised) {
2318 barray_destroy (&array);
2319
2320 return mr_error_raised;
2321 }
2322
2323 if (de->m_oper == op_and && status != mr_matched
2324 && status != mr_dont_emit) {
2325 barray_destroy (&array);
2326
2327 if (sp->m_errtext) {
2328 set_last_error (sp->m_errtext->m_text,
2329 error_get_token (sp->m_errtext, di, text, ind),
2330 ind);
2331
2332 return mr_error_raised;
2333 }
2334
2335 return mr_not_matched;
2336 }
2337
2338 if (status == mr_matched) {
2339 if (sp->m_emits)
2340 if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind)) {
2341 barray_destroy (&array);
2342 return mr_internal_error;
2343 }
2344
2345 if (array)
2346 if (barray_append (ba, &array)) {
2347 barray_destroy (&array);
2348 return mr_internal_error;
2349 }
2350 }
2351
2352 barray_destroy (&array);
2353
2354 if (de->m_oper == op_or
2355 && (status == mr_matched || status == mr_dont_emit)) {
2356 *index = ind;
2357 return mr_matched;
2358 }
2359
2360 sp = sp->m_next;
2361 }
2362
2363 if (de->m_oper == op_and
2364 && (status == mr_matched || status == mr_dont_emit)) {
2365 *index = ind;
2366 return mr_matched;
2367 }
2368
2369 return mr_not_matched;
2370 }
2371
2372 static GLubyte *
2373 error_get_token (error * er, dict * di, const GLubyte * text, unsigned int ind)
2374 {
2375 GLubyte *str = NULL;
2376
2377 if (er->m_token) {
2378 barray *ba;
2379 GLuint filter_index = 0;
2380
2381 barray_create (&ba);
2382 if (ba != NULL) {
2383 if (match (di, text + ind, &filter_index, er->m_token, &ba, 0) ==
2384 mr_matched && filter_index) {
2385 str = (GLubyte *) mem_alloc (filter_index + 1);
2386 if (str != NULL) {
2387 _mesa_strncpy ((char *) str, (char *) (text + ind),
2388 filter_index);
2389 str[filter_index] = '\0';
2390 }
2391 }
2392 barray_destroy (&ba);
2393 }
2394 }
2395
2396 return str;
2397 }
2398
2399 typedef struct grammar_load_state_
2400 {
2401 dict *di;
2402 GLubyte *syntax_symbol;
2403 GLubyte *string_symbol;
2404 map_str *maps;
2405 map_byte *mapb;
2406 map_def *mapd;
2407 } grammar_load_state;
2408
2409
2410 static GLvoid
2411 grammar_load_state_create (grammar_load_state ** gr)
2412 {
2413 *gr = (grammar_load_state *) mem_alloc (sizeof (grammar_load_state));
2414 if (*gr) {
2415 (**gr).di = NULL;
2416 (**gr).syntax_symbol = NULL;
2417 (**gr).string_symbol = NULL;
2418 (**gr).maps = NULL;
2419 (**gr).mapb = NULL;
2420 (**gr).mapd = NULL;
2421 }
2422 }
2423
2424 static GLvoid
2425 grammar_load_state_destroy (grammar_load_state ** gr)
2426 {
2427 if (*gr) {
2428 dict_destroy (&(**gr).di);
2429 mem_free ((GLvoid **) &(**gr).syntax_symbol);
2430 mem_free ((GLvoid **) &(**gr).string_symbol);
2431 map_str_destroy (&(**gr).maps);
2432 map_byte_destroy (&(**gr).mapb);
2433 map_def_destroy (&(**gr).mapd);
2434 mem_free ((GLvoid **) gr);
2435 }
2436 }
2437
2438 /*
2439 * the API
2440 */
2441
2442 /*
2443 * loads grammar script from null-terminated ASCII text
2444 * returns the grammar object
2445 * returns NULL if an error occurs (call grammar_get_last_error to retrieve the error text)
2446 */
2447
2448 static dict *
2449 grammar_load_from_text (const GLubyte * text)
2450 {
2451 dict *d = NULL;
2452 grammar_load_state *g = NULL;
2453
2454 clear_last_error ();
2455
2456 grammar_load_state_create (&g);
2457 if (g == NULL)
2458 return NULL;
2459
2460 dict_create (&g->di);
2461 if (g->di == NULL) {
2462 grammar_load_state_destroy (&g);
2463 return NULL;
2464 }
2465
2466 eat_spaces (&text);
2467
2468 /* skip ".syntax" keyword */
2469 text += 7;
2470 eat_spaces (&text);
2471
2472 /* retrieve root symbol */
2473 if (get_identifier (&text, &g->syntax_symbol)) {
2474 grammar_load_state_destroy (&g);
2475 return NULL;
2476 }
2477 eat_spaces (&text);
2478
2479 /* skip semicolon */
2480 text++;
2481 eat_spaces (&text);
2482
2483 while (*text) {
2484 GLubyte *symbol = NULL;
2485 GLint is_dot = *text == '.';
2486
2487 if (is_dot)
2488 text++;
2489
2490 if (get_identifier (&text, &symbol)) {
2491 grammar_load_state_destroy (&g);
2492 return NULL;
2493 }
2494 eat_spaces (&text);
2495
2496 /* .emtcode */
2497 if (is_dot && _mesa_strcmp ((char *) symbol, "emtcode") == 0) {
2498 map_byte *ma = NULL;
2499
2500 mem_free ((void **) &symbol);
2501
2502 if (get_emtcode (&text, &ma)) {
2503 grammar_load_state_destroy (&g);
2504 return NULL;
2505 }
2506
2507 map_byte_append (&g->mapb, &ma);
2508 }
2509 /* .errtext */
2510 else if (is_dot && _mesa_strcmp ((char *) symbol, "errtext") == 0) {
2511 map_str *ma = NULL;
2512
2513 mem_free ((GLvoid **) &symbol);
2514
2515 if (get_errtext (&text, &ma)) {
2516 grammar_load_state_destroy (&g);
2517 return NULL;
2518 }
2519
2520 map_str_append (&g->maps, &ma);
2521 }
2522 /* .string */
2523 else if (is_dot && _mesa_strcmp ((char *) symbol, "string") == 0) {
2524 mem_free ((GLvoid **) (&symbol));
2525
2526 if (g->di->m_string != NULL) {
2527 grammar_load_state_destroy (&g);
2528 return NULL;
2529 }
2530
2531 if (get_identifier (&text, &g->string_symbol)) {
2532 grammar_load_state_destroy (&g);
2533 return NULL;
2534 }
2535
2536 /* skip semicolon */
2537 eat_spaces (&text);
2538 text++;
2539 eat_spaces (&text);
2540 }
2541 else {
2542 defntn *de = NULL;
2543 map_def *ma = NULL;
2544
2545 if (get_definition (&text, &de, g->maps, g->mapb)) {
2546 grammar_load_state_destroy (&g);
2547 return NULL;
2548 }
2549
2550 defntn_append (&g->di->m_defntns, &de);
2551
2552 /* if definition consist of only one specifier, give it an ".and" operator */
2553 if (de->m_oper == op_none)
2554 de->m_oper = op_and;
2555
2556 map_def_create (&ma);
2557 if (ma == NULL) {
2558 grammar_load_state_destroy (&g);
2559 return NULL;
2560 }
2561
2562 ma->key = symbol;
2563 ma->data = de;
2564 map_def_append (&g->mapd, &ma);
2565 }
2566 }
2567
2568 if (update_dependencies
2569 (g->di, g->mapd, &g->syntax_symbol, &g->string_symbol)) {
2570 grammar_load_state_destroy (&g);
2571 return NULL;
2572 }
2573
2574 d = g->di;
2575 g->di = NULL;
2576
2577 grammar_load_state_destroy (&g);
2578
2579 return d;
2580 }
2581
2582 /**
2583 * checks if a null-terminated text matches given grammar
2584 * returns 0 on error (call grammar_get_last_error to retrieve the error text)
2585 * returns 1 on success, the prod points to newly allocated buffer with
2586 * production and size is filled with the production size
2587 *
2588 * \param id - The grammar returned from grammar_load_from_text()
2589 * \param text - The program string
2590 * \param production - The return parameter for the binary array holding the
2591 * parsed results
2592 * \param size - The return parameter for the size of production
2593 *
2594 * \return 1 on sucess, 0 on parser error
2595 */
2596 static GLint
2597 grammar_check (dict * di, const GLubyte * text, GLubyte ** production,
2598 GLuint *size)
2599 {
2600 barray *ba = NULL;
2601 GLuint index = 0;
2602
2603 clear_last_error ();
2604
2605 barray_create (&ba);
2606 if (ba == NULL)
2607 return 0;
2608
2609 *production = NULL;
2610 *size = 0;
2611
2612 if (match (di, text, &index, di->m_syntax, &ba, 0) != mr_matched) {
2613 barray_destroy (&ba);
2614 return 0;
2615 }
2616
2617 *production = (GLubyte *) mem_alloc (ba->len * sizeof (GLubyte));
2618 if (*production == NULL) {
2619 barray_destroy (&ba);
2620 return 0;
2621 }
2622
2623 memcpy (*production, ba->data, ba->len * sizeof (GLubyte));
2624 *size = ba->len;
2625 barray_destroy (&ba);
2626
2627 return 1;
2628 }
2629
2630 static GLvoid
2631 grammar_get_last_error (GLubyte * text, GLint size, GLint *pos)
2632 {
2633 GLint len = 0, dots_made = 0;
2634 const GLubyte *p = error_message;
2635
2636 *text = '\0';
2637 #define APPEND_CHARACTER(x) if (dots_made == 0) {\
2638 if (len < size - 1) {\
2639 text[len++] = (x); text[len] = '\0';\
2640 } else {\
2641 GLint i;\
2642 for (i = 0; i < 3; i++)\
2643 if (--len >= 0)\
2644 text[len] = '.';\
2645 dots_made = 1;\
2646 }\
2647 }
2648
2649 if (p) {
2650 while (*p) {
2651 if (*p == '$') {
2652 const GLubyte *r = error_param;
2653
2654 while (*r) {
2655 APPEND_CHARACTER (*r)
2656 r++;
2657 }
2658
2659 p++;
2660 }
2661 else {
2662 APPEND_CHARACTER (*p)
2663 p++;
2664 }
2665 }
2666 }
2667 *pos = error_position;
2668 }
2669
2670 /*-----------------------------------------------------------------------
2671 * From here on down is the semantic checking portion
2672 *
2673 */
2674
2675 /**
2676 * Variable Table Handling functions
2677 */
2678 typedef enum
2679 {
2680 vt_none,
2681 vt_address,
2682 vt_attrib,
2683 vt_param,
2684 vt_temp,
2685 vt_output,
2686 vt_alias
2687 } var_type;
2688
2689
2690 /*
2691 * Setting an explicit field for each of the binding properties is a bit wasteful
2692 * of space, but it should be much more clear when reading later on..
2693 */
2694 struct var_cache
2695 {
2696 GLubyte *name;
2697 var_type type;
2698 GLuint address_binding; /* The index of the address register we should
2699 * be using */
2700 GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */
2701 GLuint attrib_binding_idx; /* The index into the attrib register file corresponding
2702 * to the state in attrib_binding */
2703 GLuint attrib_is_generic; /* If the attrib was specified through a generic
2704 * vertex attrib */
2705 GLuint temp_binding; /* The index of the temp register we are to use */
2706 GLuint output_binding; /* For type vt_output, see nvfragprog.h for values */
2707 GLuint output_binding_idx; /* This is the index into the result register file
2708 * corresponding to the bound result state */
2709 struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry
2710 * that this is aliased to */
2711 GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,
2712 * PROGRAM_ENV_PARAM} */
2713 GLuint param_binding_begin; /* This is the offset into the program_parameter_list where
2714 * the tokens representing our bound state (or constants)
2715 * start */
2716 GLuint param_binding_length; /* This is how many entries in the the program_parameter_list
2717 * we take up with our state tokens or constants. Note that
2718 * this is _not_ the same as the number of param registers
2719 * we eventually use */
2720 struct var_cache *next;
2721 };
2722
2723 static GLvoid
2724 var_cache_create (struct var_cache **va)
2725 {
2726 *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache));
2727 if (*va) {
2728 (**va).name = NULL;
2729 (**va).type = vt_none;
2730 (**va).attrib_binding = ~0;
2731 (**va).attrib_is_generic = 0;
2732 (**va).temp_binding = ~0;
2733 (**va).output_binding = ~0;
2734 (**va).output_binding_idx = ~0;
2735 (**va).param_binding_type = ~0;
2736 (**va).param_binding_begin = ~0;
2737 (**va).param_binding_length = ~0;
2738 (**va).alias_binding = NULL;
2739 (**va).next = NULL;
2740 }
2741 }
2742
2743 static GLvoid
2744 var_cache_destroy (struct var_cache **va)
2745 {
2746 if (*va) {
2747 var_cache_destroy (&(**va).next);
2748 _mesa_free (*va);
2749 *va = NULL;
2750 }
2751 }
2752
2753 static GLvoid
2754 var_cache_append (struct var_cache **va, struct var_cache *nv)
2755 {
2756 if (*va)
2757 var_cache_append (&(**va).next, nv);
2758 else
2759 *va = nv;
2760 }
2761
2762 static struct var_cache *
2763 var_cache_find (struct var_cache *va, GLubyte * name)
2764 {
2765 struct var_cache *first = va;
2766
2767 while (va) {
2768 if (!strcmp ( (const char*) name, (const char*) va->name)) {
2769 if (va->type == vt_alias)
2770 return var_cache_find (first, va->name);
2771 return va;
2772 }
2773
2774 va = va->next;
2775 }
2776
2777 return NULL;
2778 }
2779
2780 /**
2781 * constructs an integer from 4 GLubytes in LE format
2782 */
2783 static GLuint
2784 parse_position (GLubyte ** inst)
2785 {
2786 GLuint value;
2787
2788 value = (GLuint) (*(*inst)++);
2789 value += (GLuint) (*(*inst)++) * 0x100;
2790 value += (GLuint) (*(*inst)++) * 0x10000;
2791 value += (GLuint) (*(*inst)++) * 0x1000000;
2792
2793 return value;
2794 }
2795
2796 /**
2797 * This will, given a string, lookup the string as a variable name in the
2798 * var cache. If the name is found, the var cache node corresponding to the
2799 * var name is returned. If it is not found, a new entry is allocated
2800 *
2801 * \param I Points into the binary array where the string identifier begins
2802 * \param found 1 if the string was found in the var_cache, 0 if it was allocated
2803 * \return The location on the var_cache corresponding the the string starting at I
2804 */
2805 static struct var_cache *
2806 parse_string (GLubyte ** inst, struct var_cache **vc_head,
2807 struct arb_program *Program, GLuint * found)
2808 {
2809 GLubyte *i = *inst;
2810 struct var_cache *va = NULL;
2811
2812 *inst += _mesa_strlen ((char *) i) + 1;
2813
2814 va = var_cache_find (*vc_head, i);
2815
2816 if (va) {
2817 *found = 1;
2818 return va;
2819 }
2820
2821 *found = 0;
2822 var_cache_create (&va);
2823 va->name = i;
2824
2825 var_cache_append (vc_head, va);
2826
2827 return va;
2828 }
2829
2830 static char *
2831 parse_string_without_adding (GLubyte ** inst, struct arb_program *Program)
2832 {
2833 GLubyte *i = *inst;
2834
2835 *inst += _mesa_strlen ((char *) i) + 1;
2836
2837 return (char *) i;
2838 }
2839
2840 /**
2841 * \return 0 if sign is plus, 1 if sign is minus
2842 */
2843 static GLuint
2844 parse_sign (GLubyte ** inst)
2845 {
2846 /*return *(*inst)++ != '+'; */
2847
2848 if (**inst == '-') {
2849 (*inst)++;
2850 return 1;
2851 }
2852 else if (**inst == '+') {
2853 (*inst)++;
2854 return 0;
2855 }
2856
2857 return 0;
2858 }
2859
2860 /**
2861 * parses and returns signed integer
2862 */
2863 static GLint
2864 parse_integer (GLubyte ** inst, struct arb_program *Program)
2865 {
2866 GLint sign;
2867 GLint value;
2868
2869 /* check if *inst points to '+' or '-'
2870 * if yes, grab the sign and increment *inst
2871 */
2872 sign = parse_sign (inst);
2873
2874 /* now check if *inst points to 0
2875 * if yes, increment the *inst and return the default value
2876 */
2877 if (**inst == 0) {
2878 (*inst)++;
2879 return 0;
2880 }
2881
2882 /* parse the integer as you normally would do it */
2883 value = _mesa_atoi (parse_string_without_adding (inst, Program));
2884
2885 /* now, after terminating 0 there is a position
2886 * to parse it - parse_position()
2887 */
2888 Program->Position = parse_position (inst);
2889
2890 if (sign)
2891 value *= -1;
2892
2893 return value;
2894 }
2895
2896 /**
2897 */
2898 static GLfloat
2899 parse_float (GLubyte ** inst, struct arb_program *Program)
2900 {
2901 GLint tmp[5], denom;
2902 GLfloat value = 0;
2903
2904 #if 0
2905 tmp[0] = parse_sign (inst); /* This is the sign of the number + - >0, - -> 1 */
2906 #endif
2907 tmp[1] = parse_integer (inst, Program); /* This is the integer portion of the number */
2908 tmp[2] = parse_integer (inst, Program); /* This is the fractional portion of the number */
2909 tmp[3] = parse_sign (inst); /* This is the sign of the exponent */
2910 tmp[4] = parse_integer (inst, Program); /* This is the exponent */
2911
2912 value = (GLfloat) tmp[1];
2913 denom = 1;
2914 while (denom < tmp[2])
2915 denom *= 10;
2916 value += (GLfloat) tmp[2] / (GLfloat) denom;
2917 #if 0
2918 if (tmp[0])
2919 value *= -1;
2920 #endif
2921 value *= _mesa_pow (10, (GLfloat) tmp[3] * (GLfloat) tmp[4]);
2922
2923 return value;
2924 }
2925
2926 /**
2927 */
2928 static GLfloat
2929 parse_signed_float (GLubyte ** inst, struct arb_program *Program)
2930 {
2931 GLint negate;
2932 GLfloat value;
2933
2934 negate = parse_sign (inst);
2935
2936 value = parse_float (inst, Program);
2937
2938 if (negate)
2939 value *= -1;
2940
2941 return value;
2942 }
2943
2944 /**
2945 * This picks out a constant value from the parsed array. The constant vector is r
2946 * returned in the *values array, which should be of length 4.
2947 *
2948 * \param values - The 4 component vector with the constant value in it
2949 */
2950 static GLvoid
2951 parse_constant (GLubyte ** inst, GLfloat *values, struct arb_program *Program,
2952 GLboolean use)
2953 {
2954 GLuint components, i;
2955
2956
2957 switch (*(*inst)++) {
2958 case CONSTANT_SCALAR:
2959 if (use == GL_TRUE) {
2960 values[0] =
2961 values[1] =
2962 values[2] = values[3] = parse_float (inst, Program);
2963 }
2964 else {
2965 values[0] =
2966 values[1] =
2967 values[2] = values[3] = parse_signed_float (inst, Program);
2968 }
2969
2970 break;
2971 case CONSTANT_VECTOR:
2972 values[0] = values[1] = values[2] = 0;
2973 values[3] = 1;
2974 components = *(*inst)++;
2975 for (i = 0; i < components; i++) {
2976 values[i] = parse_signed_float (inst, Program);
2977 }
2978 break;
2979 }
2980 }
2981
2982
2983 /**
2984 * \param color 0 if color type is primary, 1 if color type is secondary
2985 * \return 0 on sucess, 1 on error
2986 */
2987 static GLuint
2988 parse_color_type (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
2989 GLint * color)
2990 {
2991 *color = *(*inst)++ != COLOR_PRIMARY;
2992 return 0;
2993 }
2994
2995 /**
2996 * Get an integer corresponding to a generic vertex attribute.
2997 *
2998 * \return 0 on sucess, 1 on error
2999 */
3000 static GLuint
3001 parse_generic_attrib_num(GLcontext *ctx, GLubyte ** inst,
3002 struct arb_program *Program, GLuint *attrib)
3003 {
3004 *attrib = parse_integer(inst, Program);
3005
3006 if ((*attrib < 0) || (*attrib > MAX_VERTEX_PROGRAM_ATTRIBS))
3007 {
3008 _mesa_set_program_error (ctx, Program->Position,
3009 "Invalid generic vertex attribute index");
3010 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid generic vertex attribute index");
3011
3012 return 1;
3013 }
3014
3015 return 0;
3016 }
3017
3018
3019 /**
3020 * \param coord The texture unit index
3021 * \return 0 on sucess, 1 on error
3022 */
3023 static GLuint
3024 parse_texcoord_num (GLcontext * ctx, GLubyte ** inst,
3025 struct arb_program *Program, GLuint * coord)
3026 {
3027 *coord = parse_integer (inst, Program);
3028
3029 if ((*coord < 0) || (*coord >= ctx->Const.MaxTextureUnits)) {
3030 _mesa_set_program_error (ctx, Program->Position,
3031 "Invalid texture unit index");
3032 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid texture unit index");
3033 return 1;
3034 }
3035
3036 return 0;
3037 }
3038
3039 /**
3040 * \param coord The weight index
3041 * \return 0 on sucess, 1 on error
3042 */
3043 static GLuint
3044 parse_weight_num (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
3045 GLint * coord)
3046 {
3047 *coord = parse_integer (inst, Program);
3048
3049 if ((*coord < 0) || (*coord >= 1)) {
3050 _mesa_set_program_error (ctx, Program->Position,
3051 "Invalid weight index");
3052 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid weight index");
3053 return 1;
3054 }
3055
3056 return 0;
3057 }
3058
3059 /**
3060 * \param coord The clip plane index
3061 * \return 0 on sucess, 1 on error
3062 */
3063 static GLuint
3064 parse_clipplane_num (GLcontext * ctx, GLubyte ** inst,
3065 struct arb_program *Program, GLint * coord)
3066 {
3067 *coord = parse_integer (inst, Program);
3068
3069 if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) {
3070 _mesa_set_program_error (ctx, Program->Position,
3071 "Invalid clip plane index");
3072 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid clip plane index");
3073 return 1;
3074 }
3075
3076 return 0;
3077 }
3078
3079
3080 /**
3081 * \return 0 on front face, 1 on back face
3082 */
3083 static GLuint
3084 parse_face_type (GLubyte ** inst)
3085 {
3086 switch (*(*inst)++) {
3087 case FACE_FRONT:
3088 return 0;
3089
3090 case FACE_BACK:
3091 return 1;
3092 }
3093 return 0;
3094 }
3095
3096
3097 /**
3098 * Given a matrix and a modifier token on the binary array, return tokens
3099 * that _mesa_fetch_state() [program.c] can understand.
3100 *
3101 * \param matrix - the matrix we are talking about
3102 * \param matrix_idx - the index of the matrix we have (for texture & program matricies)
3103 * \param matrix_modifier - the matrix modifier (trans, inv, etc)
3104 * \return 0 on sucess, 1 on failure
3105 */
3106 static GLuint
3107 parse_matrix (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
3108 GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier)
3109 {
3110 GLubyte mat = *(*inst)++;
3111
3112 *matrix_idx = 0;
3113
3114 switch (mat) {
3115 case MATRIX_MODELVIEW:
3116 *matrix = STATE_MODELVIEW;
3117 *matrix_idx = parse_integer (inst, Program);
3118 if (*matrix_idx > 0) {
3119 _mesa_set_program_error (ctx, Program->Position,
3120 "ARB_vertex_blend not supported\n");
3121 _mesa_error (ctx, GL_INVALID_OPERATION,
3122 "ARB_vertex_blend not supported\n");
3123 return 1;
3124 }
3125 break;
3126
3127 case MATRIX_PROJECTION:
3128 *matrix = STATE_PROJECTION;
3129 break;
3130
3131 case MATRIX_MVP:
3132 *matrix = STATE_MVP;
3133 break;
3134
3135 case MATRIX_TEXTURE:
3136 *matrix = STATE_TEXTURE;
3137 *matrix_idx = parse_integer (inst, Program);
3138 if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) {
3139 _mesa_set_program_error (ctx, Program->Position,
3140 "Invalid Texture Unit");
3141 _mesa_error (ctx, GL_INVALID_OPERATION,
3142 "Invalid Texture Unit: %d", *matrix_idx);
3143 return 1;
3144 }
3145 break;
3146
3147 /* This is not currently supported (ARB_matrix_palette) */
3148 case MATRIX_PALETTE:
3149 *matrix_idx = parse_integer (inst, Program);
3150 _mesa_set_program_error (ctx, Program->Position,
3151 "ARB_matrix_palette not supported\n");
3152 _mesa_error (ctx, GL_INVALID_OPERATION,
3153 "ARB_matrix_palette not supported\n");
3154 return 1;
3155 break;
3156
3157 case MATRIX_PROGRAM:
3158 *matrix = STATE_PROGRAM;
3159 *matrix_idx = parse_integer (inst, Program);
3160 if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) {
3161 _mesa_set_program_error (ctx, Program->Position,
3162 "Invalid Program Matrix");
3163 _mesa_error (ctx, GL_INVALID_OPERATION,
3164 "Invalid Program Matrix: %d", *matrix_idx);
3165 return 1;
3166 }
3167 break;
3168 }
3169
3170 switch (*(*inst)++) {
3171 case MATRIX_MODIFIER_IDENTITY:
3172 *matrix_modifier = 0;
3173 break;
3174 case MATRIX_MODIFIER_INVERSE:
3175 *matrix_modifier = STATE_MATRIX_INVERSE;
3176 break;
3177 case MATRIX_MODIFIER_TRANSPOSE:
3178 *matrix_modifier = STATE_MATRIX_TRANSPOSE;
3179 break;
3180 case MATRIX_MODIFIER_INVTRANS:
3181 *matrix_modifier = STATE_MATRIX_INVTRANS;
3182 break;
3183 }
3184
3185 return 0;
3186 }
3187
3188
3189 /**
3190 * This parses a state string (rather, the binary version of it) into
3191 * a 6-token sequence as described in _mesa_fetch_state() [program.c]
3192 *
3193 * \param inst - the start in the binary arry to start working from
3194 * \param state_tokens - the storage for the 6-token state description
3195 * \return - 0 on sucess, 1 on error
3196 */
3197 static GLuint
3198 parse_state_single_item (GLcontext * ctx, GLubyte ** inst,
3199 struct arb_program *Program, GLint * state_tokens)
3200 {
3201 switch (*(*inst)++) {
3202 case STATE_MATERIAL_PARSER:
3203 state_tokens[0] = STATE_MATERIAL;
3204 state_tokens[1] = parse_face_type (inst);
3205 switch (*(*inst)++) {
3206 case MATERIAL_AMBIENT:
3207 state_tokens[2] = STATE_AMBIENT;
3208 break;
3209 case MATERIAL_DIFFUSE:
3210 state_tokens[2] = STATE_DIFFUSE;
3211 break;
3212 case MATERIAL_SPECULAR:
3213 state_tokens[2] = STATE_SPECULAR;
3214 break;
3215 case MATERIAL_EMISSION:
3216 state_tokens[2] = STATE_EMISSION;
3217 break;
3218 case MATERIAL_SHININESS:
3219 state_tokens[2] = STATE_SHININESS;
3220 break;
3221 }
3222 break;
3223
3224 case STATE_LIGHT_PARSER:
3225 state_tokens[0] = STATE_LIGHT;
3226 state_tokens[1] = parse_integer (inst, Program);
3227
3228 /* Check the value of state_tokens[1] against the # of lights */
3229 if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
3230 _mesa_set_program_error (ctx, Program->Position,
3231 "Invalid Light Number");
3232 _mesa_error (ctx, GL_INVALID_OPERATION,
3233 "Invalid Light Number: %d", state_tokens[1]);
3234 return 1;
3235 }
3236
3237 switch (*(*inst)++) {
3238 case LIGHT_AMBIENT:
3239 state_tokens[2] = STATE_AMBIENT;
3240 break;
3241 case LIGHT_DIFFUSE:
3242 state_tokens[2] = STATE_DIFFUSE;
3243 break;
3244 case LIGHT_SPECULAR:
3245 state_tokens[2] = STATE_SPECULAR;
3246 break;
3247 case LIGHT_POSITION:
3248 state_tokens[2] = STATE_POSITION;
3249 break;
3250 case LIGHT_ATTENUATION:
3251 state_tokens[2] = STATE_ATTENUATION;
3252 break;
3253 case LIGHT_HALF:
3254 state_tokens[2] = STATE_HALF;
3255 break;
3256 case LIGHT_SPOT_DIRECTION:
3257 state_tokens[2] = STATE_SPOT_DIRECTION;
3258 break;
3259 }
3260 break;
3261
3262 case STATE_LIGHT_MODEL:
3263 switch (*(*inst)++) {
3264 case LIGHT_MODEL_AMBIENT:
3265 state_tokens[0] = STATE_LIGHTMODEL_AMBIENT;
3266 break;
3267 case LIGHT_MODEL_SCENECOLOR:
3268 state_tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
3269 state_tokens[1] = parse_face_type (inst);
3270 break;
3271 }
3272 break;
3273
3274 case STATE_LIGHT_PROD:
3275 state_tokens[0] = STATE_LIGHTPROD;
3276 state_tokens[1] = parse_integer (inst, Program);
3277
3278 /* Check the value of state_tokens[1] against the # of lights */
3279 if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
3280 _mesa_set_program_error (ctx, Program->Position,
3281 "Invalid Light Number");
3282 _mesa_error (ctx, GL_INVALID_OPERATION,
3283 "Invalid Light Number: %d", state_tokens[1]);
3284 return 1;
3285 }
3286
3287 state_tokens[2] = parse_face_type (inst);
3288 switch (*(*inst)++) {
3289 case LIGHT_PROD_AMBIENT:
3290 state_tokens[3] = STATE_AMBIENT;
3291 break;
3292 case LIGHT_PROD_DIFFUSE:
3293 state_tokens[3] = STATE_DIFFUSE;
3294 break;
3295 case LIGHT_PROD_SPECULAR:
3296 state_tokens[3] = STATE_SPECULAR;
3297 break;
3298 }
3299 break;
3300
3301
3302 case STATE_FOG:
3303 switch (*(*inst)++) {
3304 case FOG_COLOR:
3305 state_tokens[0] = STATE_FOG_COLOR;
3306 break;
3307 case FOG_PARAMS:
3308 state_tokens[0] = STATE_FOG_PARAMS;
3309 break;
3310 }
3311 break;
3312
3313 case STATE_TEX_ENV:
3314 state_tokens[1] = parse_integer (inst, Program);
3315 switch (*(*inst)++) {
3316 case TEX_ENV_COLOR:
3317 state_tokens[0] = STATE_TEXENV_COLOR;
3318 break;
3319 }
3320 break;
3321
3322 case STATE_TEX_GEN:
3323 {
3324 GLuint type, coord;
3325
3326 state_tokens[0] = STATE_TEXGEN;
3327 /*state_tokens[1] = parse_integer (inst, Program);*/ /* Texture Unit */
3328
3329 if (parse_texcoord_num (ctx, inst, Program, &coord))
3330 return 1;
3331 state_tokens[1] = coord;
3332
3333 /* EYE or OBJECT */
3334 type = *(*inst++);
3335
3336 /* 0 - s, 1 - t, 2 - r, 3 - q */
3337 coord = *(*inst++);
3338
3339 if (type == TEX_GEN_EYE) {
3340 switch (coord) {
3341 case COMPONENT_X:
3342 state_tokens[2] = STATE_TEXGEN_EYE_S;
3343 break;
3344 case COMPONENT_Y:
3345 state_tokens[2] = STATE_TEXGEN_EYE_T;
3346 break;
3347 case COMPONENT_Z:
3348 state_tokens[2] = STATE_TEXGEN_EYE_R;
3349 break;
3350 case COMPONENT_W:
3351 state_tokens[2] = STATE_TEXGEN_EYE_Q;
3352 break;
3353 }
3354 }
3355 else {
3356 switch (coord) {
3357 case COMPONENT_X:
3358 state_tokens[2] = STATE_TEXGEN_OBJECT_S;
3359 break;
3360 case COMPONENT_Y:
3361 state_tokens[2] = STATE_TEXGEN_OBJECT_T;
3362 break;
3363 case COMPONENT_Z:
3364 state_tokens[2] = STATE_TEXGEN_OBJECT_R;
3365 break;
3366 case COMPONENT_W:
3367 state_tokens[2] = STATE_TEXGEN_OBJECT_Q;
3368 break;
3369 }
3370 }
3371 }
3372 break;
3373
3374 case STATE_DEPTH:
3375 switch (*(*inst)++) {
3376 case DEPTH_RANGE:
3377 state_tokens[0] = STATE_DEPTH_RANGE;
3378 break;
3379 }
3380 break;
3381
3382 case STATE_CLIP_PLANE:
3383 state_tokens[0] = STATE_CLIPPLANE;
3384 state_tokens[1] = parse_integer (inst, Program);
3385 if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1]))
3386 return 1;
3387 break;
3388
3389 case STATE_POINT:
3390 switch (*(*inst++)) {
3391 case POINT_SIZE:
3392 state_tokens[0] = STATE_POINT_SIZE;
3393 break;
3394
3395 case POINT_ATTENUATION:
3396 state_tokens[0] = STATE_POINT_ATTENUATION;
3397 break;
3398 }
3399 break;
3400
3401 /* XXX: I think this is the correct format for a matrix row */
3402 case STATE_MATRIX_ROWS:
3403 state_tokens[0] = STATE_MATRIX;
3404
3405 if (parse_matrix
3406 (ctx, inst, Program, &state_tokens[1], &state_tokens[2],
3407 &state_tokens[5]))
3408 return 1;
3409
3410 state_tokens[3] = parse_integer (inst, Program); /* The first row to grab */
3411
3412 state_tokens[4] = parse_integer (inst, Program); /* Either the last row, 0 */
3413 if (state_tokens[4] == 0) {
3414 state_tokens[4] = state_tokens[3];
3415 }
3416 break;
3417 }
3418
3419 return 0;
3420 }
3421
3422 /**
3423 * This parses a state string (rather, the binary version of it) into
3424 * a 6-token similar for the state fetching code in program.c
3425 *
3426 * One might ask, why fetch these parameters into just like you fetch
3427 * state when they are already stored in other places?
3428 *
3429 * Because of array offsets -> We can stick env/local parameters in the
3430 * middle of a parameter array and then index someplace into the array
3431 * when we execute.
3432 *
3433 * One optimization might be to only do this for the cases where the
3434 * env/local parameters end up inside of an array, and leave the
3435 * single parameters (or arrays of pure env/local pareameters) in their
3436 * respective register files.
3437 *
3438 * For ENV parameters, the format is:
3439 * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
3440 * state_tokens[1] = STATE_ENV
3441 * state_tokens[2] = the parameter index
3442 *
3443 * for LOCAL parameters, the format is:
3444 * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
3445 * state_tokens[1] = STATE_LOCAL
3446 * state_tokens[2] = the parameter index
3447 *
3448 * \param inst - the start in the binary arry to start working from
3449 * \param state_tokens - the storage for the 6-token state description
3450 * \return - 0 on sucess, 1 on failure
3451 */
3452 static GLuint
3453 parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
3454 struct arb_program *Program, GLint * state_tokens)
3455 {
3456 if (Program->type == GL_FRAGMENT_PROGRAM_ARB)
3457 state_tokens[0] = STATE_FRAGMENT_PROGRAM;
3458 else
3459 state_tokens[0] = STATE_VERTEX_PROGRAM;
3460
3461
3462 switch (*(*inst)++) {
3463 case PROGRAM_PARAM_ENV:
3464 state_tokens[1] = STATE_ENV;
3465 state_tokens[2] = parse_integer (inst, Program);
3466
3467 /* Check state_tokens[2] against the number of ENV parameters available */
3468 if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
3469 (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramEnvParams))
3470 ||
3471 ((Program->type == GL_VERTEX_PROGRAM_ARB) &&
3472 (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramEnvParams))) {
3473 _mesa_set_program_error (ctx, Program->Position,
3474 "Invalid Program Env Parameter");
3475 _mesa_error (ctx, GL_INVALID_OPERATION,
3476 "Invalid Program Env Parameter: %d",
3477 state_tokens[2]);
3478 return 1;
3479 }
3480
3481 break;
3482
3483 case PROGRAM_PARAM_LOCAL:
3484 state_tokens[1] = STATE_LOCAL;
3485 state_tokens[2] = parse_integer (inst, Program);
3486
3487 /* Check state_tokens[2] against the number of LOCAL parameters available */
3488 if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
3489 (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramLocalParams))
3490 ||
3491 ((Program->type == GL_VERTEX_PROGRAM_ARB) &&
3492 (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramLocalParams))) {
3493 _mesa_set_program_error (ctx, Program->Position,
3494 "Invalid Program Local Parameter");
3495 _mesa_error (ctx, GL_INVALID_OPERATION,
3496 "Invalid Program Local Parameter: %d",
3497 state_tokens[2]);
3498 return 1;
3499 }
3500 break;
3501 }
3502
3503 return 0;
3504 }
3505
3506 /**
3507 * For ARB_vertex_program, programs are not allowed to use both an explicit
3508 * vertex attribute and a generic vertex attribute corresponding to the same
3509 * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec.
3510 *
3511 * This will walk our var_cache and make sure that nobody does anything fishy.
3512 *
3513 * \return 0 on sucess, 1 on error
3514 */
3515 static GLuint
3516 generic_attrib_check(struct var_cache *vc_head)
3517 {
3518 int a;
3519 struct var_cache *curr;
3520 GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS],
3521 genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS];
3522
3523 for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
3524 explicitAttrib[a] = GL_FALSE;
3525 genericAttrib[a] = GL_FALSE;
3526 }
3527
3528 curr = vc_head;
3529 while (curr) {
3530 if (curr->type == vt_attrib) {
3531 if (curr->attrib_is_generic)
3532 genericAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
3533 else
3534 explicitAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
3535 }
3536
3537 curr = curr->next;
3538 }
3539
3540 for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
3541 if ((explicitAttrib[a]) && (genericAttrib[a]))
3542 return 1;
3543 }
3544
3545 return 0;
3546 }
3547
3548 /**
3549 * This will handle the binding side of an ATTRIB var declaration
3550 *
3551 * \param binding - the fragment input register state, defined in nvfragprog.h
3552 * \param binding_idx - the index in the attrib register file that binding is associated with
3553 * \return returns 0 on sucess, 1 on error
3554 *
3555 * See nvfragparse.c for attrib register file layout
3556 */
3557 static GLuint
3558 parse_attrib_binding (GLcontext * ctx, GLubyte ** inst,
3559 struct arb_program *Program, GLuint * binding,
3560 GLuint * binding_idx, GLuint *is_generic)
3561 {
3562 GLuint texcoord;
3563 GLint coord;
3564 GLint err = 0;
3565
3566 *is_generic = 0;
3567 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
3568 switch (*(*inst)++) {
3569 case FRAGMENT_ATTRIB_COLOR:
3570 err = parse_color_type (ctx, inst, Program, &coord);
3571 *binding = FRAG_ATTRIB_COL0 + coord;
3572 *binding_idx = 1 + coord;
3573 break;
3574
3575 case FRAGMENT_ATTRIB_TEXCOORD:
3576 err = parse_texcoord_num (ctx, inst, Program, &texcoord);
3577 *binding = FRAG_ATTRIB_TEX0 + texcoord;
3578 *binding_idx = 4 + texcoord;
3579 break;
3580
3581 case FRAGMENT_ATTRIB_FOGCOORD:
3582 *binding = FRAG_ATTRIB_FOGC;
3583 *binding_idx = 3;
3584 break;
3585
3586 case FRAGMENT_ATTRIB_POSITION:
3587 *binding = FRAG_ATTRIB_WPOS;
3588 *binding_idx = 0;
3589 break;
3590
3591 default:
3592 err = 1;
3593 break;
3594 }
3595 }
3596 else {
3597 switch (*(*inst)++) {
3598 case VERTEX_ATTRIB_POSITION:
3599 *binding = VERT_ATTRIB_POS;
3600 *binding_idx = 0;
3601 break;
3602
3603 case VERTEX_ATTRIB_WEIGHT:
3604 {
3605 GLint weight;
3606
3607 err = parse_weight_num (ctx, inst, Program, &weight);
3608 *binding = VERT_ATTRIB_WEIGHT;
3609 *binding_idx = 1;
3610 }
3611 _mesa_set_program_error (ctx, Program->Position,
3612 "ARB_vertex_blend not supported\n");
3613 _mesa_error (ctx, GL_INVALID_OPERATION,
3614 "ARB_vertex_blend not supported\n");
3615 return 1;
3616 break;
3617
3618 case VERTEX_ATTRIB_NORMAL:
3619 *binding = VERT_ATTRIB_NORMAL;
3620 *binding_idx = 2;
3621 break;
3622
3623 case VERTEX_ATTRIB_COLOR:
3624 {
3625 GLint color;
3626
3627 err = parse_color_type (ctx, inst, Program, &color);
3628 if (color) {
3629 *binding = VERT_ATTRIB_COLOR1;
3630 *binding_idx = 4;
3631 }
3632 else {
3633 *binding = VERT_ATTRIB_COLOR0;
3634 *binding_idx = 3;
3635 }
3636 }
3637 break;
3638
3639 case VERTEX_ATTRIB_FOGCOORD:
3640 *binding = VERT_ATTRIB_FOG;
3641 *binding_idx = 5;
3642 break;
3643
3644 case VERTEX_ATTRIB_TEXCOORD:
3645 {
3646 GLuint unit;
3647
3648 err = parse_texcoord_num (ctx, inst, Program, &unit);
3649 *binding = VERT_ATTRIB_TEX0 + unit;
3650 *binding_idx = 8 + unit;
3651 }
3652 break;
3653
3654 /* It looks like we don't support this at all, atm */
3655 case VERTEX_ATTRIB_MATRIXINDEX:
3656 parse_integer (inst, Program);
3657 _mesa_set_program_error (ctx, Program->Position,
3658 "ARB_palette_matrix not supported");
3659 _mesa_error (ctx, GL_INVALID_OPERATION,
3660 "ARB_palette_matrix not supported");
3661 return 1;
3662 break;
3663
3664 case VERTEX_ATTRIB_GENERIC:
3665 {
3666 GLuint attrib;
3667
3668 if (!parse_generic_attrib_num(ctx, inst, Program, &attrib)) {
3669 *is_generic = 1;
3670 switch (attrib) {
3671 case 0:
3672 *binding = VERT_ATTRIB_POS;
3673 break;
3674 case 1:
3675 *binding = VERT_ATTRIB_WEIGHT;
3676 break;
3677 case 2:
3678 *binding = VERT_ATTRIB_NORMAL;
3679 break;
3680 case 3:
3681 *binding = VERT_ATTRIB_COLOR0;
3682 break;
3683 case 4:
3684 *binding = VERT_ATTRIB_COLOR1;
3685 break;
3686 case 5:
3687 *binding = VERT_ATTRIB_FOG;
3688 break;
3689 case 6:
3690 break;
3691 case 7:
3692 break;
3693 default:
3694 *binding = VERT_ATTRIB_TEX0 + (attrib-8);
3695 break;
3696 }
3697 *binding_idx = attrib;
3698 }
3699 }
3700 break;
3701
3702 default:
3703 err = 1;
3704 break;
3705 }
3706 }
3707
3708 /* Can this even happen? */
3709 if (err) {
3710 _mesa_set_program_error (ctx, Program->Position,
3711 "Bad attribute binding");
3712 _mesa_error (ctx, GL_INVALID_OPERATION, "Bad attribute binding");
3713 }
3714
3715 Program->InputsRead |= (1 << *binding_idx);
3716
3717 return err;
3718 }
3719
3720 /**
3721 * This translates between a binary token for an output variable type
3722 * and the mesa token for the same thing.
3723 *
3724 *
3725 * XXX: What is the 'name' for vertex program state? -> do we need it?
3726 * I don't think we do;
3727 *
3728 * See nvfragprog.h for definitions
3729 *
3730 * \param inst - The parsed tokens
3731 * \param binding - The name of the state we are binding too
3732 * \param binding_idx - The index into the result register file that this is bound too
3733 *
3734 * See nvfragparse.c for the register file layout for fragment programs
3735 * See nvvertparse.c for the register file layout for vertex programs
3736 */
3737 static GLuint
3738 parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding,
3739 GLuint * binding_idx, struct arb_program *Program)
3740 {
3741 GLuint b;
3742
3743 switch (*(*inst)++) {
3744 case FRAGMENT_RESULT_COLOR:
3745 /* for frag programs, this is FRAGMENT_RESULT_COLOR */
3746 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
3747 *binding = FRAG_OUTPUT_COLR;
3748 *binding_idx = 0;
3749 }
3750 /* for vtx programs, this is VERTEX_RESULT_POSITION */
3751 else {
3752 *binding_idx = 0;
3753 }
3754 break;
3755
3756 case FRAGMENT_RESULT_DEPTH:
3757 /* for frag programs, this is FRAGMENT_RESULT_DEPTH */
3758 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
3759 *binding = FRAG_OUTPUT_DEPR;
3760 *binding_idx = 2;
3761 }
3762 /* for vtx programs, this is VERTEX_RESULT_COLOR */
3763 else {
3764 GLint color_type;
3765 GLuint face_type = parse_face_type(inst);
3766 GLint color_type_ret = parse_color_type(ctx, inst, Program, &color_type);
3767
3768 /* back face */
3769 if (face_type) {
3770 if (color_type_ret) return 1;
3771
3772 /* secondary color */
3773 if (color_type) {
3774 *binding_idx = 4;
3775 }
3776 /* primary color */
3777 else {
3778 *binding_idx = 3;
3779 }
3780 }
3781 /* front face */
3782 else {
3783 /* secondary color */
3784 if (color_type) {
3785 *binding_idx = 2;
3786 }
3787 /* primary color */
3788 else {
3789 *binding_idx = 1;
3790 }
3791 }
3792 }
3793 break;
3794
3795 case VERTEX_RESULT_FOGCOORD:
3796 *binding_idx = 5;
3797 break;
3798
3799 case VERTEX_RESULT_POINTSIZE:
3800 *binding_idx = 6;
3801 break;
3802
3803 case VERTEX_RESULT_TEXCOORD:
3804 if (parse_texcoord_num (ctx, inst, Program, &b))
3805 return 1;
3806 *binding_idx = 7 + b;
3807 break;
3808 }
3809
3810 Program->OutputsWritten |= (1 << *binding_idx);
3811
3812 return 0;
3813 }
3814
3815 /**
3816 * This handles the declaration of ATTRIB variables
3817 *
3818 * XXX: Still needs
3819 * parse_vert_attrib_binding(), or something like that
3820 *
3821 * \return 0 on sucess, 1 on error
3822 */
3823 static GLint
3824 parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
3825 struct arb_program *Program)
3826 {
3827 GLuint found;
3828 char *error_msg;
3829 struct var_cache *attrib_var;
3830
3831 attrib_var = parse_string (inst, vc_head, Program, &found);
3832 Program->Position = parse_position (inst);
3833 if (found) {
3834 error_msg = (char *)
3835 _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40);
3836 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
3837 attrib_var->name);
3838
3839 _mesa_set_program_error (ctx, Program->Position, error_msg);
3840 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
3841
3842 _mesa_free (error_msg);
3843 return 1;
3844 }
3845
3846 attrib_var->type = vt_attrib;
3847
3848 /* I think this is ok now - karl */
3849 /* XXX: */
3850 /*if (Program->type == GL_FRAGMENT_PROGRAM_ARB) */
3851 {
3852 if (parse_attrib_binding
3853 (ctx, inst, Program, &attrib_var->attrib_binding,
3854 &attrib_var->attrib_binding_idx, &attrib_var->attrib_is_generic))
3855 return 1;
3856 if (generic_attrib_check(*vc_head)) {
3857 _mesa_set_program_error (ctx, Program->Position,
3858 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
3859 _mesa_error (ctx, GL_INVALID_OPERATION,
3860 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
3861 return 1;
3862 }
3863
3864 }
3865
3866 Program->Base.NumAttributes++;
3867 return 0;
3868 }
3869
3870 /**
3871 * \param use -- TRUE if we're called when declaring implicit parameters,
3872 * FALSE if we're declaraing variables. This has to do with
3873 * if we get a signed or unsigned float for scalar constants
3874 */
3875 static GLuint
3876 parse_param_elements (GLcontext * ctx, GLubyte ** inst,
3877 struct var_cache *param_var,
3878 struct arb_program *Program, GLboolean use)
3879 {
3880 GLint idx;
3881 GLuint err;
3882 GLint state_tokens[6];
3883 GLfloat const_values[4];
3884
3885 err = 0;
3886
3887 switch (*(*inst)++) {
3888 case PARAM_STATE_ELEMENT:
3889
3890 if (parse_state_single_item (ctx, inst, Program, state_tokens))
3891 return 1;
3892
3893 /* If we adding STATE_MATRIX that has multiple rows, we need to
3894 * unroll it and call _mesa_add_state_reference() for each row
3895 */
3896 if ((state_tokens[0] == STATE_MATRIX)
3897 && (state_tokens[3] != state_tokens[4])) {
3898 GLint row;
3899 GLint first_row = state_tokens[3];
3900 GLint last_row = state_tokens[4];
3901
3902 for (row = first_row; row <= last_row; row++) {
3903 state_tokens[3] = state_tokens[4] = row;
3904
3905 idx =
3906 _mesa_add_state_reference (Program->Parameters,
3907 state_tokens);
3908 if (param_var->param_binding_begin == ~0U)
3909 param_var->param_binding_begin = idx;
3910 param_var->param_binding_length++;
3911 Program->Base.NumParameters++;
3912 }
3913 }
3914 else {
3915 idx =
3916 _mesa_add_state_reference (Program->Parameters, state_tokens);
3917 if (param_var->param_binding_begin == ~0U)
3918 param_var->param_binding_begin = idx;
3919 param_var->param_binding_length++;
3920 Program->Base.NumParameters++;
3921 }
3922 break;
3923
3924 case PARAM_PROGRAM_ELEMENT:
3925
3926 if (parse_program_single_item (ctx, inst, Program, state_tokens))
3927 return 1;
3928 idx = _mesa_add_state_reference (Program->Parameters, state_tokens);
3929 if (param_var->param_binding_begin == ~0U)
3930 param_var->param_binding_begin = idx;
3931 param_var->param_binding_length++;
3932 Program->Base.NumParameters++;
3933
3934 /* Check if there is more: 0 -> we're done, else its an integer */
3935 if (**inst) {
3936 GLuint out_of_range, new_idx;
3937 GLuint start_idx = state_tokens[2] + 1;
3938 GLuint end_idx = parse_integer (inst, Program);
3939
3940 out_of_range = 0;
3941 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
3942 if (((state_tokens[1] == STATE_ENV)
3943 && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams))
3944 || ((state_tokens[1] == STATE_LOCAL)
3945 && (end_idx >=
3946 ctx->Const.MaxFragmentProgramLocalParams)))
3947 out_of_range = 1;
3948 }
3949 else {
3950 if (((state_tokens[1] == STATE_ENV)
3951 && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams))
3952 || ((state_tokens[1] == STATE_LOCAL)
3953 && (end_idx >=
3954 ctx->Const.MaxFragmentProgramLocalParams)))
3955 out_of_range = 1;
3956 }
3957 if (out_of_range) {
3958 _mesa_set_program_error (ctx, Program->Position,
3959 "Invalid Program Parameter");
3960 _mesa_error (ctx, GL_INVALID_OPERATION,
3961 "Invalid Program Parameter: %d", end_idx);
3962 return 1;
3963 }
3964
3965 for (new_idx = start_idx; new_idx <= end_idx; new_idx++) {
3966 state_tokens[2] = new_idx;
3967 idx =
3968 _mesa_add_state_reference (Program->Parameters,
3969 state_tokens);
3970 param_var->param_binding_length++;
3971 Program->Base.NumParameters++;
3972 }
3973 }
3974 else
3975 {
3976 (*inst)++;
3977 }
3978 break;
3979
3980 case PARAM_CONSTANT:
3981 parse_constant (inst, const_values, Program, use);
3982 idx =
3983 _mesa_add_named_constant (Program->Parameters,
3984 (char *) param_var->name, const_values);
3985 if (param_var->param_binding_begin == ~0U)
3986 param_var->param_binding_begin = idx;
3987 param_var->param_binding_length++;
3988 Program->Base.NumParameters++;
3989 break;
3990
3991 default:
3992 _mesa_set_program_error (ctx, Program->Position,
3993 "Unexpected token in parse_param_elements()");
3994 _mesa_error (ctx, GL_INVALID_OPERATION,
3995 "Unexpected token in parse_param_elements()");
3996 return 1;
3997 }
3998
3999 /* Make sure we haven't blown past our parameter limits */
4000 if (((Program->type == GL_VERTEX_PROGRAM_ARB) &&
4001 (Program->Base.NumParameters >=
4002 ctx->Const.MaxVertexProgramLocalParams))
4003 || ((Program->type == GL_FRAGMENT_PROGRAM_ARB)
4004 && (Program->Base.NumParameters >=
4005 ctx->Const.MaxFragmentProgramLocalParams))) {
4006 _mesa_set_program_error (ctx, Program->Position,
4007 "Too many parameter variables");
4008 _mesa_error (ctx, GL_INVALID_OPERATION, "Too many parameter variables");
4009 return 1;
4010 }
4011
4012 return err;
4013 }
4014
4015 /**
4016 * This picks out PARAM program parameter bindings.
4017 *
4018 * XXX: This needs to be stressed & tested
4019 *
4020 * \return 0 on sucess, 1 on error
4021 */
4022 static GLuint
4023 parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4024 struct arb_program *Program)
4025 {
4026 GLuint found, specified_length, err;
4027 char *error_msg;
4028 struct var_cache *param_var;
4029
4030 err = 0;
4031 param_var = parse_string (inst, vc_head, Program, &found);
4032 Program->Position = parse_position (inst);
4033
4034 if (found) {
4035 error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
4036 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4037 param_var->name);
4038
4039 _mesa_set_program_error (ctx, Program->Position, error_msg);
4040 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4041
4042 _mesa_free (error_msg);
4043 return 1;
4044 }
4045
4046 specified_length = parse_integer (inst, Program);
4047
4048 if (specified_length < 0) {
4049 _mesa_set_program_error (ctx, Program->Position,
4050 "Negative parameter array length");
4051 _mesa_error (ctx, GL_INVALID_OPERATION,
4052 "Negative parameter array length: %d", specified_length);
4053 return 1;
4054 }
4055
4056 param_var->type = vt_param;
4057 param_var->param_binding_length = 0;
4058
4059 /* Right now, everything is shoved into the main state register file.
4060 *
4061 * In the future, it would be nice to leave things ENV/LOCAL params
4062 * in their respective register files, if possible
4063 */
4064 param_var->param_binding_type = PROGRAM_STATE_VAR;
4065
4066 /* Remember to:
4067 * * - add each guy to the parameter list
4068 * * - increment the param_var->param_binding_len
4069 * * - store the param_var->param_binding_begin for the first one
4070 * * - compare the actual len to the specified len at the end
4071 */
4072 while (**inst != PARAM_NULL) {
4073 if (parse_param_elements (ctx, inst, param_var, Program, GL_FALSE))
4074 return 1;
4075 }
4076
4077 /* Test array length here! */
4078 if (specified_length) {
4079 if (specified_length != param_var->param_binding_length) {
4080 _mesa_set_program_error (ctx, Program->Position,
4081 "Declared parameter array lenght does not match parameter list");
4082 _mesa_error (ctx, GL_INVALID_OPERATION,
4083 "Declared parameter array lenght does not match parameter list");
4084 }
4085 }
4086
4087 (*inst)++;
4088
4089 return 0;
4090 }
4091
4092 /**
4093 *
4094 */
4095 static GLuint
4096 parse_param_use (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4097 struct arb_program *Program, struct var_cache **new_var)
4098 {
4099 struct var_cache *param_var;
4100
4101 /* First, insert a dummy entry into the var_cache */
4102 var_cache_create (&param_var);
4103 param_var->name = (GLubyte *) _mesa_strdup (" ");
4104 param_var->type = vt_param;
4105
4106 param_var->param_binding_length = 0;
4107 /* Don't fill in binding_begin; We use the default value of -1
4108 * to tell if its already initialized, elsewhere.
4109 *
4110 * param_var->param_binding_begin = 0;
4111 */
4112 param_var->param_binding_type = PROGRAM_STATE_VAR;
4113
4114 var_cache_append (vc_head, param_var);
4115
4116 /* Then fill it with juicy parameter goodness */
4117 if (parse_param_elements (ctx, inst, param_var, Program, GL_TRUE))
4118 return 1;
4119
4120 *new_var = param_var;
4121
4122 return 0;
4123 }
4124
4125
4126 /**
4127 * This handles the declaration of TEMP variables
4128 *
4129 * \return 0 on sucess, 1 on error
4130 */
4131 static GLuint
4132 parse_temp (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4133 struct arb_program *Program)
4134 {
4135 GLuint found;
4136 struct var_cache *temp_var;
4137 char *error_msg;
4138
4139 while (**inst != 0) {
4140 temp_var = parse_string (inst, vc_head, Program, &found);
4141 Program->Position = parse_position (inst);
4142 if (found) {
4143 error_msg = (char *)
4144 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
4145 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4146 temp_var->name);
4147
4148 _mesa_set_program_error (ctx, Program->Position, error_msg);
4149 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4150
4151 _mesa_free (error_msg);
4152 return 1;
4153 }
4154
4155 temp_var->type = vt_temp;
4156
4157 if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
4158 (Program->Base.NumTemporaries >=
4159 ctx->Const.MaxFragmentProgramTemps))
4160 || ((Program->type == GL_VERTEX_PROGRAM_ARB)
4161 && (Program->Base.NumTemporaries >=
4162 ctx->Const.MaxVertexProgramTemps))) {
4163 _mesa_set_program_error (ctx, Program->Position,
4164 "Too many TEMP variables declared");
4165 _mesa_error (ctx, GL_INVALID_OPERATION,
4166 "Too many TEMP variables declared");
4167 return 1;
4168 }
4169
4170 temp_var->temp_binding = Program->Base.NumTemporaries;
4171 Program->Base.NumTemporaries++;
4172 }
4173 (*inst)++;
4174
4175 return 0;
4176 }
4177
4178 /**
4179 * This handles variables of the OUTPUT variety
4180 *
4181 * \return 0 on sucess, 1 on error
4182 */
4183 static GLuint
4184 parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4185 struct arb_program *Program)
4186 {
4187 GLuint found;
4188 struct var_cache *output_var;
4189
4190 output_var = parse_string (inst, vc_head, Program, &found);
4191 Program->Position = parse_position (inst);
4192 if (found) {
4193 char *error_msg;
4194 error_msg = (char *)
4195 _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);
4196 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4197 output_var->name);
4198
4199 _mesa_set_program_error (ctx, Program->Position, error_msg);
4200 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4201
4202 _mesa_free (error_msg);
4203 return 1;
4204 }
4205
4206 output_var->type = vt_output;
4207 return parse_result_binding (ctx, inst, &output_var->output_binding,
4208 &output_var->output_binding_idx, Program);
4209 }
4210
4211 /**
4212 * This handles variables of the ALIAS kind
4213 *
4214 * \return 0 on sucess, 1 on error
4215 */
4216 static GLuint
4217 parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4218 struct arb_program *Program)
4219 {
4220 GLuint found;
4221 struct var_cache *temp_var;
4222 char *error_msg;
4223
4224
4225 temp_var = parse_string (inst, vc_head, Program, &found);
4226 Program->Position = parse_position (inst);
4227
4228 if (found) {
4229 error_msg = (char *)
4230 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
4231 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4232 temp_var->name);
4233
4234 _mesa_set_program_error (ctx, Program->Position, error_msg);
4235 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4236
4237 _mesa_free (error_msg);
4238 return 1;
4239 }
4240
4241 temp_var->type = vt_alias;
4242 temp_var->alias_binding = parse_string (inst, vc_head, Program, &found);
4243 Program->Position = parse_position (inst);
4244
4245 if (!found)
4246 {
4247 error_msg = (char *)
4248 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
4249 _mesa_sprintf (error_msg, "Alias value %s is not defined",
4250 temp_var->alias_binding->name);
4251
4252 _mesa_set_program_error (ctx, Program->Position, error_msg);
4253 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4254
4255 _mesa_free (error_msg);
4256 return 1;
4257 }
4258
4259 return 0;
4260 }
4261
4262 /**
4263 * This handles variables of the ADDRESS kind
4264 *
4265 * \return 0 on sucess, 1 on error
4266 */
4267 static GLuint
4268 parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4269 struct arb_program *Program)
4270 {
4271 GLuint found;
4272 struct var_cache *temp_var;
4273 char *error_msg;
4274
4275 while (**inst != 0) {
4276 temp_var = parse_string (inst, vc_head, Program, &found);
4277 Program->Position = parse_position (inst);
4278 if (found) {
4279 error_msg = (char *)
4280 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
4281 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
4282 temp_var->name);
4283
4284 _mesa_set_program_error (ctx, Program->Position, error_msg);
4285 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
4286
4287 _mesa_free (error_msg);
4288 return 1;
4289 }
4290
4291 temp_var->type = vt_address;
4292
4293 if (Program->Base.NumAddressRegs >=
4294 ctx->Const.MaxVertexProgramAddressRegs) {
4295 _mesa_set_program_error (ctx, Program->Position,
4296 "Too many ADDRESS variables declared");
4297 _mesa_error (ctx, GL_INVALID_OPERATION,
4298 "Too many ADDRESS variables declared");
4299 return 1;
4300 }
4301
4302 temp_var->address_binding = Program->Base.NumAddressRegs;
4303 Program->Base.NumAddressRegs++;
4304 }
4305 (*inst)++;
4306
4307 return 0;
4308 }
4309
4310 /**
4311 * Parse a program declaration
4312 *
4313 * \return 0 on sucess, 1 on error
4314 */
4315 static GLint
4316 parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4317 struct arb_program *Program)
4318 {
4319 GLint err = 0;
4320
4321 switch (*(*inst)++) {
4322 case ADDRESS:
4323 err = parse_address (ctx, inst, vc_head, Program);
4324 break;
4325
4326 case ALIAS:
4327 err = parse_alias (ctx, inst, vc_head, Program);
4328 break;
4329
4330 case ATTRIB:
4331 err = parse_attrib (ctx, inst, vc_head, Program);
4332 break;
4333
4334 case OUTPUT:
4335 err = parse_output (ctx, inst, vc_head, Program);
4336 break;
4337
4338 case PARAM:
4339 err = parse_param (ctx, inst, vc_head, Program);
4340 break;
4341
4342 case TEMP:
4343 err = parse_temp (ctx, inst, vc_head, Program);
4344 break;
4345 }
4346
4347 return err;
4348 }
4349
4350 /**
4351 * Handle the parsing out of a masked destination register
4352 *
4353 * \param File - The register file we write to
4354 * \param Index - The register index we write to
4355 * \param WriteMask - The mask controlling which components we write (1->write)
4356 *
4357 * \return 0 on sucess, 1 on error
4358 */
4359 static GLuint
4360 parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
4361 struct var_cache **vc_head, struct arb_program *Program,
4362 GLint * File, GLint * Index, GLboolean * WriteMask)
4363 {
4364 GLuint result;
4365 GLubyte mask;
4366 struct var_cache *dst;
4367
4368 /* We either have a result register specified, or a
4369 * variable that may or may not be writable
4370 */
4371 switch (*(*inst)++) {
4372 case REGISTER_RESULT:
4373 if (parse_result_binding
4374 (ctx, inst, &result, (GLuint *) Index, Program))
4375 return 1;
4376 *File = PROGRAM_OUTPUT;
4377 break;
4378
4379 case REGISTER_ESTABLISHED_NAME:
4380 dst = parse_string (inst, vc_head, Program, &result);
4381 Program->Position = parse_position (inst);
4382
4383 /* If the name has never been added to our symbol table, we're hosed */
4384 if (!result) {
4385 _mesa_set_program_error (ctx, Program->Position,
4386 "0: Undefined variable");
4387 _mesa_error (ctx, GL_INVALID_OPERATION, "0: Undefined variable: %s",
4388 dst->name);
4389 return 1;
4390 }
4391
4392 switch (dst->type) {
4393 case vt_output:
4394 *File = PROGRAM_OUTPUT;
4395 *Index = dst->output_binding_idx;
4396 break;
4397
4398 case vt_temp:
4399 *File = PROGRAM_TEMPORARY;
4400 *Index = dst->temp_binding;
4401 break;
4402
4403 /* If the var type is not vt_output or vt_temp, no go */
4404 default:
4405 _mesa_set_program_error (ctx, Program->Position,
4406 "Destination register is read only");
4407 _mesa_error (ctx, GL_INVALID_OPERATION,
4408 "Destination register is read only: %s",
4409 dst->name);
4410 return 1;
4411 }
4412 break;
4413
4414 default:
4415 _mesa_set_program_error (ctx, Program->Position,
4416 "Unexpected opcode in parse_masked_dst_reg()");
4417 _mesa_error (ctx, GL_INVALID_OPERATION,
4418 "Unexpected opcode in parse_masked_dst_reg()");
4419 return 1;
4420 }
4421
4422 /* And then the mask.
4423 * w,a -> bit 0
4424 * z,b -> bit 1
4425 * y,g -> bit 2
4426 * x,r -> bit 3
4427 */
4428 mask = *(*inst)++;
4429
4430 WriteMask[0] = (mask & (1 << 3)) >> 3;
4431 WriteMask[1] = (mask & (1 << 2)) >> 2;
4432 WriteMask[2] = (mask & (1 << 1)) >> 1;
4433 WriteMask[3] = (mask & (1));
4434
4435 return 0;
4436 }
4437
4438 /**
4439 * Handle the parsing out of a masked address register
4440 *
4441 * \param Index - The register index we write to
4442 * \param WriteMask - The mask controlling which components we write (1->write)
4443 *
4444 * \return 0 on sucess, 1 on error
4445 */
4446 static GLuint
4447 parse_masked_address_reg (GLcontext * ctx, GLubyte ** inst,
4448 struct var_cache **vc_head,
4449 struct arb_program *Program, GLint * Index,
4450 GLboolean * WriteMask)
4451 {
4452 struct var_cache *dst;
4453 GLuint result;
4454
4455 dst = parse_string (inst, vc_head, Program, &result);
4456 Program->Position = parse_position (inst);
4457
4458 /* If the name has never been added to our symbol table, we're hosed */
4459 if (!result) {
4460 _mesa_set_program_error (ctx, Program->Position, "1: Undefined variable");
4461 _mesa_error (ctx, GL_INVALID_OPERATION, "1: Undefined variable: %s",
4462 dst->name);
4463 return 1;
4464 }
4465
4466 if (dst->type != vt_address) {
4467 _mesa_set_program_error (ctx, Program->Position,
4468 "Variable is not of type ADDRESS");
4469 _mesa_error (ctx, GL_INVALID_OPERATION,
4470 "Variable: %s is not of type ADDRESS", dst->name);
4471 return 1;
4472 }
4473
4474 /* Writemask of .x is implied */
4475 WriteMask[0] = 1;
4476 WriteMask[1] = WriteMask[2] = WriteMask[3] = 0;
4477
4478 return 0;
4479 }
4480
4481 /**
4482 * Parse out a swizzle mask.
4483 *
4484 * The values in the input stream are:
4485 * COMPONENT_X -> x/r
4486 * COMPONENT_Y -> y/g
4487 * COMPONENT_Z-> z/b
4488 * COMPONENT_W-> w/a
4489 *
4490 * The values in the output mask are:
4491 * 0 -> x/r
4492 * 1 -> y/g
4493 * 2 -> z/b
4494 * 3 -> w/a
4495 *
4496 * The len parameter allows us to grab 4 components for a vector
4497 * swizzle, or just 1 component for a scalar src register selection
4498 */
4499 static GLuint
4500 parse_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLint len)
4501 {
4502 GLint a;
4503
4504 for (a = 0; a < 4; a++)
4505 mask[a] = a;
4506
4507 for (a = 0; a < len; a++) {
4508 switch (*(*inst)++) {
4509 case COMPONENT_X:
4510 mask[a] = 0;
4511 break;
4512
4513 case COMPONENT_Y:
4514 mask[a] = 1;
4515 break;
4516
4517 case COMPONENT_Z:
4518 mask[a] = 2;
4519 break;
4520
4521 case COMPONENT_W:
4522 mask[a] = 3;
4523 break;
4524 }
4525 }
4526
4527 return 0;
4528 }
4529
4530 /**
4531 */
4532 static GLuint
4533 parse_extended_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLboolean * Negate)
4534 {
4535 GLint a;
4536 GLubyte swz;
4537
4538 *Negate = GL_FALSE;
4539 for (a = 0; a < 4; a++) {
4540 if (parse_sign (inst))
4541 *Negate = GL_TRUE;
4542
4543 swz = *(*inst)++;
4544
4545 switch (swz) {
4546 case COMPONENT_0:
4547 mask[a] = SWIZZLE_ZERO;
4548 break;
4549 case COMPONENT_1:
4550 mask[a] = SWIZZLE_ONE;
4551 break;
4552 case COMPONENT_X:
4553 mask[a] = 0;
4554 break;
4555 case COMPONENT_Y:
4556 mask[a] = 1;
4557 break;
4558 case COMPONENT_Z:
4559 mask[a] = 2;
4560 break;
4561 case COMPONENT_W:
4562 mask[a] = 3;
4563 break;
4564
4565 }
4566 #if 0
4567 if (swz == 0)
4568 mask[a] = SWIZZLE_ZERO;
4569 else if (swz == 1)
4570 mask[a] = SWIZZLE_ONE;
4571 else
4572 mask[a] = swz - 2;
4573 #endif
4574
4575 }
4576
4577 return 0;
4578 }
4579
4580
4581 static GLuint
4582 parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
4583 struct arb_program *Program, GLint * File, GLint * Index)
4584 {
4585 struct var_cache *src;
4586 GLuint binding_state, binding_idx, is_generic, found, offset;
4587
4588 /* And the binding for the src */
4589 switch (*(*inst)++) {
4590 case REGISTER_ATTRIB:
4591 if (parse_attrib_binding
4592 (ctx, inst, Program, &binding_state, &binding_idx, &is_generic))
4593 return 1;
4594 *File = PROGRAM_INPUT;
4595 *Index = binding_idx;
4596
4597 /* We need to insert a dummy variable into the var_cache so we can
4598 * catch generic vertex attrib aliasing errors
4599 */
4600 var_cache_create(&src);
4601 src->type = vt_attrib;
4602 src->name = (GLubyte *)_mesa_strdup("Dummy Attrib Variable");
4603 src->attrib_binding = binding_state;
4604 src->attrib_binding_idx = binding_idx;
4605 src->attrib_is_generic = is_generic;
4606 var_cache_append(vc_head, src);
4607 if (generic_attrib_check(*vc_head)) {
4608 _mesa_set_program_error (ctx, Program->Position,
4609 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
4610 _mesa_error (ctx, GL_INVALID_OPERATION,
4611 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
4612 return 1;
4613 }
4614 break;
4615
4616 case REGISTER_PARAM:
4617 switch (**inst) {
4618 case PARAM_ARRAY_ELEMENT:
4619 (*inst)++;
4620 src = parse_string (inst, vc_head, Program, &found);
4621 Program->Position = parse_position (inst);
4622
4623 if (!found) {
4624 _mesa_set_program_error (ctx, Program->Position,
4625 "2: Undefined variable");
4626 _mesa_error (ctx, GL_INVALID_OPERATION,
4627 "2: Undefined variable: %s", src->name);
4628 return 1;
4629 }
4630
4631 *File = src->param_binding_type;
4632
4633 switch (*(*inst)++) {
4634 case ARRAY_INDEX_ABSOLUTE:
4635 offset = parse_integer (inst, Program);
4636
4637 if ((offset < 0)
4638 || (offset >= src->param_binding_length)) {
4639 _mesa_set_program_error (ctx, Program->Position,
4640 "Index out of range");
4641 _mesa_error (ctx, GL_INVALID_OPERATION,
4642 "Index %d out of range for %s", offset,
4643 src->name);
4644 return 1;
4645 }
4646
4647 *Index = src->param_binding_begin + offset;
4648 break;
4649
4650 /* XXX: */
4651 case ARRAY_INDEX_RELATIVE:
4652 break;
4653 }
4654 break;
4655
4656 default:
4657
4658 if (parse_param_use (ctx, inst, vc_head, Program, &src))
4659 return 1;
4660
4661 *File = src->param_binding_type;
4662 *Index = src->param_binding_begin;
4663 break;
4664 }
4665 break;
4666
4667 case REGISTER_ESTABLISHED_NAME:
4668
4669 src = parse_string (inst, vc_head, Program, &found);
4670 Program->Position = parse_position (inst);
4671
4672 /* If the name has never been added to our symbol table, we're hosed */
4673 if (!found) {
4674 _mesa_set_program_error (ctx, Program->Position,
4675 "3: Undefined variable");
4676 _mesa_error (ctx, GL_INVALID_OPERATION, "3: Undefined variable: %s",
4677 src->name);
4678 return 1;
4679 }
4680
4681 switch (src->type) {
4682 case vt_attrib:
4683 *File = PROGRAM_INPUT;
4684 *Index = src->attrib_binding_idx;
4685 break;
4686
4687 /* XXX: We have to handle offsets someplace in here! -- or are those above? */
4688 case vt_param:
4689 *File = src->param_binding_type;
4690 *Index = src->param_binding_begin;
4691 break;
4692
4693 case vt_temp:
4694 *File = PROGRAM_TEMPORARY;
4695 *Index = src->temp_binding;
4696 break;
4697
4698 /* If the var type is vt_output no go */
4699 default:
4700 _mesa_set_program_error (ctx, Program->Position,
4701 "destination register is read only");
4702 _mesa_error (ctx, GL_INVALID_OPERATION,
4703 "destination register is read only: %s",
4704 src->name);
4705 return 1;
4706 }
4707 break;
4708
4709 default:
4710 _mesa_set_program_error (ctx, Program->Position,
4711 "Unknown token in parse_src_reg");
4712 _mesa_error (ctx, GL_INVALID_OPERATION,
4713 "Unknown token in parse_src_reg");
4714 return 1;
4715 }
4716
4717 return 0;
4718 }
4719
4720 /**
4721 */
4722 static GLuint
4723 parse_vector_src_reg (GLcontext * ctx, GLubyte ** inst,
4724 struct var_cache **vc_head, struct arb_program *Program,
4725 GLint * File, GLint * Index, GLboolean * Negate,
4726 GLubyte * Swizzle)
4727 {
4728 /* Grab the sign */
4729 *Negate = parse_sign (inst);
4730
4731 /* And the src reg */
4732 if (parse_src_reg (ctx, inst, vc_head, Program, File, Index))
4733 return 1;
4734
4735 /* finally, the swizzle */
4736 parse_swizzle_mask (inst, Swizzle, 4);
4737
4738 return 0;
4739 }
4740
4741 /**
4742 */
4743 static GLuint
4744 parse_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
4745 struct var_cache **vc_head, struct arb_program *Program,
4746 GLint * File, GLint * Index, GLboolean * Negate,
4747 GLubyte * Swizzle)
4748 {
4749 /* Grab the sign */
4750 *Negate = parse_sign (inst);
4751
4752 /* And the src reg */
4753 if (parse_src_reg (ctx, inst, vc_head, Program, File, Index))
4754 return 1;
4755
4756 /* Now, get the component and shove it into all the swizzle slots */
4757 parse_swizzle_mask (inst, Swizzle, 1);
4758
4759 return 0;
4760 }
4761
4762 /**
4763 * This is a big mother that handles getting opcodes into the instruction
4764 * and handling the src & dst registers for fragment program instructions
4765 */
4766 static GLuint
4767 parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
4768 struct var_cache **vc_head, struct arb_program *Program,
4769 struct fp_instruction *fp)
4770 {
4771 GLint a, b;
4772 GLubyte swz[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */
4773 GLuint texcoord;
4774 GLubyte instClass, type, code;
4775
4776 /* No condition codes in ARB_fp */
4777 fp->UpdateCondRegister = 0;
4778
4779 /* Record the position in the program string for debugging */
4780 fp->StringPos = Program->Position;
4781
4782 /* F_ALU_INST or F_TEX_INST */
4783 instClass = *(*inst)++;
4784
4785 /* F_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ},
4786 * F_TEX_{SAMPLE, KIL}
4787 */
4788 type = *(*inst)++;
4789
4790 /* The actual opcode name */
4791 code = *(*inst)++;
4792
4793 /* Increment the correct count */
4794 switch (instClass) {
4795 case F_ALU_INST:
4796 Program->NumAluInstructions++;
4797 break;
4798 case F_TEX_INST:
4799 Program->NumTexInstructions++;
4800 break;
4801 }
4802
4803 fp->Saturate = 0;
4804 fp->Precision = FLOAT32;
4805
4806 fp->DstReg.CondMask = COND_TR;
4807
4808 switch (type) {
4809 case F_ALU_VECTOR:
4810 switch (code) {
4811 case F_ABS_SAT:
4812 fp->Saturate = 1;
4813 case F_ABS:
4814 fp->Opcode = FP_OPCODE_ABS;
4815 break;
4816
4817 case F_FLR_SAT:
4818 fp->Saturate = 1;
4819 case F_FLR:
4820 fp->Opcode = FP_OPCODE_FLR;
4821 break;
4822
4823 case F_FRC_SAT:
4824 fp->Saturate = 1;
4825 case F_FRC:
4826 fp->Opcode = FP_OPCODE_FRC;
4827 break;
4828
4829 case F_LIT_SAT:
4830 fp->Saturate = 1;
4831 case F_LIT:
4832 fp->Opcode = FP_OPCODE_LIT;
4833 break;
4834
4835 case F_MOV_SAT:
4836 fp->Saturate = 1;
4837 case F_MOV:
4838 fp->Opcode = FP_OPCODE_MOV;
4839 break;
4840 }
4841
4842 if (parse_masked_dst_reg
4843 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
4844 &fp->DstReg.Index, fp->DstReg.WriteMask))
4845 return 1;
4846
4847 fp->SrcReg[0].Abs = GL_FALSE;
4848 fp->SrcReg[0].NegateAbs = GL_FALSE;
4849 if (parse_vector_src_reg
4850 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
4851 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
4852 swz))
4853 return 1;
4854 for (b=0; b<4; b++)
4855 fp->SrcReg[0].Swizzle[b] = swz[b];
4856 break;
4857
4858 case F_ALU_SCALAR:
4859 switch (code) {
4860 case F_COS_SAT:
4861 fp->Saturate = 1;
4862 case F_COS:
4863 fp->Opcode = FP_OPCODE_COS;
4864 break;
4865
4866 case F_EX2_SAT:
4867 fp->Saturate = 1;
4868 case F_EX2:
4869 fp->Opcode = FP_OPCODE_EX2;
4870 break;
4871
4872 case F_LG2_SAT:
4873 fp->Saturate = 1;
4874 case F_LG2:
4875 fp->Opcode = FP_OPCODE_LG2;
4876 break;
4877
4878 case F_RCP_SAT:
4879 fp->Saturate = 1;
4880 case F_RCP:
4881 fp->Opcode = FP_OPCODE_RCP;
4882 break;
4883
4884 case F_RSQ_SAT:
4885 fp->Saturate = 1;
4886 case F_RSQ:
4887 fp->Opcode = FP_OPCODE_RSQ;
4888 break;
4889
4890 case F_SIN_SAT:
4891 fp->Saturate = 1;
4892 case F_SIN:
4893 fp->Opcode = FP_OPCODE_SIN;
4894 break;
4895
4896 case F_SCS_SAT:
4897 fp->Saturate = 1;
4898 case F_SCS:
4899 fp->Opcode = FP_OPCODE_SCS;
4900 break;
4901 }
4902
4903 if (parse_masked_dst_reg
4904 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
4905 &fp->DstReg.Index, fp->DstReg.WriteMask))
4906 return 1;
4907 fp->SrcReg[0].Abs = GL_FALSE;
4908 fp->SrcReg[0].NegateAbs = GL_FALSE;
4909 if (parse_scalar_src_reg
4910 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
4911 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
4912 swz))
4913 return 1;
4914 for (b=0; b<4; b++)
4915 fp->SrcReg[0].Swizzle[b] = swz[b];
4916 break;
4917
4918 case F_ALU_BINSC:
4919 switch (code) {
4920 case F_POW_SAT:
4921 fp->Saturate = 1;
4922 case F_POW:
4923 fp->Opcode = FP_OPCODE_POW;
4924 break;
4925 }
4926
4927 if (parse_masked_dst_reg
4928 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
4929 &fp->DstReg.Index, fp->DstReg.WriteMask))
4930 return 1;
4931 for (a = 0; a < 2; a++) {
4932 fp->SrcReg[a].Abs = GL_FALSE;
4933 fp->SrcReg[a].NegateAbs = GL_FALSE;
4934 if (parse_scalar_src_reg
4935 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
4936 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
4937 swz))
4938 return 1;
4939 for (b=0; b<4; b++)
4940 fp->SrcReg[a].Swizzle[b] = swz[b];
4941 }
4942 break;
4943
4944
4945 case F_ALU_BIN:
4946 switch (code) {
4947 case F_ADD_SAT:
4948 fp->Saturate = 1;
4949 case F_ADD:
4950 fp->Opcode = FP_OPCODE_ADD;
4951 break;
4952
4953 case F_DP3_SAT:
4954 fp->Saturate = 1;
4955 case F_DP3:
4956 fp->Opcode = FP_OPCODE_DP3;
4957 break;
4958
4959 case F_DP4_SAT:
4960 fp->Saturate = 1;
4961 case F_DP4:
4962 fp->Opcode = FP_OPCODE_DP4;
4963 break;
4964
4965 case F_DPH_SAT:
4966 fp->Saturate = 1;
4967 case F_DPH:
4968 fp->Opcode = FP_OPCODE_DPH;
4969 break;
4970
4971 case F_DST_SAT:
4972 fp->Saturate = 1;
4973 case F_DST:
4974 fp->Opcode = FP_OPCODE_DST;
4975 break;
4976
4977 case F_MAX_SAT:
4978 fp->Saturate = 1;
4979 case F_MAX:
4980 fp->Opcode = FP_OPCODE_MAX;
4981 break;
4982
4983 case F_MIN_SAT:
4984 fp->Saturate = 1;
4985 case F_MIN:
4986 fp->Opcode = FP_OPCODE_MIN;
4987 break;
4988
4989 case F_MUL_SAT:
4990 fp->Saturate = 1;
4991 case F_MUL:
4992 fp->Opcode = FP_OPCODE_MUL;
4993 break;
4994
4995 case F_SGE_SAT:
4996 fp->Saturate = 1;
4997 case F_SGE:
4998 fp->Opcode = FP_OPCODE_SGE;
4999 break;
5000
5001 case F_SLT_SAT:
5002 fp->Saturate = 1;
5003 case F_SLT:
5004 fp->Opcode = FP_OPCODE_SLT;
5005 break;
5006
5007 case F_SUB_SAT:
5008 fp->Saturate = 1;
5009 case F_SUB:
5010 fp->Opcode = FP_OPCODE_SUB;
5011 break;
5012
5013 case F_XPD_SAT:
5014 fp->Saturate = 1;
5015 case F_XPD:
5016 fp->Opcode = FP_OPCODE_X2D;
5017 break;
5018 }
5019
5020 if (parse_masked_dst_reg
5021 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
5022 &fp->DstReg.Index, fp->DstReg.WriteMask))
5023 return 1;
5024 for (a = 0; a < 2; a++) {
5025 fp->SrcReg[a].Abs = GL_FALSE;
5026 fp->SrcReg[a].NegateAbs = GL_FALSE;
5027 if (parse_vector_src_reg
5028 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
5029 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
5030 swz))
5031 return 1;
5032 for (b=0; b<4; b++)
5033 fp->SrcReg[a].Swizzle[b] = swz[b];
5034 }
5035 break;
5036
5037 case F_ALU_TRI:
5038 switch (code) {
5039 case F_CMP_SAT:
5040 fp->Saturate = 1;
5041 case F_CMP:
5042 fp->Opcode = FP_OPCODE_CMP;
5043 break;
5044
5045 case F_LRP_SAT:
5046 fp->Saturate = 1;
5047 case F_LRP:
5048 fp->Opcode = FP_OPCODE_LRP;
5049 break;
5050
5051 case F_MAD_SAT:
5052 fp->Saturate = 1;
5053 case F_MAD:
5054 fp->Opcode = FP_OPCODE_MAD;
5055 break;
5056 }
5057
5058 if (parse_masked_dst_reg
5059 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
5060 &fp->DstReg.Index, fp->DstReg.WriteMask))
5061 return 1;
5062 for (a = 0; a < 3; a++) {
5063 fp->SrcReg[a].Abs = GL_FALSE;
5064 fp->SrcReg[a].NegateAbs = GL_FALSE;
5065 if (parse_vector_src_reg
5066 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
5067 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
5068 swz))
5069 return 1;
5070 for (b=0; b<4; b++)
5071 fp->SrcReg[a].Swizzle[b] = swz[b];
5072 }
5073 break;
5074
5075 case F_ALU_SWZ:
5076 switch (code) {
5077 case F_SWZ_SAT:
5078 fp->Saturate = 1;
5079 case F_SWZ:
5080 fp->Opcode = FP_OPCODE_SWZ;
5081 break;
5082 }
5083 if (parse_masked_dst_reg
5084 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
5085 &fp->DstReg.Index, fp->DstReg.WriteMask))
5086 return 1;
5087
5088 if (parse_src_reg
5089 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
5090 &fp->SrcReg[0].Index))
5091 return 1;
5092 parse_extended_swizzle_mask (inst, swz,
5093 &fp->SrcReg[0].NegateBase);
5094 for (b=0; b<4; b++)
5095 fp->SrcReg[0].Swizzle[b] = swz[b];
5096 break;
5097
5098 case F_TEX_SAMPLE:
5099 switch (code) {
5100 case F_TEX_SAT:
5101 fp->Saturate = 1;
5102 case F_TEX:
5103 fp->Opcode = FP_OPCODE_TEX;
5104 break;
5105
5106 case F_TXP_SAT:
5107 fp->Saturate = 1;
5108 case F_TXP:
5109 fp->Opcode = FP_OPCODE_TXP;
5110 break;
5111
5112 case F_TXB_SAT:
5113 fp->Saturate = 1;
5114 case F_TXB:
5115 fp->Opcode = FP_OPCODE_TXB;
5116 break;
5117 }
5118
5119 if (parse_masked_dst_reg
5120 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
5121 &fp->DstReg.Index, fp->DstReg.WriteMask))
5122 return 1;
5123 fp->SrcReg[0].Abs = GL_FALSE;
5124 fp->SrcReg[0].NegateAbs = GL_FALSE;
5125 if (parse_vector_src_reg
5126 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
5127 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
5128 swz))
5129 return 1;
5130 for (b=0; b<4; b++)
5131 fp->SrcReg[0].Swizzle[b] = swz[b];
5132
5133 /* texImageUnit */
5134 if (parse_texcoord_num (ctx, inst, Program, &texcoord))
5135 return 1;
5136 fp->TexSrcUnit = texcoord;
5137
5138 /* texTarget */
5139 switch (*(*inst)++) {
5140 case TEXTARGET_1D:
5141 fp->TexSrcBit = TEXTURE_1D_BIT;
5142 break;
5143 case TEXTARGET_2D:
5144 fp->TexSrcBit = TEXTURE_2D_BIT;
5145 break;
5146 case TEXTARGET_3D:
5147 fp->TexSrcBit = TEXTURE_3D_BIT;
5148 break;
5149 case TEXTARGET_RECT:
5150 fp->TexSrcBit = TEXTURE_RECT_BIT;
5151 break;
5152 case TEXTARGET_CUBE:
5153 fp->TexSrcBit = TEXTURE_CUBE_BIT;
5154 break;
5155 }
5156 Program->TexturesUsed[texcoord] |= fp->TexSrcBit;
5157 break;
5158
5159 case F_TEX_KIL:
5160 fp->Opcode = FP_OPCODE_KIL;
5161 fp->SrcReg[0].Abs = GL_FALSE;
5162 fp->SrcReg[0].NegateAbs = GL_FALSE;
5163 if (parse_vector_src_reg
5164 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
5165 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
5166 swz))
5167 return 1;
5168 for (b=0; b<4; b++)
5169 fp->SrcReg[0].Swizzle[b] = swz[b];
5170 break;
5171 }
5172
5173 return 0;
5174 }
5175
5176 /**
5177 * This is a big mother that handles getting opcodes into the instruction
5178 * and handling the src & dst registers for vertex program instructions
5179 */
5180 static GLuint
5181 parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
5182 struct var_cache **vc_head, struct arb_program *Program,
5183 struct vp_instruction *vp)
5184 {
5185 GLint a;
5186 GLubyte type, code;
5187
5188 /* V_GEN_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */
5189 type = *(*inst)++;
5190
5191 /* The actual opcode name */
5192 code = *(*inst)++;
5193
5194 vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0;
5195
5196 for (a = 0; a < 4; a++) {
5197 vp->SrcReg[0].Swizzle[a] = a;
5198 vp->SrcReg[1].Swizzle[a] = a;
5199 vp->SrcReg[2].Swizzle[a] = a;
5200 vp->DstReg.WriteMask[a] = 1;
5201 }
5202
5203 switch (type) {
5204 /* XXX: */
5205 case V_GEN_ARL:
5206 vp->Opcode = VP_OPCODE_ARL;
5207
5208 /* Remember to set SrcReg.RelAddr; */
5209
5210 /* Get the masked address register [dst] */
5211 if (parse_masked_address_reg
5212 (ctx, inst, vc_head, Program, &vp->DstReg.Index,
5213 vp->DstReg.WriteMask))
5214 return 1;
5215 vp->DstReg.File = PROGRAM_ADDRESS;
5216
5217
5218 /* Get a scalar src register */
5219 if (parse_scalar_src_reg
5220 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
5221 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
5222 vp->SrcReg[0].Swizzle))
5223 return 1;
5224
5225 break;
5226
5227 case V_GEN_VECTOR:
5228 switch (code) {
5229 case V_ABS:
5230 vp->Opcode = VP_OPCODE_ABS;
5231 break;
5232 case V_FLR:
5233 vp->Opcode = VP_OPCODE_FLR;
5234 break;
5235 case V_FRC:
5236 vp->Opcode = VP_OPCODE_FRC;
5237 break;
5238 case V_LIT:
5239 vp->Opcode = VP_OPCODE_LIT;
5240 break;
5241 case V_MOV:
5242 vp->Opcode = VP_OPCODE_MOV;
5243 break;
5244 }
5245 if (parse_masked_dst_reg
5246 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5247 &vp->DstReg.Index, vp->DstReg.WriteMask))
5248 return 1;
5249 if (parse_vector_src_reg
5250 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
5251 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
5252 vp->SrcReg[0].Swizzle))
5253 return 1;
5254 break;
5255
5256 case V_GEN_SCALAR:
5257 switch (code) {
5258 case V_EX2:
5259 vp->Opcode = VP_OPCODE_EX2;
5260 break;
5261 case V_EXP:
5262 vp->Opcode = VP_OPCODE_EXP;
5263 break;
5264 case V_LG2:
5265 vp->Opcode = VP_OPCODE_LG2;
5266 break;
5267 case V_LOG:
5268 vp->Opcode = VP_OPCODE_LOG;
5269 break;
5270 case V_RCP:
5271 vp->Opcode = VP_OPCODE_RCP;
5272 break;
5273 case V_RSQ:
5274 vp->Opcode = VP_OPCODE_RSQ;
5275 break;
5276 }
5277 if (parse_masked_dst_reg
5278 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5279 &vp->DstReg.Index, vp->DstReg.WriteMask))
5280 return 1;
5281 if (parse_scalar_src_reg
5282 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
5283 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
5284 vp->SrcReg[0].Swizzle))
5285 return 1;
5286 break;
5287
5288 case V_GEN_BINSC:
5289 switch (code) {
5290 case V_POW:
5291 vp->Opcode = VP_OPCODE_POW;
5292 break;
5293 }
5294 if (parse_masked_dst_reg
5295 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5296 &vp->DstReg.Index, vp->DstReg.WriteMask))
5297 return 1;
5298 for (a = 0; a < 2; a++) {
5299 if (parse_scalar_src_reg
5300 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
5301 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
5302 vp->SrcReg[a].Swizzle))
5303 return 1;
5304 }
5305 break;
5306
5307 case V_GEN_BIN:
5308 switch (code) {
5309 case V_ADD:
5310 vp->Opcode = VP_OPCODE_ADD;
5311 break;
5312 case V_DP3:
5313 vp->Opcode = VP_OPCODE_DP3;
5314 break;
5315 case V_DP4:
5316 vp->Opcode = VP_OPCODE_DP4;
5317 break;
5318 case V_DPH:
5319 vp->Opcode = VP_OPCODE_DPH;
5320 break;
5321 case V_DST:
5322 vp->Opcode = VP_OPCODE_DST;
5323 break;
5324 case V_MAX:
5325 vp->Opcode = VP_OPCODE_MAX;
5326 break;
5327 case V_MIN:
5328 vp->Opcode = VP_OPCODE_MIN;
5329 break;
5330 case V_MUL:
5331 vp->Opcode = VP_OPCODE_MUL;
5332 break;
5333 case V_SGE:
5334 vp->Opcode = VP_OPCODE_SGE;
5335 break;
5336 case V_SLT:
5337 vp->Opcode = VP_OPCODE_SLT;
5338 break;
5339 case V_SUB:
5340 vp->Opcode = VP_OPCODE_SUB;
5341 break;
5342 case V_XPD:
5343 vp->Opcode = VP_OPCODE_XPD;
5344 break;
5345 }
5346 if (parse_masked_dst_reg
5347 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5348 &vp->DstReg.Index, vp->DstReg.WriteMask))
5349 return 1;
5350 for (a = 0; a < 2; a++) {
5351 if (parse_vector_src_reg
5352 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
5353 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
5354 vp->SrcReg[a].Swizzle))
5355 return 1;
5356 }
5357 break;
5358
5359 case V_GEN_TRI:
5360 switch (code) {
5361 case V_MAD:
5362 vp->Opcode = VP_OPCODE_MAD;
5363 break;
5364 }
5365
5366 if (parse_masked_dst_reg
5367 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5368 &vp->DstReg.Index, vp->DstReg.WriteMask))
5369 return 1;
5370 for (a = 0; a < 3; a++) {
5371 if (parse_vector_src_reg
5372 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
5373 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
5374 vp->SrcReg[a].Swizzle))
5375 return 1;
5376 }
5377 break;
5378
5379 case V_GEN_SWZ:
5380 switch (code) {
5381 case V_SWZ:
5382 vp->Opcode = VP_OPCODE_SWZ;
5383 break;
5384 }
5385 if (parse_masked_dst_reg
5386 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
5387 &vp->DstReg.Index, vp->DstReg.WriteMask))
5388 return 1;
5389
5390 if (parse_src_reg
5391 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
5392 &vp->SrcReg[0].Index))
5393 return 1;
5394 parse_extended_swizzle_mask (inst, vp->SrcReg[0].Swizzle,
5395 &vp->SrcReg[0].Negate);
5396 break;
5397 }
5398 return 0;
5399 }
5400
5401 #if DEBUG_PARSING
5402
5403 static GLvoid
5404 print_state_token (GLint token)
5405 {
5406 switch (token) {
5407 case STATE_MATERIAL:
5408 fprintf (stderr, "STATE_MATERIAL ");
5409 break;
5410 case STATE_LIGHT:
5411 fprintf (stderr, "STATE_LIGHT ");
5412 break;
5413
5414 case STATE_LIGHTMODEL_AMBIENT:
5415 fprintf (stderr, "STATE_AMBIENT ");
5416 break;
5417
5418 case STATE_LIGHTMODEL_SCENECOLOR:
5419 fprintf (stderr, "STATE_SCENECOLOR ");
5420 break;
5421
5422 case STATE_LIGHTPROD:
5423 fprintf (stderr, "STATE_LIGHTPROD ");
5424 break;
5425
5426 case STATE_TEXGEN:
5427 fprintf (stderr, "STATE_TEXGEN ");
5428 break;
5429
5430 case STATE_FOG_COLOR:
5431 fprintf (stderr, "STATE_FOG_COLOR ");
5432 break;
5433
5434 case STATE_FOG_PARAMS:
5435 fprintf (stderr, "STATE_FOG_PARAMS ");
5436 break;
5437
5438 case STATE_CLIPPLANE:
5439 fprintf (stderr, "STATE_CLIPPLANE ");
5440 break;
5441
5442 case STATE_POINT_SIZE:
5443 fprintf (stderr, "STATE_POINT_SIZE ");
5444 break;
5445
5446 case STATE_POINT_ATTENUATION:
5447 fprintf (stderr, "STATE_ATTENUATION ");
5448 break;
5449
5450 case STATE_MATRIX:
5451 fprintf (stderr, "STATE_MATRIX ");
5452 break;
5453
5454 case STATE_MODELVIEW:
5455 fprintf (stderr, "STATE_MODELVIEW ");
5456 break;
5457
5458 case STATE_PROJECTION:
5459 fprintf (stderr, "STATE_PROJECTION ");
5460 break;
5461
5462 case STATE_MVP:
5463 fprintf (stderr, "STATE_MVP ");
5464 break;
5465
5466 case STATE_TEXTURE:
5467 fprintf (stderr, "STATE_TEXTURE ");
5468 break;
5469
5470 case STATE_PROGRAM:
5471 fprintf (stderr, "STATE_PROGRAM ");
5472 break;
5473
5474 case STATE_MATRIX_INVERSE:
5475 fprintf (stderr, "STATE_INVERSE ");
5476 break;
5477
5478 case STATE_MATRIX_TRANSPOSE:
5479 fprintf (stderr, "STATE_TRANSPOSE ");
5480 break;
5481
5482 case STATE_MATRIX_INVTRANS:
5483 fprintf (stderr, "STATE_INVTRANS ");
5484 break;
5485
5486 case STATE_AMBIENT:
5487 fprintf (stderr, "STATE_AMBIENT ");
5488 break;
5489
5490 case STATE_DIFFUSE:
5491 fprintf (stderr, "STATE_DIFFUSE ");
5492 break;
5493
5494 case STATE_SPECULAR:
5495 fprintf (stderr, "STATE_SPECULAR ");
5496 break;
5497
5498 case STATE_EMISSION:
5499 fprintf (stderr, "STATE_EMISSION ");
5500 break;
5501
5502 case STATE_SHININESS:
5503 fprintf (stderr, "STATE_SHININESS ");
5504 break;
5505
5506 case STATE_HALF:
5507 fprintf (stderr, "STATE_HALF ");
5508 break;
5509
5510 case STATE_POSITION:
5511 fprintf (stderr, "STATE_POSITION ");
5512 break;
5513
5514 case STATE_ATTENUATION:
5515 fprintf (stderr, "STATE_ATTENUATION ");
5516 break;
5517
5518 case STATE_SPOT_DIRECTION:
5519 fprintf (stderr, "STATE_DIRECTION ");
5520 break;
5521
5522 case STATE_TEXGEN_EYE_S:
5523 fprintf (stderr, "STATE_TEXGEN_EYE_S ");
5524 break;
5525
5526 case STATE_TEXGEN_EYE_T:
5527 fprintf (stderr, "STATE_TEXGEN_EYE_T ");
5528 break;
5529
5530 case STATE_TEXGEN_EYE_R:
5531 fprintf (stderr, "STATE_TEXGEN_EYE_R ");
5532 break;
5533
5534 case STATE_TEXGEN_EYE_Q:
5535 fprintf (stderr, "STATE_TEXGEN_EYE_Q ");
5536 break;
5537
5538 case STATE_TEXGEN_OBJECT_S:
5539 fprintf (stderr, "STATE_TEXGEN_EYE_S ");
5540 break;
5541
5542 case STATE_TEXGEN_OBJECT_T:
5543 fprintf (stderr, "STATE_TEXGEN_OBJECT_T ");
5544 break;
5545
5546 case STATE_TEXGEN_OBJECT_R:
5547 fprintf (stderr, "STATE_TEXGEN_OBJECT_R ");
5548 break;
5549
5550 case STATE_TEXGEN_OBJECT_Q:
5551 fprintf (stderr, "STATE_TEXGEN_OBJECT_Q ");
5552 break;
5553
5554 case STATE_TEXENV_COLOR:
5555 fprintf (stderr, "STATE_TEXENV_COLOR ");
5556 break;
5557
5558 case STATE_DEPTH_RANGE:
5559 fprintf (stderr, "STATE_DEPTH_RANGE ");
5560 break;
5561
5562 case STATE_VERTEX_PROGRAM:
5563 fprintf (stderr, "STATE_VERTEX_PROGRAM ");
5564 break;
5565
5566 case STATE_FRAGMENT_PROGRAM:
5567 fprintf (stderr, "STATE_FRAGMENT_PROGRAM ");
5568 break;
5569
5570 case STATE_ENV:
5571 fprintf (stderr, "STATE_ENV ");
5572 break;
5573
5574 case STATE_LOCAL:
5575 fprintf (stderr, "STATE_LOCAL ");
5576 break;
5577
5578 }
5579 fprintf (stderr, "[%d] ", token);
5580 }
5581
5582
5583 static GLvoid
5584 debug_variables (GLcontext * ctx, struct var_cache *vc_head,
5585 struct arb_program *Program)
5586 {
5587 struct var_cache *vc;
5588 GLint a, b;
5589
5590 fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head);
5591
5592 /* First of all, print out the contents of the var_cache */
5593 vc = vc_head;
5594 while (vc) {
5595 fprintf (stderr, "[%x]\n", vc);
5596 switch (vc->type) {
5597 case vt_none:
5598 fprintf (stderr, "UNDEFINED %s\n", vc->name);
5599 break;
5600 case vt_attrib:
5601 fprintf (stderr, "ATTRIB %s\n", vc->name);
5602 fprintf (stderr, " binding: 0x%x\n", vc->attrib_binding);
5603 break;
5604 case vt_param:
5605 fprintf (stderr, "PARAM %s begin: %d len: %d\n", vc->name,
5606 vc->param_binding_begin, vc->param_binding_length);
5607 b = vc->param_binding_begin;
5608 for (a = 0; a < vc->param_binding_length; a++) {
5609 fprintf (stderr, "%s\n",
5610 Program->Parameters->Parameters[a + b].Name);
5611 if (Program->Parameters->Parameters[a + b].Type == STATE) {
5612 print_state_token (Program->Parameters->Parameters[a + b].
5613 StateIndexes[0]);
5614 print_state_token (Program->Parameters->Parameters[a + b].
5615 StateIndexes[1]);
5616 print_state_token (Program->Parameters->Parameters[a + b].
5617 StateIndexes[2]);
5618 print_state_token (Program->Parameters->Parameters[a + b].
5619 StateIndexes[3]);
5620 print_state_token (Program->Parameters->Parameters[a + b].
5621 StateIndexes[4]);
5622 print_state_token (Program->Parameters->Parameters[a + b].
5623 StateIndexes[5]);
5624 }
5625 else
5626 fprintf (stderr, "%f %f %f %f\n",
5627 Program->Parameters->Parameters[a + b].Values[0],
5628 Program->Parameters->Parameters[a + b].Values[1],
5629 Program->Parameters->Parameters[a + b].Values[2],
5630 Program->Parameters->Parameters[a + b].Values[3]);
5631 }
5632 break;
5633 case vt_temp:
5634 fprintf (stderr, "TEMP %s\n", vc->name);
5635 fprintf (stderr, " binding: 0x%x\n", vc->temp_binding);
5636 break;
5637 case vt_output:
5638 fprintf (stderr, "OUTPUT %s\n", vc->name);
5639 fprintf (stderr, " binding: 0x%x\n", vc->output_binding);
5640 break;
5641 case vt_alias:
5642 fprintf (stderr, "ALIAS %s\n", vc->name);
5643 fprintf (stderr, " binding: 0x%x (%s)\n",
5644 vc->alias_binding, vc->alias_binding->name);
5645 break;
5646 }
5647 vc = vc->next;
5648 }
5649 }
5650
5651 #endif
5652
5653
5654 /**
5655 * The main loop for parsing a fragment or vertex program
5656 *
5657 * \return 0 on sucess, 1 on error
5658 */
5659 static GLint
5660 parse_arb_program (GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
5661 struct arb_program *Program)
5662 {
5663 GLint err = 0;
5664
5665 Program->MajorVersion = (GLuint) * inst++;
5666 Program->MinorVersion = (GLuint) * inst++;
5667
5668 while (*inst != END) {
5669 switch (*inst++) {
5670
5671 case OPTION:
5672 switch (*inst++) {
5673 case ARB_PRECISION_HINT_FASTEST:
5674 Program->HintPrecisionFastest = 1;
5675 break;
5676
5677 case ARB_PRECISION_HINT_NICEST:
5678 Program->HintPrecisionNicest = 1;
5679 break;
5680
5681 case ARB_FOG_EXP:
5682 Program->HintFogExp = 1;
5683 break;
5684
5685 case ARB_FOG_EXP2:
5686 Program->HintFogExp2 = 1;
5687 break;
5688
5689 case ARB_FOG_LINEAR:
5690 Program->HintFogLinear = 1;
5691 break;
5692
5693 case ARB_POSITION_INVARIANT:
5694 Program->HintPositionInvariant = 1;
5695 break;
5696 }
5697 break;
5698
5699 case INSTRUCTION:
5700 Program->Position = parse_position (&inst);
5701
5702 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
5703 /* Realloc Program->FPInstructions */
5704 Program->FPInstructions =
5705 (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
5706 Program->Base.NumInstructions*sizeof(struct fp_instruction),
5707 (Program->Base.NumInstructions+1)*sizeof (struct fp_instruction));
5708
5709 /* parse the current instruction */
5710 err = parse_fp_instruction (ctx, &inst, vc_head, Program,
5711 &Program->FPInstructions[Program->Base.NumInstructions]);
5712
5713 }
5714 else {
5715 /* Realloc Program->VPInstructions */
5716 Program->VPInstructions =
5717 (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
5718 Program->Base.NumInstructions*sizeof(struct vp_instruction),
5719 (Program->Base.NumInstructions +1)*sizeof(struct vp_instruction));
5720
5721 /* parse the current instruction */
5722 err = parse_vp_instruction (ctx, &inst, vc_head, Program,
5723 &Program->VPInstructions[Program->Base.NumInstructions]);
5724 }
5725
5726 /* increment Program->Base.NumInstructions */
5727 Program->Base.NumInstructions++;
5728 break;
5729
5730 case DECLARATION:
5731 err = parse_declaration (ctx, &inst, vc_head, Program);
5732 break;
5733
5734 default:
5735 break;
5736 }
5737
5738 if (err)
5739 break;
5740 }
5741
5742 /* Finally, tag on an OPCODE_END instruction */
5743 if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
5744 Program->FPInstructions =
5745 (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
5746 Program->Base.NumInstructions*sizeof(struct fp_instruction),
5747 (Program->Base.NumInstructions+1)*sizeof(struct fp_instruction));
5748
5749 Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END;
5750 }
5751 else {
5752 Program->VPInstructions =
5753 (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
5754 Program->Base.NumInstructions*sizeof(struct vp_instruction),
5755 (Program->Base.NumInstructions+1)*sizeof(struct vp_instruction));
5756
5757 Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END;
5758 }
5759
5760 /* increment Program->Base.NumInstructions */
5761 Program->Base.NumInstructions++;
5762
5763 return err;
5764 }
5765
5766
5767 /**
5768 * This kicks everything off.
5769 *
5770 * \param ctx - The GL Context
5771 * \param str - The program string
5772 * \param len - The program string length
5773 * \param Program - The arb_program struct to return all the parsed info in
5774 * \return 0 on sucess, 1 on error
5775 */
5776 GLuint
5777 _mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len,
5778 struct arb_program * program)
5779 {
5780 GLint a, err, error_pos;
5781 char error_msg[300];
5782 GLuint parsed_len;
5783 struct var_cache *vc_head;
5784 dict *dt;
5785 GLubyte *parsed, *inst;
5786
5787 #if DEBUG_PARSING
5788 fprintf (stderr, "Loading grammar text!\n");
5789 #endif
5790 dt = grammar_load_from_text ((GLubyte *) arb_grammar_text);
5791 if (!dt) {
5792 grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
5793 _mesa_set_program_error (ctx, error_pos, error_msg);
5794 _mesa_error (ctx, GL_INVALID_OPERATION,
5795 "Error loading grammer rule set");
5796 return 1;
5797 }
5798
5799 #if DEBUG_PARSING
5800 printf ("Checking Grammar!\n");
5801 #endif
5802 err = grammar_check (dt, str, &parsed, &parsed_len);
5803
5804
5805 /* Syntax parse error */
5806 if (err == 0) {
5807 grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
5808 _mesa_set_program_error (ctx, error_pos, error_msg);
5809 _mesa_error (ctx, GL_INVALID_OPERATION, "Parse Error");
5810
5811 dict_destroy (&dt);
5812 return 1;
5813 }
5814
5815 #if DEBUG_PARSING
5816 printf ("Destroying grammer dict [parse retval: %d]\n", err);
5817 #endif
5818 dict_destroy (&dt);
5819
5820 /* Initialize the arb_program struct */
5821 program->Base.NumInstructions =
5822 program->Base.NumTemporaries =
5823 program->Base.NumParameters =
5824 program->Base.NumAttributes = program->Base.NumAddressRegs = 0;
5825 program->Parameters = _mesa_new_parameter_list ();
5826 program->InputsRead = 0;
5827 program->OutputsWritten = 0;
5828 program->Position = 0;
5829 program->MajorVersion = program->MinorVersion = 0;
5830 program->HintPrecisionFastest =
5831 program->HintPrecisionNicest =
5832 program->HintFogExp2 =
5833 program->HintFogExp =
5834 program->HintFogLinear = program->HintPositionInvariant = 0;
5835 for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)
5836 program->TexturesUsed[a] = 0;
5837 program->NumAluInstructions =
5838 program->NumTexInstructions =
5839 program->NumTexIndirections = 0;
5840
5841 program->FPInstructions = NULL;
5842 program->VPInstructions = NULL;
5843
5844 vc_head = NULL;
5845 err = 0;
5846
5847 /* Start examining the tokens in the array */
5848 inst = parsed;
5849
5850 /* Check the grammer rev */
5851 if (*inst++ != REVISION) {
5852 _mesa_set_program_error (ctx, 0, "Grammar version mismatch");
5853 _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar verison mismatch");
5854 err = 1;
5855 }
5856 else {
5857 switch (*inst++) {
5858 case FRAGMENT_PROGRAM:
5859 program->type = GL_FRAGMENT_PROGRAM_ARB;
5860 break;
5861
5862 case VERTEX_PROGRAM:
5863 program->type = GL_VERTEX_PROGRAM_ARB;
5864 break;
5865 }
5866
5867 err = parse_arb_program (ctx, inst, &vc_head, program);
5868 #if DEBUG_PARSING
5869 fprintf (stderr, "Symantic analysis returns %d [1 is bad!]\n", err);
5870 #endif
5871 }
5872
5873 /*debug_variables(ctx, vc_head, program); */
5874
5875 /* We're done with the parsed binary array */
5876 var_cache_destroy (&vc_head);
5877
5878 _mesa_free (parsed);
5879 #if DEBUG_PARSING
5880 printf ("_mesa_parse_arb_program() done\n");
5881 #endif
5882 return err;
5883 }