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_typeinfo.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  6.5
00004  *
00005  * Copyright (C) 2005-2006  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 "shader/prog_instruction.h"
00033 #include "slang_typeinfo.h"
00034 #include "slang_compile.h"
00035 #include "slang_log.h"
00036 #include "slang_mem.h"
00037 
00038 
00045 GLboolean
00046 _slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz)
00047 {
00048    GLuint i;
00049    GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE;
00050 
00051    /* init to undefined.
00052     * We rely on undefined/nil values to distinguish between
00053     * regular swizzles and writemasks.
00054     * For example, the swizzle ".xNNN" is the writemask ".x".
00055     * That's different than the swizzle ".xxxx".
00056     */
00057    for (i = 0; i < 4; i++)
00058       swz->swizzle[i] = SWIZZLE_NIL;
00059 
00060    /* the swizzle can be at most 4-component long */
00061    swz->num_components = slang_string_length(field);
00062    if (swz->num_components > 4)
00063       return GL_FALSE;
00064 
00065    for (i = 0; i < swz->num_components; i++) {
00066       /* mark which swizzle group is used */
00067       switch (field[i]) {
00068       case 'x':
00069       case 'y':
00070       case 'z':
00071       case 'w':
00072          xyzw = GL_TRUE;
00073          break;
00074       case 'r':
00075       case 'g':
00076       case 'b':
00077       case 'a':
00078          rgba = GL_TRUE;
00079          break;
00080       case 's':
00081       case 't':
00082       case 'p':
00083       case 'q':
00084          stpq = GL_TRUE;
00085          break;
00086       default:
00087          return GL_FALSE;
00088       }
00089 
00090       /* collect swizzle component */
00091       switch (field[i]) {
00092       case 'x':
00093       case 'r':
00094       case 's':
00095          swz->swizzle[i] = 0;
00096          break;
00097       case 'y':
00098       case 'g':
00099       case 't':
00100          swz->swizzle[i] = 1;
00101          break;
00102       case 'z':
00103       case 'b':
00104       case 'p':
00105          swz->swizzle[i] = 2;
00106          break;
00107       case 'w':
00108       case 'a':
00109       case 'q':
00110          swz->swizzle[i] = 3;
00111          break;
00112       }
00113 
00114       /* check if the component is valid for given vector's row count */
00115       if (rows <= swz->swizzle[i])
00116          return GL_FALSE;
00117    }
00118 
00119    /* only one swizzle group can be used */
00120    if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
00121       return GL_FALSE;
00122 
00123    return GL_TRUE;
00124 }
00125 
00126 
00127 
00133 static GLboolean
00134 _slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows)
00135 {
00136    GLuint i, c = 0;
00137 
00138    /* the swizzle may not be longer than the vector dim */
00139    if (swz->num_components > rows)
00140       return GL_FALSE;
00141 
00142    /* the swizzle components cannot be duplicated */
00143    for (i = 0; i < swz->num_components; i++) {
00144       if ((c & (1 << swz->swizzle[i])) != 0)
00145          return GL_FALSE;
00146       c |= 1 << swz->swizzle[i];
00147    }
00148 
00149    return GL_TRUE;
00150 }
00151 
00152 
00157 static void
00158 _slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left,
00159                          const slang_swizzle * right)
00160 {
00161    GLuint i;
00162 
00163    dst->num_components = right->num_components;
00164    for (i = 0; i < right->num_components; i++)
00165       dst->swizzle[i] = left->swizzle[right->swizzle[i]];
00166 }
00167 
00168 
00169 typedef struct
00170 {
00171    const char *name;
00172    slang_type_specifier_type type;
00173 } type_specifier_type_name;
00174 
00175 static const type_specifier_type_name type_specifier_type_names[] = {
00176    {"void", SLANG_SPEC_VOID},
00177    {"bool", SLANG_SPEC_BOOL},
00178    {"bvec2", SLANG_SPEC_BVEC2},
00179    {"bvec3", SLANG_SPEC_BVEC3},
00180    {"bvec4", SLANG_SPEC_BVEC4},
00181    {"int", SLANG_SPEC_INT},
00182    {"ivec2", SLANG_SPEC_IVEC2},
00183    {"ivec3", SLANG_SPEC_IVEC3},
00184    {"ivec4", SLANG_SPEC_IVEC4},
00185    {"float", SLANG_SPEC_FLOAT},
00186    {"vec2", SLANG_SPEC_VEC2},
00187    {"vec3", SLANG_SPEC_VEC3},
00188    {"vec4", SLANG_SPEC_VEC4},
00189    {"mat2", SLANG_SPEC_MAT2},
00190    {"mat3", SLANG_SPEC_MAT3},
00191    {"mat4", SLANG_SPEC_MAT4},
00192    {"mat2x3", SLANG_SPEC_MAT23},
00193    {"mat3x2", SLANG_SPEC_MAT32},
00194    {"mat2x4", SLANG_SPEC_MAT24},
00195    {"mat4x2", SLANG_SPEC_MAT42},
00196    {"mat3x4", SLANG_SPEC_MAT34},
00197    {"mat4x3", SLANG_SPEC_MAT43},
00198    {"sampler1D", SLANG_SPEC_SAMPLER1D},
00199    {"sampler2D", SLANG_SPEC_SAMPLER2D},
00200    {"sampler3D", SLANG_SPEC_SAMPLER3D},
00201    {"samplerCube", SLANG_SPEC_SAMPLERCUBE},
00202    {"sampler1DShadow", SLANG_SPEC_SAMPLER1DSHADOW},
00203    {"sampler2DShadow", SLANG_SPEC_SAMPLER2DSHADOW},
00204    {"sampler2DRect", SLANG_SPEC_SAMPLER2DRECT},
00205    {"sampler2DRectShadow", SLANG_SPEC_SAMPLER2DRECTSHADOW},
00206    {NULL, SLANG_SPEC_VOID}
00207 };
00208 
00209 slang_type_specifier_type
00210 slang_type_specifier_type_from_string(const char *name)
00211 {
00212    const type_specifier_type_name *p = type_specifier_type_names;
00213    while (p->name != NULL) {
00214       if (slang_string_compare(p->name, name) == 0)
00215          break;
00216       p++;
00217    }
00218    return p->type;
00219 }
00220 
00221 const char *
00222 slang_type_specifier_type_to_string(slang_type_specifier_type type)
00223 {
00224    const type_specifier_type_name *p = type_specifier_type_names;
00225    while (p->name != NULL) {
00226       if (p->type == type)
00227          break;
00228       p++;
00229    }
00230    return p->name;
00231 }
00232 
00233 /* slang_fully_specified_type */
00234 
00235 int
00236 slang_fully_specified_type_construct(slang_fully_specified_type * type)
00237 {
00238    type->qualifier = SLANG_QUAL_NONE;
00239    slang_type_specifier_ctr(&type->specifier);
00240    return 1;
00241 }
00242 
00243 void
00244 slang_fully_specified_type_destruct(slang_fully_specified_type * type)
00245 {
00246    slang_type_specifier_dtr(&type->specifier);
00247 }
00248 
00249 int
00250 slang_fully_specified_type_copy(slang_fully_specified_type * x,
00251                                 const slang_fully_specified_type * y)
00252 {
00253    slang_fully_specified_type z;
00254 
00255    if (!slang_fully_specified_type_construct(&z))
00256       return 0;
00257    z.qualifier = y->qualifier;
00258    z.precision = y->precision;
00259    z.variant = y->variant;
00260    z.centroid = y->centroid;
00261    z.array_len = y->array_len;
00262    if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) {
00263       slang_fully_specified_type_destruct(&z);
00264       return 0;
00265    }
00266    slang_fully_specified_type_destruct(x);
00267    *x = z;
00268    return 1;
00269 }
00270 
00271 
00272 
00273 GLvoid
00274 slang_type_specifier_ctr(slang_type_specifier * self)
00275 {
00276    self->type = SLANG_SPEC_VOID;
00277    self->_struct = NULL;
00278    self->_array = NULL;
00279 }
00280 
00281 GLvoid
00282 slang_type_specifier_dtr(slang_type_specifier * self)
00283 {
00284    if (self->_struct != NULL) {
00285       slang_struct_destruct(self->_struct);
00286       _slang_free(self->_struct);
00287    }
00288    if (self->_array != NULL) {
00289       slang_type_specifier_dtr(self->_array);
00290       _slang_free(self->_array);
00291    }
00292 }
00293 
00294 slang_type_specifier *
00295 slang_type_specifier_new(slang_type_specifier_type type,
00296                          struct slang_struct_ *_struct,
00297                          struct slang_type_specifier_ *_array)
00298 {
00299    slang_type_specifier *spec =
00300       (slang_type_specifier *) _slang_alloc(sizeof(slang_type_specifier));
00301    if (spec) {
00302       spec->type = type;
00303       spec->_struct = _struct;
00304       spec->_array = _array;
00305    }
00306    return spec;
00307 }
00308 
00309 GLboolean
00310 slang_type_specifier_copy(slang_type_specifier * x,
00311                           const slang_type_specifier * y)
00312 {
00313    slang_type_specifier z;
00314 
00315    slang_type_specifier_ctr(&z);
00316    z.type = y->type;
00317    if (z.type == SLANG_SPEC_STRUCT) {
00318       z._struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
00319       if (z._struct == NULL) {
00320          slang_type_specifier_dtr(&z);
00321          return GL_FALSE;
00322       }
00323       if (!slang_struct_construct(z._struct)) {
00324          _slang_free(z._struct);
00325          slang_type_specifier_dtr(&z);
00326          return GL_FALSE;
00327       }
00328       if (!slang_struct_copy(z._struct, y->_struct)) {
00329          slang_type_specifier_dtr(&z);
00330          return GL_FALSE;
00331       }
00332    }
00333    else if (z.type == SLANG_SPEC_ARRAY) {
00334       z._array = (slang_type_specifier *)
00335          _slang_alloc(sizeof(slang_type_specifier));
00336       if (z._array == NULL) {
00337          slang_type_specifier_dtr(&z);
00338          return GL_FALSE;
00339       }
00340       slang_type_specifier_ctr(z._array);
00341       if (!slang_type_specifier_copy(z._array, y->_array)) {
00342          slang_type_specifier_dtr(&z);
00343          return GL_FALSE;
00344       }
00345    }
00346    slang_type_specifier_dtr(x);
00347    *x = z;
00348    return GL_TRUE;
00349 }
00350 
00351 
00355 GLboolean
00356 slang_type_specifier_equal(const slang_type_specifier * x,
00357                            const slang_type_specifier * y)
00358 {
00359    if (x->type != y->type)
00360       return GL_FALSE;
00361    if (x->type == SLANG_SPEC_STRUCT)
00362       return slang_struct_equal(x->_struct, y->_struct);
00363    if (x->type == SLANG_SPEC_ARRAY)
00364       return slang_type_specifier_equal(x->_array, y->_array);
00365    return GL_TRUE;
00366 }
00367 
00368 
00372 GLboolean
00373 slang_type_specifier_compatible(const slang_type_specifier * x,
00374                                 const slang_type_specifier * y)
00375 {
00376    /* special case: float == int */
00377    if (x->type == SLANG_SPEC_INT && y->type == SLANG_SPEC_FLOAT) {
00378       return GL_TRUE;
00379    }
00380    /* XXX may need to add bool/int compatibility, etc */
00381 
00382    if (x->type != y->type)
00383       return GL_FALSE;
00384    if (x->type == SLANG_SPEC_STRUCT)
00385       return slang_struct_equal(x->_struct, y->_struct);
00386    if (x->type == SLANG_SPEC_ARRAY)
00387       return slang_type_specifier_compatible(x->_array, y->_array);
00388    return GL_TRUE;
00389 }
00390 
00391 
00392 GLboolean
00393 slang_typeinfo_construct(slang_typeinfo * ti)
00394 {
00395    _mesa_bzero(ti, sizeof(*ti));
00396    slang_type_specifier_ctr(&ti->spec);
00397    ti->array_len = 0;
00398    return GL_TRUE;
00399 }
00400 
00401 GLvoid
00402 slang_typeinfo_destruct(slang_typeinfo * ti)
00403 {
00404    slang_type_specifier_dtr(&ti->spec);
00405 }
00406 
00407 
00408 
00419 static GLboolean
00420 _slang_typeof_function(slang_atom a_name,
00421                        slang_operation * params, GLuint num_params,
00422                        const slang_name_space * space,
00423                        slang_type_specifier * spec,
00424                        slang_function **funFound,
00425                        slang_atom_pool *atoms, slang_info_log *log)
00426 {
00427    GLboolean error;
00428 
00429    *funFound = _slang_function_locate(space->funcs, a_name, params,
00430                                       num_params, space, atoms, log, &error);
00431    if (error)
00432       return GL_FALSE;
00433 
00434    if (!*funFound)
00435       return GL_TRUE;  /* yes, not false */
00436 
00437    return slang_type_specifier_copy(spec, &(*funFound)->header.type.specifier);
00438 }
00439 
00440 
00451 static GLboolean
00452 typeof_math_call(const char *name, slang_operation *call,
00453                  const slang_name_space * space,
00454                  slang_type_specifier * spec,
00455                  slang_atom_pool * atoms,
00456                  slang_info_log *log)
00457 {
00458    if (call->fun) {
00459       /* we've previously resolved this function call */
00460       slang_type_specifier_copy(spec, &call->fun->header.type.specifier);
00461       return GL_TRUE;
00462    }
00463    else {
00464       slang_atom atom;
00465       slang_function *fun;
00466 
00467       /* number of params: */
00468       assert(call->num_children == 1 || call->num_children == 2);
00469 
00470       atom = slang_atom_pool_atom(atoms, name);
00471       if (!_slang_typeof_function(atom, call->children, call->num_children,
00472                                   space, spec, &fun, atoms, log))
00473          return GL_FALSE;
00474 
00475       if (fun) {
00476          /* Save pointer to save time in future */
00477          call->fun = fun;
00478          return GL_TRUE;
00479       }
00480       return GL_FALSE;
00481    }
00482 }
00483 
00484 
00493 GLboolean
00494 _slang_typeof_operation(slang_operation * op,
00495                          const slang_name_space * space,
00496                          slang_typeinfo * ti,
00497                          slang_atom_pool * atoms,
00498                          slang_info_log *log)
00499 {
00500    ti->can_be_referenced = GL_FALSE;
00501    ti->is_swizzled = GL_FALSE;
00502 
00503    switch (op->type) {
00504    case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
00505    case SLANG_OPER_BLOCK_NEW_SCOPE:
00506    case SLANG_OPER_ASM:
00507    case SLANG_OPER_BREAK:
00508    case SLANG_OPER_CONTINUE:
00509    case SLANG_OPER_DISCARD:
00510    case SLANG_OPER_RETURN:
00511    case SLANG_OPER_IF:
00512    case SLANG_OPER_WHILE:
00513    case SLANG_OPER_DO:
00514    case SLANG_OPER_FOR:
00515    case SLANG_OPER_VOID:
00516       ti->spec.type = SLANG_SPEC_VOID;
00517       break;
00518    case SLANG_OPER_EXPRESSION:
00519    case SLANG_OPER_ASSIGN:
00520    case SLANG_OPER_ADDASSIGN:
00521    case SLANG_OPER_SUBASSIGN:
00522    case SLANG_OPER_MULASSIGN:
00523    case SLANG_OPER_DIVASSIGN:
00524    case SLANG_OPER_PREINCREMENT:
00525    case SLANG_OPER_PREDECREMENT:
00526       if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
00527          return GL_FALSE;
00528       break;
00529    case SLANG_OPER_LITERAL_BOOL:
00530       if (op->literal_size == 1)
00531          ti->spec.type = SLANG_SPEC_BOOL;
00532       else if (op->literal_size == 2)
00533          ti->spec.type = SLANG_SPEC_BVEC2;
00534       else if (op->literal_size == 3)
00535          ti->spec.type = SLANG_SPEC_BVEC3;
00536       else if (op->literal_size == 4)
00537          ti->spec.type = SLANG_SPEC_BVEC4;
00538       else {
00539          _mesa_problem(NULL,
00540                "Unexpected bool literal_size %d in _slang_typeof_operation()",
00541                op->literal_size);
00542          ti->spec.type = SLANG_SPEC_BOOL;
00543       }
00544       break;
00545    case SLANG_OPER_LOGICALOR:
00546    case SLANG_OPER_LOGICALXOR:
00547    case SLANG_OPER_LOGICALAND:
00548    case SLANG_OPER_EQUAL:
00549    case SLANG_OPER_NOTEQUAL:
00550    case SLANG_OPER_LESS:
00551    case SLANG_OPER_GREATER:
00552    case SLANG_OPER_LESSEQUAL:
00553    case SLANG_OPER_GREATEREQUAL:
00554    case SLANG_OPER_NOT:
00555       ti->spec.type = SLANG_SPEC_BOOL;
00556       break;
00557    case SLANG_OPER_LITERAL_INT:
00558       if (op->literal_size == 1)
00559          ti->spec.type = SLANG_SPEC_INT;
00560       else if (op->literal_size == 2)
00561          ti->spec.type = SLANG_SPEC_IVEC2;
00562       else if (op->literal_size == 3)
00563          ti->spec.type = SLANG_SPEC_IVEC3;
00564       else if (op->literal_size == 4)
00565          ti->spec.type = SLANG_SPEC_IVEC4;
00566       else {
00567          _mesa_problem(NULL,
00568                "Unexpected int literal_size %d in _slang_typeof_operation()",
00569                op->literal_size);
00570          ti->spec.type = SLANG_SPEC_INT;
00571       }
00572       break;
00573    case SLANG_OPER_LITERAL_FLOAT:
00574       if (op->literal_size == 1)
00575          ti->spec.type = SLANG_SPEC_FLOAT;
00576       else if (op->literal_size == 2)
00577          ti->spec.type = SLANG_SPEC_VEC2;
00578       else if (op->literal_size == 3)
00579          ti->spec.type = SLANG_SPEC_VEC3;
00580       else if (op->literal_size == 4)
00581          ti->spec.type = SLANG_SPEC_VEC4;
00582       else {
00583          _mesa_problem(NULL,
00584                "Unexpected float literal_size %d in _slang_typeof_operation()",
00585                op->literal_size);
00586          ti->spec.type = SLANG_SPEC_FLOAT;
00587       }
00588       break;
00589    case SLANG_OPER_IDENTIFIER:
00590    case SLANG_OPER_VARIABLE_DECL:
00591       {
00592          slang_variable *var;
00593          var = _slang_variable_locate(op->locals, op->a_id, GL_TRUE);
00594          if (!var) {
00595             slang_info_log_error(log, "undefined variable '%s'",
00596                                  (char *) op->a_id);
00597             return GL_FALSE;
00598          }
00599          if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) {
00600             slang_info_log_memory(log);
00601             return GL_FALSE;
00602          }
00603          ti->can_be_referenced = GL_TRUE;
00604          if (var->type.specifier.type == SLANG_SPEC_ARRAY &&
00605              var->type.array_len >= 1) {
00606             /* the datatype is an array, ex: float[3] x; */
00607             ti->array_len = var->type.array_len;
00608          }
00609          else {
00610             /* the variable is an array, ex: float x[3]; */
00611             ti->array_len = var->array_len;
00612          }
00613       }
00614       break;
00615    case SLANG_OPER_SEQUENCE:
00616       /* TODO: check [0] and [1] if they match */
00617       if (!_slang_typeof_operation(&op->children[1], space, ti, atoms, log)) {
00618          return GL_FALSE;
00619       }
00620       ti->can_be_referenced = GL_FALSE;
00621       ti->is_swizzled = GL_FALSE;
00622       break;
00623       /*case SLANG_OPER_MODASSIGN: */
00624       /*case SLANG_OPER_LSHASSIGN: */
00625       /*case SLANG_OPER_RSHASSIGN: */
00626       /*case SLANG_OPER_ORASSIGN: */
00627       /*case SLANG_OPER_XORASSIGN: */
00628       /*case SLANG_OPER_ANDASSIGN: */
00629    case SLANG_OPER_SELECT:
00630       /* TODO: check [1] and [2] if they match */
00631       if (!_slang_typeof_operation(&op->children[1], space, ti, atoms, log)) {
00632          return GL_FALSE;
00633       }
00634       ti->can_be_referenced = GL_FALSE;
00635       ti->is_swizzled = GL_FALSE;
00636       break;
00637       /*case SLANG_OPER_BITOR: */
00638       /*case SLANG_OPER_BITXOR: */
00639       /*case SLANG_OPER_BITAND: */
00640       /*case SLANG_OPER_LSHIFT: */
00641       /*case SLANG_OPER_RSHIFT: */
00642    case SLANG_OPER_ADD:
00643       assert(op->num_children == 2);
00644       if (!typeof_math_call("+", op, space, &ti->spec, atoms, log))
00645          return GL_FALSE;
00646       break;
00647    case SLANG_OPER_SUBTRACT:
00648       assert(op->num_children == 2);
00649       if (!typeof_math_call("-", op, space, &ti->spec, atoms, log))
00650          return GL_FALSE;
00651       break;
00652    case SLANG_OPER_MULTIPLY:
00653       assert(op->num_children == 2);
00654       if (!typeof_math_call("*", op, space, &ti->spec, atoms, log))
00655          return GL_FALSE;
00656       break;
00657    case SLANG_OPER_DIVIDE:
00658       assert(op->num_children == 2);
00659       if (!typeof_math_call("/", op, space, &ti->spec, atoms, log))
00660          return GL_FALSE;
00661       break;
00662    /*case SLANG_OPER_MODULUS: */
00663    case SLANG_OPER_PLUS:
00664       if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
00665          return GL_FALSE;
00666       ti->can_be_referenced = GL_FALSE;
00667       ti->is_swizzled = GL_FALSE;
00668       break;
00669    case SLANG_OPER_MINUS:
00670       assert(op->num_children == 1);
00671       if (!typeof_math_call("-", op, space, &ti->spec, atoms, log))
00672          return GL_FALSE;
00673       break;
00674       /*case SLANG_OPER_COMPLEMENT: */
00675    case SLANG_OPER_SUBSCRIPT:
00676       {
00677          slang_typeinfo _ti;
00678 
00679          if (!slang_typeinfo_construct(&_ti))
00680             return GL_FALSE;
00681          if (!_slang_typeof_operation(op->children, space, &_ti, atoms, log)) {
00682             slang_typeinfo_destruct(&_ti);
00683             return GL_FALSE;
00684          }
00685          ti->can_be_referenced = _ti.can_be_referenced;
00686          if (_ti.spec.type == SLANG_SPEC_ARRAY) {
00687             if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) {
00688                slang_typeinfo_destruct(&_ti);
00689                return GL_FALSE;
00690             }
00691          }
00692          else {
00693             if (!_slang_type_is_vector(_ti.spec.type)
00694                 && !_slang_type_is_matrix(_ti.spec.type)) {
00695                slang_typeinfo_destruct(&_ti);
00696                slang_info_log_error(log, "cannot index a non-array type");
00697                return GL_FALSE;
00698             }
00699             ti->spec.type = _slang_type_base(_ti.spec.type);
00700          }
00701          slang_typeinfo_destruct(&_ti);
00702       }
00703       break;
00704    case SLANG_OPER_CALL:
00705       if (op->array_constructor) {
00706          /* build array typeinfo */
00707          ti->spec.type = SLANG_SPEC_ARRAY;
00708          ti->spec._array = (slang_type_specifier *)
00709             _slang_alloc(sizeof(slang_type_specifier));
00710          slang_type_specifier_ctr(ti->spec._array);
00711 
00712          ti->spec._array->type =
00713             slang_type_specifier_type_from_string((char *) op->a_id);
00714          ti->array_len = op->num_children;
00715       }
00716       else if (op->fun) {
00717          /* we've resolved this call before */
00718          slang_type_specifier_copy(&ti->spec, &op->fun->header.type.specifier);
00719       }
00720       else {
00721          slang_function *fun;
00722          if (!_slang_typeof_function(op->a_id, op->children, op->num_children,
00723                                      space, &ti->spec, &fun, atoms, log))
00724             return GL_FALSE;
00725          if (fun) {
00726             /* save result for future use */
00727             op->fun = fun;
00728          }
00729          else {
00730             slang_struct *s =
00731                slang_struct_scope_find(space->structs, op->a_id, GL_TRUE);
00732             if (s) {
00733                /* struct initializer */
00734                ti->spec.type = SLANG_SPEC_STRUCT;
00735                ti->spec._struct =
00736                   (slang_struct *) _slang_alloc(sizeof(slang_struct));
00737                if (ti->spec._struct == NULL)
00738                   return GL_FALSE;
00739                if (!slang_struct_construct(ti->spec._struct)) {
00740                   _slang_free(ti->spec._struct);
00741                   ti->spec._struct = NULL;
00742                   return GL_FALSE;
00743                }
00744                if (!slang_struct_copy(ti->spec._struct, s))
00745                   return GL_FALSE;
00746             }
00747             else {
00748                /* float, int, vec4, mat3, etc. constructor? */
00749                const char *name;
00750                slang_type_specifier_type type;
00751 
00752                name = slang_atom_pool_id(atoms, op->a_id);
00753                type = slang_type_specifier_type_from_string(name);
00754                if (type == SLANG_SPEC_VOID) {
00755                   slang_info_log_error(log, "undefined function '%s'", name);
00756                   return GL_FALSE;
00757                }
00758                ti->spec.type = type;
00759             }
00760          }
00761       }
00762       break;
00763    case SLANG_OPER_METHOD:
00764       /* at this time, GLSL 1.20 only has one method: array.length()
00765        * which returns an integer.
00766        */
00767       ti->spec.type = SLANG_SPEC_INT;
00768       break;
00769    case SLANG_OPER_FIELD:
00770       {
00771          slang_typeinfo _ti;
00772 
00773          if (!slang_typeinfo_construct(&_ti))
00774             return GL_FALSE;
00775          if (!_slang_typeof_operation(op->children, space, &_ti, atoms, log)) {
00776             slang_typeinfo_destruct(&_ti);
00777             return GL_FALSE;
00778          }
00779          if (_ti.spec.type == SLANG_SPEC_STRUCT) {
00780             slang_variable *field;
00781 
00782             field = _slang_variable_locate(_ti.spec._struct->fields, op->a_id,
00783                                            GL_FALSE);
00784             if (field == NULL) {
00785                slang_typeinfo_destruct(&_ti);
00786                return GL_FALSE;
00787             }
00788             if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) {
00789                slang_typeinfo_destruct(&_ti);
00790                return GL_FALSE;
00791             }
00792             ti->can_be_referenced = _ti.can_be_referenced;
00793          }
00794          else {
00795             GLuint rows;
00796             const char *swizzle;
00797             slang_type_specifier_type base;
00798 
00799             /* determine the swizzle of the field expression */
00800             if (!_slang_type_is_vector(_ti.spec.type)) {
00801                slang_typeinfo_destruct(&_ti);
00802                slang_info_log_error(log, "Can't swizzle scalar expression");
00803                return GL_FALSE;
00804             }
00805             rows = _slang_type_dim(_ti.spec.type);
00806             swizzle = slang_atom_pool_id(atoms, op->a_id);
00807             if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) {
00808                slang_typeinfo_destruct(&_ti);
00809                slang_info_log_error(log, "bad swizzle '%s'", swizzle);
00810                return GL_FALSE;
00811             }
00812             ti->is_swizzled = GL_TRUE;
00813             ti->can_be_referenced = _ti.can_be_referenced
00814                && _slang_is_swizzle_mask(&ti->swz, rows);
00815             if (_ti.is_swizzled) {
00816                slang_swizzle swz;
00817 
00818                /* swizzle the swizzle */
00819                _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz);
00820                ti->swz = swz;
00821             }
00822             base = _slang_type_base(_ti.spec.type);
00823             switch (ti->swz.num_components) {
00824             case 1:
00825                ti->spec.type = base;
00826                break;
00827             case 2:
00828                switch (base) {
00829                case SLANG_SPEC_FLOAT:
00830                   ti->spec.type = SLANG_SPEC_VEC2;
00831                   break;
00832                case SLANG_SPEC_INT:
00833                   ti->spec.type = SLANG_SPEC_IVEC2;
00834                   break;
00835                case SLANG_SPEC_BOOL:
00836                   ti->spec.type = SLANG_SPEC_BVEC2;
00837                   break;
00838                default:
00839                   break;
00840                }
00841                break;
00842             case 3:
00843                switch (base) {
00844                case SLANG_SPEC_FLOAT:
00845                   ti->spec.type = SLANG_SPEC_VEC3;
00846                   break;
00847                case SLANG_SPEC_INT:
00848                   ti->spec.type = SLANG_SPEC_IVEC3;
00849                   break;
00850                case SLANG_SPEC_BOOL:
00851                   ti->spec.type = SLANG_SPEC_BVEC3;
00852                   break;
00853                default:
00854                   break;
00855                }
00856                break;
00857             case 4:
00858                switch (base) {
00859                case SLANG_SPEC_FLOAT:
00860                   ti->spec.type = SLANG_SPEC_VEC4;
00861                   break;
00862                case SLANG_SPEC_INT:
00863                   ti->spec.type = SLANG_SPEC_IVEC4;
00864                   break;
00865                case SLANG_SPEC_BOOL:
00866                   ti->spec.type = SLANG_SPEC_BVEC4;
00867                   break;
00868                default:
00869                   break;
00870                }
00871                break;
00872             default:
00873                break;
00874             }
00875          }
00876          slang_typeinfo_destruct(&_ti);
00877       }
00878       break;
00879    case SLANG_OPER_POSTINCREMENT:
00880    case SLANG_OPER_POSTDECREMENT:
00881       if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
00882          return GL_FALSE;
00883       ti->can_be_referenced = GL_FALSE;
00884       ti->is_swizzled = GL_FALSE;
00885       break;
00886    default:
00887       return GL_FALSE;
00888    }
00889 
00890    return GL_TRUE;
00891 }
00892 
00893 
00898 GLboolean
00899 _slang_type_is_matrix(slang_type_specifier_type ty)
00900 {
00901    switch (ty) {
00902    case SLANG_SPEC_MAT2:
00903    case SLANG_SPEC_MAT3:
00904    case SLANG_SPEC_MAT4:
00905    case SLANG_SPEC_MAT23:
00906    case SLANG_SPEC_MAT32:
00907    case SLANG_SPEC_MAT24:
00908    case SLANG_SPEC_MAT42:
00909    case SLANG_SPEC_MAT34:
00910    case SLANG_SPEC_MAT43:
00911       return GL_TRUE;
00912    default:
00913       return GL_FALSE;
00914    }
00915 }
00916 
00917 
00922 GLboolean
00923 _slang_type_is_vector(slang_type_specifier_type ty)
00924 {
00925    switch (ty) {
00926    case SLANG_SPEC_VEC2:
00927    case SLANG_SPEC_VEC3:
00928    case SLANG_SPEC_VEC4:
00929    case SLANG_SPEC_IVEC2:
00930    case SLANG_SPEC_IVEC3:
00931    case SLANG_SPEC_IVEC4:
00932    case SLANG_SPEC_BVEC2:
00933    case SLANG_SPEC_BVEC3:
00934    case SLANG_SPEC_BVEC4:
00935       return GL_TRUE;
00936    default:
00937       return GL_FALSE;
00938    }
00939 }
00940 
00941 
00946 GLboolean
00947 _slang_type_is_float_vec_mat(slang_type_specifier_type ty)
00948 {
00949    switch (ty) {
00950    case SLANG_SPEC_FLOAT:
00951    case SLANG_SPEC_VEC2:
00952    case SLANG_SPEC_VEC3:
00953    case SLANG_SPEC_VEC4:
00954    case SLANG_SPEC_MAT2:
00955    case SLANG_SPEC_MAT3:
00956    case SLANG_SPEC_MAT4:
00957    case SLANG_SPEC_MAT23:
00958    case SLANG_SPEC_MAT32:
00959    case SLANG_SPEC_MAT24:
00960    case SLANG_SPEC_MAT42:
00961    case SLANG_SPEC_MAT34:
00962    case SLANG_SPEC_MAT43:
00963       return GL_TRUE;
00964    default:
00965       return GL_FALSE;
00966    }
00967 }
00968 
00969 
00974 slang_type_specifier_type
00975 _slang_type_base(slang_type_specifier_type ty)
00976 {
00977    switch (ty) {
00978    case SLANG_SPEC_FLOAT:
00979    case SLANG_SPEC_VEC2:
00980    case SLANG_SPEC_VEC3:
00981    case SLANG_SPEC_VEC4:
00982       return SLANG_SPEC_FLOAT;
00983    case SLANG_SPEC_INT:
00984    case SLANG_SPEC_IVEC2:
00985    case SLANG_SPEC_IVEC3:
00986    case SLANG_SPEC_IVEC4:
00987       return SLANG_SPEC_INT;
00988    case SLANG_SPEC_BOOL:
00989    case SLANG_SPEC_BVEC2:
00990    case SLANG_SPEC_BVEC3:
00991    case SLANG_SPEC_BVEC4:
00992       return SLANG_SPEC_BOOL;
00993    case SLANG_SPEC_MAT2:
00994       return SLANG_SPEC_VEC2;
00995    case SLANG_SPEC_MAT3:
00996       return SLANG_SPEC_VEC3;
00997    case SLANG_SPEC_MAT4:
00998       return SLANG_SPEC_VEC4;
00999    case SLANG_SPEC_MAT23:
01000       return SLANG_SPEC_VEC3;
01001    case SLANG_SPEC_MAT32:
01002       return SLANG_SPEC_VEC2;
01003    case SLANG_SPEC_MAT24:
01004       return SLANG_SPEC_VEC4;
01005    case SLANG_SPEC_MAT42:
01006       return SLANG_SPEC_VEC2;
01007    case SLANG_SPEC_MAT34:
01008       return SLANG_SPEC_VEC4;
01009    case SLANG_SPEC_MAT43:
01010       return SLANG_SPEC_VEC3;
01011    default:
01012       return SLANG_SPEC_VOID;
01013    }
01014 }
01015 
01016 
01021 GLuint
01022 _slang_type_dim(slang_type_specifier_type ty)
01023 {
01024    switch (ty) {
01025    case SLANG_SPEC_FLOAT:
01026    case SLANG_SPEC_INT:
01027    case SLANG_SPEC_BOOL:
01028       return 1;
01029    case SLANG_SPEC_VEC2:
01030    case SLANG_SPEC_IVEC2:
01031    case SLANG_SPEC_BVEC2:
01032    case SLANG_SPEC_MAT2:
01033       return 2;
01034    case SLANG_SPEC_VEC3:
01035    case SLANG_SPEC_IVEC3:
01036    case SLANG_SPEC_BVEC3:
01037    case SLANG_SPEC_MAT3:
01038       return 3;
01039    case SLANG_SPEC_VEC4:
01040    case SLANG_SPEC_IVEC4:
01041    case SLANG_SPEC_BVEC4:
01042    case SLANG_SPEC_MAT4:
01043       return 4;
01044 
01045    case SLANG_SPEC_MAT23:
01046       return 2;
01047    case SLANG_SPEC_MAT32:
01048       return 3;
01049    case SLANG_SPEC_MAT24:
01050       return 2;
01051    case SLANG_SPEC_MAT42:
01052       return 4;
01053    case SLANG_SPEC_MAT34:
01054       return 3;
01055    case SLANG_SPEC_MAT43:
01056       return 4;
01057 
01058    default:
01059       return 0;
01060    }
01061 }
01062 
01063 
01067 GLenum
01068 _slang_gltype_from_specifier(const slang_type_specifier *type)
01069 {
01070    switch (type->type) {
01071    case SLANG_SPEC_BOOL:
01072       return GL_BOOL;
01073    case SLANG_SPEC_BVEC2:
01074       return GL_BOOL_VEC2;
01075    case SLANG_SPEC_BVEC3:
01076       return GL_BOOL_VEC3;
01077    case SLANG_SPEC_BVEC4:
01078       return GL_BOOL_VEC4;
01079    case SLANG_SPEC_INT:
01080       return GL_INT;
01081    case SLANG_SPEC_IVEC2:
01082       return GL_INT_VEC2;
01083    case SLANG_SPEC_IVEC3:
01084       return GL_INT_VEC3;
01085    case SLANG_SPEC_IVEC4:
01086       return GL_INT_VEC4;
01087    case SLANG_SPEC_FLOAT:
01088       return GL_FLOAT;
01089    case SLANG_SPEC_VEC2:
01090       return GL_FLOAT_VEC2;
01091    case SLANG_SPEC_VEC3:
01092       return GL_FLOAT_VEC3;
01093    case SLANG_SPEC_VEC4:
01094       return GL_FLOAT_VEC4;
01095    case SLANG_SPEC_MAT2:
01096       return GL_FLOAT_MAT2;
01097    case SLANG_SPEC_MAT3:
01098       return GL_FLOAT_MAT3;
01099    case SLANG_SPEC_MAT4:
01100       return GL_FLOAT_MAT4;
01101    case SLANG_SPEC_MAT23:
01102       return GL_FLOAT_MAT2x3;
01103    case SLANG_SPEC_MAT32:
01104       return GL_FLOAT_MAT3x2;
01105    case SLANG_SPEC_MAT24:
01106       return GL_FLOAT_MAT2x4;
01107    case SLANG_SPEC_MAT42:
01108       return GL_FLOAT_MAT4x2;
01109    case SLANG_SPEC_MAT34:
01110       return GL_FLOAT_MAT3x4;
01111    case SLANG_SPEC_MAT43:
01112       return GL_FLOAT_MAT4x3;
01113    case SLANG_SPEC_SAMPLER1D:
01114       return GL_SAMPLER_1D;
01115    case SLANG_SPEC_SAMPLER2D:
01116       return GL_SAMPLER_2D;
01117    case SLANG_SPEC_SAMPLER3D:
01118       return GL_SAMPLER_3D;
01119    case SLANG_SPEC_SAMPLERCUBE:
01120       return GL_SAMPLER_CUBE;
01121    case SLANG_SPEC_SAMPLER1DSHADOW:
01122       return GL_SAMPLER_1D_SHADOW;
01123    case SLANG_SPEC_SAMPLER2DSHADOW:
01124       return GL_SAMPLER_2D_SHADOW;
01125    case SLANG_SPEC_SAMPLER2DRECT:
01126       return GL_SAMPLER_2D_RECT_ARB;
01127    case SLANG_SPEC_SAMPLER2DRECTSHADOW:
01128       return GL_SAMPLER_2D_RECT_SHADOW_ARB;
01129    case SLANG_SPEC_ARRAY:
01130       return _slang_gltype_from_specifier(type->_array);
01131    case SLANG_SPEC_STRUCT:
01132       /* fall-through */
01133    default:
01134       return GL_NONE;
01135    }
01136 }
01137 

Generated on Fri May 25 2012 04:18:50 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.