[Mesa-dev] [PATCH v3 11 1/3] glsl: Modify ir_emit_vertex to have a stream.

Iago Toral Quiroga itoral at igalia.com
Fri Jun 20 02:02:35 PDT 2014


This will be necessary to implement EmitStreamVertex().
EmitVertex() will produce an ir_emit_vertex with the default stream 0.
---
 src/glsl/builtin_functions.cpp       |  3 ++-
 src/glsl/ir.h                        | 17 +++++++++++++----
 src/glsl/ir_hierarchical_visitor.cpp | 25 ++++++++++++++++---------
 src/glsl/ir_hierarchical_visitor.h   |  3 ++-
 src/glsl/ir_hv_accept.cpp            | 10 +++++++++-
 src/glsl/ir_rvalue_visitor.cpp       | 18 ++++++++++++++++++
 src/glsl/ir_rvalue_visitor.h         |  3 +++
 src/glsl/lower_output_reads.cpp      |  4 ++--
 src/glsl/lower_packed_varyings.cpp   |  4 ++--
 src/glsl/opt_dead_code_local.cpp     |  2 +-
 10 files changed, 68 insertions(+), 21 deletions(-)

diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp
index f9f0686..33b88439 100644
--- a/src/glsl/builtin_functions.cpp
+++ b/src/glsl/builtin_functions.cpp
@@ -3872,7 +3872,8 @@ builtin_builder::_EmitVertex()
 {
    MAKE_SIG(glsl_type::void_type, gs_only, 0);
 
-   body.emit(new(mem_ctx) ir_emit_vertex());
+   ir_rvalue *stream = new(mem_ctx) ir_constant(0, 1);
+   body.emit(new(mem_ctx) ir_emit_vertex(stream));
 
    return sig;
 }
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 2e422dd..fa22190 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -2159,9 +2159,11 @@ private:
  */
 class ir_emit_vertex : public ir_instruction {
 public:
-   ir_emit_vertex()
-      : ir_instruction(ir_type_emit_vertex)
+   ir_emit_vertex(ir_rvalue *stream)
+      : ir_instruction(ir_type_emit_vertex),
+        stream(stream)
    {
+      assert(stream);
    }
 
    virtual void accept(ir_visitor *v)
@@ -2169,12 +2171,19 @@ public:
       v->visit(this);
    }
 
-   virtual ir_emit_vertex *clone(void *mem_ctx, struct hash_table *) const
+   virtual ir_emit_vertex *clone(void *mem_ctx, struct hash_table *ht) const
    {
-      return new(mem_ctx) ir_emit_vertex();
+      return new(mem_ctx) ir_emit_vertex(this->stream->clone(mem_ctx, ht));
    }
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+
+   int stream_id() const
+   {
+      return stream->as_constant()->value.i[0];
+   }
+
+   ir_rvalue *stream;
 };
 
 /**
diff --git a/src/glsl/ir_hierarchical_visitor.cpp b/src/glsl/ir_hierarchical_visitor.cpp
index 2e606dd..78ae2df 100644
--- a/src/glsl/ir_hierarchical_visitor.cpp
+++ b/src/glsl/ir_hierarchical_visitor.cpp
@@ -69,15 +69,6 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir)
 }
 
 ir_visitor_status
-ir_hierarchical_visitor::visit(ir_emit_vertex *ir)
-{
-   if (this->callback != NULL)
-      this->callback(ir, this->data);
-
-   return visit_continue;
-}
-
-ir_visitor_status
 ir_hierarchical_visitor::visit(ir_end_primitive *ir)
 {
    if (this->callback != NULL)
@@ -303,6 +294,22 @@ ir_hierarchical_visitor::visit_leave(ir_if *ir)
    return visit_continue;
 }
 
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_emit_vertex *ir)
+{
+   if (this->callback != NULL)
+      this->callback(ir, this->data);
+
+   return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_emit_vertex *ir)
+{
+   (void) ir;
+   return visit_continue;
+}
+
 void
 ir_hierarchical_visitor::run(exec_list *instructions)
 {
diff --git a/src/glsl/ir_hierarchical_visitor.h b/src/glsl/ir_hierarchical_visitor.h
index 647d2e0..1679e0a 100644
--- a/src/glsl/ir_hierarchical_visitor.h
+++ b/src/glsl/ir_hierarchical_visitor.h
@@ -87,7 +87,6 @@ public:
    virtual ir_visitor_status visit(class ir_variable *);
    virtual ir_visitor_status visit(class ir_constant *);
    virtual ir_visitor_status visit(class ir_loop_jump *);
-   virtual ir_visitor_status visit(class ir_emit_vertex *);
    virtual ir_visitor_status visit(class ir_end_primitive *);
 
    /**
@@ -137,6 +136,8 @@ public:
    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 *);
+   virtual ir_visitor_status visit_enter(class ir_emit_vertex *);
+   virtual ir_visitor_status visit_leave(class ir_emit_vertex *);
    /*@}*/
 
 
