[Mesa-dev] [PATCH 5/6] i965: Add support for gl_VertexID and gl_InstanceID.

Eric Anholt eric at anholt.net
Wed Nov 9 11:33:28 PST 2011


The compiler setup for these VF-uploaded attributes looks a little
cheesy with mixing system values and real VBO-sourced attributes.  It
would be nice if we could just compute the ATTR[] map to GRF index up
front and use it at visit time instead of using ir->location in the
ATTR file.  However, we don't know the reg_offset at
visit(ir_variable *) time, so we can't do the mapping that early.

Fixes piglit vertexid test.
---
 src/mesa/drivers/dri/i965/brw_context.h        |    1 +
 src/mesa/drivers/dri/i965/brw_draw_upload.c    |   36 ++++++++++++++++++++---
 src/mesa/drivers/dri/i965/brw_vec4_emit.cpp    |   11 ++++++-
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |   21 ++++++++++++++
 4 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 3e05e36..9c4d09a 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -391,6 +391,7 @@ struct brw_vs_prog_data {
    const float *pull_param[MAX_UNIFORMS * 4];
 
    bool uses_new_param_layout;
+   bool uses_vertexid;
 };
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 52daed8..bd3d969 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -591,7 +591,7 @@ static void brw_emit_vertices(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->intel.ctx;
    struct intel_context *intel = intel_context(ctx);
-   GLuint i;
+   GLuint i, nr_elements;
 
    brw_prepare_vertices(brw);
 
@@ -667,17 +667,19 @@ static void brw_emit_vertices(struct brw_context *brw)
       ADVANCE_BATCH();
    }
 
+   nr_elements = brw->vb.nr_enabled + brw->vs.prog_data->uses_vertexid;
+
    /* The hardware allows one more VERTEX_ELEMENTS than VERTEX_BUFFERS, presumably
     * for VertexID/InstanceID.
     */
    if (intel->gen >= 6) {
-      assert(brw->vb.nr_enabled <= 34);
+      assert(nr_elements <= 34);
    } else {
-      assert(brw->vb.nr_enabled <= 18);
+      assert(nr_elements <= 18);
    }
 
-   BEGIN_BATCH(1 + brw->vb.nr_enabled * 2);
-   OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (2*brw->vb.nr_enabled - 1));
+   BEGIN_BATCH(1 + nr_elements * 2);
+   OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (2 * nr_elements - 1));
    for (i = 0; i < brw->vb.nr_enabled; i++) {
       struct brw_vertex_element *input = brw->vb.enabled[i];
       uint32_t format = get_surface_type(input->glarray->Type,
@@ -723,6 +725,30 @@ static void brw_emit_vertices(struct brw_context *brw)
                     (comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
                     ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
    }
+
+   if (brw->vs.prog_data->uses_vertexid) {
+      uint32_t dw0 = 0, dw1 = 0;
+
+      dw1 = ((BRW_VE1_COMPONENT_STORE_VID << BRW_VE1_COMPONENT_0_SHIFT) |
+	     (BRW_VE1_COMPONENT_STORE_IID << BRW_VE1_COMPONENT_1_SHIFT) |
+	     (BRW_VE1_COMPONENT_STORE_PID << BRW_VE1_COMPONENT_2_SHIFT) |
+	     (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT));
+
+      if (intel->gen >= 6) {
+	 dw0 |= GEN6_VE0_VALID;
+      } else {
+	 dw0 |= BRW_VE0_VALID;
+	 dw1 |= (i * 4) << BRW_VE1_DST_OFFSET_SHIFT;
+      }
+
+      /* Note that for gl_VertexID, gl_InstanceID, and gl_PrimitiveID values,
+       * the format is ignored and the value is always int.
+       */
+
+      OUT_BATCH(dw0);
+      OUT_BATCH(dw1);
+   }
+
    CACHED_BATCH();
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
index dc39f17..54bbe13 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
@@ -35,7 +35,7 @@ int
 vec4_visitor::setup_attributes(int payload_reg)
 {
    int nr_attributes;
-   int attribute_map[VERT_ATTRIB_MAX];
+   int attribute_map[VERT_ATTRIB_MAX + 1];
 
    nr_attributes = 0;
    for (int i = 0; i < VERT_ATTRIB_MAX; i++) {
@@ -45,6 +45,15 @@ vec4_visitor::setup_attributes(int payload_reg)
       }
    }
 
+   /* VertexID is stored by the VF as the last vertex element, but we
+    * don't represent it with a flag in inputs_read, so we call it
+    * VERT_ATTRIB_MAX.
+    */
+   if (prog_data->uses_vertexid) {
+      attribute_map[VERT_ATTRIB_MAX] = payload_reg + nr_attributes;
+      nr_attributes++;
+   }
+
    foreach_list(node, &this->instructions) {
       vec4_instruction *inst = (vec4_instruction *)node;
 
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 5b80f55..853c3ee 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -880,6 +880,27 @@ vec4_visitor::visit(ir_variable *ir)
       }
       break;
 
+   case ir_var_system_value:
+      /* VertexID is stored by the VF as the last vertex element, but
+       * we don't represent it with a flag in inputs_read, so we call
+       * it VERT_ATTRIB_MAX, which setup_attributes() picks up on.
+       */
+      reg = new(mem_ctx) dst_reg(ATTR, VERT_ATTRIB_MAX);
+      prog_data->uses_vertexid = true;
+
+      switch (ir->location) {
+      case SYSTEM_VALUE_VERTEX_ID:
+	 reg->writemask = WRITEMASK_X;
+	 break;
+      case SYSTEM_VALUE_INSTANCE_ID:
+	 reg->writemask = WRITEMASK_Y;
+	 break;
+      default:
+	 assert(!"not reached");
+	 break;
+      }
+      break;
+
    default:
       assert(!"not reached");
    }
-- 
1.7.7



More information about the mesa-dev mailing list