Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenslang_builtin.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.3 00004 * 00005 * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. 00006 * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 00007 * 00008 * Permission is hereby granted, free of charge, to any person obtaining a 00009 * copy of this software and associated documentation files (the "Software"), 00010 * to deal in the Software without restriction, including without limitation 00011 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00012 * and/or sell copies of the Software, and to permit persons to whom the 00013 * Software is furnished to do so, subject to the following conditions: 00014 * 00015 * The above copyright notice and this permission notice shall be included 00016 * in all copies or substantial portions of the Software. 00017 * 00018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00019 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00020 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00021 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00022 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00023 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00024 */ 00025 00032 #include "main/imports.h" 00033 #include "main/mtypes.h" 00034 #include "shader/program.h" 00035 #include "shader/prog_instruction.h" 00036 #include "shader/prog_parameter.h" 00037 #include "shader/prog_statevars.h" 00038 #include "shader/slang/slang_ir.h" 00039 #include "shader/slang/slang_emit.h" 00040 #include "shader/slang/slang_builtin.h" 00041 00042 00044 #define STATE_ARRAY ((gl_state_index) 0xfffff) 00045 00046 00053 static GLint 00054 lookup_statevar(const char *var, GLint index1, GLint index2, const char *field, 00055 GLuint *swizzleOut, 00056 struct gl_program_parameter_list *paramList) 00057 { 00058 /* 00059 * NOTE: The ARB_vertex_program extension specified that matrices get 00060 * loaded in registers in row-major order. With GLSL, we want column- 00061 * major order. So, we need to transpose all matrices here... 00062 */ 00063 static const struct { 00064 const char *name; 00065 gl_state_index matrix; 00066 gl_state_index modifier; 00067 } matrices[] = { 00068 { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, 00069 { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS }, 00070 { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, 00071 { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, 00072 00073 { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE }, 00074 { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS }, 00075 { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 }, 00076 { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE }, 00077 00078 { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE }, 00079 { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS }, 00080 { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 }, 00081 { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE }, 00082 00083 { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE }, 00084 { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS }, 00085 { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 }, 00086 { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE }, 00087 00088 { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, 00089 00090 { NULL, 0, 0 } 00091 }; 00092 gl_state_index tokens[STATE_LENGTH]; 00093 GLuint i; 00094 GLboolean isMatrix = GL_FALSE; 00095 00096 for (i = 0; i < STATE_LENGTH; i++) { 00097 tokens[i] = 0; 00098 } 00099 *swizzleOut = SWIZZLE_NOOP; 00100 00101 /* first, look if var is a pre-defined matrix */ 00102 for (i = 0; matrices[i].name; i++) { 00103 if (strcmp(var, matrices[i].name) == 0) { 00104 tokens[0] = matrices[i].matrix; 00105 /* tokens[1], [2] and [3] filled below */ 00106 tokens[4] = matrices[i].modifier; 00107 isMatrix = GL_TRUE; 00108 break; 00109 } 00110 } 00111 00112 if (isMatrix) { 00113 if (tokens[0] == STATE_TEXTURE_MATRIX) { 00114 if (index1 >= 0) { 00115 tokens[1] = index1; /* which texture matrix */ 00116 index1 = 0; /* prevent extra addition at end of function */ 00117 } 00118 } 00119 if (index1 < 0) { 00120 /* index1 is unused: prevent extra addition at end of function */ 00121 index1 = 0; 00122 } 00123 } 00124 else if (strcmp(var, "gl_DepthRange") == 0) { 00125 tokens[0] = STATE_DEPTH_RANGE; 00126 if (strcmp(field, "near") == 0) { 00127 *swizzleOut = SWIZZLE_XXXX; 00128 } 00129 else if (strcmp(field, "far") == 0) { 00130 *swizzleOut = SWIZZLE_YYYY; 00131 } 00132 else if (strcmp(field, "diff") == 0) { 00133 *swizzleOut = SWIZZLE_ZZZZ; 00134 } 00135 else { 00136 return -1; 00137 } 00138 } 00139 else if (strcmp(var, "gl_ClipPlane") == 0) { 00140 if (index1 < 0) 00141 return -1; 00142 tokens[0] = STATE_CLIPPLANE; 00143 tokens[1] = index1; 00144 } 00145 else if (strcmp(var, "gl_Point") == 0) { 00146 if (strcmp(field, "size") == 0) { 00147 tokens[0] = STATE_POINT_SIZE; 00148 *swizzleOut = SWIZZLE_XXXX; 00149 } 00150 else if (strcmp(field, "sizeMin") == 0) { 00151 tokens[0] = STATE_POINT_SIZE; 00152 *swizzleOut = SWIZZLE_YYYY; 00153 } 00154 else if (strcmp(field, "sizeMax") == 0) { 00155 tokens[0] = STATE_POINT_SIZE; 00156 *swizzleOut = SWIZZLE_ZZZZ; 00157 } 00158 else if (strcmp(field, "fadeThresholdSize") == 0) { 00159 tokens[0] = STATE_POINT_SIZE; 00160 *swizzleOut = SWIZZLE_WWWW; 00161 } 00162 else if (strcmp(field, "distanceConstantAttenuation") == 0) { 00163 tokens[0] = STATE_POINT_ATTENUATION; 00164 *swizzleOut = SWIZZLE_XXXX; 00165 } 00166 else if (strcmp(field, "distanceLinearAttenuation") == 0) { 00167 tokens[0] = STATE_POINT_ATTENUATION; 00168 *swizzleOut = SWIZZLE_YYYY; 00169 } 00170 else if (strcmp(field, "distanceQuadraticAttenuation") == 0) { 00171 tokens[0] = STATE_POINT_ATTENUATION; 00172 *swizzleOut = SWIZZLE_ZZZZ; 00173 } 00174 else { 00175 return -1; 00176 } 00177 } 00178 else if (strcmp(var, "gl_FrontMaterial") == 0 || 00179 strcmp(var, "gl_BackMaterial") == 0) { 00180 tokens[0] = STATE_MATERIAL; 00181 if (strcmp(var, "gl_FrontMaterial") == 0) 00182 tokens[1] = 0; 00183 else 00184 tokens[1] = 1; 00185 if (strcmp(field, "emission") == 0) { 00186 tokens[2] = STATE_EMISSION; 00187 } 00188 else if (strcmp(field, "ambient") == 0) { 00189 tokens[2] = STATE_AMBIENT; 00190 } 00191 else if (strcmp(field, "diffuse") == 0) { 00192 tokens[2] = STATE_DIFFUSE; 00193 } 00194 else if (strcmp(field, "specular") == 0) { 00195 tokens[2] = STATE_SPECULAR; 00196 } 00197 else if (strcmp(field, "shininess") == 0) { 00198 tokens[2] = STATE_SHININESS; 00199 *swizzleOut = SWIZZLE_XXXX; 00200 } 00201 else { 00202 return -1; 00203 } 00204 } 00205 else if (strcmp(var, "gl_LightSource") == 0) { 00206 if (!field || index1 < 0) 00207 return -1; 00208 00209 tokens[0] = STATE_LIGHT; 00210 tokens[1] = index1; 00211 00212 if (strcmp(field, "ambient") == 0) { 00213 tokens[2] = STATE_AMBIENT; 00214 } 00215 else if (strcmp(field, "diffuse") == 0) { 00216 tokens[2] = STATE_DIFFUSE; 00217 } 00218 else if (strcmp(field, "specular") == 0) { 00219 tokens[2] = STATE_SPECULAR; 00220 } 00221 else if (strcmp(field, "position") == 0) { 00222 tokens[2] = STATE_POSITION; 00223 } 00224 else if (strcmp(field, "halfVector") == 0) { 00225 tokens[2] = STATE_HALF_VECTOR; 00226 } 00227 else if (strcmp(field, "spotDirection") == 0) { 00228 tokens[2] = STATE_SPOT_DIRECTION; 00229 } 00230 else if (strcmp(field, "spotCosCutoff") == 0) { 00231 tokens[2] = STATE_SPOT_DIRECTION; 00232 *swizzleOut = SWIZZLE_WWWW; 00233 } 00234 else if (strcmp(field, "spotCutoff") == 0) { 00235 tokens[2] = STATE_SPOT_CUTOFF; 00236 *swizzleOut = SWIZZLE_XXXX; 00237 } 00238 else if (strcmp(field, "spotExponent") == 0) { 00239 tokens[2] = STATE_ATTENUATION; 00240 *swizzleOut = SWIZZLE_WWWW; 00241 } 00242 else if (strcmp(field, "constantAttenuation") == 0) { 00243 tokens[2] = STATE_ATTENUATION; 00244 *swizzleOut = SWIZZLE_XXXX; 00245 } 00246 else if (strcmp(field, "linearAttenuation") == 0) { 00247 tokens[2] = STATE_ATTENUATION; 00248 *swizzleOut = SWIZZLE_YYYY; 00249 } 00250 else if (strcmp(field, "quadraticAttenuation") == 0) { 00251 tokens[2] = STATE_ATTENUATION; 00252 *swizzleOut = SWIZZLE_ZZZZ; 00253 } 00254 else { 00255 return -1; 00256 } 00257 } 00258 else if (strcmp(var, "gl_LightModel") == 0) { 00259 if (strcmp(field, "ambient") == 0) { 00260 tokens[0] = STATE_LIGHTMODEL_AMBIENT; 00261 } 00262 else { 00263 return -1; 00264 } 00265 } 00266 else if (strcmp(var, "gl_FrontLightModelProduct") == 0) { 00267 if (strcmp(field, "sceneColor") == 0) { 00268 tokens[0] = STATE_LIGHTMODEL_SCENECOLOR; 00269 tokens[1] = 0; 00270 } 00271 else { 00272 return -1; 00273 } 00274 } 00275 else if (strcmp(var, "gl_BackLightModelProduct") == 0) { 00276 if (strcmp(field, "sceneColor") == 0) { 00277 tokens[0] = STATE_LIGHTMODEL_SCENECOLOR; 00278 tokens[1] = 1; 00279 } 00280 else { 00281 return -1; 00282 } 00283 } 00284 else if (strcmp(var, "gl_FrontLightProduct") == 0 || 00285 strcmp(var, "gl_BackLightProduct") == 0) { 00286 if (index1 < 0 || !field) 00287 return -1; 00288 00289 tokens[0] = STATE_LIGHTPROD; 00290 tokens[1] = index1; /* light number */ 00291 if (strcmp(var, "gl_FrontLightProduct") == 0) { 00292 tokens[2] = 0; /* front */ 00293 } 00294 else { 00295 tokens[2] = 1; /* back */ 00296 } 00297 if (strcmp(field, "ambient") == 0) { 00298 tokens[3] = STATE_AMBIENT; 00299 } 00300 else if (strcmp(field, "diffuse") == 0) { 00301 tokens[3] = STATE_DIFFUSE; 00302 } 00303 else if (strcmp(field, "specular") == 0) { 00304 tokens[3] = STATE_SPECULAR; 00305 } 00306 else { 00307 return -1; 00308 } 00309 } 00310 else if (strcmp(var, "gl_TextureEnvColor") == 0) { 00311 if (index1 < 0) 00312 return -1; 00313 tokens[0] = STATE_TEXENV_COLOR; 00314 tokens[1] = index1; 00315 } 00316 else if (strcmp(var, "gl_EyePlaneS") == 0) { 00317 if (index1 < 0) 00318 return -1; 00319 tokens[0] = STATE_TEXGEN; 00320 tokens[1] = index1; /* tex unit */ 00321 tokens[2] = STATE_TEXGEN_EYE_S; 00322 } 00323 else if (strcmp(var, "gl_EyePlaneT") == 0) { 00324 if (index1 < 0) 00325 return -1; 00326 tokens[0] = STATE_TEXGEN; 00327 tokens[1] = index1; /* tex unit */ 00328 tokens[2] = STATE_TEXGEN_EYE_T; 00329 } 00330 else if (strcmp(var, "gl_EyePlaneR") == 0) { 00331 if (index1 < 0) 00332 return -1; 00333 tokens[0] = STATE_TEXGEN; 00334 tokens[1] = index1; /* tex unit */ 00335 tokens[2] = STATE_TEXGEN_EYE_R; 00336 } 00337 else if (strcmp(var, "gl_EyePlaneQ") == 0) { 00338 if (index1 < 0) 00339 return -1; 00340 tokens[0] = STATE_TEXGEN; 00341 tokens[1] = index1; /* tex unit */ 00342 tokens[2] = STATE_TEXGEN_EYE_Q; 00343 } 00344 else if (strcmp(var, "gl_ObjectPlaneS") == 0) { 00345 if (index1 < 0) 00346 return -1; 00347 tokens[0] = STATE_TEXGEN; 00348 tokens[1] = index1; /* tex unit */ 00349 tokens[2] = STATE_TEXGEN_OBJECT_S; 00350 } 00351 else if (strcmp(var, "gl_ObjectPlaneT") == 0) { 00352 if (index1 < 0) 00353 return -1; 00354 tokens[0] = STATE_TEXGEN; 00355 tokens[1] = index1; /* tex unit */ 00356 tokens[2] = STATE_TEXGEN_OBJECT_T; 00357 } 00358 else if (strcmp(var, "gl_ObjectPlaneR") == 0) { 00359 if (index1 < 0) 00360 return -1; 00361 tokens[0] = STATE_TEXGEN; 00362 tokens[1] = index1; /* tex unit */ 00363 tokens[2] = STATE_TEXGEN_OBJECT_R; 00364 } 00365 else if (strcmp(var, "gl_ObjectPlaneQ") == 0) { 00366 if (index1 < 0) 00367 return -1; 00368 tokens[0] = STATE_TEXGEN; 00369 tokens[1] = index1; /* tex unit */ 00370 tokens[2] = STATE_TEXGEN_OBJECT_Q; 00371 } 00372 else if (strcmp(var, "gl_Fog") == 0) { 00373 if (strcmp(field, "color") == 0) { 00374 tokens[0] = STATE_FOG_COLOR; 00375 } 00376 else if (strcmp(field, "density") == 0) { 00377 tokens[0] = STATE_FOG_PARAMS; 00378 *swizzleOut = SWIZZLE_XXXX; 00379 } 00380 else if (strcmp(field, "start") == 0) { 00381 tokens[0] = STATE_FOG_PARAMS; 00382 *swizzleOut = SWIZZLE_YYYY; 00383 } 00384 else if (strcmp(field, "end") == 0) { 00385 tokens[0] = STATE_FOG_PARAMS; 00386 *swizzleOut = SWIZZLE_ZZZZ; 00387 } 00388 else if (strcmp(field, "scale") == 0) { 00389 tokens[0] = STATE_FOG_PARAMS; 00390 *swizzleOut = SWIZZLE_WWWW; 00391 } 00392 else { 00393 return -1; 00394 } 00395 } 00396 else { 00397 return -1; 00398 } 00399 00400 if (isMatrix) { 00401 /* load all four columns of matrix */ 00402 GLint pos[4]; 00403 GLuint j; 00404 for (j = 0; j < 4; j++) { 00405 tokens[2] = tokens[3] = j; /* jth row of matrix */ 00406 pos[j] = _mesa_add_state_reference(paramList, tokens); 00407 assert(pos[j] >= 0); 00408 ASSERT(pos[j] >= 0); 00409 } 00410 return pos[0] + index1; 00411 } 00412 else { 00413 /* allocate a single register */ 00414 GLint pos = _mesa_add_state_reference(paramList, tokens); 00415 ASSERT(pos >= 0); 00416 return pos; 00417 } 00418 } 00419 00420 00421 00433 static GLint 00434 emit_statevars(const char *name, int array_len, 00435 const slang_type_specifier *type, 00436 gl_state_index tokens[STATE_LENGTH], 00437 struct gl_program_parameter_list *paramList) 00438 { 00439 if (type->type == SLANG_SPEC_ARRAY) { 00440 GLint i, pos; 00441 assert(array_len > 0); 00442 if (strcmp(name, "gl_ClipPlane") == 0) { 00443 tokens[0] = STATE_CLIPPLANE; 00444 } 00445 else if (strcmp(name, "gl_LightSource") == 0) { 00446 tokens[0] = STATE_LIGHT; 00447 } 00448 else if (strcmp(name, "gl_FrontLightProduct") == 0) { 00449 tokens[0] = STATE_LIGHTPROD; 00450 tokens[2] = 0; /* front */ 00451 } 00452 else if (strcmp(name, "gl_BackLightProduct") == 0) { 00453 tokens[0] = STATE_LIGHTPROD; 00454 tokens[2] = 1; /* back */ 00455 } 00456 else if (strcmp(name, "gl_TextureEnvColor") == 0) { 00457 tokens[0] = STATE_TEXENV_COLOR; 00458 } 00459 else if (strcmp(name, "gl_EyePlaneS") == 0) { 00460 tokens[0] = STATE_TEXGEN_EYE_S; 00461 } 00462 else if (strcmp(name, "gl_EyePlaneT") == 0) { 00463 tokens[0] = STATE_TEXGEN_EYE_T; 00464 } 00465 else if (strcmp(name, "gl_EyePlaneR") == 0) { 00466 tokens[0] = STATE_TEXGEN_EYE_R; 00467 } 00468 else if (strcmp(name, "gl_EyePlaneQ") == 0) { 00469 tokens[0] = STATE_TEXGEN_EYE_Q; 00470 } 00471 else if (strcmp(name, "gl_ObjectPlaneS") == 0) { 00472 tokens[0] = STATE_TEXGEN_OBJECT_S; 00473 } 00474 else if (strcmp(name, "gl_ObjectPlaneT") == 0) { 00475 tokens[0] = STATE_TEXGEN_OBJECT_T; 00476 } 00477 else if (strcmp(name, "gl_ObjectPlaneR") == 0) { 00478 tokens[0] = STATE_TEXGEN_OBJECT_R; 00479 } 00480 else if (strcmp(name, "gl_ObjectPlaneQ") == 0) { 00481 tokens[0] = STATE_TEXGEN_OBJECT_Q; 00482 } 00483 else { 00484 return -1; /* invalid array name */ 00485 } 00486 for (i = 0; i < array_len; i++) { 00487 GLint p; 00488 tokens[1] = i; 00489 p = emit_statevars(NULL, 0, type->_array, tokens, paramList); 00490 if (i == 0) 00491 pos = p; 00492 } 00493 return pos; 00494 } 00495 else if (type->type == SLANG_SPEC_STRUCT) { 00496 const slang_variable_scope *fields = type->_struct->fields; 00497 GLuint i, pos; 00498 for (i = 0; i < fields->num_variables; i++) { 00499 const slang_variable *var = fields->variables[i]; 00500 GLint p = emit_statevars(var->a_name, 0, &var->type.specifier, 00501 tokens, paramList); 00502 if (i == 0) 00503 pos = p; 00504 } 00505 return pos; 00506 } 00507 else { 00508 GLint pos; 00509 assert(type->type == SLANG_SPEC_VEC4 || 00510 type->type == SLANG_SPEC_VEC3 || 00511 type->type == SLANG_SPEC_VEC2 || 00512 type->type == SLANG_SPEC_FLOAT || 00513 type->type == SLANG_SPEC_IVEC4 || 00514 type->type == SLANG_SPEC_IVEC3 || 00515 type->type == SLANG_SPEC_IVEC2 || 00516 type->type == SLANG_SPEC_INT); 00517 if (name) { 00518 GLint t; 00519 00520 if (tokens[0] == STATE_LIGHT) 00521 t = 2; 00522 else if (tokens[0] == STATE_LIGHTPROD) 00523 t = 3; 00524 else 00525 return -1; /* invalid array name */ 00526 00527 if (strcmp(name, "ambient") == 0) { 00528 tokens[t] = STATE_AMBIENT; 00529 } 00530 else if (strcmp(name, "diffuse") == 0) { 00531 tokens[t] = STATE_DIFFUSE; 00532 } 00533 else if (strcmp(name, "specular") == 0) { 00534 tokens[t] = STATE_SPECULAR; 00535 } 00536 else if (strcmp(name, "position") == 0) { 00537 tokens[t] = STATE_POSITION; 00538 } 00539 else if (strcmp(name, "halfVector") == 0) { 00540 tokens[t] = STATE_HALF_VECTOR; 00541 } 00542 else if (strcmp(name, "spotDirection") == 0) { 00543 tokens[t] = STATE_SPOT_DIRECTION; /* xyz components */ 00544 } 00545 else if (strcmp(name, "spotCosCutoff") == 0) { 00546 tokens[t] = STATE_SPOT_DIRECTION; /* w component */ 00547 } 00548 00549 else if (strcmp(name, "constantAttenuation") == 0) { 00550 tokens[t] = STATE_ATTENUATION; /* x component */ 00551 } 00552 else if (strcmp(name, "linearAttenuation") == 0) { 00553 tokens[t] = STATE_ATTENUATION; /* y component */ 00554 } 00555 else if (strcmp(name, "quadraticAttenuation") == 0) { 00556 tokens[t] = STATE_ATTENUATION; /* z component */ 00557 } 00558 else if (strcmp(name, "spotExponent") == 0) { 00559 tokens[t] = STATE_ATTENUATION; /* w = spot exponent */ 00560 } 00561 00562 else if (strcmp(name, "spotCutoff") == 0) { 00563 tokens[t] = STATE_SPOT_CUTOFF; /* x component */ 00564 } 00565 00566 else { 00567 return -1; /* invalid field name */ 00568 } 00569 } 00570 00571 pos = _mesa_add_state_reference(paramList, tokens); 00572 return pos; 00573 } 00574 00575 return 1; 00576 } 00577 00578 00583 static GLint 00584 alloc_state_var_array(const slang_variable *var, 00585 struct gl_program_parameter_list *paramList) 00586 { 00587 gl_state_index tokens[STATE_LENGTH]; 00588 GLuint i; 00589 GLint pos; 00590 00591 /* Initialize the state tokens array. This is very important. 00592 * When we call _mesa_add_state_reference() it'll searches the parameter 00593 * list to see if the given statevar token sequence is already present. 00594 * This is normally a good thing since it prevents redundant values in the 00595 * constant buffer. 00596 * 00597 * But when we're building arrays of state this can be bad. For example, 00598 * consider this fragment of GLSL code: 00599 * foo = gl_LightSource[3].diffuse; 00600 * ... 00601 * bar = gl_LightSource[i].diffuse; 00602 * 00603 * When we unroll the gl_LightSource array (for "bar") we want to re-emit 00604 * gl_LightSource[3].diffuse and not re-use the first instance (from "foo") 00605 * since that would upset the array layout. We handle this situation by 00606 * setting the last token in the state var token array to the special 00607 * value STATE_ARRAY. 00608 * This token will only be set for array state. We can hijack the last 00609 * element in the array for this since it's never used for light, clipplane 00610 * or texture env array state. 00611 */ 00612 for (i = 0; i < STATE_LENGTH; i++) 00613 tokens[i] = 0; 00614 tokens[STATE_LENGTH - 1] = STATE_ARRAY; 00615 00616 pos = emit_statevars(var->a_name, var->array_len, &var->type.specifier, 00617 tokens, paramList); 00618 00619 return pos; 00620 } 00621 00622 00623 00647 GLint 00648 _slang_alloc_statevar(slang_ir_node *n, 00649 struct gl_program_parameter_list *paramList, 00650 GLboolean *direct) 00651 { 00652 slang_ir_node *n0 = n; 00653 const char *field = NULL; 00654 GLint index1 = -1, index2 = -1; 00655 GLuint swizzle; 00656 00657 *direct = GL_TRUE; 00658 00659 if (n->Opcode == IR_FIELD) { 00660 field = n->Field; 00661 n = n->Children[0]; 00662 } 00663 00664 if (n->Opcode == IR_ELEMENT) { 00665 if (n->Children[1]->Opcode == IR_FLOAT) { 00666 index1 = (GLint) n->Children[1]->Value[0]; 00667 } 00668 else { 00669 *direct = GL_FALSE; 00670 } 00671 n = n->Children[0]; 00672 } 00673 00674 if (n->Opcode == IR_ELEMENT) { 00675 /* XXX can only handle constant indexes for now */ 00676 if (n->Children[1]->Opcode == IR_FLOAT) { 00677 index2 = (GLint) n->Children[1]->Value[0]; 00678 } 00679 else { 00680 *direct = GL_FALSE; 00681 } 00682 n = n->Children[0]; 00683 } 00684 00685 assert(n->Opcode == IR_VAR); 00686 00687 if (*direct) { 00688 const char *var = (const char *) n->Var->a_name; 00689 GLint pos = 00690 lookup_statevar(var, index1, index2, field, &swizzle, paramList); 00691 if (pos >= 0) { 00692 /* newly resolved storage for the statevar/constant/uniform */ 00693 n0->Store->File = PROGRAM_STATE_VAR; 00694 n0->Store->Index = pos; 00695 n0->Store->Swizzle = swizzle; 00696 n0->Store->Parent = NULL; 00697 return pos; 00698 } 00699 } 00700 00701 *direct = GL_FALSE; 00702 return alloc_state_var_array(n->Var, paramList); 00703 } Generated on Sat May 26 2012 04:19:23 for ReactOS by
1.7.6.1
|