diff --git a/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp
index 2a1f70e..f633283 100644
--- a/src/glsl/ir_hv_accept.cpp
+++ b/src/glsl/ir_hv_accept.cpp
@@ -405,7 +405,15 @@ ir_if::accept(ir_hierarchical_visitor *v)
 ir_visitor_status
 ir_emit_vertex::accept(ir_hierarchical_visitor *v)
 {
-   return v->visit(this);
+   ir_visitor_status s = v->visit_enter(this);
+   if (s != visit_continue)
+      return (s == visit_continue_with_parent) ? visit_continue : s;
+
+   s = this->stream->accept(v);
+   if (s != visit_continue)
+      return (s == visit_continue_with_parent) ? visit_continue : s;
+
+   return (s == visit_stop) ? s : v->visit_leave(this);
 }
 
 
diff --git a/src/glsl/ir_rvalue_visitor.cpp b/src/glsl/ir_rvalue_visitor.cpp
index fcbe944..eb6691e 100644
--- a/src/glsl/ir_rvalue_visitor.cpp
+++ b/src/glsl/ir_rvalue_visitor.cpp
@@ -149,6 +149,12 @@ ir_rvalue_base_visitor::rvalue_visit(ir_if *ir)
    return visit_continue;
 }
 
+ir_visitor_status
+ir_rvalue_base_visitor::rvalue_visit(ir_emit_vertex *ir)
+{
+   handle_rvalue(&ir->stream);
+   return visit_continue;
+}
 
 ir_visitor_status
 ir_rvalue_visitor::visit_leave(ir_expression *ir)
@@ -205,6 +211,12 @@ ir_rvalue_visitor::visit_leave(ir_if *ir)
 }
 
 ir_visitor_status
+ir_rvalue_visitor::visit_leave(ir_emit_vertex *ir)
+{
+   return rvalue_visit(ir);
+}
+
+ir_visitor_status
 ir_rvalue_enter_visitor::visit_enter(ir_expression *ir)
 {
    return rvalue_visit(ir);
@@ -257,3 +269,9 @@ ir_rvalue_enter_visitor::visit_enter(ir_if *ir)
 {
    return rvalue_visit(ir);
 }
+
+ir_visitor_status
+ir_rvalue_enter_visitor::visit_enter(ir_emit_vertex *ir)
+{
+   return rvalue_visit(ir);
+}
diff --git a/src/glsl/ir_rvalue_visitor.h b/src/glsl/ir_rvalue_visitor.h
index 2179fa5..ad16941 100644
--- a/src/glsl/ir_rvalue_visitor.h
+++ b/src/glsl/ir_rvalue_visitor.h
@@ -41,6 +41,7 @@ public:
    ir_visitor_status rvalue_visit(ir_return *);
    ir_visitor_status rvalue_visit(ir_swizzle *);
    ir_visitor_status rvalue_visit(ir_texture *);
+   ir_visitor_status rvalue_visit(ir_emit_vertex *);
 
    virtual void handle_rvalue(ir_rvalue **rvalue) = 0;
 };
