diff options
| -rw-r--r-- | src/glsl/ir.h | 22 | ||||
| -rw-r--r-- | src/glsl/ir_constant_expression.cpp | 207 | 
2 files changed, 60 insertions, 169 deletions
| diff --git a/src/glsl/ir.h b/src/glsl/ir.h index b6cd1bae31..3be096270d 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -112,10 +112,10 @@ protected:  class ir_rvalue : public ir_instruction {  public: -   class ir_constant *constant_expression_value(); -     virtual ir_rvalue *clone(struct hash_table *) const = 0; +   virtual ir_constant *constant_expression_value() = 0; +     virtual ir_rvalue * as_rvalue()     {        return this; @@ -511,6 +511,8 @@ public:     virtual ir_assignment *clone(struct hash_table *ht) const; +   virtual ir_constant *constant_expression_value(); +     virtual void accept(ir_visitor *v)     {        v->visit(this); @@ -651,6 +653,8 @@ public:     virtual ir_expression *clone(struct hash_table *ht) const; +   virtual ir_constant *constant_expression_value(); +     static unsigned int get_num_operands(ir_expression_operation);     unsigned int get_num_operands() const     { @@ -695,6 +699,8 @@ public:     virtual ir_call *clone(struct hash_table *ht) const; +   virtual ir_constant *constant_expression_value(); +     virtual ir_call *as_call()     {        return this; @@ -929,6 +935,8 @@ public:     virtual ir_texture *clone(struct hash_table *) const; +   virtual ir_constant *constant_expression_value(); +     virtual void accept(ir_visitor *v)     {        v->visit(this); @@ -1019,6 +1027,8 @@ public:     virtual ir_swizzle *clone(struct hash_table *) const; +   virtual ir_constant *constant_expression_value(); +     virtual ir_swizzle *as_swizzle()     {        return this; @@ -1083,6 +1093,8 @@ public:     virtual ir_dereference_variable *clone(struct hash_table *) const; +   virtual ir_constant *constant_expression_value(); +     virtual ir_dereference_variable *as_dereference_variable()     {        return this; @@ -1129,6 +1141,8 @@ public:     virtual ir_dereference_array *clone(struct hash_table *) const; +   virtual ir_constant *constant_expression_value(); +     virtual ir_dereference_array *as_dereference_array()     {        return this; @@ -1165,6 +1179,8 @@ public:     virtual ir_dereference_record *clone(struct hash_table *) const; +   virtual ir_constant *constant_expression_value(); +     /**      * Get the variable that is ultimately referenced by an r-value      */ @@ -1223,6 +1239,8 @@ public:     virtual ir_constant *clone(struct hash_table *) const; +   virtual ir_constant *constant_expression_value(); +     virtual ir_constant *as_constant()     {        return this; diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index 44f4a64209..e3e717a14e 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -41,97 +41,10 @@  #define min(x,y) (x) < (y) ? (x) : (y)  #define max(x,y) (x) > (y) ? (x) : (y) -/** - * Visitor class for evaluating constant expressions - */ -class ir_constant_visitor : public ir_visitor { -public: -   ir_constant_visitor() -      : value(NULL) -   { -      /* empty */ -   } - -   virtual ~ir_constant_visitor() -   { -      /* empty */ -   } - -   /** -    * \name Visit methods -    * -    * As typical for the visitor pattern, there must be one \c visit method for -    * each concrete subclass of \c ir_instruction.  Virtual base classes within -    * the hierarchy should not have \c visit methods. -    */ -   /*@{*/ -   virtual void visit(ir_variable *); -   virtual void visit(ir_function_signature *); -   virtual void visit(ir_function *); -   virtual void visit(ir_expression *); -   virtual void visit(ir_texture *); -   virtual void visit(ir_swizzle *); -   virtual void visit(ir_dereference_variable *); -   virtual void visit(ir_dereference_array *); -   virtual void visit(ir_dereference_record *); -   virtual void visit(ir_assignment *); -   virtual void visit(ir_constant *); -   virtual void visit(ir_call *); -   virtual void visit(ir_return *); -   virtual void visit(ir_discard *); -   virtual void visit(ir_if *); -   virtual void visit(ir_loop *); -   virtual void visit(ir_loop_jump *); -   /*@}*/ - -   /** -    * Value of the constant expression. -    * -    * \note -    * This field will be \c NULL if the expression is not constant valued. -    */ -   /* FINIHSME: This cannot hold values for constant arrays or structures. */ -   ir_constant *value; -}; - -  ir_constant * -ir_rvalue::constant_expression_value() +ir_expression::constant_expression_value()  { -   ir_constant_visitor visitor; - -   this->accept(& visitor); -   return visitor.value; -} - - -void -ir_constant_visitor::visit(ir_variable *ir) -{ -   (void) ir; -   value = NULL; -} - - -void -ir_constant_visitor::visit(ir_function_signature *ir) -{ -   (void) ir; -   value = NULL; -} - - -void -ir_constant_visitor::visit(ir_function *ir) -{ -   (void) ir; -   value = NULL; -} - -void -ir_constant_visitor::visit(ir_expression *ir) -{ -   value = NULL; +   ir_expression *ir = this;     ir_constant *op[2] = { NULL, NULL };     ir_constant_data data; @@ -140,7 +53,7 @@ ir_constant_visitor::visit(ir_expression *ir)     for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) {        op[operand] = ir->operands[operand]->constant_expression_value();        if (!op[operand]) -	 return; +	 return NULL;     }     if (op[1] != NULL) @@ -735,30 +648,28 @@ ir_constant_visitor::visit(ir_expression *ir)     default:        /* FINISHME: Should handle all expression types. */ -      return; +      return NULL;     }     void *ctx = talloc_parent(ir); -   this->value = new(ctx) ir_constant(ir->type, &data); +   return new(ctx) ir_constant(ir->type, &data);  } -void -ir_constant_visitor::visit(ir_texture *ir) +ir_constant * +ir_texture::constant_expression_value()  { -   // FINISHME: Do stuff with texture lookups -   (void) ir; -   value = NULL; +   /* texture lookups aren't constant expressions */ +   return NULL;  } -void -ir_constant_visitor::visit(ir_swizzle *ir) +ir_constant * +ir_swizzle::constant_expression_value()  { +   ir_swizzle *ir = this;     ir_constant *v = ir->val->constant_expression_value(); -   this->value = NULL; -     if (v != NULL) {        ir_constant_data data; @@ -777,31 +688,30 @@ ir_constant_visitor::visit(ir_swizzle *ir)        }        void *ctx = talloc_parent(ir); -      this->value = new(ctx) ir_constant(ir->type, &data); +      return new(ctx) ir_constant(ir->type, &data);     } +   return NULL;  } -void -ir_constant_visitor::visit(ir_dereference_variable *ir) +ir_constant * +ir_dereference_variable::constant_expression_value()  { -   value = NULL; - -   ir_variable *var = ir->variable_referenced(); +   ir_variable *var = this->variable_referenced();     if (var && var->constant_value) -      value = var->constant_value->clone(NULL); +      return var->constant_value->clone(NULL); +   return NULL;  } -void -ir_constant_visitor::visit(ir_dereference_array *ir) +ir_constant * +ir_dereference_array::constant_expression_value()  { +   ir_dereference_array *ir = this;     void *ctx = talloc_parent(ir);     ir_constant *array = ir->array->constant_expression_value();     ir_constant *idx = ir->array_index->constant_expression_value(); -   this->value = NULL; -     if ((array != NULL) && (idx != NULL)) {        if (array->type->is_matrix()) {  	 /* Array access of a matrix results in a vector. @@ -836,85 +746,48 @@ ir_constant_visitor::visit(ir_dereference_array *ir)  	    break;  	 } -	 this->value = new(ctx) ir_constant(column_type, &data); +	 return new(ctx) ir_constant(column_type, &data);        } else if (array->type->is_vector()) {  	 const unsigned component = idx->value.u[0]; -	 this->value = new(ctx) ir_constant(array, component); +	 return new(ctx) ir_constant(array, component);        } else {  	 /* FINISHME: Handle access of constant arrays. */        }     } +   return NULL;  } -void -ir_constant_visitor::visit(ir_dereference_record *ir) +ir_constant * +ir_dereference_record::constant_expression_value()  { +   ir_dereference_record *ir = this;     ir_constant *v = ir->record->constant_expression_value(); -   this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL; -} - - -void -ir_constant_visitor::visit(ir_assignment *ir) -{ -   (void) ir; -   value = NULL; -} - - -void -ir_constant_visitor::visit(ir_constant *ir) -{ -   value = ir; -} - - -void -ir_constant_visitor::visit(ir_call *ir) -{ -   (void) ir; -   value = NULL; -} - - -void -ir_constant_visitor::visit(ir_return *ir) -{ -   (void) ir; -   value = NULL; +   return (v != NULL) ? v->get_record_field(ir->field) : NULL;  } -void -ir_constant_visitor::visit(ir_discard *ir) +ir_constant * +ir_assignment::constant_expression_value()  { -   (void) ir; -   value = NULL; +   /* FINISHME: Handle CEs involving assignment (return RHS) */ +   return NULL;  } -void -ir_constant_visitor::visit(ir_if *ir) +ir_constant * +ir_constant::constant_expression_value()  { -   (void) ir; -   value = NULL; +   return this;  } -void -ir_constant_visitor::visit(ir_loop *ir) +ir_constant * +ir_call::constant_expression_value()  { -   (void) ir; -   value = NULL; +   /* FINISHME: Handle CEs involving builtin function calls. */ +   return NULL;  } - -void -ir_constant_visitor::visit(ir_loop_jump *ir) -{ -   (void) ir; -   value = NULL; -} | 
