i965/gs: Add the ability to compile a DUAL_INSTANCED geometry shader.
authorPaul Berry <stereotype441@gmail.com>
Wed, 16 Oct 2013 19:04:19 +0000 (12:04 -0700)
committerPaul Berry <stereotype441@gmail.com>
Fri, 25 Oct 2013 05:00:46 +0000 (22:00 -0700)
Not yet enabled.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h
src/mesa/drivers/dri/i965/gen7_gs_state.c

index 39f45c64f87bd919c074602bba1dfaef28354cee..4bff63ed01a267043ddf682f7671521da8db34c3 100644 (file)
@@ -641,6 +641,12 @@ struct brw_gs_prog_data
    unsigned control_data_format;
 
    bool include_primitive_id;
+
+   /**
+    * 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 */
index a44f59300298cd0aee3daf84ded6b1986c1b1ee0..8af7a3cf6de2ad19bf20396d8dd080d6b29574cd 100644 (file)
@@ -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;
 }
@@ -534,6 +544,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;
index 39d20bb7cb878a7c6430469b71145bcacdb56ed3..68756f74904e65aa52ea349ef7e3f65123119845 100644 (file)
@@ -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();
 
    src_reg vertex_count;
index c272b7d8b5788cc2a8d6fc83a38a14aaa938ed7e..2602200eb683c62f4c7cfddf585556e272b6f7d8 100644 (file)
@@ -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) |