summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIago Toral Quiroga <[email protected]>2014-07-09 16:28:30 +0200
committerIago Toral Quiroga <[email protected]>2014-09-19 15:01:15 +0200
commit2c85132e511bbef9a0965c69848981b1bffb5bad (patch)
tree00d07ecdbd5e3cdc70d98d6f669d69b75ca0da1b /src
parentd0bdd4ce983ddd52f9f4b70dced4e471c60a130c (diff)
i965/gen6/gs: Implement GS_OPCODE_URB_WRITE_ALLOCATE.
Gen6 geometry shaders need to allocate URB handles for each new vertex they emit after the first (the URB handle for the first vertex is obtained via the FF_SYNC message). This opcode adds the URB allocation mechanism to regular URB writes. Acked-by: Kenneth Graunke <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h8
-rw-r--r--src/mesa/drivers/dri/i965/brw_shader.cpp2
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_generator.cpp30
5 files changed, 42 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 27a513ac58d..0b5735cc02e 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -941,6 +941,14 @@ enum opcode {
GS_OPCODE_URB_WRITE,
/**
+ * Write geometry shader output data to the URB and request a new URB
+ * handle (gen6).
+ *
+ * This opcode doesn't do an implied move from R0 to the first MRF.
+ */
+ GS_OPCODE_URB_WRITE_ALLOCATE,
+
+ /**
* 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
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 4eea74e7e10..b2352468450 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -508,6 +508,8 @@ brw_instruction_name(enum opcode op)
case GS_OPCODE_URB_WRITE:
return "gs_urb_write";
+ case GS_OPCODE_URB_WRITE_ALLOCATE:
+ return "gs_urb_write_allocate";
case GS_OPCODE_THREAD_END:
return "gs_thread_end";
case GS_OPCODE_SET_WRITE_OFFSET:
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index fa992766a43..4210ee00a54 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -274,6 +274,7 @@ vec4_visitor::implied_mrf_writes(vec4_instruction *inst)
case SHADER_OPCODE_GEN4_SCRATCH_WRITE:
return 3;
case GS_OPCODE_URB_WRITE:
+ case GS_OPCODE_URB_WRITE_ALLOCATE:
case GS_OPCODE_THREAD_END:
return 0;
case GS_OPCODE_FF_SYNC:
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index d2d2a8f5fac..cb863c80595 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -646,6 +646,7 @@ private:
void generate_vs_urb_write(vec4_instruction *inst);
void generate_gs_urb_write(vec4_instruction *inst);
+ void generate_gs_urb_write_allocate(vec4_instruction *inst);
void generate_gs_thread_end(vec4_instruction *inst);
void generate_gs_set_write_offset(struct brw_reg dst,
struct brw_reg src0,
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
index c1eda12a7f3..f98c472430c 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
@@ -467,6 +467,32 @@ vec4_generator::generate_gs_urb_write(vec4_instruction *inst)
}
void
+vec4_generator::generate_gs_urb_write_allocate(vec4_instruction *inst)
+{
+ struct brw_reg src = brw_message_reg(inst->base_mrf);
+
+ /* We pass the temporary passed in src0 as the writeback register */
+ brw_urb_WRITE(p,
+ inst->get_src(this->prog_data, 0), /* dest */
+ inst->base_mrf, /* starting mrf reg nr */
+ src,
+ BRW_URB_WRITE_ALLOCATE_COMPLETE,
+ inst->mlen,
+ 1, /* response len */
+ inst->offset, /* urb destination offset */
+ BRW_URB_SWIZZLE_INTERLEAVE);
+
+ /* Now put allocated urb handle in dst.0 */
+ brw_push_insn_state(p);
+ brw_set_default_access_mode(p, BRW_ALIGN_1);
+ brw_set_default_mask_control(p, BRW_MASK_DISABLE);
+ brw_MOV(p, get_element_ud(inst->get_dst(), 0),
+ get_element_ud(inst->get_src(this->prog_data, 0), 0));
+ brw_set_default_access_mode(p, BRW_ALIGN_16);
+ brw_pop_insn_state(p);
+}
+
+void
vec4_generator::generate_gs_thread_end(vec4_instruction *inst)
{
struct brw_reg src = brw_message_reg(inst->base_mrf);
@@ -1309,6 +1335,10 @@ vec4_generator::generate_code(const cfg_t *cfg)
generate_gs_urb_write(inst);
break;
+ case GS_OPCODE_URB_WRITE_ALLOCATE:
+ generate_gs_urb_write_allocate(inst);
+ break;
+
case GS_OPCODE_THREAD_END:
generate_gs_thread_end(inst);
break;