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