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