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 <kenneth@whitecape.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Iago Toral Quiroga 2014-07-09 16:28:30 +02:00
parent d0bdd4ce98
commit 2c85132e51
5 changed files with 42 additions and 0 deletions

View file

@ -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.
*

View file

@ -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:

View file

@ -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:

View file

@ -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,

View file

@ -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;