i965/gs: Set control data bits for vertices emitted in stream mode.
authorIago Toral Quiroga <itoral@igalia.com>
Tue, 3 Jun 2014 14:38:44 +0000 (16:38 +0200)
committerIago Toral Quiroga <itoral@igalia.com>
Mon, 30 Jun 2014 06:08:50 +0000 (08:08 +0200)
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>
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h

index 1321a94..b245924 100644 (file)
@@ -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)));
index 25415ea..0be7559 100644 (file)
@@ -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;