[Mesa-dev] [RFC 3/7] i965/fs: Add a CHANNEL_IDS opcode

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


---
 src/mesa/drivers/dri/i965/brw_defines.h        |  6 ++++++
 src/mesa/drivers/dri/i965/brw_fs.h             |  3 +++
 src/mesa/drivers/dri/i965/brw_fs_cse.cpp       |  1 +
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 28 ++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_fs_nir.cpp       | 14 +++----------
 src/mesa/drivers/dri/i965/brw_shader.cpp       |  2 ++
 6 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index f22a52f..16a72c4 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -1095,6 +1095,12 @@ enum opcode {
     */
    SHADER_OPCODE_BROADCAST,
 
+   /* Takes no sources and returns the index of each channel in its respective
+    * SIMD channel in the destination register.  The instruction must have
+    * WE_all set and the destination must have type BRW_REGISTER_TYPE_UW.
+    */
+   SHADER_OPCODE_CHANNEL_IDS,
+
    VEC4_OPCODE_MOV_BYTES,
    VEC4_OPCODE_PACK_BYTES,
    VEC4_OPCODE_UNPACK_UNIFORM,
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 002cee8..4ce0f56 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -437,6 +437,9 @@ private:
                                           struct brw_reg msg_data,
                                           unsigned msg_type);
 
+   void generate_channel_ids(fs_inst *inst,
+                             struct brw_reg dst);
+
    void generate_set_sample_id(fs_inst *inst,
                                struct brw_reg dst,
                                struct brw_reg src0,
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
index 48220ef..02ccda1 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
@@ -79,6 +79,7 @@ is_expression(const fs_visitor *v, const fs_inst *const inst)
    case FS_OPCODE_LINTERP:
    case SHADER_OPCODE_FIND_LIVE_CHANNEL:
    case SHADER_OPCODE_BROADCAST:
+   case SHADER_OPCODE_CHANNEL_IDS:
    case SHADER_OPCODE_MOV_INDIRECT:
    case SHADER_OPCODE_TEX_LOGICAL:
    case SHADER_OPCODE_TXD_LOGICAL:
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index c5b50e1..3ef2d5b 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -1435,6 +1435,30 @@ fs_generator::generate_set_simd4x2_offset(fs_inst *inst,
    brw_pop_insn_state(p);
 }
 
+void
+fs_generator::generate_channel_ids(fs_inst *inst, struct brw_reg dst)
+{
+   assert(dst.type == BRW_REGISTER_TYPE_UW ||
+          dst.type == BRW_REGISTER_TYPE_W);
+   assert(inst->exec_size >= 8);
+
+   brw_push_insn_state(p);
+   brw_set_default_exec_size(p, BRW_EXECUTE_8);
+   brw_set_default_compression_control(p, BRW_COMPRESSION_NONE);
+   brw_set_default_mask_control(p, true);
+   brw_MOV(p, dst, brw_imm_v(0x76543210));
+
+   if (inst->exec_size > 8) {
+      assert(inst->exec_size == 16);
+      brw_ADD(p, vec8(suboffset(dst, 8)), vec8(dst), brw_imm_w(8));
+   }
+
+   brw_pop_insn_state(p);
+
+   if (inst->group > 0)
+      brw_ADD(p, dst, dst, brw_imm_w(inst->group));
+}
+
 /* Sets vstride=1, width=4, hstride=0 of register src1 during
  * the ADD instruction.
  */
@@ -2056,6 +2080,10 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
          brw_broadcast(p, dst, src[0], src[1]);
          break;
 
+      case SHADER_OPCODE_CHANNEL_IDS:
+         generate_channel_ids(inst, dst);
+         break;
+
       case FS_OPCODE_SET_SAMPLE_ID:
          generate_set_sample_id(inst, dst, src[0], src[1]);
          break;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 855266f..9478bb8 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -4310,17 +4310,9 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
    }
 
    case nir_intrinsic_load_channel_num: {
-      fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_UW);
-      dest = retype(dest, BRW_REGISTER_TYPE_UD);
-      const fs_builder allbld8 = bld.group(8, 0).exec_all();
-      allbld8.MOV(tmp, brw_imm_v(0x76543210));
-      if (dispatch_width > 8)
-         allbld8.ADD(byte_offset(tmp, 16), tmp, brw_imm_uw(8u));
-      if (dispatch_width > 16) {
-         const fs_builder allbld16 = bld.group(16, 0).exec_all();
-         allbld16.ADD(byte_offset(tmp, 32), tmp, brw_imm_uw(16u));
-      }
-      bld.MOV(dest, tmp);
+      fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_W);
+      bld.exec_all().emit(SHADER_OPCODE_CHANNEL_IDS, tmp);
+      bld.MOV(retype(dest, BRW_REGISTER_TYPE_D), tmp);
       break;
    }
 
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 25f745d..726bc7d 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -315,6 +315,8 @@ brw_instruction_name(const struct gen_device_info *devinfo, enum opcode op)
       return "find_live_channel";
    case SHADER_OPCODE_BROADCAST:
       return "broadcast";
+   case SHADER_OPCODE_CHANNEL_IDS:
+      return "channel_ids";
 
    case VEC4_OPCODE_MOV_BYTES:
       return "mov_bytes";
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list