i965/fs: Implement support for ir_barrier
authorJordan Justen <jordan.l.justen@intel.com>
Wed, 27 Aug 2014 18:32:08 +0000 (11:32 -0700)
committerJordan Justen <jordan.l.justen@intel.com>
Fri, 12 Jun 2015 22:12:40 +0000 (15:12 -0700)
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_generator.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
src/mesa/drivers/dri/i965/brw_shader.cpp

index eb04cc9d471431053ad2b6a6649aceadeba99623..2a8fc0beea485a7068b4a15bf1e48c7d1d7d24b2 100644 (file)
@@ -1135,6 +1135,11 @@ enum opcode {
     * Terminate the compute shader.
     */
    CS_OPCODE_CS_TERMINATE,
+
+   /**
+    * GLSL barrier()
+    */
+   SHADER_OPCODE_BARRIER,
 };
 
 enum brw_urb_write_flags {
index ca887ec0b37c05cf47b5503b0465dfe24969e24d..cdeea6d9988d37c994af76db15a69ac818a7e8ed 100644 (file)
@@ -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);
index ff05b2a35abd0441062f9c4e6c41373a6dbf90a8..8eb3ace5c0afb43d1536605a48e439cc21aafd75 100644 (file)
@@ -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");
 
index 588966b66f1c5736c6243bb836c083343778432b..4770838b26fcb34e3aaaaa460f14bf0f2814dcb1 100644 (file)
@@ -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,
index 76285f273e423d3b6df3ae41bc3055b24049db82..545ec2679ae56827077e5867dc600c39fa6856ef 100644 (file)
@@ -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;