From 16efab1c4dee6e6a827ba5f1c482378159545ae5 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 30 Jun 2010 10:47:34 -0700 Subject: glsl2: Define new ir_discard instruction. --- src/glsl/ir.h | 27 +++++++++++++++++++++++++++ src/glsl/ir_clone.cpp | 12 ++++++++++++ src/glsl/ir_constant_expression.cpp | 9 +++++++++ src/glsl/ir_constant_folding.cpp | 8 ++++++++ src/glsl/ir_hierarchical_visitor.cpp | 16 ++++++++++++++++ src/glsl/ir_hierarchical_visitor.h | 2 ++ src/glsl/ir_hv_accept.cpp | 17 +++++++++++++++++ src/glsl/ir_print_visitor.cpp | 14 ++++++++++++++ src/glsl/ir_print_visitor.h | 1 + src/glsl/ir_visitor.h | 1 + src/mesa/shader/ir_to_mesa.cpp | 8 ++++++++ 11 files changed, 115 insertions(+) diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 65026ef1f5..00b0076c17 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 01a1ce3a6d..74cc858bda 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 3408f5256a..c6348ac434 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 342d027bbe..2daa6fde38 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 0d520b127f..9afb12a4a2 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 8b9e49dab1..2c4590d4b1 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 f936b3500e..7b5cc5234c 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 be5a843f67..6f867e3253 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 e97b823522..3db42e24ca 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 a6f9d2b7ee..b87d737318 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 ef9a96e2f5..8c074a8bd9 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) -- cgit v1.2.3