This will be necessary to implement EmitStreamVertex(). EmitVertex() will produce an ir_emit_vertex with the default stream 0. Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>tags/10.3-branchpoint
@@ -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; | |||
} |
@@ -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; | |||
}; | |||
/** |
@@ -68,15 +68,6 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir) | |||
return visit_continue; | |||
} | |||
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) | |||
{ | |||
@@ -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) | |||
{ |
@@ -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 *); | |||
/*@}*/ | |||
@@ -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); | |||
} | |||
@@ -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) | |||
@@ -204,6 +210,12 @@ ir_rvalue_visitor::visit_leave(ir_if *ir) | |||
return rvalue_visit(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) | |||
{ | |||
@@ -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); | |||
} |
@@ -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 *); | |||
}; |
@@ -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); |
@@ -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; |
@@ -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. |