From: Iago Toral Quiroga Date: Wed, 9 Jul 2014 14:28:30 +0000 (+0200) Subject: i965/gen6/gs: Implement GS_OPCODE_URB_WRITE_ALLOCATE. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2c85132e511bbef9a0965c69848981b1bffb5bad;p=mesa.git 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 Reviewed-by: Jordan Justen --- 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 @@ -940,6 +940,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. * 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 @@ -466,6 +466,32 @@ vec4_generator::generate_gs_urb_write(vec4_instruction *inst) BRW_URB_SWIZZLE_INTERLEAVE); } +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) { @@ -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;