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>
{
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;
}
*/
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)
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;
};
/**
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)
{
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)
{
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 *);
/**
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 *);
/*@}*/
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);
}
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)
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)
{
{
return rvalue_visit(ir);
}
+
+ir_visitor_status
+ir_rvalue_enter_visitor::visit_enter(ir_emit_vertex *ir)
+{
+ return rvalue_visit(ir);
+}
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;
};
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 {
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 *);
};
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 *);
};
}
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);
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:
/**
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;
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.