i965/gs: Add GS_OPCODE_THREAD_END.
authorPaul Berry <stereotype441@gmail.com>
Sat, 23 Mar 2013 14:42:32 +0000 (07:42 -0700)
committerPaul Berry <stereotype441@gmail.com>
Fri, 23 Aug 2013 18:03:19 +0000 (11:03 -0700)
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_shader.cpp
src/mesa/drivers/dri/i965/brw_vec4.cpp
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_emit.cpp

index 16a1dbc022789c52502e56310f8914563ea97cf9..52009e204fc28bec1eb4efa1a7df1ce6444671b6 100644 (file)
@@ -808,6 +808,15 @@ enum opcode {
     * "Slot {0,1} Offset" fields in the message header.
     */
    GS_OPCODE_URB_WRITE,
+
+   /**
+    * Terminate the geometry shader thread by doing an empty URB write.
+    *
+    * This opcode doesn't do an implied move from R0 to the first MRF.  This
+    * allows the geometry shader to override the "GS Number of Output Vertices
+    * for Slot {0,1}" fields in the message header.
+    */
+   GS_OPCODE_THREAD_END,
 };
 
 #define BRW_PREDICATE_NONE             0
index d3de6edb8ce05f1da3339712814de6ea690cfafa..689e908d37dd86ba2dbef9c71a0af286a1608b66 100644 (file)
@@ -499,6 +499,8 @@ brw_instruction_name(enum opcode op)
 
    case GS_OPCODE_URB_WRITE:
       return "gs_urb_write";
+   case GS_OPCODE_THREAD_END:
+      return "gs_thread_end";
 
    default:
       /* Yes, this leaks.  It's in debug code, it should never occur, and if
index c97839641e1bf2eb33c24572f9d93c3500698a90..ae836d31ef1afda72c53fe959a4d437ba6bf3091 100644 (file)
@@ -260,6 +260,7 @@ vec4_visitor::implied_mrf_writes(vec4_instruction *inst)
    case VS_OPCODE_SCRATCH_WRITE:
       return 3;
    case GS_OPCODE_URB_WRITE:
+   case GS_OPCODE_THREAD_END:
       return 0;
    case SHADER_OPCODE_SHADER_TIME_ADD:
       return 0;
index c3e2212ac591caeeae00c72a6a8e580c854c568a..a95f61fb75ac6b921197dfc4f08ec262502e261a 100644 (file)
@@ -629,6 +629,7 @@ private:
 
    void generate_vs_urb_write(vec4_instruction *inst);
    void generate_gs_urb_write(vec4_instruction *inst);
+   void generate_gs_thread_end(vec4_instruction *inst);
    void generate_oword_dual_block_offsets(struct brw_reg m1,
                                          struct brw_reg index);
    void generate_scratch_write(vec4_instruction *inst,
index 84f50b065767abaae10ceda1d997a09b11b3f1d9..23a3b675138ab7f8608d1b9a442e7943d3182470 100644 (file)
@@ -427,6 +427,21 @@ vec4_generator::generate_gs_urb_write(vec4_instruction *inst)
                  BRW_URB_SWIZZLE_INTERLEAVE);
 }
 
+void
+vec4_generator::generate_gs_thread_end(vec4_instruction *inst)
+{
+   struct brw_reg src = brw_message_reg(inst->base_mrf);
+   brw_urb_WRITE(p,
+                 brw_null_reg(), /* dest */
+                 inst->base_mrf, /* starting mrf reg nr */
+                 src,
+                 BRW_URB_WRITE_EOT,
+                 1,              /* message len */
+                 0,              /* response len */
+                 0,              /* urb destination offset */
+                 BRW_URB_SWIZZLE_INTERLEAVE);
+}
+
 void
 vec4_generator::generate_oword_dual_block_offsets(struct brw_reg m1,
                                                   struct brw_reg index)
@@ -899,6 +914,10 @@ vec4_generator::generate_vec4_instruction(vec4_instruction *instruction,
       generate_gs_urb_write(inst);
       break;
 
+   case GS_OPCODE_THREAD_END:
+      generate_gs_thread_end(inst);
+      break;
+
    case SHADER_OPCODE_SHADER_TIME_ADD:
       brw_shader_time_add(p, src[0], SURF_INDEX_VS_SHADER_TIME);
       mark_surface_used(SURF_INDEX_VS_SHADER_TIME);