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