@@ -57,6 +58,7 @@ public:
    virtual ir_visitor_status visit_leave(ir_return *);
    virtual ir_visitor_status visit_leave(ir_swizzle *);
    virtual ir_visitor_status visit_leave(ir_texture *);
+   virtual ir_visitor_status visit_leave(ir_emit_vertex *);
 };
 
 class ir_rvalue_enter_visitor : public ir_rvalue_base_visitor {
@@ -71,4 +73,5 @@ public:
    virtual ir_visitor_status visit_enter(ir_return *);
    virtual ir_visitor_status visit_enter(ir_swizzle *);
    virtual ir_visitor_status visit_enter(ir_texture *);
+   virtual ir_visitor_status visit_enter(ir_emit_vertex *);
 };
diff --git a/src/glsl/lower_output_reads.cpp b/src/glsl/lower_output_reads.cpp
index afe1776..1ee815d 100644
--- a/src/glsl/lower_output_reads.cpp
+++ b/src/glsl/lower_output_reads.cpp
@@ -52,7 +52,7 @@ public:
    output_read_remover();
    ~output_read_remover();
    virtual ir_visitor_status visit(class ir_dereference_variable *);
-   virtual ir_visitor_status visit(class ir_emit_vertex *);
+   virtual ir_visitor_status visit_leave(class ir_emit_vertex *);
    virtual ir_visitor_status visit_leave(class ir_return *);
    virtual ir_visitor_status visit_leave(class ir_function_signature *);
 };
@@ -148,7 +148,7 @@ output_read_remover::visit_leave(ir_return *ir)
 }
 
 ir_visitor_status
-output_read_remover::visit(ir_emit_vertex *ir)
+output_read_remover::visit_leave(ir_emit_vertex *ir)
 {
    hash_table_call_foreach(replacements, emit_return_copy, ir);
    hash_table_clear(replacements);
diff --git a/src/glsl/lower_packed_varyings.cpp b/src/glsl/lower_packed_varyings.cpp
index e865474..eda56a9 100644
--- a/src/glsl/lower_packed_varyings.cpp
+++ b/src/glsl/lower_packed_varyings.cpp
@@ -613,7 +613,7 @@ public:
    explicit lower_packed_varyings_gs_splicer(void *mem_ctx,
                                              const exec_list *instructions);
 
-   virtual ir_visitor_status visit(ir_emit_vertex *ev);
+   virtual ir_visitor_status visit_leave(ir_emit_vertex *ev);
 
 private:
    /**
@@ -637,7 +637,7 @@ lower_packed_varyings_gs_splicer::lower_packed_varyings_gs_splicer(
 
 
 ir_visitor_status
-lower_packed_varyings_gs_splicer::visit(ir_emit_vertex *ev)
+lower_packed_varyings_gs_splicer::visit_leave(ir_emit_vertex *ev)
 {
    foreach_list(node, this->instructions) {
       ir_instruction *ir = (ir_instruction *) node;
diff --git a/src/glsl/opt_dead_code_local.cpp b/src/glsl/opt_dead_code_local.cpp
index c27c526..88895fb 100644
--- a/src/glsl/opt_dead_code_local.cpp
+++ b/src/glsl/opt_dead_code_local.cpp
@@ -114,7 +114,7 @@ public:
       return visit_continue_with_parent;
    }
 
-   virtual ir_visitor_status visit(ir_emit_vertex *)
+   virtual ir_visitor_status visit_leave(ir_emit_vertex *)
    {
       /* For the purpose of dead code elimination, emitting a vertex counts as
        * "reading" all of the currently assigned output variables.
-- 
1.9.1



More information about the mesa-dev mailing list