--- 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev