From: Kenneth Graunke Date: Wed, 30 Jun 2010 17:47:34 +0000 (-0700) Subject: glsl2: Define new ir_discard instruction. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=16efab1c4dee6e6a827ba5f1c482378159545ae5;p=mesa.git glsl2: Define new ir_discard instruction. --- 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 @@ -74,6 +74,18 @@ ir_return::clone(struct hash_table *ht) const return new(ctx) ir_return(new_value); } +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 { 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 *); @@ -647,6 +648,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) { 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 *); @@ -190,6 +191,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) { 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 @@ -242,6 +242,22 @@ ir_hierarchical_visitor::visit_leave(ir_return *ir) return visit_continue; } +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) { 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 @@ -321,6 +321,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) { 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 @@ -314,6 +314,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) { 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)