a little program to change // comments to /* */ ones
[mesa.git] / src / mesa / shader / arbprogparse.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.2
4 *
5 * Copyright (C) 1999-2004 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 arbprogparse.c
29 * ARB_*_program parser core
30 * \author Karl Rasche
31 */
32
33 #include "mtypes.h"
34 #include "glheader.h"
35 #include "context.h"
36 #include "hash.h"
37 #include "imports.h"
38 #include "macros.h"
39 #include "program.h"
40 #include "nvvertprog.h"
41 #include "nvfragprog.h"
42 #include "arbprogparse.h"
43 #include "grammar_mesa.h"
44
45 #ifndef __extension__
46 #if !defined(__GNUC__) || (__GNUC__ < 2) || \
47 ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 7))
48 # define __extension__
49 #endif
50 #endif
51
52 /* TODO:
53 * Fragment Program Stuff:
54 * -----------------------------------------------------
55 *
56 * - things from Michal's email
57 * + overflow on atoi
58 * + not-overflowing floats (don't use parse_integer..)
59 * + can remove range checking in arbparse.c
60 *
61 * - check all limits of number of various variables
62 * + parameters
63 *
64 * - test! test! test!
65 *
66 * Vertex Program Stuff:
67 * -----------------------------------------------------
68 * - Optimize param array usage and count limits correctly, see spec,
69 * section 2.14.3.7
70 * + Record if an array is reference absolutly or relatively (or both)
71 * + For absolute arrays, store a bitmap of accesses
72 * + For single parameters, store an access flag
73 * + After parsing, make a parameter cleanup and merging pass, where
74 * relative arrays are layed out first, followed by abs arrays, and
75 * finally single state.
76 * + Remap offsets for param src and dst registers
77 * + Now we can properly count parameter usage
78 *
79 * - Multiple state binding errors in param arrays (see spec, just before
80 * section 2.14.3.3)
81 * - grep for XXX
82 *
83 * Mesa Stuff
84 * -----------------------------------------------------
85 * - User clipping planes vs. PositionInvariant
86 * - Is it sufficient to just multiply by the mvp to transform in the
87 * PositionInvariant case? Or do we need something more involved?
88 *
89 * - vp_src swizzle is GLubyte, fp_src swizzle is GLuint
90 * - fetch state listed in program_parameters list
91 * + WTF should this go???
92 * + currently in nvvertexec.c and s_nvfragprog.c
93 *
94 * - allow for multiple address registers (and fetch address regs properly)
95 *
96 * Cosmetic Stuff
97 * -----------------------------------------------------
98 * - remove any leftover unused grammer.c stuff (dict_ ?)
99 * - fix grammer.c error handling so its not static
100 * - #ifdef around stuff pertaining to extentions
101 *
102 * Outstanding Questions:
103 * -----------------------------------------------------
104 * - ARB_matrix_palette / ARB_vertex_blend -- not supported
105 * what gets hacked off because of this:
106 * + VERTEX_ATTRIB_MATRIXINDEX
107 * + VERTEX_ATTRIB_WEIGHT
108 * + MATRIX_MODELVIEW
109 * + MATRIX_PALETTE
110 *
111 * - When can we fetch env/local params from their own register files, and
112 * when to we have to fetch them into the main state register file?
113 * (think arrays)
114 *
115 * Grammar Changes:
116 * -----------------------------------------------------
117 */
118
119 /* Changes since moving the file to shader directory
120
121 2004-III-4 ------------------------------------------------------------
122 - added #include "grammar_mesa.h"
123 - removed grammar specific code part (it resides now in grammar.c)
124 - added GL_ARB_fragment_program_shadow tokens
125 - modified #include "arbparse_syn.h"
126 - major changes inside _mesa_parse_arb_program()
127 - check the program string for '\0' characters
128 - copy the program string to a one-byte-longer location to have
129 it null-terminated
130 - position invariance test (not writing to result.position) moved
131 to syntax part
132 */
133
134 typedef GLubyte *production;
135
136 /**
137 * This is the text describing the rules to parse the grammar
138 */
139 __extension__ static char arb_grammar_text[] =
140 #include "arbprogram_syn.h"
141 ;
142
143 /**
144 * These should match up with the values defined in arbprogram.syn
145 */
146
147 /*
148 Changes:
149 - changed and merged V_* and F_* opcode values to OP_*.
150 - added GL_ARB_fragment_program_shadow specific tokens (michal)
151 */
152 #define REVISION 0x09
153
154 /* program type */
155 #define FRAGMENT_PROGRAM 0x01
156 #define VERTEX_PROGRAM 0x02
157
158 /* program section */
159 #define OPTION 0x01
160 #define INSTRUCTION 0x02
161 #define DECLARATION 0x03
162 #define END 0x04
163
164 /* GL_ARB_fragment_program option */
165 #define ARB_PRECISION_HINT_FASTEST 0x00
166 #define ARB_PRECISION_HINT_NICEST 0x01
167 #define ARB_FOG_EXP 0x02
168 #define ARB_FOG_EXP2 0x03
169 #define ARB_FOG_LINEAR 0x04
170
171 /* GL_ARB_vertex_program option */
172 #define ARB_POSITION_INVARIANT 0x05
173
174 /* GL_ARB_fragment_program_shadow option */
175 #define ARB_FRAGMENT_PROGRAM_SHADOW 0x06
176
177 /* GL_ARB_draw_buffers option */
178 #define ARB_DRAW_BUFFERS 0x07
179
180 /* GL_ARB_fragment_program instruction class */
181 #define OP_ALU_INST 0x00
182 #define OP_TEX_INST 0x01
183
184 /* GL_ARB_vertex_program instruction class */
185 /* OP_ALU_INST */
186
187 /* GL_ARB_fragment_program instruction type */
188 #define OP_ALU_VECTOR 0x00
189 #define OP_ALU_SCALAR 0x01
190 #define OP_ALU_BINSC 0x02
191 #define OP_ALU_BIN 0x03
192 #define OP_ALU_TRI 0x04
193 #define OP_ALU_SWZ 0x05
194 #define OP_TEX_SAMPLE 0x06
195 #define OP_TEX_KIL 0x07
196
197 /* GL_ARB_vertex_program instruction type */
198 #define OP_ALU_ARL 0x08
199 /* OP_ALU_VECTOR */
200 /* OP_ALU_SCALAR */
201 /* OP_ALU_BINSC */
202 /* OP_ALU_BIN */
203 /* OP_ALU_TRI */
204 /* OP_ALU_SWZ */
205
206 /* GL_ARB_fragment_program instruction code */
207 #define OP_ABS 0x00
208 #define OP_ABS_SAT 0x1B
209 #define OP_FLR 0x09
210 #define OP_FLR_SAT 0x26
211 #define OP_FRC 0x0A
212 #define OP_FRC_SAT 0x27
213 #define OP_LIT 0x0C
214 #define OP_LIT_SAT 0x2A
215 #define OP_MOV 0x11
216 #define OP_MOV_SAT 0x30
217 #define OP_COS 0x1F
218 #define OP_COS_SAT 0x20
219 #define OP_EX2 0x07
220 #define OP_EX2_SAT 0x25
221 #define OP_LG2 0x0B
222 #define OP_LG2_SAT 0x29
223 #define OP_RCP 0x14
224 #define OP_RCP_SAT 0x33
225 #define OP_RSQ 0x15
226 #define OP_RSQ_SAT 0x34
227 #define OP_SIN 0x38
228 #define OP_SIN_SAT 0x39
229 #define OP_SCS 0x35
230 #define OP_SCS_SAT 0x36
231 #define OP_POW 0x13
232 #define OP_POW_SAT 0x32
233 #define OP_ADD 0x01
234 #define OP_ADD_SAT 0x1C
235 #define OP_DP3 0x03
236 #define OP_DP3_SAT 0x21
237 #define OP_DP4 0x04
238 #define OP_DP4_SAT 0x22
239 #define OP_DPH 0x05
240 #define OP_DPH_SAT 0x23
241 #define OP_DST 0x06
242 #define OP_DST_SAT 0x24
243 #define OP_MAX 0x0F
244 #define OP_MAX_SAT 0x2E
245 #define OP_MIN 0x10
246 #define OP_MIN_SAT 0x2F
247 #define OP_MUL 0x12
248 #define OP_MUL_SAT 0x31
249 #define OP_SGE 0x16
250 #define OP_SGE_SAT 0x37
251 #define OP_SLT 0x17
252 #define OP_SLT_SAT 0x3A
253 #define OP_SUB 0x18
254 #define OP_SUB_SAT 0x3B
255 #define OP_XPD 0x1A
256 #define OP_XPD_SAT 0x43
257 #define OP_CMP 0x1D
258 #define OP_CMP_SAT 0x1E
259 #define OP_LRP 0x2B
260 #define OP_LRP_SAT 0x2C
261 #define OP_MAD 0x0E
262 #define OP_MAD_SAT 0x2D
263 #define OP_SWZ 0x19
264 #define OP_SWZ_SAT 0x3C
265 #define OP_TEX 0x3D
266 #define OP_TEX_SAT 0x3E
267 #define OP_TXB 0x3F
268 #define OP_TXB_SAT 0x40
269 #define OP_TXP 0x41
270 #define OP_TXP_SAT 0x42
271 #define OP_KIL 0x28
272
273 /* GL_ARB_vertex_program instruction code */
274 #define OP_ARL 0x02
275 /* OP_ABS */
276 /* OP_FLR */
277 /* OP_FRC */
278 /* OP_LIT */
279 /* OP_MOV */
280 /* OP_EX2 */
281 #define OP_EXP 0x08
282 /* OP_LG2 */
283 #define OP_LOG 0x0D
284 /* OP_RCP */
285 /* OP_RSQ */
286 /* OP_POW */
287 /* OP_ADD */
288 /* OP_DP3 */
289 /* OP_DP4 */
290 /* OP_DPH */
291 /* OP_DST */
292 /* OP_MAX */
293 /* OP_MIN */
294 /* OP_MUL */
295 /* OP_SGE */
296 /* OP_SLT */
297 /* OP_SUB */
298 /* OP_XPD */
299 /* OP_MAD */
300 /* OP_SWZ */
301
302 /* fragment attribute binding */
303 #define FRAGMENT_ATTRIB_COLOR 0x01
304 #define FRAGMENT_ATTRIB_TEXCOORD 0x02
305 #define FRAGMENT_ATTRIB_FOGCOORD 0x03
306 #define FRAGMENT_ATTRIB_POSITION 0x04
307
308 /* vertex attribute binding */
309 #define VERTEX_ATTRIB_POSITION 0x01
310 #define VERTEX_ATTRIB_WEIGHT 0x02
311 #define VERTEX_ATTRIB_NORMAL 0x03
312 #define VERTEX_ATTRIB_COLOR 0x04
313 #define VERTEX_ATTRIB_FOGCOORD 0x05
314 #define VERTEX_ATTRIB_TEXCOORD 0x06
315 #define VERTEX_ATTRIB_MATRIXINDEX 0x07
316 #define VERTEX_ATTRIB_GENERIC 0x08
317
318 /* fragment result binding */
319 #define FRAGMENT_RESULT_COLOR 0x01
320 #define FRAGMENT_RESULT_DEPTH 0x02
321
322 /* vertex result binding */
323 #define VERTEX_RESULT_POSITION 0x01
324 #define VERTEX_RESULT_COLOR 0x02
325 #define VERTEX_RESULT_FOGCOORD 0x03
326 #define VERTEX_RESULT_POINTSIZE 0x04
327 #define VERTEX_RESULT_TEXCOORD 0x05
328
329 /* texture target */
330 #define TEXTARGET_1D 0x01
331 #define TEXTARGET_2D 0x02
332 #define TEXTARGET_3D 0x03
333 #define TEXTARGET_RECT 0x04
334 #define TEXTARGET_CUBE 0x05
335 /* GL_ARB_fragment_program_shadow */
336 #define TEXTARGET_SHADOW1D 0x06
337 #define TEXTARGET_SHADOW2D 0x07
338 #define TEXTARGET_SHADOWRECT 0x08
339
340 /* face type */
341 #define FACE_FRONT 0x00
342 #define FACE_BACK 0x01
343
344 /* color type */
345 #define COLOR_PRIMARY 0x00
346 #define COLOR_SECONDARY 0x01
347
348 /* component */
349 #define COMPONENT_X 0x00
350 #define COMPONENT_Y 0x01
351 #define COMPONENT_Z 0x02
352 #define COMPONENT_W 0x03
353 #define COMPONENT_0 0x04
354 #define COMPONENT_1 0x05
355
356 /* array index type */
357 #define ARRAY_INDEX_ABSOLUTE 0x00
358 #define ARRAY_INDEX_RELATIVE 0x01
359
360 /* matrix name */
361 #define MATRIX_MODELVIEW 0x01
362 #define MATRIX_PROJECTION 0x02
363 #define MATRIX_MVP 0x03
364 #define MATRIX_TEXTURE 0x04
365 #define MATRIX_PALETTE 0x05
366 #define MATRIX_PROGRAM 0x06
367
368 /* matrix modifier */
369 #define MATRIX_MODIFIER_IDENTITY 0x00
370 #define MATRIX_MODIFIER_INVERSE 0x01
371 #define MATRIX_MODIFIER_TRANSPOSE 0x02
372 #define MATRIX_MODIFIER_INVTRANS 0x03
373
374 /* constant type */
375 #define CONSTANT_SCALAR 0x01
376 #define CONSTANT_VECTOR 0x02
377
378 /* program param type */
379 #define PROGRAM_PARAM_ENV 0x01
380 #define PROGRAM_PARAM_LOCAL 0x02
381
382 /* register type */
383 #define REGISTER_ATTRIB 0x01
384 #define REGISTER_PARAM 0x02
385 #define REGISTER_RESULT 0x03
386 #define REGISTER_ESTABLISHED_NAME 0x04
387
388 /* param binding */
389 #define PARAM_NULL 0x00
390 #define PARAM_ARRAY_ELEMENT 0x01
391 #define PARAM_STATE_ELEMENT 0x02
392 #define PARAM_PROGRAM_ELEMENT 0x03
393 #define PARAM_PROGRAM_ELEMENTS 0x04
394 #define PARAM_CONSTANT 0x05
395
396 /* param state property */
397 #define STATE_MATERIAL_PARSER 0x01
398 #define STATE_LIGHT_PARSER 0x02
399 #define STATE_LIGHT_MODEL 0x03
400 #define STATE_LIGHT_PROD 0x04
401 #define STATE_FOG 0x05
402 #define STATE_MATRIX_ROWS 0x06
403 /* GL_ARB_fragment_program */
404 #define STATE_TEX_ENV 0x07
405 #define STATE_DEPTH 0x08
406 /* GL_ARB_vertex_program */
407 #define STATE_TEX_GEN 0x09
408 #define STATE_CLIP_PLANE 0x0A
409 #define STATE_POINT 0x0B
410
411 /* state material property */
412 #define MATERIAL_AMBIENT 0x01
413 #define MATERIAL_DIFFUSE 0x02
414 #define MATERIAL_SPECULAR 0x03
415 #define MATERIAL_EMISSION 0x04
416 #define MATERIAL_SHININESS 0x05
417
418 /* state light property */
419 #define LIGHT_AMBIENT 0x01
420 #define LIGHT_DIFFUSE 0x02
421 #define LIGHT_SPECULAR 0x03
422 #define LIGHT_POSITION 0x04
423 #define LIGHT_ATTENUATION 0x05
424 #define LIGHT_HALF 0x06
425 #define LIGHT_SPOT_DIRECTION 0x07
426
427 /* state light model property */
428 #define LIGHT_MODEL_AMBIENT 0x01
429 #define LIGHT_MODEL_SCENECOLOR 0x02
430
431 /* state light product property */
432 #define LIGHT_PROD_AMBIENT 0x01
433 #define LIGHT_PROD_DIFFUSE 0x02
434 #define LIGHT_PROD_SPECULAR 0x03
435
436 /* state texture environment property */
437 #define TEX_ENV_COLOR 0x01
438
439 /* state texture generation coord property */
440 #define TEX_GEN_EYE 0x01
441 #define TEX_GEN_OBJECT 0x02
442
443 /* state fog property */
444 #define FOG_COLOR 0x01
445 #define FOG_PARAMS 0x02
446
447 /* state depth property */
448 #define DEPTH_RANGE 0x01
449
450 /* state point parameters property */
451 #define POINT_SIZE 0x01
452 #define POINT_ATTENUATION 0x02
453
454 /* declaration */
455 #define ATTRIB 0x01
456 #define PARAM 0x02
457 #define TEMP 0x03
458 #define OUTPUT 0x04
459 #define ALIAS 0x05
460 /* GL_ARB_vertex_program */
461 #define ADDRESS 0x06
462
463 /*-----------------------------------------------------------------------
464 * From here on down is the semantic checking portion
465 *
466 */
467
468 /**
469 * Variable Table Handling functions
470 */
471 typedef enum
472 {
473 vt_none,
474 vt_address,
475 vt_attrib,
476 vt_param,
477 vt_temp,
478 vt_output,
479 vt_alias
480 } var_type;
481
482
483 /*
484 * Setting an explicit field for each of the binding properties is a bit wasteful
485 * of space, but it should be much more clear when reading later on..
486 */
487 struct var_cache
488 {
489 GLubyte *name;
490 var_type type;
491 GLuint address_binding; /* The index of the address register we should
492 * be using */
493 GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */
494 GLuint attrib_binding_idx; /* The index into the attrib register file corresponding
495 * to the state in attrib_binding */
496 GLuint attrib_is_generic; /* If the attrib was specified through a generic
497 * vertex attrib */
498 GLuint temp_binding; /* The index of the temp register we are to use */
499 GLuint output_binding; /* For type vt_output, see nvfragprog.h for values */
500 GLuint output_binding_idx; /* This is the index into the result register file
501 * corresponding to the bound result state */
502 struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry
503 * that this is aliased to */
504 GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,
505 * PROGRAM_ENV_PARAM} */
506 GLuint param_binding_begin; /* This is the offset into the program_parameter_list where
507 * the tokens representing our bound state (or constants)
508 * start */
509 GLuint param_binding_length; /* This is how many entries in the the program_parameter_list
510 * we take up with our state tokens or constants. Note that
511 * this is _not_ the same as the number of param registers
512 * we eventually use */
513 struct var_cache *next;
514 };
515
516 static GLvoid
517 var_cache_create (struct var_cache **va)
518 {
519 *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache));
520 if (*va) {
521 (**va).name = NULL;
522 (**va).type = vt_none;
523 (**va).attrib_binding = ~0;
524 (**va).attrib_is_generic = 0;
525 (**va).temp_binding = ~0;
526 (**va).output_binding = ~0;
527 (**va).output_binding_idx = ~0;
528 (**va).param_binding_type = ~0;
529 (**va).param_binding_begin = ~0;
530 (**va).param_binding_length = ~0;
531 (**va).alias_binding = NULL;
532 (**va).next = NULL;
533 }
534 }
535
536 static GLvoid
537 var_cache_destroy (struct var_cache **va)
538 {
539 if (*va) {
540 var_cache_destroy (&(**va).next);
541 _mesa_free (*va);
542 *va = NULL;
543 }
544 }
545
546 static GLvoid
547 var_cache_append (struct var_cache **va, struct var_cache *nv)
548 {
549 if (*va)
550 var_cache_append (&(**va).next, nv);
551 else
552 *va = nv;
553 }
554
555 static struct var_cache *
556 var_cache_find (struct var_cache *va, GLubyte * name)
557 {
558 /*struct var_cache *first = va;*/
559
560 while (va) {
561 if (!strcmp ( (const char*) name, (const char*) va->name)) {
562 if (va->type == vt_alias)
563 return va->alias_binding;
564 return va;
565 }
566
567 va = va->next;
568 }
569
570 return NULL;
571 }
572
573 /**
574 * constructs an integer from 4 GLubytes in LE format
575 */
576 static GLuint
577 parse_position (GLubyte ** inst)
578 {
579 GLuint value;
580
581 value = (GLuint) (*(*inst)++);
582 value += (GLuint) (*(*inst)++) * 0x100;
583 value += (GLuint) (*(*inst)++) * 0x10000;
584 value += (GLuint) (*(*inst)++) * 0x1000000;
585
586 return value;
587 }
588
589 /**
590 * This will, given a string, lookup the string as a variable name in the
591 * var cache. If the name is found, the var cache node corresponding to the
592 * var name is returned. If it is not found, a new entry is allocated
593 *
594 * \param I Points into the binary array where the string identifier begins
595 * \param found 1 if the string was found in the var_cache, 0 if it was allocated
596 * \return The location on the var_cache corresponding the the string starting at I
597 */
598 static struct var_cache *
599 parse_string (GLubyte ** inst, struct var_cache **vc_head,
600 struct arb_program *Program, GLuint * found)
601 {
602 GLubyte *i = *inst;
603 struct var_cache *va = NULL;
604 (void) Program;
605
606 *inst += _mesa_strlen ((char *) i) + 1;
607
608 va = var_cache_find (*vc_head, i);
609
610 if (va) {
611 *found = 1;
612 return va;
613 }
614
615 *found = 0;
616 var_cache_create (&va);
617 va->name = i;
618
619 var_cache_append (vc_head, va);
620
621 return va;
622 }
623
624 static char *
625 parse_string_without_adding (GLubyte ** inst, struct arb_program *Program)
626 {
627 GLubyte *i = *inst;
628 (void) Program;
629
630 *inst += _mesa_strlen ((char *) i) + 1;
631
632 return (char *) i;
633 }
634
635 /**
636 * \return -1 if we parse '-', return 1 otherwise
637 */
638 static GLint
639 parse_sign (GLubyte ** inst)
640 {
641 /*return *(*inst)++ != '+'; */
642
643 if (**inst == '-') {
644 (*inst)++;
645 return -1;
646 }
647 else if (**inst == '+') {
648 (*inst)++;
649 return 1;
650 }
651
652 return 1;
653 }
654
655 /**
656 * parses and returns signed integer
657 */
658 static GLint
659 parse_integer (GLubyte ** inst, struct arb_program *Program)
660 {
661 GLint sign;
662 GLint value;
663
664 /* check if *inst points to '+' or '-'
665 * if yes, grab the sign and increment *inst
666 */
667 sign = parse_sign (inst);
668
669 /* now check if *inst points to 0
670 * if yes, increment the *inst and return the default value
671 */
672 if (**inst == 0) {
673 (*inst)++;
674 return 0;
675 }
676
677 /* parse the integer as you normally would do it */
678 value = _mesa_atoi (parse_string_without_adding (inst, Program));
679
680 /* now, after terminating 0 there is a position
681 * to parse it - parse_position()
682 */
683 Program->Position = parse_position (inst);
684
685 return value * sign;
686 }
687
688 /**
689 Accumulate this string of digits, and return them as
690 a large integer represented in floating point (for range).
691 If scale is not NULL, also accumulates a power-of-ten
692 integer scale factor that represents the number of digits
693 in the string.
694 */
695 static GLdouble
696 parse_float_string(GLubyte ** inst, struct arb_program *Program, GLdouble *scale)
697 {
698 GLdouble value = 0.0;
699 GLdouble oscale = 1.0;
700
701 if (**inst == 0) { /* this string of digits is empty-- do nothing */
702 (*inst)++;
703 }
704 else { /* nonempty string-- parse out the digits */
705 while (isdigit(**inst)) {
706 GLubyte digit = *((*inst)++);
707 value = value * 10.0 + (GLint) (digit - '0');
708 oscale *= 10.0;
709 }
710 assert(**inst == 0); /* integer string should end with 0 */
711 (*inst)++; /* skip over terminating 0 */
712 Program->Position = parse_position(inst); /* skip position (from integer) */
713 }
714 if (scale)
715 *scale = oscale;
716 return value;
717 }
718
719 /**
720 Parse an unsigned floating-point number from this stream of tokenized
721 characters. Example floating-point formats supported:
722 12.34
723 12
724 0.34
725 .34
726 12.34e-4
727 */
728 static GLfloat
729 parse_float (GLubyte ** inst, struct arb_program *Program)
730 {
731 GLint exponent;
732 GLdouble whole, fraction, fracScale = 1.0;
733
734 whole = parse_float_string(inst, Program, 0);
735 fraction = parse_float_string(inst, Program, &fracScale);
736
737 /* Parse signed exponent */
738 exponent = parse_integer(inst, Program); /* This is the exponent */
739
740 /* Assemble parts of floating-point number: */
741 return (GLfloat) ((whole + fraction / fracScale) *
742 _mesa_pow(10.0, (GLfloat) exponent));
743 }
744
745
746 /**
747 */
748 static GLfloat
749 parse_signed_float (GLubyte ** inst, struct arb_program *Program)
750 {
751 GLint sign = parse_sign (inst);
752 GLfloat value = parse_float (inst, Program);
753 return value * sign;
754 }
755
756 /**
757 * This picks out a constant value from the parsed array. The constant vector is r
758 * returned in the *values array, which should be of length 4.
759 *
760 * \param values - The 4 component vector with the constant value in it
761 */
762 static GLvoid
763 parse_constant (GLubyte ** inst, GLfloat *values, struct arb_program *Program,
764 GLboolean use)
765 {
766 GLuint components, i;
767
768
769 switch (*(*inst)++) {
770 case CONSTANT_SCALAR:
771 if (use == GL_TRUE) {
772 values[0] =
773 values[1] =
774 values[2] = values[3] = parse_float (inst, Program);
775 }
776 else {
777 values[0] =
778 values[1] =
779 values[2] = values[3] = parse_signed_float (inst, Program);
780 }
781
782 break;
783 case CONSTANT_VECTOR:
784 values[0] = values[1] = values[2] = 0;
785 values[3] = 1;
786 components = *(*inst)++;
787 for (i = 0; i < components; i++) {
788 values[i] = parse_signed_float (inst, Program);
789 }
790 break;
791 }
792 }
793
794 /**
795 * \param offset The offset from the address register that we should
796 * address
797 *
798 * \return 0 on sucess, 1 on error
799 */
800 static GLuint
801 parse_relative_offset (GLcontext *ctx, GLubyte **inst, struct arb_program *Program,
802 GLint *offset)
803 {
804 *offset = parse_integer(inst, Program);
805 return 0;
806 }
807
808 /**
809 * \param color 0 if color type is primary, 1 if color type is secondary
810 * \return 0 on sucess, 1 on error
811 */
812 static GLuint
813 parse_color_type (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
814 GLint * color)
815 {
816 (void) ctx; (void) Program;
817 *color = *(*inst)++ != COLOR_PRIMARY;
818 return 0;
819 }
820
821 /**
822 * Get an integer corresponding to a generic vertex attribute.
823 *
824 * \return 0 on sucess, 1 on error
825 */
826 static GLuint
827 parse_generic_attrib_num(GLcontext *ctx, GLubyte ** inst,
828 struct arb_program *Program, GLuint *attrib)
829 {
830 GLint i = parse_integer(inst, Program);
831
832 if ((i < 0) || (i > MAX_VERTEX_PROGRAM_ATTRIBS))
833 {
834 _mesa_set_program_error (ctx, Program->Position,
835 "Invalid generic vertex attribute index");
836 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid generic vertex attribute index");
837
838 return 1;
839 }
840
841 *attrib = (GLuint) i;
842
843 return 0;
844 }
845
846
847 /**
848 * \param color The index of the color buffer to write into
849 * \return 0 on sucess, 1 on error
850 */
851 static GLuint
852 parse_output_color_num (GLcontext * ctx, GLubyte ** inst,
853 struct arb_program *Program, GLuint * color)
854 {
855 GLint i = parse_integer (inst, Program);
856
857 if ((i < 0) || (i >= (int)ctx->Const.MaxDrawBuffers)) {
858 _mesa_set_program_error (ctx, Program->Position,
859 "Invalid draw buffer index");
860 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid draw buffer index");
861 return 1;
862 }
863
864 *color = (GLuint) i;
865 return 0;
866 }
867
868
869 /**
870 * \param coord The texture unit index
871 * \return 0 on sucess, 1 on error
872 */
873 static GLuint
874 parse_texcoord_num (GLcontext * ctx, GLubyte ** inst,
875 struct arb_program *Program, GLuint * coord)
876 {
877 GLint i = parse_integer (inst, Program);
878
879 if ((i < 0) || (i >= (int)ctx->Const.MaxTextureUnits)) {
880 _mesa_set_program_error (ctx, Program->Position,
881 "Invalid texture unit index");
882 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid texture unit index");
883 return 1;
884 }
885
886 *coord = (GLuint) i;
887 return 0;
888 }
889
890 /**
891 * \param coord The weight index
892 * \return 0 on sucess, 1 on error
893 */
894 static GLuint
895 parse_weight_num (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
896 GLint * coord)
897 {
898 *coord = parse_integer (inst, Program);
899
900 if ((*coord < 0) || (*coord >= 1)) {
901 _mesa_set_program_error (ctx, Program->Position,
902 "Invalid weight index");
903 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid weight index");
904 return 1;
905 }
906
907 return 0;
908 }
909
910 /**
911 * \param coord The clip plane index
912 * \return 0 on sucess, 1 on error
913 */
914 static GLuint
915 parse_clipplane_num (GLcontext * ctx, GLubyte ** inst,
916 struct arb_program *Program, GLint * coord)
917 {
918 *coord = parse_integer (inst, Program);
919
920 if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) {
921 _mesa_set_program_error (ctx, Program->Position,
922 "Invalid clip plane index");
923 _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid clip plane index");
924 return 1;
925 }
926
927 return 0;
928 }
929
930
931 /**
932 * \return 0 on front face, 1 on back face
933 */
934 static GLuint
935 parse_face_type (GLubyte ** inst)
936 {
937 switch (*(*inst)++) {
938 case FACE_FRONT:
939 return 0;
940
941 case FACE_BACK:
942 return 1;
943 }
944 return 0;
945 }
946
947
948 /**
949 * Given a matrix and a modifier token on the binary array, return tokens
950 * that _mesa_fetch_state() [program.c] can understand.
951 *
952 * \param matrix - the matrix we are talking about
953 * \param matrix_idx - the index of the matrix we have (for texture & program matricies)
954 * \param matrix_modifier - the matrix modifier (trans, inv, etc)
955 * \return 0 on sucess, 1 on failure
956 */
957 static GLuint
958 parse_matrix (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
959 GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier)
960 {
961 GLubyte mat = *(*inst)++;
962
963 *matrix_idx = 0;
964
965 switch (mat) {
966 case MATRIX_MODELVIEW:
967 *matrix = STATE_MODELVIEW;
968 *matrix_idx = parse_integer (inst, Program);
969 if (*matrix_idx > 0) {
970 _mesa_set_program_error (ctx, Program->Position,
971 "ARB_vertex_blend not supported\n");
972 _mesa_error (ctx, GL_INVALID_OPERATION,
973 "ARB_vertex_blend not supported\n");
974 return 1;
975 }
976 break;
977
978 case MATRIX_PROJECTION:
979 *matrix = STATE_PROJECTION;
980 break;
981
982 case MATRIX_MVP:
983 *matrix = STATE_MVP;
984 break;
985
986 case MATRIX_TEXTURE:
987 *matrix = STATE_TEXTURE;
988 *matrix_idx = parse_integer (inst, Program);
989 if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) {
990 _mesa_set_program_error (ctx, Program->Position,
991 "Invalid Texture Unit");
992 _mesa_error (ctx, GL_INVALID_OPERATION,
993 "Invalid Texture Unit: %d", *matrix_idx);
994 return 1;
995 }
996 break;
997
998 /* This is not currently supported (ARB_matrix_palette) */
999 case MATRIX_PALETTE:
1000 *matrix_idx = parse_integer (inst, Program);
1001 _mesa_set_program_error (ctx, Program->Position,
1002 "ARB_matrix_palette not supported\n");
1003 _mesa_error (ctx, GL_INVALID_OPERATION,
1004 "ARB_matrix_palette not supported\n");
1005 return 1;
1006 break;
1007
1008 case MATRIX_PROGRAM:
1009 *matrix = STATE_PROGRAM;
1010 *matrix_idx = parse_integer (inst, Program);
1011 if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) {
1012 _mesa_set_program_error (ctx, Program->Position,
1013 "Invalid Program Matrix");
1014 _mesa_error (ctx, GL_INVALID_OPERATION,
1015 "Invalid Program Matrix: %d", *matrix_idx);
1016 return 1;
1017 }
1018 break;
1019 }
1020
1021 switch (*(*inst)++) {
1022 case MATRIX_MODIFIER_IDENTITY:
1023 *matrix_modifier = 0;
1024 break;
1025 case MATRIX_MODIFIER_INVERSE:
1026 *matrix_modifier = STATE_MATRIX_INVERSE;
1027 break;
1028 case MATRIX_MODIFIER_TRANSPOSE:
1029 *matrix_modifier = STATE_MATRIX_TRANSPOSE;
1030 break;
1031 case MATRIX_MODIFIER_INVTRANS:
1032 *matrix_modifier = STATE_MATRIX_INVTRANS;
1033 break;
1034 }
1035
1036 return 0;
1037 }
1038
1039
1040 /**
1041 * This parses a state string (rather, the binary version of it) into
1042 * a 6-token sequence as described in _mesa_fetch_state() [program.c]
1043 *
1044 * \param inst - the start in the binary arry to start working from
1045 * \param state_tokens - the storage for the 6-token state description
1046 * \return - 0 on sucess, 1 on error
1047 */
1048 static GLuint
1049 parse_state_single_item (GLcontext * ctx, GLubyte ** inst,
1050 struct arb_program *Program, GLint * state_tokens)
1051 {
1052 switch (*(*inst)++) {
1053 case STATE_MATERIAL_PARSER:
1054 state_tokens[0] = STATE_MATERIAL;
1055 state_tokens[1] = parse_face_type (inst);
1056 switch (*(*inst)++) {
1057 case MATERIAL_AMBIENT:
1058 state_tokens[2] = STATE_AMBIENT;
1059 break;
1060 case MATERIAL_DIFFUSE:
1061 state_tokens[2] = STATE_DIFFUSE;
1062 break;
1063 case MATERIAL_SPECULAR:
1064 state_tokens[2] = STATE_SPECULAR;
1065 break;
1066 case MATERIAL_EMISSION:
1067 state_tokens[2] = STATE_EMISSION;
1068 break;
1069 case MATERIAL_SHININESS:
1070 state_tokens[2] = STATE_SHININESS;
1071 break;
1072 }
1073 break;
1074
1075 case STATE_LIGHT_PARSER:
1076 state_tokens[0] = STATE_LIGHT;
1077 state_tokens[1] = parse_integer (inst, Program);
1078
1079 /* Check the value of state_tokens[1] against the # of lights */
1080 if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
1081 _mesa_set_program_error (ctx, Program->Position,
1082 "Invalid Light Number");
1083 _mesa_error (ctx, GL_INVALID_OPERATION,
1084 "Invalid Light Number: %d", state_tokens[1]);
1085 return 1;
1086 }
1087
1088 switch (*(*inst)++) {
1089 case LIGHT_AMBIENT:
1090 state_tokens[2] = STATE_AMBIENT;
1091 break;
1092 case LIGHT_DIFFUSE:
1093 state_tokens[2] = STATE_DIFFUSE;
1094 break;
1095 case LIGHT_SPECULAR:
1096 state_tokens[2] = STATE_SPECULAR;
1097 break;
1098 case LIGHT_POSITION:
1099 state_tokens[2] = STATE_POSITION;
1100 break;
1101 case LIGHT_ATTENUATION:
1102 state_tokens[2] = STATE_ATTENUATION;
1103 break;
1104 case LIGHT_HALF:
1105 state_tokens[2] = STATE_HALF;
1106 break;
1107 case LIGHT_SPOT_DIRECTION:
1108 state_tokens[2] = STATE_SPOT_DIRECTION;
1109 break;
1110 }
1111 break;
1112
1113 case STATE_LIGHT_MODEL:
1114 switch (*(*inst)++) {
1115 case LIGHT_MODEL_AMBIENT:
1116 state_tokens[0] = STATE_LIGHTMODEL_AMBIENT;
1117 break;
1118 case LIGHT_MODEL_SCENECOLOR:
1119 state_tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
1120 state_tokens[1] = parse_face_type (inst);
1121 break;
1122 }
1123 break;
1124
1125 case STATE_LIGHT_PROD:
1126 state_tokens[0] = STATE_LIGHTPROD;
1127 state_tokens[1] = parse_integer (inst, Program);
1128
1129 /* Check the value of state_tokens[1] against the # of lights */
1130 if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
1131 _mesa_set_program_error (ctx, Program->Position,
1132 "Invalid Light Number");
1133 _mesa_error (ctx, GL_INVALID_OPERATION,
1134 "Invalid Light Number: %d", state_tokens[1]);
1135 return 1;
1136 }
1137
1138 state_tokens[2] = parse_face_type (inst);
1139 switch (*(*inst)++) {
1140 case LIGHT_PROD_AMBIENT:
1141 state_tokens[3] = STATE_AMBIENT;
1142 break;
1143 case LIGHT_PROD_DIFFUSE:
1144 state_tokens[3] = STATE_DIFFUSE;
1145 break;
1146 case LIGHT_PROD_SPECULAR:
1147 state_tokens[3] = STATE_SPECULAR;
1148 break;
1149 }
1150 break;
1151
1152
1153 case STATE_FOG:
1154 switch (*(*inst)++) {
1155 case FOG_COLOR:
1156 state_tokens[0] = STATE_FOG_COLOR;
1157 break;
1158 case FOG_PARAMS:
1159 state_tokens[0] = STATE_FOG_PARAMS;
1160 break;
1161 }
1162 break;
1163
1164 case STATE_TEX_ENV:
1165 state_tokens[1] = parse_integer (inst, Program);
1166 switch (*(*inst)++) {
1167 case TEX_ENV_COLOR:
1168 state_tokens[0] = STATE_TEXENV_COLOR;
1169 break;
1170 }
1171 break;
1172
1173 case STATE_TEX_GEN:
1174 {
1175 GLuint type, coord;
1176
1177 state_tokens[0] = STATE_TEXGEN;
1178 /*state_tokens[1] = parse_integer (inst, Program);*/ /* Texture Unit */
1179
1180 if (parse_texcoord_num (ctx, inst, Program, &coord))
1181 return 1;
1182 state_tokens[1] = coord;
1183
1184 /* EYE or OBJECT */
1185 type = *(*inst++);
1186
1187 /* 0 - s, 1 - t, 2 - r, 3 - q */
1188 coord = *(*inst++);
1189
1190 if (type == TEX_GEN_EYE) {
1191 switch (coord) {
1192 case COMPONENT_X:
1193 state_tokens[2] = STATE_TEXGEN_EYE_S;
1194 break;
1195 case COMPONENT_Y:
1196 state_tokens[2] = STATE_TEXGEN_EYE_T;
1197 break;
1198 case COMPONENT_Z:
1199 state_tokens[2] = STATE_TEXGEN_EYE_R;
1200 break;
1201 case COMPONENT_W:
1202 state_tokens[2] = STATE_TEXGEN_EYE_Q;
1203 break;
1204 }
1205 }
1206 else {
1207 switch (coord) {
1208 case COMPONENT_X:
1209 state_tokens[2] = STATE_TEXGEN_OBJECT_S;
1210 break;
1211 case COMPONENT_Y:
1212 state_tokens[2] = STATE_TEXGEN_OBJECT_T;
1213 break;
1214 case COMPONENT_Z:
1215 state_tokens[2] = STATE_TEXGEN_OBJECT_R;
1216 break;
1217 case COMPONENT_W:
1218 state_tokens[2] = STATE_TEXGEN_OBJECT_Q;
1219 break;
1220 }
1221 }
1222 }
1223 break;
1224
1225 case STATE_DEPTH:
1226 switch (*(*inst)++) {
1227 case DEPTH_RANGE:
1228 state_tokens[0] = STATE_DEPTH_RANGE;
1229 break;
1230 }
1231 break;
1232
1233 case STATE_CLIP_PLANE:
1234 state_tokens[0] = STATE_CLIPPLANE;
1235 state_tokens[1] = parse_integer (inst, Program);
1236 if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1]))
1237 return 1;
1238 break;
1239
1240 case STATE_POINT:
1241 switch (*(*inst++)) {
1242 case POINT_SIZE:
1243 state_tokens[0] = STATE_POINT_SIZE;
1244 break;
1245
1246 case POINT_ATTENUATION:
1247 state_tokens[0] = STATE_POINT_ATTENUATION;
1248 break;
1249 }
1250 break;
1251
1252 /* XXX: I think this is the correct format for a matrix row */
1253 case STATE_MATRIX_ROWS:
1254 state_tokens[0] = STATE_MATRIX;
1255 if (parse_matrix
1256 (ctx, inst, Program, &state_tokens[1], &state_tokens[2],
1257 &state_tokens[5]))
1258 return 1;
1259
1260 state_tokens[3] = parse_integer (inst, Program); /* The first row to grab */
1261
1262 if ((**inst) != 0) { /* Either the last row, 0 */
1263 state_tokens[4] = parse_integer (inst, Program);
1264 if (state_tokens[4] < state_tokens[3]) {
1265 _mesa_set_program_error (ctx, Program->Position,
1266 "Second matrix index less than the first");
1267 _mesa_error (ctx, GL_INVALID_OPERATION,
1268 "Second matrix index (%d) less than the first (%d)",
1269 state_tokens[4], state_tokens[3]);
1270 return 1;
1271 }
1272 }
1273 else {
1274 state_tokens[4] = state_tokens[3];
1275 (*inst)++;
1276 }
1277 break;
1278 }
1279
1280 return 0;
1281 }
1282
1283 /**
1284 * This parses a state string (rather, the binary version of it) into
1285 * a 6-token similar for the state fetching code in program.c
1286 *
1287 * One might ask, why fetch these parameters into just like you fetch
1288 * state when they are already stored in other places?
1289 *
1290 * Because of array offsets -> We can stick env/local parameters in the
1291 * middle of a parameter array and then index someplace into the array
1292 * when we execute.
1293 *
1294 * One optimization might be to only do this for the cases where the
1295 * env/local parameters end up inside of an array, and leave the
1296 * single parameters (or arrays of pure env/local pareameters) in their
1297 * respective register files.
1298 *
1299 * For ENV parameters, the format is:
1300 * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
1301 * state_tokens[1] = STATE_ENV
1302 * state_tokens[2] = the parameter index
1303 *
1304 * for LOCAL parameters, the format is:
1305 * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
1306 * state_tokens[1] = STATE_LOCAL
1307 * state_tokens[2] = the parameter index
1308 *
1309 * \param inst - the start in the binary arry to start working from
1310 * \param state_tokens - the storage for the 6-token state description
1311 * \return - 0 on sucess, 1 on failure
1312 */
1313 static GLuint
1314 parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
1315 struct arb_program *Program, GLint * state_tokens)
1316 {
1317 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
1318 state_tokens[0] = STATE_FRAGMENT_PROGRAM;
1319 else
1320 state_tokens[0] = STATE_VERTEX_PROGRAM;
1321
1322
1323 switch (*(*inst)++) {
1324 case PROGRAM_PARAM_ENV:
1325 state_tokens[1] = STATE_ENV;
1326 state_tokens[2] = parse_integer (inst, Program);
1327
1328 /* Check state_tokens[2] against the number of ENV parameters available */
1329 if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&
1330 (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramEnvParams))
1331 ||
1332 ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
1333 (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramEnvParams))) {
1334 _mesa_set_program_error (ctx, Program->Position,
1335 "Invalid Program Env Parameter");
1336 _mesa_error (ctx, GL_INVALID_OPERATION,
1337 "Invalid Program Env Parameter: %d",
1338 state_tokens[2]);
1339 return 1;
1340 }
1341
1342 break;
1343
1344 case PROGRAM_PARAM_LOCAL:
1345 state_tokens[1] = STATE_LOCAL;
1346 state_tokens[2] = parse_integer (inst, Program);
1347
1348 /* Check state_tokens[2] against the number of LOCAL parameters available */
1349 if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&
1350 (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramLocalParams))
1351 ||
1352 ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
1353 (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramLocalParams))) {
1354 _mesa_set_program_error (ctx, Program->Position,
1355 "Invalid Program Local Parameter");
1356 _mesa_error (ctx, GL_INVALID_OPERATION,
1357 "Invalid Program Local Parameter: %d",
1358 state_tokens[2]);
1359 return 1;
1360 }
1361 break;
1362 }
1363
1364 return 0;
1365 }
1366
1367 /**
1368 * For ARB_vertex_program, programs are not allowed to use both an explicit
1369 * vertex attribute and a generic vertex attribute corresponding to the same
1370 * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec.
1371 *
1372 * This will walk our var_cache and make sure that nobody does anything fishy.
1373 *
1374 * \return 0 on sucess, 1 on error
1375 */
1376 static GLuint
1377 generic_attrib_check(struct var_cache *vc_head)
1378 {
1379 int a;
1380 struct var_cache *curr;
1381 GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS],
1382 genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS];
1383
1384 for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
1385 explicitAttrib[a] = GL_FALSE;
1386 genericAttrib[a] = GL_FALSE;
1387 }
1388
1389 curr = vc_head;
1390 while (curr) {
1391 if (curr->type == vt_attrib) {
1392 if (curr->attrib_is_generic)
1393 genericAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
1394 else
1395 explicitAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
1396 }
1397
1398 curr = curr->next;
1399 }
1400
1401 for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
1402 if ((explicitAttrib[a]) && (genericAttrib[a]))
1403 return 1;
1404 }
1405
1406 return 0;
1407 }
1408
1409 /**
1410 * This will handle the binding side of an ATTRIB var declaration
1411 *
1412 * \param binding - the fragment input register state, defined in nvfragprog.h
1413 * \param binding_idx - the index in the attrib register file that binding is associated with
1414 * \return returns 0 on sucess, 1 on error
1415 *
1416 * See nvfragparse.c for attrib register file layout
1417 */
1418 static GLuint
1419 parse_attrib_binding (GLcontext * ctx, GLubyte ** inst,
1420 struct arb_program *Program, GLuint * binding,
1421 GLuint * binding_idx, GLuint *is_generic)
1422 {
1423 GLuint texcoord;
1424 GLint coord;
1425 GLint err = 0;
1426
1427 *is_generic = 0;
1428 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
1429 switch (*(*inst)++) {
1430 case FRAGMENT_ATTRIB_COLOR:
1431 err = parse_color_type (ctx, inst, Program, &coord);
1432 *binding = FRAG_ATTRIB_COL0 + coord;
1433 *binding_idx = 1 + coord;
1434 break;
1435
1436 case FRAGMENT_ATTRIB_TEXCOORD:
1437 err = parse_texcoord_num (ctx, inst, Program, &texcoord);
1438 *binding = FRAG_ATTRIB_TEX0 + texcoord;
1439 *binding_idx = 4 + texcoord;
1440 break;
1441
1442 case FRAGMENT_ATTRIB_FOGCOORD:
1443 *binding = FRAG_ATTRIB_FOGC;
1444 *binding_idx = 3;
1445 break;
1446
1447 case FRAGMENT_ATTRIB_POSITION:
1448 *binding = FRAG_ATTRIB_WPOS;
1449 *binding_idx = 0;
1450 break;
1451
1452 default:
1453 err = 1;
1454 break;
1455 }
1456 }
1457 else {
1458 switch (*(*inst)++) {
1459 case VERTEX_ATTRIB_POSITION:
1460 *binding = VERT_ATTRIB_POS;
1461 *binding_idx = 0;
1462 break;
1463
1464 case VERTEX_ATTRIB_WEIGHT:
1465 {
1466 GLint weight;
1467
1468 err = parse_weight_num (ctx, inst, Program, &weight);
1469 *binding = VERT_ATTRIB_WEIGHT;
1470 *binding_idx = 1;
1471 }
1472 _mesa_set_program_error (ctx, Program->Position,
1473 "ARB_vertex_blend not supported\n");
1474 _mesa_error (ctx, GL_INVALID_OPERATION,
1475 "ARB_vertex_blend not supported\n");
1476 return 1;
1477 break;
1478
1479 case VERTEX_ATTRIB_NORMAL:
1480 *binding = VERT_ATTRIB_NORMAL;
1481 *binding_idx = 2;
1482 break;
1483
1484 case VERTEX_ATTRIB_COLOR:
1485 {
1486 GLint color;
1487
1488 err = parse_color_type (ctx, inst, Program, &color);
1489 if (color) {
1490 *binding = VERT_ATTRIB_COLOR1;
1491 *binding_idx = 4;
1492 }
1493 else {
1494 *binding = VERT_ATTRIB_COLOR0;
1495 *binding_idx = 3;
1496 }
1497 }
1498 break;
1499
1500 case VERTEX_ATTRIB_FOGCOORD:
1501 *binding = VERT_ATTRIB_FOG;
1502 *binding_idx = 5;
1503 break;
1504
1505 case VERTEX_ATTRIB_TEXCOORD:
1506 {
1507 GLuint unit;
1508
1509 err = parse_texcoord_num (ctx, inst, Program, &unit);
1510 *binding = VERT_ATTRIB_TEX0 + unit;
1511 *binding_idx = 8 + unit;
1512 }
1513 break;
1514
1515 /* It looks like we don't support this at all, atm */
1516 case VERTEX_ATTRIB_MATRIXINDEX:
1517 parse_integer (inst, Program);
1518 _mesa_set_program_error (ctx, Program->Position,
1519 "ARB_palette_matrix not supported");
1520 _mesa_error (ctx, GL_INVALID_OPERATION,
1521 "ARB_palette_matrix not supported");
1522 return 1;
1523 break;
1524
1525 case VERTEX_ATTRIB_GENERIC:
1526 {
1527 GLuint attrib;
1528
1529 if (!parse_generic_attrib_num(ctx, inst, Program, &attrib)) {
1530 *is_generic = 1;
1531 switch (attrib) {
1532 case 0:
1533 *binding = VERT_ATTRIB_POS;
1534 break;
1535 case 1:
1536 *binding = VERT_ATTRIB_WEIGHT;
1537 break;
1538 case 2:
1539 *binding = VERT_ATTRIB_NORMAL;
1540 break;
1541 case 3:
1542 *binding = VERT_ATTRIB_COLOR0;
1543 break;
1544 case 4:
1545 *binding = VERT_ATTRIB_COLOR1;
1546 break;
1547 case 5:
1548 *binding = VERT_ATTRIB_FOG;
1549 break;
1550 case 6:
1551 break;
1552 case 7:
1553 break;
1554 default:
1555 *binding = VERT_ATTRIB_TEX0 + (attrib-8);
1556 break;
1557 }
1558 *binding_idx = attrib;
1559 }
1560 }
1561 break;
1562
1563 default:
1564 err = 1;
1565 break;
1566 }
1567 }
1568
1569 /* Can this even happen? */
1570 if (err) {
1571 _mesa_set_program_error (ctx, Program->Position,
1572 "Bad attribute binding");
1573 _mesa_error (ctx, GL_INVALID_OPERATION, "Bad attribute binding");
1574 }
1575
1576 Program->InputsRead |= (1 << *binding_idx);
1577
1578 return err;
1579 }
1580
1581 /**
1582 * This translates between a binary token for an output variable type
1583 * and the mesa token for the same thing.
1584 *
1585 *
1586 * XXX: What is the 'name' for vertex program state? -> do we need it?
1587 * I don't think we do;
1588 *
1589 * See nvfragprog.h for definitions
1590 *
1591 * \param inst - The parsed tokens
1592 * \param binding - The name of the state we are binding too
1593 * \param binding_idx - The index into the result register file that this is bound too
1594 *
1595 * See nvfragparse.c for the register file layout for fragment programs
1596 * See nvvertparse.c for the register file layout for vertex programs
1597 */
1598 static GLuint
1599 parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding,
1600 GLuint * binding_idx, struct arb_program *Program)
1601 {
1602 GLuint b, out_color;
1603
1604 switch (*(*inst)++) {
1605 case FRAGMENT_RESULT_COLOR:
1606 /* for frag programs, this is FRAGMENT_RESULT_COLOR */
1607 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
1608 /* This gets result of the color buffer we're supposed to
1609 * draw into
1610 */
1611 parse_output_color_num(ctx, inst, Program, &out_color);
1612
1613 *binding = FRAG_OUTPUT_COLR;
1614
1615 /* XXX: We're ignoring the color buffer for now. */
1616 *binding_idx = 0;
1617 }
1618 /* for vtx programs, this is VERTEX_RESULT_POSITION */
1619 else {
1620 *binding_idx = 0;
1621 }
1622 break;
1623
1624 case FRAGMENT_RESULT_DEPTH:
1625 /* for frag programs, this is FRAGMENT_RESULT_DEPTH */
1626 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
1627 *binding = FRAG_OUTPUT_DEPR;
1628 *binding_idx = 2;
1629 }
1630 /* for vtx programs, this is VERTEX_RESULT_COLOR */
1631 else {
1632 GLint color_type;
1633 GLuint face_type = parse_face_type(inst);
1634 GLint color_type_ret = parse_color_type(ctx, inst, Program, &color_type);
1635
1636 /* back face */
1637 if (face_type) {
1638 if (color_type_ret) return 1;
1639
1640 /* secondary color */
1641 if (color_type) {
1642 *binding_idx = 4;
1643 }
1644 /* primary color */
1645 else {
1646 *binding_idx = 3;
1647 }
1648 }
1649 /* front face */
1650 else {
1651 /* secondary color */
1652 if (color_type) {
1653 *binding_idx = 2;
1654 }
1655 /* primary color */
1656 else {
1657 *binding_idx = 1;
1658 }
1659 }
1660 }
1661 break;
1662
1663 case VERTEX_RESULT_FOGCOORD:
1664 *binding_idx = 5;
1665 break;
1666
1667 case VERTEX_RESULT_POINTSIZE:
1668 *binding_idx = 6;
1669 break;
1670
1671 case VERTEX_RESULT_TEXCOORD:
1672 if (parse_texcoord_num (ctx, inst, Program, &b))
1673 return 1;
1674 *binding_idx = 7 + b;
1675 break;
1676 }
1677
1678 Program->OutputsWritten |= (1 << *binding_idx);
1679
1680 return 0;
1681 }
1682
1683 /**
1684 * This handles the declaration of ATTRIB variables
1685 *
1686 * XXX: Still needs
1687 * parse_vert_attrib_binding(), or something like that
1688 *
1689 * \return 0 on sucess, 1 on error
1690 */
1691 static GLint
1692 parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
1693 struct arb_program *Program)
1694 {
1695 GLuint found;
1696 char *error_msg;
1697 struct var_cache *attrib_var;
1698
1699 attrib_var = parse_string (inst, vc_head, Program, &found);
1700 Program->Position = parse_position (inst);
1701 if (found) {
1702 error_msg = (char *)
1703 _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40);
1704 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
1705 attrib_var->name);
1706
1707 _mesa_set_program_error (ctx, Program->Position, error_msg);
1708 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
1709
1710 _mesa_free (error_msg);
1711 return 1;
1712 }
1713
1714 attrib_var->type = vt_attrib;
1715
1716 /* I think this is ok now - karl */
1717 /* XXX: */
1718 /*if (Program->type == GL_FRAGMENT_PROGRAM_ARB) */
1719 {
1720 if (parse_attrib_binding
1721 (ctx, inst, Program, &attrib_var->attrib_binding,
1722 &attrib_var->attrib_binding_idx, &attrib_var->attrib_is_generic))
1723 return 1;
1724 if (generic_attrib_check(*vc_head)) {
1725 _mesa_set_program_error (ctx, Program->Position,
1726 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
1727 _mesa_error (ctx, GL_INVALID_OPERATION,
1728 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
1729 return 1;
1730 }
1731
1732 }
1733
1734 Program->Base.NumAttributes++;
1735 return 0;
1736 }
1737
1738 /**
1739 * \param use -- TRUE if we're called when declaring implicit parameters,
1740 * FALSE if we're declaraing variables. This has to do with
1741 * if we get a signed or unsigned float for scalar constants
1742 */
1743 static GLuint
1744 parse_param_elements (GLcontext * ctx, GLubyte ** inst,
1745 struct var_cache *param_var,
1746 struct arb_program *Program, GLboolean use)
1747 {
1748 GLint idx;
1749 GLuint err;
1750 GLint state_tokens[6];
1751 GLfloat const_values[4];
1752
1753 err = 0;
1754
1755 switch (*(*inst)++) {
1756 case PARAM_STATE_ELEMENT:
1757
1758 if (parse_state_single_item (ctx, inst, Program, state_tokens))
1759 return 1;
1760
1761 /* If we adding STATE_MATRIX that has multiple rows, we need to
1762 * unroll it and call _mesa_add_state_reference() for each row
1763 */
1764 if ((state_tokens[0] == STATE_MATRIX)
1765 && (state_tokens[3] != state_tokens[4])) {
1766 GLint row;
1767 GLint first_row = state_tokens[3];
1768 GLint last_row = state_tokens[4];
1769
1770 for (row = first_row; row <= last_row; row++) {
1771 state_tokens[3] = state_tokens[4] = row;
1772
1773 idx =
1774 _mesa_add_state_reference (Program->Parameters,
1775 state_tokens);
1776 if (param_var->param_binding_begin == ~0U)
1777 param_var->param_binding_begin = idx;
1778 param_var->param_binding_length++;
1779 Program->Base.NumParameters++;
1780 }
1781 }
1782 else {
1783 idx =
1784 _mesa_add_state_reference (Program->Parameters, state_tokens);
1785 if (param_var->param_binding_begin == ~0U)
1786 param_var->param_binding_begin = idx;
1787 param_var->param_binding_length++;
1788 Program->Base.NumParameters++;
1789 }
1790 break;
1791
1792 case PARAM_PROGRAM_ELEMENT:
1793
1794 if (parse_program_single_item (ctx, inst, Program, state_tokens))
1795 return 1;
1796 idx = _mesa_add_state_reference (Program->Parameters, state_tokens);
1797 if (param_var->param_binding_begin == ~0U)
1798 param_var->param_binding_begin = idx;
1799 param_var->param_binding_length++;
1800 Program->Base.NumParameters++;
1801
1802 /* Check if there is more: 0 -> we're done, else its an integer */
1803 if (**inst) {
1804 GLuint out_of_range, new_idx;
1805 GLuint start_idx = state_tokens[2] + 1;
1806 GLuint end_idx = parse_integer (inst, Program);
1807
1808 out_of_range = 0;
1809 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
1810 if (((state_tokens[1] == STATE_ENV)
1811 && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams))
1812 || ((state_tokens[1] == STATE_LOCAL)
1813 && (end_idx >=
1814 ctx->Const.MaxFragmentProgramLocalParams)))
1815 out_of_range = 1;
1816 }
1817 else {
1818 if (((state_tokens[1] == STATE_ENV)
1819 && (end_idx >= ctx->Const.MaxVertexProgramEnvParams))
1820 || ((state_tokens[1] == STATE_LOCAL)
1821 && (end_idx >=
1822 ctx->Const.MaxVertexProgramLocalParams)))
1823 out_of_range = 1;
1824 }
1825 if (out_of_range) {
1826 _mesa_set_program_error (ctx, Program->Position,
1827 "Invalid Program Parameter");
1828 _mesa_error (ctx, GL_INVALID_OPERATION,
1829 "Invalid Program Parameter: %d", end_idx);
1830 return 1;
1831 }
1832
1833 for (new_idx = start_idx; new_idx <= end_idx; new_idx++) {
1834 state_tokens[2] = new_idx;
1835 idx =
1836 _mesa_add_state_reference (Program->Parameters,
1837 state_tokens);
1838 param_var->param_binding_length++;
1839 Program->Base.NumParameters++;
1840 }
1841 }
1842 else
1843 {
1844 (*inst)++;
1845 }
1846 break;
1847
1848 case PARAM_CONSTANT:
1849 parse_constant (inst, const_values, Program, use);
1850 idx =
1851 _mesa_add_named_constant (Program->Parameters,
1852 (char *) param_var->name, const_values);
1853 if (param_var->param_binding_begin == ~0U)
1854 param_var->param_binding_begin = idx;
1855 param_var->param_binding_length++;
1856 Program->Base.NumParameters++;
1857 break;
1858
1859 default:
1860 _mesa_set_program_error (ctx, Program->Position,
1861 "Unexpected token in parse_param_elements()");
1862 _mesa_error (ctx, GL_INVALID_OPERATION,
1863 "Unexpected token in parse_param_elements()");
1864 return 1;
1865 }
1866
1867 /* Make sure we haven't blown past our parameter limits */
1868 if (((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
1869 (Program->Base.NumParameters >=
1870 ctx->Const.MaxVertexProgramLocalParams))
1871 || ((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
1872 && (Program->Base.NumParameters >=
1873 ctx->Const.MaxFragmentProgramLocalParams))) {
1874 _mesa_set_program_error (ctx, Program->Position,
1875 "Too many parameter variables");
1876 _mesa_error (ctx, GL_INVALID_OPERATION, "Too many parameter variables");
1877 return 1;
1878 }
1879
1880 return err;
1881 }
1882
1883 /**
1884 * This picks out PARAM program parameter bindings.
1885 *
1886 * XXX: This needs to be stressed & tested
1887 *
1888 * \return 0 on sucess, 1 on error
1889 */
1890 static GLuint
1891 parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
1892 struct arb_program *Program)
1893 {
1894 GLuint found, err;
1895 GLint specified_length;
1896 char *error_msg;
1897 struct var_cache *param_var;
1898
1899 err = 0;
1900 param_var = parse_string (inst, vc_head, Program, &found);
1901 Program->Position = parse_position (inst);
1902
1903 if (found) {
1904 error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
1905 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
1906 param_var->name);
1907
1908 _mesa_set_program_error (ctx, Program->Position, error_msg);
1909 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
1910
1911 _mesa_free (error_msg);
1912 return 1;
1913 }
1914
1915 specified_length = parse_integer (inst, Program);
1916
1917 if (specified_length < 0) {
1918 _mesa_set_program_error (ctx, Program->Position,
1919 "Negative parameter array length");
1920 _mesa_error (ctx, GL_INVALID_OPERATION,
1921 "Negative parameter array length: %d", specified_length);
1922 return 1;
1923 }
1924
1925 param_var->type = vt_param;
1926 param_var->param_binding_length = 0;
1927
1928 /* Right now, everything is shoved into the main state register file.
1929 *
1930 * In the future, it would be nice to leave things ENV/LOCAL params
1931 * in their respective register files, if possible
1932 */
1933 param_var->param_binding_type = PROGRAM_STATE_VAR;
1934
1935 /* Remember to:
1936 * * - add each guy to the parameter list
1937 * * - increment the param_var->param_binding_len
1938 * * - store the param_var->param_binding_begin for the first one
1939 * * - compare the actual len to the specified len at the end
1940 */
1941 while (**inst != PARAM_NULL) {
1942 if (parse_param_elements (ctx, inst, param_var, Program, GL_FALSE))
1943 return 1;
1944 }
1945
1946 /* Test array length here! */
1947 if (specified_length) {
1948 if (specified_length != (int)param_var->param_binding_length) {
1949 _mesa_set_program_error (ctx, Program->Position,
1950 "Declared parameter array lenght does not match parameter list");
1951 _mesa_error (ctx, GL_INVALID_OPERATION,
1952 "Declared parameter array lenght does not match parameter list");
1953 }
1954 }
1955
1956 (*inst)++;
1957
1958 return 0;
1959 }
1960
1961 /**
1962 *
1963 */
1964 static GLuint
1965 parse_param_use (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
1966 struct arb_program *Program, struct var_cache **new_var)
1967 {
1968 struct var_cache *param_var;
1969
1970 /* First, insert a dummy entry into the var_cache */
1971 var_cache_create (&param_var);
1972 param_var->name = (GLubyte *) _mesa_strdup (" ");
1973 param_var->type = vt_param;
1974
1975 param_var->param_binding_length = 0;
1976 /* Don't fill in binding_begin; We use the default value of -1
1977 * to tell if its already initialized, elsewhere.
1978 *
1979 * param_var->param_binding_begin = 0;
1980 */
1981 param_var->param_binding_type = PROGRAM_STATE_VAR;
1982
1983 var_cache_append (vc_head, param_var);
1984
1985 /* Then fill it with juicy parameter goodness */
1986 if (parse_param_elements (ctx, inst, param_var, Program, GL_TRUE))
1987 return 1;
1988
1989 *new_var = param_var;
1990
1991 return 0;
1992 }
1993
1994
1995 /**
1996 * This handles the declaration of TEMP variables
1997 *
1998 * \return 0 on sucess, 1 on error
1999 */
2000 static GLuint
2001 parse_temp (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
2002 struct arb_program *Program)
2003 {
2004 GLuint found;
2005 struct var_cache *temp_var;
2006 char *error_msg;
2007
2008 while (**inst != 0) {
2009 temp_var = parse_string (inst, vc_head, Program, &found);
2010 Program->Position = parse_position (inst);
2011 if (found) {
2012 error_msg = (char *)
2013 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
2014 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
2015 temp_var->name);
2016
2017 _mesa_set_program_error (ctx, Program->Position, error_msg);
2018 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
2019
2020 _mesa_free (error_msg);
2021 return 1;
2022 }
2023
2024 temp_var->type = vt_temp;
2025
2026 if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&
2027 (Program->Base.NumTemporaries >=
2028 ctx->Const.MaxFragmentProgramTemps))
2029 || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB)
2030 && (Program->Base.NumTemporaries >=
2031 ctx->Const.MaxVertexProgramTemps))) {
2032 _mesa_set_program_error (ctx, Program->Position,
2033 "Too many TEMP variables declared");
2034 _mesa_error (ctx, GL_INVALID_OPERATION,
2035 "Too many TEMP variables declared");
2036 return 1;
2037 }
2038
2039 temp_var->temp_binding = Program->Base.NumTemporaries;
2040 Program->Base.NumTemporaries++;
2041 }
2042 (*inst)++;
2043
2044 return 0;
2045 }
2046
2047 /**
2048 * This handles variables of the OUTPUT variety
2049 *
2050 * \return 0 on sucess, 1 on error
2051 */
2052 static GLuint
2053 parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
2054 struct arb_program *Program)
2055 {
2056 GLuint found;
2057 struct var_cache *output_var;
2058
2059 output_var = parse_string (inst, vc_head, Program, &found);
2060 Program->Position = parse_position (inst);
2061 if (found) {
2062 char *error_msg;
2063 error_msg = (char *)
2064 _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);
2065 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
2066 output_var->name);
2067
2068 _mesa_set_program_error (ctx, Program->Position, error_msg);
2069 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
2070
2071 _mesa_free (error_msg);
2072 return 1;
2073 }
2074
2075 output_var->type = vt_output;
2076 return parse_result_binding (ctx, inst, &output_var->output_binding,
2077 &output_var->output_binding_idx, Program);
2078 }
2079
2080 /**
2081 * This handles variables of the ALIAS kind
2082 *
2083 * \return 0 on sucess, 1 on error
2084 */
2085 static GLuint
2086 parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
2087 struct arb_program *Program)
2088 {
2089 GLuint found;
2090 struct var_cache *temp_var;
2091 char *error_msg;
2092
2093
2094 temp_var = parse_string (inst, vc_head, Program, &found);
2095 Program->Position = parse_position (inst);
2096
2097 if (found) {
2098 error_msg = (char *)
2099 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
2100 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
2101 temp_var->name);
2102
2103 _mesa_set_program_error (ctx, Program->Position, error_msg);
2104 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
2105
2106 _mesa_free (error_msg);
2107 return 1;
2108 }
2109
2110 temp_var->type = vt_alias;
2111 temp_var->alias_binding = parse_string (inst, vc_head, Program, &found);
2112 Program->Position = parse_position (inst);
2113
2114 if (!found)
2115 {
2116 error_msg = (char *)
2117 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
2118 _mesa_sprintf (error_msg, "Alias value %s is not defined",
2119 temp_var->alias_binding->name);
2120
2121 _mesa_set_program_error (ctx, Program->Position, error_msg);
2122 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
2123
2124 _mesa_free (error_msg);
2125 return 1;
2126 }
2127
2128 return 0;
2129 }
2130
2131 /**
2132 * This handles variables of the ADDRESS kind
2133 *
2134 * \return 0 on sucess, 1 on error
2135 */
2136 static GLuint
2137 parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
2138 struct arb_program *Program)
2139 {
2140 GLuint found;
2141 struct var_cache *temp_var;
2142 char *error_msg;
2143
2144 while (**inst != 0) {
2145 temp_var = parse_string (inst, vc_head, Program, &found);
2146 Program->Position = parse_position (inst);
2147 if (found) {
2148 error_msg = (char *)
2149 _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
2150 _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
2151 temp_var->name);
2152
2153 _mesa_set_program_error (ctx, Program->Position, error_msg);
2154 _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
2155
2156 _mesa_free (error_msg);
2157 return 1;
2158 }
2159
2160 temp_var->type = vt_address;
2161
2162 if (Program->Base.NumAddressRegs >=
2163 ctx->Const.MaxVertexProgramAddressRegs) {
2164 _mesa_set_program_error (ctx, Program->Position,
2165 "Too many ADDRESS variables declared");
2166 _mesa_error (ctx, GL_INVALID_OPERATION,
2167 "Too many ADDRESS variables declared");
2168 return 1;
2169 }
2170
2171 temp_var->address_binding = Program->Base.NumAddressRegs;
2172 Program->Base.NumAddressRegs++;
2173 }
2174 (*inst)++;
2175
2176 return 0;
2177 }
2178
2179 /**
2180 * Parse a program declaration
2181 *
2182 * \return 0 on sucess, 1 on error
2183 */
2184 static GLint
2185 parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
2186 struct arb_program *Program)
2187 {
2188 GLint err = 0;
2189
2190 switch (*(*inst)++) {
2191 case ADDRESS:
2192 err = parse_address (ctx, inst, vc_head, Program);
2193 break;
2194
2195 case ALIAS:
2196 err = parse_alias (ctx, inst, vc_head, Program);
2197 break;
2198
2199 case ATTRIB:
2200 err = parse_attrib (ctx, inst, vc_head, Program);
2201 break;
2202
2203 case OUTPUT:
2204 err = parse_output (ctx, inst, vc_head, Program);
2205 break;
2206
2207 case PARAM:
2208 err = parse_param (ctx, inst, vc_head, Program);
2209 break;
2210
2211 case TEMP:
2212 err = parse_temp (ctx, inst, vc_head, Program);
2213 break;
2214 }
2215
2216 return err;
2217 }
2218
2219 /**
2220 * Handle the parsing out of a masked destination register
2221 *
2222 * If we are a vertex program, make sure we don't write to
2223 * result.position of we have specified that the program is
2224 * position invariant
2225 *
2226 * \param File - The register file we write to
2227 * \param Index - The register index we write to
2228 * \param WriteMask - The mask controlling which components we write (1->write)
2229 *
2230 * \return 0 on sucess, 1 on error
2231 */
2232 static GLuint
2233 parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
2234 struct var_cache **vc_head, struct arb_program *Program,
2235 GLint * File, GLint * Index, GLboolean * WriteMask)
2236 {
2237 GLuint result;
2238 GLubyte mask;
2239 struct var_cache *dst;
2240
2241 /* We either have a result register specified, or a
2242 * variable that may or may not be writable
2243 */
2244 switch (*(*inst)++) {
2245 case REGISTER_RESULT:
2246 if (parse_result_binding
2247 (ctx, inst, &result, (GLuint *) Index, Program))
2248 return 1;
2249 *File = PROGRAM_OUTPUT;
2250 break;
2251
2252 case REGISTER_ESTABLISHED_NAME:
2253 dst = parse_string (inst, vc_head, Program, &result);
2254 Program->Position = parse_position (inst);
2255
2256 /* If the name has never been added to our symbol table, we're hosed */
2257 if (!result) {
2258 _mesa_set_program_error (ctx, Program->Position,
2259 "0: Undefined variable");
2260 _mesa_error (ctx, GL_INVALID_OPERATION, "0: Undefined variable: %s",
2261 dst->name);
2262 return 1;
2263 }
2264
2265 switch (dst->type) {
2266 case vt_output:
2267 *File = PROGRAM_OUTPUT;
2268 *Index = dst->output_binding_idx;
2269 break;
2270
2271 case vt_temp:
2272 *File = PROGRAM_TEMPORARY;
2273 *Index = dst->temp_binding;
2274 break;
2275
2276 /* If the var type is not vt_output or vt_temp, no go */
2277 default:
2278 _mesa_set_program_error (ctx, Program->Position,
2279 "Destination register is read only");
2280 _mesa_error (ctx, GL_INVALID_OPERATION,
2281 "Destination register is read only: %s",
2282 dst->name);
2283 return 1;
2284 }
2285 break;
2286
2287 default:
2288 _mesa_set_program_error (ctx, Program->Position,
2289 "Unexpected opcode in parse_masked_dst_reg()");
2290 _mesa_error (ctx, GL_INVALID_OPERATION,
2291 "Unexpected opcode in parse_masked_dst_reg()");
2292 return 1;
2293 }
2294
2295
2296 /* Position invariance test */
2297 /* This test is done now in syntax portion - when position invariance OPTION
2298 is specified, "result.position" rule is disabled so there is no way
2299 to write the position
2300 */
2301 /*if ((Program->HintPositionInvariant) && (*File == PROGRAM_OUTPUT) &&
2302 (*Index == 0)) {
2303 _mesa_set_program_error (ctx, Program->Position,
2304 "Vertex program specified position invariance and wrote vertex position");
2305 _mesa_error (ctx, GL_INVALID_OPERATION,
2306 "Vertex program specified position invariance and wrote vertex position");
2307 }*/
2308
2309 /* And then the mask.
2310 * w,a -> bit 0
2311 * z,b -> bit 1
2312 * y,g -> bit 2
2313 * x,r -> bit 3
2314 */
2315 mask = *(*inst)++;
2316
2317 WriteMask[0] = (GLboolean) (mask & (1 << 3)) >> 3;
2318 WriteMask[1] = (GLboolean) (mask & (1 << 2)) >> 2;
2319 WriteMask[2] = (GLboolean) (mask & (1 << 1)) >> 1;
2320 WriteMask[3] = (GLboolean) (mask & (1));
2321
2322 return 0;
2323 }
2324
2325
2326 /**
2327 * Handle the parsing of a address register
2328 *
2329 * \param Index - The register index we write to
2330 *
2331 * \return 0 on sucess, 1 on error
2332 */
2333 static GLuint
2334 parse_address_reg (GLcontext * ctx, GLubyte ** inst,
2335 struct var_cache **vc_head,
2336 struct arb_program *Program, GLint * Index)
2337 {
2338 struct var_cache *dst;
2339 GLuint result;
2340 (void) Index;
2341
2342 dst = parse_string (inst, vc_head, Program, &result);
2343 Program->Position = parse_position (inst);
2344
2345 /* If the name has never been added to our symbol table, we're hosed */
2346 if (!result) {
2347 _mesa_set_program_error (ctx, Program->Position, "Undefined variable");
2348 _mesa_error (ctx, GL_INVALID_OPERATION, "Undefined variable: %s",
2349 dst->name);
2350 return 1;
2351 }
2352
2353 if (dst->type != vt_address) {
2354 _mesa_set_program_error (ctx, Program->Position,
2355 "Variable is not of type ADDRESS");
2356 _mesa_error (ctx, GL_INVALID_OPERATION,
2357 "Variable: %s is not of type ADDRESS", dst->name);
2358 return 1;
2359 }
2360
2361 return 0;
2362 }
2363
2364 /**
2365 * Handle the parsing out of a masked address register
2366 *
2367 * \param Index - The register index we write to
2368 * \param WriteMask - The mask controlling which components we write (1->write)
2369 *
2370 * \return 0 on sucess, 1 on error
2371 */
2372 static GLuint
2373 parse_masked_address_reg (GLcontext * ctx, GLubyte ** inst,
2374 struct var_cache **vc_head,
2375 struct arb_program *Program, GLint * Index,
2376 GLboolean * WriteMask)
2377 {
2378 if (parse_address_reg (ctx, inst, vc_head, Program, Index))
2379 return 1;
2380
2381 /* This should be 0x8 */
2382 (*inst)++;
2383
2384 /* Writemask of .x is implied */
2385 WriteMask[0] = 1;
2386 WriteMask[1] = WriteMask[2] = WriteMask[3] = 0;
2387
2388 return 0;
2389 }
2390
2391
2392 /**
2393 * Parse out a swizzle mask.
2394 *
2395 * The values in the input stream are:
2396 * COMPONENT_X -> x/r
2397 * COMPONENT_Y -> y/g
2398 * COMPONENT_Z-> z/b
2399 * COMPONENT_W-> w/a
2400 *
2401 * The values in the output mask are:
2402 * 0 -> x/r
2403 * 1 -> y/g
2404 * 2 -> z/b
2405 * 3 -> w/a
2406 *
2407 * The len parameter allows us to grab 4 components for a vector
2408 * swizzle, or just 1 component for a scalar src register selection
2409 */
2410 static GLuint
2411 parse_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLint len)
2412 {
2413 GLint a;
2414
2415 for (a = 0; a < 4; a++)
2416 mask[a] = a;
2417
2418 for (a = 0; a < len; a++) {
2419 switch (*(*inst)++) {
2420 case COMPONENT_X:
2421 mask[a] = 0;
2422 break;
2423
2424 case COMPONENT_Y:
2425 mask[a] = 1;
2426 break;
2427
2428 case COMPONENT_Z:
2429 mask[a] = 2;
2430 break;
2431
2432 case COMPONENT_W:
2433 mask[a] = 3;
2434 break;
2435 }
2436 }
2437
2438 return 0;
2439 }
2440
2441 /**
2442 */
2443 static GLuint
2444 parse_extended_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLboolean * Negate)
2445 {
2446 GLint a;
2447 GLubyte swz;
2448
2449 *Negate = GL_FALSE;
2450 for (a = 0; a < 4; a++) {
2451 if (parse_sign (inst) == -1)
2452 *Negate = GL_TRUE;
2453
2454 swz = *(*inst)++;
2455
2456 switch (swz) {
2457 case COMPONENT_0:
2458 mask[a] = SWIZZLE_ZERO;
2459 break;
2460 case COMPONENT_1:
2461 mask[a] = SWIZZLE_ONE;
2462 break;
2463 case COMPONENT_X:
2464 mask[a] = SWIZZLE_X;
2465 break;
2466 case COMPONENT_Y:
2467 mask[a] = SWIZZLE_Y;
2468 break;
2469 case COMPONENT_Z:
2470 mask[a] = SWIZZLE_Z;
2471 break;
2472 case COMPONENT_W:
2473 mask[a] = SWIZZLE_W;
2474 break;
2475
2476 }
2477 #if 0
2478 if (swz == 0)
2479 mask[a] = SWIZZLE_ZERO;
2480 else if (swz == 1)
2481 mask[a] = SWIZZLE_ONE;
2482 else
2483 mask[a] = swz - 2;
2484 #endif
2485
2486 }
2487
2488 return 0;
2489 }
2490
2491
2492 static GLuint
2493 parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
2494 struct arb_program *Program, GLint * File, GLint * Index,
2495 GLboolean *IsRelOffset )
2496 {
2497 struct var_cache *src;
2498 GLuint binding_state, binding_idx, is_generic, found;
2499 GLint offset;
2500
2501 /* And the binding for the src */
2502 switch (*(*inst)++) {
2503 case REGISTER_ATTRIB:
2504 if (parse_attrib_binding
2505 (ctx, inst, Program, &binding_state, &binding_idx, &is_generic))
2506 return 1;
2507 *File = PROGRAM_INPUT;
2508 *Index = binding_idx;
2509
2510 /* We need to insert a dummy variable into the var_cache so we can
2511 * catch generic vertex attrib aliasing errors
2512 */
2513 var_cache_create(&src);
2514 src->type = vt_attrib;
2515 src->name = (GLubyte *)_mesa_strdup("Dummy Attrib Variable");
2516 src->attrib_binding = binding_state;
2517 src->attrib_binding_idx = binding_idx;
2518 src->attrib_is_generic = is_generic;
2519 var_cache_append(vc_head, src);
2520 if (generic_attrib_check(*vc_head)) {
2521 _mesa_set_program_error (ctx, Program->Position,
2522 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
2523 _mesa_error (ctx, GL_INVALID_OPERATION,
2524 "Cannot use both a generic vertex attribute and a specific attribute of the same type");
2525 return 1;
2526 }
2527 break;
2528
2529 case REGISTER_PARAM:
2530 switch (**inst) {
2531 case PARAM_ARRAY_ELEMENT:
2532 (*inst)++;
2533 src = parse_string (inst, vc_head, Program, &found);
2534 Program->Position = parse_position (inst);
2535
2536 if (!found) {
2537 _mesa_set_program_error (ctx, Program->Position,
2538 "2: Undefined variable");
2539 _mesa_error (ctx, GL_INVALID_OPERATION,
2540 "2: Undefined variable: %s", src->name);
2541 return 1;
2542 }
2543
2544 *File = src->param_binding_type;
2545
2546 switch (*(*inst)++) {
2547 case ARRAY_INDEX_ABSOLUTE:
2548 offset = parse_integer (inst, Program);
2549
2550 if ((offset < 0)
2551 || (offset >= (int)src->param_binding_length)) {
2552 _mesa_set_program_error (ctx, Program->Position,
2553 "Index out of range");
2554 _mesa_error (ctx, GL_INVALID_OPERATION,
2555 "Index %d out of range for %s", offset,
2556 src->name);
2557 return 1;
2558 }
2559
2560 *Index = src->param_binding_begin + offset;
2561 break;
2562
2563 case ARRAY_INDEX_RELATIVE:
2564 {
2565 GLint addr_reg_idx, rel_off;
2566
2567 /* First, grab the address regiseter */
2568 if (parse_address_reg (ctx, inst, vc_head, Program, &addr_reg_idx))
2569 return 1;
2570
2571 /* And the .x */
2572 ((*inst)++);
2573 ((*inst)++);
2574 ((*inst)++);
2575 ((*inst)++);
2576
2577 /* Then the relative offset */
2578 if (parse_relative_offset(ctx, inst, Program, &rel_off)) return 1;
2579
2580 /* And store it properly */
2581 *Index = src->param_binding_begin + rel_off;
2582 *IsRelOffset = 1;
2583 }
2584 break;
2585 }
2586 break;
2587
2588 default:
2589
2590 if (parse_param_use (ctx, inst, vc_head, Program, &src))
2591 return 1;
2592
2593 *File = src->param_binding_type;
2594 *Index = src->param_binding_begin;
2595 break;
2596 }
2597 break;
2598
2599 case REGISTER_ESTABLISHED_NAME:
2600
2601 src = parse_string (inst, vc_head, Program, &found);
2602 Program->Position = parse_position (inst);
2603
2604 /* If the name has never been added to our symbol table, we're hosed */
2605 if (!found) {
2606 _mesa_set_program_error (ctx, Program->Position,
2607 "3: Undefined variable");
2608 _mesa_error (ctx, GL_INVALID_OPERATION, "3: Undefined variable: %s",
2609 src->name);
2610 return 1;
2611 }
2612
2613 switch (src->type) {
2614 case vt_attrib:
2615 *File = PROGRAM_INPUT;
2616 *Index = src->attrib_binding_idx;
2617 break;
2618
2619 /* XXX: We have to handle offsets someplace in here! -- or are those above? */
2620 case vt_param:
2621 *File = src->param_binding_type;
2622 *Index = src->param_binding_begin;
2623 break;
2624
2625 case vt_temp:
2626 *File = PROGRAM_TEMPORARY;
2627 *Index = src->temp_binding;
2628 break;
2629
2630 /* If the var type is vt_output no go */
2631 default:
2632 _mesa_set_program_error (ctx, Program->Position,
2633 "destination register is read only");
2634 _mesa_error (ctx, GL_INVALID_OPERATION,
2635 "destination register is read only: %s",
2636 src->name);
2637 return 1;
2638 }
2639 break;
2640
2641 default:
2642 _mesa_set_program_error (ctx, Program->Position,
2643 "Unknown token in parse_src_reg");
2644 _mesa_error (ctx, GL_INVALID_OPERATION,
2645 "Unknown token in parse_src_reg");
2646 return 1;
2647 }
2648
2649 return 0;
2650 }
2651
2652 /**
2653 */
2654 static GLuint
2655 parse_vector_src_reg (GLcontext * ctx, GLubyte ** inst,
2656 struct var_cache **vc_head, struct arb_program *Program,
2657 GLint * File, GLint * Index, GLboolean * Negate,
2658 GLubyte * Swizzle, GLboolean *IsRelOffset)
2659 {
2660 /* Grab the sign */
2661 *Negate = (parse_sign (inst) == -1);
2662
2663 /* And the src reg */
2664 if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset))
2665 return 1;
2666
2667 /* finally, the swizzle */
2668 parse_swizzle_mask (inst, Swizzle, 4);
2669
2670 return 0;
2671 }
2672
2673 /**
2674 */
2675 static GLuint
2676 parse_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
2677 struct var_cache **vc_head, struct arb_program *Program,
2678 GLint * File, GLint * Index, GLboolean * Negate,
2679 GLubyte * Swizzle, GLboolean *IsRelOffset)
2680 {
2681 /* Grab the sign */
2682 *Negate = (parse_sign (inst) == -1);
2683
2684 /* And the src reg */
2685 if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset))
2686 return 1;
2687
2688 /* Now, get the component and shove it into all the swizzle slots */
2689 parse_swizzle_mask (inst, Swizzle, 1);
2690
2691 return 0;
2692 }
2693
2694 /**
2695 * This is a big mother that handles getting opcodes into the instruction
2696 * and handling the src & dst registers for fragment program instructions
2697 */
2698 static GLuint
2699 parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
2700 struct var_cache **vc_head, struct arb_program *Program,
2701 struct fp_instruction *fp)
2702 {
2703 GLint a, b;
2704 GLubyte swz[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */
2705 GLuint texcoord;
2706 GLubyte instClass, type, code;
2707 GLboolean rel;
2708
2709 /* No condition codes in ARB_fp */
2710 fp->UpdateCondRegister = 0;
2711
2712 /* Record the position in the program string for debugging */
2713 fp->StringPos = Program->Position;
2714
2715 fp->Data = NULL;
2716
2717 /* OP_ALU_INST or OP_TEX_INST */
2718 instClass = *(*inst)++;
2719
2720 /* OP_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ},
2721 * OP_TEX_{SAMPLE, KIL}
2722 */
2723 type = *(*inst)++;
2724
2725 /* The actual opcode name */
2726 code = *(*inst)++;
2727
2728 /* Increment the correct count */
2729 switch (instClass) {
2730 case OP_ALU_INST:
2731 Program->NumAluInstructions++;
2732 break;
2733 case OP_TEX_INST:
2734 Program->NumTexInstructions++;
2735 break;
2736 }
2737
2738 fp->Saturate = 0;
2739 fp->Precision = FLOAT32;
2740
2741 fp->DstReg.CondMask = COND_TR;
2742
2743 switch (type) {
2744 case OP_ALU_VECTOR:
2745 switch (code) {
2746 case OP_ABS_SAT:
2747 fp->Saturate = 1;
2748 case OP_ABS:
2749 fp->Opcode = FP_OPCODE_ABS;
2750 break;
2751
2752 case OP_FLR_SAT:
2753 fp->Saturate = 1;
2754 case OP_FLR:
2755 fp->Opcode = FP_OPCODE_FLR;
2756 break;
2757
2758 case OP_FRC_SAT:
2759 fp->Saturate = 1;
2760 case OP_FRC:
2761 fp->Opcode = FP_OPCODE_FRC;
2762 break;
2763
2764 case OP_LIT_SAT:
2765 fp->Saturate = 1;
2766 case OP_LIT:
2767 fp->Opcode = FP_OPCODE_LIT;
2768 break;
2769
2770 case OP_MOV_SAT:
2771 fp->Saturate = 1;
2772 case OP_MOV:
2773 fp->Opcode = FP_OPCODE_MOV;
2774 break;
2775 }
2776
2777 if (parse_masked_dst_reg
2778 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2779 &fp->DstReg.Index, fp->DstReg.WriteMask))
2780 return 1;
2781
2782 fp->SrcReg[0].Abs = GL_FALSE;
2783 fp->SrcReg[0].NegateAbs = GL_FALSE;
2784 if (parse_vector_src_reg
2785 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
2786 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
2787 swz, &rel))
2788 return 1;
2789 for (b=0; b<4; b++)
2790 fp->SrcReg[0].Swizzle[b] = swz[b];
2791 break;
2792
2793 case OP_ALU_SCALAR:
2794 switch (code) {
2795 case OP_COS_SAT:
2796 fp->Saturate = 1;
2797 case OP_COS:
2798 fp->Opcode = FP_OPCODE_COS;
2799 break;
2800
2801 case OP_EX2_SAT:
2802 fp->Saturate = 1;
2803 case OP_EX2:
2804 fp->Opcode = FP_OPCODE_EX2;
2805 break;
2806
2807 case OP_LG2_SAT:
2808 fp->Saturate = 1;
2809 case OP_LG2:
2810 fp->Opcode = FP_OPCODE_LG2;
2811 break;
2812
2813 case OP_RCP_SAT:
2814 fp->Saturate = 1;
2815 case OP_RCP:
2816 fp->Opcode = FP_OPCODE_RCP;
2817 break;
2818
2819 case OP_RSQ_SAT:
2820 fp->Saturate = 1;
2821 case OP_RSQ:
2822 fp->Opcode = FP_OPCODE_RSQ;
2823 break;
2824
2825 case OP_SIN_SAT:
2826 fp->Saturate = 1;
2827 case OP_SIN:
2828 fp->Opcode = FP_OPCODE_SIN;
2829 break;
2830
2831 case OP_SCS_SAT:
2832 fp->Saturate = 1;
2833 case OP_SCS:
2834
2835 fp->Opcode = FP_OPCODE_SCS;
2836 break;
2837 }
2838
2839 if (parse_masked_dst_reg
2840 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2841 &fp->DstReg.Index, fp->DstReg.WriteMask))
2842 return 1;
2843 fp->SrcReg[0].Abs = GL_FALSE;
2844 fp->SrcReg[0].NegateAbs = GL_FALSE;
2845 if (parse_scalar_src_reg
2846 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
2847 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
2848 swz, &rel))
2849 return 1;
2850 for (b=0; b<4; b++)
2851 fp->SrcReg[0].Swizzle[b] = swz[b];
2852 break;
2853
2854 case OP_ALU_BINSC:
2855 switch (code) {
2856 case OP_POW_SAT:
2857 fp->Saturate = 1;
2858 case OP_POW:
2859 fp->Opcode = FP_OPCODE_POW;
2860 break;
2861 }
2862
2863 if (parse_masked_dst_reg
2864 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2865 &fp->DstReg.Index, fp->DstReg.WriteMask))
2866 return 1;
2867 for (a = 0; a < 2; a++) {
2868 fp->SrcReg[a].Abs = GL_FALSE;
2869 fp->SrcReg[a].NegateAbs = GL_FALSE;
2870 if (parse_scalar_src_reg
2871 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
2872 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
2873 swz, &rel))
2874 return 1;
2875 for (b=0; b<4; b++)
2876 fp->SrcReg[a].Swizzle[b] = swz[b];
2877 }
2878 break;
2879
2880
2881 case OP_ALU_BIN:
2882 switch (code) {
2883 case OP_ADD_SAT:
2884 fp->Saturate = 1;
2885 case OP_ADD:
2886 fp->Opcode = FP_OPCODE_ADD;
2887 break;
2888
2889 case OP_DP3_SAT:
2890 fp->Saturate = 1;
2891 case OP_DP3:
2892 fp->Opcode = FP_OPCODE_DP3;
2893 break;
2894
2895 case OP_DP4_SAT:
2896 fp->Saturate = 1;
2897 case OP_DP4:
2898 fp->Opcode = FP_OPCODE_DP4;
2899 break;
2900
2901 case OP_DPH_SAT:
2902 fp->Saturate = 1;
2903 case OP_DPH:
2904 fp->Opcode = FP_OPCODE_DPH;
2905 break;
2906
2907 case OP_DST_SAT:
2908 fp->Saturate = 1;
2909 case OP_DST:
2910 fp->Opcode = FP_OPCODE_DST;
2911 break;
2912
2913 case OP_MAX_SAT:
2914 fp->Saturate = 1;
2915 case OP_MAX:
2916 fp->Opcode = FP_OPCODE_MAX;
2917 break;
2918
2919 case OP_MIN_SAT:
2920 fp->Saturate = 1;
2921 case OP_MIN:
2922 fp->Opcode = FP_OPCODE_MIN;
2923 break;
2924
2925 case OP_MUL_SAT:
2926 fp->Saturate = 1;
2927 case OP_MUL:
2928 fp->Opcode = FP_OPCODE_MUL;
2929 break;
2930
2931 case OP_SGE_SAT:
2932 fp->Saturate = 1;
2933 case OP_SGE:
2934 fp->Opcode = FP_OPCODE_SGE;
2935 break;
2936
2937 case OP_SLT_SAT:
2938 fp->Saturate = 1;
2939 case OP_SLT:
2940 fp->Opcode = FP_OPCODE_SLT;
2941 break;
2942
2943 case OP_SUB_SAT:
2944 fp->Saturate = 1;
2945 case OP_SUB:
2946 fp->Opcode = FP_OPCODE_SUB;
2947 break;
2948
2949 case OP_XPD_SAT:
2950 fp->Saturate = 1;
2951 case OP_XPD:
2952 fp->Opcode = FP_OPCODE_XPD;
2953 break;
2954 }
2955
2956 if (parse_masked_dst_reg
2957 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2958 &fp->DstReg.Index, fp->DstReg.WriteMask))
2959 return 1;
2960 for (a = 0; a < 2; a++) {
2961 fp->SrcReg[a].Abs = GL_FALSE;
2962 fp->SrcReg[a].NegateAbs = GL_FALSE;
2963 if (parse_vector_src_reg
2964 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
2965 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
2966 swz, &rel))
2967 return 1;
2968 for (b=0; b<4; b++)
2969 fp->SrcReg[a].Swizzle[b] = swz[b];
2970 }
2971 break;
2972
2973 case OP_ALU_TRI:
2974 switch (code) {
2975 case OP_CMP_SAT:
2976 fp->Saturate = 1;
2977 case OP_CMP:
2978 fp->Opcode = FP_OPCODE_CMP;
2979 break;
2980
2981 case OP_LRP_SAT:
2982 fp->Saturate = 1;
2983 case OP_LRP:
2984 fp->Opcode = FP_OPCODE_LRP;
2985 break;
2986
2987 case OP_MAD_SAT:
2988 fp->Saturate = 1;
2989 case OP_MAD:
2990 fp->Opcode = FP_OPCODE_MAD;
2991 break;
2992 }
2993
2994 if (parse_masked_dst_reg
2995 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2996 &fp->DstReg.Index, fp->DstReg.WriteMask))
2997 return 1;
2998 for (a = 0; a < 3; a++) {
2999 fp->SrcReg[a].Abs = GL_FALSE;
3000 fp->SrcReg[a].NegateAbs = GL_FALSE;
3001 if (parse_vector_src_reg
3002 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
3003 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
3004 swz, &rel))
3005 return 1;
3006 for (b=0; b<4; b++)
3007 fp->SrcReg[a].Swizzle[b] = swz[b];
3008 }
3009 break;
3010
3011 case OP_ALU_SWZ:
3012 switch (code) {
3013 case OP_SWZ_SAT:
3014 fp->Saturate = 1;
3015 case OP_SWZ:
3016 fp->Opcode = FP_OPCODE_SWZ;
3017 break;
3018 }
3019 if (parse_masked_dst_reg
3020 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
3021 &fp->DstReg.Index, fp->DstReg.WriteMask))
3022 return 1;
3023
3024 if (parse_src_reg
3025 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
3026 &fp->SrcReg[0].Index, &rel))
3027 return 1;
3028 parse_extended_swizzle_mask (inst, swz,
3029 &fp->SrcReg[0].NegateBase);
3030 for (b=0; b<4; b++)
3031 fp->SrcReg[0].Swizzle[b] = swz[b];
3032 break;
3033
3034 case OP_TEX_SAMPLE:
3035 switch (code) {
3036 case OP_TEX_SAT:
3037 fp->Saturate = 1;
3038 case OP_TEX:
3039 fp->Opcode = FP_OPCODE_TEX;
3040 break;
3041
3042 case OP_TXP_SAT:
3043 fp->Saturate = 1;
3044 case OP_TXP:
3045 fp->Opcode = FP_OPCODE_TXP;
3046 break;
3047
3048 case OP_TXB_SAT:
3049
3050 fp->Saturate = 1;
3051 case OP_TXB:
3052 fp->Opcode = FP_OPCODE_TXB;
3053 break;
3054 }
3055
3056 if (parse_masked_dst_reg
3057 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
3058 &fp->DstReg.Index, fp->DstReg.WriteMask))
3059 return 1;
3060 fp->SrcReg[0].Abs = GL_FALSE;
3061 fp->SrcReg[0].NegateAbs = GL_FALSE;
3062 if (parse_vector_src_reg
3063 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
3064 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
3065 swz, &rel))
3066 return 1;
3067 for (b=0; b<4; b++)
3068 fp->SrcReg[0].Swizzle[b] = swz[b];
3069
3070 /* texImageUnit */
3071 if (parse_texcoord_num (ctx, inst, Program, &texcoord))
3072 return 1;
3073 fp->TexSrcUnit = texcoord;
3074
3075 /* texTarget */
3076 switch (*(*inst)++) {
3077 case TEXTARGET_1D:
3078 fp->TexSrcBit = TEXTURE_1D_BIT;
3079 break;
3080 case TEXTARGET_2D:
3081 fp->TexSrcBit = TEXTURE_2D_BIT;
3082 break;
3083 case TEXTARGET_3D:
3084 fp->TexSrcBit = TEXTURE_3D_BIT;
3085 break;
3086 case TEXTARGET_RECT:
3087 fp->TexSrcBit = TEXTURE_RECT_BIT;
3088 break;
3089 case TEXTARGET_CUBE:
3090 fp->TexSrcBit = TEXTURE_CUBE_BIT;
3091 break;
3092 case TEXTARGET_SHADOW1D:
3093 case TEXTARGET_SHADOW2D:
3094 case TEXTARGET_SHADOWRECT:
3095 /* TODO ARB_fragment_program_shadow code */
3096 break;
3097 }
3098 Program->TexturesUsed[texcoord] |= fp->TexSrcBit;
3099 break;
3100
3101 case OP_TEX_KIL:
3102 fp->Opcode = FP_OPCODE_KIL;
3103 fp->SrcReg[0].Abs = GL_FALSE;
3104 fp->SrcReg[0].NegateAbs = GL_FALSE;
3105 if (parse_vector_src_reg
3106 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
3107 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
3108 swz, &rel))
3109 return 1;
3110 for (b=0; b<4; b++)
3111 fp->SrcReg[0].Swizzle[b] = swz[b];
3112 break;
3113 }
3114
3115 return 0;
3116 }
3117
3118 /**
3119 * This is a big mother that handles getting opcodes into the instruction
3120 * and handling the src & dst registers for vertex program instructions
3121 */
3122 static GLuint
3123 parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
3124 struct var_cache **vc_head, struct arb_program *Program,
3125 struct vp_instruction *vp)
3126 {
3127 GLint a;
3128 GLubyte type, code;
3129
3130 /* OP_ALU_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */
3131 type = *(*inst)++;
3132
3133 /* The actual opcode name */
3134 code = *(*inst)++;
3135
3136 /* Record the position in the program string for debugging */
3137 vp->StringPos = Program->Position;
3138
3139 vp->Data = NULL;
3140
3141 vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0;
3142
3143 for (a = 0; a < 4; a++) {
3144 vp->SrcReg[0].Swizzle[a] = a;
3145 vp->SrcReg[1].Swizzle[a] = a;
3146 vp->SrcReg[2].Swizzle[a] = a;
3147 vp->DstReg.WriteMask[a] = 1;
3148 }
3149
3150 switch (type) {
3151 /* XXX: */
3152 case OP_ALU_ARL:
3153 vp->Opcode = VP_OPCODE_ARL;
3154
3155 /* Remember to set SrcReg.RelAddr; */
3156
3157 /* Get the masked address register [dst] */
3158 if (parse_masked_address_reg
3159 (ctx, inst, vc_head, Program, &vp->DstReg.Index,
3160 vp->DstReg.WriteMask))
3161 return 1;
3162 vp->DstReg.File = PROGRAM_ADDRESS;
3163
3164 /* Get a scalar src register */
3165 if (parse_scalar_src_reg
3166 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
3167 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
3168 vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
3169 return 1;
3170
3171 break;
3172
3173 case OP_ALU_VECTOR:
3174 switch (code) {
3175 case OP_ABS:
3176 vp->Opcode = VP_OPCODE_ABS;
3177 break;
3178 case OP_FLR:
3179 vp->Opcode = VP_OPCODE_FLR;
3180 break;
3181 case OP_FRC:
3182 vp->Opcode = VP_OPCODE_FRC;
3183 break;
3184 case OP_LIT:
3185 vp->Opcode = VP_OPCODE_LIT;
3186 break;
3187 case OP_MOV:
3188 vp->Opcode = VP_OPCODE_MOV;
3189 break;
3190 }
3191 if (parse_masked_dst_reg
3192 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3193 &vp->DstReg.Index, vp->DstReg.WriteMask))
3194 return 1;
3195 if (parse_vector_src_reg
3196 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
3197 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
3198 vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
3199 return 1;
3200 break;
3201
3202 case OP_ALU_SCALAR:
3203 switch (code) {
3204 case OP_EX2:
3205 vp->Opcode = VP_OPCODE_EX2;
3206 break;
3207 case OP_EXP:
3208 vp->Opcode = VP_OPCODE_EXP;
3209 break;
3210 case OP_LG2:
3211 vp->Opcode = VP_OPCODE_LG2;
3212 break;
3213 case OP_LOG:
3214 vp->Opcode = VP_OPCODE_LOG;
3215 break;
3216 case OP_RCP:
3217 vp->Opcode = VP_OPCODE_RCP;
3218 break;
3219 case OP_RSQ:
3220 vp->Opcode = VP_OPCODE_RSQ;
3221 break;
3222 }
3223 if (parse_masked_dst_reg
3224 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3225 &vp->DstReg.Index, vp->DstReg.WriteMask))
3226 return 1;
3227 if (parse_scalar_src_reg
3228 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
3229 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
3230 vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
3231 return 1;
3232 break;
3233
3234 case OP_ALU_BINSC:
3235 switch (code) {
3236 case OP_POW:
3237 vp->Opcode = VP_OPCODE_POW;
3238 break;
3239 }
3240 if (parse_masked_dst_reg
3241 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3242 &vp->DstReg.Index, vp->DstReg.WriteMask))
3243 return 1;
3244 for (a = 0; a < 2; a++) {
3245 if (parse_scalar_src_reg
3246 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
3247 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
3248 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
3249 return 1;
3250 }
3251 break;
3252
3253 case OP_ALU_BIN:
3254 switch (code) {
3255 case OP_ADD:
3256 vp->Opcode = VP_OPCODE_ADD;
3257 break;
3258 case OP_DP3:
3259 vp->Opcode = VP_OPCODE_DP3;
3260 break;
3261 case OP_DP4:
3262 vp->Opcode = VP_OPCODE_DP4;
3263 break;
3264 case OP_DPH:
3265 vp->Opcode = VP_OPCODE_DPH;
3266 break;
3267 case OP_DST:
3268 vp->Opcode = VP_OPCODE_DST;
3269 break;
3270 case OP_MAX:
3271 vp->Opcode = VP_OPCODE_MAX;
3272 break;
3273 case OP_MIN:
3274 vp->Opcode = VP_OPCODE_MIN;
3275 break;
3276 case OP_MUL:
3277 vp->Opcode = VP_OPCODE_MUL;
3278 break;
3279 case OP_SGE:
3280 vp->Opcode = VP_OPCODE_SGE;
3281 break;
3282 case OP_SLT:
3283 vp->Opcode = VP_OPCODE_SLT;
3284 break;
3285 case OP_SUB:
3286 vp->Opcode = VP_OPCODE_SUB;
3287 break;
3288 case OP_XPD:
3289 vp->Opcode = VP_OPCODE_XPD;
3290 break;
3291 }
3292 if (parse_masked_dst_reg
3293 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3294 &vp->DstReg.Index, vp->DstReg.WriteMask))
3295 return 1;
3296 for (a = 0; a < 2; a++) {
3297 if (parse_vector_src_reg
3298 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
3299 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
3300 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
3301 return 1;
3302 }
3303 break;
3304
3305 case OP_ALU_TRI:
3306 switch (code) {
3307 case OP_MAD:
3308 vp->Opcode = VP_OPCODE_MAD;
3309 break;
3310 }
3311
3312 if (parse_masked_dst_reg
3313 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3314 &vp->DstReg.Index, vp->DstReg.WriteMask))
3315 return 1;
3316 for (a = 0; a < 3; a++) {
3317 if (parse_vector_src_reg
3318 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
3319 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
3320 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
3321 return 1;
3322 }
3323 break;
3324
3325 case OP_ALU_SWZ:
3326 switch (code) {
3327 case OP_SWZ:
3328 vp->Opcode = VP_OPCODE_SWZ;
3329 break;
3330 }
3331 if (parse_masked_dst_reg
3332 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3333 &vp->DstReg.Index, vp->DstReg.WriteMask))
3334 return 1;
3335
3336 if (parse_src_reg
3337 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
3338 &vp->SrcReg[0].Index, &vp->SrcReg[0].RelAddr))
3339 return 1;
3340 parse_extended_swizzle_mask (inst, vp->SrcReg[0].Swizzle,
3341 &vp->SrcReg[0].Negate);
3342 break;
3343 }
3344 return 0;
3345 }
3346
3347 #if DEBUG_PARSING
3348
3349 static GLvoid
3350 print_state_token (GLint token)
3351 {
3352 switch (token) {
3353 case STATE_MATERIAL:
3354 fprintf (stderr, "STATE_MATERIAL ");
3355 break;
3356 case STATE_LIGHT:
3357 fprintf (stderr, "STATE_LIGHT ");
3358 break;
3359
3360 case STATE_LIGHTMODEL_AMBIENT:
3361 fprintf (stderr, "STATE_AMBIENT ");
3362 break;
3363
3364 case STATE_LIGHTMODEL_SCENECOLOR:
3365 fprintf (stderr, "STATE_SCENECOLOR ");
3366 break;
3367
3368 case STATE_LIGHTPROD:
3369 fprintf (stderr, "STATE_LIGHTPROD ");
3370 break;
3371
3372 case STATE_TEXGEN:
3373 fprintf (stderr, "STATE_TEXGEN ");
3374 break;
3375
3376 case STATE_FOG_COLOR:
3377 fprintf (stderr, "STATE_FOG_COLOR ");
3378 break;
3379
3380 case STATE_FOG_PARAMS:
3381 fprintf (stderr, "STATE_FOG_PARAMS ");
3382 break;
3383
3384 case STATE_CLIPPLANE:
3385 fprintf (stderr, "STATE_CLIPPLANE ");
3386 break;
3387
3388 case STATE_POINT_SIZE:
3389 fprintf (stderr, "STATE_POINT_SIZE ");
3390 break;
3391
3392 case STATE_POINT_ATTENUATION:
3393 fprintf (stderr, "STATE_ATTENUATION ");
3394 break;
3395
3396 case STATE_MATRIX:
3397 fprintf (stderr, "STATE_MATRIX ");
3398 break;
3399
3400 case STATE_MODELVIEW:
3401 fprintf (stderr, "STATE_MODELVIEW ");
3402 break;
3403
3404 case STATE_PROJECTION:
3405 fprintf (stderr, "STATE_PROJECTION ");
3406 break;
3407
3408 case STATE_MVP:
3409 fprintf (stderr, "STATE_MVP ");
3410 break;
3411
3412 case STATE_TEXTURE:
3413 fprintf (stderr, "STATE_TEXTURE ");
3414 break;
3415
3416 case STATE_PROGRAM:
3417 fprintf (stderr, "STATE_PROGRAM ");
3418 break;
3419
3420 case STATE_MATRIX_INVERSE:
3421 fprintf (stderr, "STATE_INVERSE ");
3422 break;
3423
3424 case STATE_MATRIX_TRANSPOSE:
3425 fprintf (stderr, "STATE_TRANSPOSE ");
3426 break;
3427
3428 case STATE_MATRIX_INVTRANS:
3429 fprintf (stderr, "STATE_INVTRANS ");
3430 break;
3431
3432 case STATE_AMBIENT:
3433 fprintf (stderr, "STATE_AMBIENT ");
3434 break;
3435
3436 case STATE_DIFFUSE:
3437 fprintf (stderr, "STATE_DIFFUSE ");
3438 break;
3439
3440 case STATE_SPECULAR:
3441 fprintf (stderr, "STATE_SPECULAR ");
3442 break;
3443
3444 case STATE_EMISSION:
3445 fprintf (stderr, "STATE_EMISSION ");
3446 break;
3447
3448 case STATE_SHININESS:
3449 fprintf (stderr, "STATE_SHININESS ");
3450 break;
3451
3452 case STATE_HALF:
3453 fprintf (stderr, "STATE_HALF ");
3454 break;
3455
3456 case STATE_POSITION:
3457 fprintf (stderr, "STATE_POSITION ");
3458 break;
3459
3460 case STATE_ATTENUATION:
3461 fprintf (stderr, "STATE_ATTENUATION ");
3462 break;
3463
3464 case STATE_SPOT_DIRECTION:
3465 fprintf (stderr, "STATE_DIRECTION ");
3466 break;
3467
3468 case STATE_TEXGEN_EYE_S:
3469 fprintf (stderr, "STATE_TEXGEN_EYE_S ");
3470 break;
3471
3472 case STATE_TEXGEN_EYE_T:
3473 fprintf (stderr, "STATE_TEXGEN_EYE_T ");
3474 break;
3475
3476 case STATE_TEXGEN_EYE_R:
3477 fprintf (stderr, "STATE_TEXGEN_EYE_R ");
3478 break;
3479
3480 case STATE_TEXGEN_EYE_Q:
3481 fprintf (stderr, "STATE_TEXGEN_EYE_Q ");
3482 break;
3483
3484 case STATE_TEXGEN_OBJECT_S:
3485 fprintf (stderr, "STATE_TEXGEN_EYE_S ");
3486 break;
3487
3488 case STATE_TEXGEN_OBJECT_T:
3489 fprintf (stderr, "STATE_TEXGEN_OBJECT_T ");
3490 break;
3491
3492 case STATE_TEXGEN_OBJECT_R:
3493 fprintf (stderr, "STATE_TEXGEN_OBJECT_R ");
3494 break;
3495
3496 case STATE_TEXGEN_OBJECT_Q:
3497 fprintf (stderr, "STATE_TEXGEN_OBJECT_Q ");
3498 break;
3499
3500 case STATE_TEXENV_COLOR:
3501 fprintf (stderr, "STATE_TEXENV_COLOR ");
3502 break;
3503
3504 case STATE_DEPTH_RANGE:
3505 fprintf (stderr, "STATE_DEPTH_RANGE ");
3506 break;
3507
3508 case STATE_VERTEX_PROGRAM:
3509 fprintf (stderr, "STATE_VERTEX_PROGRAM ");
3510 break;
3511
3512 case STATE_FRAGMENT_PROGRAM:
3513 fprintf (stderr, "STATE_FRAGMENT_PROGRAM ");
3514 break;
3515
3516 case STATE_ENV:
3517 fprintf (stderr, "STATE_ENV ");
3518 break;
3519
3520 case STATE_LOCAL:
3521 fprintf (stderr, "STATE_LOCAL ");
3522 break;
3523
3524 }
3525 fprintf (stderr, "[%d] ", token);
3526 }
3527
3528
3529 static GLvoid
3530 debug_variables (GLcontext * ctx, struct var_cache *vc_head,
3531 struct arb_program *Program)
3532 {
3533 struct var_cache *vc;
3534 GLint a, b;
3535
3536 fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head);
3537
3538 /* First of all, print out the contents of the var_cache */
3539 vc = vc_head;
3540 while (vc) {
3541 fprintf (stderr, "[%x]\n", vc);
3542 switch (vc->type) {
3543 case vt_none:
3544 fprintf (stderr, "UNDEFINED %s\n", vc->name);
3545 break;
3546 case vt_attrib:
3547 fprintf (stderr, "ATTRIB %s\n", vc->name);
3548 fprintf (stderr, " binding: 0x%x\n", vc->attrib_binding);
3549 break;
3550 case vt_param:
3551 fprintf (stderr, "PARAM %s begin: %d len: %d\n", vc->name,
3552 vc->param_binding_begin, vc->param_binding_length);
3553 b = vc->param_binding_begin;
3554 for (a = 0; a < vc->param_binding_length; a++) {
3555 fprintf (stderr, "%s\n",
3556 Program->Parameters->Parameters[a + b].Name);
3557 if (Program->Parameters->Parameters[a + b].Type == STATE) {
3558 print_state_token (Program->Parameters->Parameters[a + b].
3559 StateIndexes[0]);
3560 print_state_token (Program->Parameters->Parameters[a + b].
3561 StateIndexes[1]);
3562 print_state_token (Program->Parameters->Parameters[a + b].
3563 StateIndexes[2]);
3564 print_state_token (Program->Parameters->Parameters[a + b].
3565 StateIndexes[3]);
3566 print_state_token (Program->Parameters->Parameters[a + b].
3567 StateIndexes[4]);
3568 print_state_token (Program->Parameters->Parameters[a + b].
3569 StateIndexes[5]);
3570 }
3571 else
3572 fprintf (stderr, "%f %f %f %f\n",
3573 Program->Parameters->Parameters[a + b].Values[0],
3574 Program->Parameters->Parameters[a + b].Values[1],
3575 Program->Parameters->Parameters[a + b].Values[2],
3576 Program->Parameters->Parameters[a + b].Values[3]);
3577 }
3578 break;
3579 case vt_temp:
3580 fprintf (stderr, "TEMP %s\n", vc->name);
3581 fprintf (stderr, " binding: 0x%x\n", vc->temp_binding);
3582 break;
3583 case vt_output:
3584 fprintf (stderr, "OUTPUT %s\n", vc->name);
3585 fprintf (stderr, " binding: 0x%x\n", vc->output_binding);
3586 break;
3587 case vt_alias:
3588 fprintf (stderr, "ALIAS %s\n", vc->name);
3589 fprintf (stderr, " binding: 0x%x (%s)\n",
3590 vc->alias_binding, vc->alias_binding->name);
3591 break;
3592 }
3593 vc = vc->next;
3594 }
3595 }
3596
3597 #endif
3598
3599
3600 /**
3601 * The main loop for parsing a fragment or vertex program
3602 *
3603 * \return 0 on sucess, 1 on error
3604 */
3605 static GLint
3606 parse_arb_program (GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
3607 struct arb_program *Program)
3608 {
3609 GLint err = 0;
3610
3611 Program->MajorVersion = (GLuint) * inst++;
3612 Program->MinorVersion = (GLuint) * inst++;
3613
3614 while (*inst != END) {
3615 switch (*inst++) {
3616
3617 case OPTION:
3618 switch (*inst++) {
3619 case ARB_PRECISION_HINT_FASTEST:
3620 Program->PrecisionOption = GL_FASTEST;
3621 break;
3622
3623 case ARB_PRECISION_HINT_NICEST:
3624 Program->PrecisionOption = GL_NICEST;
3625 break;
3626
3627 case ARB_FOG_EXP:
3628 Program->FogOption = GL_EXP;
3629 break;
3630
3631 case ARB_FOG_EXP2:
3632 Program->FogOption = GL_EXP2;
3633 break;
3634
3635 case ARB_FOG_LINEAR:
3636 Program->FogOption = GL_LINEAR;
3637 break;
3638
3639 case ARB_POSITION_INVARIANT:
3640 if (Program->Base.Target == GL_VERTEX_PROGRAM_ARB)
3641 Program->HintPositionInvariant = 1;
3642 break;
3643
3644 case ARB_FRAGMENT_PROGRAM_SHADOW:
3645 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
3646 /* TODO ARB_fragment_program_shadow code */
3647 }
3648 break;
3649
3650 case ARB_DRAW_BUFFERS:
3651 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
3652 /* do nothing for now */
3653 }
3654 break;
3655 }
3656 break;
3657
3658 case INSTRUCTION:
3659 Program->Position = parse_position (&inst);
3660
3661 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
3662
3663 /* Check the instruction count
3664 * XXX: Does END count as an instruction?
3665 */
3666 if (Program->Base.NumInstructions+1 == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) {
3667 _mesa_set_program_error (ctx, Program->Position,
3668 "Max instruction count exceeded!");
3669 _mesa_error (ctx, GL_INVALID_OPERATION,
3670 "Max instruction count exceeded!");
3671 }
3672
3673 /* Realloc Program->FPInstructions */
3674 Program->FPInstructions =
3675 (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
3676 Program->Base.NumInstructions*sizeof(struct fp_instruction),
3677 (Program->Base.NumInstructions+1)*sizeof (struct fp_instruction));
3678
3679 /* parse the current instruction */
3680 err = parse_fp_instruction (ctx, &inst, vc_head, Program,
3681 &Program->FPInstructions[Program->Base.NumInstructions]);
3682
3683 }
3684 else {
3685 /* Check the instruction count
3686 * XXX: Does END count as an instruction?
3687 */
3688 if (Program->Base.NumInstructions+1 == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) {
3689 _mesa_set_program_error (ctx, Program->Position,
3690 "Max instruction count exceeded!");
3691 _mesa_error (ctx, GL_INVALID_OPERATION,
3692 "Max instruction count exceeded!");
3693 }
3694
3695 /* Realloc Program->VPInstructions */
3696 Program->VPInstructions =
3697 (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
3698 Program->Base.NumInstructions*sizeof(struct vp_instruction),
3699 (Program->Base.NumInstructions +1)*sizeof(struct vp_instruction));
3700
3701 /* parse the current instruction */
3702 err = parse_vp_instruction (ctx, &inst, vc_head, Program,
3703 &Program->VPInstructions[Program->Base.NumInstructions]);
3704 }
3705
3706 /* increment Program->Base.NumInstructions */
3707 Program->Base.NumInstructions++;
3708 break;
3709
3710 case DECLARATION:
3711 err = parse_declaration (ctx, &inst, vc_head, Program);
3712 break;
3713
3714 default:
3715 break;
3716 }
3717
3718 if (err)
3719 break;
3720 }
3721
3722 /* Finally, tag on an OPCODE_END instruction */
3723 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
3724 Program->FPInstructions =
3725 (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
3726 Program->Base.NumInstructions*sizeof(struct fp_instruction),
3727 (Program->Base.NumInstructions+1)*sizeof(struct fp_instruction));
3728
3729 Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END;
3730 /* YYY Wrong Position in program, whatever, at least not random -> crash
3731 Program->Position = parse_position (&inst);
3732 */
3733 Program->FPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
3734 Program->FPInstructions[Program->Base.NumInstructions].Data = NULL;
3735 }
3736 else {
3737 Program->VPInstructions =
3738 (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
3739 Program->Base.NumInstructions*sizeof(struct vp_instruction),
3740 (Program->Base.NumInstructions+1)*sizeof(struct vp_instruction));
3741
3742 Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END;
3743 /* YYY Wrong Position in program, whatever, at least not random -> crash
3744 Program->Position = parse_position (&inst);
3745 */
3746 Program->VPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
3747 Program->VPInstructions[Program->Base.NumInstructions].Data = NULL;
3748 }
3749
3750 /* increment Program->Base.NumInstructions */
3751 Program->Base.NumInstructions++;
3752
3753 return err;
3754 }
3755
3756 /* XXX temporary */
3757 __extension__ static char core_grammar_text[] =
3758 #include "grammar_syn.h"
3759 ;
3760
3761 static int set_reg8 (GLcontext *ctx, grammar id, const byte *name, byte value)
3762 {
3763 char error_msg[300];
3764 GLint error_pos;
3765
3766 if (grammar_set_reg8 (id, name, value))
3767 return 0;
3768
3769 grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
3770 _mesa_set_program_error (ctx, error_pos, error_msg);
3771 _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar Register Error");
3772 return 1;
3773 }
3774
3775 static int extension_is_supported (const GLubyte *ext)
3776 {
3777 const GLubyte *extensions = GL_CALL(GetString)(GL_EXTENSIONS);
3778 const GLubyte *end = extensions + _mesa_strlen ((const char *) extensions);
3779 const GLint ext_len = _mesa_strlen ((const char *) ext);
3780
3781 while (extensions < end)
3782 {
3783 const GLubyte *name_end = (const GLubyte *) strchr ((const char *) extensions, ' ');
3784 if (name_end == NULL)
3785 name_end = end;
3786 if (name_end - extensions == ext_len && _mesa_strncmp ((const char *) ext,
3787 (const char *) extensions, ext_len) == 0)
3788 return 1;
3789 extensions = name_end + 1;
3790 }
3791
3792 return 0;
3793 }
3794
3795 static int enable_ext (GLcontext *ctx, grammar id, const byte *name, const byte *extname)
3796 {
3797 if (extension_is_supported (extname))
3798 if (set_reg8 (ctx, id, name, 0x01))
3799 return 1;
3800 return 0;
3801 }
3802
3803 /**
3804 * This kicks everything off.
3805 *
3806 * \param ctx - The GL Context
3807 * \param str - The program string
3808 * \param len - The program string length
3809 * \param Program - The arb_program struct to return all the parsed info in
3810 * \return 0 on sucess, 1 on error
3811 */
3812 GLuint
3813 _mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len,
3814 struct arb_program * program)
3815 {
3816 GLint a, err, error_pos;
3817 char error_msg[300];
3818 GLuint parsed_len;
3819 struct var_cache *vc_head;
3820 grammar arbprogram_syn_id;
3821 GLubyte *parsed, *inst;
3822 GLubyte *strz = NULL;
3823 static int arbprogram_syn_is_ok = 0; /* XXX temporary */
3824
3825 /* Reset error state */
3826 _mesa_set_program_error(ctx, -1, NULL);
3827
3828 #if DEBUG_PARSING
3829 fprintf (stderr, "Loading grammar text!\n");
3830 #endif
3831
3832 /* check if the arb_grammar_text (arbprogram.syn) is syntactically correct */
3833 if (!arbprogram_syn_is_ok) {
3834 grammar grammar_syn_id;
3835 GLint err;
3836 GLuint parsed_len;
3837 byte *parsed;
3838
3839 grammar_syn_id = grammar_load_from_text ((byte *) core_grammar_text);
3840 if (grammar_syn_id == 0) {
3841 grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
3842 _mesa_set_program_error (ctx, error_pos, error_msg);
3843 _mesa_error (ctx, GL_INVALID_OPERATION,
3844 "Error loading grammar rule set");
3845 return 1;
3846 }
3847
3848 err = grammar_check (grammar_syn_id, (byte *) arb_grammar_text, &parsed, &parsed_len);
3849
3850 /* NOTE: we cant destroy grammar_syn_id right here because grammar_destroy() can
3851 reset the last error
3852 */
3853
3854 if (err == 0) {
3855 grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
3856 _mesa_set_program_error (ctx, error_pos, error_msg);
3857 _mesa_error (ctx, GL_INVALID_OPERATION, "Error loading grammar rule set");
3858
3859 grammar_destroy (grammar_syn_id);
3860 return 1;
3861 }
3862
3863 grammar_destroy (grammar_syn_id);
3864
3865 arbprogram_syn_is_ok = 1;
3866 }
3867
3868 /* create the grammar object */
3869 arbprogram_syn_id = grammar_load_from_text ((byte *) arb_grammar_text);
3870 if (arbprogram_syn_id == 0) {
3871 grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
3872 _mesa_set_program_error (ctx, error_pos, error_msg);
3873 _mesa_error (ctx, GL_INVALID_OPERATION,
3874 "Error loading grammer rule set");
3875 return 1;
3876 }
3877
3878 /* Set program_target register value */
3879 if (set_reg8 (ctx, arbprogram_syn_id, (byte *) "program_target",
3880 program->Base.Target == GL_FRAGMENT_PROGRAM_ARB ? 0x10 : 0x20)) {
3881 grammar_destroy (arbprogram_syn_id);
3882 return 1;
3883 }
3884
3885 /* Enable all active extensions */
3886 if (enable_ext (ctx, arbprogram_syn_id,
3887 (byte *) "vertex_blend", (byte *) "GL_ARB_vertex_blend") ||
3888 enable_ext (ctx, arbprogram_syn_id,
3889 (byte *) "vertex_blend", (byte *) "GL_EXT_vertex_weighting") ||
3890 enable_ext (ctx, arbprogram_syn_id,
3891 (byte *) "matrix_palette", (byte *) "GL_ARB_matrix_palette") ||
3892 enable_ext (ctx, arbprogram_syn_id,
3893 (byte *) "point_parameters", (byte *) "GL_ARB_point_parameters") ||
3894 enable_ext (ctx, arbprogram_syn_id,
3895 (byte *) "point_parameters", (byte *) "GL_EXT_point_parameters") ||
3896 enable_ext (ctx, arbprogram_syn_id,
3897 (byte *) "secondary_color", (byte *) "GL_EXT_secondary_color") ||
3898 enable_ext (ctx, arbprogram_syn_id,
3899 (byte *) "fog_coord", (byte *) "GL_EXT_fog_coord") ||
3900 enable_ext (ctx, arbprogram_syn_id,
3901 (byte *) "texture_rectangle", (byte *) "GL_ARB_texture_rectangle") ||
3902 enable_ext (ctx, arbprogram_syn_id,
3903 (byte *) "texture_rectangle", (byte *) "GL_EXT_texture_rectangle") ||
3904 enable_ext (ctx, arbprogram_syn_id,
3905 (byte *) "texture_rectangle", (byte *) "GL_NV_texture_rectangle") ||
3906 enable_ext (ctx, arbprogram_syn_id,
3907 (byte *) "fragment_program_shadow", (byte *) "GL_ARB_fragment_program_shadow") ||
3908 enable_ext (ctx, arbprogram_syn_id,
3909 (byte *) "draw_buffers", (byte *) "GL_ARB_draw_buffers")) {
3910 grammar_destroy (arbprogram_syn_id);
3911 return 1;
3912 }
3913
3914 /* check for NULL character occurences */
3915 {
3916 int i;
3917 for (i = 0; i < len; i++)
3918 if (str[i] == '\0') {
3919 _mesa_set_program_error (ctx, i, "invalid character");
3920 _mesa_error (ctx, GL_INVALID_OPERATION, "Lexical Error");
3921
3922 grammar_destroy (arbprogram_syn_id);
3923 return 1;
3924 }
3925 }
3926
3927 /* copy the program string to a null-terminated string */
3928 /* XXX should I check for NULL from malloc()? */
3929 strz = (GLubyte *) _mesa_malloc (len + 1);
3930 _mesa_memcpy (strz, str, len);
3931 strz[len] = '\0';
3932
3933 #if DEBUG_PARSING
3934 printf ("Checking Grammar!\n");
3935 #endif
3936 /* do a fast check on program string - initial production buffer is 4K */
3937 err = grammar_fast_check (arbprogram_syn_id, strz, &parsed, &parsed_len, 0x1000);
3938
3939 /* Syntax parse error */
3940 if (err == 0) {
3941 _mesa_free (strz);
3942 grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
3943 _mesa_set_program_error (ctx, error_pos, error_msg);
3944 _mesa_error (ctx, GL_INVALID_OPERATION, "glProgramStringARB(syntax error)");
3945
3946 /* useful for debugging */
3947 if (0) {
3948 int line, col;
3949 char *s;
3950 printf("Program: %s\n", (char *) strz);
3951 printf("Error Pos: %d\n", ctx->Program.ErrorPos);
3952 s = (char *) _mesa_find_line_column(strz, strz+ctx->Program.ErrorPos, &line, &col);
3953 printf("line %d col %d: %s\n", line, col, s);
3954 }
3955
3956 grammar_destroy (arbprogram_syn_id);
3957 return 1;
3958 }
3959
3960 #if DEBUG_PARSING
3961 printf ("Destroying grammer dict [parse retval: %d]\n", err);
3962 #endif
3963 grammar_destroy (arbprogram_syn_id);
3964
3965 /* Initialize the arb_program struct */
3966 program->Base.String = strz;
3967 program->Base.NumInstructions =
3968 program->Base.NumTemporaries =
3969 program->Base.NumParameters =
3970 program->Base.NumAttributes = program->Base.NumAddressRegs = 0;
3971 program->Parameters = _mesa_new_parameter_list ();
3972 program->InputsRead = 0;
3973 program->OutputsWritten = 0;
3974 program->Position = 0;
3975 program->MajorVersion = program->MinorVersion = 0;
3976 program->PrecisionOption = GL_DONT_CARE;
3977 program->FogOption = GL_NONE;
3978 program->HintPositionInvariant = GL_FALSE;
3979 for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)
3980 program->TexturesUsed[a] = 0;
3981 program->NumAluInstructions =
3982 program->NumTexInstructions =
3983 program->NumTexIndirections = 0;
3984
3985 program->FPInstructions = NULL;
3986 program->VPInstructions = NULL;
3987
3988 vc_head = NULL;
3989 err = 0;
3990
3991 /* Start examining the tokens in the array */
3992 inst = parsed;
3993
3994 /* Check the grammer rev */
3995 if (*inst++ != REVISION) {
3996 _mesa_set_program_error (ctx, 0, "Grammar version mismatch");
3997 _mesa_error (ctx, GL_INVALID_OPERATION, "glProgramStringARB(Grammar verison mismatch)");
3998 err = 1;
3999 }
4000 else {
4001 /* ignore program target */
4002 inst++;
4003
4004 err = parse_arb_program (ctx, inst, &vc_head, program);
4005 #if DEBUG_PARSING
4006 fprintf (stderr, "Symantic analysis returns %d [1 is bad!]\n", err);
4007 #endif
4008 }
4009
4010 /*debug_variables(ctx, vc_head, program); */
4011
4012 /* We're done with the parsed binary array */
4013 var_cache_destroy (&vc_head);
4014
4015 _mesa_free (parsed);
4016 #if DEBUG_PARSING
4017 printf ("_mesa_parse_arb_program() done\n");
4018 #endif
4019 return err;
4020 }