diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp | 51 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h | 1 |
2 files changed, 51 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp index 1321a94d658..b24592423da 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp @@ -432,9 +432,47 @@ vec4_gs_visitor::emit_control_data_bits() emit(BRW_OPCODE_ENDIF); } +void +vec4_gs_visitor::set_stream_control_data_bits(unsigned stream_id) +{ + /* control_data_bits |= stream_id << ((2 * (vertex_count - 1)) % 32) */ + + /* Note: we are calling this *before* increasing vertex_count, so + * this->vertex_count == vertex_count - 1 in the formula above. + */ + + /* Stream mode uses 2 bits per vertex */ + assert(c->control_data_bits_per_vertex == 2); + + /* Must be a valid stream */ + assert(stream_id >= 0 && stream_id < MAX_VERTEX_STREAMS); + + /* Control data bits are initialized to 0 so we don't have to set any + * bits when sending vertices to stream 0. + */ + if (stream_id == 0) + return; + + /* reg::sid = stream_id */ + src_reg sid(this, glsl_type::uint_type); + emit(MOV(dst_reg(sid), stream_id)); + + /* reg:shift_count = 2 * (vertex_count - 1) */ + src_reg shift_count(this, glsl_type::uint_type); + emit(SHL(dst_reg(shift_count), this->vertex_count, 1u)); + + /* Note: we're relying on the fact that the GEN SHL instruction only pays + * attention to the lower 5 bits of its second source argument, so on this + * architecture, stream_id << 2 * (vertex_count - 1) is equivalent to + * stream_id << ((2 * (vertex_count - 1)) % 32). + */ + src_reg mask(this, glsl_type::uint_type); + emit(SHL(dst_reg(mask), sid, shift_count)); + emit(OR(dst_reg(this->control_data_bits), this->control_data_bits, mask)); +} void -vec4_gs_visitor::visit(ir_emit_vertex *) +vec4_gs_visitor::visit(ir_emit_vertex *ir) { this->current_annotation = "emit vertex: safety check"; @@ -498,6 +536,17 @@ vec4_gs_visitor::visit(ir_emit_vertex *) this->current_annotation = "emit vertex: vertex data"; emit_vertex(); + /* In stream mode we have to set control data bits for all vertices + * unless we have disabled control data bits completely (which we do + * do for GL_POINTS outputs that don't use streams). + */ + if (c->control_data_header_size_bits > 0 && + c->prog_data.control_data_format == + GEN7_GS_CONTROL_DATA_FORMAT_GSCTL_SID) { + this->current_annotation = "emit vertex: Stream control data bits"; + set_stream_control_data_bits(ir->stream_id()); + } + this->current_annotation = "emit vertex: increment vertex count"; emit(ADD(dst_reg(this->vertex_count), this->vertex_count, src_reg(1u))); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h index 25415ea3df1..0be755921c5 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h +++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h @@ -99,6 +99,7 @@ private: int setup_varying_inputs(int payload_reg, int *attribute_map, int attributes_per_reg); void emit_control_data_bits(); + void set_stream_control_data_bits(unsigned stream_id); src_reg vertex_count; src_reg control_data_bits; |