[Mesa-dev] [PATCH v2 11/23] glsl: Add support for EmitStreamVertex() and EndStreamPrimitive().
Iago Toral Quiroga
itoral at igalia.com
Wed Jun 18 02:51:38 PDT 2014
---
src/glsl/builtin_functions.cpp | 52 ++++++++++++++++++++++++++++++++++--
src/glsl/ir.h | 34 +++++++++++++++++------
src/glsl/ir_hierarchical_visitor.cpp | 50 +++++++++++++++++++++-------------
src/glsl/ir_hierarchical_visitor.h | 6 +++--
src/glsl/ir_hv_accept.cpp | 21 ++++++++++++---
src/glsl/ir_rvalue_visitor.cpp | 37 +++++++++++++++++++++++++
src/glsl/ir_rvalue_visitor.h | 6 +++++
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, 178 insertions(+), 38 deletions(-)
diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp
index f9f0686..07a0722 100644
--- a/src/glsl/builtin_functions.cpp
+++ b/src/glsl/builtin_functions.cpp
@@ -359,6 +359,12 @@ shader_image_load_store(const _mesa_glsl_parse_state *state)
state->ARB_shader_image_load_store_enable);
}
+static bool
+gs_streams(const _mesa_glsl_parse_state *state)
+{
+ return gpu_shader5(state) && gs_only(state);
+}
+
/** @} */
/******************************************************************************/
@@ -594,6 +600,10 @@ private:
B0(EmitVertex)
B0(EndPrimitive)
+ ir_function_signature *_EmitStreamVertex(builtin_available_predicate avail,
+ const glsl_type *stream_type);
+ ir_function_signature *_EndStreamPrimitive(builtin_available_predicate avail,
+ const glsl_type *stream_type);
B2(textureQueryLod);
B1(textureQueryLevels);
@@ -1708,6 +1718,14 @@ builtin_builder::create_builtins()
add_function("EmitVertex", _EmitVertex(), NULL);
add_function("EndPrimitive", _EndPrimitive(), NULL);
+ add_function("EmitStreamVertex",
+ _EmitStreamVertex(gs_streams, glsl_type::uint_type),
+ _EmitStreamVertex(gs_streams, glsl_type::int_type),
+ NULL);
+ add_function("EndStreamPrimitive",
+ _EndStreamPrimitive(gs_streams, glsl_type::uint_type),
+ _EndStreamPrimitive(gs_streams, glsl_type::int_type),
+ NULL);
add_function("textureQueryLOD",
_textureQueryLod(glsl_type::sampler1D_type, glsl_type::float_type),
@@ -3872,7 +3890,22 @@ 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;
+}
+
+ir_function_signature *
+builtin_builder::_EmitStreamVertex(builtin_available_predicate avail,
+ const glsl_type *stream_type)
+{
+ ir_variable *stream =
+ new(mem_ctx) ir_variable(stream_type, "stream", ir_var_const_in);
+
+ MAKE_SIG(glsl_type::void_type, avail, 1, stream);
+
+ body.emit(new(mem_ctx) ir_emit_vertex(var_ref(stream)));
return sig;
}
@@ -3882,7 +3915,22 @@ builtin_builder::_EndPrimitive()
{
MAKE_SIG(glsl_type::void_type, gs_only, 0);
- body.emit(new(mem_ctx) ir_end_primitive());
+ ir_rvalue *stream = new(mem_ctx) ir_constant(0, 1);
+ body.emit(new(mem_ctx) ir_end_primitive(stream));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_EndStreamPrimitive(builtin_available_predicate avail,
+ const glsl_type *stream_type)
+{
+ ir_variable *stream =
+ new(mem_ctx) ir_variable(stream_type, "stream", ir_var_const_in);
+
+ MAKE_SIG(glsl_type::void_type, avail, 1, stream);
+
+ body.emit(new(mem_ctx) ir_end_primitive(var_ref(stream)));
return sig;
}
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index dbbabb5..ea5ba27 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;
};
/**
@@ -2183,9 +2192,11 @@ public:
*/
class ir_end_primitive : public ir_instruction {
public:
- ir_end_primitive()
- : ir_instruction(ir_type_end_primitive)
+ ir_end_primitive(ir_rvalue *stream)
+ : ir_instruction(ir_type_end_primitive),
+ stream(stream)
{
+ assert(stream);
}
virtual void accept(ir_visitor *v)
@@ -2193,12 +2204,19 @@ public:
v->visit(this);
}
- virtual ir_end_primitive *clone(void *mem_ctx, struct hash_table *) const
+ virtual ir_end_primitive *clone(void *mem_ctx, struct hash_table *ht) const
{
- return new(mem_ctx) ir_end_primitive();
+ return new(mem_ctx) ir_end_primitive(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..d3c00ec 100644
--- a/src/glsl/ir_hierarchical_visitor.cpp
+++ b/src/glsl/ir_hierarchical_visitor.cpp
@@ -69,24 +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)
- this->callback(ir, this->data);
-
- return visit_continue;
-}
-
-ir_visitor_status
ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
{
if (this->callback != NULL)
@@ -303,6 +285,38 @@ 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;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_enter(ir_end_primitive *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit_leave(ir_end_primitive *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..bc89a04 100644
--- a/src/glsl/ir_hierarchical_visitor.h
+++ b/src/glsl/ir_hierarchical_visitor.h
@@ -87,8 +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 *);
/**
* ir_dereference_variable isn't technically a leaf, but it is treated as a
@@ -137,6 +135,10 @@ 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 *);
+ virtual ir_visitor_status visit_enter(class ir_end_primitive *);
+ virtual ir_visitor_status visit_leave(class ir_end_primitive *);
/*@}*/
diff --git a/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp
index 2a1f70e..eed761f 100644
--- a/src/glsl/ir_hv_accept.cpp
+++ b/src/glsl/ir_hv_accept.cpp
@@ -405,12 +405,27 @@ 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);
+}
ir_visitor_status
ir_end_primitive::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..0370170 100644
--- a/src/glsl/ir_rvalue_visitor.cpp
+++ b/src/glsl/ir_rvalue_visitor.cpp
@@ -149,6 +149,19 @@ 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_base_visitor::rvalue_visit(ir_end_primitive *ir)
+{
+ handle_rvalue(&ir->stream);
+ return visit_continue;
+}
ir_visitor_status
ir_rvalue_visitor::visit_leave(ir_expression *ir)
@@ -205,6 +218,18 @@ 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_visitor::visit_leave(ir_end_primitive *ir)
+{
+ return rvalue_visit(ir);
+}
+
+ir_visitor_status
ir_rvalue_enter_visitor::visit_enter(ir_expression *ir)
{
return rvalue_visit(ir);
@@ -257,3 +282,15 @@ 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);
+}
+
+ir_visitor_status
+ir_rvalue_enter_visitor::visit_enter(ir_end_primitive *ir)
+{
+ return rvalue_visit(ir);
+}
diff --git a/src/glsl/ir_rvalue_visitor.h b/src/glsl/ir_rvalue_visitor.h
index 2179fa5..04ec0fa 100644
--- a/src/glsl/ir_rvalue_visitor.h
+++ b/src/glsl/ir_rvalue_visitor.h
@@ -41,6 +41,8 @@ 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 *);
+ ir_visitor_status rvalue_visit(ir_end_primitive *);
virtual void handle_rvalue(ir_rvalue **rvalue) = 0;
};
@@ -57,6 +59,8 @@ 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 *);
+ virtual ir_visitor_status visit_leave(ir_end_primitive *);
};
class ir_rvalue_enter_visitor : public ir_rvalue_base_visitor {
@@ -71,4 +75,6 @@ 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 *);
+ virtual ir_visitor_status visit_enter(ir_end_primitive *);
};
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