[Mesa-dev,v2,13/23] i965/gs: Set control data bits for vertices emitted in stream mode.

Submitted by Iago Toral Quiroga on June 18, 2014, 9:51 a.m.

Details

Message ID 1403085110-31168-14-git-send-email-itoral@igalia.com
State Accepted
Commit 5d562588a5a1067cf80148ddad3815fdba816151
Headers show

Not browsing as part of any series.

Commit Message

Iago Toral Quiroga June 18, 2014, 9:51 a.m.
In stream mode we have to set control data bits with the StreamID
information for every vertex.
---
 src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp | 51 ++++++++++++++++++++++-
 src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h   |  1 +
 2 files changed, 51 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

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)));
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 25415ea..0be7559 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;