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 b6cd1bae31c..3be096270d8 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 44f4a642099..e3e717a14e6 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_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) +ir_expression::constant_expression_value() { - (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; -} |