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