mesa: glsl: handle user-defined const vars in expression simplification
authorBrian Paul <brian.paul@tungstengraphics.com>
Mon, 4 Aug 2008 17:02:22 +0000 (11:02 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Mon, 4 Aug 2008 23:14:48 +0000 (17:14 -0600)
src/mesa/shader/slang/slang_simplify.c

index c4bf017..bc65196 100644 (file)
@@ -94,6 +94,15 @@ _slang_lookup_constant(const char *name)
 }
 
 
+static slang_operation_type
+literal_type(slang_operation_type t1, slang_operation_type t2)
+{
+   if (t1 == SLANG_OPER_LITERAL_FLOAT || t2 == SLANG_OPER_LITERAL_FLOAT)
+      return SLANG_OPER_LITERAL_FLOAT;
+   else
+      return SLANG_OPER_LITERAL_INT;
+}
+
 
 /**
  * Recursively traverse an AST tree, applying simplifications wherever
@@ -114,6 +123,7 @@ _slang_simplify(slang_operation *oper,
    if (oper->type == SLANG_OPER_IDENTIFIER) {
       /* see if it's a named constant */
       GLint value = _slang_lookup_constant((char *) oper->a_id);
+      /*printf("value[%s] = %d\n", (char*) oper->a_id, value);*/
       if (value >= 0) {
          oper->literal[0] =
          oper->literal[1] =
@@ -122,6 +132,28 @@ _slang_simplify(slang_operation *oper,
          oper->type = SLANG_OPER_LITERAL_INT;
          return;
       }
+      /* look for user-defined constant */
+      {
+         slang_variable *var;
+         var = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE);
+         if (var) {
+            if (var->type.qualifier == SLANG_QUAL_CONST &&
+                var->initializer &&
+                (var->initializer->type == SLANG_OPER_LITERAL_INT ||
+                 var->initializer->type == SLANG_OPER_LITERAL_FLOAT)) {
+               oper->literal[0] = var->initializer->literal[0];
+               oper->literal[1] = var->initializer->literal[1];
+               oper->literal[2] = var->initializer->literal[2];
+               oper->literal[3] = var->initializer->literal[3];
+               oper->type = var->initializer->type;
+               /*
+               printf("value[%s] = %f\n",
+                      (char*) oper->a_id, oper->literal[0]);
+               */
+               return;
+            }
+         }
+      }
    }
 
    /* first, simplify children */
@@ -146,8 +178,9 @@ _slang_simplify(slang_operation *oper,
                = oper->children[0].literal[i] + oper->children[1].literal[i];
          }
          oper->literal_size = oper->children[0].literal_size;
-         slang_operation_destruct(oper);
-         oper->type = SLANG_OPER_LITERAL_FLOAT;
+         oper->type = literal_type(oper->children[0].type, 
+                                   oper->children[1].type);
+         slang_operation_destruct(oper);  /* frees unused children */
          return;
       case SLANG_OPER_SUBTRACT:
          for (i = 0; i < 4; i++) {
@@ -155,8 +188,9 @@ _slang_simplify(slang_operation *oper,
                = oper->children[0].literal[i] - oper->children[1].literal[i];
          }
          oper->literal_size = oper->children[0].literal_size;
+         oper->type = literal_type(oper->children[0].type, 
+                                   oper->children[1].type);
          slang_operation_destruct(oper);
-         oper->type = SLANG_OPER_LITERAL_FLOAT;
          return;
       case SLANG_OPER_MULTIPLY:
          for (i = 0; i < 4; i++) {
@@ -164,8 +198,9 @@ _slang_simplify(slang_operation *oper,
                = oper->children[0].literal[i] * oper->children[1].literal[i];
          }
          oper->literal_size = oper->children[0].literal_size;
+         oper->type = literal_type(oper->children[0].type, 
+                                   oper->children[1].type);
          slang_operation_destruct(oper);
-         oper->type = SLANG_OPER_LITERAL_FLOAT;
          return;
       case SLANG_OPER_DIVIDE:
          for (i = 0; i < 4; i++) {
@@ -173,8 +208,9 @@ _slang_simplify(slang_operation *oper,
                = oper->children[0].literal[i] / oper->children[1].literal[i];
          }
          oper->literal_size = oper->children[0].literal_size;
+         oper->type = literal_type(oper->children[0].type, 
+                                   oper->children[1].type);
          slang_operation_destruct(oper);
-         oper->type = SLANG_OPER_LITERAL_FLOAT;
          return;
       default:
          ; /* nothing */