ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

slang_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.