From f7ef8ec9d8f56b77029534952628c3204c4d5f63 Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Wed, 27 Aug 2014 11:32:08 -0700 Subject: [PATCH] i965/fs: Implement support for ir_barrier Signed-off-by: Jordan Justen Reviewed-by: Chris Forbes --- src/mesa/drivers/dri/i965/brw_defines.h | 5 ++++ src/mesa/drivers/dri/i965/brw_fs.h | 3 +++ .../drivers/dri/i965/brw_fs_generator.cpp | 11 +++++++++ src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 23 +++++++++++++++++++ src/mesa/drivers/dri/i965/brw_shader.cpp | 3 +++ 5 files changed, 45 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index eb04cc9d471..2a8fc0beea4 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -1135,6 +1135,11 @@ enum opcode { * Terminate the compute shader. */ CS_OPCODE_CS_TERMINATE, + + /** + * GLSL barrier() + */ + SHADER_OPCODE_BARRIER, }; enum brw_urb_write_flags { diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index ca887ec0b37..cdeea6d9988 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -273,6 +273,8 @@ public: void emit_urb_writes(); void emit_cs_terminate(); + void emit_barrier(); + void emit_shader_time_begin(); void emit_shader_time_end(); void SHADER_TIME_ADD(const brw::fs_builder &bld, @@ -418,6 +420,7 @@ private: void generate_fb_write(fs_inst *inst, struct brw_reg payload); void generate_urb_write(fs_inst *inst, struct brw_reg payload); void generate_cs_terminate(fs_inst *inst, struct brw_reg payload); + void generate_barrier(fs_inst *inst, struct brw_reg src); void generate_blorp_fb_write(fs_inst *inst); void generate_linterp(fs_inst *inst, struct brw_reg dst, struct brw_reg *src); diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index ff05b2a35ab..8eb3ace5c0a 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -400,6 +400,13 @@ fs_generator::generate_cs_terminate(fs_inst *inst, struct brw_reg payload) brw_inst_set_mask_control(devinfo, insn, BRW_MASK_DISABLE); } +void +fs_generator::generate_barrier(fs_inst *inst, struct brw_reg src) +{ + brw_barrier(p, src); + brw_WAIT(p); +} + void fs_generator::generate_blorp_fb_write(fs_inst *inst) { @@ -2117,6 +2124,10 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) generate_cs_terminate(inst, src[0]); break; + case SHADER_OPCODE_BARRIER: + generate_barrier(inst, src[0]); + break; + default: unreachable("Unsupported opcode"); diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 588966b66f1..4770838b26f 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1953,6 +1953,29 @@ fs_visitor::emit_cs_terminate() inst->eot = true; } +void +fs_visitor::emit_barrier() +{ + assert(brw->gen >= 7); + + /* We are getting the barrier ID from the compute shader header */ + assert(stage == MESA_SHADER_COMPUTE); + + fs_reg payload = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD); + + /* Clear the message payload */ + fs_inst *inst = bld.exec_all().MOV(payload, fs_reg(0u)); + + /* Copy bits 27:24 of r0.2 (barrier id) to the message payload reg.2 */ + fs_reg r0_2 = fs_reg(retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_UD)); + inst = bld.exec_all().AND(component(payload, 2), r0_2, fs_reg(0x0f000000u)); + + /* Emit a gateway "barrier" message using the payload we set up, followed + * by a wait instruction. + */ + bld.exec_all().emit(SHADER_OPCODE_BARRIER, reg_undef, payload); +} + fs_visitor::fs_visitor(struct brw_context *brw, void *mem_ctx, gl_shader_stage stage, diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index 76285f273e4..545ec2679ae 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -631,6 +631,8 @@ brw_instruction_name(enum opcode op) return "gs_ff_sync_set_primitives"; case CS_OPCODE_CS_TERMINATE: return "cs_terminate"; + case SHADER_OPCODE_BARRIER: + return "barrier"; } unreachable("not reached"); @@ -1058,6 +1060,7 @@ backend_instruction::has_side_effects() const case SHADER_OPCODE_MEMORY_FENCE: case SHADER_OPCODE_URB_WRITE_SIMD8: case FS_OPCODE_FB_WRITE: + case SHADER_OPCODE_BARRIER: return true; default: return false; -- 2.30.2