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