From 4416cb79926f089ff55dbbb352b94ec2890ae823 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Sat, 23 Mar 2013 07:42:32 -0700 Subject: [PATCH] i965/gs: Add GS_OPCODE_THREAD_END. Reviewed-by: Ian Romanick Reviewed-by: Kenneth Graunke Reviewed-by: Matt Turner --- src/mesa/drivers/dri/i965/brw_defines.h | 9 +++++++++ src/mesa/drivers/dri/i965/brw_shader.cpp | 2 ++ src/mesa/drivers/dri/i965/brw_vec4.cpp | 1 + src/mesa/drivers/dri/i965/brw_vec4.h | 1 + src/mesa/drivers/dri/i965/brw_vec4_emit.cpp | 19 +++++++++++++++++++ 5 files changed, 32 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 16a1dbc0227..52009e204fc 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -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 diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index d3de6edb8ce..689e908d37d 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -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 diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp index c97839641e1..ae836d31ef1 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp @@ -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; diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index c3e2212ac59..a95f61fb75a 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -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, diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp index 84f50b06576..23a3b675138 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp @@ -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); -- 2.30.2