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