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