[Mesa-dev] [PATCH 4/8] i965/gs: Add the ability to compile a DUAL_INSTANCED geometry shader.

Paul Berry stereotype441 at gmail.com
Thu Oct 17 17:14:07 CEST 2013


Not yet enabled.
---
 src/mesa/drivers/dri/i965/brw_context.h           |  6 ++++++
 src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp | 25 +++++++++++++++++------
 src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h   |  3 ++-
 src/mesa/drivers/dri/i965/gen7_gs_state.c         |  4 +++-
 4 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index cafcf5c..6a14c7f 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -642,6 +642,12 @@ struct brw_gs_prog_data
 
    bool include_primitive_id;
    bool need_primitive_id_workaround;
+
+   /**
+    * True if the thread should be dispatched in DUAL_INSTANCE mode, false if
+    * it should be dispatched in DUAL_OBJECT mode.
+    */
+   bool dual_instanced_dispatch;
 };
 
 /** Number of texture sampler units */
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 8d8f20e..2be2666 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
@@ -57,7 +57,8 @@ vec4_gs_visitor::make_reg_for_system_value(ir_variable *ir)
 
 
 int
-vec4_gs_visitor::setup_varying_inputs(int payload_reg, int *attribute_map)
+vec4_gs_visitor::setup_varying_inputs(int payload_reg, int *attribute_map,
+                                      int attributes_per_reg)
 {
    /* For geometry shaders there are N copies of the input attributes, where N
     * is the number of input vertices.  attribute_map[BRW_VARYING_SLOT_COUNT *
@@ -75,11 +76,14 @@ vec4_gs_visitor::setup_varying_inputs(int payload_reg, int *attribute_map)
       int varying = c->input_vue_map.slot_to_varying[slot];
       for (unsigned vertex = 0; vertex < num_input_vertices; vertex++) {
          attribute_map[BRW_VARYING_SLOT_COUNT * vertex + varying] =
-            payload_reg + input_array_stride * vertex + slot;
+            attributes_per_reg * payload_reg + input_array_stride * vertex +
+            slot;
       }
    }
 
-   return payload_reg + input_array_stride * num_input_vertices;
+   int regs_used = ALIGN(input_array_stride * num_input_vertices,
+                         attributes_per_reg) / attributes_per_reg;
+   return payload_reg + regs_used;
 }
 
 
@@ -88,6 +92,11 @@ vec4_gs_visitor::setup_payload()
 {
    int attribute_map[BRW_VARYING_SLOT_COUNT * MAX_GS_INPUT_VERTICES];
 
+   /* If we are in dual instanced mode, then attributes are going to be
+    * interleaved, so one register contains two attribute slots.
+    */
+   int attributes_per_reg = c->prog_data.dual_instanced_dispatch ? 2 : 1;
+
    /* If a geometry shader tries to read from an input that wasn't written by
     * the vertex shader, that produces undefined results, but it shouldn't
     * crash anything.  So initialize attribute_map to zeros--that ensures that
@@ -105,13 +114,14 @@ vec4_gs_visitor::setup_payload()
 
    /* If the shader uses gl_PrimitiveIDIn, that goes in r1. */
    if (c->prog_data.include_primitive_id)
-      attribute_map[VARYING_SLOT_PRIMITIVE_ID] = reg++;
+      attribute_map[VARYING_SLOT_PRIMITIVE_ID] = attributes_per_reg * reg++;
 
    reg = setup_uniforms(reg);
 
-   reg = setup_varying_inputs(reg, attribute_map);
+   reg = setup_varying_inputs(reg, attribute_map, attributes_per_reg);
 
-   lower_attributes_to_hw_regs(attribute_map, false /* interleaved */);
+   lower_attributes_to_hw_regs(attribute_map,
+                               c->prog_data.dual_instanced_dispatch);
 
    this->first_non_payload_grf = reg;
 }
@@ -563,6 +573,9 @@ brw_gs_emit(struct brw_context *brw,
       printf("\n\n");
    }
 
+   /* Assume the geometry shader will use DUAL_OBJECT dispatch for now. */
+   c->prog_data.dual_instanced_dispatch = false;
+
    vec4_gs_visitor v(brw, c, prog, shader, mem_ctx, false /* no_spills */);
    if (!v.run()) {
       prog->LinkStatus = false;
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 f7ca5f0..da4adcd 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h
@@ -97,7 +97,8 @@ protected:
    virtual void visit(ir_end_primitive *);
 
 private:
-   int setup_varying_inputs(int payload_reg, int *attribute_map);
+   int setup_varying_inputs(int payload_reg, int *attribute_map,
+                            int attributes_per_reg);
    void emit_control_data_bits();
    void primitive_id_workaround();
 
diff --git a/src/mesa/drivers/dri/i965/gen7_gs_state.c b/src/mesa/drivers/dri/i965/gen7_gs_state.c
index c272b7d..2602200 100644
--- a/src/mesa/drivers/dri/i965/gen7_gs_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_gs_state.c
@@ -136,7 +136,9 @@ upload_gs_state(struct brw_context *brw)
          ((brw->max_gs_threads - 1) << max_threads_shift) |
          (brw->gs.prog_data->control_data_header_size_hwords <<
           GEN7_GS_CONTROL_DATA_HEADER_SIZE_SHIFT) |
-         GEN7_GS_DISPATCH_MODE_DUAL_OBJECT |
+         (brw->gs.prog_data->dual_instanced_dispatch ?
+          GEN7_GS_DISPATCH_MODE_DUAL_INSTANCE :
+          GEN7_GS_DISPATCH_MODE_DUAL_OBJECT) |
          GEN6_GS_STATISTICS_ENABLE |
          (brw->gs.prog_data->include_primitive_id ?
           GEN7_GS_INCLUDE_PRIMITIVE_ID : 0) |
-- 
1.8.4.1



More information about the mesa-dev mailing list