summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/glsl/ir.h27
-rw-r--r--src/glsl/ir_clone.cpp12
-rw-r--r--src/glsl/ir_constant_expression.cpp9
-rw-r--r--src/glsl/ir_constant_folding.cpp8
-rw-r--r--src/glsl/ir_hierarchical_visitor.cpp16
-rw-r--r--src/glsl/ir_hierarchical_visitor.h2
-rw-r--r--src/glsl/ir_hv_accept.cpp17
-rw-r--r--src/glsl/ir_print_visitor.cpp14
-rw-r--r--src/glsl/ir_print_visitor.h1
-rw-r--r--src/glsl/ir_visitor.h1
-rw-r--r--src/mesa/shader/ir_to_mesa.cpp8
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)