Mesa (master): i965: support gl_InvocationID for gen7

Jordan Justen jljusten at kemper.freedesktop.org
Thu Feb 20 19:19:39 UTC 2014


Module: Mesa
Branch: master
Commit: 008338bc4e2d9cc5931b9968d019619c09392389
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=008338bc4e2d9cc5931b9968d019619c09392389

Author: Jordan Justen <jordan.l.justen at intel.com>
Date:   Sat Jan 25 12:55:24 2014 -0800

i965: support gl_InvocationID for gen7

v2:
 * Make gl_InvocationID a system value

v3:
 * Properly shift from R0.1 into DST.4 by adding
   GS_OPCODE_GET_INSTANCE_ID

Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
Acked-by: Paul Berry <stereotype441 at gmail.com>
Reviewed-by: Anuj Phogat <anuj.phogat at gmail.com>

---

 src/mesa/drivers/dri/i965/brw_defines.h           |   12 ++++++++++++
 src/mesa/drivers/dri/i965/brw_shader.cpp          |    2 ++
 src/mesa/drivers/dri/i965/brw_vec4.h              |    1 +
 src/mesa/drivers/dri/i965/brw_vec4_generator.cpp  |   21 +++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp |   16 +++++++++++++---
 5 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 1cbbe67..1b57344 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -902,6 +902,13 @@ enum opcode {
     *   form the final channel mask.
     */
    GS_OPCODE_SET_CHANNEL_MASKS,
+
+   /**
+    * Get the "Instance ID" fields from the payload.
+    *
+    * - dst is the GRF for gl_InvocationID.
+    */
+   GS_OPCODE_GET_INSTANCE_ID,
 };
 
 enum brw_urb_write_flags {
@@ -1538,6 +1545,11 @@ enum brw_message_target {
 # define BRW_GS_EDGE_INDICATOR_0			(1 << 8)
 # define BRW_GS_EDGE_INDICATOR_1			(1 << 9)
 
+/* GS Thread Payload
+ */
+/* R0 */
+# define GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT		27
+
 /* 3DSTATE_GS "Output Vertex Size" has an effective maximum of 62.  It's
  * counted in multiples of 16 bytes.
  */
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index d3a7560..08ceca1 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -527,6 +527,8 @@ brw_instruction_name(enum opcode op)
       return "prepare_channel_masks";
    case GS_OPCODE_SET_CHANNEL_MASKS:
       return "set_channel_masks";
+   case GS_OPCODE_GET_INSTANCE_ID:
+      return "get_instance_id";
 
    default:
       /* Yes, this leaks.  It's in debug code, it should never occur, and if
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 1e0d882..6bd8b80 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -675,6 +675,7 @@ private:
    void generate_gs_set_dword_2_immed(struct brw_reg dst, struct brw_reg src);
    void generate_gs_prepare_channel_masks(struct brw_reg dst);
    void generate_gs_set_channel_masks(struct brw_reg dst, struct brw_reg src);
+   void generate_gs_get_instance_id(struct brw_reg dst);
    void generate_oword_dual_block_offsets(struct brw_reg m1,
 					  struct brw_reg index);
    void generate_scratch_write(vec4_instruction *inst,
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
index e0c59ba..d3d5939 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
@@ -632,6 +632,23 @@ vec4_generator::generate_gs_set_channel_masks(struct brw_reg dst,
 }
 
 void
+vec4_generator::generate_gs_get_instance_id(struct brw_reg dst)
+{
+   /* We want to right shift R0.0 & R0.1 by GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT
+    * and store into dst.0 & dst.4. So generate the instruction:
+    *
+    *     shr(8) dst<1> R0<1,4,0> GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT { align1 WE_normal 1Q }
+    */
+   brw_push_insn_state(p);
+   brw_set_access_mode(p, BRW_ALIGN_1);
+   dst = retype(dst, BRW_REGISTER_TYPE_UD);
+   struct brw_reg r0(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
+   brw_SHR(p, dst, stride(r0, 1, 4, 0),
+           brw_imm_ud(GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT));
+   brw_pop_insn_state(p);
+}
+
+void
 vec4_generator::generate_oword_dual_block_offsets(struct brw_reg m1,
                                                   struct brw_reg index)
 {
@@ -1211,6 +1228,10 @@ vec4_generator::generate_vec4_instruction(vec4_instruction *instruction,
       generate_gs_set_channel_masks(dst, src[0]);
       break;
 
+   case GS_OPCODE_GET_INSTANCE_ID:
+      generate_gs_get_instance_id(dst);
+      break;
+
    case SHADER_OPCODE_SHADER_TIME_ADD:
       brw_shader_time_add(p, src[0],
                           prog_data->base.binding_table.shader_time_start);
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 d57c619..1d00796 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
@@ -51,9 +51,19 @@ vec4_gs_visitor::vec4_gs_visitor(struct brw_context *brw,
 dst_reg *
 vec4_gs_visitor::make_reg_for_system_value(ir_variable *ir)
 {
-   /* Geometry shaders don't use any system values. */
-   assert(!"Unreached");
-   return NULL;
+   dst_reg *reg = new(mem_ctx) dst_reg(this, ir->type);
+
+   switch (ir->data.location) {
+   case SYSTEM_VALUE_INVOCATION_ID:
+      this->current_annotation = "initialize gl_InvocationID";
+      emit(GS_OPCODE_GET_INSTANCE_ID, *reg);
+      break;
+   default:
+      assert(!"not reached");
+      break;
+   }
+
+   return reg;
 }
 
 




More information about the mesa-commit mailing list