Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenarbprogparse.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.1 00004 * 00005 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 #define DEBUG_PARSING 0 00026 00033 #include "main/glheader.h" 00034 #include "main/imports.h" 00035 #include "main/context.h" 00036 #include "main/macros.h" 00037 #include "main/mtypes.h" 00038 #include "shader/grammar/grammar_mesa.h" 00039 #include "arbprogparse.h" 00040 #include "program.h" 00041 #include "prog_parameter.h" 00042 #include "prog_statevars.h" 00043 #include "prog_instruction.h" 00044 00045 00046 /* For ARB programs, use the NV instruction limits */ 00047 #define MAX_INSTRUCTIONS MAX2(MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS, \ 00048 MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) 00049 00050 00057 struct arb_program 00058 { 00059 struct gl_program Base; 00060 00061 GLuint Position; /* Just used for error reporting while parsing */ 00062 GLuint MajorVersion; 00063 GLuint MinorVersion; 00064 00065 /* ARB_vertex_progmra options */ 00066 GLboolean HintPositionInvariant; 00067 00068 /* ARB_fragment_progmra options */ 00069 GLenum PrecisionOption; /* GL_DONT_CARE, GL_NICEST or GL_FASTEST */ 00070 GLenum FogOption; /* GL_NONE, GL_LINEAR, GL_EXP or GL_EXP2 */ 00071 00072 /* ARB_fragment_program specifics */ 00073 GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; 00074 GLbitfield ShadowSamplers; 00075 GLuint NumAluInstructions; 00076 GLuint NumTexInstructions; 00077 GLuint NumTexIndirections; 00078 00079 GLboolean UsesKill; 00080 }; 00081 00082 00083 00084 /* TODO: 00085 * Fragment Program Stuff: 00086 * ----------------------------------------------------- 00087 * 00088 * - things from Michal's email 00089 * + overflow on atoi 00090 * + not-overflowing floats (don't use parse_integer..) 00091 * + can remove range checking in arbparse.c 00092 * 00093 * - check all limits of number of various variables 00094 * + parameters 00095 * 00096 * - test! test! test! 00097 * 00098 * Vertex Program Stuff: 00099 * ----------------------------------------------------- 00100 * - Optimize param array usage and count limits correctly, see spec, 00101 * section 2.14.3.7 00102 * + Record if an array is reference absolutly or relatively (or both) 00103 * + For absolute arrays, store a bitmap of accesses 00104 * + For single parameters, store an access flag 00105 * + After parsing, make a parameter cleanup and merging pass, where 00106 * relative arrays are layed out first, followed by abs arrays, and 00107 * finally single state. 00108 * + Remap offsets for param src and dst registers 00109 * + Now we can properly count parameter usage 00110 * 00111 * - Multiple state binding errors in param arrays (see spec, just before 00112 * section 2.14.3.3) 00113 * - grep for XXX 00114 * 00115 * Mesa Stuff 00116 * ----------------------------------------------------- 00117 * - User clipping planes vs. PositionInvariant 00118 * - Is it sufficient to just multiply by the mvp to transform in the 00119 * PositionInvariant case? Or do we need something more involved? 00120 * 00121 * - vp_src swizzle is GLubyte, fp_src swizzle is GLuint 00122 * - fetch state listed in program_parameters list 00123 * + WTF should this go??? 00124 * + currently in nvvertexec.c and s_nvfragprog.c 00125 * 00126 * - allow for multiple address registers (and fetch address regs properly) 00127 * 00128 * Cosmetic Stuff 00129 * ----------------------------------------------------- 00130 * - remove any leftover unused grammer.c stuff (dict_ ?) 00131 * - fix grammer.c error handling so its not static 00132 * - #ifdef around stuff pertaining to extentions 00133 * 00134 * Outstanding Questions: 00135 * ----------------------------------------------------- 00136 * - ARB_matrix_palette / ARB_vertex_blend -- not supported 00137 * what gets hacked off because of this: 00138 * + VERTEX_ATTRIB_MATRIXINDEX 00139 * + VERTEX_ATTRIB_WEIGHT 00140 * + MATRIX_MODELVIEW 00141 * + MATRIX_PALETTE 00142 * 00143 * - When can we fetch env/local params from their own register files, and 00144 * when to we have to fetch them into the main state register file? 00145 * (think arrays) 00146 * 00147 * Grammar Changes: 00148 * ----------------------------------------------------- 00149 */ 00150 00151 /* Changes since moving the file to shader directory 00152 00153 2004-III-4 ------------------------------------------------------------ 00154 - added #include "grammar_mesa.h" 00155 - removed grammar specific code part (it resides now in grammar.c) 00156 - added GL_ARB_fragment_program_shadow tokens 00157 - modified #include "arbparse_syn.h" 00158 - major changes inside _mesa_parse_arb_program() 00159 - check the program string for '\0' characters 00160 - copy the program string to a one-byte-longer location to have 00161 it null-terminated 00162 - position invariance test (not writing to result.position) moved 00163 to syntax part 00164 */ 00165 00166 typedef GLubyte *production; 00167 00168 00172 LONGSTRING static char arb_grammar_text[] = 00173 #include "arbprogram_syn.h" 00174 ; 00175 00180 /* 00181 Changes: 00182 - changed and merged V_* and F_* opcode values to OP_*. 00183 - added GL_ARB_fragment_program_shadow specific tokens (michal) 00184 */ 00185 #define REVISION 0x0a 00186 00187 /* program type */ 00188 #define FRAGMENT_PROGRAM 0x01 00189 #define VERTEX_PROGRAM 0x02 00190 00191 /* program section */ 00192 #define OPTION 0x01 00193 #define INSTRUCTION 0x02 00194 #define DECLARATION 0x03 00195 #define END 0x04 00196 00197 /* GL_ARB_fragment_program option */ 00198 #define ARB_PRECISION_HINT_FASTEST 0x00 00199 #define ARB_PRECISION_HINT_NICEST 0x01 00200 #define ARB_FOG_EXP 0x02 00201 #define ARB_FOG_EXP2 0x03 00202 #define ARB_FOG_LINEAR 0x04 00203 00204 /* GL_ARB_vertex_program option */ 00205 #define ARB_POSITION_INVARIANT 0x05 00206 00207 /* GL_ARB_fragment_program_shadow option */ 00208 #define ARB_FRAGMENT_PROGRAM_SHADOW 0x06 00209 00210 /* GL_ARB_draw_buffers option */ 00211 #define ARB_DRAW_BUFFERS 0x07 00212 00213 /* GL_MESA_texture_array option */ 00214 #define MESA_TEXTURE_ARRAY 0x08 00215 00216 /* GL_ARB_fragment_program instruction class */ 00217 #define OP_ALU_INST 0x00 00218 #define OP_TEX_INST 0x01 00219 00220 /* GL_ARB_vertex_program instruction class */ 00221 /* OP_ALU_INST */ 00222 00223 /* GL_ARB_fragment_program instruction type */ 00224 #define OP_ALU_VECTOR 0x00 00225 #define OP_ALU_SCALAR 0x01 00226 #define OP_ALU_BINSC 0x02 00227 #define OP_ALU_BIN 0x03 00228 #define OP_ALU_TRI 0x04 00229 #define OP_ALU_SWZ 0x05 00230 #define OP_TEX_SAMPLE 0x06 00231 #define OP_TEX_KIL 0x07 00232 00233 /* GL_ARB_vertex_program instruction type */ 00234 #define OP_ALU_ARL 0x08 00235 /* OP_ALU_VECTOR */ 00236 /* OP_ALU_SCALAR */ 00237 /* OP_ALU_BINSC */ 00238 /* OP_ALU_BIN */ 00239 /* OP_ALU_TRI */ 00240 /* OP_ALU_SWZ */ 00241 00242 /* GL_ARB_fragment_program instruction code */ 00243 #define OP_ABS 0x00 00244 #define OP_ABS_SAT 0x1B 00245 #define OP_FLR 0x09 00246 #define OP_FLR_SAT 0x26 00247 #define OP_FRC 0x0A 00248 #define OP_FRC_SAT 0x27 00249 #define OP_LIT 0x0C 00250 #define OP_LIT_SAT 0x2A 00251 #define OP_MOV 0x11 00252 #define OP_MOV_SAT 0x30 00253 #define OP_COS 0x1F 00254 #define OP_COS_SAT 0x20 00255 #define OP_EX2 0x07 00256 #define OP_EX2_SAT 0x25 00257 #define OP_LG2 0x0B 00258 #define OP_LG2_SAT 0x29 00259 #define OP_RCP 0x14 00260 #define OP_RCP_SAT 0x33 00261 #define OP_RSQ 0x15 00262 #define OP_RSQ_SAT 0x34 00263 #define OP_SIN 0x38 00264 #define OP_SIN_SAT 0x39 00265 #define OP_SCS 0x35 00266 #define OP_SCS_SAT 0x36 00267 #define OP_POW 0x13 00268 #define OP_POW_SAT 0x32 00269 #define OP_ADD 0x01 00270 #define OP_ADD_SAT 0x1C 00271 #define OP_DP3 0x03 00272 #define OP_DP3_SAT 0x21 00273 #define OP_DP4 0x04 00274 #define OP_DP4_SAT 0x22 00275 #define OP_DPH 0x05 00276 #define OP_DPH_SAT 0x23 00277 #define OP_DST 0x06 00278 #define OP_DST_SAT 0x24 00279 #define OP_MAX 0x0F 00280 #define OP_MAX_SAT 0x2E 00281 #define OP_MIN 0x10 00282 #define OP_MIN_SAT 0x2F 00283 #define OP_MUL 0x12 00284 #define OP_MUL_SAT 0x31 00285 #define OP_SGE 0x16 00286 #define OP_SGE_SAT 0x37 00287 #define OP_SLT 0x17 00288 #define OP_SLT_SAT 0x3A 00289 #define OP_SUB 0x18 00290 #define OP_SUB_SAT 0x3B 00291 #define OP_XPD 0x1A 00292 #define OP_XPD_SAT 0x43 00293 #define OP_CMP 0x1D 00294 #define OP_CMP_SAT 0x1E 00295 #define OP_LRP 0x2B 00296 #define OP_LRP_SAT 0x2C 00297 #define OP_MAD 0x0E 00298 #define OP_MAD_SAT 0x2D 00299 #define OP_SWZ 0x19 00300 #define OP_SWZ_SAT 0x3C 00301 #define OP_TEX 0x3D 00302 #define OP_TEX_SAT 0x3E 00303 #define OP_TXB 0x3F 00304 #define OP_TXB_SAT 0x40 00305 #define OP_TXP 0x41 00306 #define OP_TXP_SAT 0x42 00307 #define OP_KIL 0x28 00308 00309 /* GL_ARB_vertex_program instruction code */ 00310 #define OP_ARL 0x02 00311 /* OP_ABS */ 00312 /* OP_FLR */ 00313 /* OP_FRC */ 00314 /* OP_LIT */ 00315 /* OP_MOV */ 00316 /* OP_EX2 */ 00317 #define OP_EXP 0x08 00318 /* OP_LG2 */ 00319 #define OP_LOG 0x0D 00320 /* OP_RCP */ 00321 /* OP_RSQ */ 00322 /* OP_POW */ 00323 /* OP_ADD */ 00324 /* OP_DP3 */ 00325 /* OP_DP4 */ 00326 /* OP_DPH */ 00327 /* OP_DST */ 00328 /* OP_MAX */ 00329 /* OP_MIN */ 00330 /* OP_MUL */ 00331 /* OP_SGE */ 00332 /* OP_SLT */ 00333 /* OP_SUB */ 00334 /* OP_XPD */ 00335 /* OP_MAD */ 00336 /* OP_SWZ */ 00337 00338 /* fragment attribute binding */ 00339 #define FRAGMENT_ATTRIB_COLOR 0x01 00340 #define FRAGMENT_ATTRIB_TEXCOORD 0x02 00341 #define FRAGMENT_ATTRIB_FOGCOORD 0x03 00342 #define FRAGMENT_ATTRIB_POSITION 0x04 00343 00344 /* vertex attribute binding */ 00345 #define VERTEX_ATTRIB_POSITION 0x01 00346 #define VERTEX_ATTRIB_WEIGHT 0x02 00347 #define VERTEX_ATTRIB_NORMAL 0x03 00348 #define VERTEX_ATTRIB_COLOR 0x04 00349 #define VERTEX_ATTRIB_FOGCOORD 0x05 00350 #define VERTEX_ATTRIB_TEXCOORD 0x06 00351 #define VERTEX_ATTRIB_MATRIXINDEX 0x07 00352 #define VERTEX_ATTRIB_GENERIC 0x08 00353 00354 /* fragment result binding */ 00355 #define FRAGMENT_RESULT_COLOR 0x01 00356 #define FRAGMENT_RESULT_DEPTH 0x02 00357 00358 /* vertex result binding */ 00359 #define VERTEX_RESULT_POSITION 0x01 00360 #define VERTEX_RESULT_COLOR 0x02 00361 #define VERTEX_RESULT_FOGCOORD 0x03 00362 #define VERTEX_RESULT_POINTSIZE 0x04 00363 #define VERTEX_RESULT_TEXCOORD 0x05 00364 00365 /* texture target */ 00366 #define TEXTARGET_1D 0x01 00367 #define TEXTARGET_2D 0x02 00368 #define TEXTARGET_3D 0x03 00369 #define TEXTARGET_RECT 0x04 00370 #define TEXTARGET_CUBE 0x05 00371 /* GL_ARB_fragment_program_shadow */ 00372 #define TEXTARGET_SHADOW1D 0x06 00373 #define TEXTARGET_SHADOW2D 0x07 00374 #define TEXTARGET_SHADOWRECT 0x08 00375 /* GL_MESA_texture_array */ 00376 #define TEXTARGET_1D_ARRAY 0x09 00377 #define TEXTARGET_2D_ARRAY 0x0a 00378 #define TEXTARGET_SHADOW1D_ARRAY 0x0b 00379 #define TEXTARGET_SHADOW2D_ARRAY 0x0c 00380 00381 /* face type */ 00382 #define FACE_FRONT 0x00 00383 #define FACE_BACK 0x01 00384 00385 /* color type */ 00386 #define COLOR_PRIMARY 0x00 00387 #define COLOR_SECONDARY 0x01 00388 00389 /* component */ 00390 #define COMPONENT_X 0x00 00391 #define COMPONENT_Y 0x01 00392 #define COMPONENT_Z 0x02 00393 #define COMPONENT_W 0x03 00394 #define COMPONENT_0 0x04 00395 #define COMPONENT_1 0x05 00396 00397 /* array index type */ 00398 #define ARRAY_INDEX_ABSOLUTE 0x00 00399 #define ARRAY_INDEX_RELATIVE 0x01 00400 00401 /* matrix name */ 00402 #define MATRIX_MODELVIEW 0x01 00403 #define MATRIX_PROJECTION 0x02 00404 #define MATRIX_MVP 0x03 00405 #define MATRIX_TEXTURE 0x04 00406 #define MATRIX_PALETTE 0x05 00407 #define MATRIX_PROGRAM 0x06 00408 00409 /* matrix modifier */ 00410 #define MATRIX_MODIFIER_IDENTITY 0x00 00411 #define MATRIX_MODIFIER_INVERSE 0x01 00412 #define MATRIX_MODIFIER_TRANSPOSE 0x02 00413 #define MATRIX_MODIFIER_INVTRANS 0x03 00414 00415 /* constant type */ 00416 #define CONSTANT_SCALAR 0x01 00417 #define CONSTANT_VECTOR 0x02 00418 00419 /* program param type */ 00420 #define PROGRAM_PARAM_ENV 0x01 00421 #define PROGRAM_PARAM_LOCAL 0x02 00422 00423 /* register type */ 00424 #define REGISTER_ATTRIB 0x01 00425 #define REGISTER_PARAM 0x02 00426 #define REGISTER_RESULT 0x03 00427 #define REGISTER_ESTABLISHED_NAME 0x04 00428 00429 /* param binding */ 00430 #define PARAM_NULL 0x00 00431 #define PARAM_ARRAY_ELEMENT 0x01 00432 #define PARAM_STATE_ELEMENT 0x02 00433 #define PARAM_PROGRAM_ELEMENT 0x03 00434 #define PARAM_PROGRAM_ELEMENTS 0x04 00435 #define PARAM_CONSTANT 0x05 00436 00437 /* param state property */ 00438 #define STATE_MATERIAL_PARSER 0x01 00439 #define STATE_LIGHT_PARSER 0x02 00440 #define STATE_LIGHT_MODEL 0x03 00441 #define STATE_LIGHT_PROD 0x04 00442 #define STATE_FOG 0x05 00443 #define STATE_MATRIX_ROWS 0x06 00444 /* GL_ARB_fragment_program */ 00445 #define STATE_TEX_ENV 0x07 00446 #define STATE_DEPTH 0x08 00447 /* GL_ARB_vertex_program */ 00448 #define STATE_TEX_GEN 0x09 00449 #define STATE_CLIP_PLANE 0x0A 00450 #define STATE_POINT 0x0B 00451 00452 /* state material property */ 00453 #define MATERIAL_AMBIENT 0x01 00454 #define MATERIAL_DIFFUSE 0x02 00455 #define MATERIAL_SPECULAR 0x03 00456 #define MATERIAL_EMISSION 0x04 00457 #define MATERIAL_SHININESS 0x05 00458 00459 /* state light property */ 00460 #define LIGHT_AMBIENT 0x01 00461 #define LIGHT_DIFFUSE 0x02 00462 #define LIGHT_SPECULAR 0x03 00463 #define LIGHT_POSITION 0x04 00464 #define LIGHT_ATTENUATION 0x05 00465 #define LIGHT_HALF 0x06 00466 #define LIGHT_SPOT_DIRECTION 0x07 00467 00468 /* state light model property */ 00469 #define LIGHT_MODEL_AMBIENT 0x01 00470 #define LIGHT_MODEL_SCENECOLOR 0x02 00471 00472 /* state light product property */ 00473 #define LIGHT_PROD_AMBIENT 0x01 00474 #define LIGHT_PROD_DIFFUSE 0x02 00475 #define LIGHT_PROD_SPECULAR 0x03 00476 00477 /* state texture environment property */ 00478 #define TEX_ENV_COLOR 0x01 00479 00480 /* state texture generation coord property */ 00481 #define TEX_GEN_EYE 0x01 00482 #define TEX_GEN_OBJECT 0x02 00483 00484 /* state fog property */ 00485 #define FOG_COLOR 0x01 00486 #define FOG_PARAMS 0x02 00487 00488 /* state depth property */ 00489 #define DEPTH_RANGE 0x01 00490 00491 /* state point parameters property */ 00492 #define POINT_SIZE 0x01 00493 #define POINT_ATTENUATION 0x02 00494 00495 /* declaration */ 00496 #define ATTRIB 0x01 00497 #define PARAM 0x02 00498 #define TEMP 0x03 00499 #define OUTPUT 0x04 00500 #define ALIAS 0x05 00501 /* GL_ARB_vertex_program */ 00502 #define ADDRESS 0x06 00503 00504 /*----------------------------------------------------------------------- 00505 * From here on down is the semantic checking portion 00506 * 00507 */ 00508 00512 typedef enum 00513 { 00514 vt_none, 00515 vt_address, 00516 vt_attrib, 00517 vt_param, 00518 vt_temp, 00519 vt_output, 00520 vt_alias 00521 } var_type; 00522 00523 00528 struct var_cache 00529 { 00530 const GLubyte *name; /* don't free() - no need */ 00531 var_type type; 00532 GLuint address_binding; /* The index of the address register we should 00533 * be using */ 00534 GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */ 00535 GLuint attrib_is_generic; /* If the attrib was specified through a generic 00536 * vertex attrib */ 00537 GLuint temp_binding; /* The index of the temp register we are to use */ 00538 GLuint output_binding; /* Output/result register number */ 00539 struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry 00540 * that this is aliased to */ 00541 GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, 00542 * PROGRAM_ENV_PARAM} */ 00543 GLuint param_binding_begin; /* This is the offset into the program_parameter_list where 00544 * the tokens representing our bound state (or constants) 00545 * start */ 00546 GLuint param_binding_length; /* This is how many entries in the the program_parameter_list 00547 * we take up with our state tokens or constants. Note that 00548 * this is _not_ the same as the number of param registers 00549 * we eventually use */ 00550 struct var_cache *next; 00551 }; 00552 00553 static GLvoid 00554 var_cache_create (struct var_cache **va) 00555 { 00556 *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache)); 00557 if (*va) { 00558 (**va).name = NULL; 00559 (**va).type = vt_none; 00560 (**va).attrib_binding = ~0; 00561 (**va).attrib_is_generic = 0; 00562 (**va).temp_binding = ~0; 00563 (**va).output_binding = ~0; 00564 (**va).param_binding_type = ~0; 00565 (**va).param_binding_begin = ~0; 00566 (**va).param_binding_length = ~0; 00567 (**va).alias_binding = NULL; 00568 (**va).next = NULL; 00569 } 00570 } 00571 00572 static GLvoid 00573 var_cache_destroy (struct var_cache **va) 00574 { 00575 if (*va) { 00576 var_cache_destroy (&(**va).next); 00577 _mesa_free (*va); 00578 *va = NULL; 00579 } 00580 } 00581 00582 static GLvoid 00583 var_cache_append (struct var_cache **va, struct var_cache *nv) 00584 { 00585 if (*va) 00586 var_cache_append (&(**va).next, nv); 00587 else 00588 *va = nv; 00589 } 00590 00591 static struct var_cache * 00592 var_cache_find (struct var_cache *va, const GLubyte * name) 00593 { 00594 /*struct var_cache *first = va;*/ 00595 00596 while (va) { 00597 if (!_mesa_strcmp ( (const char*) name, (const char*) va->name)) { 00598 if (va->type == vt_alias) 00599 return va->alias_binding; 00600 return va; 00601 } 00602 00603 va = va->next; 00604 } 00605 00606 return NULL; 00607 } 00608 00609 00610 00618 static void 00619 program_error(GLcontext *ctx, GLint position, const char *descrip) 00620 { 00621 if (descrip) { 00622 const char *prefix = "glProgramString(", *suffix = ")"; 00623 char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + 00624 _mesa_strlen(prefix) + 00625 _mesa_strlen(suffix) + 1); 00626 if (str) { 00627 _mesa_sprintf(str, "%s%s%s", prefix, descrip, suffix); 00628 _mesa_error(ctx, GL_INVALID_OPERATION, str); 00629 _mesa_free(str); 00630 } 00631 } 00632 _mesa_set_program_error(ctx, position, descrip); 00633 } 00634 00635 00639 static void 00640 program_error2(GLcontext *ctx, GLint position, const char *descrip, 00641 const char *var) 00642 { 00643 if (descrip) { 00644 const char *prefix = "glProgramString(", *suffix = ")"; 00645 char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + 00646 _mesa_strlen(": ") + 00647 _mesa_strlen(var) + 00648 _mesa_strlen(prefix) + 00649 _mesa_strlen(suffix) + 1); 00650 if (str) { 00651 _mesa_sprintf(str, "%s%s: %s%s", prefix, descrip, var, suffix); 00652 _mesa_error(ctx, GL_INVALID_OPERATION, str); 00653 _mesa_free(str); 00654 } 00655 } 00656 { 00657 char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + 00658 _mesa_strlen(": ") + 00659 _mesa_strlen(var) + 1); 00660 if (str) { 00661 _mesa_sprintf(str, "%s: %s", descrip, var); 00662 } 00663 _mesa_set_program_error(ctx, position, str); 00664 if (str) { 00665 _mesa_free(str); 00666 } 00667 } 00668 } 00669 00670 00671 00675 static GLuint 00676 parse_position (const GLubyte ** inst) 00677 { 00678 GLuint value; 00679 00680 value = (GLuint) (*(*inst)++); 00681 value += (GLuint) (*(*inst)++) * 0x100; 00682 value += (GLuint) (*(*inst)++) * 0x10000; 00683 value += (GLuint) (*(*inst)++) * 0x1000000; 00684 00685 return value; 00686 } 00687 00697 static struct var_cache * 00698 parse_string (const GLubyte ** inst, struct var_cache **vc_head, 00699 struct arb_program *Program, GLuint * found) 00700 { 00701 const GLubyte *i = *inst; 00702 struct var_cache *va = NULL; 00703 (void) Program; 00704 00705 *inst += _mesa_strlen ((char *) i) + 1; 00706 00707 va = var_cache_find (*vc_head, i); 00708 00709 if (va) { 00710 *found = 1; 00711 return va; 00712 } 00713 00714 *found = 0; 00715 var_cache_create (&va); 00716 va->name = (const GLubyte *) i; 00717 00718 var_cache_append (vc_head, va); 00719 00720 return va; 00721 } 00722 00723 static char * 00724 parse_string_without_adding (const GLubyte ** inst, struct arb_program *Program) 00725 { 00726 const GLubyte *i = *inst; 00727 (void) Program; 00728 00729 *inst += _mesa_strlen ((char *) i) + 1; 00730 00731 return (char *) i; 00732 } 00733 00737 static GLint 00738 parse_sign (const GLubyte ** inst) 00739 { 00740 /*return *(*inst)++ != '+'; */ 00741 00742 if (**inst == '-') { 00743 (*inst)++; 00744 return -1; 00745 } 00746 else if (**inst == '+') { 00747 (*inst)++; 00748 return 1; 00749 } 00750 00751 return 1; 00752 } 00753 00757 static GLint 00758 parse_integer (const GLubyte ** inst, struct arb_program *Program) 00759 { 00760 GLint sign; 00761 GLint value; 00762 00763 /* check if *inst points to '+' or '-' 00764 * if yes, grab the sign and increment *inst 00765 */ 00766 sign = parse_sign (inst); 00767 00768 /* now check if *inst points to 0 00769 * if yes, increment the *inst and return the default value 00770 */ 00771 if (**inst == 0) { 00772 (*inst)++; 00773 return 0; 00774 } 00775 00776 /* parse the integer as you normally would do it */ 00777 value = _mesa_atoi (parse_string_without_adding (inst, Program)); 00778 00779 /* now, after terminating 0 there is a position 00780 * to parse it - parse_position() 00781 */ 00782 Program->Position = parse_position (inst); 00783 00784 return value * sign; 00785 } 00786 00794 static GLdouble 00795 parse_float_string(const GLubyte ** inst, struct arb_program *Program, GLdouble *scale) 00796 { 00797 GLdouble value = 0.0; 00798 GLdouble oscale = 1.0; 00799 00800 if (**inst == 0) { /* this string of digits is empty-- do nothing */ 00801 (*inst)++; 00802 } 00803 else { /* nonempty string-- parse out the digits */ 00804 while (**inst >= '0' && **inst <= '9') { 00805 GLubyte digit = *((*inst)++); 00806 value = value * 10.0 + (GLint) (digit - '0'); 00807 oscale *= 10.0; 00808 } 00809 assert(**inst == 0); /* integer string should end with 0 */ 00810 (*inst)++; /* skip over terminating 0 */ 00811 Program->Position = parse_position(inst); /* skip position (from integer) */ 00812 } 00813 if (scale) 00814 *scale = oscale; 00815 return value; 00816 } 00817 00827 static GLfloat 00828 parse_float (const GLubyte ** inst, struct arb_program *Program) 00829 { 00830 GLint exponent; 00831 GLdouble whole, fraction, fracScale = 1.0; 00832 00833 whole = parse_float_string(inst, Program, 0); 00834 fraction = parse_float_string(inst, Program, &fracScale); 00835 00836 /* Parse signed exponent */ 00837 exponent = parse_integer(inst, Program); /* This is the exponent */ 00838 00839 /* Assemble parts of floating-point number: */ 00840 return (GLfloat) ((whole + fraction / fracScale) * 00841 _mesa_pow(10.0, (GLfloat) exponent)); 00842 } 00843 00844 00847 static GLfloat 00848 parse_signed_float (const GLubyte ** inst, struct arb_program *Program) 00849 { 00850 GLint sign = parse_sign (inst); 00851 GLfloat value = parse_float (inst, Program); 00852 return value * sign; 00853 } 00854 00861 static GLvoid 00862 parse_constant (const GLubyte ** inst, GLfloat *values, struct arb_program *Program, 00863 GLboolean use) 00864 { 00865 GLuint components, i; 00866 00867 00868 switch (*(*inst)++) { 00869 case CONSTANT_SCALAR: 00870 if (use == GL_TRUE) { 00871 values[0] = 00872 values[1] = 00873 values[2] = values[3] = parse_float (inst, Program); 00874 } 00875 else { 00876 values[0] = 00877 values[1] = 00878 values[2] = values[3] = parse_signed_float (inst, Program); 00879 } 00880 00881 break; 00882 case CONSTANT_VECTOR: 00883 values[0] = values[1] = values[2] = 0; 00884 values[3] = 1; 00885 components = *(*inst)++; 00886 for (i = 0; i < components; i++) { 00887 values[i] = parse_signed_float (inst, Program); 00888 } 00889 break; 00890 } 00891 } 00892 00899 static GLuint 00900 parse_relative_offset(GLcontext *ctx, const GLubyte **inst, 00901 struct arb_program *Program, GLint *offset) 00902 { 00903 (void) ctx; 00904 *offset = parse_integer(inst, Program); 00905 return 0; 00906 } 00907 00912 static GLuint 00913 parse_color_type (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, 00914 GLint * color) 00915 { 00916 (void) ctx; (void) Program; 00917 *color = *(*inst)++ != COLOR_PRIMARY; 00918 return 0; 00919 } 00920 00926 static GLuint 00927 parse_generic_attrib_num(GLcontext *ctx, const GLubyte ** inst, 00928 struct arb_program *Program, GLuint *attrib) 00929 { 00930 GLint i = parse_integer(inst, Program); 00931 00932 if ((i < 0) || (i >= MAX_VERTEX_PROGRAM_ATTRIBS)) 00933 { 00934 program_error(ctx, Program->Position, 00935 "Invalid generic vertex attribute index"); 00936 return 1; 00937 } 00938 00939 *attrib = (GLuint) i; 00940 00941 return 0; 00942 } 00943 00944 00949 static GLuint 00950 parse_output_color_num (GLcontext * ctx, const GLubyte ** inst, 00951 struct arb_program *Program, GLuint * color) 00952 { 00953 GLint i = parse_integer (inst, Program); 00954 00955 if ((i < 0) || (i >= (int)ctx->Const.MaxDrawBuffers)) { 00956 program_error(ctx, Program->Position, "Invalid draw buffer index"); 00957 return 1; 00958 } 00959 00960 *color = (GLuint) i; 00961 return 0; 00962 } 00963 00964 00971 static GLuint 00972 parse_texcoord_num (GLcontext * ctx, const GLubyte ** inst, 00973 struct arb_program *Program, GLuint * coord) 00974 { 00975 GLint i = parse_integer (inst, Program); 00976 00977 if ((i < 0) || (i >= (int)ctx->Const.MaxTextureCoordUnits)) { 00978 program_error(ctx, Program->Position, "Invalid texture coordinate index"); 00979 return 1; 00980 } 00981 00982 *coord = (GLuint) i; 00983 return 0; 00984 } 00985 00986 00993 static GLuint 00994 parse_teximage_num (GLcontext * ctx, const GLubyte ** inst, 00995 struct arb_program *Program, GLuint * coord) 00996 { 00997 GLint i = parse_integer (inst, Program); 00998 00999 if ((i < 0) || (i >= (int)ctx->Const.MaxTextureImageUnits)) { 01000 program_error(ctx, Program->Position, "Invalid texture image index"); 01001 return 1; 01002 } 01003 01004 *coord = (GLuint) i; 01005 return 0; 01006 } 01007 01008 01013 static GLuint 01014 parse_weight_num (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, 01015 GLint * coord) 01016 { 01017 *coord = parse_integer (inst, Program); 01018 01019 if ((*coord < 0) || (*coord >= 1)) { 01020 program_error(ctx, Program->Position, "Invalid weight index"); 01021 return 1; 01022 } 01023 01024 return 0; 01025 } 01026 01031 static GLuint 01032 parse_clipplane_num (GLcontext * ctx, const GLubyte ** inst, 01033 struct arb_program *Program, GLint * coord) 01034 { 01035 *coord = parse_integer (inst, Program); 01036 01037 if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) { 01038 program_error(ctx, Program->Position, "Invalid clip plane index"); 01039 return 1; 01040 } 01041 01042 return 0; 01043 } 01044 01045 01049 static GLuint 01050 parse_face_type (const GLubyte ** inst) 01051 { 01052 switch (*(*inst)++) { 01053 case FACE_FRONT: 01054 return 0; 01055 01056 case FACE_BACK: 01057 return 1; 01058 } 01059 return 0; 01060 } 01061 01062 01072 static GLuint 01073 parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, 01074 GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier) 01075 { 01076 GLubyte mat = *(*inst)++; 01077 01078 *matrix_idx = 0; 01079 01080 switch (mat) { 01081 case MATRIX_MODELVIEW: 01082 *matrix = STATE_MODELVIEW_MATRIX; 01083 *matrix_idx = parse_integer (inst, Program); 01084 if (*matrix_idx > 0) { 01085 program_error(ctx, Program->Position, 01086 "ARB_vertex_blend not supported"); 01087 return 1; 01088 } 01089 break; 01090 01091 case MATRIX_PROJECTION: 01092 *matrix = STATE_PROJECTION_MATRIX; 01093 break; 01094 01095 case MATRIX_MVP: 01096 *matrix = STATE_MVP_MATRIX; 01097 break; 01098 01099 case MATRIX_TEXTURE: 01100 *matrix = STATE_TEXTURE_MATRIX; 01101 *matrix_idx = parse_integer (inst, Program); 01102 if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) { 01103 program_error(ctx, Program->Position, "Invalid Texture Unit"); 01104 /* bad *matrix_id */ 01105 return 1; 01106 } 01107 break; 01108 01109 /* This is not currently supported (ARB_matrix_palette) */ 01110 case MATRIX_PALETTE: 01111 *matrix_idx = parse_integer (inst, Program); 01112 program_error(ctx, Program->Position, 01113 "ARB_matrix_palette not supported"); 01114 return 1; 01115 break; 01116 01117 case MATRIX_PROGRAM: 01118 *matrix = STATE_PROGRAM_MATRIX; 01119 *matrix_idx = parse_integer (inst, Program); 01120 if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) { 01121 program_error(ctx, Program->Position, "Invalid Program Matrix"); 01122 /* bad *matrix_idx */ 01123 return 1; 01124 } 01125 break; 01126 } 01127 01128 switch (*(*inst)++) { 01129 case MATRIX_MODIFIER_IDENTITY: 01130 *matrix_modifier = 0; 01131 break; 01132 case MATRIX_MODIFIER_INVERSE: 01133 *matrix_modifier = STATE_MATRIX_INVERSE; 01134 break; 01135 case MATRIX_MODIFIER_TRANSPOSE: 01136 *matrix_modifier = STATE_MATRIX_TRANSPOSE; 01137 break; 01138 case MATRIX_MODIFIER_INVTRANS: 01139 *matrix_modifier = STATE_MATRIX_INVTRANS; 01140 break; 01141 } 01142 01143 return 0; 01144 } 01145 01146 01155 static GLuint 01156 parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, 01157 struct arb_program *Program, 01158 gl_state_index state_tokens[STATE_LENGTH]) 01159 { 01160 GLubyte token = *(*inst)++; 01161 01162 switch (token) { 01163 case STATE_MATERIAL_PARSER: 01164 state_tokens[0] = STATE_MATERIAL; 01165 state_tokens[1] = parse_face_type (inst); 01166 switch (*(*inst)++) { 01167 case MATERIAL_AMBIENT: 01168 state_tokens[2] = STATE_AMBIENT; 01169 break; 01170 case MATERIAL_DIFFUSE: 01171 state_tokens[2] = STATE_DIFFUSE; 01172 break; 01173 case MATERIAL_SPECULAR: 01174 state_tokens[2] = STATE_SPECULAR; 01175 break; 01176 case MATERIAL_EMISSION: 01177 state_tokens[2] = STATE_EMISSION; 01178 break; 01179 case MATERIAL_SHININESS: 01180 state_tokens[2] = STATE_SHININESS; 01181 break; 01182 } 01183 break; 01184 01185 case STATE_LIGHT_PARSER: 01186 state_tokens[0] = STATE_LIGHT; 01187 state_tokens[1] = parse_integer (inst, Program); 01188 01189 /* Check the value of state_tokens[1] against the # of lights */ 01190 if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) { 01191 program_error(ctx, Program->Position, "Invalid Light Number"); 01192 /* bad state_tokens[1] */ 01193 return 1; 01194 } 01195 01196 switch (*(*inst)++) { 01197 case LIGHT_AMBIENT: 01198 state_tokens[2] = STATE_AMBIENT; 01199 break; 01200 case LIGHT_DIFFUSE: 01201 state_tokens[2] = STATE_DIFFUSE; 01202 break; 01203 case LIGHT_SPECULAR: 01204 state_tokens[2] = STATE_SPECULAR; 01205 break; 01206 case LIGHT_POSITION: 01207 state_tokens[2] = STATE_POSITION; 01208 break; 01209 case LIGHT_ATTENUATION: 01210 state_tokens[2] = STATE_ATTENUATION; 01211 break; 01212 case LIGHT_HALF: 01213 state_tokens[2] = STATE_HALF_VECTOR; 01214 break; 01215 case LIGHT_SPOT_DIRECTION: 01216 state_tokens[2] = STATE_SPOT_DIRECTION; 01217 break; 01218 } 01219 break; 01220 01221 case STATE_LIGHT_MODEL: 01222 switch (*(*inst)++) { 01223 case LIGHT_MODEL_AMBIENT: 01224 state_tokens[0] = STATE_LIGHTMODEL_AMBIENT; 01225 break; 01226 case LIGHT_MODEL_SCENECOLOR: 01227 state_tokens[0] = STATE_LIGHTMODEL_SCENECOLOR; 01228 state_tokens[1] = parse_face_type (inst); 01229 break; 01230 } 01231 break; 01232 01233 case STATE_LIGHT_PROD: 01234 state_tokens[0] = STATE_LIGHTPROD; 01235 state_tokens[1] = parse_integer (inst, Program); 01236 01237 /* Check the value of state_tokens[1] against the # of lights */ 01238 if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) { 01239 program_error(ctx, Program->Position, "Invalid Light Number"); 01240 /* bad state_tokens[1] */ 01241 return 1; 01242 } 01243 01244 state_tokens[2] = parse_face_type (inst); 01245 switch (*(*inst)++) { 01246 case LIGHT_PROD_AMBIENT: 01247 state_tokens[3] = STATE_AMBIENT; 01248 break; 01249 case LIGHT_PROD_DIFFUSE: 01250 state_tokens[3] = STATE_DIFFUSE; 01251 break; 01252 case LIGHT_PROD_SPECULAR: 01253 state_tokens[3] = STATE_SPECULAR; 01254 break; 01255 } 01256 break; 01257 01258 01259 case STATE_FOG: 01260 switch (*(*inst)++) { 01261 case FOG_COLOR: 01262 state_tokens[0] = STATE_FOG_COLOR; 01263 break; 01264 case FOG_PARAMS: 01265 state_tokens[0] = STATE_FOG_PARAMS; 01266 break; 01267 } 01268 break; 01269 01270 case STATE_TEX_ENV: 01271 state_tokens[1] = parse_integer (inst, Program); 01272 switch (*(*inst)++) { 01273 case TEX_ENV_COLOR: 01274 state_tokens[0] = STATE_TEXENV_COLOR; 01275 break; 01276 } 01277 break; 01278 01279 case STATE_TEX_GEN: 01280 { 01281 GLuint type, coord; 01282 01283 state_tokens[0] = STATE_TEXGEN; 01284 /*state_tokens[1] = parse_integer (inst, Program);*/ /* Texture Unit */ 01285 01286 if (parse_texcoord_num (ctx, inst, Program, &coord)) 01287 return 1; 01288 state_tokens[1] = coord; 01289 01290 /* EYE or OBJECT */ 01291 type = *(*inst)++; 01292 01293 /* 0 - s, 1 - t, 2 - r, 3 - q */ 01294 coord = *(*inst)++; 01295 01296 if (type == TEX_GEN_EYE) { 01297 switch (coord) { 01298 case COMPONENT_X: 01299 state_tokens[2] = STATE_TEXGEN_EYE_S; 01300 break; 01301 case COMPONENT_Y: 01302 state_tokens[2] = STATE_TEXGEN_EYE_T; 01303 break; 01304 case COMPONENT_Z: 01305 state_tokens[2] = STATE_TEXGEN_EYE_R; 01306 break; 01307 case COMPONENT_W: 01308 state_tokens[2] = STATE_TEXGEN_EYE_Q; 01309 break; 01310 default: 01311 _mesa_problem(ctx, "bad texgen component in " 01312 "parse_state_single_item()"); 01313 } 01314 } 01315 else { 01316 switch (coord) { 01317 case COMPONENT_X: 01318 state_tokens[2] = STATE_TEXGEN_OBJECT_S; 01319 break; 01320 case COMPONENT_Y: 01321 state_tokens[2] = STATE_TEXGEN_OBJECT_T; 01322 break; 01323 case COMPONENT_Z: 01324 state_tokens[2] = STATE_TEXGEN_OBJECT_R; 01325 break; 01326 case COMPONENT_W: 01327 state_tokens[2] = STATE_TEXGEN_OBJECT_Q; 01328 break; 01329 default: 01330 _mesa_problem(ctx, "bad texgen component in " 01331 "parse_state_single_item()"); 01332 } 01333 } 01334 } 01335 break; 01336 01337 case STATE_DEPTH: 01338 switch (*(*inst)++) { 01339 case DEPTH_RANGE: 01340 state_tokens[0] = STATE_DEPTH_RANGE; 01341 break; 01342 } 01343 break; 01344 01345 case STATE_CLIP_PLANE: 01346 state_tokens[0] = STATE_CLIPPLANE; 01347 if (parse_clipplane_num (ctx, inst, Program, 01348 (GLint *) &state_tokens[1])) 01349 return 1; 01350 break; 01351 01352 case STATE_POINT: 01353 switch (*(*inst)++) { 01354 case POINT_SIZE: 01355 state_tokens[0] = STATE_POINT_SIZE; 01356 break; 01357 01358 case POINT_ATTENUATION: 01359 state_tokens[0] = STATE_POINT_ATTENUATION; 01360 break; 01361 } 01362 break; 01363 01364 /* XXX: I think this is the correct format for a matrix row */ 01365 case STATE_MATRIX_ROWS: 01366 if (parse_matrix(ctx, inst, Program, 01367 (GLint *) &state_tokens[0], 01368 (GLint *) &state_tokens[1], 01369 (GLint *) &state_tokens[4])) 01370 return 1; 01371 01372 state_tokens[2] = parse_integer (inst, Program); /* The first row to grab */ 01373 01374 if ((**inst) != 0) { /* Either the last row, 0 */ 01375 state_tokens[3] = parse_integer (inst, Program); 01376 if (state_tokens[3] < state_tokens[2]) { 01377 program_error(ctx, Program->Position, 01378 "Second matrix index less than the first"); 01379 /* state_tokens[4] vs. state_tokens[3] */ 01380 return 1; 01381 } 01382 } 01383 else { 01384 state_tokens[3] = state_tokens[2]; 01385 (*inst)++; 01386 } 01387 break; 01388 } 01389 01390 return 0; 01391 } 01392 01423 static GLuint 01424 parse_program_single_item (GLcontext * ctx, const GLubyte ** inst, 01425 struct arb_program *Program, 01426 gl_state_index state_tokens[STATE_LENGTH]) 01427 { 01428 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) 01429 state_tokens[0] = STATE_FRAGMENT_PROGRAM; 01430 else 01431 state_tokens[0] = STATE_VERTEX_PROGRAM; 01432 01433 01434 switch (*(*inst)++) { 01435 case PROGRAM_PARAM_ENV: 01436 state_tokens[1] = STATE_ENV; 01437 state_tokens[2] = parse_integer (inst, Program); 01438 01439 /* Check state_tokens[2] against the number of ENV parameters available */ 01440 if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && 01441 (state_tokens[2] >= (GLint) ctx->Const.FragmentProgram.MaxEnvParams)) 01442 || 01443 ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && 01444 (state_tokens[2] >= (GLint) ctx->Const.VertexProgram.MaxEnvParams))) { 01445 program_error(ctx, Program->Position, 01446 "Invalid Program Env Parameter"); 01447 /* bad state_tokens[2] */ 01448 return 1; 01449 } 01450 01451 break; 01452 01453 case PROGRAM_PARAM_LOCAL: 01454 state_tokens[1] = STATE_LOCAL; 01455 state_tokens[2] = parse_integer (inst, Program); 01456 01457 /* Check state_tokens[2] against the number of LOCAL parameters available */ 01458 if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && 01459 (state_tokens[2] >= (GLint) ctx->Const.FragmentProgram.MaxLocalParams)) 01460 || 01461 ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && 01462 (state_tokens[2] >= (GLint) ctx->Const.VertexProgram.MaxLocalParams))) { 01463 program_error(ctx, Program->Position, 01464 "Invalid Program Local Parameter"); 01465 /* bad state_tokens[2] */ 01466 return 1; 01467 } 01468 break; 01469 } 01470 01471 return 0; 01472 } 01473 01483 static GLuint 01484 generic_attrib_check(struct var_cache *vc_head) 01485 { 01486 int a; 01487 struct var_cache *curr; 01488 GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS], 01489 genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS]; 01490 01491 for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) { 01492 explicitAttrib[a] = GL_FALSE; 01493 genericAttrib[a] = GL_FALSE; 01494 } 01495 01496 curr = vc_head; 01497 while (curr) { 01498 if (curr->type == vt_attrib) { 01499 if (curr->attrib_is_generic) 01500 genericAttrib[ curr->attrib_binding ] = GL_TRUE; 01501 else 01502 explicitAttrib[ curr->attrib_binding ] = GL_TRUE; 01503 } 01504 01505 curr = curr->next; 01506 } 01507 01508 for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) { 01509 if ((explicitAttrib[a]) && (genericAttrib[a])) 01510 return 1; 01511 } 01512 01513 return 0; 01514 } 01515 01523 static GLuint 01524 parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst, 01525 struct arb_program *Program, 01526 GLuint *inputReg, GLuint *is_generic) 01527 { 01528 GLint err = 0; 01529 01530 *is_generic = 0; 01531 01532 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 01533 switch (*(*inst)++) { 01534 case FRAGMENT_ATTRIB_COLOR: 01535 { 01536 GLint coord; 01537 err = parse_color_type (ctx, inst, Program, &coord); 01538 *inputReg = FRAG_ATTRIB_COL0 + coord; 01539 } 01540 break; 01541 case FRAGMENT_ATTRIB_TEXCOORD: 01542 { 01543 GLuint texcoord = 0; 01544 err = parse_texcoord_num (ctx, inst, Program, &texcoord); 01545 *inputReg = FRAG_ATTRIB_TEX0 + texcoord; 01546 } 01547 break; 01548 case FRAGMENT_ATTRIB_FOGCOORD: 01549 *inputReg = FRAG_ATTRIB_FOGC; 01550 break; 01551 case FRAGMENT_ATTRIB_POSITION: 01552 *inputReg = FRAG_ATTRIB_WPOS; 01553 break; 01554 default: 01555 err = 1; 01556 break; 01557 } 01558 } 01559 else { 01560 switch (*(*inst)++) { 01561 case VERTEX_ATTRIB_POSITION: 01562 *inputReg = VERT_ATTRIB_POS; 01563 break; 01564 01565 case VERTEX_ATTRIB_WEIGHT: 01566 { 01567 GLint weight; 01568 err = parse_weight_num (ctx, inst, Program, &weight); 01569 *inputReg = VERT_ATTRIB_WEIGHT; 01570 #if 1 01571 /* hack for Warcraft (see bug 8060) */ 01572 _mesa_warning(ctx, "Application error: vertex program uses 'vertex.weight' but GL_ARB_vertex_blend not supported."); 01573 break; 01574 #else 01575 program_error(ctx, Program->Position, 01576 "ARB_vertex_blend not supported"); 01577 return 1; 01578 #endif 01579 } 01580 01581 case VERTEX_ATTRIB_NORMAL: 01582 *inputReg = VERT_ATTRIB_NORMAL; 01583 break; 01584 01585 case VERTEX_ATTRIB_COLOR: 01586 { 01587 GLint color; 01588 err = parse_color_type (ctx, inst, Program, &color); 01589 if (color) { 01590 *inputReg = VERT_ATTRIB_COLOR1; 01591 } 01592 else { 01593 *inputReg = VERT_ATTRIB_COLOR0; 01594 } 01595 } 01596 break; 01597 01598 case VERTEX_ATTRIB_FOGCOORD: 01599 *inputReg = VERT_ATTRIB_FOG; 01600 break; 01601 01602 case VERTEX_ATTRIB_TEXCOORD: 01603 { 01604 GLuint unit = 0; 01605 err = parse_texcoord_num (ctx, inst, Program, &unit); 01606 *inputReg = VERT_ATTRIB_TEX0 + unit; 01607 } 01608 break; 01609 01610 case VERTEX_ATTRIB_MATRIXINDEX: 01611 /* Not supported at this time */ 01612 { 01613 const char *msg = "ARB_palette_matrix not supported"; 01614 parse_integer (inst, Program); 01615 program_error(ctx, Program->Position, msg); 01616 } 01617 return 1; 01618 01619 case VERTEX_ATTRIB_GENERIC: 01620 { 01621 GLuint attrib; 01622 err = parse_generic_attrib_num(ctx, inst, Program, &attrib); 01623 if (!err) { 01624 *is_generic = 1; 01625 /* Add VERT_ATTRIB_GENERIC0 here because ARB_vertex_program's 01626 * attributes do not alias the conventional vertex 01627 * attributes. 01628 */ 01629 if (attrib > 0) 01630 *inputReg = attrib + VERT_ATTRIB_GENERIC0; 01631 else 01632 *inputReg = 0; 01633 } 01634 } 01635 break; 01636 01637 default: 01638 err = 1; 01639 break; 01640 } 01641 } 01642 01643 if (err) { 01644 program_error(ctx, Program->Position, "Bad attribute binding"); 01645 } 01646 01647 return err; 01648 } 01649 01650 01659 static GLuint 01660 parse_result_binding(GLcontext *ctx, const GLubyte **inst, 01661 GLuint *outputReg, struct arb_program *Program) 01662 { 01663 const GLubyte token = *(*inst)++; 01664 01665 switch (token) { 01666 case FRAGMENT_RESULT_COLOR: 01667 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 01668 GLuint out_color; 01669 01670 /* This gets result of the color buffer we're supposed to 01671 * draw into. This pertains to GL_ARB_draw_buffers. 01672 */ 01673 parse_output_color_num(ctx, inst, Program, &out_color); 01674 ASSERT(out_color < MAX_DRAW_BUFFERS); 01675 *outputReg = FRAG_RESULT_COLR; 01676 } 01677 else { 01678 /* for vtx programs, this is VERTEX_RESULT_POSITION */ 01679 *outputReg = VERT_RESULT_HPOS; 01680 } 01681 break; 01682 01683 case FRAGMENT_RESULT_DEPTH: 01684 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 01685 /* for frag programs, this is FRAGMENT_RESULT_DEPTH */ 01686 *outputReg = FRAG_RESULT_DEPR; 01687 } 01688 else { 01689 /* for vtx programs, this is VERTEX_RESULT_COLOR */ 01690 GLint color_type; 01691 GLuint face_type = parse_face_type(inst); 01692 GLint err = parse_color_type(ctx, inst, Program, &color_type); 01693 if (err) 01694 return 1; 01695 01696 if (face_type) { 01697 /* back face */ 01698 if (color_type) { 01699 *outputReg = VERT_RESULT_BFC1; /* secondary color */ 01700 } 01701 else { 01702 *outputReg = VERT_RESULT_BFC0; /* primary color */ 01703 } 01704 } 01705 else { 01706 /* front face */ 01707 if (color_type) { 01708 *outputReg = VERT_RESULT_COL1; /* secondary color */ 01709 } 01710 /* primary color */ 01711 else { 01712 *outputReg = VERT_RESULT_COL0; /* primary color */ 01713 } 01714 } 01715 } 01716 break; 01717 01718 case VERTEX_RESULT_FOGCOORD: 01719 *outputReg = VERT_RESULT_FOGC; 01720 break; 01721 01722 case VERTEX_RESULT_POINTSIZE: 01723 *outputReg = VERT_RESULT_PSIZ; 01724 break; 01725 01726 case VERTEX_RESULT_TEXCOORD: 01727 { 01728 GLuint unit; 01729 if (parse_texcoord_num (ctx, inst, Program, &unit)) 01730 return 1; 01731 *outputReg = VERT_RESULT_TEX0 + unit; 01732 } 01733 break; 01734 } 01735 01736 Program->Base.OutputsWritten |= (1 << *outputReg); 01737 01738 return 0; 01739 } 01740 01741 01750 static GLint 01751 parse_attrib (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, 01752 struct arb_program *Program) 01753 { 01754 GLuint found; 01755 struct var_cache *attrib_var; 01756 01757 attrib_var = parse_string (inst, vc_head, Program, &found); 01758 Program->Position = parse_position (inst); 01759 if (found) { 01760 program_error2(ctx, Program->Position, 01761 "Duplicate variable declaration", 01762 (char *) attrib_var->name); 01763 return 1; 01764 } 01765 01766 attrib_var->type = vt_attrib; 01767 01768 if (parse_attrib_binding(ctx, inst, Program, &attrib_var->attrib_binding, 01769 &attrib_var->attrib_is_generic)) 01770 return 1; 01771 01772 if (generic_attrib_check(*vc_head)) { 01773 program_error(ctx, Program->Position, 01774 "Cannot use both a generic vertex attribute " 01775 "and a specific attribute of the same type"); 01776 return 1; 01777 } 01778 01779 Program->Base.NumAttributes++; 01780 return 0; 01781 } 01782 01788 static GLuint 01789 parse_param_elements (GLcontext * ctx, const GLubyte ** inst, 01790 struct var_cache *param_var, 01791 struct arb_program *Program, GLboolean use) 01792 { 01793 GLint idx; 01794 GLuint err = 0; 01795 gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0}; 01796 GLfloat const_values[4]; 01797 01798 GLubyte token = *(*inst)++; 01799 01800 switch (token) { 01801 case PARAM_STATE_ELEMENT: 01802 if (parse_state_single_item (ctx, inst, Program, state_tokens)) 01803 return 1; 01804 01805 /* If we adding STATE_MATRIX that has multiple rows, we need to 01806 * unroll it and call _mesa_add_state_reference() for each row 01807 */ 01808 if ((state_tokens[0] == STATE_MODELVIEW_MATRIX || 01809 state_tokens[0] == STATE_PROJECTION_MATRIX || 01810 state_tokens[0] == STATE_MVP_MATRIX || 01811 state_tokens[0] == STATE_TEXTURE_MATRIX || 01812 state_tokens[0] == STATE_PROGRAM_MATRIX) 01813 && (state_tokens[2] != state_tokens[3])) { 01814 GLint row; 01815 const GLint first_row = state_tokens[2]; 01816 const GLint last_row = state_tokens[3]; 01817 01818 for (row = first_row; row <= last_row; row++) { 01819 state_tokens[2] = state_tokens[3] = row; 01820 01821 idx = _mesa_add_state_reference(Program->Base.Parameters, 01822 state_tokens); 01823 if (param_var->param_binding_begin == ~0U) 01824 param_var->param_binding_begin = idx; 01825 param_var->param_binding_length++; 01826 Program->Base.NumParameters++; 01827 } 01828 } 01829 else { 01830 idx = _mesa_add_state_reference(Program->Base.Parameters, 01831 state_tokens); 01832 if (param_var->param_binding_begin == ~0U) 01833 param_var->param_binding_begin = idx; 01834 param_var->param_binding_length++; 01835 Program->Base.NumParameters++; 01836 } 01837 break; 01838 01839 case PARAM_PROGRAM_ELEMENT: 01840 if (parse_program_single_item (ctx, inst, Program, state_tokens)) 01841 return 1; 01842 idx = _mesa_add_state_reference (Program->Base.Parameters, state_tokens); 01843 if (param_var->param_binding_begin == ~0U) 01844 param_var->param_binding_begin = idx; 01845 param_var->param_binding_length++; 01846 Program->Base.NumParameters++; 01847 01848 /* Check if there is more: 0 -> we're done, else its an integer */ 01849 if (**inst) { 01850 GLuint out_of_range, new_idx; 01851 GLuint start_idx = state_tokens[2] + 1; 01852 GLuint end_idx = parse_integer (inst, Program); 01853 01854 out_of_range = 0; 01855 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 01856 if (((state_tokens[1] == STATE_ENV) 01857 && (end_idx >= ctx->Const.FragmentProgram.MaxEnvParams)) 01858 || ((state_tokens[1] == STATE_LOCAL) 01859 && (end_idx >= 01860 ctx->Const.FragmentProgram.MaxLocalParams))) 01861 out_of_range = 1; 01862 } 01863 else { 01864 if (((state_tokens[1] == STATE_ENV) 01865 && (end_idx >= ctx->Const.VertexProgram.MaxEnvParams)) 01866 || ((state_tokens[1] == STATE_LOCAL) 01867 && (end_idx >= 01868 ctx->Const.VertexProgram.MaxLocalParams))) 01869 out_of_range = 1; 01870 } 01871 if (out_of_range) { 01872 program_error(ctx, Program->Position, 01873 "Invalid Program Parameter"); /*end_idx*/ 01874 return 1; 01875 } 01876 01877 for (new_idx = start_idx; new_idx <= end_idx; new_idx++) { 01878 state_tokens[2] = new_idx; 01879 idx = _mesa_add_state_reference(Program->Base.Parameters, 01880 state_tokens); 01881 param_var->param_binding_length++; 01882 Program->Base.NumParameters++; 01883 } 01884 } 01885 else { 01886 (*inst)++; 01887 } 01888 break; 01889 01890 case PARAM_CONSTANT: 01891 /* parsing something like {1.0, 2.0, 3.0, 4.0} */ 01892 parse_constant (inst, const_values, Program, use); 01893 idx = _mesa_add_named_constant(Program->Base.Parameters, 01894 (char *) param_var->name, 01895 const_values, 4); 01896 if (param_var->param_binding_begin == ~0U) 01897 param_var->param_binding_begin = idx; 01898 param_var->param_binding_type = PROGRAM_CONSTANT; 01899 param_var->param_binding_length++; 01900 Program->Base.NumParameters++; 01901 break; 01902 01903 default: 01904 program_error(ctx, Program->Position, 01905 "Unexpected token (in parse_param_elements())"); 01906 return 1; 01907 } 01908 01909 /* Make sure we haven't blown past our parameter limits */ 01910 if (((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && 01911 (Program->Base.NumParameters >= 01912 ctx->Const.VertexProgram.MaxLocalParams)) 01913 || ((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) 01914 && (Program->Base.NumParameters >= 01915 ctx->Const.FragmentProgram.MaxLocalParams))) { 01916 program_error(ctx, Program->Position, "Too many parameter variables"); 01917 return 1; 01918 } 01919 01920 return err; 01921 } 01922 01923 01931 static GLuint 01932 parse_param (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, 01933 struct arb_program *Program) 01934 { 01935 GLuint found, err; 01936 GLint specified_length; 01937 struct var_cache *param_var; 01938 01939 err = 0; 01940 param_var = parse_string (inst, vc_head, Program, &found); 01941 Program->Position = parse_position (inst); 01942 01943 if (found) { 01944 program_error2(ctx, Program->Position, 01945 "Duplicate variable declaration", 01946 (char *) param_var->name); 01947 return 1; 01948 } 01949 01950 specified_length = parse_integer (inst, Program); 01951 01952 if (specified_length < 0) { 01953 program_error(ctx, Program->Position, "Negative parameter array length"); 01954 return 1; 01955 } 01956 01957 param_var->type = vt_param; 01958 param_var->param_binding_length = 0; 01959 01960 /* Right now, everything is shoved into the main state register file. 01961 * 01962 * In the future, it would be nice to leave things ENV/LOCAL params 01963 * in their respective register files, if possible 01964 */ 01965 param_var->param_binding_type = PROGRAM_STATE_VAR; 01966 01967 /* Remember to: 01968 * * - add each guy to the parameter list 01969 * * - increment the param_var->param_binding_len 01970 * * - store the param_var->param_binding_begin for the first one 01971 * * - compare the actual len to the specified len at the end 01972 */ 01973 while (**inst != PARAM_NULL) { 01974 if (parse_param_elements (ctx, inst, param_var, Program, GL_FALSE)) 01975 return 1; 01976 } 01977 01978 /* Test array length here! */ 01979 if (specified_length) { 01980 if (specified_length != (int)param_var->param_binding_length) { 01981 program_error(ctx, Program->Position, 01982 "Declared parameter array length does not match parameter list"); 01983 } 01984 } 01985 01986 (*inst)++; 01987 01988 return 0; 01989 } 01990 01994 static GLuint 01995 parse_param_use (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, 01996 struct arb_program *Program, struct var_cache **new_var) 01997 { 01998 struct var_cache *param_var; 01999 02000 /* First, insert a dummy entry into the var_cache */ 02001 var_cache_create (¶m_var); 02002 param_var->name = (const GLubyte *) " "; 02003 param_var->type = vt_param; 02004 02005 param_var->param_binding_length = 0; 02006 /* Don't fill in binding_begin; We use the default value of -1 02007 * to tell if its already initialized, elsewhere. 02008 * 02009 * param_var->param_binding_begin = 0; 02010 */ 02011 param_var->param_binding_type = PROGRAM_STATE_VAR; 02012 02013 var_cache_append (vc_head, param_var); 02014 02015 /* Then fill it with juicy parameter goodness */ 02016 if (parse_param_elements (ctx, inst, param_var, Program, GL_TRUE)) 02017 return 1; 02018 02019 *new_var = param_var; 02020 02021 return 0; 02022 } 02023 02024 02030 static GLuint 02031 parse_temp (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, 02032 struct arb_program *Program) 02033 { 02034 GLuint found; 02035 struct var_cache *temp_var; 02036 02037 while (**inst != 0) { 02038 temp_var = parse_string (inst, vc_head, Program, &found); 02039 Program->Position = parse_position (inst); 02040 if (found) { 02041 program_error2(ctx, Program->Position, 02042 "Duplicate variable declaration", 02043 (char *) temp_var->name); 02044 return 1; 02045 } 02046 02047 temp_var->type = vt_temp; 02048 02049 if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && 02050 (Program->Base.NumTemporaries >= 02051 ctx->Const.FragmentProgram.MaxTemps)) 02052 || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) 02053 && (Program->Base.NumTemporaries >= 02054 ctx->Const.VertexProgram.MaxTemps))) { 02055 program_error(ctx, Program->Position, 02056 "Too many TEMP variables declared"); 02057 return 1; 02058 } 02059 02060 temp_var->temp_binding = Program->Base.NumTemporaries; 02061 Program->Base.NumTemporaries++; 02062 } 02063 (*inst)++; 02064 02065 return 0; 02066 } 02067 02073 static GLuint 02074 parse_output (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, 02075 struct arb_program *Program) 02076 { 02077 GLuint found; 02078 struct var_cache *output_var; 02079 GLuint err; 02080 02081 output_var = parse_string (inst, vc_head, Program, &found); 02082 Program->Position = parse_position (inst); 02083 if (found) { 02084 program_error2(ctx, Program->Position, 02085 "Duplicate variable declaration", 02086 (char *) output_var->name); 02087 return 1; 02088 } 02089 02090 output_var->type = vt_output; 02091 02092 err = parse_result_binding(ctx, inst, &output_var->output_binding, Program); 02093 return err; 02094 } 02095 02101 static GLuint 02102 parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, 02103 struct arb_program *Program) 02104 { 02105 GLuint found; 02106 struct var_cache *temp_var; 02107 02108 temp_var = parse_string (inst, vc_head, Program, &found); 02109 Program->Position = parse_position (inst); 02110 02111 if (found) { 02112 program_error2(ctx, Program->Position, 02113 "Duplicate variable declaration", 02114 (char *) temp_var->name); 02115 return 1; 02116 } 02117 02118 temp_var->type = vt_alias; 02119 temp_var->alias_binding = parse_string (inst, vc_head, Program, &found); 02120 Program->Position = parse_position (inst); 02121 02122 if (!found) 02123 { 02124 program_error2(ctx, Program->Position, 02125 "Undefined alias value", 02126 (char *) temp_var->alias_binding->name); 02127 return 1; 02128 } 02129 02130 return 0; 02131 } 02132 02138 static GLuint 02139 parse_address (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, 02140 struct arb_program *Program) 02141 { 02142 GLuint found; 02143 struct var_cache *temp_var; 02144 02145 while (**inst != 0) { 02146 temp_var = parse_string (inst, vc_head, Program, &found); 02147 Program->Position = parse_position (inst); 02148 if (found) { 02149 program_error2(ctx, Program->Position, 02150 "Duplicate variable declaration", 02151 (char *) temp_var->name); 02152 return 1; 02153 } 02154 02155 temp_var->type = vt_address; 02156 02157 if (Program->Base.NumAddressRegs >= 02158 ctx->Const.VertexProgram.MaxAddressRegs) { 02159 const char *msg = "Too many ADDRESS variables declared"; 02160 program_error(ctx, Program->Position, msg); 02161 return 1; 02162 } 02163 02164 temp_var->address_binding = Program->Base.NumAddressRegs; 02165 Program->Base.NumAddressRegs++; 02166 } 02167 (*inst)++; 02168 02169 return 0; 02170 } 02171 02177 static GLint 02178 parse_declaration (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, 02179 struct arb_program *Program) 02180 { 02181 GLint err = 0; 02182 02183 switch (*(*inst)++) { 02184 case ADDRESS: 02185 err = parse_address (ctx, inst, vc_head, Program); 02186 break; 02187 02188 case ALIAS: 02189 err = parse_alias (ctx, inst, vc_head, Program); 02190 break; 02191 02192 case ATTRIB: 02193 err = parse_attrib (ctx, inst, vc_head, Program); 02194 break; 02195 02196 case OUTPUT: 02197 err = parse_output (ctx, inst, vc_head, Program); 02198 break; 02199 02200 case PARAM: 02201 err = parse_param (ctx, inst, vc_head, Program); 02202 break; 02203 02204 case TEMP: 02205 err = parse_temp (ctx, inst, vc_head, Program); 02206 break; 02207 } 02208 02209 return err; 02210 } 02211 02226 static GLuint 02227 parse_masked_dst_reg (GLcontext * ctx, const GLubyte ** inst, 02228 struct var_cache **vc_head, struct arb_program *Program, 02229 enum register_file *File, GLuint *Index, GLint *WriteMask) 02230 { 02231 GLuint tmp, result; 02232 struct var_cache *dst; 02233 02234 /* We either have a result register specified, or a 02235 * variable that may or may not be writable 02236 */ 02237 switch (*(*inst)++) { 02238 case REGISTER_RESULT: 02239 if (parse_result_binding(ctx, inst, Index, Program)) 02240 return 1; 02241 *File = PROGRAM_OUTPUT; 02242 break; 02243 02244 case REGISTER_ESTABLISHED_NAME: 02245 dst = parse_string (inst, vc_head, Program, &result); 02246 Program->Position = parse_position (inst); 02247 02248 /* If the name has never been added to our symbol table, we're hosed */ 02249 if (!result) { 02250 program_error(ctx, Program->Position, "0: Undefined variable"); 02251 return 1; 02252 } 02253 02254 switch (dst->type) { 02255 case vt_output: 02256 *File = PROGRAM_OUTPUT; 02257 *Index = dst->output_binding; 02258 break; 02259 02260 case vt_temp: 02261 *File = PROGRAM_TEMPORARY; 02262 *Index = dst->temp_binding; 02263 break; 02264 02265 /* If the var type is not vt_output or vt_temp, no go */ 02266 default: 02267 program_error(ctx, Program->Position, 02268 "Destination register is read only"); 02269 return 1; 02270 } 02271 break; 02272 02273 default: 02274 program_error(ctx, Program->Position, 02275 "Unexpected opcode in parse_masked_dst_reg()"); 02276 return 1; 02277 } 02278 02279 02280 /* Position invariance test */ 02281 /* This test is done now in syntax portion - when position invariance OPTION 02282 is specified, "result.position" rule is disabled so there is no way 02283 to write the position 02284 */ 02285 /*if ((Program->HintPositionInvariant) && (*File == PROGRAM_OUTPUT) && 02286 (*Index == 0)) { 02287 program_error(ctx, Program->Position, 02288 "Vertex program specified position invariance and wrote vertex position"); 02289 }*/ 02290 02291 /* And then the mask. 02292 * w,a -> bit 0 02293 * z,b -> bit 1 02294 * y,g -> bit 2 02295 * x,r -> bit 3 02296 * 02297 * ==> Need to reverse the order of bits for this! 02298 */ 02299 tmp = (GLint) *(*inst)++; 02300 *WriteMask = (((tmp>>3) & 0x1) | 02301 ((tmp>>1) & 0x2) | 02302 ((tmp<<1) & 0x4) | 02303 ((tmp<<3) & 0x8)); 02304 02305 return 0; 02306 } 02307 02308 02316 static GLuint 02317 parse_address_reg (GLcontext * ctx, const GLubyte ** inst, 02318 struct var_cache **vc_head, 02319 struct arb_program *Program, GLint * Index) 02320 { 02321 struct var_cache *dst; 02322 GLuint result; 02323 02324 *Index = 0; /* XXX */ 02325 02326 dst = parse_string (inst, vc_head, Program, &result); 02327 Program->Position = parse_position (inst); 02328 02329 /* If the name has never been added to our symbol table, we're hosed */ 02330 if (!result) { 02331 program_error(ctx, Program->Position, "Undefined variable"); 02332 return 1; 02333 } 02334 02335 if (dst->type != vt_address) { 02336 program_error(ctx, Program->Position, "Variable is not of type ADDRESS"); 02337 return 1; 02338 } 02339 02340 return 0; 02341 } 02342 02343 #if 0 /* unused */ 02344 02352 static GLuint 02353 parse_masked_address_reg (GLcontext * ctx, const GLubyte ** inst, 02354 struct var_cache **vc_head, 02355 struct arb_program *Program, GLint * Index, 02356 GLboolean * WriteMask) 02357 { 02358 if (parse_address_reg (ctx, inst, vc_head, Program, Index)) 02359 return 1; 02360 02361 /* This should be 0x8 */ 02362 (*inst)++; 02363 02364 /* Writemask of .x is implied */ 02365 WriteMask[0] = 1; 02366 WriteMask[1] = WriteMask[2] = WriteMask[3] = 0; 02367 02368 return 0; 02369 } 02370 #endif 02371 02380 static void 02381 parse_swizzle_mask(const GLubyte ** inst, GLubyte *swizzle, GLint len) 02382 { 02383 GLint i; 02384 02385 for (i = 0; i < 4; i++) 02386 swizzle[i] = i; 02387 02388 for (i = 0; i < len; i++) { 02389 switch (*(*inst)++) { 02390 case COMPONENT_X: 02391 swizzle[i] = SWIZZLE_X; 02392 break; 02393 case COMPONENT_Y: 02394 swizzle[i] = SWIZZLE_Y; 02395 break; 02396 case COMPONENT_Z: 02397 swizzle[i] = SWIZZLE_Z; 02398 break; 02399 case COMPONENT_W: 02400 swizzle[i] = SWIZZLE_W; 02401 break; 02402 default: 02403 _mesa_problem(NULL, "bad component in parse_swizzle_mask()"); 02404 return; 02405 } 02406 } 02407 } 02408 02409 02416 static void 02417 parse_extended_swizzle_mask(const GLubyte **inst, GLubyte swizzle[4], 02418 GLubyte *negateMask) 02419 { 02420 GLint i; 02421 02422 *negateMask = 0x0; 02423 for (i = 0; i < 4; i++) { 02424 GLubyte swz; 02425 if (parse_sign(inst) == -1) 02426 *negateMask |= (1 << i); 02427 02428 swz = *(*inst)++; 02429 02430 switch (swz) { 02431 case COMPONENT_0: 02432 swizzle[i] = SWIZZLE_ZERO; 02433 break; 02434 case COMPONENT_1: 02435 swizzle[i] = SWIZZLE_ONE; 02436 break; 02437 case COMPONENT_X: 02438 swizzle[i] = SWIZZLE_X; 02439 break; 02440 case COMPONENT_Y: 02441 swizzle[i] = SWIZZLE_Y; 02442 break; 02443 case COMPONENT_Z: 02444 swizzle[i] = SWIZZLE_Z; 02445 break; 02446 case COMPONENT_W: 02447 swizzle[i] = SWIZZLE_W; 02448 break; 02449 default: 02450 _mesa_problem(NULL, "bad case in parse_extended_swizzle_mask()"); 02451 return; 02452 } 02453 } 02454 } 02455 02456 02457 static GLuint 02458 parse_src_reg (GLcontext * ctx, const GLubyte ** inst, 02459 struct var_cache **vc_head, 02460 struct arb_program *Program, 02461 enum register_file * File, GLint * Index, 02462 GLboolean *IsRelOffset ) 02463 { 02464 struct var_cache *src; 02465 GLuint binding, is_generic, found; 02466 GLint offset; 02467 02468 *IsRelOffset = 0; 02469 02470 /* And the binding for the src */ 02471 switch (*(*inst)++) { 02472 case REGISTER_ATTRIB: 02473 if (parse_attrib_binding 02474 (ctx, inst, Program, &binding, &is_generic)) 02475 return 1; 02476 *File = PROGRAM_INPUT; 02477 *Index = binding; 02478 02479 /* We need to insert a dummy variable into the var_cache so we can 02480 * catch generic vertex attrib aliasing errors 02481 */ 02482 var_cache_create(&src); 02483 src->type = vt_attrib; 02484 src->name = (const GLubyte *) "Dummy Attrib Variable"; 02485 src->attrib_binding = binding; 02486 src->attrib_is_generic = is_generic; 02487 var_cache_append(vc_head, src); 02488 if (generic_attrib_check(*vc_head)) { 02489 program_error(ctx, Program->Position, 02490 "Cannot use both a generic vertex attribute " 02491 "and a specific attribute of the same type"); 02492 return 1; 02493 } 02494 break; 02495 02496 case REGISTER_PARAM: 02497 switch (**inst) { 02498 case PARAM_ARRAY_ELEMENT: 02499 (*inst)++; 02500 src = parse_string (inst, vc_head, Program, &found); 02501 Program->Position = parse_position (inst); 02502 02503 if (!found) { 02504 program_error2(ctx, Program->Position, 02505 "Undefined variable", 02506 (char *) src->name); 02507 return 1; 02508 } 02509 02510 *File = (enum register_file) src->param_binding_type; 02511 02512 switch (*(*inst)++) { 02513 case ARRAY_INDEX_ABSOLUTE: 02514 offset = parse_integer (inst, Program); 02515 02516 if ((offset < 0) 02517 || (offset >= (int)src->param_binding_length)) { 02518 program_error(ctx, Program->Position, 02519 "Index out of range"); 02520 /* offset, src->name */ 02521 return 1; 02522 } 02523 02524 *Index = src->param_binding_begin + offset; 02525 break; 02526 02527 case ARRAY_INDEX_RELATIVE: 02528 { 02529 GLint addr_reg_idx, rel_off; 02530 02531 /* First, grab the address regiseter */ 02532 if (parse_address_reg (ctx, inst, vc_head, Program, &addr_reg_idx)) 02533 return 1; 02534 02535 /* And the .x */ 02536 ((*inst)++); 02537 ((*inst)++); 02538 ((*inst)++); 02539 ((*inst)++); 02540 02541 /* Then the relative offset */ 02542 if (parse_relative_offset(ctx, inst, Program, &rel_off)) return 1; 02543 02544 /* And store it properly */ 02545 *Index = src->param_binding_begin + rel_off; 02546 *IsRelOffset = 1; 02547 } 02548 break; 02549 } 02550 break; 02551 02552 default: 02553 if (parse_param_use (ctx, inst, vc_head, Program, &src)) 02554 return 1; 02555 02556 *File = (enum register_file) src->param_binding_type; 02557 *Index = src->param_binding_begin; 02558 break; 02559 } 02560 break; 02561 02562 case REGISTER_ESTABLISHED_NAME: 02563 src = parse_string (inst, vc_head, Program, &found); 02564 Program->Position = parse_position (inst); 02565 02566 /* If the name has never been added to our symbol table, we're hosed */ 02567 if (!found) { 02568 program_error(ctx, Program->Position, 02569 "3: Undefined variable"); /* src->name */ 02570 return 1; 02571 } 02572 02573 switch (src->type) { 02574 case vt_attrib: 02575 *File = PROGRAM_INPUT; 02576 *Index = src->attrib_binding; 02577 break; 02578 02579 /* XXX: We have to handle offsets someplace in here! -- or are those above? */ 02580 case vt_param: 02581 *File = (enum register_file) src->param_binding_type; 02582 *Index = src->param_binding_begin; 02583 break; 02584 02585 case vt_temp: 02586 *File = PROGRAM_TEMPORARY; 02587 *Index = src->temp_binding; 02588 break; 02589 02590 /* If the var type is vt_output no go */ 02591 default: 02592 program_error(ctx, Program->Position, 02593 "destination register is read only"); 02594 /* bad src->name */ 02595 return 1; 02596 } 02597 break; 02598 02599 default: 02600 program_error(ctx, Program->Position, 02601 "Unknown token in parse_src_reg"); 02602 return 1; 02603 } 02604 02605 /* Add attributes to InputsRead only if they are used the program. 02606 * This avoids the handling of unused ATTRIB declarations in the drivers. */ 02607 if (*File == PROGRAM_INPUT) 02608 Program->Base.InputsRead |= (1 << *Index); 02609 02610 return 0; 02611 } 02612 02613 02617 static GLuint 02618 parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst, 02619 struct var_cache **vc_head, 02620 struct arb_program *program, 02621 struct prog_src_register *reg) 02622 { 02623 enum register_file file; 02624 GLint index; 02625 GLubyte negateMask; 02626 GLubyte swizzle[4]; 02627 GLboolean isRelOffset; 02628 02629 /* Grab the sign */ 02630 negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE; 02631 02632 /* And the src reg */ 02633 if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset)) 02634 return 1; 02635 02636 /* finally, the swizzle */ 02637 parse_swizzle_mask(inst, swizzle, 4); 02638 02639 reg->File = file; 02640 reg->Index = index; 02641 reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); 02642 reg->NegateBase = negateMask; 02643 reg->RelAddr = isRelOffset; 02644 return 0; 02645 } 02646 02647 02651 static GLuint 02652 parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst, 02653 struct var_cache **vc_head, 02654 struct arb_program *program, 02655 struct prog_src_register *reg) 02656 { 02657 enum register_file file; 02658 GLint index; 02659 GLubyte negateMask; 02660 GLubyte swizzle[4]; 02661 GLboolean isRelOffset; 02662 02663 /* Grab the sign */ 02664 negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE; 02665 02666 /* And the src reg */ 02667 if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset)) 02668 return 1; 02669 02670 /* finally, the swizzle */ 02671 parse_swizzle_mask(inst, swizzle, 1); 02672 02673 reg->File = file; 02674 reg->Index = index; 02675 reg->Swizzle = (swizzle[0] << 0); 02676 reg->NegateBase = negateMask; 02677 reg->RelAddr = isRelOffset; 02678 return 0; 02679 } 02680 02681 02686 static GLuint 02687 parse_dst_reg(GLcontext * ctx, const GLubyte ** inst, 02688 struct var_cache **vc_head, struct arb_program *program, 02689 struct prog_dst_register *reg ) 02690 { 02691 GLint mask; 02692 GLuint idx; 02693 enum register_file file; 02694 02695 if (parse_masked_dst_reg (ctx, inst, vc_head, program, &file, &idx, &mask)) 02696 return 1; 02697 02698 reg->File = file; 02699 reg->Index = idx; 02700 reg->WriteMask = mask; 02701 return 0; 02702 } 02703 02704 02710 static GLuint 02711 parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, 02712 struct var_cache **vc_head, struct arb_program *Program, 02713 struct prog_instruction *fp) 02714 { 02715 GLint a; 02716 GLuint texcoord; 02717 GLubyte instClass, type, code; 02718 GLboolean rel; 02719 GLuint shadow_tex = 0; 02720 02721 _mesa_init_instructions(fp, 1); 02722 02723 /* Record the position in the program string for debugging */ 02724 fp->StringPos = Program->Position; 02725 02726 /* OP_ALU_INST or OP_TEX_INST */ 02727 instClass = *(*inst)++; 02728 02729 /* OP_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ}, 02730 * OP_TEX_{SAMPLE, KIL} 02731 */ 02732 type = *(*inst)++; 02733 02734 /* The actual opcode name */ 02735 code = *(*inst)++; 02736 02737 /* Increment the correct count */ 02738 switch (instClass) { 02739 case OP_ALU_INST: 02740 Program->NumAluInstructions++; 02741 break; 02742 case OP_TEX_INST: 02743 Program->NumTexInstructions++; 02744 break; 02745 } 02746 02747 switch (type) { 02748 case OP_ALU_VECTOR: 02749 switch (code) { 02750 case OP_ABS_SAT: 02751 fp->SaturateMode = SATURATE_ZERO_ONE; 02752 case OP_ABS: 02753 fp->Opcode = OPCODE_ABS; 02754 break; 02755 02756 case OP_FLR_SAT: 02757 fp->SaturateMode = SATURATE_ZERO_ONE; 02758 case OP_FLR: 02759 fp->Opcode = OPCODE_FLR; 02760 break; 02761 02762 case OP_FRC_SAT: 02763 fp->SaturateMode = SATURATE_ZERO_ONE; 02764 case OP_FRC: 02765 fp->Opcode = OPCODE_FRC; 02766 break; 02767 02768 case OP_LIT_SAT: 02769 fp->SaturateMode = SATURATE_ZERO_ONE; 02770 case OP_LIT: 02771 fp->Opcode = OPCODE_LIT; 02772 break; 02773 02774 case OP_MOV_SAT: 02775 fp->SaturateMode = SATURATE_ZERO_ONE; 02776 case OP_MOV: 02777 fp->Opcode = OPCODE_MOV; 02778 break; 02779 } 02780 02781 if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) 02782 return 1; 02783 02784 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) 02785 return 1; 02786 break; 02787 02788 case OP_ALU_SCALAR: 02789 switch (code) { 02790 case OP_COS_SAT: 02791 fp->SaturateMode = SATURATE_ZERO_ONE; 02792 case OP_COS: 02793 fp->Opcode = OPCODE_COS; 02794 break; 02795 02796 case OP_EX2_SAT: 02797 fp->SaturateMode = SATURATE_ZERO_ONE; 02798 case OP_EX2: 02799 fp->Opcode = OPCODE_EX2; 02800 break; 02801 02802 case OP_LG2_SAT: 02803 fp->SaturateMode = SATURATE_ZERO_ONE; 02804 case OP_LG2: 02805 fp->Opcode = OPCODE_LG2; 02806 break; 02807 02808 case OP_RCP_SAT: 02809 fp->SaturateMode = SATURATE_ZERO_ONE; 02810 case OP_RCP: 02811 fp->Opcode = OPCODE_RCP; 02812 break; 02813 02814 case OP_RSQ_SAT: 02815 fp->SaturateMode = SATURATE_ZERO_ONE; 02816 case OP_RSQ: 02817 fp->Opcode = OPCODE_RSQ; 02818 break; 02819 02820 case OP_SIN_SAT: 02821 fp->SaturateMode = SATURATE_ZERO_ONE; 02822 case OP_SIN: 02823 fp->Opcode = OPCODE_SIN; 02824 break; 02825 02826 case OP_SCS_SAT: 02827 fp->SaturateMode = SATURATE_ZERO_ONE; 02828 case OP_SCS: 02829 02830 fp->Opcode = OPCODE_SCS; 02831 break; 02832 } 02833 02834 if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) 02835 return 1; 02836 02837 if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) 02838 return 1; 02839 break; 02840 02841 case OP_ALU_BINSC: 02842 switch (code) { 02843 case OP_POW_SAT: 02844 fp->SaturateMode = SATURATE_ZERO_ONE; 02845 case OP_POW: 02846 fp->Opcode = OPCODE_POW; 02847 break; 02848 } 02849 02850 if (parse_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg)) 02851 return 1; 02852 02853 for (a = 0; a < 2; a++) { 02854 if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) 02855 return 1; 02856 } 02857 break; 02858 02859 02860 case OP_ALU_BIN: 02861 switch (code) { 02862 case OP_ADD_SAT: 02863 fp->SaturateMode = SATURATE_ZERO_ONE; 02864 case OP_ADD: 02865 fp->Opcode = OPCODE_ADD; 02866 break; 02867 02868 case OP_DP3_SAT: 02869 fp->SaturateMode = SATURATE_ZERO_ONE; 02870 case OP_DP3: 02871 fp->Opcode = OPCODE_DP3; 02872 break; 02873 02874 case OP_DP4_SAT: 02875 fp->SaturateMode = SATURATE_ZERO_ONE; 02876 case OP_DP4: 02877 fp->Opcode = OPCODE_DP4; 02878 break; 02879 02880 case OP_DPH_SAT: 02881 fp->SaturateMode = SATURATE_ZERO_ONE; 02882 case OP_DPH: 02883 fp->Opcode = OPCODE_DPH; 02884 break; 02885 02886 case OP_DST_SAT: 02887 fp->SaturateMode = SATURATE_ZERO_ONE; 02888 case OP_DST: 02889 fp->Opcode = OPCODE_DST; 02890 break; 02891 02892 case OP_MAX_SAT: 02893 fp->SaturateMode = SATURATE_ZERO_ONE; 02894 case OP_MAX: 02895 fp->Opcode = OPCODE_MAX; 02896 break; 02897 02898 case OP_MIN_SAT: 02899 fp->SaturateMode = SATURATE_ZERO_ONE; 02900 case OP_MIN: 02901 fp->Opcode = OPCODE_MIN; 02902 break; 02903 02904 case OP_MUL_SAT: 02905 fp->SaturateMode = SATURATE_ZERO_ONE; 02906 case OP_MUL: 02907 fp->Opcode = OPCODE_MUL; 02908 break; 02909 02910 case OP_SGE_SAT: 02911 fp->SaturateMode = SATURATE_ZERO_ONE; 02912 case OP_SGE: 02913 fp->Opcode = OPCODE_SGE; 02914 break; 02915 02916 case OP_SLT_SAT: 02917 fp->SaturateMode = SATURATE_ZERO_ONE; 02918 case OP_SLT: 02919 fp->Opcode = OPCODE_SLT; 02920 break; 02921 02922 case OP_SUB_SAT: 02923 fp->SaturateMode = SATURATE_ZERO_ONE; 02924 case OP_SUB: 02925 fp->Opcode = OPCODE_SUB; 02926 break; 02927 02928 case OP_XPD_SAT: 02929 fp->SaturateMode = SATURATE_ZERO_ONE; 02930 case OP_XPD: 02931 fp->Opcode = OPCODE_XPD; 02932 break; 02933 } 02934 02935 if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) 02936 return 1; 02937 for (a = 0; a < 2; a++) { 02938 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) 02939 return 1; 02940 } 02941 break; 02942 02943 case OP_ALU_TRI: 02944 switch (code) { 02945 case OP_CMP_SAT: 02946 fp->SaturateMode = SATURATE_ZERO_ONE; 02947 case OP_CMP: 02948 fp->Opcode = OPCODE_CMP; 02949 break; 02950 02951 case OP_LRP_SAT: 02952 fp->SaturateMode = SATURATE_ZERO_ONE; 02953 case OP_LRP: 02954 fp->Opcode = OPCODE_LRP; 02955 break; 02956 02957 case OP_MAD_SAT: 02958 fp->SaturateMode = SATURATE_ZERO_ONE; 02959 case OP_MAD: 02960 fp->Opcode = OPCODE_MAD; 02961 break; 02962 } 02963 02964 if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) 02965 return 1; 02966 02967 for (a = 0; a < 3; a++) { 02968 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) 02969 return 1; 02970 } 02971 break; 02972 02973 case OP_ALU_SWZ: 02974 switch (code) { 02975 case OP_SWZ_SAT: 02976 fp->SaturateMode = SATURATE_ZERO_ONE; 02977 case OP_SWZ: 02978 fp->Opcode = OPCODE_SWZ; 02979 break; 02980 } 02981 if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) 02982 return 1; 02983 02984 { 02985 GLubyte swizzle[4]; 02986 GLubyte negateMask; 02987 enum register_file file; 02988 GLint index; 02989 02990 if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &rel)) 02991 return 1; 02992 parse_extended_swizzle_mask(inst, swizzle, &negateMask); 02993 fp->SrcReg[0].File = file; 02994 fp->SrcReg[0].Index = index; 02995 fp->SrcReg[0].NegateBase = negateMask; 02996 fp->SrcReg[0].Swizzle = MAKE_SWIZZLE4(swizzle[0], 02997 swizzle[1], 02998 swizzle[2], 02999 swizzle[3]); 03000 } 03001 break; 03002 03003 case OP_TEX_SAMPLE: 03004 switch (code) { 03005 case OP_TEX_SAT: 03006 fp->SaturateMode = SATURATE_ZERO_ONE; 03007 case OP_TEX: 03008 fp->Opcode = OPCODE_TEX; 03009 break; 03010 03011 case OP_TXP_SAT: 03012 fp->SaturateMode = SATURATE_ZERO_ONE; 03013 case OP_TXP: 03014 fp->Opcode = OPCODE_TXP; 03015 break; 03016 03017 case OP_TXB_SAT: 03018 fp->SaturateMode = SATURATE_ZERO_ONE; 03019 case OP_TXB: 03020 fp->Opcode = OPCODE_TXB; 03021 break; 03022 } 03023 03024 if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) 03025 return 1; 03026 03027 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) 03028 return 1; 03029 03030 /* texImageUnit */ 03031 if (parse_teximage_num (ctx, inst, Program, &texcoord)) 03032 return 1; 03033 fp->TexSrcUnit = texcoord; 03034 03035 /* texTarget */ 03036 switch (*(*inst)++) { 03037 case TEXTARGET_SHADOW1D: 03038 shadow_tex = 1 << texcoord; 03039 /* FALLTHROUGH */ 03040 case TEXTARGET_1D: 03041 fp->TexSrcTarget = TEXTURE_1D_INDEX; 03042 break; 03043 case TEXTARGET_SHADOW2D: 03044 shadow_tex = 1 << texcoord; 03045 /* FALLTHROUGH */ 03046 case TEXTARGET_2D: 03047 fp->TexSrcTarget = TEXTURE_2D_INDEX; 03048 break; 03049 case TEXTARGET_3D: 03050 fp->TexSrcTarget = TEXTURE_3D_INDEX; 03051 break; 03052 case TEXTARGET_SHADOWRECT: 03053 shadow_tex = 1 << texcoord; 03054 /* FALLTHROUGH */ 03055 case TEXTARGET_RECT: 03056 fp->TexSrcTarget = TEXTURE_RECT_INDEX; 03057 break; 03058 case TEXTARGET_CUBE: 03059 fp->TexSrcTarget = TEXTURE_CUBE_INDEX; 03060 break; 03061 case TEXTARGET_SHADOW1D_ARRAY: 03062 shadow_tex = 1 << texcoord; 03063 /* FALLTHROUGH */ 03064 case TEXTARGET_1D_ARRAY: 03065 fp->TexSrcTarget = TEXTURE_1D_ARRAY_INDEX; 03066 break; 03067 case TEXTARGET_SHADOW2D_ARRAY: 03068 shadow_tex = 1 << texcoord; 03069 /* FALLTHROUGH */ 03070 case TEXTARGET_2D_ARRAY: 03071 fp->TexSrcTarget = TEXTURE_2D_ARRAY_INDEX; 03072 break; 03073 } 03074 03075 /* Don't test the first time a particular sampler is seen. Each time 03076 * after that, make sure the shadow state is the same. 03077 */ 03078 if ((_mesa_bitcount(Program->TexturesUsed[texcoord]) > 0) 03079 && ((Program->ShadowSamplers & (1 << texcoord)) != shadow_tex)) { 03080 program_error(ctx, Program->Position, 03081 "texture image unit used for shadow sampling and non-shadow sampling"); 03082 return 1; 03083 } 03084 03085 Program->TexturesUsed[texcoord] |= (1 << fp->TexSrcTarget); 03086 /* Check that both "2D" and "CUBE" (for example) aren't both used */ 03087 if (_mesa_bitcount(Program->TexturesUsed[texcoord]) > 1) { 03088 program_error(ctx, Program->Position, 03089 "multiple targets used on one texture image unit"); 03090 return 1; 03091 } 03092 03093 03094 Program->ShadowSamplers |= shadow_tex; 03095 break; 03096 03097 case OP_TEX_KIL: 03098 Program->UsesKill = 1; 03099 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) 03100 return 1; 03101 fp->Opcode = OPCODE_KIL; 03102 break; 03103 default: 03104 _mesa_problem(ctx, "bad type 0x%x in parse_fp_instruction()", type); 03105 return 1; 03106 } 03107 03108 return 0; 03109 } 03110 03111 03120 static GLuint 03121 parse_vp_address_reg (GLcontext * ctx, const GLubyte ** inst, 03122 struct var_cache **vc_head, 03123 struct arb_program *Program, 03124 struct prog_dst_register *reg) 03125 { 03126 GLint idx; 03127 03128 if (parse_address_reg (ctx, inst, vc_head, Program, &idx)) 03129 return 1; 03130 03131 /* This should be 0x8 */ 03132 (*inst)++; 03133 03134 reg->File = PROGRAM_ADDRESS; 03135 reg->Index = idx; 03136 03137 /* Writemask of .x is implied */ 03138 reg->WriteMask = 0x1; 03139 return 0; 03140 } 03141 03142 03147 static GLuint 03148 parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, 03149 struct var_cache **vc_head, struct arb_program *Program, 03150 struct prog_instruction *vp) 03151 { 03152 GLint a; 03153 GLubyte type, code; 03154 03155 /* OP_ALU_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */ 03156 type = *(*inst)++; 03157 03158 /* The actual opcode name */ 03159 code = *(*inst)++; 03160 03161 _mesa_init_instructions(vp, 1); 03162 /* Record the position in the program string for debugging */ 03163 vp->StringPos = Program->Position; 03164 03165 switch (type) { 03166 /* XXX: */ 03167 case OP_ALU_ARL: 03168 vp->Opcode = OPCODE_ARL; 03169 03170 /* Remember to set SrcReg.RelAddr; */ 03171 03172 /* Get the masked address register [dst] */ 03173 if (parse_vp_address_reg(ctx, inst, vc_head, Program, &vp->DstReg)) 03174 return 1; 03175 03176 vp->DstReg.File = PROGRAM_ADDRESS; 03177 03178 /* Get a scalar src register */ 03179 if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) 03180 return 1; 03181 03182 break; 03183 03184 case OP_ALU_VECTOR: 03185 switch (code) { 03186 case OP_ABS: 03187 vp->Opcode = OPCODE_ABS; 03188 break; 03189 case OP_FLR: 03190 vp->Opcode = OPCODE_FLR; 03191 break; 03192 case OP_FRC: 03193 vp->Opcode = OPCODE_FRC; 03194 break; 03195 case OP_LIT: 03196 vp->Opcode = OPCODE_LIT; 03197 break; 03198 case OP_MOV: 03199 vp->Opcode = OPCODE_MOV; 03200 break; 03201 } 03202 03203 if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) 03204 return 1; 03205 03206 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) 03207 return 1; 03208 break; 03209 03210 case OP_ALU_SCALAR: 03211 switch (code) { 03212 case OP_EX2: 03213 vp->Opcode = OPCODE_EX2; 03214 break; 03215 case OP_EXP: 03216 vp->Opcode = OPCODE_EXP; 03217 break; 03218 case OP_LG2: 03219 vp->Opcode = OPCODE_LG2; 03220 break; 03221 case OP_LOG: 03222 vp->Opcode = OPCODE_LOG; 03223 break; 03224 case OP_RCP: 03225 vp->Opcode = OPCODE_RCP; 03226 break; 03227 case OP_RSQ: 03228 vp->Opcode = OPCODE_RSQ; 03229 break; 03230 } 03231 if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) 03232 return 1; 03233 03234 if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) 03235 return 1; 03236 break; 03237 03238 case OP_ALU_BINSC: 03239 switch (code) { 03240 case OP_POW: 03241 vp->Opcode = OPCODE_POW; 03242 break; 03243 } 03244 if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) 03245 return 1; 03246 03247 for (a = 0; a < 2; a++) { 03248 if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) 03249 return 1; 03250 } 03251 break; 03252 03253 case OP_ALU_BIN: 03254 switch (code) { 03255 case OP_ADD: 03256 vp->Opcode = OPCODE_ADD; 03257 break; 03258 case OP_DP3: 03259 vp->Opcode = OPCODE_DP3; 03260 break; 03261 case OP_DP4: 03262 vp->Opcode = OPCODE_DP4; 03263 break; 03264 case OP_DPH: 03265 vp->Opcode = OPCODE_DPH; 03266 break; 03267 case OP_DST: 03268 vp->Opcode = OPCODE_DST; 03269 break; 03270 case OP_MAX: 03271 vp->Opcode = OPCODE_MAX; 03272 break; 03273 case OP_MIN: 03274 vp->Opcode = OPCODE_MIN; 03275 break; 03276 case OP_MUL: 03277 vp->Opcode = OPCODE_MUL; 03278 break; 03279 case OP_SGE: 03280 vp->Opcode = OPCODE_SGE; 03281 break; 03282 case OP_SLT: 03283 vp->Opcode = OPCODE_SLT; 03284 break; 03285 case OP_SUB: 03286 vp->Opcode = OPCODE_SUB; 03287 break; 03288 case OP_XPD: 03289 vp->Opcode = OPCODE_XPD; 03290 break; 03291 } 03292 if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) 03293 return 1; 03294 03295 for (a = 0; a < 2; a++) { 03296 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) 03297 return 1; 03298 } 03299 break; 03300 03301 case OP_ALU_TRI: 03302 switch (code) { 03303 case OP_MAD: 03304 vp->Opcode = OPCODE_MAD; 03305 break; 03306 } 03307 03308 if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) 03309 return 1; 03310 03311 for (a = 0; a < 3; a++) { 03312 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) 03313 return 1; 03314 } 03315 break; 03316 03317 case OP_ALU_SWZ: 03318 switch (code) { 03319 case OP_SWZ: 03320 vp->Opcode = OPCODE_SWZ; 03321 break; 03322 } 03323 { 03324 GLubyte swizzle[4]; 03325 GLubyte negateMask; 03326 GLboolean relAddr; 03327 enum register_file file; 03328 GLint index; 03329 03330 if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) 03331 return 1; 03332 03333 if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &relAddr)) 03334 return 1; 03335 parse_extended_swizzle_mask (inst, swizzle, &negateMask); 03336 vp->SrcReg[0].File = file; 03337 vp->SrcReg[0].Index = index; 03338 vp->SrcReg[0].NegateBase = negateMask; 03339 vp->SrcReg[0].Swizzle = MAKE_SWIZZLE4(swizzle[0], 03340 swizzle[1], 03341 swizzle[2], 03342 swizzle[3]); 03343 vp->SrcReg[0].RelAddr = relAddr; 03344 } 03345 break; 03346 } 03347 return 0; 03348 } 03349 03350 #if DEBUG_PARSING 03351 03352 static GLvoid 03353 debug_variables (GLcontext * ctx, struct var_cache *vc_head, 03354 struct arb_program *Program) 03355 { 03356 struct var_cache *vc; 03357 GLint a, b; 03358 03359 fprintf (stderr, "debug_variables, vc_head: %p\n", (void*) vc_head); 03360 03361 /* First of all, print out the contents of the var_cache */ 03362 vc = vc_head; 03363 while (vc) { 03364 fprintf (stderr, "[%p]\n", (void*) vc); 03365 switch (vc->type) { 03366 case vt_none: 03367 fprintf (stderr, "UNDEFINED %s\n", vc->name); 03368 break; 03369 case vt_attrib: 03370 fprintf (stderr, "ATTRIB %s\n", vc->name); 03371 fprintf (stderr, " binding: 0x%x\n", vc->attrib_binding); 03372 break; 03373 case vt_param: 03374 fprintf (stderr, "PARAM %s begin: %d len: %d\n", vc->name, 03375 vc->param_binding_begin, vc->param_binding_length); 03376 b = vc->param_binding_begin; 03377 for (a = 0; a < vc->param_binding_length; a++) { 03378 fprintf (stderr, "%s\n", 03379 Program->Base.Parameters->Parameters[a + b].Name); 03380 if (Program->Base.Parameters->Parameters[a + b].Type == PROGRAM_STATE_VAR) { 03381 const char *s; 03382 s = _mesa_program_state_string(Program->Base.Parameters->Parameters 03383 [a + b].StateIndexes); 03384 fprintf(stderr, "%s\n", s); 03385 _mesa_free((char *) s); 03386 } 03387 else 03388 fprintf (stderr, "%f %f %f %f\n", 03389 Program->Base.Parameters->ParameterValues[a + b][0], 03390 Program->Base.Parameters->ParameterValues[a + b][1], 03391 Program->Base.Parameters->ParameterValues[a + b][2], 03392 Program->Base.Parameters->ParameterValues[a + b][3]); 03393 } 03394 break; 03395 case vt_temp: 03396 fprintf (stderr, "TEMP %s\n", vc->name); 03397 fprintf (stderr, " binding: 0x%x\n", vc->temp_binding); 03398 break; 03399 case vt_output: 03400 fprintf (stderr, "OUTPUT %s\n", vc->name); 03401 fprintf (stderr, " binding: 0x%x\n", vc->output_binding); 03402 break; 03403 case vt_alias: 03404 fprintf (stderr, "ALIAS %s\n", vc->name); 03405 fprintf (stderr, " binding: 0x%p (%s)\n", 03406 (void*) vc->alias_binding, vc->alias_binding->name); 03407 break; 03408 default: 03409 /* nothing */ 03410 ; 03411 } 03412 vc = vc->next; 03413 } 03414 } 03415 03416 #endif /* DEBUG_PARSING */ 03417 03418 03424 static GLint 03425 parse_instructions(GLcontext * ctx, const GLubyte * inst, 03426 struct var_cache **vc_head, struct arb_program *Program) 03427 { 03428 const GLuint maxInst = (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) 03429 ? ctx->Const.FragmentProgram.MaxInstructions 03430 : ctx->Const.VertexProgram.MaxInstructions; 03431 GLint err = 0; 03432 03433 ASSERT(MAX_INSTRUCTIONS >= maxInst); 03434 03435 Program->MajorVersion = (GLuint) * inst++; 03436 Program->MinorVersion = (GLuint) * inst++; 03437 03438 while (*inst != END) { 03439 switch (*inst++) { 03440 03441 case OPTION: 03442 switch (*inst++) { 03443 case ARB_PRECISION_HINT_FASTEST: 03444 Program->PrecisionOption = GL_FASTEST; 03445 break; 03446 03447 case ARB_PRECISION_HINT_NICEST: 03448 Program->PrecisionOption = GL_NICEST; 03449 break; 03450 03451 case ARB_FOG_EXP: 03452 Program->FogOption = GL_EXP; 03453 break; 03454 03455 case ARB_FOG_EXP2: 03456 Program->FogOption = GL_EXP2; 03457 break; 03458 03459 case ARB_FOG_LINEAR: 03460 Program->FogOption = GL_LINEAR; 03461 break; 03462 03463 case ARB_POSITION_INVARIANT: 03464 if (Program->Base.Target == GL_VERTEX_PROGRAM_ARB) 03465 Program->HintPositionInvariant = GL_TRUE; 03466 break; 03467 03468 case ARB_FRAGMENT_PROGRAM_SHADOW: 03469 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 03470 /* TODO ARB_fragment_program_shadow code */ 03471 } 03472 break; 03473 03474 case ARB_DRAW_BUFFERS: 03475 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 03476 /* do nothing for now */ 03477 } 03478 break; 03479 03480 case MESA_TEXTURE_ARRAY: 03481 /* do nothing for now */ 03482 break; 03483 } 03484 break; 03485 03486 case INSTRUCTION: 03487 /* check length */ 03488 if (Program->Base.NumInstructions + 1 >= maxInst) { 03489 program_error(ctx, Program->Position, 03490 "Max instruction count exceeded"); 03491 return 1; 03492 } 03493 Program->Position = parse_position (&inst); 03494 /* parse the current instruction */ 03495 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 03496 err = parse_fp_instruction (ctx, &inst, vc_head, Program, 03497 &Program->Base.Instructions[Program->Base.NumInstructions]); 03498 } 03499 else { 03500 err = parse_vp_instruction (ctx, &inst, vc_head, Program, 03501 &Program->Base.Instructions[Program->Base.NumInstructions]); 03502 } 03503 03504 /* increment instuction count */ 03505 Program->Base.NumInstructions++; 03506 break; 03507 03508 case DECLARATION: 03509 err = parse_declaration (ctx, &inst, vc_head, Program); 03510 break; 03511 03512 default: 03513 break; 03514 } 03515 03516 if (err) 03517 break; 03518 } 03519 03520 /* Finally, tag on an OPCODE_END instruction */ 03521 { 03522 const GLuint numInst = Program->Base.NumInstructions; 03523 _mesa_init_instructions(Program->Base.Instructions + numInst, 1); 03524 Program->Base.Instructions[numInst].Opcode = OPCODE_END; 03525 /* YYY Wrong Position in program, whatever, at least not random -> crash 03526 Program->Position = parse_position (&inst); 03527 */ 03528 Program->Base.Instructions[numInst].StringPos = Program->Position; 03529 } 03530 Program->Base.NumInstructions++; 03531 03532 /* 03533 * Initialize native counts to logical counts. The device driver may 03534 * change them if program is translated into a hardware program. 03535 */ 03536 Program->Base.NumNativeInstructions = Program->Base.NumInstructions; 03537 Program->Base.NumNativeTemporaries = Program->Base.NumTemporaries; 03538 Program->Base.NumNativeParameters = Program->Base.NumParameters; 03539 Program->Base.NumNativeAttributes = Program->Base.NumAttributes; 03540 Program->Base.NumNativeAddressRegs = Program->Base.NumAddressRegs; 03541 03542 return err; 03543 } 03544 03545 03546 /* XXX temporary */ 03547 LONGSTRING static char core_grammar_text[] = 03548 #include "shader/grammar/grammar_syn.h" 03549 ; 03550 03551 03558 static int 03559 set_reg8 (GLcontext *ctx, grammar id, const char *name, GLubyte value) 03560 { 03561 char error_msg[300]; 03562 GLint error_pos; 03563 03564 if (grammar_set_reg8 (id, (const byte *) name, value)) 03565 return 0; 03566 03567 grammar_get_last_error ((byte *) error_msg, 300, &error_pos); 03568 _mesa_set_program_error (ctx, error_pos, error_msg); 03569 _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar Register Error"); 03570 return 1; 03571 } 03572 03573 03578 static int 03579 enable_ext(GLcontext *ctx, grammar id, const char *name) 03580 { 03581 return !set_reg8(ctx, id, name, 1); 03582 } 03583 03584 03591 static GLboolean 03592 enable_parser_extensions(GLcontext *ctx, grammar id) 03593 { 03594 #if 0 03595 /* These are not supported at this time */ 03596 if ((ctx->Extensions.ARB_vertex_blend || 03597 ctx->Extensions.EXT_vertex_weighting) 03598 && !enable_ext(ctx, id, "vertex_blend")) 03599 return GL_FALSE; 03600 if (ctx->Extensions.ARB_matrix_palette 03601 && !enable_ext(ctx, id, "matrix_palette")) 03602 return GL_FALSE; 03603 #endif 03604 if (ctx->Extensions.ARB_fragment_program_shadow 03605 && !enable_ext(ctx, id, "fragment_program_shadow")) 03606 return GL_FALSE; 03607 if (ctx->Extensions.EXT_point_parameters 03608 && !enable_ext(ctx, id, "point_parameters")) 03609 return GL_FALSE; 03610 if (ctx->Extensions.EXT_secondary_color 03611 && !enable_ext(ctx, id, "secondary_color")) 03612 return GL_FALSE; 03613 if (ctx->Extensions.EXT_fog_coord 03614 && !enable_ext(ctx, id, "fog_coord")) 03615 return GL_FALSE; 03616 if (ctx->Extensions.NV_texture_rectangle 03617 && !enable_ext(ctx, id, "texture_rectangle")) 03618 return GL_FALSE; 03619 if (ctx->Extensions.ARB_draw_buffers 03620 && !enable_ext(ctx, id, "draw_buffers")) 03621 return GL_FALSE; 03622 if (ctx->Extensions.MESA_texture_array 03623 && !enable_ext(ctx, id, "texture_array")) 03624 return GL_FALSE; 03625 #if 1 03626 /* hack for Warcraft (see bug 8060) */ 03627 enable_ext(ctx, id, "vertex_blend"); 03628 #endif 03629 03630 return GL_TRUE; 03631 } 03632 03633 03643 static GLboolean 03644 _mesa_parse_arb_program(GLcontext *ctx, GLenum target, 03645 const GLubyte *str, GLsizei len, 03646 struct arb_program *program) 03647 { 03648 GLint a, err, error_pos; 03649 char error_msg[300]; 03650 GLuint parsed_len; 03651 struct var_cache *vc_head; 03652 grammar arbprogram_syn_id; 03653 GLubyte *parsed, *inst; 03654 GLubyte *strz = NULL; 03655 static int arbprogram_syn_is_ok = 0; /* XXX temporary */ 03656 03657 /* set the program target before parsing */ 03658 program->Base.Target = target; 03659 03660 /* Reset error state */ 03661 _mesa_set_program_error(ctx, -1, NULL); 03662 03663 /* check if arb_grammar_text (arbprogram.syn) is syntactically correct */ 03664 if (!arbprogram_syn_is_ok) { 03665 /* One-time initialization of parsing system */ 03666 grammar grammar_syn_id; 03667 GLuint parsed_len; 03668 03669 grammar_syn_id = grammar_load_from_text ((byte *) core_grammar_text); 03670 if (grammar_syn_id == 0) { 03671 grammar_get_last_error ((byte *) error_msg, 300, &error_pos); 03672 /* XXX this is not a GL error - it's an implementation bug! - FIX */ 03673 _mesa_set_program_error (ctx, error_pos, error_msg); 03674 _mesa_error (ctx, GL_INVALID_OPERATION, 03675 "glProgramStringARB(Error loading grammar rule set)"); 03676 return GL_FALSE; 03677 } 03678 03679 err = !grammar_check(grammar_syn_id, (byte *) arb_grammar_text, 03680 &parsed, &parsed_len); 03681 03682 /* 'parsed' is unused here */ 03683 _mesa_free (parsed); 03684 parsed = NULL; 03685 03686 /* NOTE: we can't destroy grammar_syn_id right here because 03687 * grammar_destroy() can reset the last error 03688 */ 03689 if (err) { 03690 /* XXX this is not a GL error - it's an implementation bug! - FIX */ 03691 grammar_get_last_error ((byte *) error_msg, 300, &error_pos); 03692 _mesa_set_program_error (ctx, error_pos, error_msg); 03693 _mesa_error (ctx, GL_INVALID_OPERATION, 03694 "glProgramString(Error loading grammar rule set"); 03695 grammar_destroy (grammar_syn_id); 03696 return GL_FALSE; 03697 } 03698 03699 grammar_destroy (grammar_syn_id); 03700 03701 arbprogram_syn_is_ok = 1; 03702 } 03703 03704 /* create the grammar object */ 03705 arbprogram_syn_id = grammar_load_from_text ((byte *) arb_grammar_text); 03706 if (arbprogram_syn_id == 0) { 03707 /* XXX this is not a GL error - it's an implementation bug! - FIX */ 03708 grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos); 03709 _mesa_set_program_error (ctx, error_pos, error_msg); 03710 _mesa_error (ctx, GL_INVALID_OPERATION, 03711 "glProgramString(Error loading grammer rule set)"); 03712 return GL_FALSE; 03713 } 03714 03715 /* Set program_target register value */ 03716 if (set_reg8 (ctx, arbprogram_syn_id, "program_target", 03717 program->Base.Target == GL_FRAGMENT_PROGRAM_ARB ? 0x10 : 0x20)) { 03718 grammar_destroy (arbprogram_syn_id); 03719 return GL_FALSE; 03720 } 03721 03722 if (!enable_parser_extensions(ctx, arbprogram_syn_id)) { 03723 grammar_destroy(arbprogram_syn_id); 03724 return GL_FALSE; 03725 } 03726 03727 /* check for NULL character occurences */ 03728 { 03729 GLint i; 03730 for (i = 0; i < len; i++) { 03731 if (str[i] == '\0') { 03732 program_error(ctx, i, "illegal character"); 03733 grammar_destroy (arbprogram_syn_id); 03734 return GL_FALSE; 03735 } 03736 } 03737 } 03738 03739 /* copy the program string to a null-terminated string */ 03740 strz = (GLubyte *) _mesa_malloc (len + 1); 03741 if (!strz) { 03742 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); 03743 grammar_destroy (arbprogram_syn_id); 03744 return GL_FALSE; 03745 } 03746 _mesa_memcpy (strz, str, len); 03747 strz[len] = '\0'; 03748 03749 /* do a fast check on program string - initial production buffer is 4K */ 03750 err = !grammar_fast_check(arbprogram_syn_id, strz, 03751 &parsed, &parsed_len, 0x1000); 03752 03753 /* Syntax parse error */ 03754 if (err) { 03755 grammar_get_last_error((GLubyte *) error_msg, 300, &error_pos); 03756 program_error(ctx, error_pos, error_msg); 03757 03758 #if DEBUG_PARSING 03759 /* useful for debugging */ 03760 do { 03761 int line, col; 03762 char *s; 03763 fprintf(stderr, "program: %s\n", (char *) strz); 03764 fprintf(stderr, "Error Pos: %d\n", ctx->Program.ErrorPos); 03765 s = (char *) _mesa_find_line_column(strz, strz+ctx->Program.ErrorPos, 03766 &line, &col); 03767 fprintf(stderr, "line %d col %d: %s\n", line, col, s); 03768 } while (0); 03769 #endif 03770 03771 _mesa_free(strz); 03772 _mesa_free(parsed); 03773 03774 grammar_destroy (arbprogram_syn_id); 03775 return GL_FALSE; 03776 } 03777 03778 grammar_destroy (arbprogram_syn_id); 03779 03780 /* 03781 * Program string is syntactically correct at this point 03782 * Parse the tokenized version of the program now, generating 03783 * vertex/fragment program instructions. 03784 */ 03785 03786 /* Initialize the arb_program struct */ 03787 program->Base.String = strz; 03788 program->Base.Instructions = _mesa_alloc_instructions(MAX_INSTRUCTIONS); 03789 program->Base.NumInstructions = 03790 program->Base.NumTemporaries = 03791 program->Base.NumParameters = 03792 program->Base.NumAttributes = program->Base.NumAddressRegs = 0; 03793 program->Base.Parameters = _mesa_new_parameter_list (); 03794 program->Base.InputsRead = 0x0; 03795 program->Base.OutputsWritten = 0x0; 03796 program->Position = 0; 03797 program->MajorVersion = program->MinorVersion = 0; 03798 program->PrecisionOption = GL_DONT_CARE; 03799 program->FogOption = GL_NONE; 03800 program->HintPositionInvariant = GL_FALSE; 03801 for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++) 03802 program->TexturesUsed[a] = 0x0; 03803 program->ShadowSamplers = 0x0; 03804 program->NumAluInstructions = 03805 program->NumTexInstructions = 03806 program->NumTexIndirections = 0; 03807 program->UsesKill = 0; 03808 03809 vc_head = NULL; 03810 err = GL_FALSE; 03811 03812 /* Start examining the tokens in the array */ 03813 inst = parsed; 03814 03815 /* Check the grammer rev */ 03816 if (*inst++ != REVISION) { 03817 program_error (ctx, 0, "Grammar version mismatch"); 03818 err = GL_TRUE; 03819 } 03820 else { 03821 /* ignore program target */ 03822 inst++; 03823 err = parse_instructions(ctx, inst, &vc_head, program); 03824 } 03825 03826 /*debug_variables(ctx, vc_head, program); */ 03827 03828 /* We're done with the parsed binary array */ 03829 var_cache_destroy (&vc_head); 03830 03831 _mesa_free (parsed); 03832 03833 /* Reallocate the instruction array from size [MAX_INSTRUCTIONS] 03834 * to size [ap.Base.NumInstructions]. 03835 */ 03836 program->Base.Instructions 03837 = _mesa_realloc_instructions(program->Base.Instructions, 03838 MAX_INSTRUCTIONS, 03839 program->Base.NumInstructions); 03840 03841 return !err; 03842 } 03843 03844 03845 03846 void 03847 _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, 03848 const GLvoid *str, GLsizei len, 03849 struct gl_fragment_program *program) 03850 { 03851 struct arb_program ap; 03852 GLuint i; 03853 03854 ASSERT(target == GL_FRAGMENT_PROGRAM_ARB); 03855 if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, &ap)) { 03856 /* Error in the program. Just return. */ 03857 return; 03858 } 03859 03860 /* Copy the relevant contents of the arb_program struct into the 03861 * fragment_program struct. 03862 */ 03863 program->Base.String = ap.Base.String; 03864 program->Base.NumInstructions = ap.Base.NumInstructions; 03865 program->Base.NumTemporaries = ap.Base.NumTemporaries; 03866 program->Base.NumParameters = ap.Base.NumParameters; 03867 program->Base.NumAttributes = ap.Base.NumAttributes; 03868 program->Base.NumAddressRegs = ap.Base.NumAddressRegs; 03869 program->Base.NumNativeInstructions = ap.Base.NumNativeInstructions; 03870 program->Base.NumNativeTemporaries = ap.Base.NumNativeTemporaries; 03871 program->Base.NumNativeParameters = ap.Base.NumNativeParameters; 03872 program->Base.NumNativeAttributes = ap.Base.NumNativeAttributes; 03873 program->Base.NumNativeAddressRegs = ap.Base.NumNativeAddressRegs; 03874 program->Base.NumAluInstructions = ap.Base.NumAluInstructions; 03875 program->Base.NumTexInstructions = ap.Base.NumTexInstructions; 03876 program->Base.NumTexIndirections = ap.Base.NumTexIndirections; 03877 program->Base.NumNativeAluInstructions = ap.Base.NumAluInstructions; 03878 program->Base.NumNativeTexInstructions = ap.Base.NumTexInstructions; 03879 program->Base.NumNativeTexIndirections = ap.Base.NumTexIndirections; 03880 program->Base.InputsRead = ap.Base.InputsRead; 03881 program->Base.OutputsWritten = ap.Base.OutputsWritten; 03882 for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) { 03883 program->Base.TexturesUsed[i] = ap.TexturesUsed[i]; 03884 if (ap.TexturesUsed[i]) 03885 program->Base.SamplersUsed |= (1 << i); 03886 } 03887 program->Base.ShadowSamplers = ap.ShadowSamplers; 03888 program->FogOption = ap.FogOption; 03889 program->UsesKill = ap.UsesKill; 03890 03891 if (program->FogOption) 03892 program->Base.InputsRead |= FRAG_BIT_FOGC; 03893 03894 if (program->Base.Instructions) 03895 _mesa_free(program->Base.Instructions); 03896 program->Base.Instructions = ap.Base.Instructions; 03897 03898 if (program->Base.Parameters) 03899 _mesa_free_parameter_list(program->Base.Parameters); 03900 program->Base.Parameters = ap.Base.Parameters; 03901 03902 #if DEBUG_FP 03903 _mesa_printf("____________Fragment program %u ________\n", program->Base.Id); 03904 _mesa_print_program(&program->Base); 03905 #endif 03906 } 03907 03908 03909 03915 void 03916 _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, 03917 const GLvoid *str, GLsizei len, 03918 struct gl_vertex_program *program) 03919 { 03920 struct arb_program ap; 03921 03922 ASSERT(target == GL_VERTEX_PROGRAM_ARB); 03923 03924 if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, &ap)) { 03925 _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)"); 03926 return; 03927 } 03928 03929 /* Copy the relevant contents of the arb_program struct into the 03930 * vertex_program struct. 03931 */ 03932 program->Base.String = ap.Base.String; 03933 program->Base.NumInstructions = ap.Base.NumInstructions; 03934 program->Base.NumTemporaries = ap.Base.NumTemporaries; 03935 program->Base.NumParameters = ap.Base.NumParameters; 03936 program->Base.NumAttributes = ap.Base.NumAttributes; 03937 program->Base.NumAddressRegs = ap.Base.NumAddressRegs; 03938 program->Base.NumNativeInstructions = ap.Base.NumNativeInstructions; 03939 program->Base.NumNativeTemporaries = ap.Base.NumNativeTemporaries; 03940 program->Base.NumNativeParameters = ap.Base.NumNativeParameters; 03941 program->Base.NumNativeAttributes = ap.Base.NumNativeAttributes; 03942 program->Base.NumNativeAddressRegs = ap.Base.NumNativeAddressRegs; 03943 program->Base.InputsRead = ap.Base.InputsRead; 03944 program->Base.OutputsWritten = ap.Base.OutputsWritten; 03945 program->IsPositionInvariant = ap.HintPositionInvariant; 03946 03947 if (program->Base.Instructions) 03948 _mesa_free(program->Base.Instructions); 03949 program->Base.Instructions = ap.Base.Instructions; 03950 03951 if (program->Base.Parameters) 03952 _mesa_free_parameter_list(program->Base.Parameters); 03953 program->Base.Parameters = ap.Base.Parameters; 03954 03955 #if DEBUG_VP 03956 _mesa_printf("____________Vertex program %u __________\n", program->Base.Id); 03957 _mesa_print_program(&program->Base); 03958 #endif 03959 } Generated on Sat May 26 2012 04:19:19 for ReactOS by
1.7.6.1
|