silence warning
[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 /* OP_ALU_INST or OP_TEX_INST */
2695 instClass = *(*inst)++;
2696
2697 /* OP_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ},
2698 * OP_TEX_{SAMPLE, KIL}
2699 */
2700 type = *(*inst)++;
2701
2702 /* The actual opcode name */
2703 code = *(*inst)++;
2704
2705 /* Increment the correct count */
2706 switch (instClass) {
2707 case OP_ALU_INST:
2708 Program->NumAluInstructions++;
2709 break;
2710 case OP_TEX_INST:
2711 Program->NumTexInstructions++;
2712 break;
2713 }
2714
2715 fp->Saturate = 0;
2716 fp->Precision = FLOAT32;
2717
2718 fp->DstReg.CondMask = COND_TR;
2719
2720 switch (type) {
2721 case OP_ALU_VECTOR:
2722 switch (code) {
2723 case OP_ABS_SAT:
2724 fp->Saturate = 1;
2725 case OP_ABS:
2726 fp->Opcode = FP_OPCODE_ABS;
2727 break;
2728
2729 case OP_FLR_SAT:
2730 fp->Saturate = 1;
2731 case OP_FLR:
2732 fp->Opcode = FP_OPCODE_FLR;
2733 break;
2734
2735 case OP_FRC_SAT:
2736 fp->Saturate = 1;
2737 case OP_FRC:
2738 fp->Opcode = FP_OPCODE_FRC;
2739 break;
2740
2741 case OP_LIT_SAT:
2742 fp->Saturate = 1;
2743 case OP_LIT:
2744 fp->Opcode = FP_OPCODE_LIT;
2745 break;
2746
2747 case OP_MOV_SAT:
2748 fp->Saturate = 1;
2749 case OP_MOV:
2750 fp->Opcode = FP_OPCODE_MOV;
2751 break;
2752 }
2753
2754 if (parse_masked_dst_reg
2755 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2756 &fp->DstReg.Index, fp->DstReg.WriteMask))
2757 return 1;
2758
2759 fp->SrcReg[0].Abs = GL_FALSE;
2760 fp->SrcReg[0].NegateAbs = GL_FALSE;
2761 if (parse_vector_src_reg
2762 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
2763 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
2764 swz, &rel))
2765 return 1;
2766 for (b=0; b<4; b++)
2767 fp->SrcReg[0].Swizzle[b] = swz[b];
2768 break;
2769
2770 case OP_ALU_SCALAR:
2771 switch (code) {
2772 case OP_COS_SAT:
2773 fp->Saturate = 1;
2774 case OP_COS:
2775 fp->Opcode = FP_OPCODE_COS;
2776 break;
2777
2778 case OP_EX2_SAT:
2779 fp->Saturate = 1;
2780 case OP_EX2:
2781 fp->Opcode = FP_OPCODE_EX2;
2782 break;
2783
2784 case OP_LG2_SAT:
2785 fp->Saturate = 1;
2786 case OP_LG2:
2787 fp->Opcode = FP_OPCODE_LG2;
2788 break;
2789
2790 case OP_RCP_SAT:
2791 fp->Saturate = 1;
2792 case OP_RCP:
2793 fp->Opcode = FP_OPCODE_RCP;
2794 break;
2795
2796 case OP_RSQ_SAT:
2797 fp->Saturate = 1;
2798 case OP_RSQ:
2799 fp->Opcode = FP_OPCODE_RSQ;
2800 break;
2801
2802 case OP_SIN_SAT:
2803 fp->Saturate = 1;
2804 case OP_SIN:
2805 fp->Opcode = FP_OPCODE_SIN;
2806 break;
2807
2808 case OP_SCS_SAT:
2809 fp->Saturate = 1;
2810 case OP_SCS:
2811
2812 fp->Opcode = FP_OPCODE_SCS;
2813 break;
2814 }
2815
2816 if (parse_masked_dst_reg
2817 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2818 &fp->DstReg.Index, fp->DstReg.WriteMask))
2819 return 1;
2820 fp->SrcReg[0].Abs = GL_FALSE;
2821 fp->SrcReg[0].NegateAbs = GL_FALSE;
2822 if (parse_scalar_src_reg
2823 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
2824 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
2825 swz, &rel))
2826 return 1;
2827 for (b=0; b<4; b++)
2828 fp->SrcReg[0].Swizzle[b] = swz[b];
2829 break;
2830
2831 case OP_ALU_BINSC:
2832 switch (code) {
2833 case OP_POW_SAT:
2834 fp->Saturate = 1;
2835 case OP_POW:
2836 fp->Opcode = FP_OPCODE_POW;
2837 break;
2838 }
2839
2840 if (parse_masked_dst_reg
2841 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2842 &fp->DstReg.Index, fp->DstReg.WriteMask))
2843 return 1;
2844 for (a = 0; a < 2; a++) {
2845 fp->SrcReg[a].Abs = GL_FALSE;
2846 fp->SrcReg[a].NegateAbs = GL_FALSE;
2847 if (parse_scalar_src_reg
2848 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
2849 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
2850 swz, &rel))
2851 return 1;
2852 for (b=0; b<4; b++)
2853 fp->SrcReg[a].Swizzle[b] = swz[b];
2854 }
2855 break;
2856
2857
2858 case OP_ALU_BIN:
2859 switch (code) {
2860 case OP_ADD_SAT:
2861 fp->Saturate = 1;
2862 case OP_ADD:
2863 fp->Opcode = FP_OPCODE_ADD;
2864 break;
2865
2866 case OP_DP3_SAT:
2867 fp->Saturate = 1;
2868 case OP_DP3:
2869 fp->Opcode = FP_OPCODE_DP3;
2870 break;
2871
2872 case OP_DP4_SAT:
2873 fp->Saturate = 1;
2874 case OP_DP4:
2875 fp->Opcode = FP_OPCODE_DP4;
2876 break;
2877
2878 case OP_DPH_SAT:
2879 fp->Saturate = 1;
2880 case OP_DPH:
2881 fp->Opcode = FP_OPCODE_DPH;
2882 break;
2883
2884 case OP_DST_SAT:
2885 fp->Saturate = 1;
2886 case OP_DST:
2887 fp->Opcode = FP_OPCODE_DST;
2888 break;
2889
2890 case OP_MAX_SAT:
2891 fp->Saturate = 1;
2892 case OP_MAX:
2893 fp->Opcode = FP_OPCODE_MAX;
2894 break;
2895
2896 case OP_MIN_SAT:
2897 fp->Saturate = 1;
2898 case OP_MIN:
2899 fp->Opcode = FP_OPCODE_MIN;
2900 break;
2901
2902 case OP_MUL_SAT:
2903 fp->Saturate = 1;
2904 case OP_MUL:
2905 fp->Opcode = FP_OPCODE_MUL;
2906 break;
2907
2908 case OP_SGE_SAT:
2909 fp->Saturate = 1;
2910 case OP_SGE:
2911 fp->Opcode = FP_OPCODE_SGE;
2912 break;
2913
2914 case OP_SLT_SAT:
2915 fp->Saturate = 1;
2916 case OP_SLT:
2917 fp->Opcode = FP_OPCODE_SLT;
2918 break;
2919
2920 case OP_SUB_SAT:
2921 fp->Saturate = 1;
2922 case OP_SUB:
2923 fp->Opcode = FP_OPCODE_SUB;
2924 break;
2925
2926 case OP_XPD_SAT:
2927 fp->Saturate = 1;
2928 case OP_XPD:
2929 fp->Opcode = FP_OPCODE_XPD;
2930 break;
2931 }
2932
2933 if (parse_masked_dst_reg
2934 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2935 &fp->DstReg.Index, fp->DstReg.WriteMask))
2936 return 1;
2937 for (a = 0; a < 2; a++) {
2938 fp->SrcReg[a].Abs = GL_FALSE;
2939 fp->SrcReg[a].NegateAbs = GL_FALSE;
2940 if (parse_vector_src_reg
2941 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
2942 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
2943 swz, &rel))
2944 return 1;
2945 for (b=0; b<4; b++)
2946 fp->SrcReg[a].Swizzle[b] = swz[b];
2947 }
2948 break;
2949
2950 case OP_ALU_TRI:
2951 switch (code) {
2952 case OP_CMP_SAT:
2953 fp->Saturate = 1;
2954 case OP_CMP:
2955 fp->Opcode = FP_OPCODE_CMP;
2956 break;
2957
2958 case OP_LRP_SAT:
2959 fp->Saturate = 1;
2960 case OP_LRP:
2961 fp->Opcode = FP_OPCODE_LRP;
2962 break;
2963
2964 case OP_MAD_SAT:
2965 fp->Saturate = 1;
2966 case OP_MAD:
2967 fp->Opcode = FP_OPCODE_MAD;
2968 break;
2969 }
2970
2971 if (parse_masked_dst_reg
2972 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2973 &fp->DstReg.Index, fp->DstReg.WriteMask))
2974 return 1;
2975 for (a = 0; a < 3; a++) {
2976 fp->SrcReg[a].Abs = GL_FALSE;
2977 fp->SrcReg[a].NegateAbs = GL_FALSE;
2978 if (parse_vector_src_reg
2979 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
2980 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
2981 swz, &rel))
2982 return 1;
2983 for (b=0; b<4; b++)
2984 fp->SrcReg[a].Swizzle[b] = swz[b];
2985 }
2986 break;
2987
2988 case OP_ALU_SWZ:
2989 switch (code) {
2990 case OP_SWZ_SAT:
2991 fp->Saturate = 1;
2992 case OP_SWZ:
2993 fp->Opcode = FP_OPCODE_SWZ;
2994 break;
2995 }
2996 if (parse_masked_dst_reg
2997 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
2998 &fp->DstReg.Index, fp->DstReg.WriteMask))
2999 return 1;
3000
3001 if (parse_src_reg
3002 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
3003 &fp->SrcReg[0].Index, &rel))
3004 return 1;
3005 parse_extended_swizzle_mask (inst, swz,
3006 &fp->SrcReg[0].NegateBase);
3007 for (b=0; b<4; b++)
3008 fp->SrcReg[0].Swizzle[b] = swz[b];
3009 break;
3010
3011 case OP_TEX_SAMPLE:
3012 switch (code) {
3013 case OP_TEX_SAT:
3014 fp->Saturate = 1;
3015 case OP_TEX:
3016 fp->Opcode = FP_OPCODE_TEX;
3017 break;
3018
3019 case OP_TXP_SAT:
3020 fp->Saturate = 1;
3021 case OP_TXP:
3022 fp->Opcode = FP_OPCODE_TXP;
3023 break;
3024
3025 case OP_TXB_SAT:
3026
3027 fp->Saturate = 1;
3028 case OP_TXB:
3029 fp->Opcode = FP_OPCODE_TXB;
3030 break;
3031 }
3032
3033 if (parse_masked_dst_reg
3034 (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
3035 &fp->DstReg.Index, fp->DstReg.WriteMask))
3036 return 1;
3037 fp->SrcReg[0].Abs = GL_FALSE;
3038 fp->SrcReg[0].NegateAbs = GL_FALSE;
3039 if (parse_vector_src_reg
3040 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
3041 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
3042 swz, &rel))
3043 return 1;
3044 for (b=0; b<4; b++)
3045 fp->SrcReg[0].Swizzle[b] = swz[b];
3046
3047 /* texImageUnit */
3048 if (parse_texcoord_num (ctx, inst, Program, &texcoord))
3049 return 1;
3050 fp->TexSrcUnit = texcoord;
3051
3052 /* texTarget */
3053 switch (*(*inst)++) {
3054 case TEXTARGET_1D:
3055 fp->TexSrcBit = TEXTURE_1D_BIT;
3056 break;
3057 case TEXTARGET_2D:
3058 fp->TexSrcBit = TEXTURE_2D_BIT;
3059 break;
3060 case TEXTARGET_3D:
3061 fp->TexSrcBit = TEXTURE_3D_BIT;
3062 break;
3063 case TEXTARGET_RECT:
3064 fp->TexSrcBit = TEXTURE_RECT_BIT;
3065 break;
3066 case TEXTARGET_CUBE:
3067 fp->TexSrcBit = TEXTURE_CUBE_BIT;
3068 break;
3069 case TEXTARGET_SHADOW1D:
3070 case TEXTARGET_SHADOW2D:
3071 case TEXTARGET_SHADOWRECT:
3072 /* TODO ARB_fragment_program_shadow code */
3073 break;
3074 }
3075 Program->TexturesUsed[texcoord] |= fp->TexSrcBit;
3076 break;
3077
3078 case OP_TEX_KIL:
3079 fp->Opcode = FP_OPCODE_KIL;
3080 fp->SrcReg[0].Abs = GL_FALSE;
3081 fp->SrcReg[0].NegateAbs = GL_FALSE;
3082 if (parse_vector_src_reg
3083 (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
3084 &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
3085 swz, &rel))
3086 return 1;
3087 for (b=0; b<4; b++)
3088 fp->SrcReg[0].Swizzle[b] = swz[b];
3089 break;
3090 }
3091
3092 return 0;
3093 }
3094
3095 /**
3096 * This is a big mother that handles getting opcodes into the instruction
3097 * and handling the src & dst registers for vertex program instructions
3098 */
3099 static GLuint
3100 parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
3101 struct var_cache **vc_head, struct arb_program *Program,
3102 struct vp_instruction *vp)
3103 {
3104 GLint a;
3105 GLubyte type, code;
3106
3107 /* OP_ALU_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */
3108 type = *(*inst)++;
3109
3110 /* The actual opcode name */
3111 code = *(*inst)++;
3112
3113 /* Record the position in the program string for debugging */
3114 vp->StringPos = Program->Position;
3115
3116 vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0;
3117
3118 for (a = 0; a < 4; a++) {
3119 vp->SrcReg[0].Swizzle[a] = a;
3120 vp->SrcReg[1].Swizzle[a] = a;
3121 vp->SrcReg[2].Swizzle[a] = a;
3122 vp->DstReg.WriteMask[a] = 1;
3123 }
3124
3125 switch (type) {
3126 /* XXX: */
3127 case OP_ALU_ARL:
3128 vp->Opcode = VP_OPCODE_ARL;
3129
3130 /* Remember to set SrcReg.RelAddr; */
3131
3132 /* Get the masked address register [dst] */
3133 if (parse_masked_address_reg
3134 (ctx, inst, vc_head, Program, &vp->DstReg.Index,
3135 vp->DstReg.WriteMask))
3136 return 1;
3137 vp->DstReg.File = PROGRAM_ADDRESS;
3138
3139 /* Get a scalar src register */
3140 if (parse_scalar_src_reg
3141 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
3142 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
3143 vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
3144 return 1;
3145
3146 break;
3147
3148 case OP_ALU_VECTOR:
3149 switch (code) {
3150 case OP_ABS:
3151 vp->Opcode = VP_OPCODE_ABS;
3152 break;
3153 case OP_FLR:
3154 vp->Opcode = VP_OPCODE_FLR;
3155 break;
3156 case OP_FRC:
3157 vp->Opcode = VP_OPCODE_FRC;
3158 break;
3159 case OP_LIT:
3160 vp->Opcode = VP_OPCODE_LIT;
3161 break;
3162 case OP_MOV:
3163 vp->Opcode = VP_OPCODE_MOV;
3164 break;
3165 }
3166 if (parse_masked_dst_reg
3167 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3168 &vp->DstReg.Index, vp->DstReg.WriteMask))
3169 return 1;
3170 if (parse_vector_src_reg
3171 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
3172 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
3173 vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
3174 return 1;
3175 break;
3176
3177 case OP_ALU_SCALAR:
3178 switch (code) {
3179 case OP_EX2:
3180 vp->Opcode = VP_OPCODE_EX2;
3181 break;
3182 case OP_EXP:
3183 vp->Opcode = VP_OPCODE_EXP;
3184 break;
3185 case OP_LG2:
3186 vp->Opcode = VP_OPCODE_LG2;
3187 break;
3188 case OP_LOG:
3189 vp->Opcode = VP_OPCODE_LOG;
3190 break;
3191 case OP_RCP:
3192 vp->Opcode = VP_OPCODE_RCP;
3193 break;
3194 case OP_RSQ:
3195 vp->Opcode = VP_OPCODE_RSQ;
3196 break;
3197 }
3198 if (parse_masked_dst_reg
3199 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3200 &vp->DstReg.Index, vp->DstReg.WriteMask))
3201 return 1;
3202 if (parse_scalar_src_reg
3203 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
3204 &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
3205 vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
3206 return 1;
3207 break;
3208
3209 case OP_ALU_BINSC:
3210 switch (code) {
3211 case OP_POW:
3212 vp->Opcode = VP_OPCODE_POW;
3213 break;
3214 }
3215 if (parse_masked_dst_reg
3216 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3217 &vp->DstReg.Index, vp->DstReg.WriteMask))
3218 return 1;
3219 for (a = 0; a < 2; a++) {
3220 if (parse_scalar_src_reg
3221 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
3222 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
3223 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
3224 return 1;
3225 }
3226 break;
3227
3228 case OP_ALU_BIN:
3229 switch (code) {
3230 case OP_ADD:
3231 vp->Opcode = VP_OPCODE_ADD;
3232 break;
3233 case OP_DP3:
3234 vp->Opcode = VP_OPCODE_DP3;
3235 break;
3236 case OP_DP4:
3237 vp->Opcode = VP_OPCODE_DP4;
3238 break;
3239 case OP_DPH:
3240 vp->Opcode = VP_OPCODE_DPH;
3241 break;
3242 case OP_DST:
3243 vp->Opcode = VP_OPCODE_DST;
3244 break;
3245 case OP_MAX:
3246 vp->Opcode = VP_OPCODE_MAX;
3247 break;
3248 case OP_MIN:
3249 vp->Opcode = VP_OPCODE_MIN;
3250 break;
3251 case OP_MUL:
3252 vp->Opcode = VP_OPCODE_MUL;
3253 break;
3254 case OP_SGE:
3255 vp->Opcode = VP_OPCODE_SGE;
3256 break;
3257 case OP_SLT:
3258 vp->Opcode = VP_OPCODE_SLT;
3259 break;
3260 case OP_SUB:
3261 vp->Opcode = VP_OPCODE_SUB;
3262 break;
3263 case OP_XPD:
3264 vp->Opcode = VP_OPCODE_XPD;
3265 break;
3266 }
3267 if (parse_masked_dst_reg
3268 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3269 &vp->DstReg.Index, vp->DstReg.WriteMask))
3270 return 1;
3271 for (a = 0; a < 2; a++) {
3272 if (parse_vector_src_reg
3273 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
3274 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
3275 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
3276 return 1;
3277 }
3278 break;
3279
3280 case OP_ALU_TRI:
3281 switch (code) {
3282 case OP_MAD:
3283 vp->Opcode = VP_OPCODE_MAD;
3284 break;
3285 }
3286
3287 if (parse_masked_dst_reg
3288 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3289 &vp->DstReg.Index, vp->DstReg.WriteMask))
3290 return 1;
3291 for (a = 0; a < 3; a++) {
3292 if (parse_vector_src_reg
3293 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
3294 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
3295 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
3296 return 1;
3297 }
3298 break;
3299
3300 case OP_ALU_SWZ:
3301 switch (code) {
3302 case OP_SWZ:
3303 vp->Opcode = VP_OPCODE_SWZ;
3304 break;
3305 }
3306 if (parse_masked_dst_reg
3307 (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
3308 &vp->DstReg.Index, vp->DstReg.WriteMask))
3309 return 1;
3310
3311 if (parse_src_reg
3312 (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
3313 &vp->SrcReg[0].Index, &vp->SrcReg[0].RelAddr))
3314 return 1;
3315 parse_extended_swizzle_mask (inst, vp->SrcReg[0].Swizzle,
3316 &vp->SrcReg[0].Negate);
3317 break;
3318 }
3319 return 0;
3320 }
3321
3322 #if DEBUG_PARSING
3323
3324 static GLvoid
3325 print_state_token (GLint token)
3326 {
3327 switch (token) {
3328 case STATE_MATERIAL:
3329 fprintf (stderr, "STATE_MATERIAL ");
3330 break;
3331 case STATE_LIGHT:
3332 fprintf (stderr, "STATE_LIGHT ");
3333 break;
3334
3335 case STATE_LIGHTMODEL_AMBIENT:
3336 fprintf (stderr, "STATE_AMBIENT ");
3337 break;
3338
3339 case STATE_LIGHTMODEL_SCENECOLOR:
3340 fprintf (stderr, "STATE_SCENECOLOR ");
3341 break;
3342
3343 case STATE_LIGHTPROD:
3344 fprintf (stderr, "STATE_LIGHTPROD ");
3345 break;
3346
3347 case STATE_TEXGEN:
3348 fprintf (stderr, "STATE_TEXGEN ");
3349 break;
3350
3351 case STATE_FOG_COLOR:
3352 fprintf (stderr, "STATE_FOG_COLOR ");
3353 break;
3354
3355 case STATE_FOG_PARAMS:
3356 fprintf (stderr, "STATE_FOG_PARAMS ");
3357 break;
3358
3359 case STATE_CLIPPLANE:
3360 fprintf (stderr, "STATE_CLIPPLANE ");
3361 break;
3362
3363 case STATE_POINT_SIZE:
3364 fprintf (stderr, "STATE_POINT_SIZE ");
3365 break;
3366
3367 case STATE_POINT_ATTENUATION:
3368 fprintf (stderr, "STATE_ATTENUATION ");
3369 break;
3370
3371 case STATE_MATRIX:
3372 fprintf (stderr, "STATE_MATRIX ");
3373 break;
3374
3375 case STATE_MODELVIEW:
3376 fprintf (stderr, "STATE_MODELVIEW ");
3377 break;
3378
3379 case STATE_PROJECTION:
3380 fprintf (stderr, "STATE_PROJECTION ");
3381 break;
3382
3383 case STATE_MVP:
3384 fprintf (stderr, "STATE_MVP ");
3385 break;
3386
3387 case STATE_TEXTURE:
3388 fprintf (stderr, "STATE_TEXTURE ");
3389 break;
3390
3391 case STATE_PROGRAM:
3392 fprintf (stderr, "STATE_PROGRAM ");
3393 break;
3394
3395 case STATE_MATRIX_INVERSE:
3396 fprintf (stderr, "STATE_INVERSE ");
3397 break;
3398
3399 case STATE_MATRIX_TRANSPOSE:
3400 fprintf (stderr, "STATE_TRANSPOSE ");
3401 break;
3402
3403 case STATE_MATRIX_INVTRANS:
3404 fprintf (stderr, "STATE_INVTRANS ");
3405 break;
3406
3407 case STATE_AMBIENT:
3408 fprintf (stderr, "STATE_AMBIENT ");
3409 break;
3410
3411 case STATE_DIFFUSE:
3412 fprintf (stderr, "STATE_DIFFUSE ");
3413 break;
3414
3415 case STATE_SPECULAR:
3416 fprintf (stderr, "STATE_SPECULAR ");
3417 break;
3418
3419 case STATE_EMISSION:
3420 fprintf (stderr, "STATE_EMISSION ");
3421 break;
3422
3423 case STATE_SHININESS:
3424 fprintf (stderr, "STATE_SHININESS ");
3425 break;
3426
3427 case STATE_HALF:
3428 fprintf (stderr, "STATE_HALF ");
3429 break;
3430
3431 case STATE_POSITION:
3432 fprintf (stderr, "STATE_POSITION ");
3433 break;
3434
3435 case STATE_ATTENUATION:
3436 fprintf (stderr, "STATE_ATTENUATION ");
3437 break;
3438
3439 case STATE_SPOT_DIRECTION:
3440 fprintf (stderr, "STATE_DIRECTION ");
3441 break;
3442
3443 case STATE_TEXGEN_EYE_S:
3444 fprintf (stderr, "STATE_TEXGEN_EYE_S ");
3445 break;
3446
3447 case STATE_TEXGEN_EYE_T:
3448 fprintf (stderr, "STATE_TEXGEN_EYE_T ");
3449 break;
3450
3451 case STATE_TEXGEN_EYE_R:
3452 fprintf (stderr, "STATE_TEXGEN_EYE_R ");
3453 break;
3454
3455 case STATE_TEXGEN_EYE_Q:
3456 fprintf (stderr, "STATE_TEXGEN_EYE_Q ");
3457 break;
3458
3459 case STATE_TEXGEN_OBJECT_S:
3460 fprintf (stderr, "STATE_TEXGEN_EYE_S ");
3461 break;
3462
3463 case STATE_TEXGEN_OBJECT_T:
3464 fprintf (stderr, "STATE_TEXGEN_OBJECT_T ");
3465 break;
3466
3467 case STATE_TEXGEN_OBJECT_R:
3468 fprintf (stderr, "STATE_TEXGEN_OBJECT_R ");
3469 break;
3470
3471 case STATE_TEXGEN_OBJECT_Q:
3472 fprintf (stderr, "STATE_TEXGEN_OBJECT_Q ");
3473 break;
3474
3475 case STATE_TEXENV_COLOR:
3476 fprintf (stderr, "STATE_TEXENV_COLOR ");
3477 break;
3478
3479 case STATE_DEPTH_RANGE:
3480 fprintf (stderr, "STATE_DEPTH_RANGE ");
3481 break;
3482
3483 case STATE_VERTEX_PROGRAM:
3484 fprintf (stderr, "STATE_VERTEX_PROGRAM ");
3485 break;
3486
3487 case STATE_FRAGMENT_PROGRAM:
3488 fprintf (stderr, "STATE_FRAGMENT_PROGRAM ");
3489 break;
3490
3491 case STATE_ENV:
3492 fprintf (stderr, "STATE_ENV ");
3493 break;
3494
3495 case STATE_LOCAL:
3496 fprintf (stderr, "STATE_LOCAL ");
3497 break;
3498
3499 }
3500 fprintf (stderr, "[%d] ", token);
3501 }
3502
3503
3504 static GLvoid
3505 debug_variables (GLcontext * ctx, struct var_cache *vc_head,
3506 struct arb_program *Program)
3507 {
3508 struct var_cache *vc;
3509 GLint a, b;
3510
3511 fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head);
3512
3513 /* First of all, print out the contents of the var_cache */
3514 vc = vc_head;
3515 while (vc) {
3516 fprintf (stderr, "[%x]\n", vc);
3517 switch (vc->type) {
3518 case vt_none:
3519 fprintf (stderr, "UNDEFINED %s\n", vc->name);
3520 break;
3521 case vt_attrib:
3522 fprintf (stderr, "ATTRIB %s\n", vc->name);
3523 fprintf (stderr, " binding: 0x%x\n", vc->attrib_binding);
3524 break;
3525 case vt_param:
3526 fprintf (stderr, "PARAM %s begin: %d len: %d\n", vc->name,
3527 vc->param_binding_begin, vc->param_binding_length);
3528 b = vc->param_binding_begin;
3529 for (a = 0; a < vc->param_binding_length; a++) {
3530 fprintf (stderr, "%s\n",
3531 Program->Parameters->Parameters[a + b].Name);
3532 if (Program->Parameters->Parameters[a + b].Type == STATE) {
3533 print_state_token (Program->Parameters->Parameters[a + b].
3534 StateIndexes[0]);
3535 print_state_token (Program->Parameters->Parameters[a + b].
3536 StateIndexes[1]);
3537 print_state_token (Program->Parameters->Parameters[a + b].
3538 StateIndexes[2]);
3539 print_state_token (Program->Parameters->Parameters[a + b].
3540 StateIndexes[3]);
3541 print_state_token (Program->Parameters->Parameters[a + b].
3542 StateIndexes[4]);
3543 print_state_token (Program->Parameters->Parameters[a + b].
3544 StateIndexes[5]);
3545 }
3546 else
3547 fprintf (stderr, "%f %f %f %f\n",
3548 Program->Parameters->Parameters[a + b].Values[0],
3549 Program->Parameters->Parameters[a + b].Values[1],
3550 Program->Parameters->Parameters[a + b].Values[2],
3551 Program->Parameters->Parameters[a + b].Values[3]);
3552 }
3553 break;
3554 case vt_temp:
3555 fprintf (stderr, "TEMP %s\n", vc->name);
3556 fprintf (stderr, " binding: 0x%x\n", vc->temp_binding);
3557 break;
3558 case vt_output:
3559 fprintf (stderr, "OUTPUT %s\n", vc->name);
3560 fprintf (stderr, " binding: 0x%x\n", vc->output_binding);
3561 break;
3562 case vt_alias:
3563 fprintf (stderr, "ALIAS %s\n", vc->name);
3564 fprintf (stderr, " binding: 0x%x (%s)\n",
3565 vc->alias_binding, vc->alias_binding->name);
3566 break;
3567 }
3568 vc = vc->next;
3569 }
3570 }
3571
3572 #endif
3573
3574
3575 /**
3576 * The main loop for parsing a fragment or vertex program
3577 *
3578 * \return 0 on sucess, 1 on error
3579 */
3580 static GLint
3581 parse_arb_program (GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
3582 struct arb_program *Program)
3583 {
3584 GLint err = 0;
3585
3586 Program->MajorVersion = (GLuint) * inst++;
3587 Program->MinorVersion = (GLuint) * inst++;
3588
3589 while (*inst != END) {
3590 switch (*inst++) {
3591
3592 case OPTION:
3593 switch (*inst++) {
3594 case ARB_PRECISION_HINT_FASTEST:
3595 Program->PrecisionOption = GL_FASTEST;
3596 break;
3597
3598 case ARB_PRECISION_HINT_NICEST:
3599 Program->PrecisionOption = GL_NICEST;
3600 break;
3601
3602 case ARB_FOG_EXP:
3603 Program->FogOption = GL_EXP;
3604 break;
3605
3606 case ARB_FOG_EXP2:
3607 Program->FogOption = GL_EXP2;
3608 break;
3609
3610 case ARB_FOG_LINEAR:
3611 Program->FogOption = GL_LINEAR;
3612 break;
3613
3614 case ARB_POSITION_INVARIANT:
3615 if (Program->Base.Target == GL_VERTEX_PROGRAM_ARB)
3616 Program->HintPositionInvariant = 1;
3617 break;
3618
3619 case ARB_FRAGMENT_PROGRAM_SHADOW:
3620 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
3621 /* TODO ARB_fragment_program_shadow code */
3622 }
3623 break;
3624
3625 case ARB_DRAW_BUFFERS:
3626 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
3627 /* do nothing for now */
3628 }
3629 break;
3630 }
3631 break;
3632
3633 case INSTRUCTION:
3634 Program->Position = parse_position (&inst);
3635
3636 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
3637
3638 /* Check the instruction count
3639 * XXX: Does END count as an instruction?
3640 */
3641 if (Program->Base.NumInstructions+1 == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) {
3642 _mesa_set_program_error (ctx, Program->Position,
3643 "Max instruction count exceeded!");
3644 _mesa_error (ctx, GL_INVALID_OPERATION,
3645 "Max instruction count exceeded!");
3646 }
3647
3648 /* Realloc Program->FPInstructions */
3649 Program->FPInstructions =
3650 (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
3651 Program->Base.NumInstructions*sizeof(struct fp_instruction),
3652 (Program->Base.NumInstructions+1)*sizeof (struct fp_instruction));
3653
3654 /* parse the current instruction */
3655 err = parse_fp_instruction (ctx, &inst, vc_head, Program,
3656 &Program->FPInstructions[Program->Base.NumInstructions]);
3657
3658 }
3659 else {
3660 /* Check the instruction count
3661 * XXX: Does END count as an instruction?
3662 */
3663 if (Program->Base.NumInstructions+1 == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) {
3664 _mesa_set_program_error (ctx, Program->Position,
3665 "Max instruction count exceeded!");
3666 _mesa_error (ctx, GL_INVALID_OPERATION,
3667 "Max instruction count exceeded!");
3668 }
3669
3670 /* Realloc Program->VPInstructions */
3671 Program->VPInstructions =
3672 (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
3673 Program->Base.NumInstructions*sizeof(struct vp_instruction),
3674 (Program->Base.NumInstructions +1)*sizeof(struct vp_instruction));
3675
3676 /* parse the current instruction */
3677 err = parse_vp_instruction (ctx, &inst, vc_head, Program,
3678 &Program->VPInstructions[Program->Base.NumInstructions]);
3679 }
3680
3681 /* increment Program->Base.NumInstructions */
3682 Program->Base.NumInstructions++;
3683 break;
3684
3685 case DECLARATION:
3686 err = parse_declaration (ctx, &inst, vc_head, Program);
3687 break;
3688
3689 default:
3690 break;
3691 }
3692
3693 if (err)
3694 break;
3695 }
3696
3697 /* Finally, tag on an OPCODE_END instruction */
3698 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
3699 Program->FPInstructions =
3700 (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
3701 Program->Base.NumInstructions*sizeof(struct fp_instruction),
3702 (Program->Base.NumInstructions+1)*sizeof(struct fp_instruction));
3703
3704 Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END;
3705 /* YYY Wrong Position in program, whatever, at least not random -> crash
3706 Program->Position = parse_position (&inst);
3707 */
3708 Program->FPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
3709 }
3710 else {
3711 Program->VPInstructions =
3712 (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
3713 Program->Base.NumInstructions*sizeof(struct vp_instruction),
3714 (Program->Base.NumInstructions+1)*sizeof(struct vp_instruction));
3715
3716 Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END;
3717 /* YYY Wrong Position in program, whatever, at least not random -> crash
3718 Program->Position = parse_position (&inst);
3719 */
3720 Program->VPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
3721 }
3722
3723 /* increment Program->Base.NumInstructions */
3724 Program->Base.NumInstructions++;
3725
3726 return err;
3727 }
3728
3729 /* XXX temporary */
3730 __extension__ static char core_grammar_text[] =
3731 #include "grammar_syn.h"
3732 ;
3733
3734 static int set_reg8 (GLcontext *ctx, grammar id, const byte *name, byte value)
3735 {
3736 char error_msg[300];
3737 GLint error_pos;
3738
3739 if (grammar_set_reg8 (id, name, value))
3740 return 0;
3741
3742 grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
3743 _mesa_set_program_error (ctx, error_pos, error_msg);
3744 _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar Register Error");
3745 return 1;
3746 }
3747
3748 static int extension_is_supported (const GLubyte *ext)
3749 {
3750 const GLubyte *extensions = GL_CALL(GetString)(GL_EXTENSIONS);
3751 const GLubyte *end = extensions + _mesa_strlen ((const char *) extensions);
3752 const GLint ext_len = _mesa_strlen ((const char *) ext);
3753
3754 while (extensions < end)
3755 {
3756 const GLubyte *name_end = (const GLubyte *) strchr ((const char *) extensions, ' ');
3757 if (name_end == NULL)
3758 name_end = end;
3759 if (name_end - extensions == ext_len && _mesa_strncmp ((const char *) ext,
3760 (const char *) extensions, ext_len) == 0)
3761 return 1;
3762 extensions = name_end + 1;
3763 }
3764
3765 return 0;
3766 }
3767
3768 static int enable_ext (GLcontext *ctx, grammar id, const byte *name, const byte *extname)
3769 {
3770 if (extension_is_supported (extname))
3771 if (set_reg8 (ctx, id, name, 0x01))
3772 return 1;
3773 return 0;
3774 }
3775
3776 /**
3777 * This kicks everything off.
3778 *
3779 * \param ctx - The GL Context
3780 * \param str - The program string
3781 * \param len - The program string length
3782 * \param Program - The arb_program struct to return all the parsed info in
3783 * \return 0 on sucess, 1 on error
3784 */
3785 GLuint
3786 _mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len,
3787 struct arb_program * program)
3788 {
3789 GLint a, err, error_pos;
3790 char error_msg[300];
3791 GLuint parsed_len;
3792 struct var_cache *vc_head;
3793 grammar arbprogram_syn_id;
3794 GLubyte *parsed, *inst;
3795 GLubyte *strz = NULL;
3796 static int arbprogram_syn_is_ok = 0; /* XXX temporary */
3797
3798 /* Reset error state */
3799 _mesa_set_program_error(ctx, -1, NULL);
3800
3801 #if DEBUG_PARSING
3802 fprintf (stderr, "Loading grammar text!\n");
3803 #endif
3804
3805 /* check if the arb_grammar_text (arbprogram.syn) is syntactically correct */
3806 if (!arbprogram_syn_is_ok) {
3807 grammar grammar_syn_id;
3808 GLint err;
3809 GLuint parsed_len;
3810 byte *parsed;
3811
3812 grammar_syn_id = grammar_load_from_text ((byte *) core_grammar_text);
3813 if (grammar_syn_id == 0) {
3814 grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
3815 _mesa_set_program_error (ctx, error_pos, error_msg);
3816 _mesa_error (ctx, GL_INVALID_OPERATION,
3817 "Error loading grammar rule set");
3818 return 1;
3819 }
3820
3821 err = grammar_check (grammar_syn_id, (byte *) arb_grammar_text, &parsed, &parsed_len);
3822
3823 /* NOTE: we cant destroy grammar_syn_id right here because grammar_destroy() can
3824 reset the last error
3825 */
3826
3827 if (err == 0) {
3828 grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
3829 _mesa_set_program_error (ctx, error_pos, error_msg);
3830 _mesa_error (ctx, GL_INVALID_OPERATION, "Error loading grammar rule set");
3831
3832 grammar_destroy (grammar_syn_id);
3833 return 1;
3834 }
3835
3836 grammar_destroy (grammar_syn_id);
3837
3838 arbprogram_syn_is_ok = 1;
3839 }
3840
3841 /* create the grammar object */
3842 arbprogram_syn_id = grammar_load_from_text ((byte *) arb_grammar_text);
3843 if (arbprogram_syn_id == 0) {
3844 grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
3845 _mesa_set_program_error (ctx, error_pos, error_msg);
3846 _mesa_error (ctx, GL_INVALID_OPERATION,
3847 "Error loading grammer rule set");
3848 return 1;
3849 }
3850
3851 /* Set program_target register value */
3852 if (set_reg8 (ctx, arbprogram_syn_id, (byte *) "program_target",
3853 program->Base.Target == GL_FRAGMENT_PROGRAM_ARB ? 0x10 : 0x20)) {
3854 grammar_destroy (arbprogram_syn_id);
3855 return 1;
3856 }
3857
3858 /* Enable all active extensions */
3859 if (enable_ext (ctx, arbprogram_syn_id,
3860 (byte *) "vertex_blend", (byte *) "GL_ARB_vertex_blend") ||
3861 enable_ext (ctx, arbprogram_syn_id,
3862 (byte *) "vertex_blend", (byte *) "GL_EXT_vertex_weighting") ||
3863 enable_ext (ctx, arbprogram_syn_id,
3864 (byte *) "matrix_palette", (byte *) "GL_ARB_matrix_palette") ||
3865 enable_ext (ctx, arbprogram_syn_id,
3866 (byte *) "point_parameters", (byte *) "GL_ARB_point_parameters") ||
3867 enable_ext (ctx, arbprogram_syn_id,
3868 (byte *) "point_parameters", (byte *) "GL_EXT_point_parameters") ||
3869 enable_ext (ctx, arbprogram_syn_id,
3870 (byte *) "secondary_color", (byte *) "GL_EXT_secondary_color") ||
3871 enable_ext (ctx, arbprogram_syn_id,
3872 (byte *) "fog_coord", (byte *) "GL_EXT_fog_coord") ||
3873 enable_ext (ctx, arbprogram_syn_id,
3874 (byte *) "texture_rectangle", (byte *) "GL_ARB_texture_rectangle") ||
3875 enable_ext (ctx, arbprogram_syn_id,
3876 (byte *) "texture_rectangle", (byte *) "GL_EXT_texture_rectangle") ||
3877 enable_ext (ctx, arbprogram_syn_id,
3878 (byte *) "texture_rectangle", (byte *) "GL_NV_texture_rectangle") ||
3879 enable_ext (ctx, arbprogram_syn_id,
3880 (byte *) "fragment_program_shadow", (byte *) "GL_ARB_fragment_program_shadow") ||
3881 enable_ext (ctx, arbprogram_syn_id,
3882 (byte *) "draw_buffers", (byte *) "GL_ARB_draw_buffers")) {
3883 grammar_destroy (arbprogram_syn_id);
3884 return 1;
3885 }
3886
3887 /* check for NULL character occurences */
3888 {
3889 int i;
3890 for (i = 0; i < len; i++)
3891 if (str[i] == '\0') {
3892 _mesa_set_program_error (ctx, i, "invalid character");
3893 _mesa_error (ctx, GL_INVALID_OPERATION, "Lexical Error");
3894
3895 grammar_destroy (arbprogram_syn_id);
3896 return 1;
3897 }
3898 }
3899
3900 /* copy the program string to a null-terminated string */
3901 /* XXX should I check for NULL from malloc()? */
3902 strz = (GLubyte *) _mesa_malloc (len + 1);
3903 _mesa_memcpy (strz, str, len);
3904 strz[len] = '\0';
3905
3906 #if DEBUG_PARSING
3907 printf ("Checking Grammar!\n");
3908 #endif
3909 /* do a fast check on program string - initial production buffer is 4K */
3910 err = grammar_fast_check (arbprogram_syn_id, strz, &parsed, &parsed_len, 0x1000);
3911
3912 /* Syntax parse error */
3913 if (err == 0) {
3914 _mesa_free (strz);
3915 grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
3916 _mesa_set_program_error (ctx, error_pos, error_msg);
3917 _mesa_error (ctx, GL_INVALID_OPERATION, "glProgramStringARB(syntax error)");
3918
3919 /* useful for debugging */
3920 if (0) {
3921 int line, col;
3922 char *s;
3923 printf("Program: %s\n", (char *) strz);
3924 printf("Error Pos: %d\n", ctx->Program.ErrorPos);
3925 s = (char *) _mesa_find_line_column(strz, strz+ctx->Program.ErrorPos, &line, &col);
3926 printf("line %d col %d: %s\n", line, col, s);
3927 }
3928
3929 grammar_destroy (arbprogram_syn_id);
3930 return 1;
3931 }
3932
3933 #if DEBUG_PARSING
3934 printf ("Destroying grammer dict [parse retval: %d]\n", err);
3935 #endif
3936 grammar_destroy (arbprogram_syn_id);
3937
3938 /* Initialize the arb_program struct */
3939 program->Base.String = strz;
3940 program->Base.NumInstructions =
3941 program->Base.NumTemporaries =
3942 program->Base.NumParameters =
3943 program->Base.NumAttributes = program->Base.NumAddressRegs = 0;
3944 program->Parameters = _mesa_new_parameter_list ();
3945 program->InputsRead = 0;
3946 program->OutputsWritten = 0;
3947 program->Position = 0;
3948 program->MajorVersion = program->MinorVersion = 0;
3949 program->PrecisionOption = GL_DONT_CARE;
3950 program->FogOption = GL_NONE;
3951 program->HintPositionInvariant = GL_FALSE;
3952 for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)
3953 program->TexturesUsed[a] = 0;
3954 program->NumAluInstructions =
3955 program->NumTexInstructions =
3956 program->NumTexIndirections = 0;
3957
3958 program->FPInstructions = NULL;
3959 program->VPInstructions = NULL;
3960
3961 vc_head = NULL;
3962 err = 0;
3963
3964 /* Start examining the tokens in the array */
3965 inst = parsed;
3966
3967 /* Check the grammer rev */
3968 if (*inst++ != REVISION) {
3969 _mesa_set_program_error (ctx, 0, "Grammar version mismatch");
3970 _mesa_error (ctx, GL_INVALID_OPERATION, "glProgramStringARB(Grammar verison mismatch)");
3971 err = 1;
3972 }
3973 else {
3974 /* ignore program target */
3975 inst++;
3976
3977 err = parse_arb_program (ctx, inst, &vc_head, program);
3978 #if DEBUG_PARSING
3979 fprintf (stderr, "Symantic analysis returns %d [1 is bad!]\n", err);
3980 #endif
3981 }
3982
3983 /*debug_variables(ctx, vc_head, program); */
3984
3985 /* We're done with the parsed binary array */
3986 var_cache_destroy (&vc_head);
3987
3988 _mesa_free (parsed);
3989 #if DEBUG_PARSING
3990 printf ("_mesa_parse_arb_program() done\n");
3991 #endif
3992 return err;
3993 }