<div dir="ltr">On 28 January 2014 11:22, Jordan Justen <span dir="ltr"><<a href="mailto:jordan.l.justen@intel.com" target="_blank">jordan.l.justen@intel.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Signed-off-by: Jordan Justen <<a href="mailto:jordan.l.justen@intel.com">jordan.l.justen@intel.com</a>><br>

---<br>
 src/mesa/drivers/dri/i965/brw_defines.h           |  5 +++++<br>
 src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp | 24 ++++++++++++++++++++---<br>
 2 files changed, 26 insertions(+), 3 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h<br>
index 7f4cd10..5fe1aba 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_defines.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_defines.h<br>
@@ -1500,6 +1500,11 @@ enum brw_message_target {<br>
 # define BRW_GS_EDGE_INDICATOR_0                       (1 << 8)<br>
 # define BRW_GS_EDGE_INDICATOR_1                       (1 << 9)<br>
<br>
+/* GS Thread Payload<br>
+ */<br>
+/* R0 */<br>
+# define GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT             27<br>
+<br>
 /* 3DSTATE_GS "Output Vertex Size" has an effective maximum of 62.  It's<br>
  * counted in multiples of 16 bytes.<br>
  */<br>
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp<br>
index 40743cc..12e137c 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp<br>
@@ -51,9 +51,27 @@ vec4_gs_visitor::vec4_gs_visitor(struct brw_context *brw,<br>
 dst_reg *<br>
 vec4_gs_visitor::make_reg_for_system_value(ir_variable *ir)<br>
 {<br>
-   /* Geometry shaders don't use any system values. */<br>
-   assert(!"Unreached");<br>
-   return NULL;<br>
+   dst_reg *reg;<br>
+   src_reg r0(retype(brw_vec4_grf(0, 0), BRW_REGISTER_TYPE_UD));<br>
+<br>
+   switch (ir->data.location) {<br>
+   case SYSTEM_VALUE_INVOCATION_ID:<br>
+      this->current_annotation = "initialize gl_InvocationID";<br>
+<br>
+      reg = new(mem_ctx) dst_reg(this, ir->type);<br>
+<br>
+      /* Copy and shift gen7 instance id from R0 into the<br>
+       * gl_InvocationID register.<br>
+       */<br>
+      emit(SHR(*reg, src_reg(r0),<br>
+               (uint32_t) GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT));<br>
+      break;<br>
+   default:<br>
+      assert(!"not reached");<br>
+      break;<br>
+   }<br>
+<br>
+   return reg;<br>
 }<br></blockquote><div><br></div><div>This would do what you want if invocation ID 0 was delivered in the upper bits of R0.0 and invocation ID 1 was delivered in the upper bits of R0.4.  But that's not the case.  They are delivered in R0.0 and R0.1 respectively.  I think you need to generate this instruction:<br>
<br></div><div>SHR (8) dst<1> R0<1;4,0> GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT<br><br></div><div>Note that this instruction requires ALIGN1 mode and a goofy register region, so you can't generate it directly from the visitor; what you'll have to do instead is create a new opcode to do it.  If you want to see examples where we've done similar things, grep for GS_OPCODE_SET_WRITE_OFFSET, GS_OPCODE_SET_VERTEX_COUNT, GS_OPCODE_SET_DWORD_2_IMMED, GS_OPCODE_PREPARE_CHANNEL_MASKS, or GS_OPCODE_SET_CHANNEL_MASKS.<br>
</div></div></div></div>