Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenslang_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
1.7.6.1
|