summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
diff options
context:
space:
mode:
authorIago Toral Quiroga <itoral@igalia.com>2014-06-03 16:38:44 +0200
committerIago Toral Quiroga <itoral@igalia.com>2014-06-30 08:08:50 +0200
commit5d562588a5a1067cf80148ddad3815fdba816151 (patch)
treee4bcd9e6df707ef19f03f8b98c3afad6f31e03dd /src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
parent7589683c97442239295e700cbea17e82736f1f27 (diff)
downloadexternal_mesa3d-5d562588a5a1067cf80148ddad3815fdba816151.zip
external_mesa3d-5d562588a5a1067cf80148ddad3815fdba816151.tar.gz
external_mesa3d-5d562588a5a1067cf80148ddad3815fdba816151.tar.bz2
i965/gs: Set control data bits for vertices emitted in stream mode.
In stream mode we have to set control data bits with the StreamID information for every vertex. Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp')
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp51
1 files changed, 50 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 1321a94..b245924 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)));