diff options
-rw-r--r-- | src/glsl/ir.h | 27 | ||||
-rw-r--r-- | src/glsl/ir_clone.cpp | 12 | ||||
-rw-r--r-- | src/glsl/ir_constant_expression.cpp | 9 | ||||
-rw-r--r-- | src/glsl/ir_constant_folding.cpp | 8 | ||||
-rw-r--r-- | src/glsl/ir_hierarchical_visitor.cpp | 16 | ||||
-rw-r--r-- | src/glsl/ir_hierarchical_visitor.h | 2 | ||||
-rw-r--r-- | src/glsl/ir_hv_accept.cpp | 17 | ||||
-rw-r--r-- | src/glsl/ir_print_visitor.cpp | 14 | ||||
-rw-r--r-- | src/glsl/ir_print_visitor.h | 1 | ||||
-rw-r--r-- | src/glsl/ir_visitor.h | 1 | ||||
-rw-r--r-- | src/mesa/shader/ir_to_mesa.cpp | 8 |
11 files changed, 115 insertions, 0 deletions
diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 65026ef1f5b..00b0076c172 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -793,6 +793,33 @@ private: /** Loop containing this break instruction. */ ir_loop *loop; }; + +/** + * IR instruction representing discard statements. + */ +class ir_discard : public ir_jump { +public: + ir_discard() + { + this->condition = NULL; + } + + ir_discard(ir_rvalue *cond) + { + this->condition = cond; + } + + virtual ir_instruction *clone(struct hash_table *ht) const; + + virtual void accept(ir_visitor *v) + { + v->visit(this); + } + + virtual ir_visitor_status accept(ir_hierarchical_visitor *); + + ir_rvalue *condition; +}; /*@}*/ diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index 01a1ce3a6d4..74cc858bda4 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -75,6 +75,18 @@ ir_return::clone(struct hash_table *ht) const } ir_instruction * +ir_discard::clone(struct hash_table *ht) const +{ + void *ctx = talloc_parent(this); + ir_rvalue *new_condition = NULL; + + if (this->condition != NULL) + new_condition = (ir_rvalue *) this->condition->clone(ht); + + return new(ctx) ir_discard(new_condition); +} + +ir_instruction * ir_loop_jump::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index 3408f5256a7..c6348ac4347 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -75,6 +75,7 @@ public: 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 *); @@ -648,6 +649,14 @@ ir_constant_visitor::visit(ir_return *ir) void +ir_constant_visitor::visit(ir_discard *ir) +{ + (void) ir; + value = NULL; +} + + +void ir_constant_visitor::visit(ir_if *ir) { (void) ir; diff --git a/src/glsl/ir_constant_folding.cpp b/src/glsl/ir_constant_folding.cpp index 342d027bbe8..2daa6fde38d 100644 --- a/src/glsl/ir_constant_folding.cpp +++ b/src/glsl/ir_constant_folding.cpp @@ -68,6 +68,7 @@ public: 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 *); @@ -191,6 +192,13 @@ ir_constant_folding_visitor::visit(ir_return *ir) void +ir_constant_folding_visitor::visit(ir_discard *ir) +{ + (void) ir; +} + + +void ir_constant_folding_visitor::visit(ir_if *ir) { ir_constant *const_val = ir->condition->constant_expression_value(); diff --git a/src/glsl/ir_hierarchical_visitor.cpp b/src/glsl/ir_hierarchical_visitor.cpp index 0d520b127f2..9afb12a4a2b 100644 --- a/src/glsl/ir_hierarchical_visitor.cpp +++ b/src/glsl/ir_hierarchical_visitor.cpp @@ -243,6 +243,22 @@ ir_hierarchical_visitor::visit_leave(ir_return *ir) } ir_visitor_status +ir_hierarchical_visitor::visit_enter(ir_discard *ir) +{ + if (this->callback != NULL) + this->callback(ir, this->data); + + return visit_continue; +} + +ir_visitor_status +ir_hierarchical_visitor::visit_leave(ir_discard *ir) +{ + (void) ir; + return visit_continue; +} + +ir_visitor_status ir_hierarchical_visitor::visit_enter(ir_if *ir) { if (this->callback != NULL) diff --git a/src/glsl/ir_hierarchical_visitor.h b/src/glsl/ir_hierarchical_visitor.h index 8b9e49dab13..2c4590d4b10 100644 --- a/src/glsl/ir_hierarchical_visitor.h +++ b/src/glsl/ir_hierarchical_visitor.h @@ -129,6 +129,8 @@ public: virtual ir_visitor_status visit_leave(class ir_call *); virtual ir_visitor_status visit_enter(class ir_return *); virtual ir_visitor_status visit_leave(class ir_return *); + virtual ir_visitor_status visit_enter(class ir_discard *); + virtual ir_visitor_status visit_leave(class ir_discard *); virtual ir_visitor_status visit_enter(class ir_if *); virtual ir_visitor_status visit_leave(class ir_if *); /*@}*/ diff --git a/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp index f936b3500eb..7b5cc5234c5 100644 --- a/src/glsl/ir_hv_accept.cpp +++ b/src/glsl/ir_hv_accept.cpp @@ -322,6 +322,23 @@ ir_return::accept(ir_hierarchical_visitor *v) ir_visitor_status +ir_discard::accept(ir_hierarchical_visitor *v) +{ + ir_visitor_status s = v->visit_enter(this); + if (s != visit_continue) + return (s == visit_continue_with_parent) ? visit_continue : s; + + if (this->condition != NULL) { + s = this->condition->accept(v); + if (s != visit_continue) + return (s == visit_continue_with_parent) ? visit_continue : s; + } + + return v->visit_leave(this); +} + + +ir_visitor_status ir_if::accept(ir_hierarchical_visitor *v) { ir_visitor_status s = v->visit_enter(this); diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp index be5a843f67d..6f867e32532 100644 --- a/src/glsl/ir_print_visitor.cpp +++ b/src/glsl/ir_print_visitor.cpp @@ -315,6 +315,20 @@ ir_print_visitor::visit(ir_return *ir) void +ir_print_visitor::visit(ir_discard *ir) +{ + printf("(discard "); + + if (ir->condition != NULL) { + printf(" "); + ir->condition->accept(this); + } + + printf(")"); +} + + +void ir_print_visitor::visit(ir_if *ir) { printf("(if "); diff --git a/src/glsl/ir_print_visitor.h b/src/glsl/ir_print_visitor.h index e97b823522a..3db42e24ca3 100644 --- a/src/glsl/ir_print_visitor.h +++ b/src/glsl/ir_print_visitor.h @@ -69,6 +69,7 @@ public: 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 *); diff --git a/src/glsl/ir_visitor.h b/src/glsl/ir_visitor.h index a6f9d2b7ee3..b87d7373180 100644 --- a/src/glsl/ir_visitor.h +++ b/src/glsl/ir_visitor.h @@ -57,6 +57,7 @@ public: virtual void visit(class ir_constant *) = 0; virtual void visit(class ir_call *) = 0; virtual void visit(class ir_return *) = 0; + virtual void visit(class ir_discard *) = 0; virtual void visit(class ir_if *) = 0; virtual void visit(class ir_loop *) = 0; virtual void visit(class ir_loop_jump *) = 0; diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp index ef9a96e2f52..8c074a8bd9a 100644 --- a/src/mesa/shader/ir_to_mesa.cpp +++ b/src/mesa/shader/ir_to_mesa.cpp @@ -134,6 +134,7 @@ public: virtual void visit(ir_constant *); virtual void visit(ir_call *); virtual void visit(ir_return *); + virtual void visit(ir_discard *); virtual void visit(ir_texture *); virtual void visit(ir_if *); /*@}*/ @@ -1321,6 +1322,13 @@ ir_to_mesa_visitor::visit(ir_return *ir) ir->get_value()->accept(this); } +void +ir_to_mesa_visitor::visit(ir_discard *ir) +{ + assert(0); + + ir->condition->accept(this); +} void ir_to_mesa_visitor::visit(ir_if *ir) |