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_simplify.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 2005-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 
00031 #include "main/imports.h"
00032 #include "main/macros.h"
00033 #include "main/get.h"
00034 #include "slang_compile.h"
00035 #include "slang_codegen.h"
00036 #include "slang_simplify.h"
00037 #include "slang_print.h"
00038 
00039 
00040 #ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS
00041 #define GL_MAX_FRAGMENT_UNIFORM_VECTORS     0x8DFD
00042 #endif
00043 #ifndef GL_MAX_VERTEX_UNIFORM_VECTORS
00044 #define GL_MAX_VERTEX_UNIFORM_VECTORS       0x8DFB
00045 #endif
00046 #ifndef GL_MAX_VARYING_VECTORS
00047 #define GL_MAX_VARYING_VECTORS              0x8DFC
00048 #endif
00049 
00050 
00055 GLint
00056 _slang_lookup_constant(const char *name)
00057 {
00058    struct constant_info {
00059       const char *Name;
00060       const GLenum Token;
00061    };
00062    static const struct constant_info info[] = {
00063       { "gl_MaxClipPlanes", GL_MAX_CLIP_PLANES },
00064       { "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS },
00065       { "gl_MaxDrawBuffers", GL_MAX_DRAW_BUFFERS },
00066       { "gl_MaxFragmentUniformComponents", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS },
00067       { "gl_MaxLights", GL_MAX_LIGHTS },
00068       { "gl_MaxTextureUnits", GL_MAX_TEXTURE_UNITS },
00069       { "gl_MaxTextureCoords", GL_MAX_TEXTURE_COORDS },
00070       { "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS },
00071       { "gl_MaxVertexUniformComponents", GL_MAX_VERTEX_UNIFORM_COMPONENTS },
00072       { "gl_MaxVaryingFloats", GL_MAX_VARYING_FLOATS },
00073       { "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS },
00074       { "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS },
00075 #if FEATURE_es2_glsl
00076       { "gl_MaxVertexUniformVectors", GL_MAX_VERTEX_UNIFORM_VECTORS },
00077       { "gl_MaxVaryingVectors", GL_MAX_VARYING_VECTORS },
00078       { "gl_MaxFragmentUniformVectors", GL_MAX_FRAGMENT_UNIFORM_VECTORS },
00079 #endif
00080       { NULL, 0 }
00081    };
00082    GLuint i;
00083 
00084    for (i = 0; info[i].Name; i++) {
00085       if (strcmp(info[i].Name, name) == 0) {
00086          /* found */
00087          GLint value = -1;
00088          _mesa_GetIntegerv(info[i].Token, &value);
00089          ASSERT(value >= 0);  /* sanity check that glGetFloatv worked */
00090          return value;
00091       }
00092    }
00093    return -1;
00094 }
00095 
00096 
00097 static slang_operation_type
00098 literal_type(slang_operation_type t1, slang_operation_type t2)
00099 {
00100    if (t1 == SLANG_OPER_LITERAL_FLOAT || t2 == SLANG_OPER_LITERAL_FLOAT)
00101       return SLANG_OPER_LITERAL_FLOAT;
00102    else
00103       return SLANG_OPER_LITERAL_INT;
00104 }
00105 
00106 
00114 void
00115 _slang_simplify(slang_operation *oper,
00116                 const slang_name_space * space,
00117                 slang_atom_pool * atoms)
00118 {
00119    GLboolean isFloat[4];
00120    GLboolean isBool[4];
00121    GLuint i, n;
00122 
00123    if (oper->type == SLANG_OPER_IDENTIFIER) {
00124       /* see if it's a named constant */
00125       GLint value = _slang_lookup_constant((char *) oper->a_id);
00126       /*printf("value[%s] = %d\n", (char*) oper->a_id, value);*/
00127       if (value >= 0) {
00128          oper->literal[0] =
00129          oper->literal[1] =
00130          oper->literal[2] =
00131          oper->literal[3] = (GLfloat) value;
00132          oper->type = SLANG_OPER_LITERAL_INT;
00133          return;
00134       }
00135       /* look for user-defined constant */
00136       {
00137          slang_variable *var;
00138          var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
00139          if (var) {
00140             if (var->type.qualifier == SLANG_QUAL_CONST &&
00141                 var->initializer &&
00142                 (var->initializer->type == SLANG_OPER_LITERAL_INT ||
00143                  var->initializer->type == SLANG_OPER_LITERAL_FLOAT)) {
00144                oper->literal[0] = var->initializer->literal[0];
00145                oper->literal[1] = var->initializer->literal[1];
00146                oper->literal[2] = var->initializer->literal[2];
00147                oper->literal[3] = var->initializer->literal[3];
00148                oper->literal_size = var->initializer->literal_size;
00149                oper->type = var->initializer->type;
00150                /*
00151                printf("value[%s] = %f\n",
00152                       (char*) oper->a_id, oper->literal[0]);
00153                */
00154                return;
00155             }
00156          }
00157       }
00158    }
00159 
00160    /* first, simplify children */
00161    for (i = 0; i < oper->num_children; i++) {
00162       _slang_simplify(&oper->children[i], space, atoms);
00163    }
00164 
00165    /* examine children */
00166    n = MIN2(oper->num_children, 4);
00167    for (i = 0; i < n; i++) {
00168       isFloat[i] = (oper->children[i].type == SLANG_OPER_LITERAL_FLOAT ||
00169                    oper->children[i].type == SLANG_OPER_LITERAL_INT);
00170       isBool[i] = (oper->children[i].type == SLANG_OPER_LITERAL_BOOL);
00171    }
00172                               
00173    if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
00174       /* probably simple arithmetic */
00175       switch (oper->type) {
00176       case SLANG_OPER_ADD:
00177          for (i = 0; i < 4; i++) {
00178             oper->literal[i]
00179                = oper->children[0].literal[i] + oper->children[1].literal[i];
00180          }
00181          oper->literal_size = oper->children[0].literal_size;
00182          oper->type = literal_type(oper->children[0].type, 
00183                                    oper->children[1].type);
00184          slang_operation_destruct(oper);  /* frees unused children */
00185          return;
00186       case SLANG_OPER_SUBTRACT:
00187          for (i = 0; i < 4; i++) {
00188             oper->literal[i]
00189                = oper->children[0].literal[i] - oper->children[1].literal[i];
00190          }
00191          oper->literal_size = oper->children[0].literal_size;
00192          oper->type = literal_type(oper->children[0].type, 
00193                                    oper->children[1].type);
00194          slang_operation_destruct(oper);
00195          return;
00196       case SLANG_OPER_MULTIPLY:
00197          for (i = 0; i < 4; i++) {
00198             oper->literal[i]
00199                = oper->children[0].literal[i] * oper->children[1].literal[i];
00200          }
00201          oper->literal_size = oper->children[0].literal_size;
00202          oper->type = literal_type(oper->children[0].type, 
00203                                    oper->children[1].type);
00204          slang_operation_destruct(oper);
00205          return;
00206       case SLANG_OPER_DIVIDE:
00207          for (i = 0; i < 4; i++) {
00208             oper->literal[i]
00209                = oper->children[0].literal[i] / oper->children[1].literal[i];
00210          }
00211          oper->literal_size = oper->children[0].literal_size;
00212          oper->type = literal_type(oper->children[0].type, 
00213                                    oper->children[1].type);
00214          slang_operation_destruct(oper);
00215          return;
00216       default:
00217          ; /* nothing */
00218       }
00219    }
00220 
00221    if (oper->num_children == 1 && isFloat[0]) {
00222       switch (oper->type) {
00223       case SLANG_OPER_MINUS:
00224          for (i = 0; i < 4; i++) {
00225             oper->literal[i] = -oper->children[0].literal[i];
00226          }
00227          oper->literal_size = oper->children[0].literal_size;
00228          slang_operation_destruct(oper);
00229          oper->type = SLANG_OPER_LITERAL_FLOAT;
00230          return;
00231       case SLANG_OPER_PLUS:
00232          COPY_4V(oper->literal, oper->children[0].literal);
00233          oper->literal_size = oper->children[0].literal_size;
00234          slang_operation_destruct(oper);
00235          oper->type = SLANG_OPER_LITERAL_FLOAT;
00236          return;
00237       default:
00238          ; /* nothing */
00239       }
00240    }
00241 
00242    if (oper->num_children == 2 && isBool[0] && isBool[1]) {
00243       /* simple boolean expression */
00244       switch (oper->type) {
00245       case SLANG_OPER_LOGICALAND:
00246          for (i = 0; i < 4; i++) {
00247             const GLint a = oper->children[0].literal[i] ? 1 : 0;
00248             const GLint b = oper->children[1].literal[i] ? 1 : 0;
00249             oper->literal[i] = (GLfloat) (a && b);
00250          }
00251          oper->literal_size = oper->children[0].literal_size;
00252          slang_operation_destruct(oper);
00253          oper->type = SLANG_OPER_LITERAL_BOOL;
00254          return;
00255       case SLANG_OPER_LOGICALOR:
00256          for (i = 0; i < 4; i++) {
00257             const GLint a = oper->children[0].literal[i] ? 1 : 0;
00258             const GLint b = oper->children[1].literal[i] ? 1 : 0;
00259             oper->literal[i] = (GLfloat) (a || b);
00260          }
00261          oper->literal_size = oper->children[0].literal_size;
00262          slang_operation_destruct(oper);
00263          oper->type = SLANG_OPER_LITERAL_BOOL;
00264          return;
00265       case SLANG_OPER_LOGICALXOR:
00266          for (i = 0; i < 4; i++) {
00267             const GLint a = oper->children[0].literal[i] ? 1 : 0;
00268             const GLint b = oper->children[1].literal[i] ? 1 : 0;
00269             oper->literal[i] = (GLfloat) (a ^ b);
00270          }
00271          oper->literal_size = oper->children[0].literal_size;
00272          slang_operation_destruct(oper);
00273          oper->type = SLANG_OPER_LITERAL_BOOL;
00274          return;
00275       default:
00276          ; /* nothing */
00277       }
00278    }
00279 
00280    if (oper->num_children == 4
00281        && isFloat[0] && isFloat[1] && isFloat[2] && isFloat[3]) {
00282       /* vec4(flt, flt, flt, flt) constructor */
00283       if (oper->type == SLANG_OPER_CALL) {
00284          if (strcmp((char *) oper->a_id, "vec4") == 0) {
00285             oper->literal[0] = oper->children[0].literal[0];
00286             oper->literal[1] = oper->children[1].literal[0];
00287             oper->literal[2] = oper->children[2].literal[0];
00288             oper->literal[3] = oper->children[3].literal[0];
00289             oper->literal_size = 4;
00290             slang_operation_destruct(oper);
00291             oper->type = SLANG_OPER_LITERAL_FLOAT;
00292             return;
00293          }
00294       }
00295    }
00296 
00297    if (oper->num_children == 3 && isFloat[0] && isFloat[1] && isFloat[2]) {
00298       /* vec3(flt, flt, flt) constructor */
00299       if (oper->type == SLANG_OPER_CALL) {
00300          if (strcmp((char *) oper->a_id, "vec3") == 0) {
00301             oper->literal[0] = oper->children[0].literal[0];
00302             oper->literal[1] = oper->children[1].literal[0];
00303             oper->literal[2] = oper->children[2].literal[0];
00304             oper->literal[3] = oper->literal[2];
00305             oper->literal_size = 3;
00306             slang_operation_destruct(oper);
00307             oper->type = SLANG_OPER_LITERAL_FLOAT;
00308             return;
00309          }
00310       }
00311    }
00312 
00313    if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
00314       /* vec2(flt, flt) constructor */
00315       if (oper->type == SLANG_OPER_CALL) {
00316          if (strcmp((char *) oper->a_id, "vec2") == 0) {
00317             oper->literal[0] = oper->children[0].literal[0];
00318             oper->literal[1] = oper->children[1].literal[0];
00319             oper->literal[2] = oper->literal[1];
00320             oper->literal[3] = oper->literal[1];
00321             oper->literal_size = 2;
00322             slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
00323             oper->type = SLANG_OPER_LITERAL_FLOAT;
00324             assert(oper->num_children == 0);
00325             return;
00326          }
00327       }
00328    }
00329 
00330    if (oper->num_children == 1 && isFloat[0]) {
00331       /* vec2/3/4(flt, flt) constructor */
00332       if (oper->type == SLANG_OPER_CALL) {
00333          const char *func = (const char *) oper->a_id;
00334          if (strncmp(func, "vec", 3) == 0 && func[3] >= '2' && func[3] <= '4') {
00335             oper->literal[0] =
00336             oper->literal[1] =
00337             oper->literal[2] =
00338             oper->literal[3] = oper->children[0].literal[0];
00339             oper->literal_size = func[3] - '0';
00340             assert(oper->literal_size >= 2);
00341             assert(oper->literal_size <= 4);
00342             slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
00343             oper->type = SLANG_OPER_LITERAL_FLOAT;
00344             assert(oper->num_children == 0);
00345             return;
00346          }
00347       }
00348    }
00349 }
00350 
00351 
00352 
00362 GLboolean
00363 _slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
00364                         const slang_name_space * space,
00365                         slang_atom_pool * atoms, slang_info_log *log)
00366 {
00367    const GLboolean haveRetValue = _slang_function_has_return_value(fun);
00368    const int numParams = fun->param_count - haveRetValue;
00369    int i;
00370    int dbg = 0;
00371 
00372    if (dbg)
00373       printf("Adapt call of %d args to func %s (%d params)\n",
00374              callOper->num_children, (char*) fun->header.a_name, numParams);
00375 
00376    for (i = 0; i < numParams; i++) {
00377       slang_typeinfo argType;
00378       slang_variable *paramVar = fun->parameters->variables[i];
00379 
00380       /* Get type of arg[i] */
00381       if (!slang_typeinfo_construct(&argType))
00382          return GL_FALSE;
00383       if (!_slang_typeof_operation(&callOper->children[i], space,
00384                                     &argType, atoms, log)) {
00385          slang_typeinfo_destruct(&argType);
00386          return GL_FALSE;
00387       }
00388 
00389       /* see if arg type matches parameter type */
00390       if (!slang_type_specifier_equal(&argType.spec,
00391                                       &paramVar->type.specifier)) {
00392          /* need to adapt arg type to match param type */
00393          const char *constructorName =
00394             slang_type_specifier_type_to_string(paramVar->type.specifier.type);
00395          slang_operation *child = slang_operation_new(1);
00396 
00397          if (dbg)
00398             printf("Need to adapt types of arg %d\n", i);
00399 
00400          slang_operation_copy(child, &callOper->children[i]);
00401          child->locals->outer_scope = callOper->children[i].locals;
00402 
00403 #if 0
00404          if (_slang_sizeof_type_specifier(&argType.spec) >
00405              _slang_sizeof_type_specifier(&paramVar->type.specifier)) {
00406          }
00407 #endif
00408 
00409          callOper->children[i].type = SLANG_OPER_CALL;
00410          callOper->children[i].a_id = slang_atom_pool_atom(atoms, constructorName);
00411          callOper->children[i].num_children = 1;
00412          callOper->children[i].children = child;
00413       }
00414 
00415       slang_typeinfo_destruct(&argType);
00416    }
00417 
00418    if (dbg) {
00419       printf("===== New call to %s with cast arguments ===============\n",
00420              (char*) fun->header.a_name);
00421       slang_print_tree(callOper, 5);
00422    }
00423 
00424    return GL_TRUE;
00425 }
00426 
00427 
00436 GLboolean
00437 _slang_adapt_call(slang_operation *callOper, const slang_function *fun,
00438                   const slang_name_space * space,
00439                   slang_atom_pool * atoms, slang_info_log *log)
00440 {
00441    const GLboolean haveRetValue = _slang_function_has_return_value(fun);
00442    const int numParams = fun->param_count - haveRetValue;
00443    int i;
00444    int dbg = 0;
00445 
00446    if (dbg)
00447       printf("Adapt %d args to %d parameters for %s\n",
00448              callOper->num_children, numParams, (char *) fun->header.a_name);
00449 
00450    /* Only try adapting for constructors */
00451    if (fun->kind != SLANG_FUNC_CONSTRUCTOR)
00452       return GL_FALSE;
00453 
00454    if (callOper->num_children != numParams) {
00455       /* number of arguments doesn't match number of parameters */
00456 
00457       /* For constructor calls, we can try to unroll vector/matrix args
00458        * into individual floats/ints and try to match the function params.
00459        */
00460       for (i = 0; i < numParams; i++) {
00461          slang_typeinfo argType;
00462          GLint argSz, j;
00463 
00464          /* Get type of arg[i] */
00465          if (!slang_typeinfo_construct(&argType))
00466             return GL_FALSE;
00467          if (!_slang_typeof_operation(&callOper->children[i], space,
00468                                        &argType, atoms, log)) {
00469             slang_typeinfo_destruct(&argType);
00470             return GL_FALSE;
00471          }
00472 
00473          /*
00474            paramSz = _slang_sizeof_type_specifier(&paramVar->type.specifier);
00475            assert(paramSz == 1);
00476          */
00477          argSz = _slang_sizeof_type_specifier(&argType.spec);
00478          if (argSz > 1) {
00479             slang_operation origArg;
00480             /* break up arg[i] into components */
00481             if (dbg)
00482                printf("Break up arg %d from 1 to %d elements\n", i, argSz);
00483 
00484             slang_operation_construct(&origArg);
00485             slang_operation_copy(&origArg, &callOper->children[i]);
00486 
00487             /* insert argSz-1 new children/args */
00488             for (j = 0; j < argSz - 1; j++) {
00489                (void) slang_operation_insert(&callOper->num_children,
00490                                              &callOper->children, i);
00491             }
00492 
00493             /* replace arg[i+j] with subscript/index oper */
00494             for (j = 0; j < argSz; j++) {
00495                callOper->children[i + j].type = SLANG_OPER_SUBSCRIPT;
00496                callOper->children[i + j].locals = _slang_variable_scope_new(callOper->locals);
00497                callOper->children[i + j].num_children = 2;
00498                callOper->children[i + j].children = slang_operation_new(2);
00499                slang_operation_copy(&callOper->children[i + j].children[0],
00500                                     &origArg);
00501                callOper->children[i + j].children[1].type
00502                   = SLANG_OPER_LITERAL_INT;
00503                callOper->children[i + j].children[1].literal[0] = (GLfloat) j;
00504             }
00505          }
00506       }
00507    }
00508 
00509    if (callOper->num_children < (GLuint) numParams) {
00510       /* still not enough args for all params */
00511       return GL_FALSE;
00512    }
00513    else if (callOper->num_children > (GLuint) numParams) {
00514       /* now too many arguments */
00515       /* just truncate */
00516       callOper->num_children = (GLuint) numParams;
00517    }
00518 
00519    if (dbg) {
00520       printf("===== New call to %s with adapted arguments ===============\n",
00521              (char*) fun->header.a_name);
00522       slang_print_tree(callOper, 5);
00523    }
00524 
00525    return GL_TRUE;
00526 }

Generated on Mon May 28 2012 04:20:21 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.