[Mesa-dev] [RFC 4/7] i965/fs: Add DWord scattered read/write opcodes

Jason Ekstrand jason at jlekstrand.net
Mon Dec 5 19:59:55 UTC 2016


---
 src/mesa/drivers/dri/i965/brw_defines.h        |   2 +
 src/mesa/drivers/dri/i965/brw_fs.cpp           |   2 +
 src/mesa/drivers/dri/i965/brw_fs.h             |   3 +
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 142 +++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_shader.cpp       |   5 +
 5 files changed, 154 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 16a72c4..1fd0b94 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -1063,6 +1063,8 @@ enum opcode {
    SHADER_OPCODE_GEN4_SCRATCH_READ,
    SHADER_OPCODE_GEN4_SCRATCH_WRITE,
    SHADER_OPCODE_GEN7_SCRATCH_READ,
+   SHADER_OPCODE_DWORD_SCATTERED_READ,
+   SHADER_OPCODE_DWORD_SCATTERED_WRITE,
 
    /**
     * Gen8+ SIMD8 URB Read messages.
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index c218f56..8d47638 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -792,6 +792,8 @@ fs_inst::size_read(int arg) const
    switch (opcode) {
    case FS_OPCODE_FB_WRITE:
    case FS_OPCODE_FB_READ:
+   case SHADER_OPCODE_DWORD_SCATTERED_READ:
+   case SHADER_OPCODE_DWORD_SCATTERED_WRITE:
    case SHADER_OPCODE_URB_WRITE_SIMD8:
    case SHADER_OPCODE_URB_WRITE_SIMD8_PER_SLOT:
    case SHADER_OPCODE_URB_WRITE_SIMD8_MASKED:
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 4ce0f56..d34428b 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -415,6 +415,9 @@ private:
    void generate_scratch_write(fs_inst *inst, struct brw_reg src);
    void generate_scratch_read(fs_inst *inst, struct brw_reg dst);
    void generate_scratch_read_gen7(fs_inst *inst, struct brw_reg dst);
+   void generate_dword_scattered_read(fs_inst *inst, struct brw_reg dst,
+                                      struct brw_reg payload);
+   void generate_dword_scattered_write(fs_inst *inst, struct brw_reg payload);
    void generate_uniform_pull_constant_load(fs_inst *inst, struct brw_reg dst,
                                             struct brw_reg index,
                                             struct brw_reg offset);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index 3ef2d5b..1f753c1 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -1122,6 +1122,140 @@ fs_generator::generate_scratch_read_gen7(fs_inst *inst, struct brw_reg dst)
 }
 
 void
+fs_generator::generate_dword_scattered_read(fs_inst *inst, struct brw_reg dst,
+                                            struct brw_reg payload)
+{
+   assert(inst->mlen != 0);
+
+   uint32_t msg_control;
+   int rlen;
+
+   struct brw_reg mrf;
+   if (devinfo->gen >= 7) {
+      mrf = retype(payload, BRW_REGISTER_TYPE_UD);
+   } else {
+      mrf = retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD);
+   }
+
+   if (inst->exec_size == 8) {
+      msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS;
+      rlen = 1;
+   } else {
+      msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS;
+      rlen = 2;
+   }
+
+   unsigned msg_type;
+   if (devinfo->gen >= 7) {
+      msg_type = GEN7_DATAPORT_DC_DWORD_SCATTERED_READ;
+   } else if (devinfo->gen > 4 || devinfo->is_g4x) {
+      msg_type = G45_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
+   } else {
+      msg_type = BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
+   }
+
+   brw_inst *insn = brw_next_insn(p, BRW_OPCODE_SEND);
+
+   assert(brw_inst_pred_control(devinfo, insn) == 0);
+   brw_inst_set_qtr_control(devinfo, insn, BRW_COMPRESSION_NONE);
+
+   brw_set_dest(p, insn, retype(dst, BRW_REGISTER_TYPE_UD)); /* UW? */
+   if (devinfo->gen >= 6) {
+      brw_set_src0(p, insn, mrf);
+   } else {
+      brw_set_src0(p, insn, brw_null_reg());
+      brw_inst_set_base_mrf(devinfo, insn, inst->base_mrf);
+   }
+
+   const unsigned target_cache = devinfo->gen >= 7 ?
+      BRW_DATAPORT_READ_TARGET_DATA_CACHE :
+      BRW_DATAPORT_READ_TARGET_RENDER_CACHE;
+
+   brw_set_dp_read_message(p,
+                           insn,
+                           brw_scratch_surface_idx(p),
+                           msg_control,
+                           msg_type, /* msg_type */
+                           target_cache,
+                           inst->mlen, /* msg_length */
+                           true, /* header_present */
+                           rlen);
+}
+
+void
+fs_generator::generate_dword_scattered_write(fs_inst *inst,
+                                             struct brw_reg payload)
+{
+   assert(inst->mlen != 0);
+
+   struct brw_reg mrf;
+   if (devinfo->gen >= 7) {
+      mrf = retype(payload, BRW_REGISTER_TYPE_UD);
+   } else {
+      mrf = retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD);
+   }
+
+   uint32_t msg_control;
+   if (inst->exec_size == 8) {
+      msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS;
+   } else {
+      msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS;
+   }
+
+   unsigned msg_type;
+   if (devinfo->gen >= 6) {
+      msg_type = GEN6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE;
+   } else {
+      msg_type = BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE;
+   }
+
+   brw_inst *insn = brw_next_insn(p, BRW_OPCODE_SEND);
+
+   assert(brw_inst_pred_control(devinfo, insn) == 0);
+   brw_inst_set_qtr_control(devinfo, insn, BRW_COMPRESSION_NONE);
+
+   /* Until gen6, writes followed by reads from the same location
+    * are not guaranteed to be ordered unless write_commit is set.
+    * If set, then a no-op write is issued to the destination
+    * register to set a dependency, and a read from the destination
+    * can be used to ensure the ordering.
+    *
+    * For gen6, only writes between different threads need ordering
+    * protection.  Our use of DP writes is all about register
+    * spilling within a thread.
+    */
+   int send_commit_msg;
+   struct brw_reg dest;
+   if (devinfo->gen >= 6) {
+      dest = vec16(brw_null_reg());
+      send_commit_msg = 0;
+   } else {
+      dest = brw_vec16_grf(0, 0);
+      send_commit_msg = 1;
+   }
+   brw_set_dest(p, insn, retype(dest, BRW_REGISTER_TYPE_UW));
+
+   if (devinfo->gen >= 6) {
+      brw_set_src0(p, insn, mrf);
+   } else {
+      brw_set_src0(p, insn, brw_null_reg());
+      brw_inst_set_base_mrf(devinfo, insn, inst->base_mrf);
+   }
+
+   brw_set_dp_write_message(p,
+                            insn,
+                            brw_scratch_surface_idx(p),
+                            msg_control,
+                            msg_type, /* msg_type */
+                            inst->mlen, /* msg_length */
+                            true, /* header_present */
+			    0, /* not a render target */
+                            send_commit_msg, /* rlen */
+                            0, /* EOT */
+                            send_commit_msg);
+}
+
+void
 fs_generator::generate_uniform_pull_constant_load(fs_inst *inst,
                                                   struct brw_reg dst,
                                                   struct brw_reg index,
@@ -1967,6 +2101,14 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
          fill_count++;
 	 break;
 
+      case SHADER_OPCODE_DWORD_SCATTERED_READ:
+         generate_dword_scattered_read(inst, dst, src[0]);
+         break;
+
+      case SHADER_OPCODE_DWORD_SCATTERED_WRITE:
+         generate_dword_scattered_write(inst, src[0]);
+         break;
+
       case SHADER_OPCODE_MOV_INDIRECT:
          generate_mov_indirect(inst, dst, src[0], src[1]);
          break;
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 726bc7d..79fbb96 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -298,6 +298,10 @@ brw_instruction_name(const struct gen_device_info *devinfo, enum opcode op)
       return "gen4_scratch_write";
    case SHADER_OPCODE_GEN7_SCRATCH_READ:
       return "gen7_scratch_read";
+   case SHADER_OPCODE_DWORD_SCATTERED_READ:
+      return "dword_scattered_read";
+   case SHADER_OPCODE_DWORD_SCATTERED_WRITE:
+      return "dword_scattered_write";
    case SHADER_OPCODE_URB_WRITE_SIMD8:
       return "gen8_urb_write_simd8";
    case SHADER_OPCODE_URB_WRITE_SIMD8_PER_SLOT:
@@ -1005,6 +1009,7 @@ backend_instruction::has_side_effects() const
    case SHADER_OPCODE_UNTYPED_ATOMIC:
    case SHADER_OPCODE_UNTYPED_ATOMIC_LOGICAL:
    case SHADER_OPCODE_GEN4_SCRATCH_WRITE:
+   case SHADER_OPCODE_DWORD_SCATTERED_WRITE:
    case SHADER_OPCODE_UNTYPED_SURFACE_WRITE:
    case SHADER_OPCODE_UNTYPED_SURFACE_WRITE_LOGICAL:
    case SHADER_OPCODE_TYPED_ATOMIC:
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list